Skip to content

Instantly share code, notes, and snippets.

@alcatrazEscapee
Created September 4, 2018 15:36
Show Gist options
  • Save alcatrazEscapee/c61f87c78d7f833ccf9161aff0584261 to your computer and use it in GitHub Desktop.
Save alcatrazEscapee/c61f87c78d7f833ccf9161aff0584261 to your computer and use it in GitHub Desktop.
Test Annotations
package testproject.test;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
/**
* This is an example of using an annotation to indicate fields on a class to be saved
* Currently, it will save string fields with a name to a Map of String -> String
* This can be extended to save fields of other types or to save fields to another data structure (NBT).
*/
public class TestAnnotations
{
public static void init()
{
// Create a new thing
ISerializable thing = new Thing("thing1", "this is some info", "1gniht", 666);
// Write the thing to data
Map<String, String> data = thing.write();
data.forEach((x, y) -> System.out.println("Wrote data: " + x + " -> " + y));
// Output:
// Wrote data: the_name -> thing1
// Wrote data: the_info -> this is some info
// read the thing from saved data (i.e. from external source)
data = new HashMap<>();
data.put("the_name", "thing2");
data.put("the_info", "info about another thing");
thing.read(data);
// Write the thing to data again
data = thing.write();
data.forEach((x, y) -> System.out.println("Wrote data: " + x + " -> " + y));
// Output:
// Wrote data: the_name -> thing2
// Wrote data: the_info -> info about another thing
}
/**
* This is our annotation to indicate that a field needs to be written / read
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@interface Serializable
{
String value();
}
/**
* This declares the functions used to write and read an object from data
* The default implementation will search for all @Serializable fields and write them to data
* This mimics writeToNBT() and readFromNBT() in TileEntities. (This would be a top level abstract class TileEntityTFC extends TileEntity)
*/
interface ISerializable
{
default Map<String, String> write()
{
Map<String, String> data = new HashMap<>();
for(Field field : getClass().getDeclaredFields())
{
Serializable s = field.getAnnotation(Serializable.class);
if(s != null)
{
try
{
field.setAccessible(true);
Object value = field.get(this);
if(value instanceof String)
data.put(s.value(), ((String)value));
}
catch(Exception e)
{
System.out.println("Problems! " + e);
}
}
}
return data;
}
default void read(Map<String, String> map)
{
for(Field field : getClass().getDeclaredFields())
{
Serializable s = field.getAnnotation(Serializable.class);
if(s != null)
{
String newValue = map.get(s.value());
if(newValue != null)
{
try
{
field.setAccessible(true);
field.set(this, newValue);
}
catch (Exception e)
{
System.out.println("Problems! " + e);
}
}
}
}
}
}
/**
* This is the class that is written from / to data
* It has two strings that are always written correctly.
* The int field is not written or read, since it is not handled in ISerializable
* Additionally, the string not annotated with @Serializable is not read or written to data
*/
static class Thing implements ISerializable
{
@Serializable("the_name")
private String name;
@Serializable("the_info")
private String info;
@Serializable("This does not work")
private int test;
private String otherName;
Thing(String name, String info, String otherName, int test)
{
this.name = name;
this.info = info;
this.otherName = otherName;
this.test = test;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment