From 113ac7218163f47a986267fb992a678138aba9bb Mon Sep 17 00:00:00 2001 From: Klemen Plestenjak Date: Wed, 10 Jan 2024 07:36:05 +0100 Subject: [PATCH] Remove AI prefix from behaviour_tree --- engine/breeze/ai/behaviour_tree.c | 436 +++++++++++++++--------------- engine/breeze/ai/behaviour_tree.h | 126 ++++----- engine/tests/btree_test.c | 76 +++--- 3 files changed, 319 insertions(+), 319 deletions(-) diff --git a/engine/breeze/ai/behaviour_tree.c b/engine/breeze/ai/behaviour_tree.c index a5a1de2..c243058 100644 --- a/engine/breeze/ai/behaviour_tree.c +++ b/engine/breeze/ai/behaviour_tree.c @@ -5,16 +5,16 @@ //#define GET_NODE(idx) ((BzAIBTNode *) bzObjectPoolGetObject(bt->nodePool, idx)) -struct BzAIBTNode { - BzAIBTNode *parent; +struct BzBTNode { + BzBTNode *parent; // Children - BzAIBTNode *first; - BzAIBTNode *last; + BzBTNode *first; + BzBTNode *last; // Siblings - BzAIBTNode *prev; - BzAIBTNode *next; + BzBTNode *prev; + BzBTNode *next; - BzAIBTNodeType type; + BzBTNodeType type; union { struct { i32 n; @@ -23,21 +23,21 @@ struct BzAIBTNode { f32 ms; } delay; struct { - BzAIBTActionFn fn; + BzBTActionFn fn; const char *name; } action; } as; }; -struct BzAIBTNodeState { - const BzAIBTNode *node; - BzAIBTNodeState *next; - BzAIBTNodeState *prev; +struct BzBTNodeState { + const BzBTNode *node; + BzBTNodeState *next; + BzBTNodeState *prev; union { struct { - BzAIBTNode *running; + BzBTNode *running; } composite; struct { i32 iter; @@ -49,48 +49,48 @@ struct BzAIBTNodeState { }; -size_t bzAIBTGetNodeSize() { - return sizeof(BzAIBTNode); +size_t bzBTGetNodeSize() { + return sizeof(BzBTNode); } -size_t bzAIBTGetNodeStateSize() { - return sizeof(BzAIBTNodeState); +size_t bzBTGetNodeStateSize() { + return sizeof(BzBTNodeState); } -const char *bzAIBTNodeTypeToStr(BzAIBTNodeType type) { +const char *bzBTNodeTypeToStr(BzBTNodeType type) { switch (type) { - case BZ_AIBT_COMP_SELECTOR: + case BZ_BT_COMP_SELECTOR: return "SELECTOR"; - case BZ_AIBT_COMP_SEQUENCE: + case BZ_BT_COMP_SEQUENCE: return "SEQUENCE"; - case BZ_AIBT_COMP_PARALLEL_SELECTOR: + case BZ_BT_COMP_PARALLEL_SELECTOR: return "PARALLEL_SELECTOR"; - case BZ_AIBT_COMP_PARALLEL_SEQUENCE: + case BZ_BT_COMP_PARALLEL_SEQUENCE: return "PARALLEL_SEQUENCE"; - case BZ_AIBT_DECOR_DUMMY: + case BZ_BT_DECOR_DUMMY: return "DUMMY"; - case BZ_AIBT_DECOR_SUCCESS: + case BZ_BT_DECOR_SUCCESS: return "SUCCESS"; - case BZ_AIBT_DECOR_FAIL: + case BZ_BT_DECOR_FAIL: return "FAIL"; - case BZ_AIBT_DECOR_INVERT: + case BZ_BT_DECOR_INVERT: return "INVERT"; - case BZ_AIBT_DECOR_UNTIL_SUCCESS: + case BZ_BT_DECOR_UNTIL_SUCCESS: return "UNTIL_SUCCESS"; - case BZ_AIBT_DECOR_UNTIL_FAIL: + case BZ_BT_DECOR_UNTIL_FAIL: return "UNTIL_FAIL"; - case BZ_AIBT_DECOR_REPEAT: + case BZ_BT_DECOR_REPEAT: return "REPEAT"; - case BZ_AIBT_DECOR_DELAY: + case BZ_BT_DECOR_DELAY: return "DELAY"; - case BZ_AIBT_ACTION: + case BZ_BT_ACTION: return "ACTION"; } } -static BzAIBTNode *bzAIBTNodeMake(BzObjectPool *nodePool, BzAIBTNode *parent, BzAIBTNodeType type) { +static BzBTNode *bzBTNodeMake(BzObjectPool *nodePool, BzBTNode *parent, BzBTNodeType type) { BZ_ASSERT(nodePool); - BZ_ASSERT(bzObjectPoolGetObjectSize(nodePool) == bzAIBTGetNodeSize()); - BzAIBTNode *node = bzObjectPool(nodePool); + BZ_ASSERT(bzObjectPoolGetObjectSize(nodePool) == bzBTGetNodeSize()); + BzBTNode *node = bzObjectPool(nodePool); bzMemSet(node, 0, sizeof(*node)); node->type = type; @@ -108,123 +108,123 @@ static BzAIBTNode *bzAIBTNodeMake(BzObjectPool *nodePool, BzAIBTNode *parent, Bz return node; } -BzAIBTNode *bzAIBTMakeRoot(BzObjectPool *nodePool) { - return bzAIBTNodeMake(nodePool, NULL, BZ_AIBT_DECOR_DUMMY); +BzBTNode *bzBTMakeRoot(BzObjectPool *nodePool) { + return bzBTNodeMake(nodePool, NULL, BZ_BT_DECOR_DUMMY); } -void bzAIBTDestroyRoot(BzObjectPool *nodePool, BzAIBTNode *node) { +void bzBTDestroyRoot(BzObjectPool *nodePool, BzBTNode *node) { BZ_ASSERT(node); - BzAIBTNode *pNode = node; + BzBTNode *pNode = node; while (pNode) { - BzAIBTNode *next = pNode->next; - bzAIBTDestroyRoot(nodePool, pNode); + BzBTNode *next = pNode->next; + bzBTDestroyRoot(nodePool, pNode); pNode = next; } bzObjectPoolRelease(nodePool, node); } -BzAIBTNode *bzAIBTCompSelector(BzObjectPool *nodePool, BzAIBTNode *parent, bool parallel) { - BzAIBTNodeType type = parallel ? - BZ_AIBT_COMP_PARALLEL_SELECTOR : - BZ_AIBT_COMP_SELECTOR; - return bzAIBTNodeMake(nodePool, parent, type); +BzBTNode *bzBTCompSelector(BzObjectPool *nodePool, BzBTNode *parent, bool parallel) { + BzBTNodeType type = parallel ? + BZ_BT_COMP_PARALLEL_SELECTOR : + BZ_BT_COMP_SELECTOR; + return bzBTNodeMake(nodePool, parent, type); } -BzAIBTNode *bzAIBTCompSequence(BzObjectPool *nodePool, BzAIBTNode *parent, bool parallel) { - BzAIBTNodeType type = parallel ? - BZ_AIBT_COMP_PARALLEL_SEQUENCE : - BZ_AIBT_COMP_SEQUENCE; - return bzAIBTNodeMake(nodePool, parent, type); +BzBTNode *bzBTCompSequence(BzObjectPool *nodePool, BzBTNode *parent, bool parallel) { + BzBTNodeType type = parallel ? + BZ_BT_COMP_PARALLEL_SEQUENCE : + BZ_BT_COMP_SEQUENCE; + return bzBTNodeMake(nodePool, parent, type); } -BzAIBTNode *bzAIBTDecorDummy(BzObjectPool *nodePool, BzAIBTNode *parent) { - return bzAIBTNodeMake(nodePool, parent, BZ_AIBT_DECOR_DUMMY); +BzBTNode *bzBTDecorDummy(BzObjectPool *nodePool, BzBTNode *parent) { + return bzBTNodeMake(nodePool, parent, BZ_BT_DECOR_DUMMY); } -BzAIBTNode *bzAIBTDecorSuccess(BzObjectPool *nodePool, BzAIBTNode *parent) { - return bzAIBTNodeMake(nodePool, parent, BZ_AIBT_DECOR_SUCCESS); +BzBTNode *bzBTDecorSuccess(BzObjectPool *nodePool, BzBTNode *parent) { + return bzBTNodeMake(nodePool, parent, BZ_BT_DECOR_SUCCESS); } -BzAIBTNode *bzAIBTDecorFail(BzObjectPool *nodePool, BzAIBTNode *parent) { - return bzAIBTNodeMake(nodePool, parent, BZ_AIBT_DECOR_FAIL); +BzBTNode *bzBTDecorFail(BzObjectPool *nodePool, BzBTNode *parent) { + return bzBTNodeMake(nodePool, parent, BZ_BT_DECOR_FAIL); } -BzAIBTNode *bzAIBTDecorInvert(BzObjectPool *nodePool, BzAIBTNode *parent) { - return bzAIBTNodeMake(nodePool, parent, BZ_AIBT_DECOR_INVERT); +BzBTNode *bzBTDecorInvert(BzObjectPool *nodePool, BzBTNode *parent) { + return bzBTNodeMake(nodePool, parent, BZ_BT_DECOR_INVERT); } -BzAIBTNode *bzAIBTDecorUntilSuccess(BzObjectPool *nodePool, BzAIBTNode *parent) { - return bzAIBTNodeMake(nodePool, parent, BZ_AIBT_DECOR_UNTIL_SUCCESS); +BzBTNode *bzBTDecorUntilSuccess(BzObjectPool *nodePool, BzBTNode *parent) { + return bzBTNodeMake(nodePool, parent, BZ_BT_DECOR_UNTIL_SUCCESS); } -BzAIBTNode *bzAIBTDecorUntilFail(BzObjectPool *nodePool, BzAIBTNode *parent) { - return bzAIBTNodeMake(nodePool, parent, BZ_AIBT_DECOR_UNTIL_FAIL); +BzBTNode *bzBTDecorUntilFail(BzObjectPool *nodePool, BzBTNode *parent) { + return bzBTNodeMake(nodePool, parent, BZ_BT_DECOR_UNTIL_FAIL); } -BzAIBTNode *bzAIBTDecorRepeat(BzObjectPool *nodePool, BzAIBTNode *parent, i32 n) { - BzAIBTNode *node = bzAIBTNodeMake(nodePool, parent, BZ_AIBT_DECOR_REPEAT); +BzBTNode *bzBTDecorRepeat(BzObjectPool *nodePool, BzBTNode *parent, i32 n) { + BzBTNode *node = bzBTNodeMake(nodePool, parent, BZ_BT_DECOR_REPEAT); node->as.repeat.n = n; return node; } -BzAIBTNode *bzAIBTDecorDelay(BzObjectPool *nodePool, BzAIBTNode *parent, f32 ms) { - BzAIBTNode *node = bzAIBTNodeMake(nodePool, parent, BZ_AIBT_DECOR_DELAY); +BzBTNode *bzBTDecorDelay(BzObjectPool *nodePool, BzBTNode *parent, f32 ms) { + BzBTNode *node = bzBTNodeMake(nodePool, parent, BZ_BT_DECOR_DELAY); node->as.delay.ms = ms; return node; } -BzAIBTNode *bzAIBTAction(BzObjectPool *nodePool, BzAIBTNode *parent, BzAIBTActionFn fn, - const char *name) { - BzAIBTNode *node = bzAIBTNodeMake(nodePool, parent, BZ_AIBT_ACTION); +BzBTNode *bzBTAction(BzObjectPool *nodePool, BzBTNode *parent, BzBTActionFn fn, + const char *name) { + BzBTNode *node = bzBTNodeMake(nodePool, parent, BZ_BT_ACTION); node->as.action.fn = fn; node->as.action.name = name; return node; } -i32 bzAIBTDecorGetRepeat(const BzAIBTNode *node) { - BZ_ASSERT(node->type == BZ_AIBT_DECOR_REPEAT); +i32 bzBTDecorGetRepeat(const BzBTNode *node) { + BZ_ASSERT(node->type == BZ_BT_DECOR_REPEAT); return node->as.repeat.n; } -f32 bzAIBTDecorGetDelay(const BzAIBTNode *node) { - BZ_ASSERT(node->type == BZ_AIBT_DECOR_DELAY); +f32 bzBTDecorGetDelay(const BzBTNode *node) { + BZ_ASSERT(node->type == BZ_BT_DECOR_DELAY); return node->as.delay.ms; } -BzAIBTActionFn bzAIBTActionGetFn(const BzAIBTNode *node) { - BZ_ASSERT(node->type == BZ_AIBT_ACTION); +BzBTActionFn bzBTActionGetFn(const BzBTNode *node) { + BZ_ASSERT(node->type == BZ_BT_ACTION); return node->as.action.fn; } -const char *bzAIBTActionGetName(const BzAIBTNode *node) { - BZ_ASSERT(node->type == BZ_AIBT_ACTION); +const char *bzBTActionGetName(const BzBTNode *node) { + BZ_ASSERT(node->type == BZ_BT_ACTION); return node->as.action.name; } -BzAIBTNodeType bzAIBTGetNodeType(const BzAIBTNode *node) { +BzBTNodeType bzBTGetNodeType(const BzBTNode *node) { return node->type; } -BzAIBTNode *bzAIBTNodeChild(const BzAIBTNode *node) { +BzBTNode *bzBTNodeChild(const BzBTNode *node) { return node->first; } -BzAIBTNode *bzAIBTNodeNext(const BzAIBTNode *node) { +BzBTNode *bzBTNodeNext(const BzBTNode *node) { return node->next; } -const BzAIBTNodeState *bzAIBTNodeStateNext(const BzAIBTNodeState *state) { +const BzBTNodeState *bzBTNodeStateNext(const BzBTNodeState *state) { BZ_ASSERT(state); return state->next; } -bool bzAIBTNodeMatchesState(const BzAIBTNode *node, const BzAIBTNodeState *state) { +bool bzBTNodeMatchesState(const BzBTNode *node, const BzBTNodeState *state) { return state && state->node == node; } -i32 bzAIBTRepeatStateGetIter(const BzAIBTNodeState *state) { - BZ_ASSERT(state->node && state->node->type == BZ_AIBT_DECOR_REPEAT); +i32 bzBTRepeatStateGetIter(const BzBTNodeState *state) { + BZ_ASSERT(state->node && state->node->type == BZ_BT_DECOR_REPEAT); return state->as.repeat.iter; } -f32 bzAIBTDelayStateGetElapsed(const BzAIBTNodeState *state) { - BZ_ASSERT(state->node && state->node->type == BZ_AIBT_DECOR_DELAY); +f32 bzBTDelayStateGetElapsed(const BzBTNodeState *state) { + BZ_ASSERT(state->node && state->node->type == BZ_BT_DECOR_DELAY); return state->as.delay.elapsed; } -BzAIBTState bzAIBTCreateState(const BzAIBTStateDesc *desc) { +BzBTState bzBTCreateState(const BzBTStateDesc *desc) { BZ_ASSERT(desc->pool); - BZ_ASSERT(bzObjectPoolGetObjectSize(desc->pool) == bzAIBTGetNodeStateSize()); + BZ_ASSERT(bzObjectPoolGetObjectSize(desc->pool) == bzBTGetNodeStateSize()); BZ_ASSERT(desc->root); - return (BzAIBTState) { + return (BzBTState) { .root = desc->root, .first = NULL, .last = NULL, @@ -232,17 +232,17 @@ BzAIBTState bzAIBTCreateState(const BzAIBTStateDesc *desc) { .userData = desc->userData }; } -void bzAIBTDestroyState(BzAIBTState *state) { - BzAIBTNodeState *pNodeState = state->first; +void bzBTDestroyState(BzBTState *state) { + BzBTNodeState *pNodeState = state->first; while (pNodeState) { - BzAIBTNodeState *next = pNodeState->next; + BzBTNodeState *next = pNodeState->next; bzObjectPoolRelease(state->nodeStatePool, pNodeState); pNodeState = next; } bzMemSet(state, 0, sizeof(*state)); } -void bzAIBTStateAppend(BzAIBTState *state, BzAIBTNodeState *nodeState) { +void bzBTStateAppend(BzBTState *state, BzBTNodeState *nodeState) { nodeState->next = NULL; nodeState->prev = state->last; if (state->last) @@ -251,11 +251,11 @@ void bzAIBTStateAppend(BzAIBTState *state, BzAIBTNodeState *nodeState) { state->first = nodeState; state->last = nodeState; } -void bzAIBTStatePop(BzAIBTState *state, BzAIBTNodeState *nodeState) { +void bzBTStatePop(BzBTState *state, BzBTNodeState *nodeState) { if (state->first == nodeState) state->first = nodeState->next; if (state->last == nodeState) state->last = nodeState->prev; - BzAIBTNodeState *next = nodeState->next; - BzAIBTNodeState *prev = nodeState->prev; + BzBTNodeState *next = nodeState->next; + BzBTNodeState *prev = nodeState->prev; if (nodeState->prev) nodeState->prev->next = next; if (nodeState->next) @@ -263,155 +263,155 @@ void bzAIBTStatePop(BzAIBTState *state, BzAIBTNodeState *nodeState) { nodeState->next = NULL; nodeState->prev = NULL; } -void bzAIBTStateRenew(BzAIBTState *oldState, BzAIBTState *newState, BzAIBTNodeState *nodeState) { +void bzBTStateRenew(BzBTState *oldState, BzBTState *newState, BzBTNodeState *nodeState) { // Pop nodeState and transfer it to the back - bzAIBTStatePop(oldState, nodeState); - bzAIBTStateAppend(newState, nodeState); + bzBTStatePop(oldState, nodeState); + bzBTStateAppend(newState, nodeState); } -BzAIBTNodeState *bzAIBTStatePool(BzAIBTState *state, const BzAIBTNode *node) { - BzAIBTNodeState *nodeState = bzObjectPool(state->nodeStatePool); +BzBTNodeState *bzBTStatePool(BzBTState *state, const BzBTNode *node) { + BzBTNodeState *nodeState = bzObjectPool(state->nodeStatePool); nodeState->next = NULL; nodeState->prev = NULL; nodeState->node = node; return nodeState; } -void bzAIBTStateRelease(BzAIBTState *state, BzAIBTNodeState *nodeState) { +void bzBTStateRelease(BzBTState *state, BzBTNodeState *nodeState) { bzObjectPoolRelease(state->nodeStatePool, nodeState); } -bool nodeMatchesState(const BzAIBTNode *node, const BzAIBTNodeState *state) { - return bzAIBTNodeMatchesState(node, state); +bool nodeMatchesState(const BzBTNode *node, const BzBTNodeState *state) { + return bzBTNodeMatchesState(node, state); } -BzAIBTNodeState *getNextNodeState(const BzAIBTNode *node, BzAIBTNodeState *nodeState) { +BzBTNodeState *getNextNodeState(const BzBTNode *node, BzBTNodeState *nodeState) { if (nodeState && nodeMatchesState(node, nodeState)) return nodeState->next; return nodeState; } -static inline BzAIBTStatus bzAIBTExecuteNode(const BzAIBTNode *node, f32 dt, - BzAIBTNodeState *nodeState, - BzAIBTState *oldState, BzAIBTState *newState); -static inline BzAIBTStatus bzAIBTExecuteComposite(const BzAIBTNode *node, f32 dt, - BzAIBTNodeState *nodeState, - BzAIBTState *oldState, BzAIBTState *newState) { - BzAIBTNodeState *nextState = getNextNodeState(node, nodeState); - BzAIBTNode *start = node->first; - bool isParallel = node->type == BZ_AIBT_COMP_PARALLEL_SEQUENCE || - node->type == BZ_AIBT_COMP_PARALLEL_SELECTOR; +static inline BzBTStatus bzBTExecuteNode(const BzBTNode *node, f32 dt, + BzBTNodeState *nodeState, + BzBTState *oldState, BzBTState *newState); +static inline BzBTStatus bzBTExecuteComposite(const BzBTNode *node, f32 dt, + BzBTNodeState *nodeState, + BzBTState *oldState, BzBTState *newState) { + BzBTNodeState *nextState = getNextNodeState(node, nodeState); + BzBTNode *start = node->first; + bool isParallel = node->type == BZ_BT_COMP_PARALLEL_SEQUENCE || + node->type == BZ_BT_COMP_PARALLEL_SELECTOR; if (!isParallel && nodeMatchesState(node, nodeState)) start = nodeState->as.composite.running; // Always push dummy state if (nodeMatchesState(node, nodeState)) { - bzAIBTStateRenew(oldState, newState, nodeState); + bzBTStateRenew(oldState, newState, nodeState); } else { - nodeState = bzAIBTStatePool(oldState, node); - bzAIBTStateAppend(newState, nodeState); + nodeState = bzBTStatePool(oldState, node); + bzBTStateAppend(newState, nodeState); } i32 numRunning = 0; i32 numSuccessful = 0; i32 numFailed = 0; i32 numChildren = 0; - BzAIBTStatus status = BZ_AIBT_ERROR; - BzAIBTNode *child = start; + BzBTStatus status = BZ_BT_ERROR; + BzBTNode *child = start; for (;child; child = child->next) { - BzAIBTStatus childStatus = bzAIBTExecuteNode(child, dt, nextState, oldState, newState); + BzBTStatus childStatus = bzBTExecuteNode(child, dt, nextState, oldState, newState); numChildren++; switch (childStatus) { - case BZ_AIBT_RUNNING: + case BZ_BT_RUNNING: numRunning++; break; - case BZ_AIBT_SUCCESS: + case BZ_BT_SUCCESS: numSuccessful++; break; - case BZ_AIBT_FAIL: + case BZ_BT_FAIL: numFailed++; break; default: break; } switch (node->type) { - case BZ_AIBT_COMP_SELECTOR: - case BZ_AIBT_COMP_PARALLEL_SELECTOR: - if (childStatus == BZ_AIBT_SUCCESS) - status = BZ_AIBT_SUCCESS; + case BZ_BT_COMP_SELECTOR: + case BZ_BT_COMP_PARALLEL_SELECTOR: + if (childStatus == BZ_BT_SUCCESS) + status = BZ_BT_SUCCESS; break; - case BZ_AIBT_COMP_SEQUENCE: - case BZ_AIBT_COMP_PARALLEL_SEQUENCE: - if (childStatus == BZ_AIBT_FAIL) - status = BZ_AIBT_FAIL; + case BZ_BT_COMP_SEQUENCE: + case BZ_BT_COMP_PARALLEL_SEQUENCE: + if (childStatus == BZ_BT_FAIL) + status = BZ_BT_FAIL; break; default: break; } - if (status == BZ_AIBT_FAIL || status == BZ_AIBT_SUCCESS) + if (status == BZ_BT_FAIL || status == BZ_BT_SUCCESS) break; if (numRunning > 0 && !isParallel) { - status = BZ_AIBT_RUNNING; + status = BZ_BT_RUNNING; break; } } switch (node->type) { - case BZ_AIBT_COMP_SELECTOR: - case BZ_AIBT_COMP_PARALLEL_SELECTOR: + case BZ_BT_COMP_SELECTOR: + case BZ_BT_COMP_PARALLEL_SELECTOR: if (numFailed == numChildren) - status = BZ_AIBT_FAIL; + status = BZ_BT_FAIL; break; - case BZ_AIBT_COMP_SEQUENCE: - case BZ_AIBT_COMP_PARALLEL_SEQUENCE: + case BZ_BT_COMP_SEQUENCE: + case BZ_BT_COMP_PARALLEL_SEQUENCE: if (numSuccessful == numChildren) - status = BZ_AIBT_SUCCESS; + status = BZ_BT_SUCCESS; break; default: break; } - if (status == BZ_AIBT_ERROR) { - bzAIBTStatePop(newState, nodeState); - return BZ_AIBT_ERROR; + if (status == BZ_BT_ERROR) { + bzBTStatePop(newState, nodeState); + return BZ_BT_ERROR; } - bool finished = status == BZ_AIBT_SUCCESS || - status == BZ_AIBT_FAIL; + bool finished = status == BZ_BT_SUCCESS || + status == BZ_BT_FAIL; if (finished) { // Dummy state is no longer needed - bzAIBTStatePop(newState, nodeState); + bzBTStatePop(newState, nodeState); } else { - BZ_ASSERT(status == BZ_AIBT_RUNNING); + BZ_ASSERT(status == BZ_BT_RUNNING); nodeState->as.composite.running = child; } return status; } -static inline BzAIBTStatus bzAIBTExecuteDecorator(const BzAIBTNode *node, f32 dt, - BzAIBTNodeState *nodeState, - BzAIBTState *oldState, BzAIBTState *newState) { +static inline BzBTStatus bzBTExecuteDecorator(const BzBTNode *node, f32 dt, + BzBTNodeState *nodeState, + BzBTState *oldState, BzBTState *newState) { // Ensure decorator has only one child, if any BZ_ASSERT(!node->first || node->first == node->last); - BzAIBTNodeState *nextState = getNextNodeState(node, nodeState); + BzBTNodeState *nextState = getNextNodeState(node, nodeState); switch (node->type) { - case BZ_AIBT_DECOR_REPEAT: + case BZ_BT_DECOR_REPEAT: if (!nodeMatchesState(node, nodeState)) { - BzAIBTNodeState *newNodeState = bzAIBTStatePool(oldState, node); + BzBTNodeState *newNodeState = bzBTStatePool(oldState, node); newNodeState->as.repeat.iter = 0; - bzAIBTStateAppend(newState, newNodeState); + bzBTStateAppend(newState, newNodeState); nodeState = newNodeState; } else { - bzAIBTStateRenew(oldState, newState, nodeState); + bzBTStateRenew(oldState, newState, nodeState); } break; - case BZ_AIBT_DECOR_DELAY: + case BZ_BT_DECOR_DELAY: if (!nodeMatchesState(node, nodeState)) { - BzAIBTNodeState *newNodeState = bzAIBTStatePool(oldState, node); + BzBTNodeState *newNodeState = bzBTStatePool(oldState, node); newNodeState->as.delay.elapsed = dt; - bzAIBTStateAppend(newState, newNodeState); - return BZ_AIBT_RUNNING; + bzBTStateAppend(newState, newNodeState); + return BZ_BT_RUNNING; } nodeState->as.delay.elapsed += dt; if (nodeState->as.delay.elapsed < node->as.delay.ms) { - bzAIBTStateRenew(oldState, newState, nodeState); - return BZ_AIBT_RUNNING; + bzBTStateRenew(oldState, newState, nodeState); + return BZ_BT_RUNNING; } break; default: @@ -419,109 +419,109 @@ static inline BzAIBTStatus bzAIBTExecuteDecorator(const BzAIBTNode *node, f32 dt } // Implicit success, if no children are present - BzAIBTStatus inStatus = BZ_AIBT_SUCCESS; + BzBTStatus inStatus = BZ_BT_SUCCESS; if (node->first) - inStatus = bzAIBTExecuteNode(node->first, dt, nextState, oldState, newState); + inStatus = bzBTExecuteNode(node->first, dt, nextState, oldState, newState); // Propagate ERROR, RUNNING up - if (inStatus == BZ_AIBT_ERROR) - return BZ_AIBT_ERROR; - if (inStatus == BZ_AIBT_RUNNING) - return BZ_AIBT_RUNNING; + if (inStatus == BZ_BT_ERROR) + return BZ_BT_ERROR; + if (inStatus == BZ_BT_RUNNING) + return BZ_BT_RUNNING; - BzAIBTStatus status = BZ_AIBT_ERROR; + BzBTStatus status = BZ_BT_ERROR; switch (node->type) { - case BZ_AIBT_DECOR_DUMMY: - case BZ_AIBT_DECOR_DELAY: // Delay already handled + case BZ_BT_DECOR_DUMMY: + case BZ_BT_DECOR_DELAY: // Delay already handled status = inStatus; break; - case BZ_AIBT_DECOR_SUCCESS: - status = BZ_AIBT_SUCCESS; + case BZ_BT_DECOR_SUCCESS: + status = BZ_BT_SUCCESS; break; - case BZ_AIBT_DECOR_FAIL: - status = BZ_AIBT_FAIL; + case BZ_BT_DECOR_FAIL: + status = BZ_BT_FAIL; break; - case BZ_AIBT_DECOR_INVERT: - if (inStatus == BZ_AIBT_FAIL) - status = BZ_AIBT_SUCCESS; - if (inStatus == BZ_AIBT_SUCCESS) - status = BZ_AIBT_FAIL; + case BZ_BT_DECOR_INVERT: + if (inStatus == BZ_BT_FAIL) + status = BZ_BT_SUCCESS; + if (inStatus == BZ_BT_SUCCESS) + status = BZ_BT_FAIL; break; - case BZ_AIBT_DECOR_UNTIL_SUCCESS: - if (inStatus == BZ_AIBT_SUCCESS) - status = BZ_AIBT_SUCCESS; + case BZ_BT_DECOR_UNTIL_SUCCESS: + if (inStatus == BZ_BT_SUCCESS) + status = BZ_BT_SUCCESS; else - status = BZ_AIBT_RUNNING; + status = BZ_BT_RUNNING; break; - case BZ_AIBT_DECOR_UNTIL_FAIL: - if (inStatus == BZ_AIBT_FAIL) - status = BZ_AIBT_SUCCESS; + case BZ_BT_DECOR_UNTIL_FAIL: + if (inStatus == BZ_BT_FAIL) + status = BZ_BT_SUCCESS; else - status = BZ_AIBT_RUNNING; + status = BZ_BT_RUNNING; break; - case BZ_AIBT_DECOR_REPEAT: + case BZ_BT_DECOR_REPEAT: BZ_ASSERT(nodeState->node == node); nodeState->as.repeat.iter++; if (nodeState->as.repeat.iter >= node->as.repeat.n) { - bzAIBTStatePop(newState, nodeState); + bzBTStatePop(newState, nodeState); status = inStatus; break; } - status = BZ_AIBT_RUNNING; + status = BZ_BT_RUNNING; break; default: break; } return status; } -static inline BzAIBTStatus bzAIBTExecuteNode(const BzAIBTNode *node, f32 dt, - BzAIBTNodeState *nodeState, - BzAIBTState *oldState, BzAIBTState *newState) { - BzAIBTStatus status = BZ_AIBT_ERROR; +static inline BzBTStatus bzBTExecuteNode(const BzBTNode *node, f32 dt, + BzBTNodeState *nodeState, + BzBTState *oldState, BzBTState *newState) { + BzBTStatus status = BZ_BT_ERROR; switch (node->type) { - case BZ_AIBT_COMP_SELECTOR: - case BZ_AIBT_COMP_SEQUENCE: - case BZ_AIBT_COMP_PARALLEL_SELECTOR: - case BZ_AIBT_COMP_PARALLEL_SEQUENCE: - status = bzAIBTExecuteComposite(node, dt, nodeState, oldState, newState); + case BZ_BT_COMP_SELECTOR: + case BZ_BT_COMP_SEQUENCE: + case BZ_BT_COMP_PARALLEL_SELECTOR: + case BZ_BT_COMP_PARALLEL_SEQUENCE: + status = bzBTExecuteComposite(node, dt, nodeState, oldState, newState); break; - case BZ_AIBT_DECOR_DUMMY: - case BZ_AIBT_DECOR_SUCCESS: - case BZ_AIBT_DECOR_FAIL: - case BZ_AIBT_DECOR_INVERT: - case BZ_AIBT_DECOR_UNTIL_SUCCESS: - case BZ_AIBT_DECOR_UNTIL_FAIL: - case BZ_AIBT_DECOR_REPEAT: - case BZ_AIBT_DECOR_DELAY: - status = bzAIBTExecuteDecorator(node, dt, nodeState, oldState, newState); + case BZ_BT_DECOR_DUMMY: + case BZ_BT_DECOR_SUCCESS: + case BZ_BT_DECOR_FAIL: + case BZ_BT_DECOR_INVERT: + case BZ_BT_DECOR_UNTIL_SUCCESS: + case BZ_BT_DECOR_UNTIL_FAIL: + case BZ_BT_DECOR_REPEAT: + case BZ_BT_DECOR_DELAY: + status = bzBTExecuteDecorator(node, dt, nodeState, oldState, newState); break; - case BZ_AIBT_ACTION: + case BZ_BT_ACTION: BZ_ASSERT(node->as.action.fn); return node->as.action.fn(oldState->userData); } return status; } -BzAIBTStatus bzAIBTExecute(BzAIBTState *state, f32 dt) { +BzBTStatus bzBTExecute(BzBTState *state, f32 dt) { BZ_ASSERT(state->nodeStatePool); - BZ_ASSERT(bzObjectPoolGetObjectSize(state->nodeStatePool) == bzAIBTGetNodeStateSize()); + BZ_ASSERT(bzObjectPoolGetObjectSize(state->nodeStatePool) == bzBTGetNodeStateSize()); BZ_ASSERT(state); BZ_ASSERT(state->root); - BzAIBTState newState = { + BzBTState newState = { .first = NULL, .last = NULL, }; - BzAIBTNodeState *first = state->first; - const BzAIBTNode *firstNode = first ? first->node : state->root; - BzAIBTStatus status = bzAIBTExecuteNode(firstNode, dt, first, state, &newState); + BzBTNodeState *first = state->first; + const BzBTNode *firstNode = first ? first->node : state->root; + BzBTStatus status = bzBTExecuteNode(firstNode, dt, first, state, &newState); // Release leftover states - BzAIBTNodeState *pState = state->first; + BzBTNodeState *pState = state->first; while (pState) { - BzAIBTNodeState *next = pState->next; - bzAIBTStateRelease(state, pState); + BzBTNodeState *next = pState->next; + bzBTStateRelease(state, pState); pState = next; } state->first = newState.first; diff --git a/engine/breeze/ai/behaviour_tree.h b/engine/breeze/ai/behaviour_tree.h index 8f6016b..0089c4d 100644 --- a/engine/breeze/ai/behaviour_tree.h +++ b/engine/breeze/ai/behaviour_tree.h @@ -3,99 +3,99 @@ #include "../defines.h" -typedef struct BzAIBTNode BzAIBTNode; +typedef struct BzBTNode BzBTNode; -typedef enum BzAIBTStatus { - BZ_AIBT_RUNNING, - BZ_AIBT_SUCCESS, - BZ_AIBT_FAIL, - BZ_AIBT_ERROR, -} BzAIBTStatus; +typedef enum BzBTStatus { + BZ_BT_RUNNING, + BZ_BT_SUCCESS, + BZ_BT_FAIL, + BZ_BT_ERROR, +} BzBTStatus; -typedef BzAIBTStatus(*BzAIBTActionFn)(void *data); +typedef BzBTStatus(*BzBTActionFn)(void *data); -typedef enum BzAIBTNodeType { +typedef enum BzBTNodeType { // Composite - BZ_AIBT_COMP_SELECTOR, - BZ_AIBT_COMP_SEQUENCE, - BZ_AIBT_COMP_PARALLEL_SELECTOR, - BZ_AIBT_COMP_PARALLEL_SEQUENCE, + BZ_BT_COMP_SELECTOR, + BZ_BT_COMP_SEQUENCE, + BZ_BT_COMP_PARALLEL_SELECTOR, + BZ_BT_COMP_PARALLEL_SEQUENCE, // Decorator - BZ_AIBT_DECOR_DUMMY, - BZ_AIBT_DECOR_SUCCESS, - BZ_AIBT_DECOR_FAIL, - BZ_AIBT_DECOR_INVERT, - BZ_AIBT_DECOR_UNTIL_SUCCESS, - BZ_AIBT_DECOR_UNTIL_FAIL, - BZ_AIBT_DECOR_REPEAT, - BZ_AIBT_DECOR_DELAY, + BZ_BT_DECOR_DUMMY, + BZ_BT_DECOR_SUCCESS, + BZ_BT_DECOR_FAIL, + BZ_BT_DECOR_INVERT, + BZ_BT_DECOR_UNTIL_SUCCESS, + BZ_BT_DECOR_UNTIL_FAIL, + BZ_BT_DECOR_REPEAT, + BZ_BT_DECOR_DELAY, // Action/Task - BZ_AIBT_ACTION, -} BzAIBTNodeType; + BZ_BT_ACTION, +} BzBTNodeType; typedef struct BzObjectPool BzObjectPool; -typedef struct BzAIBTNodeState BzAIBTNodeState; +typedef struct BzBTNodeState BzBTNodeState; -typedef struct BzAIBTState { - const BzAIBTNode *root; - BzAIBTNodeState *first; - BzAIBTNodeState *last; +typedef struct BzBTState { + const BzBTNode *root; + BzBTNodeState *first; + BzBTNodeState *last; BzObjectPool *nodeStatePool; void *userData; -} BzAIBTState; +} BzBTState; -typedef struct BzAIBTStateDesc { - const BzAIBTNode *root; +typedef struct BzBTStateDesc { + const BzBTNode *root; BzObjectPool *pool; void *userData; -} BzAIBTStateDesc; +} BzBTStateDesc; -size_t bzAIBTGetNodeSize(); -size_t bzAIBTGetNodeStateSize(); +size_t bzBTGetNodeSize(); +size_t bzBTGetNodeStateSize(); -const char *bzAIBTNodeTypeToStr(BzAIBTNodeType type); +const char *bzBTNodeTypeToStr(BzBTNodeType type); -BzAIBTNode *bzAIBTMakeRoot(BzObjectPool *nodePool); -void bzAIBTDestroyRoot(BzObjectPool *nodePool, BzAIBTNode *node); +BzBTNode *bzBTMakeRoot(BzObjectPool *nodePool); +void bzBTDestroyRoot(BzObjectPool *nodePool, BzBTNode *node); -BzAIBTNode *bzAIBTCompSelector(BzObjectPool *nodePool, BzAIBTNode *parent, bool parallel); -BzAIBTNode *bzAIBTCompSequence(BzObjectPool *nodePool, BzAIBTNode *parent, bool parallel); +BzBTNode *bzBTCompSelector(BzObjectPool *nodePool, BzBTNode *parent, bool parallel); +BzBTNode *bzBTCompSequence(BzObjectPool *nodePool, BzBTNode *parent, bool parallel); -BzAIBTNode *bzAIBTDecorDummy(BzObjectPool *nodePool, BzAIBTNode *parent); -BzAIBTNode *bzAIBTDecorSuccess(BzObjectPool *nodePool, BzAIBTNode *parent); -BzAIBTNode *bzAIBTDecorFail(BzObjectPool *nodePool, BzAIBTNode *parent); -BzAIBTNode *bzAIBTDecorInvert(BzObjectPool *nodePool, BzAIBTNode *parent); -BzAIBTNode *bzAIBTDecorUntilSuccess(BzObjectPool *nodePool, BzAIBTNode *parent); -BzAIBTNode *bzAIBTDecorUntilFail(BzObjectPool *nodePool, BzAIBTNode *parent); -BzAIBTNode *bzAIBTDecorRepeat(BzObjectPool *nodePool, BzAIBTNode *parent, i32 n); -BzAIBTNode *bzAIBTDecorDelay(BzObjectPool *nodePool, BzAIBTNode *parent, f32 ms); +BzBTNode *bzBTDecorDummy(BzObjectPool *nodePool, BzBTNode *parent); +BzBTNode *bzBTDecorSuccess(BzObjectPool *nodePool, BzBTNode *parent); +BzBTNode *bzBTDecorFail(BzObjectPool *nodePool, BzBTNode *parent); +BzBTNode *bzBTDecorInvert(BzObjectPool *nodePool, BzBTNode *parent); +BzBTNode *bzBTDecorUntilSuccess(BzObjectPool *nodePool, BzBTNode *parent); +BzBTNode *bzBTDecorUntilFail(BzObjectPool *nodePool, BzBTNode *parent); +BzBTNode *bzBTDecorRepeat(BzObjectPool *nodePool, BzBTNode *parent, i32 n); +BzBTNode *bzBTDecorDelay(BzObjectPool *nodePool, BzBTNode *parent, f32 ms); -BzAIBTNode *bzAIBTAction(BzObjectPool *nodePool, BzAIBTNode *parent, BzAIBTActionFn fn, - const char *name); +BzBTNode *bzBTAction(BzObjectPool *nodePool, BzBTNode *parent, BzBTActionFn fn, + const char *name); // Reflection data -i32 bzAIBTDecorGetRepeat(const BzAIBTNode *node); -f32 bzAIBTDecorGetDelay(const BzAIBTNode *node); +i32 bzBTDecorGetRepeat(const BzBTNode *node); +f32 bzBTDecorGetDelay(const BzBTNode *node); -BzAIBTActionFn bzAIBTActionGetFn(const BzAIBTNode *node); -const char *bzAIBTActionGetName(const BzAIBTNode *node); +BzBTActionFn bzBTActionGetFn(const BzBTNode *node); +const char *bzBTActionGetName(const BzBTNode *node); -BzAIBTNodeType bzAIBTGetNodeType(const BzAIBTNode *node); -BzAIBTNode *bzAIBTNodeChild(const BzAIBTNode *node); -BzAIBTNode *bzAIBTNodeNext(const BzAIBTNode *node); +BzBTNodeType bzBTGetNodeType(const BzBTNode *node); +BzBTNode *bzBTNodeChild(const BzBTNode *node); +BzBTNode *bzBTNodeNext(const BzBTNode *node); -const BzAIBTNodeState *bzAIBTNodeStateNext(const BzAIBTNodeState *state); -bool bzAIBTNodeMatchesState(const BzAIBTNode *node, const BzAIBTNodeState *state); +const BzBTNodeState *bzBTNodeStateNext(const BzBTNodeState *state); +bool bzBTNodeMatchesState(const BzBTNode *node, const BzBTNodeState *state); -i32 bzAIBTRepeatStateGetIter(const BzAIBTNodeState *state); -f32 bzAIBTDelayStateGetElapsed(const BzAIBTNodeState *state); +i32 bzBTRepeatStateGetIter(const BzBTNodeState *state); +f32 bzBTDelayStateGetElapsed(const BzBTNodeState *state); -BzAIBTState bzAIBTCreateState(const BzAIBTStateDesc *desc); -void bzAIBTDestroyState(BzAIBTState *state); +BzBTState bzBTCreateState(const BzBTStateDesc *desc); +void bzBTDestroyState(BzBTState *state); -BzAIBTStatus bzAIBTExecute(BzAIBTState *state, f32 dt); +BzBTStatus bzBTExecute(BzBTState *state, f32 dt); #endif //BREEZE_BEHAVIOUR_TREE_H diff --git a/engine/tests/btree_test.c b/engine/tests/btree_test.c index c2a89bc..2219bf8 100644 --- a/engine/tests/btree_test.c +++ b/engine/tests/btree_test.c @@ -4,39 +4,39 @@ BzObjectPool *nodePool = NULL; BzObjectPool *nodeStatePool = NULL; -BzAIBTNode *printBT = NULL; -BzAIBTState agentState; +BzBTNode *printBT = NULL; +BzBTState agentState; -BzAIBTStatus printAction(void *data) { +BzBTStatus printAction(void *data) { bzLogInfo("Hello, world!"); - return BZ_AIBT_SUCCESS; + return BZ_BT_SUCCESS; } bool init(int *game) { rlImGuiSetup(true); nodePool = bzObjectPoolCreate(&(BzObjectPoolDesc) { - .objectSize = bzAIBTGetNodeSize(), + .objectSize = bzBTGetNodeSize(), }); nodeStatePool = bzObjectPoolCreate(&(BzObjectPoolDesc) { - .objectSize = bzAIBTGetNodeStateSize() + .objectSize = bzBTGetNodeStateSize() }); // for 1..5: // seq // delay 1s // print "Hello, world!" - printBT = bzAIBTMakeRoot(nodePool); - BzAIBTNode *node = bzAIBTDecorRepeat(nodePool, printBT, 5); + printBT = bzBTMakeRoot(nodePool); + BzBTNode *node = bzBTDecorRepeat(nodePool, printBT, 5); - BzAIBTNode *seq = bzAIBTCompSequence(nodePool, node, false); + BzBTNode *seq = bzBTCompSequence(nodePool, node, false); - bzAIBTDecorDelay(nodePool, seq, 1.0f); - bzAIBTAction(nodePool, seq, printAction, "printAction"); + bzBTDecorDelay(nodePool, seq, 1.0f); + bzBTAction(nodePool, seq, printAction, "printAction"); - agentState = bzAIBTCreateState(&(BzAIBTStateDesc) { - .root = printBT, - .pool = nodeStatePool, - .userData = NULL + agentState = bzBTCreateState(&(BzBTStateDesc) { + .root = printBT, + .pool = nodeStatePool, + .userData = NULL }); return true; @@ -47,60 +47,60 @@ void deinit(int *game) { bzObjectPoolDestroy(nodeStatePool); } -void igRenderBTNode(const BzAIBTNode *node, const BzAIBTNodeState *state, bool sameLine, i32 depth) { - const BzAIBTNode *child = bzAIBTNodeChild(node); - BzAIBTNodeType type = bzAIBTGetNodeType(node); +void igRenderBTNode(const BzBTNode *node, const BzBTNodeState *state, bool sameLine, i32 depth) { + const BzBTNode *child = bzBTNodeChild(node); + BzBTNodeType type = bzBTGetNodeType(node); char extraInfo[128]; extraInfo[0] = '\0'; - bool hasState = bzAIBTNodeMatchesState(node, state); + bool hasState = bzBTNodeMatchesState(node, state); switch (type) { - case BZ_AIBT_DECOR_REPEAT: + case BZ_BT_DECOR_REPEAT: if (hasState) { snprintf(extraInfo, sizeof(extraInfo), " (%d < %d)", - bzAIBTRepeatStateGetIter(state), - bzAIBTDecorGetRepeat(node)); + bzBTRepeatStateGetIter(state), + bzBTDecorGetRepeat(node)); } else { - snprintf(extraInfo, sizeof(extraInfo), " (%d)", bzAIBTDecorGetRepeat(node)); + snprintf(extraInfo, sizeof(extraInfo), " (%d)", bzBTDecorGetRepeat(node)); } break; - case BZ_AIBT_DECOR_DELAY: + case BZ_BT_DECOR_DELAY: if (hasState) { snprintf(extraInfo, sizeof(extraInfo), " (%.2f < %.2fms)", - bzAIBTDelayStateGetElapsed(state), - bzAIBTDecorGetDelay(node)); + bzBTDelayStateGetElapsed(state), + bzBTDecorGetDelay(node)); } else { - snprintf(extraInfo, sizeof(extraInfo), " (%.2fms)", bzAIBTDecorGetDelay(node)); + snprintf(extraInfo, sizeof(extraInfo), " (%.2fms)", bzBTDecorGetDelay(node)); } break; - case BZ_AIBT_ACTION: + case BZ_BT_ACTION: snprintf(extraInfo, sizeof(extraInfo), " (%s:%p)", - bzAIBTActionGetName(node), - bzAIBTActionGetFn(node)); + bzBTActionGetName(node), + bzBTActionGetFn(node)); break; default: break; } if (hasState) - state = bzAIBTNodeStateNext(state); + state = bzBTNodeStateNext(state); ImVec4 color = {1.0f, 1.0f, 1.0f, 1.0f}; if (hasState) color = (ImVec4) {1.0f, 1.0f, 0.5f, 1.0f}; bool hasSingleChild = false; - if (child && bzAIBTNodeNext(child) == NULL) hasSingleChild = true; + if (child && bzBTNodeNext(child) == NULL) hasSingleChild = true; const char *suffix = hasSingleChild ? " > " : ": "; if (sameLine) { - igTextColored(color, "%s%s%s", bzAIBTNodeTypeToStr(type), + igTextColored(color, "%s%s%s", bzBTNodeTypeToStr(type), extraInfo, suffix); } else { igTextColored(color, "%*s%s %s", depth * 2, "", - bzAIBTNodeTypeToStr(type), extraInfo, suffix); + bzBTNodeTypeToStr(type), extraInfo, suffix); depth++; } @@ -109,12 +109,12 @@ void igRenderBTNode(const BzAIBTNode *node, const BzAIBTNodeState *state, bool s while (child) { if (hasSingleChild) igSameLine(0, 0); igRenderBTNode(child, state, hasSingleChild, depth); - child = bzAIBTNodeNext(child); + child = bzBTNodeNext(child); } } -void igRenderBT(BzAIBTState *state) { - const BzAIBTNode *root = state->root; +void igRenderBT(BzBTState *state) { + const BzBTNode *root = state->root; if (igBegin("BehaviourTree", NULL, 0)) { igRenderBTNode(root, state->first, false, 0); } @@ -124,7 +124,7 @@ void igRenderBT(BzAIBTState *state) { void render(float dt, int *game) { ClearBackground(WHITE); - BzAIBTStatus status = bzAIBTExecute(&agentState, dt); + BzBTStatus status = bzBTExecute(&agentState, dt); rlImGuiBegin(); igRenderBT(&agentState);