Add cleanup for compsites in BT + refactor

This commit is contained in:
2024-01-11 07:48:49 +01:00
parent 2f2974fb77
commit 8043d56af9
2 changed files with 35 additions and 14 deletions

View File

@@ -345,7 +345,8 @@ static BzBTNodeState *getNodeState(const BzBTNode *node, BzBTExecState *state) {
}
return NULL;
}
static BzBTNodeState *ensureValidNodeState(const BzBTNode *node, BzObjectPool *pool, BzBTNodeState *existing) {
static BzBTNodeState *ensureValidNodeState(const BzBTNode *node, BzBTNodeState *existing,
BzObjectPool *pool) {
if (existing)
return existing;
@@ -356,12 +357,24 @@ static BzBTNodeState *ensureValidNodeState(const BzBTNode *node, BzObjectPool *p
bzMemSet(&existing->as, 0, sizeof(existing->as));
return existing;
}
static void releaseNodeState(BzObjectPool *pool, BzBTNodeState *nodeState) {
static void releaseNodeState(BzBTNodeState *nodeState, BzObjectPool *pool) {
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,
BzBTExecState *nodeState, BzObjectPool *statePool);
BzBTExecState *state, BzObjectPool *statePool);
static inline BzBTExecReturn bzBTExecuteComposite(const BzBTNode *node, f32 dt,
BzBTExecState *state, BzObjectPool *statePool) {
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 ||
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) {
BZ_ASSERT(execReturn.state.first == NULL);
if (nodeState) releaseNodeState(statePool, nodeState);
if (nodeState) releaseNodeState(nodeState, statePool);
return execReturn;
}
BZ_ASSERT(execReturn.status == BZ_BT_RUNNING);
// 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;
execStatePushFront(&execReturn.state, nodeState);
@@ -469,11 +490,11 @@ static inline BzBTExecReturn bzBTExecuteDecorator(const BzBTNode *node, f32 dt,
switch (node->type) {
case BZ_BT_DECOR_REPEAT:
nodeState = ensureValidNodeState(node, statePool, nodeState);
nodeState = ensureValidNodeState(node, nodeState, statePool);
execStatePushBack(&execReturn.state, nodeState);
break;
case BZ_BT_DECOR_DELAY:
nodeState = ensureValidNodeState(node, statePool, nodeState);
nodeState = ensureValidNodeState(node, nodeState, statePool);
nodeState->as.delay.elapsed += dt;
execStatePushBack(&execReturn.state, nodeState);
if (nodeState->as.delay.elapsed < node->as.delay.ms) {
@@ -481,7 +502,7 @@ static inline BzBTExecReturn bzBTExecuteDecorator(const BzBTNode *node, f32 dt,
return execReturn;
}
BZ_ASSERT(nodeState == execStatePopFront(&execReturn.state));
releaseNodeState(statePool, nodeState);
releaseNodeState(nodeState, statePool);
break;
default:
break;
@@ -542,7 +563,7 @@ static inline BzBTExecReturn bzBTExecuteDecorator(const BzBTNode *node, f32 dt,
nodeState->as.repeat.iter++;
if (nodeState->as.repeat.iter >= node->as.repeat.n) {
BZ_ASSERT(nodeState == execStatePopFront(&execReturn.state));
releaseNodeState(statePool, nodeState);
releaseNodeState(nodeState, statePool);
execReturn.status = childReturn.status;
break;
}
@@ -554,14 +575,14 @@ static inline BzBTExecReturn bzBTExecuteDecorator(const BzBTNode *node, f32 dt,
return execReturn;
}
static inline BzBTExecReturn bzBTExecuteNode(const BzBTNode *node, f32 dt,
BzBTExecState *nodeState, BzObjectPool *statePool) {
BzBTExecState *state, BzObjectPool *statePool) {
BzBTExecReturn execReturn = { .status = BZ_BT_ERROR };
switch (node->type) {
case BZ_BT_COMP_SELECTOR:
case BZ_BT_COMP_SEQUENCE:
case BZ_BT_COMP_P_SELECTOR:
case BZ_BT_COMP_P_SEQUENCE:
execReturn = bzBTExecuteComposite(node, dt, nodeState, statePool);
execReturn = bzBTExecuteComposite(node, dt, state, statePool);
break;
case BZ_BT_DECOR_DUMMY:
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_REPEAT:
case BZ_BT_DECOR_DELAY:
execReturn = bzBTExecuteDecorator(node, dt, nodeState, statePool);
execReturn = bzBTExecuteDecorator(node, dt, state, statePool);
break;
case BZ_BT_ACTION:
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;
}
return execReturn;

View File

@@ -26,7 +26,7 @@ bool init(int *game) {
// delay 1s
// print "Hello, world!"
printBT = bzBTMakeRoot(nodePool);
BzBTNode *pseq = bzBTCompSequence(nodePool, printBT, true);
BzBTNode *pseq = bzBTCompSelector(nodePool, printBT, true);
bzBTDecorDelay(nodePool, pseq, 2.0f);
BzBTNode *node = bzBTDecorRepeat(nodePool, pseq, 5);