Add cleanup for compsites in BT + refactor
This commit is contained in:
@@ -345,7 +345,8 @@ static BzBTNodeState *getNodeState(const BzBTNode *node, BzBTExecState *state) {
|
|||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
static BzBTNodeState *ensureValidNodeState(const BzBTNode *node, BzObjectPool *pool, BzBTNodeState *existing) {
|
static BzBTNodeState *ensureValidNodeState(const BzBTNode *node, BzBTNodeState *existing,
|
||||||
|
BzObjectPool *pool) {
|
||||||
if (existing)
|
if (existing)
|
||||||
return existing;
|
return existing;
|
||||||
|
|
||||||
@@ -356,12 +357,24 @@ static BzBTNodeState *ensureValidNodeState(const BzBTNode *node, BzObjectPool *p
|
|||||||
bzMemSet(&existing->as, 0, sizeof(existing->as));
|
bzMemSet(&existing->as, 0, sizeof(existing->as));
|
||||||
return existing;
|
return existing;
|
||||||
}
|
}
|
||||||
static void releaseNodeState(BzObjectPool *pool, BzBTNodeState *nodeState) {
|
static void releaseNodeState(BzBTNodeState *nodeState, BzObjectPool *pool) {
|
||||||
bzObjectPoolRelease(pool, nodeState);
|
bzObjectPoolRelease(pool, nodeState);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void bzBTClearNodeState(const BzBTNode *node, BzBTExecState *state,
|
||||||
|
BzObjectPool *pool) {
|
||||||
|
BzBTNodeState *nodeState = getNodeState(node, state);
|
||||||
|
if (nodeState == NULL) return;
|
||||||
|
releaseNodeState(nodeState, pool);
|
||||||
|
|
||||||
|
const BzBTNode *first = node->first;
|
||||||
|
while (first) {
|
||||||
|
bzBTClearNodeState(first, state, pool);
|
||||||
|
first = first->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
static inline BzBTExecReturn bzBTExecuteNode(const BzBTNode *node, f32 dt,
|
static inline BzBTExecReturn bzBTExecuteNode(const BzBTNode *node, f32 dt,
|
||||||
BzBTExecState *nodeState, BzObjectPool *statePool);
|
BzBTExecState *state, BzObjectPool *statePool);
|
||||||
static inline BzBTExecReturn bzBTExecuteComposite(const BzBTNode *node, f32 dt,
|
static inline BzBTExecReturn bzBTExecuteComposite(const BzBTNode *node, f32 dt,
|
||||||
BzBTExecState *state, BzObjectPool *statePool) {
|
BzBTExecState *state, BzObjectPool *statePool) {
|
||||||
BzBTNodeState *nodeState = getNodeState(node, state);
|
BzBTNodeState *nodeState = getNodeState(node, state);
|
||||||
@@ -445,14 +458,22 @@ static inline BzBTExecReturn bzBTExecuteComposite(const BzBTNode *node, f32 dt,
|
|||||||
|
|
||||||
bool finished = execReturn.status == BZ_BT_SUCCESS ||
|
bool finished = execReturn.status == BZ_BT_SUCCESS ||
|
||||||
execReturn.status == BZ_BT_FAIL;
|
execReturn.status == BZ_BT_FAIL;
|
||||||
|
|
||||||
|
// Clean up, if exited prematurely
|
||||||
|
const BzBTNode *pChild = child;
|
||||||
|
while (finished && pChild) {
|
||||||
|
bzBTClearNodeState(pChild, state, statePool);
|
||||||
|
pChild = pChild->next;
|
||||||
|
}
|
||||||
|
|
||||||
if (finished) {
|
if (finished) {
|
||||||
BZ_ASSERT(execReturn.state.first == NULL);
|
BZ_ASSERT(execReturn.state.first == NULL);
|
||||||
if (nodeState) releaseNodeState(statePool, nodeState);
|
if (nodeState) releaseNodeState(nodeState, statePool);
|
||||||
return execReturn;
|
return execReturn;
|
||||||
}
|
}
|
||||||
BZ_ASSERT(execReturn.status == BZ_BT_RUNNING);
|
BZ_ASSERT(execReturn.status == BZ_BT_RUNNING);
|
||||||
// Parallels don't utilize state but still require it for correct tree traversal.
|
// Parallels don't utilize state but still require it for correct tree traversal.
|
||||||
nodeState = ensureValidNodeState(node, statePool, nodeState);
|
nodeState = ensureValidNodeState(node, nodeState, statePool);
|
||||||
nodeState->as.composite.running = child;
|
nodeState->as.composite.running = child;
|
||||||
execStatePushFront(&execReturn.state, nodeState);
|
execStatePushFront(&execReturn.state, nodeState);
|
||||||
|
|
||||||
@@ -469,11 +490,11 @@ static inline BzBTExecReturn bzBTExecuteDecorator(const BzBTNode *node, f32 dt,
|
|||||||
|
|
||||||
switch (node->type) {
|
switch (node->type) {
|
||||||
case BZ_BT_DECOR_REPEAT:
|
case BZ_BT_DECOR_REPEAT:
|
||||||
nodeState = ensureValidNodeState(node, statePool, nodeState);
|
nodeState = ensureValidNodeState(node, nodeState, statePool);
|
||||||
execStatePushBack(&execReturn.state, nodeState);
|
execStatePushBack(&execReturn.state, nodeState);
|
||||||
break;
|
break;
|
||||||
case BZ_BT_DECOR_DELAY:
|
case BZ_BT_DECOR_DELAY:
|
||||||
nodeState = ensureValidNodeState(node, statePool, nodeState);
|
nodeState = ensureValidNodeState(node, nodeState, statePool);
|
||||||
nodeState->as.delay.elapsed += dt;
|
nodeState->as.delay.elapsed += dt;
|
||||||
execStatePushBack(&execReturn.state, nodeState);
|
execStatePushBack(&execReturn.state, nodeState);
|
||||||
if (nodeState->as.delay.elapsed < node->as.delay.ms) {
|
if (nodeState->as.delay.elapsed < node->as.delay.ms) {
|
||||||
@@ -481,7 +502,7 @@ static inline BzBTExecReturn bzBTExecuteDecorator(const BzBTNode *node, f32 dt,
|
|||||||
return execReturn;
|
return execReturn;
|
||||||
}
|
}
|
||||||
BZ_ASSERT(nodeState == execStatePopFront(&execReturn.state));
|
BZ_ASSERT(nodeState == execStatePopFront(&execReturn.state));
|
||||||
releaseNodeState(statePool, nodeState);
|
releaseNodeState(nodeState, statePool);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@@ -542,7 +563,7 @@ static inline BzBTExecReturn bzBTExecuteDecorator(const BzBTNode *node, f32 dt,
|
|||||||
nodeState->as.repeat.iter++;
|
nodeState->as.repeat.iter++;
|
||||||
if (nodeState->as.repeat.iter >= node->as.repeat.n) {
|
if (nodeState->as.repeat.iter >= node->as.repeat.n) {
|
||||||
BZ_ASSERT(nodeState == execStatePopFront(&execReturn.state));
|
BZ_ASSERT(nodeState == execStatePopFront(&execReturn.state));
|
||||||
releaseNodeState(statePool, nodeState);
|
releaseNodeState(nodeState, statePool);
|
||||||
execReturn.status = childReturn.status;
|
execReturn.status = childReturn.status;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -554,14 +575,14 @@ static inline BzBTExecReturn bzBTExecuteDecorator(const BzBTNode *node, f32 dt,
|
|||||||
return execReturn;
|
return execReturn;
|
||||||
}
|
}
|
||||||
static inline BzBTExecReturn bzBTExecuteNode(const BzBTNode *node, f32 dt,
|
static inline BzBTExecReturn bzBTExecuteNode(const BzBTNode *node, f32 dt,
|
||||||
BzBTExecState *nodeState, BzObjectPool *statePool) {
|
BzBTExecState *state, BzObjectPool *statePool) {
|
||||||
BzBTExecReturn execReturn = { .status = BZ_BT_ERROR };
|
BzBTExecReturn execReturn = { .status = BZ_BT_ERROR };
|
||||||
switch (node->type) {
|
switch (node->type) {
|
||||||
case BZ_BT_COMP_SELECTOR:
|
case BZ_BT_COMP_SELECTOR:
|
||||||
case BZ_BT_COMP_SEQUENCE:
|
case BZ_BT_COMP_SEQUENCE:
|
||||||
case BZ_BT_COMP_P_SELECTOR:
|
case BZ_BT_COMP_P_SELECTOR:
|
||||||
case BZ_BT_COMP_P_SEQUENCE:
|
case BZ_BT_COMP_P_SEQUENCE:
|
||||||
execReturn = bzBTExecuteComposite(node, dt, nodeState, statePool);
|
execReturn = bzBTExecuteComposite(node, dt, state, statePool);
|
||||||
break;
|
break;
|
||||||
case BZ_BT_DECOR_DUMMY:
|
case BZ_BT_DECOR_DUMMY:
|
||||||
case BZ_BT_DECOR_SUCCESS:
|
case BZ_BT_DECOR_SUCCESS:
|
||||||
@@ -571,11 +592,11 @@ static inline BzBTExecReturn bzBTExecuteNode(const BzBTNode *node, f32 dt,
|
|||||||
case BZ_BT_DECOR_UNTIL_FAIL:
|
case BZ_BT_DECOR_UNTIL_FAIL:
|
||||||
case BZ_BT_DECOR_REPEAT:
|
case BZ_BT_DECOR_REPEAT:
|
||||||
case BZ_BT_DECOR_DELAY:
|
case BZ_BT_DECOR_DELAY:
|
||||||
execReturn = bzBTExecuteDecorator(node, dt, nodeState, statePool);
|
execReturn = bzBTExecuteDecorator(node, dt, state, statePool);
|
||||||
break;
|
break;
|
||||||
case BZ_BT_ACTION:
|
case BZ_BT_ACTION:
|
||||||
BZ_ASSERT(node->as.action.fn);
|
BZ_ASSERT(node->as.action.fn);
|
||||||
execReturn.status = node->as.action.fn(nodeState->userData, dt);
|
execReturn.status = node->as.action.fn(state->userData, dt);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return execReturn;
|
return execReturn;
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ bool init(int *game) {
|
|||||||
// delay 1s
|
// delay 1s
|
||||||
// print "Hello, world!"
|
// print "Hello, world!"
|
||||||
printBT = bzBTMakeRoot(nodePool);
|
printBT = bzBTMakeRoot(nodePool);
|
||||||
BzBTNode *pseq = bzBTCompSequence(nodePool, printBT, true);
|
BzBTNode *pseq = bzBTCompSelector(nodePool, printBT, true);
|
||||||
bzBTDecorDelay(nodePool, pseq, 2.0f);
|
bzBTDecorDelay(nodePool, pseq, 2.0f);
|
||||||
|
|
||||||
BzBTNode *node = bzBTDecorRepeat(nodePool, pseq, 5);
|
BzBTNode *node = bzBTDecorRepeat(nodePool, pseq, 5);
|
||||||
|
|||||||
Reference in New Issue
Block a user