id persistence, formatting fixes, etc

This commit is contained in:
austin 2024-06-18 20:56:37 -04:00
parent 71a4d91497
commit f1f4375578
14 changed files with 284 additions and 49 deletions

View File

@ -24,9 +24,17 @@ public class Main {
public static int bTreeIterator = 0; 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 //hard-coded white list files to always parse
static final String[] ALWAYS_PARSED_CLASSES = new String[]{ static final String[] ALWAYS_PARSED_CLASSES = new String[]{
"ClientSynchronizationManager" "ClientSynchronizationManager",
"BehaviorTreeIdEnums",
"FieldIdEnums",
}; };
//maps the btree annotation "name" to an id //maps the btree annotation "name" to an id
@ -35,9 +43,25 @@ public class Main {
public static void main(String args[]){ public static void main(String args[]){
List<TargetFile> targets = getFilesToModify(topLevelFolderPathWindows + "/src/main/java/electrosphere"); List<TargetFile> targets = getFilesToModify(topLevelFolderPathWindows + "/src/main/java/electrosphere");
ProjectStructure structure = new ProjectStructure(targets, new File(topLevelFolderPathWindows)); ProjectStructure structure = new ProjectStructure(targets, new File(topLevelFolderPathWindows));
if(LOG){
System.out.println("Parsing project");
}
structure.parseRichStructure(); structure.parseRichStructure();
if(LOG){
System.out.println("Generating code");
}
structure.generate(); structure.generate();
if(LOG){
System.out.println("Writing files");
}
structure.writeFiles(); structure.writeFiles();
} }
/** /**

View File

@ -65,7 +65,7 @@ public class ClientGen {
if(target.getAnnotation().getStringValue("enumId") == null){ if(target.getAnnotation().getStringValue("enumId") == null){
throw new Exception("Failed to parse enum because enumId is not set on the synchronized field annotation"); 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 //find enum in current file
@ -91,12 +91,12 @@ public class ClientGen {
int endChar = enumToIntMapper.getEndPosition(); int endChar = enumToIntMapper.getEndPosition();
outputContent = outputContent.delete(startChar, endChar); outputContent = outputContent.delete(startChar, endChar);
int lineNumber = Utilities.getLineNumber(outputContent.toString(), startChar); int lineNumber = Utilities.getLineNumber(outputContent.toString(), startChar);
Utilities.insertIntoSource(outputContent, generateEnumToIntMapperCode(target,enumConstNames), lineNumber); Utilities.insertIntoSource(outputContent, generateEnumToIntMapperCode(target,enumConstNames), lineNumber, 1);
} else { } else {
//generate //generate
int positionJustBeforeClassEnd = targetFile.getSource().getEndPosition() - 1; int positionJustBeforeClassEnd = targetFile.getSource().getEndPosition() - 1;
int lineNumber = Utilities.getLineNumber(outputContent.toString(), positionJustBeforeClassEnd); 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(); int endChar = intToEnumMapper.getEndPosition();
outputContent = outputContent.delete(startChar, endChar); outputContent = outputContent.delete(startChar, endChar);
int lineNumber = Utilities.getLineNumber(outputContent.toString(), startChar); int lineNumber = Utilities.getLineNumber(outputContent.toString(), startChar);
Utilities.insertIntoSource(outputContent, generateIntToEnumMapperCode(target,enumConstNames), lineNumber); Utilities.insertIntoSource(outputContent, generateIntToEnumMapperCode(target,enumConstNames), lineNumber, 1);
} else { } else {
//generate //generate
int positionJustBeforeClassEnd = targetFile.getSource().getEndPosition() - 1; int positionJustBeforeClassEnd = targetFile.getSource().getEndPosition() - 1;
int lineNumber = Utilities.getLineNumber(outputContent.toString(), positionJustBeforeClassEnd); 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(); int endChar = setter.getEndPosition();
outputContent = outputContent.delete(startChar, endChar); outputContent = outputContent.delete(startChar, endChar);
int lineNumber = Utilities.getLineNumber(outputContent.toString(), startChar); 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 { } else {
//generate //generate
int positionJustBeforeClassEnd = targetFile.getSource().getEndPosition() - 1; int positionJustBeforeClassEnd = targetFile.getSource().getEndPosition() - 1;
int lineNumber = Utilities.getLineNumber(outputContent.toString(), positionJustBeforeClassEnd); 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 //message parser generation
@ -140,14 +140,14 @@ public class ClientGen {
//generate //generate
int positionJustBeforeClassEnd = targetFile.getSource().getEndPosition() - 1; int positionJustBeforeClassEnd = targetFile.getSource().getEndPosition() - 1;
int lineNumber = Utilities.getLineNumber(outputContent.toString(), positionJustBeforeClassEnd); 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 { } else {
//regenerate //regenerate
int startChar = parseNetworkMessageFunction.getStartPosition(); int startChar = parseNetworkMessageFunction.getStartPosition();
int endChar = parseNetworkMessageFunction.getEndPosition(); int endChar = parseNetworkMessageFunction.getEndPosition();
outputContent = outputContent.delete(startChar, endChar); outputContent = outputContent.delete(startChar, endChar);
int lineNumber = Utilities.getLineNumber(outputContent.toString(), startChar); 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); // System.out.println(outputContent);

View File

@ -74,7 +74,7 @@ public class ServerGen {
if(target.getAnnotation().getStringValue("enumId") == null){ if(target.getAnnotation().getStringValue("enumId") == null){
throw new Exception("Failed to parse enum because enumId is not set on the synchronized field annotation"); 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 //find enum in current file
@ -100,12 +100,12 @@ public class ServerGen {
int endChar = enumToIntMapper.getEndPosition(); int endChar = enumToIntMapper.getEndPosition();
outputContent = outputContent.delete(startChar, endChar); outputContent = outputContent.delete(startChar, endChar);
int lineNumber = Utilities.getLineNumber(outputContent.toString(), startChar); int lineNumber = Utilities.getLineNumber(outputContent.toString(), startChar);
Utilities.insertIntoSource(outputContent, generateEnumToIntMapperCode(target,enumConstNames), lineNumber); Utilities.insertIntoSource(outputContent, generateEnumToIntMapperCode(target,enumConstNames), lineNumber, 1);
} else { } else {
//generate //generate
int positionJustBeforeClassEnd = targetFile.getSource().getEndPosition() - 1; int positionJustBeforeClassEnd = targetFile.getSource().getEndPosition() - 1;
int lineNumber = Utilities.getLineNumber(outputContent.toString(), positionJustBeforeClassEnd); 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(); int endChar = intToEnumMapper.getEndPosition();
outputContent = outputContent.delete(startChar, endChar); outputContent = outputContent.delete(startChar, endChar);
int lineNumber = Utilities.getLineNumber(outputContent.toString(), startChar); int lineNumber = Utilities.getLineNumber(outputContent.toString(), startChar);
Utilities.insertIntoSource(outputContent, generateIntToEnumMapperCode(target,enumConstNames), lineNumber); Utilities.insertIntoSource(outputContent, generateIntToEnumMapperCode(target,enumConstNames), lineNumber, 1);
} else { } else {
//generate //generate
int positionJustBeforeClassEnd = targetFile.getSource().getEndPosition() - 1; int positionJustBeforeClassEnd = targetFile.getSource().getEndPosition() - 1;
int lineNumber = Utilities.getLineNumber(outputContent.toString(), positionJustBeforeClassEnd); 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(); int endChar = setter.getEndPosition();
outputContent = outputContent.delete(startChar, endChar); outputContent = outputContent.delete(startChar, endChar);
int lineNumber = Utilities.getLineNumber(outputContent.toString(), startChar); 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 { } else {
//generate //generate
int positionJustBeforeClassEnd = targetFile.getSource().getEndPosition() - 1; int positionJustBeforeClassEnd = targetFile.getSource().getEndPosition() - 1;
int lineNumber = Utilities.getLineNumber(outputContent.toString(), positionJustBeforeClassEnd); 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 //create network message parser for incoming requests to change synchronized variables
@ -152,14 +152,14 @@ public class ServerGen {
//generate //generate
int positionJustBeforeClassEnd = targetFile.getSource().getEndPosition() - 1; int positionJustBeforeClassEnd = targetFile.getSource().getEndPosition() - 1;
int lineNumber = Utilities.getLineNumber(outputContent.toString(), positionJustBeforeClassEnd); 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 { } else {
//regenerate //regenerate
int startChar = parseNetworkMessageFunction.getStartPosition(); int startChar = parseNetworkMessageFunction.getStartPosition();
int endChar = parseNetworkMessageFunction.getEndPosition(); int endChar = parseNetworkMessageFunction.getEndPosition();
outputContent = outputContent.delete(startChar, endChar); outputContent = outputContent.delete(startChar, endChar);
int lineNumber = Utilities.getLineNumber(outputContent.toString(), startChar); int lineNumber = Utilities.getLineNumber(outputContent.toString(), startChar);
Utilities.insertIntoSource(outputContent, generateParseBTreeMessages(targetFile, targets), lineNumber); Utilities.insertIntoSource(outputContent, generateParseBTreeMessages(targetFile, targets), lineNumber, 1);
} }
// //

View File

@ -4,7 +4,6 @@ import java.util.List;
import electrosphere.main.targets.TargetFile; import electrosphere.main.targets.TargetFile;
import electrosphere.main.util.TemplateInjectionUtils; import electrosphere.main.util.TemplateInjectionUtils;
import electrosphere.main.util.Utilities;
/** /**
* Represents a behavior tree in the source code * Represents a behavior tree in the source code
@ -126,6 +125,16 @@ public class BehaviorTree {
return rVal; return rVal;
} }
public String getConstructorMethodName(){
String rVal = className;
return rVal;
}
public String getConstructorMethodContent(){
String rVal = TemplateInjectionUtils.getFragmentWithReplacement("/btree/Constructor.java", this.className);
return rVal;
}

View File

@ -21,14 +21,15 @@ public class ClientSynchronizationManager {
*/ */
public static void update(ProjectStructure structure, TargetFile clientSynchronizationManager){ public static void update(ProjectStructure structure, TargetFile clientSynchronizationManager){
String updateCases = ""; String updateCases = "";
for(BehaviorTree tree : structure.behaviorTrees){ for(BehaviorTree serverTree : structure.behaviorTrees){
//counterintuitively, want to only update client for server behavior tree ids //counterintuitively, want to only update client for server behavior tree ids
if(tree.isServer()){ if(serverTree.isServer()){
BehaviorTree clientEquivalent = structure.getTree(tree.correspondingTreeName); BehaviorTree clientEquivalent = structure.getTree(serverTree.correspondingTreeName);
updateCases = updateCases + " case BehaviorTreeIdEnums." + BTreeIdEnum.getTreeIdEnum(tree) + ": {\n"; updateCases = updateCases + " case BehaviorTreeIdEnums." + BTreeIdEnum.getTreeIdEnum(serverTree) + ": {\n";
updateCases = updateCases + " switch(message.getfieldId()){\n"; updateCases = updateCases + " switch(message.getfieldId()){\n";
for(SynchronizedField field : tree.synchronizedFields){ for(SynchronizedField field : serverTree.synchronizedFields){
String treeName = clientEquivalent.getClassName(); String treeName = clientEquivalent.getClassName();
String fieldIdVariable = "TREE_" + serverTree.name.toUpperCase() + "_SYNCEDFIELD_" + field.fieldName.toUpperCase() + "_ID";
switch(field.typeName){ switch(field.typeName){
case "int": case "int":
case "long": case "long":
@ -38,7 +39,7 @@ public class ClientSynchronizationManager {
throw new UnsupportedOperationException("Trying to parse type that is not supported yet"); throw new UnsupportedOperationException("Trying to parse type that is not supported yet");
} }
case "String": { 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 + " " + treeName + " tree = " + treeName + ".get" + treeName + "(entity);\n";
updateCases = updateCases + " tree." + field.getSetterName() + "(message.getstringValue());\n"; updateCases = updateCases + " tree." + field.getSetterName() + "(message.getstringValue());\n";
updateCases = updateCases + " } break;\n"; updateCases = updateCases + " } break;\n";
@ -46,7 +47,7 @@ public class ClientSynchronizationManager {
default: { default: {
SynchronizedType type = structure.getType(field.typeName); SynchronizedType type = structure.getType(field.typeName);
String typeClass = type.getTargetFile().getSource().getName(); 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 + " " + treeName + " tree = " + treeName + ".get" + treeName + "(entity);\n";
updateCases = updateCases + " tree." + field.getSetterName() + "(" + typeClass + "." + type.getFromShortConversionMethodName() + "((short)message.getbTreeValue()));\n"; updateCases = updateCases + " tree." + field.getSetterName() + "(" + typeClass + "." + type.getFromShortConversionMethodName() + "((short)message.getbTreeValue()));\n";
updateCases = updateCases + " } break;\n"; updateCases = updateCases + " } break;\n";
@ -57,9 +58,11 @@ public class ClientSynchronizationManager {
updateCases = updateCases + " } break;\n"; updateCases = updateCases + " } break;\n";
//guarantee import //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); String fullReplacementText = TemplateInjectionUtils.getFragmentWithReplacement("/client/UpdateEntityState.java", updateCases);
ClassSourceUtils.addOrReplaceMethod(structure, clientSynchronizationManager, "updateEntityState", fullReplacementText); ClassSourceUtils.addOrReplaceMethod(structure, clientSynchronizationManager, "updateEntityState", fullReplacementText);
} }

View File

@ -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";
}
}

View File

@ -1,8 +1,11 @@
package electrosphere.main.structure; package electrosphere.main.structure;
import java.io.File; import java.io.File;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Map;
import org.jboss.forge.roaster.model.source.AnnotationSource; import org.jboss.forge.roaster.model.source.AnnotationSource;
import org.jboss.forge.roaster.model.source.EnumConstantSource; 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.JavaEnumSource;
import org.jboss.forge.roaster.model.source.JavaSource; import org.jboss.forge.roaster.model.source.JavaSource;
import electrosphere.main.Main;
import electrosphere.main.targets.TargetFile; import electrosphere.main.targets.TargetFile;
import electrosphere.main.util.ClassSourceUtils; import electrosphere.main.util.ClassSourceUtils;
@ -38,6 +42,16 @@ public class ProjectStructure {
//the client synchronization manager //the client synchronization manager
TargetFile clientSynchronizationManager; 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<String,Integer> 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<String,Integer> existingFieldNameToIdMap; //the map of existing field names to their ids
/** /**
* Constructor * Constructor
* @param targetFiles The target files to iterate on * @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 * Parses the target files in this project into rich data to generate off of
*/ */
public void parseRichStructure(){ public void parseRichStructure(){
int behaviorTreeIdIterator = 0;
int synchronizedFieldIterator = 0;
int typeIterator = 0; int typeIterator = 0;
for(TargetFile target : targetFiles){ for(TargetFile target : targetFiles){
AnnotationSource<JavaClassSource> mainAnnotation = target.getSource().getAnnotation("SynchronizedBehaviorTree"); AnnotationSource<JavaClassSource> mainAnnotation = target.getSource().getAnnotation("SynchronizedBehaviorTree");
@ -73,10 +85,10 @@ public class ProjectStructure {
if(syncAnnotation != null){ if(syncAnnotation != null){
String fieldName = fieldSource.getName(); String fieldName = fieldSource.getName();
String typeName = fieldSource.getType().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); this.synchronizedFields.add(field);
syncedFields.add(field); syncedFields.add(field);
synchronizedFieldIterator++;
} }
} }
@ -98,7 +110,7 @@ public class ProjectStructure {
} }
BehaviorTree newBehaviorTree = new BehaviorTree( BehaviorTree newBehaviorTree = new BehaviorTree(
behaviorTreeIdIterator, getBTreeId(bTreeName),
bTreeName, bTreeName,
target.getSource().getName(), target.getSource().getName(),
bTreeCorrespondingName, bTreeCorrespondingName,
@ -107,7 +119,6 @@ public class ProjectStructure {
target target
); );
behaviorTrees.add(newBehaviorTree); behaviorTrees.add(newBehaviorTree);
behaviorTreeIdIterator++;
//push behavior tree to each field //push behavior tree to each field
for(SynchronizedField field : syncedFields){ for(SynchronizedField field : syncedFields){
@ -122,7 +133,21 @@ public class ProjectStructure {
if(target.getName().contains("ClientSynchronizationManager")){ if(target.getName().contains("ClientSynchronizationManager")){
this.clientSynchronizationManager = target; 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(){ public void generate(){
//generate in-class functions for btrees //generate in-class functions for btrees
for(BehaviorTree tree : behaviorTrees){ for(BehaviorTree tree : behaviorTrees){
if(Main.LOG){
System.out.println("Generating for " + tree.className);
}
//server side getter + setter //server side getter + setter
if(tree.isServer){ if(tree.isServer){
@ -145,9 +173,15 @@ public class ProjectStructure {
ClassSourceUtils.addMethodIfAbsent(this, tree.getTargetFile(), tree.getAttachMethodName(), tree.getAttachMethodContent(true)); ClassSourceUtils.addMethodIfAbsent(this, tree.getTargetFile(), tree.getAttachMethodName(), tree.getAttachMethodContent(true));
ClassSourceUtils.addOrReplaceMethod(this, tree.getTargetFile(), tree.getDetachMethodName(), tree.getDetachMethodContent(true)); ClassSourceUtils.addOrReplaceMethod(this, tree.getTargetFile(), tree.getDetachMethodName(), tree.getDetachMethodContent(true));
//imports //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.server.datacell.utils.DataCellSearchUtils");
ClassSourceUtils.importClass(this, tree.getTargetFile(), "electrosphere.net.parser.net.message.SynchronizationMessage"); 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.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 { } else {
@ -159,9 +193,17 @@ public class ProjectStructure {
//attach + detatch methods //attach + detatch methods
ClassSourceUtils.addMethodIfAbsent(this, tree.getTargetFile(), tree.getAttachMethodName(), tree.getAttachMethodContent(false)); ClassSourceUtils.addMethodIfAbsent(this, tree.getTargetFile(), tree.getAttachMethodName(), tree.getAttachMethodContent(false));
ClassSourceUtils.addOrReplaceMethod(this, tree.getTargetFile(), tree.getDetachMethodName(), tree.getDetachMethodContent(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 //guarantee entity fetch method
ClassSourceUtils.addOrReplaceMethod(this, tree.getTargetFile(), tree.getEntityFetchMethodName(), tree.getEntityFetchMethodContent()); ClassSourceUtils.addOrReplaceMethod(this, tree.getTargetFile(), tree.getEntityFetchMethodName(), tree.getEntityFetchMethodContent());
//guarantee imports of required files (btree enum, etc) //guarantee imports of required files (btree enum, etc)
@ -174,6 +216,7 @@ public class ProjectStructure {
ClassSourceUtils.addOrReplaceMethod(this, type.getTargetFile(), type.getFromShortConversionMethodName(), type.getFromShortConversionMethodContent()); ClassSourceUtils.addOrReplaceMethod(this, type.getTargetFile(), type.getFromShortConversionMethodName(), type.getFromShortConversionMethodContent());
} }
BTreeIdEnum.generate(this); BTreeIdEnum.generate(this);
FieldIdEnum.generate(this);
//client sync manager //client sync manager
ClientSynchronizationManager.update(this, clientSynchronizationManager); ClientSynchronizationManager.update(this, clientSynchronizationManager);
} }
@ -227,4 +270,73 @@ public class ProjectStructure {
return null; return null;
} }
/**
* Updates the behavior tree objects with the behavior tree ids that are already defined
*/
private void pushExistingTreeIds(){
existingTreeNameToIdMap = new HashMap<String,Integer>();
for(FieldSource<JavaClassSource> 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<String,Integer>();
if(this.fieldIdEnums != null){
for(FieldSource<JavaClassSource> 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<Integer> 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<Integer> existingIds = existingFieldNameToIdMap.values();
//increment ids until we hit an available one
while(existingIds.contains(fieldIdIterator)){
fieldIdIterator++;
}
existingFieldNameToIdMap.put(qualifiedName,fieldIdIterator);
return fieldIdIterator;
}
}
} }

View File

@ -71,6 +71,8 @@ public class SynchronizedField {
public String getServerSetterContent(ProjectStructure structure){ public String getServerSetterContent(ProjectStructure structure){
String rVal = null; 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){ switch(typeName){
case "int": case "int":
case "long": case "long":
@ -80,13 +82,13 @@ public class SynchronizedField {
throw new UnsupportedOperationException("Trying to parse type that is not supported yet"); throw new UnsupportedOperationException("Trying to parse type that is not supported yet");
} }
case "String": { 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); rVal = TemplateInjectionUtils.getFragmentWithReplacement("/server/Setter.java", fieldName, Utilities.camelCase(fieldName), typeName, packetContentFiller);
} break; } break;
default: { default: {
SynchronizedType type = structure.getType(typeName); SynchronizedType type = structure.getType(typeName);
String packetContentFiller = " int value = " + type.getContainingClassName() + "." + type.getToShortConversionMethodName() + "(" + fieldName + ");\n"; 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); rVal = TemplateInjectionUtils.getFragmentWithReplacement("/server/Setter.java", fieldName, Utilities.camelCase(fieldName), typeName, packetContentFiller);
} break; } break;
} }

View File

@ -113,7 +113,9 @@ public class TargetFile {
*/ */
public void write(){ public void write(){
try { 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) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} }

View File

@ -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.JavaClassSource;
import org.jboss.forge.roaster.model.source.MethodSource; 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.structure.ProjectStructure;
import electrosphere.main.targets.TargetFile; import electrosphere.main.targets.TargetFile;
@ -45,7 +43,7 @@ public class ClassSourceUtils {
int endOfClass = findEndOfClass(modifiedContent.toString()); int endOfClass = findEndOfClass(modifiedContent.toString());
String indentedFragment = TemplateInjectionUtils.indentFragment(methodContent, DEFAULT_INDENT); String indentedFragment = TemplateInjectionUtils.indentFragment(methodContent, DEFAULT_INDENT);
//must newline //must newline
String finalInsertion = indentedFragment + "\n"; String finalInsertion = indentedFragment + "\n\n";
modifiedContent.insert(endOfClass, finalInsertion); modifiedContent.insert(endOfClass, finalInsertion);
} else { } else {
//methodStart is literally the first character of the function's name //methodStart is literally the first character of the function's name
@ -83,7 +81,7 @@ public class ClassSourceUtils {
int endOfClass = findEndOfClass(modifiedContent.toString()); int endOfClass = findEndOfClass(modifiedContent.toString());
String indentedFragment = TemplateInjectionUtils.indentFragment(methodContent, DEFAULT_INDENT); String indentedFragment = TemplateInjectionUtils.indentFragment(methodContent, DEFAULT_INDENT);
//must newline //must newline
String finalInsertion = indentedFragment + "\n"; String finalInsertion = indentedFragment + "\n\n";
modifiedContent.insert(endOfClass, finalInsertion); modifiedContent.insert(endOfClass, finalInsertion);
targetFile.setModifiedContent(modifiedContent.toString()); targetFile.setModifiedContent(modifiedContent.toString());
targetFile.reparse(); targetFile.reparse();
@ -192,7 +190,7 @@ public class ClassSourceUtils {
} }
} }
if(!present){ if(!present){
Utilities.insertIntoSource(modifiedContent, "import " + qualifiedPath + ";", 3); Utilities.insertIntoSource(modifiedContent, "import " + qualifiedPath + ";", 3, 0);
targetFile.setModifiedContent(modifiedContent.toString()); targetFile.setModifiedContent(modifiedContent.toString());
} }
} }

View File

@ -4,8 +4,6 @@ import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.stream.Collectors; 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 * Tools for taking files that represent source file fragments and injecting strings to replace portions of the fragment
*/ */

View File

@ -7,8 +7,6 @@ import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.util.Arrays; import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
@ -81,7 +79,7 @@ public class Utilities {
* @param lineNumber The line number * @param lineNumber The line number
* @return The combined string * @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 //find the position in the source string of the line number
int newLinesEncountered = 0; int newLinesEncountered = 0;
int characterPosition = 0; int characterPosition = 0;
@ -118,7 +116,10 @@ public class Utilities {
for(int i = 0; i < lines.length; i++){ for(int i = 0; i < lines.length; i++){
lines[i] = spaceString + lines[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 + "\""); System.out.println("\"" + spacedInsertion + "\"");
//insert into source file //insert into source file
source.insert(characterToInsertAt, spacedInsertion); source.insert(characterToInsertAt, spacedInsertion);

View File

@ -0,0 +1,11 @@
/**
* <p> (initially) Automatically generated </p>
* <p> Private constructor to enforce using the attach methods </p>
* <p>
* Constructor
* </p>
* @param parent The parent entity of this tree
*/
public REPLACE_0_ME(Entity parent){
this.parent = parent;
}

View File

@ -15,7 +15,7 @@ public static REPLACE_2_ME attachTree(Entity parent){
//!!WARNING!! from here below should not be touched //!!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 //This was generated automatically to properly alert various systems that the btree exists and should be tracked
parent.putData(EntityDataStrings.REPLACE_1_ME, rVal); 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); Globals.entityValueTrackingService.attachTreeToEntity(parent, BehaviorTreeIdEnums.BTREE_REPLACE_0_ME_ID);
return rVal; return rVal;
} }