Remove AI prefix from behaviour_tree

This commit is contained in:
2024-01-10 07:36:05 +01:00
parent c4c2b7610d
commit 113ac72181
3 changed files with 319 additions and 319 deletions

View File

@@ -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;

View File

@@ -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