Fixed sync issues with large objective trees

This commit is contained in:
Anuken
2024-03-03 17:09:23 -05:00
parent ed26bf18a7
commit 9e503efd2f
3 changed files with 21 additions and 30 deletions

View File

@@ -357,7 +357,8 @@ public class Logic implements ApplicationListener{
//map is over, no more world processor objective stuff //map is over, no more world processor objective stuff
state.rules.disableWorldProcessors = true; state.rules.disableWorldProcessors = true;
state.rules.objectives.clear();
Call.clearObjectives();
//save, just in case //save, just in case
if(!headless && !net.client()){ if(!headless && !net.client()){
@@ -460,9 +461,6 @@ public class Logic implements ApplicationListener{
if(!state.isEditor()){ if(!state.isEditor()){
state.rules.objectives.update(); state.rules.objectives.update();
if(state.rules.objectives.checkChanged() && net.server()){
Call.setObjectives(state.rules.objectives);
}
} }
if(state.rules.waves && state.rules.waveTimer && !state.gameOver){ if(state.rules.waves && state.rules.waveTimer && !state.gameOver){

View File

@@ -340,15 +340,23 @@ public class NetClient implements ApplicationListener{
state.rules = rules; state.rules = rules;
} }
//NOTE: avoid using this, runs into packet/buffer size limitations
@Remote(variants = Variant.both) @Remote(variants = Variant.both)
public static void setObjectives(MapObjectives executor){ public static void setObjectives(MapObjectives executor){
state.rules.objectives = executor; state.rules.objectives = executor;
} }
@Remote(called = Loc.server) @Remote(variants = Variant.both, called = Loc.server)
public static void objectiveCompleted(String[] flagsRemoved, String[] flagsAdded){ public static void clearObjectives(){
state.rules.objectiveFlags.removeAll(flagsRemoved); state.rules.objectives.clear();
state.rules.objectiveFlags.addAll(flagsAdded); }
@Remote(variants = Variant.both, called = Loc.server)
public static void completeObjective(int index){
var obj = state.rules.objectives.get(index);
if(obj != null){
obj.done();
}
} }
@Remote(variants = Variant.both) @Remote(variants = Variant.both)

View File

@@ -39,8 +39,6 @@ public class MapObjectives implements Iterable<MapObjective>, Eachable<MapObject
* @see #eachRunning(Cons) * @see #eachRunning(Cons)
*/ */
public Seq<MapObjective> all = new Seq<>(4); public Seq<MapObjective> all = new Seq<>(4);
/** @see #checkChanged() */
protected transient boolean changed;
static{ static{
registerObjective( registerObjective(
@@ -126,21 +124,13 @@ public class MapObjectives implements Iterable<MapObjective>, Eachable<MapObject
eachRunning(obj -> { eachRunning(obj -> {
//objectives cannot get completed on the client, but they do try to update for timers and such //objectives cannot get completed on the client, but they do try to update for timers and such
if(obj.update() && !net.client()){ if(obj.update() && !net.client()){
obj.completed = true; Call.completeObjective(all.indexOf(obj));
obj.done();
} }
changed |= obj.changed;
obj.changed = false;
}); });
} }
/** @return True if map rules should be synced. Reserved for {@link Vars#logic}; do not invoke directly! */ public @Nullable MapObjective get(int index){
public boolean checkChanged(){ return index < 0 || index >= all.size ? null : all.get(index);
boolean has = changed;
changed = false;
return has;
} }
/** @return Whether there are any qualified objectives at all. */ /** @return Whether there are any qualified objectives at all. */
@@ -149,7 +139,6 @@ public class MapObjectives implements Iterable<MapObjective>, Eachable<MapObject
} }
public void clear(){ public void clear(){
if(all.size > 0) changed = true;
all.clear(); all.clear();
} }
@@ -191,7 +180,7 @@ public class MapObjectives implements Iterable<MapObjective>, Eachable<MapObject
/** Whether this objective has been done yet. This is internally set. */ /** Whether this objective has been done yet. This is internally set. */
private boolean completed; private boolean completed;
/** Internal value. Do not modify! */ /** Internal value. Do not modify! */
private transient boolean depFinished, changed; private transient boolean depFinished;
/** @return True if this objective is done and should be removed from the executor. */ /** @return True if this objective is done and should be removed from the executor. */
public abstract boolean update(); public abstract boolean update();
@@ -201,13 +190,9 @@ public class MapObjectives implements Iterable<MapObjective>, Eachable<MapObject
/** Called once after {@link #update()} returns true, before this objective is removed. */ /** Called once after {@link #update()} returns true, before this objective is removed. */
public void done(){ public void done(){
changed(); state.rules.objectiveFlags.removeAll(flagsRemoved);
Call.objectiveCompleted(flagsRemoved, flagsAdded); state.rules.objectiveFlags.addAll(flagsAdded);
} completed = true;
/** Notifies the executor that map rules should be synced. */
protected void changed(){
changed = true;
} }
/** @return True if all {@link #parents} are completed, rendering this objective able to execute. */ /** @return True if all {@link #parents} are completed, rendering this objective able to execute. */