// Warning: Any Runtime.Object content referenced within the StoryState will // be re-referenced rather than cloned. This is generally okay though since // Runtime.Objects are treated as immutable after they've been set up. // (e.g. we don't edit a Runtime.StringValue after it's been created an added.) // I wonder if there's a sensible way to enforce that..?? internal StoryState CopyAndStartPatching() { var copy = new StoryState(story); copy._patch = new StatePatch(_patch); copy.outputStream.AddRange(_outputStream); copy.OutputStreamDirty(); copy._currentChoices.AddRange(_currentChoices); if (hasError) { copy.currentErrors = new List <string> (); copy.currentErrors.AddRange(currentErrors); } if (hasWarning) { copy.currentWarnings = new List <string> (); copy.currentWarnings.AddRange(currentWarnings); } copy.callStack = new CallStack(callStack); // ref copy - exactly the same variables state! // we're expecting not to read it only while in patch mode // (though the callstack will be modified) copy.variablesState = variablesState; copy.variablesState.callStack = copy.callStack; copy.variablesState.patch = copy._patch; copy.evaluationStack.AddRange(evaluationStack); if (!divertedPointer.isNull) { copy.divertedPointer = divertedPointer; } copy.previousPointer = previousPointer; // visit counts and turn indicies will be read only, not modified // while in patch mode copy._visitCounts = _visitCounts; copy._turnIndices = _turnIndices; copy.currentTurnIndex = currentTurnIndex; copy.storySeed = storySeed; copy.previousRandom = previousRandom; copy.didSafeExit = didSafeExit; return(copy); }
// Warning: Any Runtime.Object content referenced within the StoryState will // be re-referenced rather than cloned. This is generally okay though since // Runtime.Objects are treated as immutable after they've been set up. // (e.g. we don't edit a Runtime.StringValue after it's been created an added.) // I wonder if there's a sensible way to enforce that..?? public StoryState CopyAndStartPatching() { var copy = new StoryState(story); copy._patch = new StatePatch(_patch); // Hijack the new default flow to become a copy of our current one // If the patch is applied, then this new flow will replace the old one in _namedFlows copy._currentFlow.name = _currentFlow.name; copy._currentFlow.callStack = new CallStack(_currentFlow.callStack); copy._currentFlow.currentChoices.AddRange(_currentFlow.currentChoices); copy._currentFlow.outputStream.AddRange(_currentFlow.outputStream); copy.OutputStreamDirty(); // The copy of the state has its own copy of the named flows dictionary, // except with the current flow replaced with the copy above // (Assuming we're in multi-flow mode at all. If we're not then // the above copy is simply the default flow copy and we're done) if (_namedFlows != null) { copy._namedFlows = new Dictionary <string, Flow>(); foreach (var namedFlow in _namedFlows) { copy._namedFlows[namedFlow.Key] = namedFlow.Value; } copy._namedFlows[_currentFlow.name] = copy._currentFlow; } if (hasError) { copy.currentErrors = new List <string> (); copy.currentErrors.AddRange(currentErrors); } if (hasWarning) { copy.currentWarnings = new List <string> (); copy.currentWarnings.AddRange(currentWarnings); } // ref copy - exactly the same variables state! // we're expecting not to read it only while in patch mode // (though the callstack will be modified) copy.variablesState = variablesState; copy.variablesState.callStack = copy.callStack; copy.variablesState.patch = copy._patch; copy.evaluationStack.AddRange(evaluationStack); if (!divertedPointer.isNull) { copy.divertedPointer = divertedPointer; } copy.previousPointer = previousPointer; // visit counts and turn indicies will be read only, not modified // while in patch mode copy._visitCounts = _visitCounts; copy._turnIndices = _turnIndices; copy.currentTurnIndex = currentTurnIndex; copy.storySeed = storySeed; copy.previousRandom = previousRandom; copy.didSafeExit = didSafeExit; return(copy); }