Refactor behaviour_tree (more consistent naming), fix BT visualization
This commit is contained in:
@@ -61,9 +61,9 @@ const char *bzBTNodeTypeToStr(BzBTNodeType type) {
|
|||||||
return "SELECTOR";
|
return "SELECTOR";
|
||||||
case BZ_BT_COMP_SEQUENCE:
|
case BZ_BT_COMP_SEQUENCE:
|
||||||
return "SEQUENCE";
|
return "SEQUENCE";
|
||||||
case BZ_BT_COMP_PARALLEL_SELECTOR:
|
case BZ_BT_COMP_P_SELECTOR:
|
||||||
return "P_SELECTOR";
|
return "P_SELECTOR";
|
||||||
case BZ_BT_COMP_PARALLEL_SEQUENCE:
|
case BZ_BT_COMP_P_SEQUENCE:
|
||||||
return "P_SEQUENCE";
|
return "P_SEQUENCE";
|
||||||
case BZ_BT_DECOR_DUMMY:
|
case BZ_BT_DECOR_DUMMY:
|
||||||
return "DUMMY";
|
return "DUMMY";
|
||||||
@@ -126,13 +126,13 @@ void bzBTDestroyRoot(BzObjectPool *nodePool, BzBTNode *node) {
|
|||||||
|
|
||||||
BzBTNode *bzBTCompSelector(BzObjectPool *nodePool, BzBTNode *parent, bool parallel) {
|
BzBTNode *bzBTCompSelector(BzObjectPool *nodePool, BzBTNode *parent, bool parallel) {
|
||||||
BzBTNodeType type = parallel ?
|
BzBTNodeType type = parallel ?
|
||||||
BZ_BT_COMP_PARALLEL_SELECTOR :
|
BZ_BT_COMP_P_SELECTOR :
|
||||||
BZ_BT_COMP_SELECTOR;
|
BZ_BT_COMP_SELECTOR;
|
||||||
return bzBTNodeMake(nodePool, parent, type);
|
return bzBTNodeMake(nodePool, parent, type);
|
||||||
}
|
}
|
||||||
BzBTNode *bzBTCompSequence(BzObjectPool *nodePool, BzBTNode *parent, bool parallel) {
|
BzBTNode *bzBTCompSequence(BzObjectPool *nodePool, BzBTNode *parent, bool parallel) {
|
||||||
BzBTNodeType type = parallel ?
|
BzBTNodeType type = parallel ?
|
||||||
BZ_BT_COMP_PARALLEL_SEQUENCE :
|
BZ_BT_COMP_P_SEQUENCE :
|
||||||
BZ_BT_COMP_SEQUENCE;
|
BZ_BT_COMP_SEQUENCE;
|
||||||
return bzBTNodeMake(nodePool, parent, type);
|
return bzBTNodeMake(nodePool, parent, type);
|
||||||
}
|
}
|
||||||
@@ -215,9 +215,9 @@ BzBTNode *bzBTCompStateGetRunningChild(const BzBTNodeState *state) {
|
|||||||
BZ_ASSERT(state->node);
|
BZ_ASSERT(state->node);
|
||||||
BzBTNodeType type = state->node->type;
|
BzBTNodeType type = state->node->type;
|
||||||
bool isComposite = type == BZ_BT_COMP_SELECTOR ||
|
bool isComposite = type == BZ_BT_COMP_SELECTOR ||
|
||||||
type == BZ_BT_COMP_PARALLEL_SELECTOR ||
|
type == BZ_BT_COMP_P_SELECTOR ||
|
||||||
type == BZ_BT_COMP_SEQUENCE ||
|
type == BZ_BT_COMP_SEQUENCE ||
|
||||||
type == BZ_BT_COMP_PARALLEL_SEQUENCE;
|
type == BZ_BT_COMP_P_SEQUENCE;
|
||||||
BZ_ASSERT(isComposite);
|
BZ_ASSERT(isComposite);
|
||||||
return state->as.composite.running;
|
return state->as.composite.running;
|
||||||
}
|
}
|
||||||
@@ -366,8 +366,8 @@ 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);
|
||||||
|
|
||||||
bool isParallel = node->type == BZ_BT_COMP_PARALLEL_SEQUENCE ||
|
bool isParallel = node->type == BZ_BT_COMP_P_SEQUENCE ||
|
||||||
node->type == BZ_BT_COMP_PARALLEL_SELECTOR;
|
node->type == BZ_BT_COMP_P_SELECTOR;
|
||||||
|
|
||||||
BzBTNode *start = node->first;
|
BzBTNode *start = node->first;
|
||||||
if (!isParallel && nodeState)
|
if (!isParallel && nodeState)
|
||||||
@@ -384,7 +384,7 @@ static inline BzBTExecReturn bzBTExecuteComposite(const BzBTNode *node, f32 dt,
|
|||||||
if (childReturn.status == BZ_BT_RUNNING) {
|
if (childReturn.status == BZ_BT_RUNNING) {
|
||||||
execStateMerge(&execReturn.state, &childReturn.state);
|
execStateMerge(&execReturn.state, &childReturn.state);
|
||||||
}
|
}
|
||||||
BZ_ASSERT(childReturn.state.first == NULL);
|
BZ_ASSERT(childReturn.state.first == NULL && childReturn.state.last == NULL);
|
||||||
numChildren++;
|
numChildren++;
|
||||||
switch (childReturn.status) {
|
switch (childReturn.status) {
|
||||||
case BZ_BT_RUNNING:
|
case BZ_BT_RUNNING:
|
||||||
@@ -401,12 +401,12 @@ static inline BzBTExecReturn bzBTExecuteComposite(const BzBTNode *node, f32 dt,
|
|||||||
}
|
}
|
||||||
switch (node->type) {
|
switch (node->type) {
|
||||||
case BZ_BT_COMP_SELECTOR:
|
case BZ_BT_COMP_SELECTOR:
|
||||||
case BZ_BT_COMP_PARALLEL_SELECTOR:
|
case BZ_BT_COMP_P_SELECTOR:
|
||||||
if (childReturn.status == BZ_BT_SUCCESS)
|
if (childReturn.status == BZ_BT_SUCCESS)
|
||||||
execReturn.status = BZ_BT_SUCCESS;
|
execReturn.status = BZ_BT_SUCCESS;
|
||||||
break;
|
break;
|
||||||
case BZ_BT_COMP_SEQUENCE:
|
case BZ_BT_COMP_SEQUENCE:
|
||||||
case BZ_BT_COMP_PARALLEL_SEQUENCE:
|
case BZ_BT_COMP_P_SEQUENCE:
|
||||||
if (childReturn.status == BZ_BT_FAIL)
|
if (childReturn.status == BZ_BT_FAIL)
|
||||||
execReturn.status = BZ_BT_FAIL;
|
execReturn.status = BZ_BT_FAIL;
|
||||||
break;
|
break;
|
||||||
@@ -415,19 +415,20 @@ static inline BzBTExecReturn bzBTExecuteComposite(const BzBTNode *node, f32 dt,
|
|||||||
}
|
}
|
||||||
if (execReturn.status == BZ_BT_FAIL || execReturn.status == BZ_BT_SUCCESS)
|
if (execReturn.status == BZ_BT_FAIL || execReturn.status == BZ_BT_SUCCESS)
|
||||||
break;
|
break;
|
||||||
if (numRunning > 0 && !isParallel) {
|
if (numRunning > 0) {
|
||||||
execReturn.status = BZ_BT_RUNNING;
|
execReturn.status = BZ_BT_RUNNING;
|
||||||
break;
|
if (!isParallel)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
switch (node->type) {
|
switch (node->type) {
|
||||||
case BZ_BT_COMP_SELECTOR:
|
case BZ_BT_COMP_SELECTOR:
|
||||||
case BZ_BT_COMP_PARALLEL_SELECTOR:
|
case BZ_BT_COMP_P_SELECTOR:
|
||||||
if (numFailed == numChildren)
|
if (numFailed == numChildren)
|
||||||
execReturn.status = BZ_BT_FAIL;
|
execReturn.status = BZ_BT_FAIL;
|
||||||
break;
|
break;
|
||||||
case BZ_BT_COMP_SEQUENCE:
|
case BZ_BT_COMP_SEQUENCE:
|
||||||
case BZ_BT_COMP_PARALLEL_SEQUENCE:
|
case BZ_BT_COMP_P_SEQUENCE:
|
||||||
if (numSuccessful == numChildren)
|
if (numSuccessful == numChildren)
|
||||||
execReturn.status = BZ_BT_SUCCESS;
|
execReturn.status = BZ_BT_SUCCESS;
|
||||||
break;
|
break;
|
||||||
@@ -450,6 +451,7 @@ static inline BzBTExecReturn bzBTExecuteComposite(const BzBTNode *node, f32 dt,
|
|||||||
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.
|
||||||
nodeState = ensureValidNodeState(node, statePool, nodeState);
|
nodeState = ensureValidNodeState(node, statePool, nodeState);
|
||||||
nodeState->as.composite.running = child;
|
nodeState->as.composite.running = child;
|
||||||
execStatePushFront(&execReturn.state, nodeState);
|
execStatePushFront(&execReturn.state, nodeState);
|
||||||
@@ -557,8 +559,8 @@ static inline BzBTExecReturn bzBTExecuteNode(const BzBTNode *node, f32 dt,
|
|||||||
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_PARALLEL_SELECTOR:
|
case BZ_BT_COMP_P_SELECTOR:
|
||||||
case BZ_BT_COMP_PARALLEL_SEQUENCE:
|
case BZ_BT_COMP_P_SEQUENCE:
|
||||||
execReturn = bzBTExecuteComposite(node, dt, nodeState, statePool);
|
execReturn = bzBTExecuteComposite(node, dt, nodeState, statePool);
|
||||||
break;
|
break;
|
||||||
case BZ_BT_DECOR_DUMMY:
|
case BZ_BT_DECOR_DUMMY:
|
||||||
|
|||||||
@@ -18,8 +18,8 @@ typedef enum BzBTNodeType {
|
|||||||
// Composite
|
// Composite
|
||||||
BZ_BT_COMP_SELECTOR,
|
BZ_BT_COMP_SELECTOR,
|
||||||
BZ_BT_COMP_SEQUENCE,
|
BZ_BT_COMP_SEQUENCE,
|
||||||
BZ_BT_COMP_PARALLEL_SELECTOR,
|
BZ_BT_COMP_P_SELECTOR,
|
||||||
BZ_BT_COMP_PARALLEL_SEQUENCE,
|
BZ_BT_COMP_P_SEQUENCE,
|
||||||
// Decorator
|
// Decorator
|
||||||
BZ_BT_DECOR_DUMMY,
|
BZ_BT_DECOR_DUMMY,
|
||||||
BZ_BT_DECOR_SUCCESS,
|
BZ_BT_DECOR_SUCCESS,
|
||||||
|
|||||||
@@ -26,7 +26,10 @@ bool init(int *game) {
|
|||||||
// delay 1s
|
// delay 1s
|
||||||
// print "Hello, world!"
|
// print "Hello, world!"
|
||||||
printBT = bzBTMakeRoot(nodePool);
|
printBT = bzBTMakeRoot(nodePool);
|
||||||
BzBTNode *node = bzBTDecorRepeat(nodePool, printBT, 5);
|
BzBTNode *pseq = bzBTCompSequence(nodePool, printBT, true);
|
||||||
|
bzBTDecorDelay(nodePool, pseq, 2.0f);
|
||||||
|
|
||||||
|
BzBTNode *node = bzBTDecorRepeat(nodePool, pseq, 5);
|
||||||
|
|
||||||
BzBTNode *seq = bzBTCompSequence(nodePool, node, false);
|
BzBTNode *seq = bzBTCompSequence(nodePool, node, false);
|
||||||
|
|
||||||
@@ -48,78 +51,14 @@ void deinit(int *game) {
|
|||||||
bzObjectPoolDestroy(nodeStatePool);
|
bzObjectPoolDestroy(nodeStatePool);
|
||||||
}
|
}
|
||||||
|
|
||||||
void igVisualizeBTState(const BzBTNode *node, const BzBTNodeState *state, bool sameLine, i32 depth) {
|
void igVisualizeBTState(const BzBTNode *node, const BzBTNodeState *state,
|
||||||
const BzBTNode *child = bzBTNodeChild(node);
|
bool isActive, bool sameLine, i32 depth);
|
||||||
BzBTNodeType type = bzBTGetNodeType(node);
|
|
||||||
char extraInfo[128];
|
|
||||||
extraInfo[0] = '\0';
|
|
||||||
|
|
||||||
bool hasState = bzBTNodeMatchesState(node, state);
|
|
||||||
|
|
||||||
switch (type) {
|
|
||||||
case BZ_BT_DECOR_REPEAT:
|
|
||||||
if (hasState) {
|
|
||||||
snprintf(extraInfo, sizeof(extraInfo), " (%d < %d)",
|
|
||||||
bzBTRepeatStateGetIter(state),
|
|
||||||
bzBTDecorGetRepeat(node));
|
|
||||||
} else {
|
|
||||||
snprintf(extraInfo, sizeof(extraInfo), " (%d)", bzBTDecorGetRepeat(node));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case BZ_BT_DECOR_DELAY:
|
|
||||||
if (hasState) {
|
|
||||||
snprintf(extraInfo, sizeof(extraInfo), " (%.2f < %.2fms)",
|
|
||||||
bzBTDelayStateGetElapsed(state),
|
|
||||||
bzBTDecorGetDelay(node));
|
|
||||||
} else {
|
|
||||||
snprintf(extraInfo, sizeof(extraInfo), " (%.2fms)", bzBTDecorGetDelay(node));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case BZ_BT_ACTION:
|
|
||||||
snprintf(extraInfo, sizeof(extraInfo), " (%s:%p)",
|
|
||||||
bzBTNodeGetName(node) ? bzBTNodeGetName(node) : "?",
|
|
||||||
bzBTActionGetFn(node));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (hasState)
|
|
||||||
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 && bzBTNodeNext(child) == NULL) hasSingleChild = true;
|
|
||||||
|
|
||||||
const char *suffix = hasSingleChild ? " > " : ": ";
|
|
||||||
|
|
||||||
if (sameLine) {
|
|
||||||
igTextColored(color, "%s%s%s", bzBTNodeTypeToStr(type),
|
|
||||||
extraInfo, suffix);
|
|
||||||
} else {
|
|
||||||
igTextColored(color, "%*s%s %s",
|
|
||||||
depth * 2, "",
|
|
||||||
bzBTNodeTypeToStr(type), extraInfo, suffix);
|
|
||||||
depth++;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
while (child) {
|
|
||||||
if (hasSingleChild) igSameLine(0, 0);
|
|
||||||
igVisualizeBTState(child, state, hasSingleChild, depth);
|
|
||||||
child = bzBTNodeNext(child);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void igRenderBT(BzBTState *state) {
|
void igRenderBT(BzBTState *state) {
|
||||||
const BzBTNode *root = state->root;
|
const BzBTNode *root = state->root;
|
||||||
if (igBegin("BehaviourTree", NULL, 0)) {
|
if (igBegin("BehaviourTree", NULL, 0)) {
|
||||||
igText("NodeState pool: %d", bzObjectPoolGetNumFree(nodeStatePool));
|
igText("NodeState pool: %d", bzObjectPoolGetNumFree(nodeStatePool));
|
||||||
igSeparatorText("");
|
igSeparatorText("");
|
||||||
igVisualizeBTState(root, state->_first, false, 0);
|
igVisualizeBTState(root, state->_first, true, false, 0);
|
||||||
}
|
}
|
||||||
igEnd();
|
igEnd();
|
||||||
}
|
}
|
||||||
@@ -143,3 +82,89 @@ bool bzMain(BzAppDesc *appDesc, int argc, const char **argv) {
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
static const BzBTNodeState *findNodeState(const BzBTNode *node, const BzBTNodeState *state) {
|
||||||
|
const BzBTNodeState *pState = state;
|
||||||
|
|
||||||
|
// Although it's painfully slow, it serves as a debug tool,
|
||||||
|
// so speed is not a critical concern.
|
||||||
|
while (pState) {
|
||||||
|
const BzBTNodeState *next = bzBTNodeStateNext(pState);
|
||||||
|
if (bzBTNodeMatchesState(node, pState))
|
||||||
|
return pState;
|
||||||
|
pState = next;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
void igVisualizeBTState(const BzBTNode *node, const BzBTNodeState *state,
|
||||||
|
bool isActive, bool sameLine, i32 depth) {
|
||||||
|
const BzBTNode *child = bzBTNodeChild(node);
|
||||||
|
BzBTNodeType type = bzBTGetNodeType(node);
|
||||||
|
char extraInfo[128];
|
||||||
|
extraInfo[0] = '\0';
|
||||||
|
|
||||||
|
const BzBTNodeState *nodeState = findNodeState(node, state);
|
||||||
|
bool hasState = nodeState != NULL;
|
||||||
|
isActive |= hasState;
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case BZ_BT_DECOR_REPEAT:
|
||||||
|
if (hasState) {
|
||||||
|
snprintf(extraInfo, sizeof(extraInfo), " (%d < %d)",
|
||||||
|
bzBTRepeatStateGetIter(nodeState),
|
||||||
|
bzBTDecorGetRepeat(node));
|
||||||
|
} else {
|
||||||
|
snprintf(extraInfo, sizeof(extraInfo), " (%d)", bzBTDecorGetRepeat(node));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case BZ_BT_DECOR_DELAY:
|
||||||
|
if (hasState) {
|
||||||
|
snprintf(extraInfo, sizeof(extraInfo), " (%.2f < %.2fms)",
|
||||||
|
bzBTDelayStateGetElapsed(nodeState),
|
||||||
|
bzBTDecorGetDelay(node));
|
||||||
|
} else {
|
||||||
|
snprintf(extraInfo, sizeof(extraInfo), " (%.2fms)", bzBTDecorGetDelay(node));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case BZ_BT_ACTION:
|
||||||
|
snprintf(extraInfo, sizeof(extraInfo), " (%s:%p)",
|
||||||
|
bzBTNodeGetName(node) ? bzBTNodeGetName(node) : "?",
|
||||||
|
bzBTActionGetFn(node));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ImVec4 color = {1.0f, 1.0f, 1.0f, 1.0f};
|
||||||
|
if (isActive)
|
||||||
|
color = (ImVec4) {1.0f, 1.0f, 0.5f, 1.0f};
|
||||||
|
|
||||||
|
bool hasSingleChild = true;
|
||||||
|
if (child && bzBTNodeNext(child)) hasSingleChild = false;
|
||||||
|
|
||||||
|
const char *suffix = hasSingleChild ? " > " : ": ";
|
||||||
|
|
||||||
|
if (sameLine) {
|
||||||
|
igTextColored(color, "%s%s%s", bzBTNodeTypeToStr(type),
|
||||||
|
extraInfo, suffix);
|
||||||
|
} else {
|
||||||
|
igTextColored(color, "%*s%s %s",
|
||||||
|
depth * 2, "",
|
||||||
|
bzBTNodeTypeToStr(type), extraInfo, suffix);
|
||||||
|
depth++;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isComposite = type == BZ_BT_COMP_SELECTOR ||
|
||||||
|
type == BZ_BT_COMP_P_SELECTOR ||
|
||||||
|
type == BZ_BT_COMP_SEQUENCE ||
|
||||||
|
type == BZ_BT_COMP_P_SEQUENCE;
|
||||||
|
|
||||||
|
while (child) {
|
||||||
|
if (hasSingleChild) igSameLine(0, 0);
|
||||||
|
bool childActive = isActive && hasSingleChild;
|
||||||
|
if (hasState && isComposite && !childActive)
|
||||||
|
childActive = bzBTCompStateGetRunningChild(state) == child;
|
||||||
|
igVisualizeBTState(child, state, childActive, hasSingleChild, depth);
|
||||||
|
child = bzBTNodeNext(child);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -214,6 +214,19 @@ void igArm(ecs_world_t *ecs,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const BzBTNodeState *findNodeState(const BzBTNode *node, const BzBTNodeState *state) {
|
||||||
|
const BzBTNodeState *pState = state;
|
||||||
|
|
||||||
|
// Although it's painfully slow, it serves as a debug tool,
|
||||||
|
// so speed is not a critical concern.
|
||||||
|
while (pState) {
|
||||||
|
const BzBTNodeState *next = bzBTNodeStateNext(pState);
|
||||||
|
if (bzBTNodeMatchesState(node, pState))
|
||||||
|
return pState;
|
||||||
|
pState = next;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
void igVisualizeBTState(const BzBTNode *node, const BzBTNodeState *state,
|
void igVisualizeBTState(const BzBTNode *node, const BzBTNodeState *state,
|
||||||
bool isActive, bool sameLine, i32 depth) {
|
bool isActive, bool sameLine, i32 depth) {
|
||||||
const BzBTNode *child = bzBTNodeChild(node);
|
const BzBTNode *child = bzBTNodeChild(node);
|
||||||
@@ -221,14 +234,15 @@ void igVisualizeBTState(const BzBTNode *node, const BzBTNodeState *state,
|
|||||||
char extraInfo[128];
|
char extraInfo[128];
|
||||||
extraInfo[0] = '\0';
|
extraInfo[0] = '\0';
|
||||||
|
|
||||||
bool hasState = bzBTNodeMatchesState(node, state);
|
const BzBTNodeState *nodeState = findNodeState(node, state);
|
||||||
|
bool hasState = nodeState != NULL;
|
||||||
isActive |= hasState;
|
isActive |= hasState;
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case BZ_BT_DECOR_REPEAT:
|
case BZ_BT_DECOR_REPEAT:
|
||||||
if (hasState) {
|
if (hasState) {
|
||||||
snprintf(extraInfo, sizeof(extraInfo), " (%d < %d)",
|
snprintf(extraInfo, sizeof(extraInfo), " (%d < %d)",
|
||||||
bzBTRepeatStateGetIter(state),
|
bzBTRepeatStateGetIter(nodeState),
|
||||||
bzBTDecorGetRepeat(node));
|
bzBTDecorGetRepeat(node));
|
||||||
} else {
|
} else {
|
||||||
snprintf(extraInfo, sizeof(extraInfo), " (%d)", bzBTDecorGetRepeat(node));
|
snprintf(extraInfo, sizeof(extraInfo), " (%d)", bzBTDecorGetRepeat(node));
|
||||||
@@ -237,7 +251,7 @@ void igVisualizeBTState(const BzBTNode *node, const BzBTNodeState *state,
|
|||||||
case BZ_BT_DECOR_DELAY:
|
case BZ_BT_DECOR_DELAY:
|
||||||
if (hasState) {
|
if (hasState) {
|
||||||
snprintf(extraInfo, sizeof(extraInfo), " (%.2f < %.2fms)",
|
snprintf(extraInfo, sizeof(extraInfo), " (%.2f < %.2fms)",
|
||||||
bzBTDelayStateGetElapsed(state),
|
bzBTDelayStateGetElapsed(nodeState),
|
||||||
bzBTDecorGetDelay(node));
|
bzBTDecorGetDelay(node));
|
||||||
} else {
|
} else {
|
||||||
snprintf(extraInfo, sizeof(extraInfo), " (%.2fms)", bzBTDecorGetDelay(node));
|
snprintf(extraInfo, sizeof(extraInfo), " (%.2fms)", bzBTDecorGetDelay(node));
|
||||||
@@ -273,19 +287,16 @@ void igVisualizeBTState(const BzBTNode *node, const BzBTNodeState *state,
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool isComposite = type == BZ_BT_COMP_SELECTOR ||
|
bool isComposite = type == BZ_BT_COMP_SELECTOR ||
|
||||||
type == BZ_BT_COMP_PARALLEL_SELECTOR ||
|
type == BZ_BT_COMP_P_SELECTOR ||
|
||||||
type == BZ_BT_COMP_SEQUENCE ||
|
type == BZ_BT_COMP_SEQUENCE ||
|
||||||
type == BZ_BT_COMP_PARALLEL_SEQUENCE;
|
type == BZ_BT_COMP_P_SEQUENCE;
|
||||||
|
|
||||||
while (child) {
|
while (child) {
|
||||||
if (hasSingleChild) igSameLine(0, 0);
|
if (hasSingleChild) igSameLine(0, 0);
|
||||||
bool childActive = isActive && hasSingleChild;
|
bool childActive = isActive && hasSingleChild;
|
||||||
if (hasState && isComposite && !childActive)
|
if (hasState && isComposite && !childActive)
|
||||||
childActive = bzBTCompStateGetRunningChild(state) == child;
|
childActive = bzBTCompStateGetRunningChild(state) == child;
|
||||||
const BzBTNodeState *childState = state;
|
igVisualizeBTState(child, state, childActive, hasSingleChild, depth);
|
||||||
if (hasState)
|
|
||||||
childState = bzBTNodeStateNext(state);
|
|
||||||
igVisualizeBTState(child, childState, childActive, hasSingleChild, depth);
|
|
||||||
child = bzBTNodeNext(child);
|
child = bzBTNodeNext(child);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user