Created
September 4, 2018 15:36
-
-
Save alcatrazEscapee/c61f87c78d7f833ccf9161aff0584261 to your computer and use it in GitHub Desktop.
Test Annotations
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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