This commit is contained in:
Anuken
2026-02-20 16:19:39 -05:00
parent 74b9589eb6
commit 76dc529d23

View File

@@ -35,6 +35,7 @@ public class DataPatcher{
private ObjectSet<Object> usedpatches = new ObjectSet<>(); private ObjectSet<Object> usedpatches = new ObjectSet<>();
private Seq<Runnable> resetters = new Seq<>(); private Seq<Runnable> resetters = new Seq<>();
private Seq<Runnable> afterCallbacks = new Seq<>(); private Seq<Runnable> afterCallbacks = new Seq<>();
private Seq<Object> visitStack = new Seq<>();
private @Nullable PatchSet currentlyApplying; private @Nullable PatchSet currentlyApplying;
/** Currently active patches. Note that apply() should be called after modification. */ /** Currently active patches. Note that apply() should be called after modification. */
@@ -92,6 +93,7 @@ public class DataPatcher{
JsonValue value = parser.getJson().fromJson(null, Jval.read(patch).toString(Jformat.plain)); JsonValue value = parser.getJson().fromJson(null, Jval.read(patch).toString(Jformat.plain));
set.json = value; set.json = value;
currentlyApplying = set; currentlyApplying = set;
visitStack.clear();
set.name = value.getString("name", ""); set.name = value.getString("name", "");
value.remove("name"); //patchsets can have a name, ignore it if present value.remove("name"); //patchsets can have a name, ignore it if present
@@ -135,12 +137,13 @@ public class DataPatcher{
} }
void visit(Object object){ void visit(Object object){
visitStack.add(object);
if(object instanceof Content c && usedpatches.add(c)){ if(object instanceof Content c && usedpatches.add(c)){
after(c::afterPatch); after(c::afterPatch);
} }
} }
void created(Object object, Object parent){ void created(Object object){
if(object instanceof Weapon weapon){ if(object instanceof Weapon weapon){
weapon.init(); weapon.init();
}else if(object instanceof Content cont){ }else if(object instanceof Content cont){
@@ -149,6 +152,15 @@ public class DataPatcher{
} }
if(!Vars.headless){ if(!Vars.headless){
Object parent = null;
//find last item on the stack that can be mapped to this part or weapon
for(int i = visitStack.size - 1; i >= 0; i --){
Object o = visitStack.items[i];
if(o != object && (o instanceof Content || o instanceof Weapon)){
parent = o;
break;
}
}
if(object instanceof DrawPart part && parent instanceof MappableContent cont){ if(object instanceof DrawPart part && parent instanceof MappableContent cont){
part.load(cont.name); part.load(cont.name);
}else if(object instanceof DrawPart part && parent instanceof Weapon w){ }else if(object instanceof DrawPart part && parent instanceof Weapon w){
@@ -166,6 +178,9 @@ public class DataPatcher{
void assign(Object object, String field, Object value, @Nullable FieldData metadata, @Nullable Object parentObject, @Nullable String parentField) throws Exception{ void assign(Object object, String field, Object value, @Nullable FieldData metadata, @Nullable Object parentObject, @Nullable String parentField) throws Exception{
if(field == null || field.isEmpty()) return; if(field == null || field.isEmpty()) return;
int oldLength = visitStack.size;
try{
//field.field2.field3 nested syntax //field.field2.field3 nested syntax
if(field.indexOf('.') != -1){ if(field.indexOf('.') != -1){
//resolve the field chain until the final field is reached //resolve the field chain until the final field is reached
@@ -410,6 +425,9 @@ public class DataPatcher{
warn("Unknown field '@' for class '@'", field, actualType.getSimpleName()); warn("Unknown field '@' for class '@'", field, actualType.getSimpleName());
} }
} }
}finally{
visitStack.truncate(oldLength);
}
} }
void assignValue(Object object, String field, FieldData metadata, Prov getter, Cons setter, Object value, boolean modify) throws Exception{ void assignValue(Object object, String field, FieldData metadata, Prov getter, Cons setter, Object value, boolean modify) throws Exception{
@@ -426,7 +444,7 @@ public class DataPatcher{
if(modify) modifiedField(object, field, getter.get()); if(modify) modifiedField(object, field, getter.get());
//HACK: listen for creation of objects once //HACK: listen for creation of objects once
parser.listeners.add((type, jsonData, result) -> created(result, object)); parser.listeners.add((type, jsonData, result) -> created(result));
try{ try{
setter.get(parser.getJson().readValue(metadata.type, metadata.elementType, jsv)); setter.get(parser.getJson().readValue(metadata.type, metadata.elementType, jsv));
}catch(Throwable e){ }catch(Throwable e){