From 6b217b7580ecde0e8aad95c3661a7d0be31f2b53 Mon Sep 17 00:00:00 2001 From: austin Date: Sun, 11 Aug 2024 12:21:24 -0400 Subject: [PATCH] state collection work --- src/main/java/electrosphere/main/Main.java | 3 +- .../main/core/VirtualProject.java | 9 ++ .../main/core/transport/StateCollection.java | 37 ++++++++ .../methods/ApplyStateCollection.java | 84 +++++++++++++++++++ .../transport/methods/GetStateCollection.java | 84 +++++++++++++++++++ .../main/project/parsers/MainParser.java | 5 ++ .../server/ApplyStateCollection.java | 15 ++++ .../resources/server/GetStateCollection.java | 17 ++++ 8 files changed, 253 insertions(+), 1 deletion(-) create mode 100644 src/main/java/electrosphere/main/core/transport/StateCollection.java create mode 100644 src/main/java/electrosphere/main/core/transport/methods/ApplyStateCollection.java create mode 100644 src/main/java/electrosphere/main/core/transport/methods/GetStateCollection.java create mode 100644 src/main/resources/server/ApplyStateCollection.java create mode 100644 src/main/resources/server/GetStateCollection.java diff --git a/src/main/java/electrosphere/main/Main.java b/src/main/java/electrosphere/main/Main.java index b2836af..501e4a6 100644 --- a/src/main/java/electrosphere/main/Main.java +++ b/src/main/java/electrosphere/main/Main.java @@ -29,12 +29,13 @@ public class Main { public static boolean LOG = true; //controls whether files are actually written to disk or not - public static boolean WRITE_TO_DISK = false; + public static boolean WRITE_TO_DISK = true; //hard-coded white list files to always parse static final String[] ALWAYS_PARSED_CLASSES = new String[]{ "ClientSynchronizationManager", "ServerSynchronizationManager", + "StateCollection", "BehaviorTreeIdEnums", "FieldIdEnums", }; diff --git a/src/main/java/electrosphere/main/core/VirtualProject.java b/src/main/java/electrosphere/main/core/VirtualProject.java index 8374f34..7e3c337 100644 --- a/src/main/java/electrosphere/main/core/VirtualProject.java +++ b/src/main/java/electrosphere/main/core/VirtualProject.java @@ -6,6 +6,7 @@ import java.util.List; import electrosphere.main.client.syncmanager.ClientSynchronizationManager; import electrosphere.main.core.statics.btreeenum.BTreeIdEnum; import electrosphere.main.core.statics.fieldenum.FieldIdEnum; +import electrosphere.main.core.transport.StateCollection; import electrosphere.main.project.ProjectStructure; import electrosphere.main.server.syncmanager.ServerSynchronizationManager; import electrosphere.main.source.VirtualClass; @@ -80,6 +81,14 @@ public class VirtualProject { this.classes.add(new ServerSynchronizationManager(file)); } + /** + * Creates a state collection file + * @param file The target file + */ + public void createStateCollection(TargetFile file){ + this.classes.add(new StateCollection(file)); + } + /** * Adds a virtual class to the project * @param virtualClass The virtual class diff --git a/src/main/java/electrosphere/main/core/transport/StateCollection.java b/src/main/java/electrosphere/main/core/transport/StateCollection.java new file mode 100644 index 0000000..80b2876 --- /dev/null +++ b/src/main/java/electrosphere/main/core/transport/StateCollection.java @@ -0,0 +1,37 @@ +package electrosphere.main.core.transport; + +import electrosphere.main.core.transport.methods.ApplyStateCollection; +import electrosphere.main.core.transport.methods.GetStateCollection; +import electrosphere.main.source.VirtualClass; +import electrosphere.main.targets.TargetFile; + +/** + * Packages collections of synchronized variables + */ +public class StateCollection extends VirtualClass { + + //The target file for the current version of the class + TargetFile file; + + /** + * Constructor + * @param targetFile + */ + public StateCollection(TargetFile targetFile){ + super( + targetFile, + "StateCollection", + true + ); + this.file = targetFile; + + // + // + // ADD METHODS HERE + // + // + this.addMethod(new GetStateCollection()); + this.addMethod(new ApplyStateCollection()); + } + +} diff --git a/src/main/java/electrosphere/main/core/transport/methods/ApplyStateCollection.java b/src/main/java/electrosphere/main/core/transport/methods/ApplyStateCollection.java new file mode 100644 index 0000000..ea307bd --- /dev/null +++ b/src/main/java/electrosphere/main/core/transport/methods/ApplyStateCollection.java @@ -0,0 +1,84 @@ +package electrosphere.main.core.transport.methods; + +import java.util.LinkedList; +import java.util.List; + +import electrosphere.main.core.btree.BehaviorTree; +import electrosphere.main.core.statics.btreeenum.BTreeIdEnum; +import electrosphere.main.core.syncfield.SynchronizedField; +import electrosphere.main.project.ProjectStructure; +import electrosphere.main.source.VirtualMethod; +import electrosphere.main.util.TemplateInjectionUtils; +import electrosphere.main.util.Utilities; + +public class ApplyStateCollection implements VirtualMethod { + + @Override + public String getName(ProjectStructure projectStructure) { + return "applyStateCollection"; + } + + @Override + public String getContent(ProjectStructure projectStructure) { + String updateCases = ""; + for(BehaviorTree serverTree : projectStructure.getBehaviorTrees()){ + //counterintuitively, want to only update client for server behavior tree ids + if(serverTree.isServer()){ + BehaviorTree clientEquivalent = projectStructure.getTree(serverTree.getCorrespondingTreeName()); + String clientTreeName = clientEquivalent.getClassName(); + updateCases = updateCases + " case BehaviorTreeIdEnums." + BTreeIdEnum.getTreeIdEnum(serverTree) + ": {\n"; + updateCases = updateCases + " " + clientTreeName + " tree = " + clientTreeName + ".get" + clientTreeName + "(entity);\n"; + //update each field + updateCases = updateCases + " switch(syncedValue.getFieldId()){\n"; + for(SynchronizedField field : serverTree.getSynchronizedFields()){ + String fieldIdVariable = "TREE_" + serverTree.getName().toUpperCase() + "_SYNCEDFIELD_" + field.getFieldName().toUpperCase() + "_ID"; + updateCases = updateCases + " case(FieldIdEnums." + fieldIdVariable + "): {\n"; + String getFieldValue = ""; + switch(field.getTypeName()){ + case "int": { + getFieldValue = "((Double)syncedValue.getValue()).intValue()"; + } break; + case "long": { + getFieldValue = "((Double)syncedValue.getValue()).longValue()"; + } break; + case "float": { + getFieldValue = "((Double)syncedValue.getValue()).floatValue()"; + } break; + case "double": { + getFieldValue = "(double)syncedValue.getValue()"; + } break; + case "String": { + getFieldValue = "(String)syncedValue.getValue()"; + } break; + default : { + getFieldValue = clientEquivalent.getClassName() + ".get" + Utilities.camelCase(field.getTypeName()) + "ShortAsEnum(((Double)syncedValue.getValue()).shortValue())"; + } break; + } + updateCases = updateCases + " tree." + field.getSetterName() + "(" + getFieldValue + ");\n"; + updateCases = updateCases + " } break;\n"; + } + updateCases = updateCases + " }\n"; + updateCases = updateCases + " } break;\n"; + } + } + String fullReplacementText = TemplateInjectionUtils.getFragmentWithReplacement("/server/ApplyStateCollection.java", updateCases); + return fullReplacementText; + } + + @Override + public List getImports(ProjectStructure projectStructure) { + List rVal = new LinkedList(); + + //add server trees + for(BehaviorTree bTree : projectStructure.getBehaviorTrees()){ + rVal.add(bTree.getTargetFile().getQualifiedPath()); + } + return rVal; + } + + @Override + public boolean shouldOverwrite() { + return true; + } + +} diff --git a/src/main/java/electrosphere/main/core/transport/methods/GetStateCollection.java b/src/main/java/electrosphere/main/core/transport/methods/GetStateCollection.java new file mode 100644 index 0000000..c4b9275 --- /dev/null +++ b/src/main/java/electrosphere/main/core/transport/methods/GetStateCollection.java @@ -0,0 +1,84 @@ +package electrosphere.main.core.transport.methods; + +import java.util.LinkedList; +import java.util.List; + +import electrosphere.main.core.btree.BehaviorTree; +import electrosphere.main.core.statics.btreeenum.BTreeIdEnum; +import electrosphere.main.core.syncfield.SynchronizedField; +import electrosphere.main.project.ProjectStructure; +import electrosphere.main.source.VirtualMethod; +import electrosphere.main.util.TemplateInjectionUtils; +import electrosphere.main.util.Utilities; + +public class GetStateCollection implements VirtualMethod { + + @Override + public String getName(ProjectStructure projectStructure) { + return "getStateCollection"; + } + + @Override + public String getContent(ProjectStructure projectStructure) { + String updateCases = ""; + for(BehaviorTree serverTree : projectStructure.getBehaviorTrees()){ + //counterintuitively, want to only update client for server behavior tree ids + if(serverTree.isServer() && this.shouldIncludeTree(projectStructure, serverTree)){ + BehaviorTree clientEquivalent = projectStructure.getTree(serverTree.getCorrespondingTreeName()); + String serverTreeName = serverTree.getClassName(); + updateCases = updateCases + " case BehaviorTreeIdEnums." + BTreeIdEnum.getTreeIdEnum(serverTree) + ": {\n"; + updateCases = updateCases + " " + serverTreeName + " tree = " + serverTreeName + ".get" + serverTreeName + "(entity);\n"; + //update each field + for(SynchronizedField field : serverTree.getSynchronizedFields()){ + String getFieldValue = ""; + switch(field.getTypeName()){ + case "int": + case "long": + case "float": + case "double": + case "String": { + getFieldValue = "tree.get" + Utilities.camelCase(field.getFieldName()) + "()"; + } break; + default : { + getFieldValue = clientEquivalent.getClassName() + ".get" + Utilities.camelCase(field.getTypeName()) + "EnumAsShort(tree.get" + Utilities.camelCase(field.getFieldName()) + "())"; + } break; + } + String fieldIdVariable = "TREE_" + serverTree.getName().toUpperCase() + "_SYNCEDFIELD_" + field.getFieldName().toUpperCase() + "_ID"; + updateCases = updateCases + " collection.setValue(new SynchronizedFieldValue(BehaviorTreeIdEnums." + BTreeIdEnum.getTreeIdEnum(serverTree) + ",FieldIdEnums." + fieldIdVariable + "," + getFieldValue + "));\n"; + } + updateCases = updateCases + " } break;\n"; + } + } + String fullReplacementText = TemplateInjectionUtils.getFragmentWithReplacement("/server/GetStateCollection.java", updateCases); + return fullReplacementText; + } + + @Override + public List getImports(ProjectStructure projectStructure) { + List rVal = new LinkedList(); + + //add server trees + for(BehaviorTree bTree : projectStructure.getBehaviorTrees()){ + if(this.shouldIncludeTree(projectStructure,bTree)){ + rVal.add(bTree.getTargetFile().getQualifiedPath()); + } + } + return rVal; + } + + @Override + public boolean shouldOverwrite() { + return true; + } + + + /** + * Checks if this tree should be included in the synchronization manager + * @param serverTree The server behavior tree + * @return true if should be included, false otherwise + */ + private boolean shouldIncludeTree(ProjectStructure projectStructure, BehaviorTree serverTree){ + return true; + } + +} diff --git a/src/main/java/electrosphere/main/project/parsers/MainParser.java b/src/main/java/electrosphere/main/project/parsers/MainParser.java index 3b24e68..9393806 100644 --- a/src/main/java/electrosphere/main/project/parsers/MainParser.java +++ b/src/main/java/electrosphere/main/project/parsers/MainParser.java @@ -66,6 +66,11 @@ public class MainParser { if(target.getName().contains("ServerSynchronizationManager")){ rVal.createServerSynchronizationManager(target); } + + //state collection + if(target.getName().contains("StateCollection")){ + rVal.createStateCollection(target); + } } return rVal; diff --git a/src/main/resources/server/ApplyStateCollection.java b/src/main/resources/server/ApplyStateCollection.java new file mode 100644 index 0000000..69163b1 --- /dev/null +++ b/src/main/resources/server/ApplyStateCollection.java @@ -0,0 +1,15 @@ +/** + *

Automatically generated

+ *

+ * Applies the state collection to the given entity + *

+ * @param entity The entity + * @param collection The state collection + */ +public static void applyStateCollection(Entity entity, StateCollection collection){ + for(SynchronizedFieldValue syncedValue : collection.getValues()){ + switch(syncedValue.getBehaviorTreeId()){ +REPLACE_0_ME + } + } +} \ No newline at end of file diff --git a/src/main/resources/server/GetStateCollection.java b/src/main/resources/server/GetStateCollection.java new file mode 100644 index 0000000..de3fc25 --- /dev/null +++ b/src/main/resources/server/GetStateCollection.java @@ -0,0 +1,17 @@ +/** + *

Automatically generated

+ *

+ * Gets the state collection for the given entity + *

+ * @param entity The entity + * @return The state collection + */ +public static StateCollection getStateCollection(Entity entity){ + StateCollection collection = new StateCollection(); + for(int treeId : Globals.entityValueTrackingService.getEntityTrees(entity)){ + switch(treeId){ +REPLACE_0_ME + } + } + return collection; +} \ No newline at end of file