Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 1 addition & 14 deletions ss_player/ss_internal_player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1355,15 +1355,6 @@ void SsInternalPlayer::_setup_instance_children() {
auto pt = p->part_type_as_PartTypeInstance();
if (!pt) continue;

// Cyclic / runaway-nesting guard: instance children live one level
// deeper than this player. Refuse to descend past MAX_INSTANCE_DEPTH so
// a cyclic reference (A → B → A authoring mistake) can't recurse until
// the stack overflows on load.
if (_instance_depth + 1 >= MAX_INSTANCE_DEPTH) {
WARN_PRINT(vformat("[SS] instance part %d: nesting exceeded %d levels; skipping to guard against cyclic references", i, MAX_INSTANCE_DEPTH));
continue;
}

String pack_name = pt->ref_anime_pack() ? String::utf8(pt->ref_anime_pack()->c_str()) : String();
String anim_name = pt->ref_anime_name() ? String::utf8(pt->ref_anime_name()->c_str()) : String();
uint32_t pack_name_hash = pt->ref_anime_pack_hash();
Expand All @@ -1378,7 +1369,6 @@ void SsInternalPlayer::_setup_instance_children() {

SsInternalPlayer* child = memnew(SsInternalPlayer);
child->setParentDriven(true);
child->setInstanceDepth(_instance_depth + 1);
child->setSubFrameEnabled(_sub_frame_enabled);
// Hand the child the SSAB that actually contains the referenced
// animation — may be `_ssabRes` itself or an external sibling.
Expand Down Expand Up @@ -2608,10 +2598,7 @@ void SsInternalPlayer::_fetchAnimation() {
}

// Recursive setup — instance children also populate their own
// `_instance_children`, so nested Instance parts are supported. Cross-SSAB
// cycles (A → B → A authoring mistakes) are bounded by MAX_INSTANCE_DEPTH:
// `_setup_instance_children` stops spawning children past that depth (with
// a warning) instead of recursing until the stack overflows on load.
// `_instance_children`, so nested Instance parts are supported.
_setup_instance_children();
_setup_effect_slots();

Expand Down
11 changes: 0 additions & 11 deletions ss_player/ss_internal_player.h
Original file line number Diff line number Diff line change
Expand Up @@ -161,14 +161,6 @@ class SsInternalPlayer {
void setParentDriven(bool p_enabled);
bool isParentDriven() const { return _parent_driven; }

// Nesting depth within an Instance-part chain (0 = the root player the host
// owns). `_setup_instance_children` sets each spawned child to parent depth
// + 1 and refuses to descend past `MAX_INSTANCE_DEPTH`, guarding against
// cyclic Instance references (A → B → A authoring mistakes) that would
// otherwise recurse until the stack overflows on load.
void setInstanceDepth(int p_depth) { _instance_depth = p_depth; }
int getInstanceDepth() const { return _instance_depth; }

// Per-tick update (in seconds; the host typically passes
// `process_delta_time`). No-op when paused or in instance-child mode.
void update(float delta_seconds);
Expand Down Expand Up @@ -328,9 +320,6 @@ class SsInternalPlayer {
float _speed_rate = 1.0f;
bool _sub_frame_enabled = false;
bool _parent_driven = false;
int _instance_depth = 0;
// Hard cap on Instance-part nesting depth; see `setInstanceDepth`.
static constexpr int MAX_INSTANCE_DEPTH = 16;

SsPlayerEventSink* _event_sink = nullptr;

Expand Down
Loading