Rework CUTSCENE_ITEM_TYPE_INSERT to splice into the running scene's item array
Replaces the separate insert buffer/scene and insertStack return-frame mechanism with cutsceneAppend/cutsceneAppendNext, so an inserted cutscene's items become part of the running scene's own array instead of a jump-and-return. Moves the loaded-items buffer/scene from file-scope globals into cutscenesystem_t, and extracts shared start-cutscene setup into cutsceneSystemPrepare. Co-Authored-By: Claude Sonnet 5 <[email protected]>
This commit is contained in:
@@ -27,9 +27,10 @@ static cutsceneitem_t CUTSCENE_TEST_SCRATCH_ITEMS[] = {
|
||||
},
|
||||
{ .type = CUTSCENE_ITEM_TYPE_SET_PAUSE, .setPause = CUTSCENE_PAUSE_NONE }
|
||||
};
|
||||
static const cutscene_t CUTSCENE_TEST_SCRATCH = {
|
||||
static cutscene_t CUTSCENE_TEST_SCRATCH = {
|
||||
.items = CUTSCENE_TEST_SCRATCH_ITEMS,
|
||||
.itemCount = sizeof(CUTSCENE_TEST_SCRATCH_ITEMS) / sizeof(cutsceneitem_t),
|
||||
.itemsMax = sizeof(CUTSCENE_TEST_SCRATCH_ITEMS) / sizeof(cutsceneitem_t),
|
||||
.pause = CUTSCENE_PAUSE_NONE
|
||||
};
|
||||
|
||||
|
||||
@@ -23,9 +23,10 @@ static void recordCallback(void *userData) {
|
||||
static cutsceneitem_t CUTSCENE_TEST_INNER_ITEMS[] = {
|
||||
{ .type = CUTSCENE_ITEM_TYPE_CALLBACK, .callback = recordCallback }
|
||||
};
|
||||
static const cutscene_t CUTSCENE_TEST_INNER = {
|
||||
static cutscene_t CUTSCENE_TEST_INNER = {
|
||||
.items = CUTSCENE_TEST_INNER_ITEMS,
|
||||
.itemCount = sizeof(CUTSCENE_TEST_INNER_ITEMS) / sizeof(cutsceneitem_t),
|
||||
.itemsMax = sizeof(CUTSCENE_TEST_INNER_ITEMS) / sizeof(cutsceneitem_t),
|
||||
.pause = CUTSCENE_PAUSE_NONE
|
||||
};
|
||||
|
||||
@@ -33,12 +34,13 @@ static cutsceneitem_t CUTSCENE_TEST_OUTER_ITEMS[] = {
|
||||
{ .type = CUTSCENE_ITEM_TYPE_WAIT, .wait = 0.5f },
|
||||
{
|
||||
.type = CUTSCENE_ITEM_TYPE_CUTSCENE,
|
||||
.cutsceneRef = { .cutscene = &CUTSCENE_TEST_INNER, .name = NULL }
|
||||
.cutsceneRef = { .cutscene = &CUTSCENE_TEST_INNER }
|
||||
}
|
||||
};
|
||||
static const cutscene_t CUTSCENE_TEST_OUTER = {
|
||||
static cutscene_t CUTSCENE_TEST_OUTER = {
|
||||
.items = CUTSCENE_TEST_OUTER_ITEMS,
|
||||
.itemCount = sizeof(CUTSCENE_TEST_OUTER_ITEMS) / sizeof(cutsceneitem_t),
|
||||
.itemsMax = sizeof(CUTSCENE_TEST_OUTER_ITEMS) / sizeof(cutsceneitem_t),
|
||||
.pause = CUTSCENE_PAUSE_DEFAULT
|
||||
};
|
||||
|
||||
@@ -91,9 +93,10 @@ static void test_cutsceneSystemUpdateIsNoopWithNoActiveCutscene(void **state) {
|
||||
static cutsceneitem_t CUTSCENE_TEST_SINGLE_WAIT_ITEMS[] = {
|
||||
{ .type = CUTSCENE_ITEM_TYPE_WAIT, .wait = 1.0f }
|
||||
};
|
||||
static const cutscene_t CUTSCENE_TEST_SINGLE_WAIT = {
|
||||
static cutscene_t CUTSCENE_TEST_SINGLE_WAIT = {
|
||||
.items = CUTSCENE_TEST_SINGLE_WAIT_ITEMS,
|
||||
.itemCount = sizeof(CUTSCENE_TEST_SINGLE_WAIT_ITEMS) / sizeof(cutsceneitem_t),
|
||||
.itemsMax = sizeof(CUTSCENE_TEST_SINGLE_WAIT_ITEMS) / sizeof(cutsceneitem_t),
|
||||
.pause = CUTSCENE_PAUSE_NONE
|
||||
};
|
||||
|
||||
@@ -196,6 +199,17 @@ static void test_cutsceneSystemDisposeResetsState(void **state) {
|
||||
}
|
||||
|
||||
// --- CUTSCENE_INSERT ---------------------------------------------------
|
||||
//
|
||||
// INSERT now splices its target's items directly into the running
|
||||
// scene's own array (see cutsceneSystemInsertCutscene) rather than
|
||||
// swapping CUTSCENE_SYSTEM.scene to a different cutscene_t and pushing a
|
||||
// return frame - CUTSCENE_SYSTEM.scene therefore stays the same outer
|
||||
// cutscene throughout every test below; itemCount growing is what shows
|
||||
// the splice actually happened. Since the running scene's own array is
|
||||
// what gets appended into now, any outer cutscene used with INSERT must
|
||||
// declare its items array (and .itemsMax) with enough spare capacity for
|
||||
// whatever ends up spliced into it, including transitively through any
|
||||
// nested INSERT.
|
||||
|
||||
static uint8_t insertOrderLog[8];
|
||||
static uint8_t insertOrderLogCount;
|
||||
@@ -211,27 +225,30 @@ static cutsceneitem_t CUTSCENE_TEST_INSERT_SNIPPET_ITEMS[] = {
|
||||
{ .type = CUTSCENE_ITEM_TYPE_WAIT, .wait = 2.0f },
|
||||
{ .type = CUTSCENE_ITEM_TYPE_CALLBACK, .callback = recordOrderB }
|
||||
};
|
||||
static const cutscene_t CUTSCENE_TEST_INSERT_SNIPPET = {
|
||||
static cutscene_t CUTSCENE_TEST_INSERT_SNIPPET = {
|
||||
.items = CUTSCENE_TEST_INSERT_SNIPPET_ITEMS,
|
||||
.itemCount =
|
||||
sizeof(CUTSCENE_TEST_INSERT_SNIPPET_ITEMS) / sizeof(cutsceneitem_t),
|
||||
.itemsMax =
|
||||
sizeof(CUTSCENE_TEST_INSERT_SNIPPET_ITEMS) / sizeof(cutsceneitem_t),
|
||||
.pause = CUTSCENE_PAUSE_NONE
|
||||
};
|
||||
|
||||
static cutsceneitem_t CUTSCENE_TEST_INSERT_OUTER_ITEMS[] = {
|
||||
// 5 items to start, +3 spare slots for CUTSCENE_TEST_INSERT_SNIPPET's items.
|
||||
static cutsceneitem_t CUTSCENE_TEST_INSERT_OUTER_ITEMS[8] = {
|
||||
{ .type = CUTSCENE_ITEM_TYPE_CALLBACK, .callback = recordOrder0 },
|
||||
{ .type = CUTSCENE_ITEM_TYPE_WAIT, .wait = 1.0f },
|
||||
{ .type = CUTSCENE_ITEM_TYPE_CALLBACK, .callback = recordOrder1 },
|
||||
{
|
||||
.type = CUTSCENE_ITEM_TYPE_INSERT,
|
||||
.insert = { .cutscene = &CUTSCENE_TEST_INSERT_SNIPPET, .name = NULL }
|
||||
.insert = { .cutscene = &CUTSCENE_TEST_INSERT_SNIPPET }
|
||||
},
|
||||
{ .type = CUTSCENE_ITEM_TYPE_CALLBACK, .callback = recordOrder2 }
|
||||
};
|
||||
static const cutscene_t CUTSCENE_TEST_INSERT_OUTER = {
|
||||
static cutscene_t CUTSCENE_TEST_INSERT_OUTER = {
|
||||
.items = CUTSCENE_TEST_INSERT_OUTER_ITEMS,
|
||||
.itemCount =
|
||||
sizeof(CUTSCENE_TEST_INSERT_OUTER_ITEMS) / sizeof(cutsceneitem_t),
|
||||
.itemCount = 5,
|
||||
.itemsMax = sizeof(CUTSCENE_TEST_INSERT_OUTER_ITEMS) / sizeof(cutsceneitem_t),
|
||||
.pause = CUTSCENE_PAUSE_NONE
|
||||
};
|
||||
|
||||
@@ -246,12 +263,15 @@ static void test_cutsceneInsertSplicesItemsInPlaceThenResumes(void **state) {
|
||||
cutsceneSystemUpdate();// the WAIT elapses -> starts order1
|
||||
cutsceneSystemUpdate();// order1 done -> starts the INSERT, cascading into orderA
|
||||
|
||||
assert_ptr_equal(CUTSCENE_SYSTEM.scene, &CUTSCENE_TEST_INSERT_SNIPPET);
|
||||
// The splice happened in place - CUTSCENE_SYSTEM.scene never changed,
|
||||
// but it grew by the snippet's 3 items.
|
||||
assert_ptr_equal(CUTSCENE_SYSTEM.scene, &CUTSCENE_TEST_INSERT_OUTER);
|
||||
assert_int_equal(CUTSCENE_SYSTEM.scene->itemCount, 8);
|
||||
|
||||
TIME.delta = 2.5f;// elapses the snippet's WAIT(2.0)
|
||||
cutsceneSystemUpdate();// orderA done -> starts snippet's WAIT
|
||||
cutsceneSystemUpdate();// snippet's WAIT elapses -> starts orderB
|
||||
cutsceneSystemUpdate();// orderB done -> pops back, starts order2
|
||||
cutsceneSystemUpdate();// orderB done -> continues on to order2
|
||||
|
||||
assert_ptr_equal(CUTSCENE_SYSTEM.scene, &CUTSCENE_TEST_INSERT_OUTER);
|
||||
|
||||
@@ -266,25 +286,29 @@ static void test_cutsceneInsertSplicesItemsInPlaceThenResumes(void **state) {
|
||||
static cutsceneitem_t CUTSCENE_TEST_INSERT_AS_LAST_ITEM_SNIPPET_ITEMS[] = {
|
||||
{ .type = CUTSCENE_ITEM_TYPE_CALLBACK, .callback = recordOrderA }
|
||||
};
|
||||
static const cutscene_t CUTSCENE_TEST_INSERT_AS_LAST_ITEM_SNIPPET = {
|
||||
static cutscene_t CUTSCENE_TEST_INSERT_AS_LAST_ITEM_SNIPPET = {
|
||||
.items = CUTSCENE_TEST_INSERT_AS_LAST_ITEM_SNIPPET_ITEMS,
|
||||
.itemCount = sizeof(CUTSCENE_TEST_INSERT_AS_LAST_ITEM_SNIPPET_ITEMS) /
|
||||
sizeof(cutsceneitem_t),
|
||||
.itemsMax = sizeof(CUTSCENE_TEST_INSERT_AS_LAST_ITEM_SNIPPET_ITEMS) /
|
||||
sizeof(cutsceneitem_t),
|
||||
.pause = CUTSCENE_PAUSE_NONE
|
||||
};
|
||||
|
||||
static cutsceneitem_t CUTSCENE_TEST_INSERT_AS_LAST_ITEM_OUTER_ITEMS[] = {
|
||||
// 2 items to start, +1 spare slot for the snippet's single item.
|
||||
static cutsceneitem_t CUTSCENE_TEST_INSERT_AS_LAST_ITEM_OUTER_ITEMS[3] = {
|
||||
{ .type = CUTSCENE_ITEM_TYPE_CALLBACK, .callback = recordOrder0 },
|
||||
{
|
||||
.type = CUTSCENE_ITEM_TYPE_INSERT,
|
||||
.insert = {
|
||||
.cutscene = &CUTSCENE_TEST_INSERT_AS_LAST_ITEM_SNIPPET, .name = NULL
|
||||
.cutscene = &CUTSCENE_TEST_INSERT_AS_LAST_ITEM_SNIPPET
|
||||
}
|
||||
}
|
||||
};
|
||||
static const cutscene_t CUTSCENE_TEST_INSERT_AS_LAST_ITEM_OUTER = {
|
||||
static cutscene_t CUTSCENE_TEST_INSERT_AS_LAST_ITEM_OUTER = {
|
||||
.items = CUTSCENE_TEST_INSERT_AS_LAST_ITEM_OUTER_ITEMS,
|
||||
.itemCount = sizeof(CUTSCENE_TEST_INSERT_AS_LAST_ITEM_OUTER_ITEMS) /
|
||||
.itemCount = 2,
|
||||
.itemsMax = sizeof(CUTSCENE_TEST_INSERT_AS_LAST_ITEM_OUTER_ITEMS) /
|
||||
sizeof(cutsceneitem_t),
|
||||
.pause = CUTSCENE_PAUSE_NONE
|
||||
};
|
||||
@@ -298,12 +322,11 @@ static void test_cutsceneInsertAsLastItemEndsCutsceneNaturally(
|
||||
cutsceneSystemStartCutscene(&CUTSCENE_TEST_INSERT_AS_LAST_ITEM_OUTER);
|
||||
|
||||
cutsceneSystemUpdate();// order0 done -> starts INSERT, cascades to orderA
|
||||
assert_ptr_equal(
|
||||
CUTSCENE_SYSTEM.scene, &CUTSCENE_TEST_INSERT_AS_LAST_ITEM_SNIPPET
|
||||
);
|
||||
assert_ptr_equal(CUTSCENE_SYSTEM.scene, &CUTSCENE_TEST_INSERT_AS_LAST_ITEM_OUTER);
|
||||
assert_int_equal(CUTSCENE_SYSTEM.scene->itemCount, 3);
|
||||
|
||||
// orderA is the snippet's only item, and the snippet is the outer's last
|
||||
// item -- finishing it should pop straight through to the natural end
|
||||
// orderA is the snippet's only item, and the snippet was spliced in as
|
||||
// the outer's last item -- finishing it should reach the natural end
|
||||
// of the whole cutscene, not get stuck.
|
||||
cutsceneSystemUpdate();
|
||||
assert_null(CUTSCENE_SYSTEM.scene);
|
||||
@@ -316,42 +339,51 @@ static void test_cutsceneInsertAsLastItemEndsCutsceneNaturally(
|
||||
static cutsceneitem_t CUTSCENE_TEST_INSERT_NESTED_INNER_ITEMS[] = {
|
||||
{ .type = CUTSCENE_ITEM_TYPE_CALLBACK, .callback = recordOrderA }
|
||||
};
|
||||
static const cutscene_t CUTSCENE_TEST_INSERT_NESTED_INNER = {
|
||||
static cutscene_t CUTSCENE_TEST_INSERT_NESTED_INNER = {
|
||||
.items = CUTSCENE_TEST_INSERT_NESTED_INNER_ITEMS,
|
||||
.itemCount =
|
||||
sizeof(CUTSCENE_TEST_INSERT_NESTED_INNER_ITEMS) / sizeof(cutsceneitem_t),
|
||||
.itemsMax =
|
||||
sizeof(CUTSCENE_TEST_INSERT_NESTED_INNER_ITEMS) / sizeof(cutsceneitem_t),
|
||||
.pause = CUTSCENE_PAUSE_NONE
|
||||
};
|
||||
|
||||
// INSERT is MID's first item, so entering MID (from OUTER) cascades
|
||||
// straight through into INNER within the same Start chain, one level
|
||||
// deeper than a single insert.
|
||||
// deeper than a single insert. MID is only ever read from as a splice
|
||||
// source (see CUTSCENE_TEST_INSERT_NESTED_OUTER) - it's never itself the
|
||||
// running scene, so it needs no spare capacity of its own.
|
||||
static cutsceneitem_t CUTSCENE_TEST_INSERT_NESTED_MID_ITEMS[] = {
|
||||
{
|
||||
.type = CUTSCENE_ITEM_TYPE_INSERT,
|
||||
.insert = { .cutscene = &CUTSCENE_TEST_INSERT_NESTED_INNER, .name = NULL }
|
||||
.insert = { .cutscene = &CUTSCENE_TEST_INSERT_NESTED_INNER }
|
||||
},
|
||||
{ .type = CUTSCENE_ITEM_TYPE_CALLBACK, .callback = recordOrderB }
|
||||
};
|
||||
static const cutscene_t CUTSCENE_TEST_INSERT_NESTED_MID = {
|
||||
static cutscene_t CUTSCENE_TEST_INSERT_NESTED_MID = {
|
||||
.items = CUTSCENE_TEST_INSERT_NESTED_MID_ITEMS,
|
||||
.itemCount =
|
||||
sizeof(CUTSCENE_TEST_INSERT_NESTED_MID_ITEMS) / sizeof(cutsceneitem_t),
|
||||
.itemsMax =
|
||||
sizeof(CUTSCENE_TEST_INSERT_NESTED_MID_ITEMS) / sizeof(cutsceneitem_t),
|
||||
.pause = CUTSCENE_PAUSE_NONE
|
||||
};
|
||||
|
||||
static cutsceneitem_t CUTSCENE_TEST_INSERT_NESTED_OUTER_ITEMS[] = {
|
||||
// 3 items to start, +2 spare for MID's items, +1 more for MID's own
|
||||
// nested INSERT(INNER) once MID's items become part of this array too.
|
||||
static cutsceneitem_t CUTSCENE_TEST_INSERT_NESTED_OUTER_ITEMS[6] = {
|
||||
{ .type = CUTSCENE_ITEM_TYPE_CALLBACK, .callback = recordOrder0 },
|
||||
{
|
||||
.type = CUTSCENE_ITEM_TYPE_INSERT,
|
||||
.insert = { .cutscene = &CUTSCENE_TEST_INSERT_NESTED_MID, .name = NULL }
|
||||
.insert = { .cutscene = &CUTSCENE_TEST_INSERT_NESTED_MID }
|
||||
},
|
||||
{ .type = CUTSCENE_ITEM_TYPE_CALLBACK, .callback = recordOrder2 }
|
||||
};
|
||||
static const cutscene_t CUTSCENE_TEST_INSERT_NESTED_OUTER = {
|
||||
static cutscene_t CUTSCENE_TEST_INSERT_NESTED_OUTER = {
|
||||
.items = CUTSCENE_TEST_INSERT_NESTED_OUTER_ITEMS,
|
||||
.itemCount =
|
||||
sizeof(CUTSCENE_TEST_INSERT_NESTED_OUTER_ITEMS) / sizeof(cutsceneitem_t),
|
||||
.itemCount = 3,
|
||||
.itemsMax = sizeof(CUTSCENE_TEST_INSERT_NESTED_OUTER_ITEMS) /
|
||||
sizeof(cutsceneitem_t),
|
||||
.pause = CUTSCENE_PAUSE_NONE
|
||||
};
|
||||
|
||||
@@ -362,16 +394,14 @@ static void test_cutsceneInsertNestsThroughMultipleLevels(void **state) {
|
||||
cutsceneSystemStartCutscene(&CUTSCENE_TEST_INSERT_NESTED_OUTER);
|
||||
|
||||
// order0 done -> starts INSERT(MID), cascading through INSERT(INNER) ->
|
||||
// orderA, all within this one Update call's Start chain.
|
||||
// orderA, all within this one Update call's Start chain - both splices
|
||||
// land in OUTER's own array.
|
||||
cutsceneSystemUpdate();
|
||||
assert_ptr_equal(CUTSCENE_SYSTEM.scene, &CUTSCENE_TEST_INSERT_NESTED_INNER);
|
||||
|
||||
cutsceneSystemUpdate();// orderA done -> pops to MID, starts orderB
|
||||
assert_ptr_equal(CUTSCENE_SYSTEM.scene, &CUTSCENE_TEST_INSERT_NESTED_MID);
|
||||
|
||||
cutsceneSystemUpdate();// orderB done -> pops to OUTER, starts order2
|
||||
assert_ptr_equal(CUTSCENE_SYSTEM.scene, &CUTSCENE_TEST_INSERT_NESTED_OUTER);
|
||||
assert_int_equal(CUTSCENE_SYSTEM.scene->itemCount, 6);
|
||||
|
||||
cutsceneSystemUpdate();// orderA done -> continues on to orderB
|
||||
cutsceneSystemUpdate();// orderB done -> continues on to order2
|
||||
cutsceneSystemUpdate();// order2 done -> ends naturally
|
||||
assert_null(CUTSCENE_SYSTEM.scene);
|
||||
|
||||
@@ -380,87 +410,37 @@ static void test_cutsceneInsertNestsThroughMultipleLevels(void **state) {
|
||||
assert_memory_equal(insertOrderLog, expected, sizeof(expected));
|
||||
}
|
||||
|
||||
static cutsceneitem_t CUTSCENE_TEST_INSERT_OVERFLOW_LEVEL5_ITEMS[] = {
|
||||
static cutsceneitem_t CUTSCENE_TEST_INSERT_NO_CAPACITY_SNIPPET_ITEMS[] = {
|
||||
{ .type = CUTSCENE_ITEM_TYPE_CALLBACK, .callback = recordOrderA }
|
||||
};
|
||||
static const cutscene_t CUTSCENE_TEST_INSERT_OVERFLOW_LEVEL5 = {
|
||||
.items = CUTSCENE_TEST_INSERT_OVERFLOW_LEVEL5_ITEMS,
|
||||
.itemCount = sizeof(CUTSCENE_TEST_INSERT_OVERFLOW_LEVEL5_ITEMS) /
|
||||
sizeof(cutsceneitem_t),
|
||||
.pause = CUTSCENE_PAUSE_NONE
|
||||
};
|
||||
static cutsceneitem_t CUTSCENE_TEST_INSERT_OVERFLOW_LEVEL4_ITEMS[] = {
|
||||
{
|
||||
.type = CUTSCENE_ITEM_TYPE_INSERT,
|
||||
.insert = { .cutscene = &CUTSCENE_TEST_INSERT_OVERFLOW_LEVEL5, .name = NULL }
|
||||
}
|
||||
};
|
||||
static const cutscene_t CUTSCENE_TEST_INSERT_OVERFLOW_LEVEL4 = {
|
||||
.items = CUTSCENE_TEST_INSERT_OVERFLOW_LEVEL4_ITEMS,
|
||||
.itemCount = sizeof(CUTSCENE_TEST_INSERT_OVERFLOW_LEVEL4_ITEMS) /
|
||||
sizeof(cutsceneitem_t),
|
||||
.pause = CUTSCENE_PAUSE_NONE
|
||||
};
|
||||
static cutsceneitem_t CUTSCENE_TEST_INSERT_OVERFLOW_LEVEL3_ITEMS[] = {
|
||||
{
|
||||
.type = CUTSCENE_ITEM_TYPE_INSERT,
|
||||
.insert = { .cutscene = &CUTSCENE_TEST_INSERT_OVERFLOW_LEVEL4, .name = NULL }
|
||||
}
|
||||
};
|
||||
static const cutscene_t CUTSCENE_TEST_INSERT_OVERFLOW_LEVEL3 = {
|
||||
.items = CUTSCENE_TEST_INSERT_OVERFLOW_LEVEL3_ITEMS,
|
||||
.itemCount = sizeof(CUTSCENE_TEST_INSERT_OVERFLOW_LEVEL3_ITEMS) /
|
||||
sizeof(cutsceneitem_t),
|
||||
.pause = CUTSCENE_PAUSE_NONE
|
||||
};
|
||||
static cutsceneitem_t CUTSCENE_TEST_INSERT_OVERFLOW_LEVEL2_ITEMS[] = {
|
||||
{
|
||||
.type = CUTSCENE_ITEM_TYPE_INSERT,
|
||||
.insert = { .cutscene = &CUTSCENE_TEST_INSERT_OVERFLOW_LEVEL3, .name = NULL }
|
||||
}
|
||||
};
|
||||
static const cutscene_t CUTSCENE_TEST_INSERT_OVERFLOW_LEVEL2 = {
|
||||
.items = CUTSCENE_TEST_INSERT_OVERFLOW_LEVEL2_ITEMS,
|
||||
.itemCount = sizeof(CUTSCENE_TEST_INSERT_OVERFLOW_LEVEL2_ITEMS) /
|
||||
sizeof(cutsceneitem_t),
|
||||
.pause = CUTSCENE_PAUSE_NONE
|
||||
};
|
||||
static cutsceneitem_t CUTSCENE_TEST_INSERT_OVERFLOW_LEVEL1_ITEMS[] = {
|
||||
{
|
||||
.type = CUTSCENE_ITEM_TYPE_INSERT,
|
||||
.insert = { .cutscene = &CUTSCENE_TEST_INSERT_OVERFLOW_LEVEL2, .name = NULL }
|
||||
}
|
||||
};
|
||||
static const cutscene_t CUTSCENE_TEST_INSERT_OVERFLOW_LEVEL1 = {
|
||||
.items = CUTSCENE_TEST_INSERT_OVERFLOW_LEVEL1_ITEMS,
|
||||
.itemCount = sizeof(CUTSCENE_TEST_INSERT_OVERFLOW_LEVEL1_ITEMS) /
|
||||
sizeof(cutsceneitem_t),
|
||||
.pause = CUTSCENE_PAUSE_NONE
|
||||
};
|
||||
static cutsceneitem_t CUTSCENE_TEST_INSERT_OVERFLOW_LEVEL0_ITEMS[] = {
|
||||
{
|
||||
.type = CUTSCENE_ITEM_TYPE_INSERT,
|
||||
.insert = { .cutscene = &CUTSCENE_TEST_INSERT_OVERFLOW_LEVEL1, .name = NULL }
|
||||
}
|
||||
};
|
||||
static const cutscene_t CUTSCENE_TEST_INSERT_OVERFLOW_LEVEL0 = {
|
||||
.items = CUTSCENE_TEST_INSERT_OVERFLOW_LEVEL0_ITEMS,
|
||||
.itemCount = sizeof(CUTSCENE_TEST_INSERT_OVERFLOW_LEVEL0_ITEMS) /
|
||||
sizeof(cutsceneitem_t),
|
||||
static cutscene_t CUTSCENE_TEST_INSERT_NO_CAPACITY_SNIPPET = {
|
||||
.items = CUTSCENE_TEST_INSERT_NO_CAPACITY_SNIPPET_ITEMS,
|
||||
.itemCount = 1,
|
||||
.itemsMax = 1,
|
||||
.pause = CUTSCENE_PAUSE_NONE
|
||||
};
|
||||
|
||||
static void test_cutsceneInsertAssertsWhenNestingExceedsStackMax(
|
||||
void **state
|
||||
) {
|
||||
// No spare capacity at all - itemsMax equals itemCount, leaving no room
|
||||
// to splice anything into it.
|
||||
static cutsceneitem_t CUTSCENE_TEST_INSERT_NO_CAPACITY_OUTER_ITEMS[1] = {
|
||||
{
|
||||
.type = CUTSCENE_ITEM_TYPE_INSERT,
|
||||
.insert = { .cutscene = &CUTSCENE_TEST_INSERT_NO_CAPACITY_SNIPPET }
|
||||
}
|
||||
};
|
||||
static cutscene_t CUTSCENE_TEST_INSERT_NO_CAPACITY_OUTER = {
|
||||
.items = CUTSCENE_TEST_INSERT_NO_CAPACITY_OUTER_ITEMS,
|
||||
.itemCount = 1,
|
||||
.itemsMax = 1,
|
||||
.pause = CUTSCENE_PAUSE_NONE
|
||||
};
|
||||
|
||||
static void test_cutsceneInsertAssertsWhenExceedingItemsMax(void **state) {
|
||||
|
||||
cutsceneSystemInit();
|
||||
|
||||
// 5 levels of INSERT deep, one past CUTSCENE_INSERT_STACK_MAX (4) --
|
||||
// all cascade synchronously within this one call, since each level's
|
||||
// only item is the INSERT starting immediately.
|
||||
expect_assert_failure(
|
||||
cutsceneSystemStartCutscene(&CUTSCENE_TEST_INSERT_OVERFLOW_LEVEL0)
|
||||
cutsceneSystemStartCutscene(&CUTSCENE_TEST_INSERT_NO_CAPACITY_OUTER)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -469,22 +449,26 @@ static void noopInsertCallback(void *userData) {}
|
||||
static cutsceneitem_t CUTSCENE_TEST_INSERT_PERSIST_SNIPPET_ITEMS[] = {
|
||||
{ .type = CUTSCENE_ITEM_TYPE_CALLBACK, .callback = noopInsertCallback }
|
||||
};
|
||||
static const cutscene_t CUTSCENE_TEST_INSERT_PERSIST_SNIPPET = {
|
||||
static cutscene_t CUTSCENE_TEST_INSERT_PERSIST_SNIPPET = {
|
||||
.items = CUTSCENE_TEST_INSERT_PERSIST_SNIPPET_ITEMS,
|
||||
.itemCount = sizeof(CUTSCENE_TEST_INSERT_PERSIST_SNIPPET_ITEMS) /
|
||||
sizeof(cutsceneitem_t),
|
||||
.itemsMax = sizeof(CUTSCENE_TEST_INSERT_PERSIST_SNIPPET_ITEMS) /
|
||||
sizeof(cutsceneitem_t),
|
||||
.pause = CUTSCENE_PAUSE_ALL
|
||||
};
|
||||
|
||||
static cutsceneitem_t CUTSCENE_TEST_INSERT_PERSIST_OUTER_ITEMS[] = {
|
||||
// 1 item to start, +1 spare slot for the snippet's single item.
|
||||
static cutsceneitem_t CUTSCENE_TEST_INSERT_PERSIST_OUTER_ITEMS[2] = {
|
||||
{
|
||||
.type = CUTSCENE_ITEM_TYPE_INSERT,
|
||||
.insert = { .cutscene = &CUTSCENE_TEST_INSERT_PERSIST_SNIPPET, .name = NULL }
|
||||
.insert = { .cutscene = &CUTSCENE_TEST_INSERT_PERSIST_SNIPPET }
|
||||
}
|
||||
};
|
||||
static const cutscene_t CUTSCENE_TEST_INSERT_PERSIST_OUTER = {
|
||||
static cutscene_t CUTSCENE_TEST_INSERT_PERSIST_OUTER = {
|
||||
.items = CUTSCENE_TEST_INSERT_PERSIST_OUTER_ITEMS,
|
||||
.itemCount = sizeof(CUTSCENE_TEST_INSERT_PERSIST_OUTER_ITEMS) /
|
||||
.itemCount = 1,
|
||||
.itemsMax = sizeof(CUTSCENE_TEST_INSERT_PERSIST_OUTER_ITEMS) /
|
||||
sizeof(cutsceneitem_t),
|
||||
.pause = CUTSCENE_PAUSE_NPC
|
||||
};
|
||||
@@ -501,10 +485,10 @@ static void test_cutsceneInsertDoesNotResetPauseOrInteractEntities(
|
||||
&CUTSCENE_TEST_INSERT_PERSIST_OUTER, &ENTITIES[3], &ENTITIES[4]
|
||||
);
|
||||
|
||||
// The INSERT item's Start already cascaded into the snippet by now.
|
||||
assert_ptr_equal(
|
||||
CUTSCENE_SYSTEM.scene, &CUTSCENE_TEST_INSERT_PERSIST_SNIPPET
|
||||
);
|
||||
// The INSERT item's Start already spliced the snippet into place and
|
||||
// cascaded into it by now.
|
||||
assert_ptr_equal(CUTSCENE_SYSTEM.scene, &CUTSCENE_TEST_INSERT_PERSIST_OUTER);
|
||||
assert_int_equal(CUTSCENE_SYSTEM.scene->itemCount, 2);
|
||||
assert_ptr_equal(CUTSCENE_SYSTEM.entityInteract, &ENTITIES[3]);
|
||||
assert_ptr_equal(CUTSCENE_SYSTEM.entityInteracted, &ENTITIES[4]);
|
||||
// The snippet declares ALL, but INSERT doesn't apply it -- the outer
|
||||
@@ -526,7 +510,7 @@ int main(int argc, char** argv) {
|
||||
cmocka_unit_test(test_cutsceneInsertSplicesItemsInPlaceThenResumes),
|
||||
cmocka_unit_test(test_cutsceneInsertAsLastItemEndsCutsceneNaturally),
|
||||
cmocka_unit_test(test_cutsceneInsertNestsThroughMultipleLevels),
|
||||
cmocka_unit_test(test_cutsceneInsertAssertsWhenNestingExceedsStackMax),
|
||||
cmocka_unit_test(test_cutsceneInsertAssertsWhenExceedingItemsMax),
|
||||
cmocka_unit_test(test_cutsceneInsertDoesNotResetPauseOrInteractEntities),
|
||||
};
|
||||
|
||||
|
||||
@@ -14,9 +14,10 @@
|
||||
static cutsceneitem_t CUTSCENE_TEST_INTERACT_ITEMS[] = {
|
||||
{ .type = CUTSCENE_ITEM_TYPE_WAIT, .wait = 1.0f }
|
||||
};
|
||||
static const cutscene_t CUTSCENE_TEST_INTERACT = {
|
||||
static cutscene_t CUTSCENE_TEST_INTERACT = {
|
||||
.items = CUTSCENE_TEST_INTERACT_ITEMS,
|
||||
.itemCount = 1,
|
||||
.itemsMax = 1,
|
||||
.pause = CUTSCENE_PAUSE_NONE
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user