Guarded task start() method running before guard.
lukz opened this issue · comments
Is it intended to run start() method of guarded task before guard?
In my case I'm using guards to check if task should run and I'm setting some values that guarded task may use.
For example:
(isPlayerVisible? range:512 outVar:"targetPlayer") interpose ent1Var:"targetGuardEnt" ent2Var:"targetPlayer"
Guard is checking if any player is visible and output visible player reference to blackboard. Interpose task is using this reference in its start() method to set up Interpose task. But because interpose start() method is run before guard I've got null ptr exception.
Yeah I see your point.
Not sure but considering checkGuard occurrences it looks like you can replace code like this
child.setControl(this);
child.start();
if (child.checkGuard(this))
child.run();
else
child.fail();
with something along the line of
child.setControl(this);
boolean ok = child.checkGuard(this);
child.start();
if (ok)
child.run();
else
child.fail();
I'm really busy these days, sorry. Can you try it and let me know?
I can't see how this change would fix the problem.
Well, maybe I'm missing something. As said above, I've not tested this change myself. Just looked quickly into the code.
Assuming you have a tree as simple as
parent
(guard) task
wouldn't this change make guard run before task.start()
?
I'm just wondering if start method shouldn't be called at all in this context.
Wiki says :
a guard is a condition that must be met before executing the respective task
start() called when the task is entered, just before run() is invoked.
But "task execution" is not clearly defined. Is start method included in "task execution" ?
DynamicGuardSelector evaluates guard before starting children but Selector (and others) doesn't. Consider following example :
selector
(hungry?) eat
Should we really start eating even if we're not hungry ?
Sounds reasonable. It looks like this code
child.setControl(this);
child.start();
if (child.checkGuard(this))
child.run();
else
child.fail();
should become
child.setControl(this);
if (child.checkGuard(this)) {
child.start();
child.run();
}
else
childFail(null); // actually child has not failed
This kind of code should work for Decorator
and BehaviorTree
.
For Parallel
and the other branches some other changes are likely needed.