Rudimentary behaviour tree visualization
This commit is contained in:
@@ -24,6 +24,7 @@ struct BzAIBTNode {
|
||||
} delay;
|
||||
struct {
|
||||
BzAIBTActionFn fn;
|
||||
const char *name;
|
||||
} action;
|
||||
} as;
|
||||
|
||||
@@ -55,6 +56,37 @@ size_t bzAIBTGetNodeStateSize() {
|
||||
return sizeof(BzAIBTNodeState);
|
||||
}
|
||||
|
||||
const char *bzAIBTNodeTypeToStr(BzAIBTNodeType type) {
|
||||
switch (type) {
|
||||
case BZ_AIBT_COMP_SELECTOR:
|
||||
return "SELECTOR";
|
||||
case BZ_AIBT_COMP_SEQUENCE:
|
||||
return "SEQUENCE";
|
||||
case BZ_AIBT_COMP_PARALLEL_SELECTOR:
|
||||
return "PARALLEL_SELECTOR";
|
||||
case BZ_AIBT_COMP_PARALLEL_SEQUENCE:
|
||||
return "PARALLEL_SEQUENCE";
|
||||
case BZ_AIBT_DECOR_DUMMY:
|
||||
return "DUMMY";
|
||||
case BZ_AIBT_DECOR_SUCCESS:
|
||||
return "SUCCESS";
|
||||
case BZ_AIBT_DECOR_FAIL:
|
||||
return "FAIL";
|
||||
case BZ_AIBT_DECOR_INVERT:
|
||||
return "INVERT";
|
||||
case BZ_AIBT_DECOR_UNTIL_SUCCESS:
|
||||
return "UNTIL_SUCCESS";
|
||||
case BZ_AIBT_DECOR_UNTIL_FAIL:
|
||||
return "UNTIL_FAIL";
|
||||
case BZ_AIBT_DECOR_REPEAT:
|
||||
return "REPEAT";
|
||||
case BZ_AIBT_DECOR_DELAY:
|
||||
return "DELAY";
|
||||
case BZ_AIBT_ACTION:
|
||||
return "ACTION";
|
||||
}
|
||||
}
|
||||
|
||||
static BzAIBTNode *bzAIBTNodeMake(BzObjectPool *nodePool, BzAIBTNode *parent, BzAIBTNodeType type) {
|
||||
BZ_ASSERT(nodePool);
|
||||
BZ_ASSERT(bzObjectPoolGetObjectSize(nodePool) == bzAIBTGetNodeSize());
|
||||
@@ -135,15 +167,58 @@ BzAIBTNode *bzAIBTDecorDelay(BzObjectPool *nodePool, BzAIBTNode *parent, f32 ms)
|
||||
return node;
|
||||
}
|
||||
|
||||
BzAIBTNode *bzAIBTAction(BzObjectPool *nodePool, BzAIBTNode *parent, BzAIBTActionFn fn) {
|
||||
BzAIBTNode *bzAIBTAction(BzObjectPool *nodePool, BzAIBTNode *parent, BzAIBTActionFn fn,
|
||||
const char *name) {
|
||||
BzAIBTNode *node = bzAIBTNodeMake(nodePool, parent, BZ_AIBT_ACTION);
|
||||
node->as.action.fn = fn;
|
||||
node->as.action.name = name;
|
||||
return node;
|
||||
}
|
||||
|
||||
BzAIBTNodeType bzAIBTGetNodeType(BzAIBTNode *node) {
|
||||
i32 bzAIBTDecorGetRepeat(const BzAIBTNode *node) {
|
||||
BZ_ASSERT(node->type == BZ_AIBT_DECOR_REPEAT);
|
||||
return node->as.repeat.n;
|
||||
}
|
||||
f32 bzAIBTDecorGetDelay(const BzAIBTNode *node) {
|
||||
BZ_ASSERT(node->type == BZ_AIBT_DECOR_DELAY);
|
||||
return node->as.delay.ms;
|
||||
}
|
||||
|
||||
BzAIBTActionFn bzAIBTActionGetFn(const BzAIBTNode *node) {
|
||||
BZ_ASSERT(node->type == BZ_AIBT_ACTION);
|
||||
return node->as.action.fn;
|
||||
}
|
||||
const char *bzAIBTActionGetName(const BzAIBTNode *node) {
|
||||
BZ_ASSERT(node->type == BZ_AIBT_ACTION);
|
||||
return node->as.action.name;
|
||||
}
|
||||
|
||||
BzAIBTNodeType bzAIBTGetNodeType(const BzAIBTNode *node) {
|
||||
return node->type;
|
||||
}
|
||||
BzAIBTNode *bzAIBTNodeChild(const BzAIBTNode *node) {
|
||||
return node->first;
|
||||
}
|
||||
BzAIBTNode *bzAIBTNodeNext(const BzAIBTNode *node) {
|
||||
return node->next;
|
||||
}
|
||||
|
||||
const BzAIBTNodeState *bzAIBTNodeStateNext(const BzAIBTNodeState *state) {
|
||||
BZ_ASSERT(state);
|
||||
return state->next;
|
||||
}
|
||||
bool bzAIBTNodeMatchesState(const BzAIBTNode *node, const BzAIBTNodeState *state) {
|
||||
return state && state->node == node;
|
||||
}
|
||||
|
||||
i32 bzAIBTRepeatStateGetIter(const BzAIBTNodeState *state) {
|
||||
BZ_ASSERT(state->node && state->node->type == BZ_AIBT_DECOR_REPEAT);
|
||||
return state->as.repeat.iter;
|
||||
}
|
||||
f32 bzAIBTDelayStateGetElapsed(const BzAIBTNodeState *state) {
|
||||
BZ_ASSERT(state->node && state->node->type == BZ_AIBT_DECOR_DELAY);
|
||||
return state->as.delay.elapsed;
|
||||
}
|
||||
|
||||
BzAIBTState bzAIBTCreateState(const BzAIBTStateDesc *desc) {
|
||||
BZ_ASSERT(desc->pool);
|
||||
@@ -205,7 +280,7 @@ void bzAIBTStateRelease(BzAIBTState *state, BzAIBTNodeState *nodeState) {
|
||||
}
|
||||
|
||||
bool nodeMatchesState(const BzAIBTNode *node, const BzAIBTNodeState *state) {
|
||||
return state && state->node == node;
|
||||
return bzAIBTNodeMatchesState(node, state);
|
||||
}
|
||||
BzAIBTNodeState *getNextNodeState(const BzAIBTNode *node, BzAIBTNodeState *nodeState) {
|
||||
if (nodeState && nodeMatchesState(node, nodeState))
|
||||
|
||||
@@ -55,6 +55,8 @@ typedef struct BzAIBTStateDesc {
|
||||
size_t bzAIBTGetNodeSize();
|
||||
size_t bzAIBTGetNodeStateSize();
|
||||
|
||||
const char *bzAIBTNodeTypeToStr(BzAIBTNodeType type);
|
||||
|
||||
BzAIBTNode *bzAIBTMakeRoot(BzObjectPool *nodePool);
|
||||
void bzAIBTDestroyRoot(BzObjectPool *nodePool, BzAIBTNode *node);
|
||||
|
||||
@@ -70,9 +72,26 @@ BzAIBTNode *bzAIBTDecorUntilFail(BzObjectPool *nodePool, BzAIBTNode *parent);
|
||||
BzAIBTNode *bzAIBTDecorRepeat(BzObjectPool *nodePool, BzAIBTNode *parent, i32 n);
|
||||
BzAIBTNode *bzAIBTDecorDelay(BzObjectPool *nodePool, BzAIBTNode *parent, f32 ms);
|
||||
|
||||
BzAIBTNode *bzAIBTAction(BzObjectPool *nodePool, BzAIBTNode *parent, BzAIBTActionFn fn);
|
||||
BzAIBTNode *bzAIBTAction(BzObjectPool *nodePool, BzAIBTNode *parent, BzAIBTActionFn fn,
|
||||
const char *name);
|
||||
|
||||
BzAIBTNodeType bzAIBTGetNodeType(BzAIBTNode *node);
|
||||
// Reflection data
|
||||
|
||||
i32 bzAIBTDecorGetRepeat(const BzAIBTNode *node);
|
||||
f32 bzAIBTDecorGetDelay(const BzAIBTNode *node);
|
||||
|
||||
BzAIBTActionFn bzAIBTActionGetFn(const BzAIBTNode *node);
|
||||
const char *bzAIBTActionGetName(const BzAIBTNode *node);
|
||||
|
||||
BzAIBTNodeType bzAIBTGetNodeType(const BzAIBTNode *node);
|
||||
BzAIBTNode *bzAIBTNodeChild(const BzAIBTNode *node);
|
||||
BzAIBTNode *bzAIBTNodeNext(const BzAIBTNode *node);
|
||||
|
||||
const BzAIBTNodeState *bzAIBTNodeStateNext(const BzAIBTNodeState *state);
|
||||
bool bzAIBTNodeMatchesState(const BzAIBTNode *node, const BzAIBTNodeState *state);
|
||||
|
||||
i32 bzAIBTRepeatStateGetIter(const BzAIBTNodeState *state);
|
||||
f32 bzAIBTDelayStateGetElapsed(const BzAIBTNodeState *state);
|
||||
|
||||
BzAIBTState bzAIBTCreateState(const BzAIBTStateDesc *desc);
|
||||
void bzAIBTDestroyState(BzAIBTState *state);
|
||||
|
||||
Reference in New Issue
Block a user