diff --git a/src/main/java/electrosphere/main/Main.java b/src/main/java/electrosphere/main/Main.java index 57b1cbc..7855d80 100644 --- a/src/main/java/electrosphere/main/Main.java +++ b/src/main/java/electrosphere/main/Main.java @@ -24,9 +24,17 @@ public class Main { public static int bTreeIterator = 0; + //controls whether to log operations or not + public static boolean LOG = true; + + //controls whether files are actually written to disk or not + public static boolean WRITE_TO_DISK = true; + //hard-coded white list files to always parse static final String[] ALWAYS_PARSED_CLASSES = new String[]{ - "ClientSynchronizationManager" + "ClientSynchronizationManager", + "BehaviorTreeIdEnums", + "FieldIdEnums", }; //maps the btree annotation "name" to an id @@ -35,9 +43,25 @@ public class Main { public static void main(String args[]){ List targets = getFilesToModify(topLevelFolderPathWindows + "/src/main/java/electrosphere"); ProjectStructure structure = new ProjectStructure(targets, new File(topLevelFolderPathWindows)); + + if(LOG){ + System.out.println("Parsing project"); + } structure.parseRichStructure(); + + + if(LOG){ + System.out.println("Generating code"); + } structure.generate(); + + + if(LOG){ + System.out.println("Writing files"); + } structure.writeFiles(); + + } /** diff --git a/src/main/java/electrosphere/main/codegen/ClientGen.java b/src/main/java/electrosphere/main/codegen/ClientGen.java index 0f73328..f2cadcb 100644 --- a/src/main/java/electrosphere/main/codegen/ClientGen.java +++ b/src/main/java/electrosphere/main/codegen/ClientGen.java @@ -65,7 +65,7 @@ public class ClientGen { if(target.getAnnotation().getStringValue("enumId") == null){ throw new Exception("Failed to parse enum because enumId is not set on the synchronized field annotation"); } - int enumId = Integer.parseInt(target.getAnnotation().getStringValue("enumId")); + // int enumId = Integer.parseInt(target.getAnnotation().getStringValue("enumId")); // //find enum in current file @@ -91,12 +91,12 @@ public class ClientGen { int endChar = enumToIntMapper.getEndPosition(); outputContent = outputContent.delete(startChar, endChar); int lineNumber = Utilities.getLineNumber(outputContent.toString(), startChar); - Utilities.insertIntoSource(outputContent, generateEnumToIntMapperCode(target,enumConstNames), lineNumber); + Utilities.insertIntoSource(outputContent, generateEnumToIntMapperCode(target,enumConstNames), lineNumber, 1); } else { //generate int positionJustBeforeClassEnd = targetFile.getSource().getEndPosition() - 1; int lineNumber = Utilities.getLineNumber(outputContent.toString(), positionJustBeforeClassEnd); - outputContent = Utilities.insertIntoSource(outputContent, generateEnumToIntMapperCode(target,enumConstNames), lineNumber); + outputContent = Utilities.insertIntoSource(outputContent, generateEnumToIntMapperCode(target,enumConstNames), lineNumber, 1); } // @@ -107,12 +107,12 @@ public class ClientGen { int endChar = intToEnumMapper.getEndPosition(); outputContent = outputContent.delete(startChar, endChar); int lineNumber = Utilities.getLineNumber(outputContent.toString(), startChar); - Utilities.insertIntoSource(outputContent, generateIntToEnumMapperCode(target,enumConstNames), lineNumber); + Utilities.insertIntoSource(outputContent, generateIntToEnumMapperCode(target,enumConstNames), lineNumber, 1); } else { //generate int positionJustBeforeClassEnd = targetFile.getSource().getEndPosition() - 1; int lineNumber = Utilities.getLineNumber(outputContent.toString(), positionJustBeforeClassEnd); - outputContent = Utilities.insertIntoSource(outputContent, generateIntToEnumMapperCode(target,enumConstNames), lineNumber); + outputContent = Utilities.insertIntoSource(outputContent, generateIntToEnumMapperCode(target,enumConstNames), lineNumber, 1); } } @@ -127,12 +127,12 @@ public class ClientGen { int endChar = setter.getEndPosition(); outputContent = outputContent.delete(startChar, endChar); int lineNumber = Utilities.getLineNumber(outputContent.toString(), startChar); - Utilities.insertIntoSource(outputContent, generateSetterCode(targetFile,target.getName(),target), lineNumber); + Utilities.insertIntoSource(outputContent, generateSetterCode(targetFile,target.getName(),target), lineNumber, 1); } else { //generate int positionJustBeforeClassEnd = targetFile.getSource().getEndPosition() - 1; int lineNumber = Utilities.getLineNumber(outputContent.toString(), positionJustBeforeClassEnd); - outputContent = Utilities.insertIntoSource(outputContent, generateSetterCode(targetFile,target.getName(),target), lineNumber); + outputContent = Utilities.insertIntoSource(outputContent, generateSetterCode(targetFile,target.getName(),target), lineNumber, 1); } } //message parser generation @@ -140,14 +140,14 @@ public class ClientGen { //generate int positionJustBeforeClassEnd = targetFile.getSource().getEndPosition() - 1; int lineNumber = Utilities.getLineNumber(outputContent.toString(), positionJustBeforeClassEnd); - outputContent = Utilities.insertIntoSource(outputContent, generateParseBTreeMessages(targetFile, targets), lineNumber); + outputContent = Utilities.insertIntoSource(outputContent, generateParseBTreeMessages(targetFile, targets), lineNumber, 1); } else { //regenerate int startChar = parseNetworkMessageFunction.getStartPosition(); int endChar = parseNetworkMessageFunction.getEndPosition(); outputContent = outputContent.delete(startChar, endChar); int lineNumber = Utilities.getLineNumber(outputContent.toString(), startChar); - Utilities.insertIntoSource(outputContent, generateParseBTreeMessages(targetFile, targets), lineNumber); + Utilities.insertIntoSource(outputContent, generateParseBTreeMessages(targetFile, targets), lineNumber, 1); } // System.out.println(outputContent); diff --git a/src/main/java/electrosphere/main/codegen/ServerGen.java b/src/main/java/electrosphere/main/codegen/ServerGen.java index 6b7dddb..ded1f7a 100644 --- a/src/main/java/electrosphere/main/codegen/ServerGen.java +++ b/src/main/java/electrosphere/main/codegen/ServerGen.java @@ -74,7 +74,7 @@ public class ServerGen { if(target.getAnnotation().getStringValue("enumId") == null){ throw new Exception("Failed to parse enum because enumId is not set on the synchronized field annotation"); } - int enumId = Integer.parseInt(target.getAnnotation().getStringValue("enumId")); + // int enumId = Integer.parseInt(target.getAnnotation().getStringValue("enumId")); // //find enum in current file @@ -100,12 +100,12 @@ public class ServerGen { int endChar = enumToIntMapper.getEndPosition(); outputContent = outputContent.delete(startChar, endChar); int lineNumber = Utilities.getLineNumber(outputContent.toString(), startChar); - Utilities.insertIntoSource(outputContent, generateEnumToIntMapperCode(target,enumConstNames), lineNumber); + Utilities.insertIntoSource(outputContent, generateEnumToIntMapperCode(target,enumConstNames), lineNumber, 1); } else { //generate int positionJustBeforeClassEnd = targetFile.getSource().getEndPosition() - 1; int lineNumber = Utilities.getLineNumber(outputContent.toString(), positionJustBeforeClassEnd); - outputContent = Utilities.insertIntoSource(outputContent, generateEnumToIntMapperCode(target,enumConstNames), lineNumber); + outputContent = Utilities.insertIntoSource(outputContent, generateEnumToIntMapperCode(target,enumConstNames), lineNumber, 1); } // @@ -116,12 +116,12 @@ public class ServerGen { int endChar = intToEnumMapper.getEndPosition(); outputContent = outputContent.delete(startChar, endChar); int lineNumber = Utilities.getLineNumber(outputContent.toString(), startChar); - Utilities.insertIntoSource(outputContent, generateIntToEnumMapperCode(target,enumConstNames), lineNumber); + Utilities.insertIntoSource(outputContent, generateIntToEnumMapperCode(target,enumConstNames), lineNumber, 1); } else { //generate int positionJustBeforeClassEnd = targetFile.getSource().getEndPosition() - 1; int lineNumber = Utilities.getLineNumber(outputContent.toString(), positionJustBeforeClassEnd); - outputContent = Utilities.insertIntoSource(outputContent, generateIntToEnumMapperCode(target,enumConstNames), lineNumber); + outputContent = Utilities.insertIntoSource(outputContent, generateIntToEnumMapperCode(target,enumConstNames), lineNumber, 1); } } @@ -136,12 +136,12 @@ public class ServerGen { int endChar = setter.getEndPosition(); outputContent = outputContent.delete(startChar, endChar); int lineNumber = Utilities.getLineNumber(outputContent.toString(), startChar); - Utilities.insertIntoSource(outputContent, generateSetterCode(targetFile,target.getName(),target), lineNumber); + Utilities.insertIntoSource(outputContent, generateSetterCode(targetFile,target.getName(),target), lineNumber, 1); } else { //generate int positionJustBeforeClassEnd = targetFile.getSource().getEndPosition() - 1; int lineNumber = Utilities.getLineNumber(outputContent.toString(), positionJustBeforeClassEnd); - outputContent = Utilities.insertIntoSource(outputContent, generateSetterCode(targetFile,target.getName(),target), lineNumber); + outputContent = Utilities.insertIntoSource(outputContent, generateSetterCode(targetFile,target.getName(),target), lineNumber, 1); } } //create network message parser for incoming requests to change synchronized variables @@ -152,14 +152,14 @@ public class ServerGen { //generate int positionJustBeforeClassEnd = targetFile.getSource().getEndPosition() - 1; int lineNumber = Utilities.getLineNumber(outputContent.toString(), positionJustBeforeClassEnd); - outputContent = Utilities.insertIntoSource(outputContent, generateParseBTreeMessages(targetFile, targets), lineNumber); + outputContent = Utilities.insertIntoSource(outputContent, generateParseBTreeMessages(targetFile, targets), lineNumber, 1); } else { //regenerate int startChar = parseNetworkMessageFunction.getStartPosition(); int endChar = parseNetworkMessageFunction.getEndPosition(); outputContent = outputContent.delete(startChar, endChar); int lineNumber = Utilities.getLineNumber(outputContent.toString(), startChar); - Utilities.insertIntoSource(outputContent, generateParseBTreeMessages(targetFile, targets), lineNumber); + Utilities.insertIntoSource(outputContent, generateParseBTreeMessages(targetFile, targets), lineNumber, 1); } // diff --git a/src/main/java/electrosphere/main/structure/BehaviorTree.java b/src/main/java/electrosphere/main/structure/BehaviorTree.java index d4d4d82..0f94fa4 100644 --- a/src/main/java/electrosphere/main/structure/BehaviorTree.java +++ b/src/main/java/electrosphere/main/structure/BehaviorTree.java @@ -4,7 +4,6 @@ import java.util.List; import electrosphere.main.targets.TargetFile; import electrosphere.main.util.TemplateInjectionUtils; -import electrosphere.main.util.Utilities; /** * Represents a behavior tree in the source code @@ -126,6 +125,16 @@ public class BehaviorTree { return rVal; } + public String getConstructorMethodName(){ + String rVal = className; + return rVal; + } + + public String getConstructorMethodContent(){ + String rVal = TemplateInjectionUtils.getFragmentWithReplacement("/btree/Constructor.java", this.className); + return rVal; + } + diff --git a/src/main/java/electrosphere/main/structure/ClientSynchronizationManager.java b/src/main/java/electrosphere/main/structure/ClientSynchronizationManager.java index c1aad7f..61a1598 100644 --- a/src/main/java/electrosphere/main/structure/ClientSynchronizationManager.java +++ b/src/main/java/electrosphere/main/structure/ClientSynchronizationManager.java @@ -21,14 +21,15 @@ public class ClientSynchronizationManager { */ public static void update(ProjectStructure structure, TargetFile clientSynchronizationManager){ String updateCases = ""; - for(BehaviorTree tree : structure.behaviorTrees){ + for(BehaviorTree serverTree : structure.behaviorTrees){ //counterintuitively, want to only update client for server behavior tree ids - if(tree.isServer()){ - BehaviorTree clientEquivalent = structure.getTree(tree.correspondingTreeName); - updateCases = updateCases + " case BehaviorTreeIdEnums." + BTreeIdEnum.getTreeIdEnum(tree) + ": {\n"; + if(serverTree.isServer()){ + BehaviorTree clientEquivalent = structure.getTree(serverTree.correspondingTreeName); + updateCases = updateCases + " case BehaviorTreeIdEnums." + BTreeIdEnum.getTreeIdEnum(serverTree) + ": {\n"; updateCases = updateCases + " switch(message.getfieldId()){\n"; - for(SynchronizedField field : tree.synchronizedFields){ + for(SynchronizedField field : serverTree.synchronizedFields){ String treeName = clientEquivalent.getClassName(); + String fieldIdVariable = "TREE_" + serverTree.name.toUpperCase() + "_SYNCEDFIELD_" + field.fieldName.toUpperCase() + "_ID"; switch(field.typeName){ case "int": case "long": @@ -38,7 +39,7 @@ public class ClientSynchronizationManager { throw new UnsupportedOperationException("Trying to parse type that is not supported yet"); } case "String": { - updateCases = updateCases + " case " + field.id + ":{\n"; + updateCases = updateCases + " case FieldIdEnums." + fieldIdVariable + ":{\n"; updateCases = updateCases + " " + treeName + " tree = " + treeName + ".get" + treeName + "(entity);\n"; updateCases = updateCases + " tree." + field.getSetterName() + "(message.getstringValue());\n"; updateCases = updateCases + " } break;\n"; @@ -46,7 +47,7 @@ public class ClientSynchronizationManager { default: { SynchronizedType type = structure.getType(field.typeName); String typeClass = type.getTargetFile().getSource().getName(); - updateCases = updateCases + " case " + field.id + ":{\n"; + updateCases = updateCases + " case FieldIdEnums." + fieldIdVariable + ":{\n"; updateCases = updateCases + " " + treeName + " tree = " + treeName + ".get" + treeName + "(entity);\n"; updateCases = updateCases + " tree." + field.getSetterName() + "(" + typeClass + "." + type.getFromShortConversionMethodName() + "((short)message.getbTreeValue()));\n"; updateCases = updateCases + " } break;\n"; @@ -57,9 +58,11 @@ public class ClientSynchronizationManager { updateCases = updateCases + " } break;\n"; //guarantee import - ClassSourceUtils.importClass(structure, clientSynchronizationManager, tree.getTargetFile().getQualifiedPath()); + ClassSourceUtils.importClass(structure, clientSynchronizationManager, serverTree.getTargetFile().getQualifiedPath()); + ClassSourceUtils.importClass(structure, clientSynchronizationManager, structure.getTree(serverTree.correspondingTreeName).getTargetFile().getQualifiedPath()); } } + ClassSourceUtils.importClass(structure, clientSynchronizationManager, "electrosphere.net.synchronization.FieldIdEnums"); String fullReplacementText = TemplateInjectionUtils.getFragmentWithReplacement("/client/UpdateEntityState.java", updateCases); ClassSourceUtils.addOrReplaceMethod(structure, clientSynchronizationManager, "updateEntityState", fullReplacementText); } diff --git a/src/main/java/electrosphere/main/structure/FieldIdEnum.java b/src/main/java/electrosphere/main/structure/FieldIdEnum.java new file mode 100644 index 0000000..f705b4b --- /dev/null +++ b/src/main/java/electrosphere/main/structure/FieldIdEnum.java @@ -0,0 +1,75 @@ +package electrosphere.main.structure; + +import java.io.File; +import java.io.IOException; + +import com.google.common.io.Files; + +import electrosphere.main.util.ClassSourceUtils; + +/** + * A class that has an enum of all fields and their associated ids + */ +public class FieldIdEnum { + + + //The class name of this class + public static final String CLASSNAME = "FieldIdEnums"; + + //The location of the file + public static final String LOCATION = "src/main/java/electrosphere/net/synchronization/FieldIdEnums.java"; + + /** + * Gets the qualified path for the b tree id enum + * @param structure The project structure + * @return The qualified path + */ + public static String getQualifiedPath(ProjectStructure structure){ + File outFile = new File(structure.getRootFolder().getAbsolutePath()).toPath().resolve(LOCATION).toFile(); + return ClassSourceUtils.getPackageSourcePath(structure, outFile) + "." + CLASSNAME; + } + + /** + * Gets the import declaration for this class + * @param structure The project structure + * @return The import declaration + */ + public static String getImport(ProjectStructure structure){ + return "import " + getQualifiedPath(structure) + ";"; + } + + /** + * Generates a b tree id enum file + * @param structure The project structure + */ + public static void generate(ProjectStructure structure){ + + String source = ""; + File outFile = new File(structure.getRootFolder().getAbsolutePath()).toPath().resolve(LOCATION).toFile(); + source = source + ClassSourceUtils.getPackageDeclaration(structure, ClassSourceUtils.getPackageSourcePath(structure, outFile)); + source = source + "\n"; + source = source + ClassSourceUtils.generateClassHeader("FieldIdEnums", "List of enums of all fields and their associated ids.", true); + source = source + "\n"; + for(SynchronizedField field : structure.synchronizedFields){ + source = source + " public static final int " + getFieldIdEnum(field) + " = " + field.id + ";\n"; + } + source = source + "\n"; + source = source + ClassSourceUtils.generateClassEnd(); + try { + Files.write(source.getBytes(), outFile); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + /** + * Gets the enum name for this field + * @param tree the field + * @return the name + */ + public static String getFieldIdEnum(SynchronizedField field){ + return "TREE_" + field.parent.name.toUpperCase() + "_SYNCEDFIELD_" + field.fieldName.toUpperCase() + "_ID"; + } + +} diff --git a/src/main/java/electrosphere/main/structure/ProjectStructure.java b/src/main/java/electrosphere/main/structure/ProjectStructure.java index bad568a..02896d1 100644 --- a/src/main/java/electrosphere/main/structure/ProjectStructure.java +++ b/src/main/java/electrosphere/main/structure/ProjectStructure.java @@ -1,8 +1,11 @@ package electrosphere.main.structure; import java.io.File; +import java.util.Collection; +import java.util.HashMap; import java.util.LinkedList; import java.util.List; +import java.util.Map; import org.jboss.forge.roaster.model.source.AnnotationSource; import org.jboss.forge.roaster.model.source.EnumConstantSource; @@ -11,6 +14,7 @@ import org.jboss.forge.roaster.model.source.JavaClassSource; import org.jboss.forge.roaster.model.source.JavaEnumSource; import org.jboss.forge.roaster.model.source.JavaSource; +import electrosphere.main.Main; import electrosphere.main.targets.TargetFile; import electrosphere.main.util.ClassSourceUtils; @@ -38,6 +42,16 @@ public class ProjectStructure { //the client synchronization manager TargetFile clientSynchronizationManager; + //the file that has the enum of all behavior tree ids + TargetFile behaviorTreeIdEnums; + int behaviorTreeIdIterator = 0; //used to generate unique ids for new trees + Map existingTreeNameToIdMap; //the id map associated with the behaviorTreeIdEnums file + + //the file that contains the enum of all synced fields to their ids + TargetFile fieldIdEnums; + int fieldIdIterator = 0; //used to generate unique ids for new fields + Map existingFieldNameToIdMap; //the map of existing field names to their ids + /** * Constructor * @param targetFiles The target files to iterate on @@ -53,8 +67,6 @@ public class ProjectStructure { * Parses the target files in this project into rich data to generate off of */ public void parseRichStructure(){ - int behaviorTreeIdIterator = 0; - int synchronizedFieldIterator = 0; int typeIterator = 0; for(TargetFile target : targetFiles){ AnnotationSource mainAnnotation = target.getSource().getAnnotation("SynchronizedBehaviorTree"); @@ -73,10 +85,10 @@ public class ProjectStructure { if(syncAnnotation != null){ String fieldName = fieldSource.getName(); String typeName = fieldSource.getType().getName(); - SynchronizedField field = new SynchronizedField(synchronizedFieldIterator,fieldName,typeName,target); + int fieldId = getFieldId(bTreeName,fieldName); + SynchronizedField field = new SynchronizedField(fieldId,fieldName,typeName,target); this.synchronizedFields.add(field); syncedFields.add(field); - synchronizedFieldIterator++; } } @@ -98,7 +110,7 @@ public class ProjectStructure { } BehaviorTree newBehaviorTree = new BehaviorTree( - behaviorTreeIdIterator, + getBTreeId(bTreeName), bTreeName, target.getSource().getName(), bTreeCorrespondingName, @@ -107,7 +119,6 @@ public class ProjectStructure { target ); behaviorTrees.add(newBehaviorTree); - behaviorTreeIdIterator++; //push behavior tree to each field for(SynchronizedField field : syncedFields){ @@ -122,7 +133,21 @@ public class ProjectStructure { if(target.getName().contains("ClientSynchronizationManager")){ this.clientSynchronizationManager = target; } + + //currently defined behavior tree ids + //this is guaranteed to be parsed before the regular behavior trees that are discovered in the recursive file parser + if(target.getName().contains("BehaviorTreeIdEnums")){ + this.behaviorTreeIdEnums = target; + pushExistingTreeIds(); + } + + //class storing all current field's ids + if(target.getName().contains("FieldIdEnums")){ + this.fieldIdEnums = target; + pushExistingFieldIds(); + } } + } @@ -132,6 +157,9 @@ public class ProjectStructure { public void generate(){ //generate in-class functions for btrees for(BehaviorTree tree : behaviorTrees){ + if(Main.LOG){ + System.out.println("Generating for " + tree.className); + } //server side getter + setter if(tree.isServer){ @@ -145,9 +173,15 @@ public class ProjectStructure { ClassSourceUtils.addMethodIfAbsent(this, tree.getTargetFile(), tree.getAttachMethodName(), tree.getAttachMethodContent(true)); ClassSourceUtils.addOrReplaceMethod(this, tree.getTargetFile(), tree.getDetachMethodName(), tree.getDetachMethodContent(true)); //imports + ClassSourceUtils.importClass(this, tree.getTargetFile(), "electrosphere.engine.Globals"); ClassSourceUtils.importClass(this, tree.getTargetFile(), "electrosphere.server.datacell.utils.DataCellSearchUtils"); ClassSourceUtils.importClass(this, tree.getTargetFile(), "electrosphere.net.parser.net.message.SynchronizationMessage"); ClassSourceUtils.importClass(this, tree.getTargetFile(), "electrosphere.server.datacell.utils.ServerBehaviorTreeUtils"); + ClassSourceUtils.importClass(this, tree.getTargetFile(), "electrosphere.entity.Entity"); + ClassSourceUtils.importClass(this, tree.getTargetFile(), "electrosphere.entity.EntityDataStrings"); + ClassSourceUtils.importClass(this, tree.getTargetFile(), "electrosphere.entity.btree.BehaviorTree"); + ClassSourceUtils.importClass(this, tree.getTargetFile(), "electrosphere.net.synchronization.BehaviorTreeIdEnums"); + ClassSourceUtils.importClass(this, tree.getTargetFile(), "electrosphere.net.synchronization.FieldIdEnums"); } else { @@ -159,9 +193,17 @@ public class ProjectStructure { //attach + detatch methods ClassSourceUtils.addMethodIfAbsent(this, tree.getTargetFile(), tree.getAttachMethodName(), tree.getAttachMethodContent(false)); ClassSourceUtils.addOrReplaceMethod(this, tree.getTargetFile(), tree.getDetachMethodName(), tree.getDetachMethodContent(false)); + //imports + ClassSourceUtils.importClass(this, tree.getTargetFile(), "electrosphere.engine.Globals"); // for client scene wrapper + ClassSourceUtils.importClass(this, tree.getTargetFile(), "electrosphere.entity.Entity"); + ClassSourceUtils.importClass(this, tree.getTargetFile(), "electrosphere.entity.EntityDataStrings"); + ClassSourceUtils.importClass(this, tree.getTargetFile(), "electrosphere.entity.btree.BehaviorTree"); + ClassSourceUtils.importClass(this, tree.getTargetFile(), "electrosphere.net.synchronization.BehaviorTreeIdEnums"); } + //private constructor + ClassSourceUtils.addMethodIfAbsent(this, tree.getTargetFile(), tree.getConstructorMethodName(), tree.getConstructorMethodContent()); //guarantee entity fetch method ClassSourceUtils.addOrReplaceMethod(this, tree.getTargetFile(), tree.getEntityFetchMethodName(), tree.getEntityFetchMethodContent()); //guarantee imports of required files (btree enum, etc) @@ -174,6 +216,7 @@ public class ProjectStructure { ClassSourceUtils.addOrReplaceMethod(this, type.getTargetFile(), type.getFromShortConversionMethodName(), type.getFromShortConversionMethodContent()); } BTreeIdEnum.generate(this); + FieldIdEnum.generate(this); //client sync manager ClientSynchronizationManager.update(this, clientSynchronizationManager); } @@ -227,4 +270,73 @@ public class ProjectStructure { return null; } + /** + * Updates the behavior tree objects with the behavior tree ids that are already defined + */ + private void pushExistingTreeIds(){ + existingTreeNameToIdMap = new HashMap(); + for(FieldSource fieldSource : this.behaviorTreeIdEnums.getSource().getFields()){ + int value = Integer.parseInt(fieldSource.getLiteralInitializer()); + String fieldName = fieldSource.getName(); + String capitalizedBTreeName = fieldName.split("_")[1]; + existingTreeNameToIdMap.put(capitalizedBTreeName,value); + } + } + + /** + * Updates the field objects with the field ids that are already defined + */ + private void pushExistingFieldIds(){ + existingFieldNameToIdMap = new HashMap(); + if(this.fieldIdEnums != null){ + for(FieldSource fieldSource : this.fieldIdEnums.getSource().getFields()){ + int value = Integer.parseInt(fieldSource.getLiteralInitializer()); + String fieldName = fieldSource.getName(); + String capitalizedFieldName = fieldName.split("_")[1] + "_" + fieldName.split("_")[3]; + existingFieldNameToIdMap.put(capitalizedFieldName,value); + } + } + } + + /** + * Gets the id for a given btree + * @param bTreeName the name of the btree + * @return the id + */ + private int getBTreeId(String bTreeName){ + String capitalizedName = bTreeName.toUpperCase(); + if(existingTreeNameToIdMap.containsKey(capitalizedName)){ + return existingTreeNameToIdMap.get(capitalizedName); + } else { + Collection existingIds = existingTreeNameToIdMap.values(); + //increment ids until we hit an available one + while(existingIds.contains(behaviorTreeIdIterator)){ + behaviorTreeIdIterator++; + } + existingTreeNameToIdMap.put(capitalizedName,behaviorTreeIdIterator); + return behaviorTreeIdIterator; + } + } + + /** + * Gets the id for a given field + * @param bTreeName the name of the btree that the field is inside of + * @param fieldName the name of the field + * @return the id + */ + private int getFieldId(String bTreeName, String fieldName){ + String qualifiedName = bTreeName.toUpperCase() + "_" + fieldName.toUpperCase(); + if(existingFieldNameToIdMap.containsKey(qualifiedName)){ + return existingFieldNameToIdMap.get(qualifiedName); + } else { + Collection existingIds = existingFieldNameToIdMap.values(); + //increment ids until we hit an available one + while(existingIds.contains(fieldIdIterator)){ + fieldIdIterator++; + } + existingFieldNameToIdMap.put(qualifiedName,fieldIdIterator); + return fieldIdIterator; + } + } + } diff --git a/src/main/java/electrosphere/main/structure/SynchronizedField.java b/src/main/java/electrosphere/main/structure/SynchronizedField.java index 564836b..54720f9 100644 --- a/src/main/java/electrosphere/main/structure/SynchronizedField.java +++ b/src/main/java/electrosphere/main/structure/SynchronizedField.java @@ -71,6 +71,8 @@ public class SynchronizedField { public String getServerSetterContent(ProjectStructure structure){ String rVal = null; + String bTreeIdVariable = "BehaviorTreeIdEnums.BTREE_" + this.parent.name.toUpperCase() + "_ID"; + String fieldIdVariable = "FieldIdEnums.TREE_" + this.parent.name.toUpperCase() + "_SYNCEDFIELD_" + this.fieldName.toUpperCase() + "_ID"; switch(typeName){ case "int": case "long": @@ -80,13 +82,13 @@ public class SynchronizedField { throw new UnsupportedOperationException("Trying to parse type that is not supported yet"); } case "String": { - String packetContentFiller = " DataCellSearchUtils.getEntityDataCell(parent).broadcastNetworkMessage(SynchronizationMessage.constructUpdateClientStringStateMessage(parent.getId(), " + parent.id + ", " + id + ", " + fieldName + "));"; + String packetContentFiller = " DataCellSearchUtils.getEntityDataCell(parent).broadcastNetworkMessage(SynchronizationMessage.constructUpdateClientStringStateMessage(parent.getId(), " + bTreeIdVariable + ", " + fieldIdVariable + ", " + fieldName + "));"; rVal = TemplateInjectionUtils.getFragmentWithReplacement("/server/Setter.java", fieldName, Utilities.camelCase(fieldName), typeName, packetContentFiller); } break; default: { SynchronizedType type = structure.getType(typeName); String packetContentFiller = " int value = " + type.getContainingClassName() + "." + type.getToShortConversionMethodName() + "(" + fieldName + ");\n"; - packetContentFiller = packetContentFiller + " DataCellSearchUtils.getEntityDataCell(parent).broadcastNetworkMessage(SynchronizationMessage.constructUpdateClientStateMessage(parent.getId(), " + parent.id + ", " + id + ", value));"; + packetContentFiller = packetContentFiller + " DataCellSearchUtils.getEntityDataCell(parent).broadcastNetworkMessage(SynchronizationMessage.constructUpdateClientStateMessage(parent.getId(), " + bTreeIdVariable + ", " + fieldIdVariable + ", value));"; rVal = TemplateInjectionUtils.getFragmentWithReplacement("/server/Setter.java", fieldName, Utilities.camelCase(fieldName), typeName, packetContentFiller); } break; } diff --git a/src/main/java/electrosphere/main/targets/TargetFile.java b/src/main/java/electrosphere/main/targets/TargetFile.java index 831995e..dbfa5d6 100644 --- a/src/main/java/electrosphere/main/targets/TargetFile.java +++ b/src/main/java/electrosphere/main/targets/TargetFile.java @@ -113,7 +113,9 @@ public class TargetFile { */ public void write(){ try { - Files.write(this.modifiedContent.toString().getBytes(), new File(this.path)); + if(Main.WRITE_TO_DISK){ + Files.write(this.modifiedContent.toString().getBytes(), new File(this.path)); + } } catch (IOException e) { e.printStackTrace(); } diff --git a/src/main/java/electrosphere/main/util/ClassSourceUtils.java b/src/main/java/electrosphere/main/util/ClassSourceUtils.java index 6593864..14a343d 100644 --- a/src/main/java/electrosphere/main/util/ClassSourceUtils.java +++ b/src/main/java/electrosphere/main/util/ClassSourceUtils.java @@ -7,8 +7,6 @@ import org.jboss.forge.roaster.model.source.Import; import org.jboss.forge.roaster.model.source.JavaClassSource; import org.jboss.forge.roaster.model.source.MethodSource; -import electrosphere.main.structure.BTreeIdEnum; -import electrosphere.main.structure.BehaviorTree; import electrosphere.main.structure.ProjectStructure; import electrosphere.main.targets.TargetFile; @@ -45,7 +43,7 @@ public class ClassSourceUtils { int endOfClass = findEndOfClass(modifiedContent.toString()); String indentedFragment = TemplateInjectionUtils.indentFragment(methodContent, DEFAULT_INDENT); //must newline - String finalInsertion = indentedFragment + "\n"; + String finalInsertion = indentedFragment + "\n\n"; modifiedContent.insert(endOfClass, finalInsertion); } else { //methodStart is literally the first character of the function's name @@ -83,7 +81,7 @@ public class ClassSourceUtils { int endOfClass = findEndOfClass(modifiedContent.toString()); String indentedFragment = TemplateInjectionUtils.indentFragment(methodContent, DEFAULT_INDENT); //must newline - String finalInsertion = indentedFragment + "\n"; + String finalInsertion = indentedFragment + "\n\n"; modifiedContent.insert(endOfClass, finalInsertion); targetFile.setModifiedContent(modifiedContent.toString()); targetFile.reparse(); @@ -192,7 +190,7 @@ public class ClassSourceUtils { } } if(!present){ - Utilities.insertIntoSource(modifiedContent, "import " + qualifiedPath + ";", 3); + Utilities.insertIntoSource(modifiedContent, "import " + qualifiedPath + ";", 3, 0); targetFile.setModifiedContent(modifiedContent.toString()); } } diff --git a/src/main/java/electrosphere/main/util/TemplateInjectionUtils.java b/src/main/java/electrosphere/main/util/TemplateInjectionUtils.java index 24b5578..27c72d4 100644 --- a/src/main/java/electrosphere/main/util/TemplateInjectionUtils.java +++ b/src/main/java/electrosphere/main/util/TemplateInjectionUtils.java @@ -4,8 +4,6 @@ import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; -import com.sun.tools.javac.Main; - /** * Tools for taking files that represent source file fragments and injecting strings to replace portions of the fragment */ diff --git a/src/main/java/electrosphere/main/util/Utilities.java b/src/main/java/electrosphere/main/util/Utilities.java index bbf4448..4b2307f 100644 --- a/src/main/java/electrosphere/main/util/Utilities.java +++ b/src/main/java/electrosphere/main/util/Utilities.java @@ -7,8 +7,6 @@ import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.util.Arrays; -import java.util.LinkedList; -import java.util.List; import java.util.concurrent.TimeUnit; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -81,7 +79,7 @@ public class Utilities { * @param lineNumber The line number * @return The combined string */ - public static StringBuilder insertIntoSource(StringBuilder source, String insertion, int lineNumber){ + public static StringBuilder insertIntoSource(StringBuilder source, String insertion, int lineNumber, int numLinesBetweenEntries){ //find the position in the source string of the line number int newLinesEncountered = 0; int characterPosition = 0; @@ -118,7 +116,10 @@ public class Utilities { for(int i = 0; i < lines.length; i++){ lines[i] = spaceString + lines[i]; } - String spacedInsertion = "\n" + Arrays.stream(lines).collect(Collectors.joining("\n")) + "\n" + spaceString + "\n" + spaceString; + String spacedInsertion = "\n" + Arrays.stream(lines).collect(Collectors.joining("\n")) + "\n" + spaceString; + for(int i = 0; i < numLinesBetweenEntries; i++){ + spacedInsertion = spacedInsertion + "\n" + spaceString; + } System.out.println("\"" + spacedInsertion + "\""); //insert into source file source.insert(characterToInsertAt, spacedInsertion); diff --git a/src/main/resources/btree/Constructor.java b/src/main/resources/btree/Constructor.java new file mode 100644 index 0000000..039343e --- /dev/null +++ b/src/main/resources/btree/Constructor.java @@ -0,0 +1,11 @@ +/** + *

(initially) Automatically generated

+ *

Private constructor to enforce using the attach methods

+ *

+ * Constructor + *

+ * @param parent The parent entity of this tree + */ +public REPLACE_0_ME(Entity parent){ + this.parent = parent; +} \ No newline at end of file diff --git a/src/main/resources/client/AttachBTree.java b/src/main/resources/client/AttachBTree.java index d46c1fe..95a6eaf 100644 --- a/src/main/resources/client/AttachBTree.java +++ b/src/main/resources/client/AttachBTree.java @@ -15,7 +15,7 @@ public static REPLACE_2_ME attachTree(Entity parent){ //!!WARNING!! from here below should not be touched //This was generated automatically to properly alert various systems that the btree exists and should be tracked parent.putData(EntityDataStrings.REPLACE_1_ME, rVal); - Globals.clientScene.registerBehaviorTree(rVal); + Globals.clientSceneWrapper.getScene().registerBehaviorTree(rVal); Globals.entityValueTrackingService.attachTreeToEntity(parent, BehaviorTreeIdEnums.BTREE_REPLACE_0_ME_ID); return rVal; } \ No newline at end of file