From 1021b150362319654f6a7ddcd38826cfb1391b6e Mon Sep 17 00:00:00 2001 From: chrisgregan Date: Fri, 25 Mar 2016 11:07:17 +0000 Subject: [PATCH 1/3] Fixed CsvParser lineendings --- .../Fungus/Thirdparty/CSVParser/CsvParser.cs | 414 +++++++++--------- 1 file changed, 207 insertions(+), 207 deletions(-) mode change 100755 => 100644 Assets/Fungus/Thirdparty/CSVParser/CsvParser.cs diff --git a/Assets/Fungus/Thirdparty/CSVParser/CsvParser.cs b/Assets/Fungus/Thirdparty/CSVParser/CsvParser.cs old mode 100755 new mode 100644 index 6d77445a..ffc59201 --- a/Assets/Fungus/Thirdparty/CSVParser/CsvParser.cs +++ b/Assets/Fungus/Thirdparty/CSVParser/CsvParser.cs @@ -5,215 +5,215 @@ using System.Text; namespace Ideafixxxer.CsvParser { - public class CsvParser - { - private const char CommaCharacter = ','; - private const char QuoteCharacter = '"'; - - #region Nested types - - private abstract class ParserState - { - public static readonly LineStartState LineStartState = new LineStartState(); - public static readonly ValueStartState ValueStartState = new ValueStartState(); - public static readonly ValueState ValueState = new ValueState(); - public static readonly QuotedValueState QuotedValueState = new QuotedValueState(); - public static readonly QuoteState QuoteState = new QuoteState(); - - public abstract ParserState AnyChar(char ch, ParserContext context); - public abstract ParserState Comma(ParserContext context); - public abstract ParserState Quote(ParserContext context); - public abstract ParserState EndOfLine(ParserContext context); - } - - private class LineStartState : ParserState - { - public override ParserState AnyChar(char ch, ParserContext context) - { - context.AddChar(ch); - return ValueState; - } - - public override ParserState Comma(ParserContext context) - { - context.AddValue(); - return ValueStartState; - } - - public override ParserState Quote(ParserContext context) - { - return QuotedValueState; - } - - public override ParserState EndOfLine(ParserContext context) - { - context.AddLine(); - return LineStartState; - } - } - - private class ValueStartState : LineStartState - { - public override ParserState EndOfLine(ParserContext context) - { - context.AddValue(); - context.AddLine(); - return LineStartState; - } - } - - private class ValueState : ParserState - { - public override ParserState AnyChar(char ch, ParserContext context) - { - context.AddChar(ch); - return ValueState; - } - - public override ParserState Comma(ParserContext context) - { - context.AddValue(); - return ValueStartState; - } - - public override ParserState Quote(ParserContext context) - { - context.AddChar(QuoteCharacter); - return ValueState; - } - - public override ParserState EndOfLine(ParserContext context) - { - context.AddValue(); - context.AddLine(); - return LineStartState; - } - } - - private class QuotedValueState : ParserState - { - public override ParserState AnyChar(char ch, ParserContext context) - { - context.AddChar(ch); - return QuotedValueState; - } - - public override ParserState Comma(ParserContext context) - { - context.AddChar(CommaCharacter); - return QuotedValueState; - } - - public override ParserState Quote(ParserContext context) - { - return QuoteState; - } - - public override ParserState EndOfLine(ParserContext context) - { - context.AddChar('\r'); - context.AddChar('\n'); - return QuotedValueState; - } - } - - private class QuoteState : ParserState - { - public override ParserState AnyChar(char ch, ParserContext context) - { - //undefined, ignore " - context.AddChar(ch); - return QuotedValueState; - } - - public override ParserState Comma(ParserContext context) - { - context.AddValue(); - return ValueStartState; - } - - public override ParserState Quote(ParserContext context) - { - context.AddChar(QuoteCharacter); - return QuotedValueState; - } - - public override ParserState EndOfLine(ParserContext context) - { - context.AddValue(); - context.AddLine(); - return LineStartState; - } - } - - private class ParserContext - { - private readonly StringBuilder _currentValue = new StringBuilder(); - private readonly List _lines = new List(); - private readonly List _currentLine = new List(); - - public void AddChar(char ch) - { - _currentValue.Append(ch); - } - - public void AddValue() - { - _currentLine.Add(_currentValue.ToString()); - _currentValue.Remove(0, _currentValue.Length); - } - - public void AddLine() - { - _lines.Add(_currentLine.ToArray()); - _currentLine.Clear(); - } - - public List GetAllLines() - { - if (_currentValue.Length > 0) - { - AddValue(); - } - if (_currentLine.Count > 0) - { - AddLine(); - } - return _lines; - } - } - - #endregion - - public string[][] Parse(string csvData) - { - var context = new ParserContext(); + public class CsvParser + { + private const char CommaCharacter = ','; + private const char QuoteCharacter = '"'; + + #region Nested types + + private abstract class ParserState + { + public static readonly LineStartState LineStartState = new LineStartState(); + public static readonly ValueStartState ValueStartState = new ValueStartState(); + public static readonly ValueState ValueState = new ValueState(); + public static readonly QuotedValueState QuotedValueState = new QuotedValueState(); + public static readonly QuoteState QuoteState = new QuoteState(); + + public abstract ParserState AnyChar(char ch, ParserContext context); + public abstract ParserState Comma(ParserContext context); + public abstract ParserState Quote(ParserContext context); + public abstract ParserState EndOfLine(ParserContext context); + } + + private class LineStartState : ParserState + { + public override ParserState AnyChar(char ch, ParserContext context) + { + context.AddChar(ch); + return ValueState; + } + + public override ParserState Comma(ParserContext context) + { + context.AddValue(); + return ValueStartState; + } + + public override ParserState Quote(ParserContext context) + { + return QuotedValueState; + } + + public override ParserState EndOfLine(ParserContext context) + { + context.AddLine(); + return LineStartState; + } + } + + private class ValueStartState : LineStartState + { + public override ParserState EndOfLine(ParserContext context) + { + context.AddValue(); + context.AddLine(); + return LineStartState; + } + } + + private class ValueState : ParserState + { + public override ParserState AnyChar(char ch, ParserContext context) + { + context.AddChar(ch); + return ValueState; + } + + public override ParserState Comma(ParserContext context) + { + context.AddValue(); + return ValueStartState; + } + + public override ParserState Quote(ParserContext context) + { + context.AddChar(QuoteCharacter); + return ValueState; + } + + public override ParserState EndOfLine(ParserContext context) + { + context.AddValue(); + context.AddLine(); + return LineStartState; + } + } + + private class QuotedValueState : ParserState + { + public override ParserState AnyChar(char ch, ParserContext context) + { + context.AddChar(ch); + return QuotedValueState; + } + + public override ParserState Comma(ParserContext context) + { + context.AddChar(CommaCharacter); + return QuotedValueState; + } + + public override ParserState Quote(ParserContext context) + { + return QuoteState; + } + + public override ParserState EndOfLine(ParserContext context) + { + context.AddChar('\r'); + context.AddChar('\n'); + return QuotedValueState; + } + } + + private class QuoteState : ParserState + { + public override ParserState AnyChar(char ch, ParserContext context) + { + //undefined, ignore " + context.AddChar(ch); + return QuotedValueState; + } + + public override ParserState Comma(ParserContext context) + { + context.AddValue(); + return ValueStartState; + } + + public override ParserState Quote(ParserContext context) + { + context.AddChar(QuoteCharacter); + return QuotedValueState; + } + + public override ParserState EndOfLine(ParserContext context) + { + context.AddValue(); + context.AddLine(); + return LineStartState; + } + } + + private class ParserContext + { + private readonly StringBuilder _currentValue = new StringBuilder(); + private readonly List _lines = new List(); + private readonly List _currentLine = new List(); + + public void AddChar(char ch) + { + _currentValue.Append(ch); + } + + public void AddValue() + { + _currentLine.Add(_currentValue.ToString()); + _currentValue.Remove(0, _currentValue.Length); + } + + public void AddLine() + { + _lines.Add(_currentLine.ToArray()); + _currentLine.Clear(); + } + + public List GetAllLines() + { + if (_currentValue.Length > 0) + { + AddValue(); + } + if (_currentLine.Count > 0) + { + AddLine(); + } + return _lines; + } + } + + #endregion + + public string[][] Parse(string csvData) + { + var context = new ParserContext(); // Handle both Windows and Mac line endings string[] lines = csvData.Split(new string[] { "\r\n", "\n" }, StringSplitOptions.RemoveEmptyEntries); - ParserState currentState = ParserState.LineStartState; - foreach (string next in lines) - { - foreach (char ch in next) - { - switch (ch) - { - case CommaCharacter: - currentState = currentState.Comma(context); - break; - case QuoteCharacter: - currentState = currentState.Quote(context); - break; - default: - currentState = currentState.AnyChar(ch, context); - break; - } - } - currentState = currentState.EndOfLine(context); - } - List allLines = context.GetAllLines(); - return allLines.ToArray(); - } - } + ParserState currentState = ParserState.LineStartState; + foreach (string next in lines) + { + foreach (char ch in next) + { + switch (ch) + { + case CommaCharacter: + currentState = currentState.Comma(context); + break; + case QuoteCharacter: + currentState = currentState.Quote(context); + break; + default: + currentState = currentState.AnyChar(ch, context); + break; + } + } + currentState = currentState.EndOfLine(context); + } + List allLines = context.GetAllLines(); + return allLines.ToArray(); + } + } } \ No newline at end of file From c33bb139b1046c32b01d4650bb9f7aa328da8e0e Mon Sep 17 00:00:00 2001 From: chrisgregan Date: Fri, 25 Mar 2016 11:31:47 +0000 Subject: [PATCH 2/3] Changes to support Fungus Script execution --- Assets/Fungus/Flowchart/Scripts/Block.cs | 41 +++--- .../Fungus/Flowchart/Scripts/Commands/Call.cs | 4 +- Assets/Fungus/Flowchart/Scripts/Flowchart.cs | 131 +++++++++++------- .../Fungus/Narrative/Scripts/Commands/Say.cs | 2 +- Assets/Fungus/Narrative/Scripts/MenuDialog.cs | 10 +- Assets/Fungus/Narrative/Scripts/SayDialog.cs | 10 +- Assets/Fungus/UI/Scripts/Writer.cs | 8 +- 7 files changed, 124 insertions(+), 82 deletions(-) diff --git a/Assets/Fungus/Flowchart/Scripts/Block.cs b/Assets/Fungus/Flowchart/Scripts/Block.cs index 8b3c0685..2c7760c0 100644 --- a/Assets/Fungus/Flowchart/Scripts/Block.cs +++ b/Assets/Fungus/Flowchart/Scripts/Block.cs @@ -142,26 +142,25 @@ namespace Fungus return executionCount; } - public virtual bool Execute(Action onComplete = null) + /// + /// Execute the Block in a coroutine. Only one running instance of each Block is permitted. + /// + /// Index of command to start execution at + /// Delegate function to call when execution completes + public virtual IEnumerator Execute(int commandIndex = 0, Action onComplete = null) { - if (executionState != ExecutionState.Idle) - { - return false; - } - - if (!executionInfoSet) - { - SetExecutionInfo(); - } + if (executionState != ExecutionState.Idle) + { + yield break; + } - executionCount++; - StartCoroutine(ExecuteBlock(onComplete)); + if (!executionInfoSet) + { + SetExecutionInfo(); + } - return true; - } + executionCount++; - protected virtual IEnumerator ExecuteBlock(Action onComplete = null) - { Flowchart flowchart = GetFlowchart(); executionState = ExecutionState.Executing; @@ -175,6 +174,8 @@ namespace Fungus } #endif + jumpToCommandIndex = commandIndex; + int i = 0; while (true) { @@ -248,10 +249,10 @@ namespace Fungus executionState = ExecutionState.Idle; activeCommand = null; - if (onComplete != null) - { - onComplete(); - } + if (onComplete != null) + { + onComplete(); + } } public virtual void Stop() diff --git a/Assets/Fungus/Flowchart/Scripts/Commands/Call.cs b/Assets/Fungus/Flowchart/Scripts/Commands/Call.cs index d766d3a3..b14f291f 100644 --- a/Assets/Fungus/Flowchart/Scripts/Commands/Call.cs +++ b/Assets/Fungus/Flowchart/Scripts/Commands/Call.cs @@ -64,12 +64,12 @@ namespace Fungus flowchart.selectedBlock = targetBlock; } - targetBlock.Execute(onComplete); + StartCoroutine(targetBlock.Execute(0, onComplete)); } else { // Execute block in another Flowchart - targetFlowchart.ExecuteBlock(targetBlock, onComplete); + targetFlowchart.ExecuteBlock(targetBlock, 0, onComplete); } } diff --git a/Assets/Fungus/Flowchart/Scripts/Flowchart.cs b/Assets/Fungus/Flowchart/Scripts/Flowchart.cs index c7e0893a..faa7003f 100644 --- a/Assets/Fungus/Flowchart/Scripts/Flowchart.cs +++ b/Assets/Fungus/Flowchart/Scripts/Flowchart.cs @@ -371,61 +371,50 @@ namespace Fungus } /** - * Start running another Flowchart by executing a specific child block. - * The block must be in an idle state to be executed. + * Execute a child block in the Flowchart. * You can use this method in a UI event. e.g. to handle a button click. + * Returns true if the Block started execution. */ - public virtual void ExecuteBlock(string blockName) - { - Block [] blocks = GetComponentsInChildren(); - foreach (Block block in blocks) - { - if (block.blockName == blockName) - { - ExecuteBlock(block); - } - } - } - - /** - * Sends a message to this Flowchart only. - * Any block with a matching MessageReceived event handler will start executing. - */ - public virtual void SendFungusMessage(string messageName) - { - MessageReceived[] eventHandlers = GetComponentsInChildren(); - foreach (MessageReceived eventHandler in eventHandlers) - { - eventHandler.OnSendFungusMessage(messageName); - } - } - - /** - * Sends a message to all Flowchart objects in the current scene. - * Any block with a matching MessageReceived event handler will start executing. - */ - public static void BroadcastFungusMessage(string messageName) + public virtual bool ExecuteBlock(string blockName) { - MessageReceived[] eventHandlers = GameObject.FindObjectsOfType(); - foreach (MessageReceived eventHandler in eventHandlers) - { - eventHandler.OnSendFungusMessage(messageName); - } + Block block = null; + foreach (Block b in GetComponentsInChildren()) + { + if (b.blockName == blockName) + { + block = b; + break; + } + } + + if (block == null) + { + Debug.LogError("Block " + blockName + "does not exist"); + return false; + } + + return ExecuteBlock(block); } /** - * Start executing a specific child block in the flowchart. + * Execute a child block in the flowchart. * The block must be in an idle state to be executed. + * This version provides extra options to control how the block is executed. * Returns true if the Block started execution. */ - public virtual bool ExecuteBlock(Block block, Action onComplete = null) + public virtual bool ExecuteBlock(Block block, int commandIndex = 0, Action onComplete = null) { - // Block must be a component of the Flowchart game object - if (block == null || - block.gameObject != gameObject) - { - return false; - } + if (block == null) + { + Debug.LogError("Block must not be null"); + return false; + } + + if (block.gameObject != gameObject) + { + Debug.LogError("Block must belong to the same gameobject as this Flowchart"); + return false; + } // Can't restart a running block, have to wait until it's idle again if (block.IsExecuting()) @@ -433,10 +422,10 @@ namespace Fungus return false; } - // Execute the first command in the command list - block.Execute(onComplete); + // Start executing the Block as a new coroutine + StartCoroutine(block.Execute(commandIndex, onComplete)); - return true; + return true; } /** @@ -454,6 +443,32 @@ namespace Fungus } } + /** + * Sends a message to this Flowchart only. + * Any block with a matching MessageReceived event handler will start executing. + */ + public virtual void SendFungusMessage(string messageName) + { + MessageReceived[] eventHandlers = GetComponentsInChildren(); + foreach (MessageReceived eventHandler in eventHandlers) + { + eventHandler.OnSendFungusMessage(messageName); + } + } + + /** + * Sends a message to all Flowchart objects in the current scene. + * Any block with a matching MessageReceived event handler will start executing. + */ + public static void BroadcastFungusMessage(string messageName) + { + MessageReceived[] eventHandlers = GameObject.FindObjectsOfType(); + foreach (MessageReceived eventHandler in eventHandlers) + { + eventHandler.OnSendFungusMessage(messageName); + } + } + /** * Returns a new variable key that is guaranteed not to clash with any existing variable in the list. */ @@ -590,6 +605,26 @@ namespace Fungus } } + /** + * Returns the variable with the specified key, or null if the key is not found. + * You will need to cast the returned variable to the correct sub-type. + * You can then access the variable's value using the Value property. e.g. + * BooleanVariable boolVar = flowchart.GetVariable("MyBool") as BooleanVariable; + * boolVar.Value = false; + */ + public Variable GetVariable(string key) + { + foreach (Variable variable in variables) + { + if (variable != null && variable.key == key) + { + return variable; + } + } + + return null; + } + /** * Returns the variable with the specified key, or null if the key is not found. * You can then access the variable's value using the Value property. e.g. diff --git a/Assets/Fungus/Narrative/Scripts/Commands/Say.cs b/Assets/Fungus/Narrative/Scripts/Commands/Say.cs index b0fde7f8..34f35f61 100644 --- a/Assets/Fungus/Narrative/Scripts/Commands/Say.cs +++ b/Assets/Fungus/Narrative/Scripts/Commands/Say.cs @@ -99,7 +99,7 @@ namespace Fungus string subbedText = flowchart.SubstituteVariables(displayText); - sayDialog.Say(subbedText, !extendPrevious, waitForClick, fadeWhenDone, voiceOverClip, stopVoiceover, delegate { + sayDialog.Say(subbedText, !extendPrevious, waitForClick, fadeWhenDone, stopVoiceover, voiceOverClip, delegate { Continue(); }); } diff --git a/Assets/Fungus/Narrative/Scripts/MenuDialog.cs b/Assets/Fungus/Narrative/Scripts/MenuDialog.cs index 7eeb55bd..941a93d0 100644 --- a/Assets/Fungus/Narrative/Scripts/MenuDialog.cs +++ b/Assets/Fungus/Narrative/Scripts/MenuDialog.cs @@ -13,8 +13,11 @@ namespace Fungus // Currently active Menu Dialog used to display Menu options public static MenuDialog activeMenuDialog; - protected Button[] cachedButtons; - protected Slider cachedSlider; + [NonSerialized] + public Button[] cachedButtons; + + [NonSerialized] + public Slider cachedSlider; public static MenuDialog GetMenuDialog() { @@ -139,7 +142,7 @@ namespace Fungus return addedOption; } - protected virtual void HideSayDialog() + public virtual void HideSayDialog() { SayDialog sayDialog = SayDialog.GetSayDialog(); if (sayDialog != null) @@ -150,7 +153,6 @@ namespace Fungus public virtual void ShowTimer(float duration, Block targetBlock) { - if (cachedSlider != null) { cachedSlider.gameObject.SetActive(true); diff --git a/Assets/Fungus/Narrative/Scripts/SayDialog.cs b/Assets/Fungus/Narrative/Scripts/SayDialog.cs index 3f3d8c90..ff4e0b1b 100644 --- a/Assets/Fungus/Narrative/Scripts/SayDialog.cs +++ b/Assets/Fungus/Narrative/Scripts/SayDialog.cs @@ -126,12 +126,12 @@ namespace Fungus } } - public virtual void Say(string text, bool clearPrevious, bool waitForInput, bool fadeWhenDone, AudioClip voiceOverClip, bool stopVoiceover, Action onComplete) + public virtual void Say(string text, bool clearPrevious, bool waitForInput, bool fadeWhenDone, bool stopVoiceover, AudioClip voiceOverClip, Action onComplete) { - StartCoroutine(SayInternal(text, clearPrevious, waitForInput, fadeWhenDone, voiceOverClip, stopVoiceover, onComplete)); + StartCoroutine(SayInternal(text, clearPrevious, waitForInput, fadeWhenDone, stopVoiceover, voiceOverClip, onComplete)); } - protected virtual IEnumerator SayInternal(string text, bool clearPrevious, bool waitForInput, bool fadeWhenDone, AudioClip voiceOverClip, bool stopVoiceover, Action onComplete) + public virtual IEnumerator SayInternal(string text, bool clearPrevious, bool waitForInput, bool fadeWhenDone, bool stopVoiceover, AudioClip voiceOverClip, Action onComplete) { Writer writer = GetWriter(); @@ -144,6 +144,8 @@ namespace Fungus } } + gameObject.SetActive(true); + this.fadeWhenDone = fadeWhenDone; // Voice over clip takes precedence over a character sound effect if provided @@ -158,8 +160,8 @@ namespace Fungus { soundEffectClip = speakingCharacter.soundEffect; } - writer.Write(text, clearPrevious, waitForInput, stopVoiceover, soundEffectClip, onComplete); + yield return writer.Write(text, clearPrevious, waitForInput, stopVoiceover, soundEffectClip, onComplete); } protected virtual void LateUpdate() diff --git a/Assets/Fungus/UI/Scripts/Writer.cs b/Assets/Fungus/UI/Scripts/Writer.cs index 7289f8f6..df6ad23c 100644 --- a/Assets/Fungus/UI/Scripts/Writer.cs +++ b/Assets/Fungus/UI/Scripts/Writer.cs @@ -317,7 +317,7 @@ namespace Fungus } } - public virtual void Write(string content, bool clear, bool waitForInput, bool stopAudio, AudioClip audioClip, Action onComplete) + public virtual IEnumerator Write(string content, bool clear, bool waitForInput, bool stopAudio, AudioClip audioClip, Action onComplete) { if (clear) { @@ -326,7 +326,7 @@ namespace Fungus if (!HasTextObject()) { - return; + yield break; } // If this clip is null then WriterAudio will play the default sound effect (if any) @@ -341,7 +341,9 @@ namespace Fungus TextTagParser tagParser = new TextTagParser(); List tokens = tagParser.Tokenize(tokenText); - StartCoroutine(ProcessTokens(tokens, stopAudio, onComplete)); + gameObject.SetActive(true); + + yield return StartCoroutine(ProcessTokens(tokens, stopAudio, onComplete)); } virtual protected bool CheckParamCount(List paramList, int count) From e49f77d53f99cd929b76e9d0979ed2a8cd77cbd5 Mon Sep 17 00:00:00 2001 From: chrisgregan Date: Fri, 25 Mar 2016 11:37:28 +0000 Subject: [PATCH 3/3] Fixed invoke test scene --- Assets/Tests/Scripting/Scripting.unity | 38 ++------------------------ 1 file changed, 2 insertions(+), 36 deletions(-) diff --git a/Assets/Tests/Scripting/Scripting.unity b/Assets/Tests/Scripting/Scripting.unity index 2676cb12..1f6e9446 100644 --- a/Assets/Tests/Scripting/Scripting.unity +++ b/Assets/Tests/Scripting/Scripting.unity @@ -3005,7 +3005,7 @@ MonoBehaviour: targetComponentFullname: UnityEngine.Component[] targetComponentText: Flowchart targetMethod: ExecuteBlock - targetMethodText: 'ExecuteBlock (String, Int32, Action): Void' + targetMethodText: 'ExecuteBlock (String): Boolean' methodParameters: - objValue: typeAssemblyname: System.String, mscorlib, Version=2.0.0.0, Culture=neutral, @@ -3024,43 +3024,9 @@ MonoBehaviour: vector2Value: {x: 0, y: 0} vector3Value: {x: 0, y: 0, z: 0} variableKey: - - objValue: - typeAssemblyname: System.Int32, mscorlib, Version=2.0.0.0, Culture=neutral, - PublicKeyToken=b77a5c561934e089 - typeFullname: System.Int32 - intValue: 0 - boolValue: 0 - floatValue: 0 - stringValue: - colorValue: {r: 0, g: 0, b: 0, a: 0} - gameObjectValue: {fileID: 0} - materialValue: {fileID: 0} - objectValue: {fileID: 0} - spriteValue: {fileID: 0} - textureValue: {fileID: 0} - vector2Value: {x: 0, y: 0} - vector3Value: {x: 0, y: 0, z: 0} - variableKey: - - objValue: - typeAssemblyname: System.Action, System.Core, Version=3.5.0.0, Culture=neutral, - PublicKeyToken=b77a5c561934e089 - typeFullname: System.Action - intValue: 0 - boolValue: 0 - floatValue: 0 - stringValue: - colorValue: {r: 0, g: 0, b: 0, a: 0} - gameObjectValue: {fileID: 0} - materialValue: {fileID: 0} - objectValue: {fileID: 0} - spriteValue: {fileID: 0} - textureValue: {fileID: 0} - vector2Value: {x: 0, y: 0} - vector3Value: {x: 0, y: 0, z: 0} - variableKey: saveReturnValue: 0 returnValueVariableKey: - returnValueType: System.Void + returnValueType: System.Boolean showInherited: 0 callMode: 0 --- !u!114 &1618689151