int FStateDefinitions::FinishStates (FActorInfo *actor, AActor *defaults) { int count = StateArray.Size(); if (count > 0) { FState *realstates = new FState[count]; int i; memcpy(realstates, &StateArray[0], count*sizeof(FState)); actor->OwnedStates = realstates; actor->NumOwnedStates = count; // adjust the state pointers // In the case new states are added these must be adjusted, too! FixStatePointers(actor, StateLabels); // Fix state pointers that are gotos ResolveGotoLabels(actor, defaults, StateLabels); for (i = 0; i < count; i++) { // resolve labels and jumps switch (realstates[i].DefineFlags) { case SDF_STOP: // stop realstates[i].NextState = NULL; break; case SDF_WAIT: // wait realstates[i].NextState = &realstates[i]; break; case SDF_NEXT: // next realstates[i].NextState = (i < count-1 ? &realstates[i+1] : &realstates[0]); break; case SDF_INDEX: // loop realstates[i].NextState = &realstates[(size_t)realstates[i].NextState-1]; break; case SDF_LABEL: realstates[i].NextState = ResolveGotoLabel(defaults, actor->Class, (char *)realstates[i].NextState); break; } } } else { // Fix state pointers that are gotos ResolveGotoLabels(actor, defaults, StateLabels); } return count; }
void FStateDefinitions::ResolveGotoLabels (PClassActor *actor, AActor *defaults, TArray<FStateDefine> & list) { for (unsigned i = 0; i < list.Size(); i++) { if (list[i].State != NULL && list[i].DefineFlags == SDF_LABEL) { // It's not a valid state, so it must be a label string. Resolve it. list[i].State = ResolveGotoLabel (defaults, actor, (char *)list[i].State); list[i].DefineFlags = SDF_STATE; } if (list[i].Children.Size() > 0) ResolveGotoLabels(actor, defaults, list[i].Children); } }