Refactor behaviour tree composites
This commit is contained in:
@@ -276,6 +276,20 @@ BzBTNodeState *execStatePopFront(BzBTExecState *state) {
|
|||||||
popped->next = NULL;
|
popped->next = NULL;
|
||||||
return popped;
|
return popped;
|
||||||
}
|
}
|
||||||
|
void execStatePushFront(BzBTExecState *state, BzBTNodeState *nodeState) {
|
||||||
|
BZ_ASSERT(state);
|
||||||
|
|
||||||
|
nodeState->prev = NULL;
|
||||||
|
nodeState->next = state->first;
|
||||||
|
|
||||||
|
if (state->first) {
|
||||||
|
state->first->prev = nodeState;
|
||||||
|
} else {
|
||||||
|
state->first = nodeState;
|
||||||
|
state->last = nodeState;
|
||||||
|
}
|
||||||
|
state->first = nodeState;
|
||||||
|
}
|
||||||
void execStatePushBack(BzBTExecState *state, BzBTNodeState *nodeState) {
|
void execStatePushBack(BzBTExecState *state, BzBTNodeState *nodeState) {
|
||||||
BZ_ASSERT(state);
|
BZ_ASSERT(state);
|
||||||
|
|
||||||
@@ -348,34 +362,31 @@ static void releaseNodeState(BzObjectPool *pool, BzBTNodeState *nodeState) {
|
|||||||
|
|
||||||
static inline BzBTExecStatus bzBTExecuteNode(const BzBTNode *node, f32 dt,
|
static inline BzBTExecStatus bzBTExecuteNode(const BzBTNode *node, f32 dt,
|
||||||
BzBTExecState *nodeState, BzObjectPool *statePool);
|
BzBTExecState *nodeState, BzObjectPool *statePool);
|
||||||
#if 0
|
|
||||||
static inline BzBTExecStatus bzBTExecuteComposite(const BzBTNode *node, f32 dt,
|
static inline BzBTExecStatus bzBTExecuteComposite(const BzBTNode *node, f32 dt,
|
||||||
BzBTExecState *nodeState, BzObjectPool *statePool) {
|
BzBTExecState *state, BzObjectPool *statePool) {
|
||||||
BzBTNodeState *nextState = getNextNodeState(node, nodeState);
|
BzBTNodeState *nodeState = getNodeState(node, state);
|
||||||
BzBTNode *start = node->first;
|
|
||||||
bool isParallel = node->type == BZ_BT_COMP_PARALLEL_SEQUENCE ||
|
bool isParallel = node->type == BZ_BT_COMP_PARALLEL_SEQUENCE ||
|
||||||
node->type == BZ_BT_COMP_PARALLEL_SELECTOR;
|
node->type == BZ_BT_COMP_PARALLEL_SELECTOR;
|
||||||
|
|
||||||
if (!isParallel && nodeMatchesState(node, nodeState))
|
BzBTNode *start = node->first;
|
||||||
|
if (!isParallel && nodeState)
|
||||||
start = nodeState->as.composite.running;
|
start = nodeState->as.composite.running;
|
||||||
|
|
||||||
// Always push dummy state
|
|
||||||
if (nodeMatchesState(node, nodeState)) {
|
|
||||||
bzBTStateRenew(oldState, newState, nodeState);
|
|
||||||
} else {
|
|
||||||
nodeState = bzBTStatePool(oldState, node);
|
|
||||||
bzBTStateAppend(newState, nodeState);
|
|
||||||
}
|
|
||||||
i32 numRunning = 0;
|
i32 numRunning = 0;
|
||||||
i32 numSuccessful = 0;
|
i32 numSuccessful = 0;
|
||||||
i32 numFailed = 0;
|
i32 numFailed = 0;
|
||||||
i32 numChildren = 0;
|
i32 numChildren = 0;
|
||||||
BzBTStatus status = BZ_BT_ERROR;
|
BzBTExecStatus status = { .status = BZ_BT_ERROR };
|
||||||
BzBTNode *child = start;
|
BzBTNode *child = start;
|
||||||
for (;child; child = child->next) {
|
for (;child; child = child->next) {
|
||||||
BzBTStatus childStatus = bzBTExecuteNode(child, dt, nextState, oldState, newState);
|
BzBTExecStatus childStatus = bzBTExecuteNode(child, dt, state, statePool);
|
||||||
|
if (childStatus.status == BZ_BT_RUNNING) {
|
||||||
|
execStateMerge(&status.state, &childStatus.state);
|
||||||
|
}
|
||||||
|
BZ_ASSERT(childStatus.state.first == NULL);
|
||||||
numChildren++;
|
numChildren++;
|
||||||
switch (childStatus) {
|
switch (childStatus.status) {
|
||||||
case BZ_BT_RUNNING:
|
case BZ_BT_RUNNING:
|
||||||
numRunning++;
|
numRunning++;
|
||||||
break;
|
break;
|
||||||
@@ -391,21 +402,21 @@ static inline BzBTExecStatus 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_PARALLEL_SELECTOR:
|
||||||
if (childStatus == BZ_BT_SUCCESS)
|
if (childStatus.status == BZ_BT_SUCCESS)
|
||||||
status = BZ_BT_SUCCESS;
|
status.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_PARALLEL_SEQUENCE:
|
||||||
if (childStatus == BZ_BT_FAIL)
|
if (childStatus.status == BZ_BT_FAIL)
|
||||||
status = BZ_BT_FAIL;
|
status.status = BZ_BT_FAIL;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (status == BZ_BT_FAIL || status == BZ_BT_SUCCESS)
|
if (status.status == BZ_BT_FAIL || status.status == BZ_BT_SUCCESS)
|
||||||
break;
|
break;
|
||||||
if (numRunning > 0 && !isParallel) {
|
if (numRunning > 0 && !isParallel) {
|
||||||
status = BZ_BT_RUNNING;
|
status.status = BZ_BT_RUNNING;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -413,34 +424,38 @@ static inline BzBTExecStatus bzBTExecuteComposite(const BzBTNode *node, f32 dt,
|
|||||||
case BZ_BT_COMP_SELECTOR:
|
case BZ_BT_COMP_SELECTOR:
|
||||||
case BZ_BT_COMP_PARALLEL_SELECTOR:
|
case BZ_BT_COMP_PARALLEL_SELECTOR:
|
||||||
if (numFailed == numChildren)
|
if (numFailed == numChildren)
|
||||||
status = BZ_BT_FAIL;
|
status.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_PARALLEL_SEQUENCE:
|
||||||
if (numSuccessful == numChildren)
|
if (numSuccessful == numChildren)
|
||||||
status = BZ_BT_SUCCESS;
|
status.status = BZ_BT_SUCCESS;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (status == BZ_BT_ERROR) {
|
// Propagate ERROR up
|
||||||
bzBTStateRelease(newState, nodeState);
|
if (status.status == BZ_BT_ERROR) {
|
||||||
return BZ_BT_ERROR;
|
execStateClear(&status.state, statePool);
|
||||||
|
status.status = BZ_BT_ERROR;
|
||||||
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool finished = status == BZ_BT_SUCCESS ||
|
bool finished = status.status == BZ_BT_SUCCESS ||
|
||||||
status == BZ_BT_FAIL;
|
status.status == BZ_BT_FAIL;
|
||||||
if (finished) {
|
if (finished) {
|
||||||
// Dummy state is no longer needed
|
BZ_ASSERT(status.state.first == NULL);
|
||||||
bzBTStateRelease(newState, nodeState);
|
if (nodeState) releaseNodeState(statePool, nodeState);
|
||||||
} else {
|
return status;
|
||||||
BZ_ASSERT(status == BZ_BT_RUNNING);
|
|
||||||
nodeState->as.composite.running = child;
|
|
||||||
}
|
}
|
||||||
|
BZ_ASSERT(status.status == BZ_BT_RUNNING);
|
||||||
|
nodeState = ensureValidNodeState(node, statePool, nodeState);
|
||||||
|
nodeState->as.composite.running = child;
|
||||||
|
execStatePushFront(&status.state, nodeState);
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
static inline BzBTExecStatus bzBTExecuteDecorator(const BzBTNode *node, f32 dt,
|
static inline BzBTExecStatus bzBTExecuteDecorator(const BzBTNode *node, f32 dt,
|
||||||
BzBTExecState *state, BzObjectPool *statePool) {
|
BzBTExecState *state, BzObjectPool *statePool) {
|
||||||
// Ensure decorator has only one child, if any
|
// Ensure decorator has only one child, if any
|
||||||
@@ -544,7 +559,7 @@ static inline BzBTExecStatus bzBTExecuteNode(const BzBTNode *node, f32 dt,
|
|||||||
case BZ_BT_COMP_SEQUENCE:
|
case BZ_BT_COMP_SEQUENCE:
|
||||||
case BZ_BT_COMP_PARALLEL_SELECTOR:
|
case BZ_BT_COMP_PARALLEL_SELECTOR:
|
||||||
case BZ_BT_COMP_PARALLEL_SEQUENCE:
|
case BZ_BT_COMP_PARALLEL_SEQUENCE:
|
||||||
//status = bzBTExecuteComposite(node, dt, nodeState, statePool);
|
status = bzBTExecuteComposite(node, dt, nodeState, statePool);
|
||||||
break;
|
break;
|
||||||
case BZ_BT_DECOR_DUMMY:
|
case BZ_BT_DECOR_DUMMY:
|
||||||
case BZ_BT_DECOR_SUCCESS:
|
case BZ_BT_DECOR_SUCCESS:
|
||||||
|
|||||||
Reference in New Issue
Block a user