├── .gitignore ├── .src ├── .gitignore ├── Cradle.Editor │ ├── Cradle.Editor.MD.csproj │ ├── Cradle.Editor.VS.csproj │ ├── Editor │ │ ├── Attributes.cs │ │ ├── CradleAssetProcessor.cs │ │ ├── Exceptions.cs │ │ ├── Importers │ │ │ ├── TweeImporter.cs │ │ │ └── TwineHtmlImporter.cs │ │ ├── PassageData.cs │ │ ├── StoryFormatTranscoder.cs │ │ ├── StoryFormats │ │ │ ├── Harlowe │ │ │ │ ├── HarloweCodeGenMacros.cs │ │ │ │ └── HarloweTranscoder.cs │ │ │ └── Sugar │ │ │ │ ├── SugarCodeGenMacros.cs │ │ │ │ └── SugarTranscoder.cs │ │ ├── StoryImporter.cs │ │ ├── StoryInspector.cs │ │ ├── ThirdParty │ │ │ └── FullSerializer │ │ │ │ ├── Converters │ │ │ │ ├── Unity │ │ │ │ │ ├── AnimationCurve_DirectConverter.cs │ │ │ │ │ ├── Bounds_DirectConverter.cs │ │ │ │ │ ├── Gradient_DirectConverter.cs │ │ │ │ │ ├── Keyframe_DirectConverter.cs │ │ │ │ │ ├── LayerMask_DirectConverter.cs │ │ │ │ │ └── Rect_DirectConverter.cs │ │ │ │ ├── fsArrayConverter.cs │ │ │ │ ├── fsDateConverter.cs │ │ │ │ ├── fsDictionaryConverter.cs │ │ │ │ ├── fsEnumConverter.cs │ │ │ │ ├── fsForwardConverter.cs │ │ │ │ ├── fsGuidConverter.cs │ │ │ │ ├── fsIEnumerableConverter.cs │ │ │ │ ├── fsKeyValuePairConverter.cs │ │ │ │ ├── fsNullableConverter.cs │ │ │ │ ├── fsPrimitiveConverter.cs │ │ │ │ ├── fsReflectedConverter.cs │ │ │ │ ├── fsTypeConverter.cs │ │ │ │ └── fsWeakReferenceConverter.cs │ │ │ │ ├── Internal │ │ │ │ ├── fsCyclicReferenceManager.cs │ │ │ │ ├── fsOption.cs │ │ │ │ ├── fsPortableReflection.cs │ │ │ │ ├── fsTypeExtensions.cs │ │ │ │ ├── fsVersionManager.cs │ │ │ │ └── fsVersionedType.cs │ │ │ │ ├── Reflection │ │ │ │ ├── fsMetaProperty.cs │ │ │ │ ├── fsMetaType.cs │ │ │ │ ├── fsReflectionUtility.cs │ │ │ │ └── fsTypeLookup.cs │ │ │ │ ├── fsAotCompilationManager.cs │ │ │ │ ├── fsBaseConverter.cs │ │ │ │ ├── fsConfig.cs │ │ │ │ ├── fsContext.cs │ │ │ │ ├── fsConverter.cs │ │ │ │ ├── fsConverterRegistrar.cs │ │ │ │ ├── fsData.cs │ │ │ │ ├── fsDirectConverter.cs │ │ │ │ ├── fsExceptions.cs │ │ │ │ ├── fsISerializationCallbacks.cs │ │ │ │ ├── fsIgnoreAttribute.cs │ │ │ │ ├── fsJsonParser.cs │ │ │ │ ├── fsJsonPrinter.cs │ │ │ │ ├── fsMemberSerialization.cs │ │ │ │ ├── fsObjectAttribute.cs │ │ │ │ ├── fsObjectProcessor.cs │ │ │ │ ├── fsPropertyAttribute.cs │ │ │ │ ├── fsResult.cs │ │ │ │ └── fsSerializer.cs │ │ └── Utils │ │ │ ├── CodeGenUtils.cs │ │ │ ├── EditorFileUtil.cs │ │ │ └── PhantomJS.cs │ └── Properties │ │ └── AssemblyInfo.cs ├── Cradle.MD.sln ├── Cradle.VS.sln └── Cradle │ ├── Core │ ├── Attributes.cs │ ├── Exceptions.cs │ ├── Extensions.cs │ ├── OutputTypes │ │ ├── Abort.cs │ │ ├── Embed.cs │ │ ├── HtmlTag.cs │ │ ├── LineBreak.cs │ │ ├── StoryLink.cs │ │ ├── StoryPassage.cs │ │ ├── StoryText.cs │ │ └── StyleGroup.cs │ ├── RuntimeMacros.cs │ ├── RuntimeVars.cs │ ├── Story.cs │ ├── StoryOutput.cs │ ├── StoryVar.cs │ ├── StyleScope.cs │ ├── VarType.cs │ └── VarTypes │ │ ├── BoolService.cs │ │ ├── DoubleService.cs │ │ ├── IntService.cs │ │ ├── StringService.cs │ │ └── Style.cs │ ├── Cradle.MD.csproj │ ├── Cradle.VS.csproj │ ├── Properties │ └── AssemblyInfo.cs │ └── StoryFormats │ ├── Harlowe │ ├── HarloweHook.cs │ ├── HarloweRuntimeMacros.cs │ ├── HarloweStory.cs │ ├── HarloweUtils.cs │ ├── OutputTypes │ │ └── HarloweLive.cs │ └── VarTypes │ │ ├── HarloweArray.cs │ │ ├── HarloweCollection.cs │ │ ├── HarloweDatamap.cs │ │ ├── HarloweDataset.cs │ │ ├── HarloweHookRef.cs │ │ ├── HarloweSpread.cs │ │ └── HarloweStringService.cs │ └── Sugar │ └── SugarStory.cs ├── Cradle.dll ├── Cradle.dll.mdb ├── Cradle.dll.mdb.meta ├── Cradle.dll.meta ├── Cradle.pdb ├── Cradle.pdb.meta ├── Documentation.meta ├── Documentation ├── Harlowe.md ├── Harlowe.md.meta ├── Sugar.md ├── Sugar.md.meta ├── cradle-logo.png └── cradle-logo.png.meta ├── Editor.meta ├── Editor ├── Cradle.Editor.dll ├── Cradle.Editor.dll.mdb ├── Cradle.Editor.dll.mdb.meta ├── Cradle.Editor.dll.meta ├── Cradle.Editor.pdb ├── Cradle.Editor.pdb.meta ├── Templates.meta ├── Templates │ ├── Story.template │ └── Story.template.meta ├── ThirdParty.meta ├── ThirdParty │ ├── Nustache.meta │ ├── Nustache │ │ ├── Nustache.Core.dll │ │ ├── Nustache.Core.dll.meta │ │ ├── VERSION.md │ │ └── VERSION.md.meta │ ├── PhantomJS.meta │ └── PhantomJS │ │ ├── ChangeLog │ │ ├── ChangeLog.meta │ │ ├── Install.cs │ │ ├── Install.cs.meta │ │ ├── LICENSE.BSD │ │ ├── LICENSE.BSD.meta │ │ ├── README.md │ │ ├── README.md.meta │ │ ├── VERSION.md │ │ ├── VERSION.md.meta │ │ ├── bin.meta │ │ ├── bin │ │ ├── osx.meta │ │ ├── osx │ │ │ ├── phantomjs │ │ │ └── phantomjs.meta │ │ ├── win.meta │ │ └── win │ │ │ ├── phantomjs.exe │ │ │ └── phantomjs.exe.meta │ │ ├── third-party.txt │ │ └── third-party.txt.meta ├── js.meta └── js │ ├── StoryFormats.meta │ ├── StoryFormats │ ├── Harlowe.meta │ ├── Harlowe │ │ ├── harlowe.bridge.js_ │ │ └── harlowe.bridge.js_.meta │ ├── Sugar.meta │ └── Sugar │ │ ├── sugar.bridge.js_ │ │ ├── sugar.bridge.js_.meta │ │ ├── sugar.extensions.js_ │ │ └── sugar.extensions.js_.meta │ ├── phantom.js_ │ └── phantom.js_.meta ├── Examples.meta ├── Examples ├── Clockwork.meta └── Clockwork │ ├── Clockwork.cs │ ├── Clockwork.cs.meta │ ├── Clockwork.html │ ├── Clockwork.html.meta │ ├── Clockwork.unity │ └── Clockwork.unity.meta ├── LICENSE.md ├── LICENSE.md.meta ├── Players.meta ├── Players ├── TwineTMProPlayer.unitypackage ├── TwineTMProPlayer.unitypackage.meta ├── TwineTextPlayer.meta └── TwineTextPlayer │ ├── Script.meta │ ├── Script │ ├── Editor.meta │ ├── Editor │ │ ├── TwineTextElementEditor.cs │ │ └── TwineTextElementEditor.cs.meta │ ├── TwineTextElement.cs │ ├── TwineTextElement.cs.meta │ ├── TwineTextPlayer.cs │ ├── TwineTextPlayer.cs.meta │ ├── WrapLayoutGroup.cs │ ├── WrapLayoutGroup.cs.meta │ ├── WrapLineBreak.cs │ └── WrapLineBreak.cs.meta │ ├── Twine Text Player.prefab │ └── Twine Text Player.prefab.meta ├── README.md ├── README.md.meta ├── Utilities.meta └── Utilities ├── StoryVarSynchronizer.cs └── StoryVarSynchronizer.cs.meta /.gitignore: -------------------------------------------------------------------------------- 1 | Editor/js/output.json 2 | Editor/js/output.json.meta 3 | -------------------------------------------------------------------------------- /.src/.gitignore: -------------------------------------------------------------------------------- 1 | /**/bin/ 2 | /**/obj/ 3 | /.vs/ 4 | .userprefs -------------------------------------------------------------------------------- /.src/Cradle.Editor/Editor/Attributes.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace Cradle.Editor 7 | { 8 | [AttributeUsage(AttributeTargets.Field, Inherited = true, AllowMultiple = false)] 9 | public sealed class CodeGenMacroAttribute : Attribute 10 | { 11 | public readonly string TwineName; 12 | 13 | public CodeGenMacroAttribute(string twineName) 14 | { 15 | this.TwineName = twineName; 16 | } 17 | 18 | public CodeGenMacroAttribute() 19 | { 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /.src/Cradle.Editor/Editor/Exceptions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace Cradle.Editor 7 | { 8 | public class StoryImportException : Exception 9 | { 10 | public StoryImportException() { } 11 | public StoryImportException(string message) : base(message) { } 12 | public StoryImportException(string message, Exception inner) : base(message, inner) { } 13 | } 14 | 15 | public class StoryFormatTranscodeException : Exception 16 | { 17 | public string Passage; 18 | public StoryFormatTranscodeException() { } 19 | public StoryFormatTranscodeException(string message, string passageName = null) : base(message) 20 | { 21 | Passage = passageName; 22 | } 23 | public StoryFormatTranscodeException(string message, Exception inner, string passageName = null) 24 | : base(message, inner) 25 | { 26 | Passage = passageName; 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /.src/Cradle.Editor/Editor/Importers/TweeImporter.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using UnityEditor; 3 | using System; 4 | using System.Collections; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Text.RegularExpressions; 9 | using System.IO; 10 | using Cradle.Editor.StoryFormats; 11 | 12 | namespace Cradle.Editor.Importers 13 | { 14 | [InitializeOnLoad] 15 | public class TweeImporter : StoryImporter 16 | { 17 | static TweeImporter() 18 | { 19 | CradleAssetProcessor.RegisterImporter("twee"); 20 | } 21 | 22 | static Regex rx_Passages = new Regex(@"^::\s(?[^\]\|\r\n]+)(\s+\[(?[^\]]+)\])?\r?\n(?.*?)(?=\r?\n::|\Z)", 23 | RegexOptions.Singleline | RegexOptions.Multiline | RegexOptions.ExplicitCapture); 24 | 25 | public override void Initialize() 26 | { 27 | string tweeSource = File.ReadAllText(this.AssetPath); 28 | 29 | MatchCollection matches = rx_Passages.Matches(tweeSource); 30 | if (matches.Count < 1) 31 | throw new StoryImportException("Twee data could not be found."); 32 | 33 | for (int i = 0; i < matches.Count; i++) 34 | { 35 | Match m = matches[i]; 36 | 37 | // Ignore images 38 | if (m.Groups["tags"].Success && m.Groups["tags"].Value == "Twine.image") 39 | continue; 40 | 41 | this.Passages.Add(new PassageData() 42 | { 43 | Pid = i.ToString(), 44 | Name = m.Groups["name"].Value, 45 | Tags = m.Groups["tags"].Value, 46 | Body = m.Groups["body"].Value.Trim() 47 | }); 48 | } 49 | 50 | // Twee currently supports the Sugar transcoder only 51 | this.Transcoder = new StoryFormats.Sugar.SugarTranscoder() { Importer = this }; 52 | } 53 | } 54 | } -------------------------------------------------------------------------------- /.src/Cradle.Editor/Editor/Importers/TwineHtmlImporter.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using UnityEditor; 3 | using System; 4 | using System.Collections; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Text.RegularExpressions; 9 | using System.IO; 10 | using Cradle.Editor.StoryFormats.Harlowe; 11 | 12 | namespace Cradle.Editor.Importers 13 | { 14 | [InitializeOnLoad] 15 | public class TwineHtmlImporter : StoryImporter 16 | { 17 | static TwineHtmlImporter() 18 | { 19 | CradleAssetProcessor.RegisterImporter("html"); 20 | } 21 | 22 | #region Transcoder handling 23 | // -------------------------- 24 | 25 | static List _transcoders = new List(); 26 | 27 | class TranscoderDef 28 | { 29 | public int Weight; 30 | public Type Type; 31 | } 32 | 33 | public static void RegisterTranscoder(int weight = -1) where T: StoryFormatTranscoder, new() 34 | { 35 | _transcoders.Add(new TranscoderDef() 36 | { 37 | Weight = weight >= 0 ? weight : _transcoders.Count, 38 | Type = typeof(T) 39 | }); 40 | } 41 | // -------------------------- 42 | #endregion 43 | 44 | public override bool IsAssetRelevant() 45 | { 46 | foreach(TranscoderDef entry in _transcoders.OrderBy(ent => ent.Weight)) 47 | { 48 | var transcoder = (StoryFormatTranscoder)Activator.CreateInstance(entry.Type); 49 | transcoder.Importer = this; 50 | 51 | if (transcoder.RecognizeFormat()) 52 | { 53 | this.Transcoder = transcoder; 54 | break; 55 | } 56 | } 57 | 58 | // If a transcoder recognized the format, use it. Otherwise this asset is not relevant 59 | return this.Transcoder != null; 60 | } 61 | } 62 | } -------------------------------------------------------------------------------- /.src/Cradle.Editor/Editor/PassageData.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | 5 | namespace Cradle.Editor 6 | { 7 | [System.Serializable] 8 | public class PassageData 9 | { 10 | public string Pid; 11 | public string Name; 12 | public string Tags; 13 | public string Body; 14 | 15 | [System.NonSerialized] 16 | public PassageCode Code; 17 | } 18 | 19 | public class PassageCode 20 | { 21 | public string Main; 22 | public List Fragments = new List(); 23 | } 24 | } -------------------------------------------------------------------------------- /.src/Cradle.Editor/Editor/StoryFormatTranscoder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using UnityEngine; 3 | using System.Collections; 4 | using System.Collections.Generic; 5 | using System.Text.RegularExpressions; 6 | using System.Text; 7 | using System.IO; 8 | using System.CodeDom; 9 | 10 | namespace Cradle.Editor 11 | { 12 | public abstract class StoryFormatTranscoder 13 | { 14 | public StoryImporter Importer { get; internal set; } 15 | 16 | public abstract StoryFormatMetadata GetMetadata(); 17 | public virtual void Init() { } 18 | public abstract PassageCode PassageToCode(PassageData passage); 19 | public virtual bool RecognizeFormat() { return true; } 20 | 21 | static Regex _cSharpReservedWords = new Regex(@"^(abstract|as|base|bool|break|byte|case|catch|char|checked|class|const|continue|decimal|default|delegate|do|double|else|enum|event|explicit|extern|false|finally|fixed|float|for|foreach|goto|if|implicit|in|int|interface|internal|is|lock|long|namespace|new|null|object|operator|out|override|params|private|protected|public|readonly|ref|return|sbyte|sealed|short|sizeof|stackalloc|static|string|struct|switch|this|throw|true|try|typeof|uint|ulong|unchecked|unsafe|ushort|using|virtual|void|volatile|while|add|alias|ascending|async|await|descending|dynamic|from|get|global|group|into|join|let|orderby|partial|remove|select|set|value|var|where|yield)$"); 22 | public static string EscapeReservedWord(string name) 23 | { 24 | if (_cSharpReservedWords.IsMatch(name)) 25 | name = "@" + name; 26 | return name; 27 | } 28 | 29 | public string EscapeString(string input) 30 | { 31 | using (var writer = new StringWriter()) 32 | { 33 | this.Importer.CodeDomProvider.GenerateCodeFromExpression(new CodePrimitiveExpression(input), writer, null); 34 | return writer.ToString(); 35 | } 36 | } 37 | } 38 | 39 | public class StoryFormatMetadata 40 | { 41 | public string StartPassage; 42 | public string StoryFormatName; 43 | public Type StoryBaseType = typeof(Story); 44 | public bool StrictMode = false; 45 | } 46 | 47 | public class GeneratedCode 48 | { 49 | public StringBuilder Buffer = new StringBuilder(); 50 | public int Indentation = 0; 51 | public bool Collapsed = false; 52 | 53 | public void Indent() 54 | { 55 | Utils.CodeGenUtils.Indent(Indentation, Buffer); 56 | } 57 | } 58 | } -------------------------------------------------------------------------------- /.src/Cradle.Editor/Editor/StoryImporter.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.IO; 5 | using System.Linq; 6 | using System.Text.RegularExpressions; 7 | using System; 8 | using System.Reflection; 9 | using System.CodeDom.Compiler; 10 | 11 | namespace Cradle.Editor 12 | { 13 | public abstract class StoryImporter 14 | { 15 | public string AssetPath { get; internal set; } 16 | public CodeDomProvider CodeDomProvider { get; internal set; } 17 | public StoryFormatTranscoder Transcoder {get; protected set;} 18 | public PassageData CurrentPassage { get; private set; } 19 | 20 | public readonly List Passages = new List(); 21 | public readonly HashSet Vars = new HashSet(); 22 | public HashSet MacroLibs { get; private set; } 23 | public Dictionary Macros { get; private set; } 24 | public StoryFormatMetadata Metadata { get; protected set; } 25 | 26 | public virtual bool IsAssetRelevant() 27 | { 28 | return true; 29 | } 30 | 31 | public virtual void Initialize() 32 | { 33 | } 34 | 35 | public void Transcode() 36 | { 37 | if (this.Transcoder == null) 38 | throw new System.NotImplementedException("StoryImporter.Transcoder must be set by the importer implementation."); 39 | 40 | this.Metadata = this.Transcoder.GetMetadata(); 41 | 42 | // Load macro types 43 | Macros = new Dictionary(StringComparer.OrdinalIgnoreCase); 44 | MacroLibs = new HashSet(LoadMacrosInto(Macros, this.Metadata.StoryBaseType)); 45 | 46 | this.Transcoder.Init(); 47 | 48 | for (int i = 0; i < this.Passages.Count; i++) 49 | { 50 | CurrentPassage = this.Passages[i]; 51 | 52 | CurrentPassage.Tags = Regex.Replace(CurrentPassage.Tags, @"([^\s]+)", "\"$&\","); 53 | 54 | try 55 | { 56 | CurrentPassage.Code = this.Transcoder.PassageToCode(CurrentPassage); 57 | } 58 | catch(StoryFormatTranscodeException ex) 59 | { 60 | ex.Passage = CurrentPassage.Name; 61 | throw; 62 | } 63 | } 64 | } 65 | 66 | public void RegisterVar(string name) 67 | { 68 | Vars.Add(name); 69 | } 70 | 71 | IEnumerable LoadMacrosInto(Dictionary macros, Type storyType) 72 | { 73 | string projectDir = Directory.GetParent((Path.GetFullPath(Application.dataPath))).FullName; 74 | Type baseType = typeof(RuntimeMacros); 75 | 76 | int libIndex = 0; 77 | foreach(Assembly assembly in AppDomain.CurrentDomain.GetAssemblies()) 78 | { 79 | // Skip references external to the project 80 | try 81 | { 82 | if (!string.IsNullOrEmpty(assembly.Location) && !Path.GetFullPath(assembly.Location).StartsWith(projectDir, StringComparison.OrdinalIgnoreCase)) 83 | continue; 84 | } 85 | catch (NotSupportedException) 86 | { 87 | // On .NET 4+, the correct way to check this is Assembly.IsDynamic (otherwise NotSupportedException is thrown), 88 | // but this doesn't exist in .NET 3.5 so a try catch block is used here for backward compatibility 89 | continue; 90 | } 91 | 92 | foreach(Type type in assembly.GetTypes()) 93 | { 94 | if (type.IsAbstract || type.IsNested || !baseType.IsAssignableFrom(type)) 95 | continue; 96 | 97 | // Ensure that only macro libraries for this story type are loaded 98 | object[] classAttributes = type.GetCustomAttributes(typeof(MacroLibraryAttribute), true); 99 | if (classAttributes.Length > 0 && !classAttributes.Any(attr => ((MacroLibraryAttribute)attr).StoryType.IsAssignableFrom(storyType))) 100 | continue; 101 | 102 | MacroLib macroLib = new MacroLib() 103 | { 104 | Type = type 105 | }; 106 | 107 | bool hasMethods = false; 108 | foreach (MethodInfo method in type.GetMethods()) 109 | { 110 | var attr = (RuntimeMacroAttribute) Attribute.GetCustomAttribute(method, typeof(RuntimeMacroAttribute), true); 111 | if (attr == null) 112 | continue; 113 | 114 | hasMethods = true; 115 | macros[attr.TwineName ?? method.Name] = new MacroDef() 116 | { 117 | Name = method.Name, 118 | Lib = macroLib, 119 | HasOutput = typeof(StoryOutput).IsAssignableFrom(method.ReturnType) 120 | }; 121 | } 122 | 123 | if (hasMethods) 124 | { 125 | macroLib.Name = "macros" + (++libIndex).ToString(); 126 | yield return macroLib; 127 | } 128 | } 129 | } 130 | } 131 | } 132 | 133 | public class MacroLib 134 | { 135 | public Type Type; 136 | public string Name; 137 | } 138 | 139 | public class MacroDef 140 | { 141 | public string Name; 142 | public MacroLib Lib; 143 | public bool HasOutput; 144 | } 145 | } -------------------------------------------------------------------------------- /.src/Cradle.Editor/Editor/StoryInspector.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections; 3 | using UnityEditor; 4 | using Cradle; 5 | using System.Collections.Generic; 6 | using System.Runtime.Serialization; 7 | 8 | [CustomEditor(typeof(Story), true)] 9 | public class StoryInspector : Editor 10 | { 11 | public override void OnInspectorGUI() 12 | { 13 | base.OnInspectorGUI(); 14 | 15 | var story = target as Story; 16 | if (story == null || story.Output == null) 17 | return; 18 | 19 | EditorGUILayout.Separator(); 20 | 21 | EditorGUILayout.LabelField("Story State", story.State.ToString()); 22 | EditorGUILayout.LabelField("Current Passage", story.CurrentPassage == null ? "(none)" : story.CurrentPassage.Name); 23 | 24 | EditorGUILayout.Separator(); 25 | 26 | int defaultIndent = EditorGUI.indentLevel; 27 | 28 | for(int i = 0; i < story.Output.Count; i++) 29 | { 30 | StoryOutput output = story.Output[i]; 31 | 32 | if (output is Embed) 33 | continue; 34 | 35 | int groupCount = 0; 36 | StyleGroup group = output.StyleGroup; 37 | while (group != null) 38 | { 39 | groupCount++; 40 | group = group.StyleGroup; 41 | } 42 | EditorGUI.indentLevel = defaultIndent + groupCount; 43 | EditorGUILayout.LabelField(output.ToString()); 44 | } 45 | 46 | EditorGUI.indentLevel = defaultIndent; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /.src/Cradle.Editor/Editor/ThirdParty/FullSerializer/Converters/Unity/AnimationCurve_DirectConverter.cs: -------------------------------------------------------------------------------- 1 | #if !NO_UNITY 2 | using System; 3 | using System.Collections.Generic; 4 | using UnityEngine; 5 | 6 | namespace Cradle.Editor.ThirdParty.FullSerializer { 7 | partial class fsConverterRegistrar { 8 | public static Internal.DirectConverters.AnimationCurve_DirectConverter Register_AnimationCurve_DirectConverter; 9 | } 10 | } 11 | 12 | namespace Cradle.Editor.ThirdParty.FullSerializer.Internal.DirectConverters { 13 | public class AnimationCurve_DirectConverter : fsDirectConverter { 14 | protected override fsResult DoSerialize(AnimationCurve model, Dictionary serialized) { 15 | var result = fsResult.Success; 16 | 17 | result += SerializeMember(serialized, null, "keys", model.keys); 18 | result += SerializeMember(serialized, null, "preWrapMode", model.preWrapMode); 19 | result += SerializeMember(serialized, null, "postWrapMode", model.postWrapMode); 20 | 21 | return result; 22 | } 23 | 24 | protected override fsResult DoDeserialize(Dictionary data, ref AnimationCurve model) { 25 | var result = fsResult.Success; 26 | 27 | var t0 = model.keys; 28 | result += DeserializeMember(data, null, "keys", out t0); 29 | model.keys = t0; 30 | 31 | var t1 = model.preWrapMode; 32 | result += DeserializeMember(data, null, "preWrapMode", out t1); 33 | model.preWrapMode = t1; 34 | 35 | var t2 = model.postWrapMode; 36 | result += DeserializeMember(data, null, "postWrapMode", out t2); 37 | model.postWrapMode = t2; 38 | 39 | return result; 40 | } 41 | 42 | public override object CreateInstance(fsData data, Type storageType) { 43 | return new AnimationCurve(); 44 | } 45 | } 46 | } 47 | #endif -------------------------------------------------------------------------------- /.src/Cradle.Editor/Editor/ThirdParty/FullSerializer/Converters/Unity/Bounds_DirectConverter.cs: -------------------------------------------------------------------------------- 1 | #if !NO_UNITY 2 | using System; 3 | using System.Collections.Generic; 4 | using UnityEngine; 5 | 6 | namespace Cradle.Editor.ThirdParty.FullSerializer { 7 | partial class fsConverterRegistrar { 8 | public static Internal.DirectConverters.Bounds_DirectConverter Register_Bounds_DirectConverter; 9 | } 10 | } 11 | 12 | namespace Cradle.Editor.ThirdParty.FullSerializer.Internal.DirectConverters { 13 | public class Bounds_DirectConverter : fsDirectConverter { 14 | protected override fsResult DoSerialize(Bounds model, Dictionary serialized) { 15 | var result = fsResult.Success; 16 | 17 | result += SerializeMember(serialized, null, "center", model.center); 18 | result += SerializeMember(serialized, null, "size", model.size); 19 | 20 | return result; 21 | } 22 | 23 | protected override fsResult DoDeserialize(Dictionary data, ref Bounds model) { 24 | var result = fsResult.Success; 25 | 26 | var t0 = model.center; 27 | result += DeserializeMember(data, null, "center", out t0); 28 | model.center = t0; 29 | 30 | var t1 = model.size; 31 | result += DeserializeMember(data, null, "size", out t1); 32 | model.size = t1; 33 | 34 | return result; 35 | } 36 | 37 | public override object CreateInstance(fsData data, Type storageType) { 38 | return new Bounds(); 39 | } 40 | } 41 | } 42 | #endif -------------------------------------------------------------------------------- /.src/Cradle.Editor/Editor/ThirdParty/FullSerializer/Converters/Unity/Gradient_DirectConverter.cs: -------------------------------------------------------------------------------- 1 | #if !NO_UNITY 2 | using System; 3 | using System.Collections.Generic; 4 | using UnityEngine; 5 | 6 | namespace Cradle.Editor.ThirdParty.FullSerializer { 7 | partial class fsConverterRegistrar { 8 | public static Internal.DirectConverters.Gradient_DirectConverter Register_Gradient_DirectConverter; 9 | } 10 | } 11 | 12 | namespace Cradle.Editor.ThirdParty.FullSerializer.Internal.DirectConverters { 13 | public class Gradient_DirectConverter : fsDirectConverter { 14 | protected override fsResult DoSerialize(Gradient model, Dictionary serialized) { 15 | var result = fsResult.Success; 16 | 17 | result += SerializeMember(serialized, null, "alphaKeys", model.alphaKeys); 18 | result += SerializeMember(serialized, null, "colorKeys", model.colorKeys); 19 | 20 | return result; 21 | } 22 | 23 | protected override fsResult DoDeserialize(Dictionary data, ref Gradient model) { 24 | var result = fsResult.Success; 25 | 26 | var t0 = model.alphaKeys; 27 | result += DeserializeMember(data, null, "alphaKeys", out t0); 28 | model.alphaKeys = t0; 29 | 30 | var t1 = model.colorKeys; 31 | result += DeserializeMember(data, null, "colorKeys", out t1); 32 | model.colorKeys = t1; 33 | 34 | return result; 35 | } 36 | 37 | public override object CreateInstance(fsData data, Type storageType) { 38 | return new Gradient(); 39 | } 40 | } 41 | } 42 | #endif -------------------------------------------------------------------------------- /.src/Cradle.Editor/Editor/ThirdParty/FullSerializer/Converters/Unity/Keyframe_DirectConverter.cs: -------------------------------------------------------------------------------- 1 | #if !NO_UNITY 2 | using System; 3 | using System.Collections.Generic; 4 | using UnityEngine; 5 | 6 | namespace Cradle.Editor.ThirdParty.FullSerializer { 7 | partial class fsConverterRegistrar { 8 | public static Internal.DirectConverters.Keyframe_DirectConverter Register_Keyframe_DirectConverter; 9 | } 10 | } 11 | 12 | namespace Cradle.Editor.ThirdParty.FullSerializer.Internal.DirectConverters { 13 | public class Keyframe_DirectConverter : fsDirectConverter { 14 | protected override fsResult DoSerialize(Keyframe model, Dictionary serialized) { 15 | var result = fsResult.Success; 16 | 17 | result += SerializeMember(serialized, null, "time", model.time); 18 | result += SerializeMember(serialized, null, "value", model.value); 19 | result += SerializeMember(serialized, null, "tangentMode", model.tangentMode); 20 | result += SerializeMember(serialized, null, "inTangent", model.inTangent); 21 | result += SerializeMember(serialized, null, "outTangent", model.outTangent); 22 | 23 | return result; 24 | } 25 | 26 | protected override fsResult DoDeserialize(Dictionary data, ref Keyframe model) { 27 | var result = fsResult.Success; 28 | 29 | var t0 = model.time; 30 | result += DeserializeMember(data, null, "time", out t0); 31 | model.time = t0; 32 | 33 | var t1 = model.value; 34 | result += DeserializeMember(data, null, "value", out t1); 35 | model.value = t1; 36 | 37 | var t2 = model.tangentMode; 38 | result += DeserializeMember(data, null, "tangentMode", out t2); 39 | model.tangentMode = t2; 40 | 41 | var t3 = model.inTangent; 42 | result += DeserializeMember(data, null, "inTangent", out t3); 43 | model.inTangent = t3; 44 | 45 | var t4 = model.outTangent; 46 | result += DeserializeMember(data, null, "outTangent", out t4); 47 | model.outTangent = t4; 48 | 49 | return result; 50 | } 51 | 52 | public override object CreateInstance(fsData data, Type storageType) { 53 | return new Keyframe(); 54 | } 55 | } 56 | } 57 | #endif -------------------------------------------------------------------------------- /.src/Cradle.Editor/Editor/ThirdParty/FullSerializer/Converters/Unity/LayerMask_DirectConverter.cs: -------------------------------------------------------------------------------- 1 | #if !NO_UNITY 2 | using System; 3 | using System.Collections.Generic; 4 | using UnityEngine; 5 | 6 | namespace Cradle.Editor.ThirdParty.FullSerializer { 7 | partial class fsConverterRegistrar { 8 | public static Internal.DirectConverters.LayerMask_DirectConverter Register_LayerMask_DirectConverter; 9 | } 10 | } 11 | 12 | namespace Cradle.Editor.ThirdParty.FullSerializer.Internal.DirectConverters { 13 | public class LayerMask_DirectConverter : fsDirectConverter { 14 | protected override fsResult DoSerialize(LayerMask model, Dictionary serialized) { 15 | var result = fsResult.Success; 16 | 17 | result += SerializeMember(serialized, null, "value", model.value); 18 | 19 | return result; 20 | } 21 | 22 | protected override fsResult DoDeserialize(Dictionary data, ref LayerMask model) { 23 | var result = fsResult.Success; 24 | 25 | var t0 = model.value; 26 | result += DeserializeMember(data, null, "value", out t0); 27 | model.value = t0; 28 | 29 | return result; 30 | } 31 | 32 | public override object CreateInstance(fsData data, Type storageType) { 33 | return new LayerMask(); 34 | } 35 | } 36 | } 37 | #endif -------------------------------------------------------------------------------- /.src/Cradle.Editor/Editor/ThirdParty/FullSerializer/Converters/Unity/Rect_DirectConverter.cs: -------------------------------------------------------------------------------- 1 | #if !NO_UNITY 2 | using System; 3 | using System.Collections.Generic; 4 | using UnityEngine; 5 | 6 | namespace Cradle.Editor.ThirdParty.FullSerializer { 7 | partial class fsConverterRegistrar { 8 | public static Internal.DirectConverters.Rect_DirectConverter Register_Rect_DirectConverter; 9 | } 10 | } 11 | 12 | namespace Cradle.Editor.ThirdParty.FullSerializer.Internal.DirectConverters { 13 | public class Rect_DirectConverter : fsDirectConverter { 14 | protected override fsResult DoSerialize(Rect model, Dictionary serialized) { 15 | var result = fsResult.Success; 16 | 17 | result += SerializeMember(serialized, null, "xMin", model.xMin); 18 | result += SerializeMember(serialized, null, "yMin", model.yMin); 19 | result += SerializeMember(serialized, null, "xMax", model.xMax); 20 | result += SerializeMember(serialized, null, "yMax", model.yMax); 21 | 22 | return result; 23 | } 24 | 25 | protected override fsResult DoDeserialize(Dictionary data, ref Rect model) { 26 | var result = fsResult.Success; 27 | 28 | var t0 = model.xMin; 29 | result += DeserializeMember(data, null, "xMin", out t0); 30 | model.xMin = t0; 31 | 32 | var t1 = model.yMin; 33 | result += DeserializeMember(data, null, "yMin", out t1); 34 | model.yMin = t1; 35 | 36 | var t2 = model.xMax; 37 | result += DeserializeMember(data, null, "xMax", out t2); 38 | model.xMax = t2; 39 | 40 | var t3 = model.yMax; 41 | result += DeserializeMember(data, null, "yMax", out t3); 42 | model.yMax = t3; 43 | 44 | return result; 45 | } 46 | 47 | public override object CreateInstance(fsData data, Type storageType) { 48 | return new Rect(); 49 | } 50 | } 51 | } 52 | #endif -------------------------------------------------------------------------------- /.src/Cradle.Editor/Editor/ThirdParty/FullSerializer/Converters/fsArrayConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | 4 | namespace Cradle.Editor.ThirdParty.FullSerializer.Internal { 5 | public class fsArrayConverter : fsConverter { 6 | public override bool CanProcess(Type type) { 7 | return type.IsArray; 8 | } 9 | 10 | public override bool RequestCycleSupport(Type storageType) { 11 | return false; 12 | } 13 | 14 | public override bool RequestInheritanceSupport(Type storageType) { 15 | return false; 16 | } 17 | 18 | public override fsResult TrySerialize(object instance, out fsData serialized, Type storageType) { 19 | // note: IList[index] is **significantly** faster than Array.Get, so make sure we use 20 | // that instead. 21 | 22 | IList arr = (Array)instance; 23 | Type elementType = storageType.GetElementType(); 24 | 25 | var result = fsResult.Success; 26 | 27 | serialized = fsData.CreateList(arr.Count); 28 | var serializedList = serialized.AsList; 29 | 30 | for (int i = 0; i < arr.Count; ++i) { 31 | object item = arr[i]; 32 | 33 | fsData serializedItem; 34 | 35 | var itemResult = Serializer.TrySerialize(elementType, item, out serializedItem); 36 | result.AddMessages(itemResult); 37 | if (itemResult.Failed) continue; 38 | 39 | serializedList.Add(serializedItem); 40 | } 41 | 42 | return result; 43 | } 44 | 45 | public override fsResult TryDeserialize(fsData data, ref object instance, Type storageType) { 46 | var result = fsResult.Success; 47 | 48 | // Verify that we actually have an List 49 | if ((result += CheckType(data, fsDataType.Array)).Failed) { 50 | return result; 51 | } 52 | 53 | Type elementType = storageType.GetElementType(); 54 | 55 | var serializedList = data.AsList; 56 | var list = new ArrayList(serializedList.Count); 57 | int existingCount = list.Count; 58 | 59 | for (int i = 0; i < serializedList.Count; ++i) { 60 | var serializedItem = serializedList[i]; 61 | object deserialized = null; 62 | if (i < existingCount) deserialized = list[i]; 63 | 64 | var itemResult = Serializer.TryDeserialize(serializedItem, elementType, ref deserialized); 65 | result.AddMessages(itemResult); 66 | if (itemResult.Failed) continue; 67 | 68 | if (i < existingCount) list[i] = deserialized; 69 | else list.Add(deserialized); 70 | } 71 | 72 | instance = list.ToArray(elementType); 73 | return result; 74 | } 75 | 76 | public override object CreateInstance(fsData data, Type storageType) { 77 | return fsMetaType.Get(storageType).CreateInstance(); 78 | } 79 | } 80 | } -------------------------------------------------------------------------------- /.src/Cradle.Editor/Editor/ThirdParty/FullSerializer/Converters/fsDateConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | 4 | namespace Cradle.Editor.ThirdParty.FullSerializer.Internal { 5 | /// 6 | /// Supports serialization for DateTime, DateTimeOffset, and TimeSpan. 7 | /// 8 | public class fsDateConverter : fsConverter { 9 | // The format strings that we use when serializing DateTime and DateTimeOffset types. 10 | private const string DefaultDateTimeFormatString = @"o"; 11 | private const string DateTimeOffsetFormatString = @"o"; 12 | 13 | private string DateTimeFormatString { 14 | get { 15 | return fsConfig.CustomDateTimeFormatString ?? DefaultDateTimeFormatString; 16 | } 17 | } 18 | 19 | public override bool CanProcess(Type type) { 20 | return 21 | type == typeof(DateTime) || 22 | type == typeof(DateTimeOffset) || 23 | type == typeof(TimeSpan); 24 | } 25 | 26 | public override fsResult TrySerialize(object instance, out fsData serialized, Type storageType) { 27 | if (instance is DateTime) { 28 | var dateTime = (DateTime)instance; 29 | serialized = new fsData(dateTime.ToString(DateTimeFormatString)); 30 | return fsResult.Success; 31 | } 32 | 33 | if (instance is DateTimeOffset) { 34 | var dateTimeOffset = (DateTimeOffset)instance; 35 | serialized = new fsData(dateTimeOffset.ToString(DateTimeOffsetFormatString)); 36 | return fsResult.Success; 37 | } 38 | 39 | if (instance is TimeSpan) { 40 | var timeSpan = (TimeSpan)instance; 41 | serialized = new fsData(timeSpan.ToString()); 42 | return fsResult.Success; 43 | } 44 | 45 | throw new InvalidOperationException("FullSerializer Internal Error -- Unexpected serialization type"); 46 | } 47 | 48 | public override fsResult TryDeserialize(fsData data, ref object instance, Type storageType) { 49 | if (data.IsString == false) { 50 | return fsResult.Fail("Date deserialization requires a string, not " + data.Type); 51 | } 52 | 53 | if (storageType == typeof(DateTime)) { 54 | DateTime result; 55 | if (DateTime.TryParse(data.AsString, null, DateTimeStyles.RoundtripKind, out result)) { 56 | instance = result; 57 | return fsResult.Success; 58 | } 59 | 60 | return fsResult.Fail("Unable to parse " + data.AsString + " into a DateTime"); 61 | } 62 | 63 | if (storageType == typeof(DateTimeOffset)) { 64 | DateTimeOffset result; 65 | if (DateTimeOffset.TryParse(data.AsString, null, DateTimeStyles.RoundtripKind, out result)) { 66 | instance = result; 67 | return fsResult.Success; 68 | } 69 | 70 | return fsResult.Fail("Unable to parse " + data.AsString + " into a DateTimeOffset"); 71 | } 72 | 73 | if (storageType == typeof(TimeSpan)) { 74 | TimeSpan result; 75 | if (TimeSpan.TryParse(data.AsString, out result)) { 76 | instance = result; 77 | return fsResult.Success; 78 | } 79 | 80 | return fsResult.Fail("Unable to parse " + data.AsString + " into a TimeSpan"); 81 | } 82 | 83 | throw new InvalidOperationException("FullSerializer Internal Error -- Unexpected deserialization type"); 84 | } 85 | } 86 | } -------------------------------------------------------------------------------- /.src/Cradle.Editor/Editor/ThirdParty/FullSerializer/Converters/fsEnumConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Cradle.Editor.ThirdParty.FullSerializer.Internal { 6 | /// 7 | /// Serializes and deserializes enums by their current name. 8 | /// 9 | public class fsEnumConverter : fsConverter { 10 | public override bool CanProcess(Type type) { 11 | return type.Resolve().IsEnum; 12 | } 13 | 14 | public override bool RequestCycleSupport(Type storageType) { 15 | return false; 16 | } 17 | 18 | public override bool RequestInheritanceSupport(Type storageType) { 19 | return false; 20 | } 21 | 22 | public override object CreateInstance(fsData data, Type storageType) { 23 | // In .NET compact, Enum.ToObject(Type, Object) is defined but the overloads like 24 | // Enum.ToObject(Type, int) are not -- so we get around this by boxing the value. 25 | return Enum.ToObject(storageType, (object)0); 26 | } 27 | 28 | public override fsResult TrySerialize(object instance, out fsData serialized, Type storageType) { 29 | if (fsConfig.SerializeEnumsAsInteger) { 30 | serialized = new fsData(Convert.ToInt64(instance)); 31 | } 32 | else if (fsPortableReflection.GetAttribute(storageType) != null) { 33 | long instanceValue = Convert.ToInt64(instance); 34 | var result = new StringBuilder(); 35 | 36 | bool first = true; 37 | foreach (var value in Enum.GetValues(storageType)) { 38 | int integralValue = (int)value; 39 | bool isSet = (instanceValue & integralValue) != 0; 40 | 41 | if (isSet) { 42 | if (first == false) result.Append(","); 43 | first = false; 44 | result.Append(value.ToString()); 45 | } 46 | } 47 | 48 | serialized = new fsData(result.ToString()); 49 | } 50 | else { 51 | serialized = new fsData(Enum.GetName(storageType, instance)); 52 | } 53 | return fsResult.Success; 54 | } 55 | 56 | public override fsResult TryDeserialize(fsData data, ref object instance, Type storageType) { 57 | if (data.IsString) { 58 | string[] enumValues = data.AsString.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries); 59 | 60 | long instanceValue = 0; 61 | for (int i = 0; i < enumValues.Length; ++i) { 62 | string enumValue = enumValues[i]; 63 | 64 | // Verify that the enum name exists; Enum.TryParse is only available in .NET 4.0 65 | // and above :(. 66 | if (ArrayContains(Enum.GetNames(storageType), enumValue) == false) { 67 | return fsResult.Fail("Cannot find enum name " + enumValue + " on type " + storageType); 68 | } 69 | 70 | long flagValue = (long)Convert.ChangeType(Enum.Parse(storageType, enumValue), typeof(long)); 71 | instanceValue |= flagValue; 72 | } 73 | 74 | instance = Enum.ToObject(storageType, (object)instanceValue); 75 | return fsResult.Success; 76 | } 77 | 78 | else if (data.IsInt64) { 79 | int enumValue = (int)data.AsInt64; 80 | 81 | // In .NET compact, Enum.ToObject(Type, Object) is defined but the overloads like 82 | // Enum.ToObject(Type, int) are not -- so we get around this by boxing the value. 83 | instance = Enum.ToObject(storageType, (object)enumValue); 84 | 85 | return fsResult.Success; 86 | } 87 | 88 | return fsResult.Fail("EnumConverter encountered an unknown JSON data type"); 89 | } 90 | 91 | /// 92 | /// Returns true if the given value is contained within the specified array. 93 | /// 94 | private static bool ArrayContains(T[] values, T value) { 95 | // note: We don't use LINQ because this function will *not* allocate 96 | for (int i = 0; i < values.Length; ++i) { 97 | if (EqualityComparer.Default.Equals(values[i], value)) { 98 | return true; 99 | } 100 | } 101 | 102 | return false; 103 | } 104 | } 105 | } -------------------------------------------------------------------------------- /.src/Cradle.Editor/Editor/ThirdParty/FullSerializer/Converters/fsForwardConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Cradle.Editor.ThirdParty.FullSerializer { 4 | /// 5 | /// This allows you to forward serialization of an object to one of its members. For example, 6 | /// 7 | /// [fsForward("Values")] 8 | /// struct Wrapper { 9 | /// public int[] Values; 10 | /// } 11 | /// 12 | /// Then `Wrapper` will be serialized into a JSON array of integers. It will be as if `Wrapper` 13 | /// doesn't exist. 14 | /// 15 | [AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface | AttributeTargets.Struct)] 16 | public sealed class fsForwardAttribute : Attribute { 17 | /// 18 | /// The name of the member we should serialize as. 19 | /// 20 | public string MemberName; 21 | 22 | /// 23 | /// Forward object serialization to an instance member. See class comment. 24 | /// 25 | /// The name of the member that we should serialize this object as. 26 | public fsForwardAttribute(string memberName) { 27 | MemberName = memberName; 28 | } 29 | } 30 | } 31 | 32 | namespace Cradle.Editor.ThirdParty.FullSerializer.Internal { 33 | public class fsForwardConverter : fsConverter { 34 | private string _memberName; 35 | 36 | public fsForwardConverter(fsForwardAttribute attribute) { 37 | _memberName = attribute.MemberName; 38 | } 39 | 40 | public override bool CanProcess(Type type) { 41 | throw new NotSupportedException("Please use the [fsForward(...)] attribute."); 42 | } 43 | 44 | private fsResult GetProperty(object instance, out fsMetaProperty property) { 45 | var properties = fsMetaType.Get(instance.GetType()).Properties; 46 | for (int i = 0; i < properties.Length; ++i) { 47 | if (properties[i].MemberName == _memberName) { 48 | property = properties[i]; 49 | return fsResult.Success; 50 | } 51 | } 52 | 53 | property = default(fsMetaProperty); 54 | return fsResult.Fail("No property named \"" + _memberName + "\" on " + instance.GetType().CSharpName()); 55 | } 56 | 57 | public override fsResult TrySerialize(object instance, out fsData serialized, Type storageType) { 58 | serialized = fsData.Null; 59 | var result = fsResult.Success; 60 | 61 | fsMetaProperty property; 62 | if ((result += GetProperty(instance, out property)).Failed) return result; 63 | 64 | var actualInstance = property.Read(instance); 65 | return Serializer.TrySerialize(property.StorageType, actualInstance, out serialized); 66 | } 67 | 68 | public override fsResult TryDeserialize(fsData data, ref object instance, Type storageType) { 69 | var result = fsResult.Success; 70 | 71 | fsMetaProperty property; 72 | if ((result += GetProperty(instance, out property)).Failed) return result; 73 | 74 | object actualInstance = null; 75 | if ((result += Serializer.TryDeserialize(data, property.StorageType, ref actualInstance)).Failed) 76 | return result; 77 | 78 | property.Write(instance, actualInstance); 79 | return result; 80 | } 81 | 82 | public override object CreateInstance(fsData data, Type storageType) { 83 | return fsMetaType.Get(storageType).CreateInstance(); 84 | } 85 | } 86 | } -------------------------------------------------------------------------------- /.src/Cradle.Editor/Editor/ThirdParty/FullSerializer/Converters/fsGuidConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Cradle.Editor.ThirdParty.FullSerializer.Internal { 4 | /// 5 | /// Serializes and deserializes guids. 6 | /// 7 | public class fsGuidConverter : fsConverter { 8 | public override bool CanProcess(Type type) { 9 | return type == typeof(Guid); 10 | } 11 | 12 | public override bool RequestCycleSupport(Type storageType) { 13 | return false; 14 | } 15 | 16 | public override bool RequestInheritanceSupport(Type storageType) { 17 | return false; 18 | } 19 | 20 | public override fsResult TrySerialize(object instance, out fsData serialized, Type storageType) { 21 | var guid = (Guid)instance; 22 | serialized = new fsData(guid.ToString()); 23 | return fsResult.Success; 24 | } 25 | 26 | public override fsResult TryDeserialize(fsData data, ref object instance, Type storageType) { 27 | if (data.IsString) { 28 | instance = new Guid(data.AsString); 29 | return fsResult.Success; 30 | } 31 | 32 | return fsResult.Fail("fsGuidConverter encountered an unknown JSON data type"); 33 | } 34 | 35 | public override object CreateInstance(fsData data, Type storageType) { 36 | return new Guid(); 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /.src/Cradle.Editor/Editor/ThirdParty/FullSerializer/Converters/fsKeyValuePairConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Reflection; 4 | 5 | namespace Cradle.Editor.ThirdParty.FullSerializer.Internal { 6 | public class fsKeyValuePairConverter : fsConverter { 7 | public override bool CanProcess(Type type) { 8 | return 9 | type.Resolve().IsGenericType && 10 | type.GetGenericTypeDefinition() == typeof(KeyValuePair<,>); 11 | } 12 | 13 | public override bool RequestCycleSupport(Type storageType) { 14 | return false; 15 | } 16 | 17 | public override bool RequestInheritanceSupport(Type storageType) { 18 | return false; 19 | } 20 | 21 | public override fsResult TryDeserialize(fsData data, ref object instance, Type storageType) { 22 | var result = fsResult.Success; 23 | 24 | fsData keyData, valueData; 25 | if ((result += CheckKey(data, "Key", out keyData)).Failed) return result; 26 | if ((result += CheckKey(data, "Value", out valueData)).Failed) return result; 27 | 28 | var genericArguments = storageType.GetGenericArguments(); 29 | Type keyType = genericArguments[0], valueType = genericArguments[1]; 30 | 31 | object keyObject = null, valueObject = null; 32 | result.AddMessages(Serializer.TryDeserialize(keyData, keyType, ref keyObject)); 33 | result.AddMessages(Serializer.TryDeserialize(valueData, valueType, ref valueObject)); 34 | 35 | instance = Activator.CreateInstance(storageType, keyObject, valueObject); 36 | return result; 37 | } 38 | 39 | public override fsResult TrySerialize(object instance, out fsData serialized, Type storageType) { 40 | PropertyInfo keyProperty = storageType.GetDeclaredProperty("Key"); 41 | PropertyInfo valueProperty = storageType.GetDeclaredProperty("Value"); 42 | 43 | object keyObject = keyProperty.GetValue(instance, null); 44 | object valueObject = valueProperty.GetValue(instance, null); 45 | 46 | var genericArguments = storageType.GetGenericArguments(); 47 | Type keyType = genericArguments[0], valueType = genericArguments[1]; 48 | 49 | var result = fsResult.Success; 50 | 51 | fsData keyData, valueData; 52 | result.AddMessages(Serializer.TrySerialize(keyType, keyObject, out keyData)); 53 | result.AddMessages(Serializer.TrySerialize(valueType, valueObject, out valueData)); 54 | 55 | serialized = fsData.CreateDictionary(); 56 | if (keyData != null) serialized.AsDictionary["Key"] = keyData; 57 | if (valueData != null) serialized.AsDictionary["Value"] = valueData; 58 | 59 | return result; 60 | } 61 | } 62 | } -------------------------------------------------------------------------------- /.src/Cradle.Editor/Editor/ThirdParty/FullSerializer/Converters/fsNullableConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Cradle.Editor.ThirdParty.FullSerializer.Internal { 4 | /// 5 | /// The reflected converter will properly serialize nullable types. However, we do it here 6 | /// instead as we can emit less serialization data. 7 | /// 8 | public class fsNullableConverter : fsConverter { 9 | public override bool CanProcess(Type type) { 10 | return 11 | type.Resolve().IsGenericType && 12 | type.GetGenericTypeDefinition() == typeof(Nullable<>); 13 | } 14 | 15 | public override fsResult TrySerialize(object instance, out fsData serialized, Type storageType) { 16 | // null is automatically serialized 17 | return Serializer.TrySerialize(Nullable.GetUnderlyingType(storageType), instance, out serialized); 18 | } 19 | 20 | public override fsResult TryDeserialize(fsData data, ref object instance, Type storageType) { 21 | // null is automatically deserialized 22 | return Serializer.TryDeserialize(data, Nullable.GetUnderlyingType(storageType), ref instance); 23 | } 24 | 25 | public override object CreateInstance(fsData data, Type storageType) { 26 | return storageType; 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /.src/Cradle.Editor/Editor/ThirdParty/FullSerializer/Converters/fsPrimitiveConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Cradle.Editor.ThirdParty.FullSerializer.Internal { 4 | public class fsPrimitiveConverter : fsConverter { 5 | public override bool CanProcess(Type type) { 6 | return 7 | type.Resolve().IsPrimitive || 8 | type == typeof(string) || 9 | type == typeof(decimal); 10 | } 11 | 12 | public override bool RequestCycleSupport(Type storageType) { 13 | return false; 14 | } 15 | 16 | public override bool RequestInheritanceSupport(Type storageType) { 17 | return false; 18 | } 19 | 20 | private static bool UseBool(Type type) { 21 | return type == typeof(bool); 22 | } 23 | 24 | private static bool UseInt64(Type type) { 25 | return type == typeof(sbyte) || type == typeof(byte) || 26 | type == typeof(Int16) || type == typeof(UInt16) || 27 | type == typeof(Int32) || type == typeof(UInt32) || 28 | type == typeof(Int64) || type == typeof(UInt64); 29 | } 30 | 31 | private static bool UseDouble(Type type) { 32 | return type == typeof(float) || 33 | type == typeof(double) || 34 | type == typeof(decimal); 35 | } 36 | 37 | private static bool UseString(Type type) { 38 | return type == typeof(string) || 39 | type == typeof(char); 40 | } 41 | 42 | public override fsResult TrySerialize(object instance, out fsData serialized, Type storageType) { 43 | var instanceType = instance.GetType(); 44 | 45 | if (fsConfig.Serialize64BitIntegerAsString && (instanceType == typeof(Int64) || instanceType == typeof(UInt64))) { 46 | serialized = new fsData((string)Convert.ChangeType(instance, typeof(string))); 47 | return fsResult.Success; 48 | } 49 | 50 | if (UseBool(instanceType)) { 51 | serialized = new fsData((bool)instance); 52 | return fsResult.Success; 53 | } 54 | 55 | if (UseInt64(instanceType)) { 56 | serialized = new fsData((Int64)Convert.ChangeType(instance, typeof(Int64))); 57 | return fsResult.Success; 58 | } 59 | 60 | if (UseDouble(instanceType)) { 61 | serialized = new fsData((double)Convert.ChangeType(instance, typeof(double))); 62 | return fsResult.Success; 63 | } 64 | 65 | if (UseString(instanceType)) { 66 | serialized = new fsData((string)Convert.ChangeType(instance, typeof(string))); 67 | return fsResult.Success; 68 | } 69 | 70 | serialized = null; 71 | return fsResult.Fail("Unhandled primitive type " + instance.GetType()); 72 | } 73 | 74 | public override fsResult TryDeserialize(fsData storage, ref object instance, Type storageType) { 75 | var result = fsResult.Success; 76 | 77 | if (UseBool(storageType)) { 78 | if ((result += CheckType(storage, fsDataType.Boolean)).Succeeded) { 79 | instance = storage.AsBool; 80 | } 81 | return result; 82 | } 83 | 84 | if (UseDouble(storageType) || UseInt64(storageType)) { 85 | if (storage.IsDouble) { 86 | instance = Convert.ChangeType(storage.AsDouble, storageType); 87 | } 88 | else if (storage.IsInt64) { 89 | instance = Convert.ChangeType(storage.AsInt64, storageType); 90 | } 91 | else if (fsConfig.Serialize64BitIntegerAsString && storage.IsString && 92 | (storageType == typeof(Int64) || storageType == typeof(UInt64))) { 93 | instance = Convert.ChangeType(storage.AsString, storageType); 94 | } 95 | else { 96 | return fsResult.Fail(GetType().Name + " expected number but got " + storage.Type + " in " + storage); 97 | } 98 | return fsResult.Success; 99 | } 100 | 101 | if (UseString(storageType)) { 102 | if ((result += CheckType(storage, fsDataType.String)).Succeeded) { 103 | instance = storage.AsString; 104 | } 105 | return result; 106 | } 107 | 108 | return fsResult.Fail(GetType().Name + ": Bad data; expected bool, number, string, but got " + storage); 109 | } 110 | } 111 | } 112 | 113 | -------------------------------------------------------------------------------- /.src/Cradle.Editor/Editor/ThirdParty/FullSerializer/Converters/fsReflectedConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | 4 | namespace Cradle.Editor.ThirdParty.FullSerializer.Internal { 5 | public class fsReflectedConverter : fsConverter { 6 | public override bool CanProcess(Type type) { 7 | if (type.Resolve().IsArray || 8 | typeof(ICollection).IsAssignableFrom(type)) { 9 | 10 | return false; 11 | } 12 | 13 | return true; 14 | } 15 | 16 | public override fsResult TrySerialize(object instance, out fsData serialized, Type storageType) { 17 | serialized = fsData.CreateDictionary(); 18 | var result = fsResult.Success; 19 | 20 | fsMetaType metaType = fsMetaType.Get(instance.GetType()); 21 | metaType.EmitAotData(); 22 | 23 | for (int i = 0; i < metaType.Properties.Length; ++i) { 24 | fsMetaProperty property = metaType.Properties[i]; 25 | if (property.CanRead == false) continue; 26 | 27 | fsData serializedData; 28 | 29 | var itemResult = Serializer.TrySerialize(property.StorageType, property.OverrideConverterType, 30 | property.Read(instance), out serializedData); 31 | result.AddMessages(itemResult); 32 | if (itemResult.Failed) { 33 | continue; 34 | } 35 | 36 | serialized.AsDictionary[property.JsonName] = serializedData; 37 | } 38 | 39 | return result; 40 | } 41 | 42 | public override fsResult TryDeserialize(fsData data, ref object instance, Type storageType) { 43 | var result = fsResult.Success; 44 | 45 | // Verify that we actually have an Object 46 | if ((result += CheckType(data, fsDataType.Object)).Failed) { 47 | return result; 48 | } 49 | 50 | fsMetaType metaType = fsMetaType.Get(storageType); 51 | metaType.EmitAotData(); 52 | 53 | for (int i = 0; i < metaType.Properties.Length; ++i) { 54 | fsMetaProperty property = metaType.Properties[i]; 55 | if (property.CanWrite == false) continue; 56 | 57 | fsData propertyData; 58 | if (data.AsDictionary.TryGetValue(property.JsonName, out propertyData)) { 59 | object deserializedValue = null; 60 | 61 | // We have to read in the existing value, since we need to support partial 62 | // deserialization. However, this is bad for perf. 63 | // TODO: Find a way to avoid this call when we are not doing a partial deserialization 64 | // Maybe through a new property, ie, Serializer.IsPartialSerialization, which just 65 | // gets set when starting a new serialization? We cannot pipe the information 66 | // through CreateInstance unfortunately. 67 | if (property.CanRead) { 68 | deserializedValue = property.Read(instance); 69 | } 70 | 71 | var itemResult = Serializer.TryDeserialize(propertyData, property.StorageType, 72 | property.OverrideConverterType, ref deserializedValue); 73 | result.AddMessages(itemResult); 74 | if (itemResult.Failed) continue; 75 | 76 | property.Write(instance, deserializedValue); 77 | } 78 | } 79 | 80 | return result; 81 | } 82 | 83 | public override object CreateInstance(fsData data, Type storageType) { 84 | fsMetaType metaType = fsMetaType.Get(storageType); 85 | return metaType.CreateInstance(); 86 | } 87 | } 88 | } -------------------------------------------------------------------------------- /.src/Cradle.Editor/Editor/ThirdParty/FullSerializer/Converters/fsTypeConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Cradle.Editor.ThirdParty.FullSerializer.Internal { 4 | public class fsTypeConverter : fsConverter { 5 | public override bool CanProcess(Type type) { 6 | return typeof(Type).IsAssignableFrom(type); 7 | } 8 | 9 | public override bool RequestCycleSupport(Type type) { 10 | return false; 11 | } 12 | 13 | public override bool RequestInheritanceSupport(Type type) { 14 | return false; 15 | } 16 | 17 | public override fsResult TrySerialize(object instance, out fsData serialized, Type storageType) { 18 | var type = (Type)instance; 19 | serialized = new fsData(type.FullName); 20 | return fsResult.Success; 21 | } 22 | 23 | public override fsResult TryDeserialize(fsData data, ref object instance, Type storageType) { 24 | if (data.IsString == false) { 25 | return fsResult.Fail("Type converter requires a string"); 26 | } 27 | 28 | instance = fsTypeLookup.GetType(data.AsString); 29 | if (instance == null) { 30 | return fsResult.Fail("Unable to find type " + data.AsString); 31 | } 32 | return fsResult.Success; 33 | } 34 | 35 | public override object CreateInstance(fsData data, Type storageType) { 36 | return storageType; 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /.src/Cradle.Editor/Editor/ThirdParty/FullSerializer/Converters/fsWeakReferenceConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Cradle.Editor.ThirdParty.FullSerializer.Internal { 4 | /// 5 | /// Serializes and deserializes WeakReferences. 6 | /// 7 | public class fsWeakReferenceConverter : fsConverter { 8 | public override bool CanProcess(Type type) { 9 | return type == typeof(WeakReference); 10 | } 11 | 12 | public override bool RequestCycleSupport(Type storageType) { 13 | return false; 14 | } 15 | 16 | public override bool RequestInheritanceSupport(Type storageType) { 17 | return false; 18 | } 19 | 20 | public override fsResult TrySerialize(object instance, out fsData serialized, Type storageType) { 21 | var weakRef = (WeakReference)instance; 22 | 23 | var result = fsResult.Success; 24 | serialized = fsData.CreateDictionary(); 25 | 26 | if (weakRef.IsAlive) { 27 | fsData data; 28 | if ((result += Serializer.TrySerialize(weakRef.Target, out data)).Failed) { 29 | return result; 30 | } 31 | 32 | serialized.AsDictionary["Target"] = data; 33 | serialized.AsDictionary["TrackResurrection"] = new fsData(weakRef.TrackResurrection); 34 | } 35 | 36 | return result; 37 | } 38 | 39 | public override fsResult TryDeserialize(fsData data, ref object instance, Type storageType) { 40 | var result = fsResult.Success; 41 | 42 | if ((result += CheckType(data, fsDataType.Object)).Failed) return result; 43 | 44 | if (data.AsDictionary.ContainsKey("Target")) { 45 | var targetData = data.AsDictionary["Target"]; 46 | object targetInstance = null; 47 | 48 | if ((result += Serializer.TryDeserialize(targetData, typeof(object), ref targetInstance)).Failed) return result; 49 | 50 | bool trackResurrection = false; 51 | if (data.AsDictionary.ContainsKey("TrackResurrection") && data.AsDictionary["TrackResurrection"].IsBool) { 52 | trackResurrection = data.AsDictionary["TrackResurrection"].AsBool; 53 | } 54 | 55 | instance = new WeakReference(targetInstance, trackResurrection); 56 | } 57 | 58 | return result; 59 | } 60 | 61 | public override object CreateInstance(fsData data, Type storageType) { 62 | return new WeakReference(null); 63 | } 64 | } 65 | } -------------------------------------------------------------------------------- /.src/Cradle.Editor/Editor/ThirdParty/FullSerializer/Internal/fsCyclicReferenceManager.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Runtime.CompilerServices; 4 | 5 | namespace Cradle.Editor.ThirdParty.FullSerializer.Internal { 6 | public class fsCyclicReferenceManager { 7 | // We use the default ReferenceEquals when comparing two objects because 8 | // custom objects may override equals methods. These overriden equals may 9 | // treat equals differently; we want to serialize/deserialize the object 10 | // graph *identically* to how it currently exists. 11 | class ObjectReferenceEqualityComparator : IEqualityComparer { 12 | bool IEqualityComparer.Equals(object x, object y) { 13 | return ReferenceEquals(x, y); 14 | } 15 | 16 | int IEqualityComparer.GetHashCode(object obj) { 17 | return RuntimeHelpers.GetHashCode(obj); 18 | } 19 | 20 | public static readonly IEqualityComparer Instance = new ObjectReferenceEqualityComparator(); 21 | } 22 | 23 | private Dictionary _objectIds = new Dictionary(ObjectReferenceEqualityComparator.Instance); 24 | private int _nextId; 25 | 26 | private Dictionary _marked = new Dictionary(); 27 | private int _depth; 28 | 29 | public void Enter() { 30 | _depth++; 31 | } 32 | 33 | public bool Exit() { 34 | _depth--; 35 | 36 | if (_depth == 0) { 37 | _objectIds = new Dictionary(ObjectReferenceEqualityComparator.Instance); 38 | _nextId = 0; 39 | _marked = new Dictionary(); 40 | } 41 | 42 | if (_depth < 0) { 43 | _depth = 0; 44 | throw new InvalidOperationException("Internal Error - Mismatched Enter/Exit"); 45 | } 46 | 47 | return _depth == 0; 48 | } 49 | 50 | public object GetReferenceObject(int id) { 51 | if (_marked.ContainsKey(id) == false) { 52 | throw new InvalidOperationException("Internal Deserialization Error - Object " + 53 | "definition has not been encountered for object with id=" + id + 54 | "; have you reordered or modified the serialized data? If this is an issue " + 55 | "with an unmodified Full Json implementation and unmodified serialization " + 56 | "data, please report an issue with an included test case."); 57 | } 58 | 59 | return _marked[id]; 60 | } 61 | 62 | public void AddReferenceWithId(int id, object reference) { 63 | _marked[id] = reference; 64 | } 65 | 66 | public int GetReferenceId(object item) { 67 | int id; 68 | if (_objectIds.TryGetValue(item, out id) == false) { 69 | id = _nextId++; 70 | _objectIds[item] = id; 71 | } 72 | return id; 73 | } 74 | 75 | public bool IsReference(object item) { 76 | return _marked.ContainsKey(GetReferenceId(item)); 77 | } 78 | 79 | public void MarkSerialized(object item) { 80 | int referenceId = GetReferenceId(item); 81 | 82 | if (_marked.ContainsKey(referenceId)) { 83 | throw new InvalidOperationException("Internal Error - " + item + 84 | " has already been marked as serialized"); 85 | } 86 | 87 | _marked[referenceId] = item; 88 | } 89 | } 90 | } -------------------------------------------------------------------------------- /.src/Cradle.Editor/Editor/ThirdParty/FullSerializer/Internal/fsOption.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Cradle.Editor.ThirdParty.FullSerializer.Internal { 4 | /// 5 | /// Simple option type. This is akin to nullable types. 6 | /// 7 | public struct fsOption { 8 | private bool _hasValue; 9 | private T _value; 10 | 11 | public bool HasValue { 12 | get { return _hasValue; } 13 | } 14 | public bool IsEmpty { 15 | get { return _hasValue == false; } 16 | } 17 | public T Value { 18 | get { 19 | if (IsEmpty) throw new InvalidOperationException("fsOption is empty"); 20 | return _value; 21 | } 22 | } 23 | 24 | public fsOption(T value) { 25 | _hasValue = true; 26 | _value = value; 27 | } 28 | 29 | public static fsOption Empty; 30 | } 31 | 32 | public static class fsOption { 33 | public static fsOption Just(T value) { 34 | return new fsOption(value); 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /.src/Cradle.Editor/Editor/ThirdParty/FullSerializer/Internal/fsTypeExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | 5 | // Needed for WinRT compatibility 6 | using Cradle.Editor.ThirdParty.FullSerializer.Internal; 7 | 8 | namespace Cradle.Editor.ThirdParty.FullSerializer { 9 | public static class fsTypeExtensions { 10 | /// 11 | /// Returns a pretty name for the type in the style of one that you'd see in C# without the namespace. 12 | /// 13 | public static string CSharpName(this Type type) { 14 | return CSharpName(type, /*includeNamespace:*/false); 15 | } 16 | 17 | public static string CSharpName(this Type type, bool includeNamespace, bool ensureSafeDeclarationName) { 18 | var name = CSharpName(type, includeNamespace); 19 | if (ensureSafeDeclarationName) name = name.Replace('>', '_').Replace('<', '_').Replace('.', '_'); 20 | return name; 21 | } 22 | 23 | /// 24 | /// Returns a pretty name for the type in the style of one that you'd see in C#. 25 | /// 26 | /// Should the name include namespaces? 27 | public static string CSharpName(this Type type, bool includeNamespace) { 28 | // we special case some of the common type names 29 | if (type == typeof(void)) return "void"; 30 | if (type == typeof(int)) return "int"; 31 | if (type == typeof(float)) return "float"; 32 | if (type == typeof(bool)) return "bool"; 33 | if (type == typeof(double)) return "double"; 34 | if (type == typeof(string)) return "string"; 35 | 36 | // Generic parameter, ie, T in Okay 37 | // We special-case this logic otherwise we will recurse on the T 38 | if (type.IsGenericParameter) { 39 | return type.ToString(); 40 | } 41 | 42 | string name = ""; 43 | 44 | var genericArguments = (IEnumerable)type.GetGenericArguments(); 45 | if (type.IsNested) { 46 | name += type.DeclaringType.CSharpName() + "."; 47 | 48 | // The declaring type generic parameters are considered part of the nested types generic 49 | // parameters so we need to remove them, otherwise it will get included again. 50 | // 51 | // Say we have type `class Parent { class Child {} }` 52 | // If we did not do the removal, then we would output Parent.Child, but we really want 53 | // to output Parent.Child 54 | if (type.DeclaringType.GetGenericArguments().Length > 0) { 55 | genericArguments = genericArguments.Skip(type.DeclaringType.GetGenericArguments().Length); 56 | } 57 | } 58 | 59 | if (genericArguments.Any() == false) { 60 | name += type.Name; 61 | } 62 | else { 63 | name += type.Name.Substring(0, type.Name.IndexOf('`')); 64 | name += "<" + String.Join(",", genericArguments.Select(t => CSharpName(t, includeNamespace)).ToArray()) + ">"; 65 | } 66 | 67 | if (includeNamespace && type.Namespace != null) { 68 | name = type.Namespace + "." + name; 69 | } 70 | 71 | return name; 72 | } 73 | } 74 | } -------------------------------------------------------------------------------- /.src/Cradle.Editor/Editor/ThirdParty/FullSerializer/Internal/fsVersionedType.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Cradle.Editor.ThirdParty.FullSerializer.Internal { 4 | public struct fsVersionedType { 5 | /// 6 | /// The direct ancestors that this type can import. 7 | /// 8 | public fsVersionedType[] Ancestors; 9 | 10 | /// 11 | /// The identifying string that is unique among all ancestors. 12 | /// 13 | public string VersionString; 14 | 15 | /// 16 | /// The modeling type that this versioned type maps back to. 17 | /// 18 | public Type ModelType; 19 | 20 | /// 21 | /// Migrate from an instance of an ancestor. 22 | /// 23 | public object Migrate(object ancestorInstance) { 24 | return Activator.CreateInstance(ModelType, ancestorInstance); 25 | } 26 | 27 | public override string ToString() { 28 | return "fsVersionedType [ModelType=" + ModelType + ", VersionString=" + VersionString + ", Ancestors.Length=" + Ancestors.Length + "]"; 29 | } 30 | 31 | public static bool operator ==(fsVersionedType a, fsVersionedType b) { 32 | return a.ModelType == b.ModelType; 33 | } 34 | 35 | public static bool operator !=(fsVersionedType a, fsVersionedType b) { 36 | return a.ModelType != b.ModelType; 37 | } 38 | 39 | public override bool Equals(object obj) { 40 | return 41 | obj is fsVersionedType && 42 | ModelType == ((fsVersionedType)obj).ModelType; 43 | } 44 | 45 | public override int GetHashCode() { 46 | return ModelType.GetHashCode(); 47 | } 48 | } 49 | } -------------------------------------------------------------------------------- /.src/Cradle.Editor/Editor/ThirdParty/FullSerializer/Reflection/fsReflectionUtility.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Cradle.Editor.ThirdParty.FullSerializer.Internal { 4 | public static class fsReflectionUtility { 5 | /// 6 | /// Searches for a particular implementation of the given interface type inside of the type. 7 | /// This is particularly useful if the interface type is an open type, ie, typeof(IFace{}), 8 | /// because this method will then return IFace{} but with appropriate type parameters 9 | /// inserted. 10 | /// 11 | /// The base type to search for interface 12 | /// The interface type to search for. Can be an open generic 13 | /// type. 14 | /// The actual interface type that the type contains, or null if there is no 15 | /// implementation of the given interfaceType on type. 16 | public static Type GetInterface(Type type, Type interfaceType) { 17 | if (interfaceType.Resolve().IsGenericType && 18 | interfaceType.Resolve().IsGenericTypeDefinition == false) { 19 | 20 | throw new ArgumentException("GetInterface requires that if the interface " + 21 | "type is generic, then it must be the generic type definition, not a " + 22 | "specific generic type instantiation"); 23 | }; 24 | 25 | while (type != null) { 26 | foreach (var iface in type.GetInterfaces()) { 27 | if (iface.Resolve().IsGenericType) { 28 | if (interfaceType == iface.GetGenericTypeDefinition()) { 29 | return iface; 30 | } 31 | } 32 | 33 | else if (interfaceType == iface) { 34 | return iface; 35 | } 36 | } 37 | 38 | type = type.Resolve().BaseType; 39 | } 40 | 41 | return null; 42 | } 43 | } 44 | } -------------------------------------------------------------------------------- /.src/Cradle.Editor/Editor/ThirdParty/FullSerializer/Reflection/fsTypeLookup.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Reflection; 3 | 4 | namespace Cradle.Editor.ThirdParty.FullSerializer.Internal { 5 | /// 6 | /// Provides APIs for looking up types based on their name. 7 | /// 8 | internal static class fsTypeLookup { 9 | /// 10 | /// Attempts to lookup the given type. Returns null if the type lookup fails. 11 | /// 12 | public static Type GetType(string typeName) { 13 | Type type = null; 14 | 15 | // Try a direct type lookup 16 | type = Type.GetType(typeName); 17 | if (type != null) { 18 | return type; 19 | } 20 | 21 | #if (!UNITY_EDITOR && UNITY_METRO) == false // no AppDomain on WinRT 22 | // If we still haven't found the proper type, we can enumerate all of the loaded 23 | // assemblies and see if any of them define the type 24 | foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies()) { 25 | // See if that assembly defines the named type 26 | type = assembly.GetType(typeName); 27 | if (type != null) { 28 | return type; 29 | } 30 | } 31 | #endif 32 | 33 | return null; 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /.src/Cradle.Editor/Editor/ThirdParty/FullSerializer/fsConfig.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Reflection; 3 | 4 | namespace Cradle.Editor.ThirdParty.FullSerializer { 5 | /// 6 | /// Enables some top-level customization of Full Serializer. 7 | /// 8 | public static class fsConfig { 9 | /// 10 | /// The attributes that will force a field or property to be serialized. 11 | /// 12 | public static Type[] SerializeAttributes = { 13 | #if !NO_UNITY 14 | typeof(UnityEngine.SerializeField), 15 | #endif 16 | typeof(fsPropertyAttribute) 17 | }; 18 | 19 | /// 20 | /// The attributes that will force a field or property to *not* be serialized. 21 | /// 22 | public static Type[] IgnoreSerializeAttributes = { typeof(NonSerializedAttribute), typeof(fsIgnoreAttribute) }; 23 | 24 | /// 25 | /// The default member serialization. 26 | /// 27 | public static fsMemberSerialization DefaultMemberSerialization { 28 | get { 29 | return _defaultMemberSerialization; 30 | } 31 | set { 32 | _defaultMemberSerialization = value; 33 | fsMetaType.ClearCache(); 34 | } 35 | } 36 | 37 | private static fsMemberSerialization _defaultMemberSerialization = fsMemberSerialization.Default; 38 | 39 | /// 40 | /// Convert a C# field/property name into the key used for the JSON object. For example, you could 41 | /// force all JSON names to lowercase with: 42 | /// 43 | /// fsConfig.GetJsonNameFromMemberName = (name, info) => name.ToLower(); 44 | /// 45 | /// This will only be used when the name is not explicitly specified with fsProperty. 46 | /// 47 | public static Func GetJsonNameFromMemberName = (name, info) => name; 48 | 49 | /// 50 | /// Should the default serialization behaviour include non-auto properties? 51 | /// 52 | public static bool SerializeNonAutoProperties = false; 53 | 54 | /// 55 | /// Should the default serialization behaviour include properties with non-public setters? 56 | /// 57 | public static bool SerializeNonPublicSetProperties = true; 58 | 59 | /// 60 | /// Should deserialization be case sensitive? If this is false and the JSON has multiple members with the 61 | /// same keys only separated by case, then this results in undefined behavior. 62 | /// 63 | public static bool IsCaseSensitive = true; 64 | 65 | /// 66 | /// If not null, this string format will be used for DateTime instead of the default one. 67 | /// 68 | public static string CustomDateTimeFormatString = null; 69 | 70 | /// 71 | /// Int64 and UInt64 will be serialized and deserialized as string for compatibility 72 | /// 73 | public static bool Serialize64BitIntegerAsString = false; 74 | 75 | /// 76 | /// Enums are serialized using their names by default. Setting this to true will serialize them as integers instead. 77 | /// 78 | public static bool SerializeEnumsAsInteger = false; 79 | } 80 | } -------------------------------------------------------------------------------- /.src/Cradle.Editor/Editor/ThirdParty/FullSerializer/fsContext.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace Cradle.Editor.ThirdParty.FullSerializer { 5 | /// 6 | /// fsContext stores global metadata that can be used to customize how fsConverters operate 7 | /// during serialization. 8 | /// 9 | public sealed class fsContext { 10 | /// 11 | /// All of the context objects. 12 | /// 13 | private readonly Dictionary _contextObjects = new Dictionary(); 14 | 15 | /// 16 | /// Removes all context objects from the context. 17 | /// 18 | public void Reset() { 19 | _contextObjects.Clear(); 20 | } 21 | 22 | /// 23 | /// Sets the context object for the given type with the given value. 24 | /// 25 | public void Set(T obj) { 26 | _contextObjects[typeof(T)] = obj; 27 | } 28 | 29 | /// 30 | /// Returns true if there is a context object for the given type. 31 | /// 32 | public bool Has() { 33 | return _contextObjects.ContainsKey(typeof(T)); 34 | } 35 | 36 | /// 37 | /// Fetches the context object for the given type. 38 | /// 39 | public T Get() { 40 | object val; 41 | if (_contextObjects.TryGetValue(typeof(T), out val)) { 42 | return (T)val; 43 | } 44 | throw new InvalidOperationException("There is no context object of type " + typeof(T)); 45 | } 46 | } 47 | } -------------------------------------------------------------------------------- /.src/Cradle.Editor/Editor/ThirdParty/FullSerializer/fsConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Cradle.Editor.ThirdParty.FullSerializer { 4 | /// 5 | /// The serialization converter allows for customization of the serialization process. 6 | /// 7 | public abstract class fsConverter : fsBaseConverter { 8 | /// 9 | /// Can this converter serialize and deserialize the given object type? 10 | /// 11 | /// The given object type. 12 | /// True if the converter can serialize it, false otherwise. 13 | public abstract bool CanProcess(Type type); 14 | } 15 | } -------------------------------------------------------------------------------- /.src/Cradle.Editor/Editor/ThirdParty/FullSerializer/fsConverterRegistrar.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Cradle.Editor.ThirdParty.FullSerializer.Internal; 4 | 5 | namespace Cradle.Editor.ThirdParty.FullSerializer { 6 | /// 7 | /// This class allows arbitrary code to easily register global converters. To add a converter, 8 | /// simply declare a new field called "Register_*" that stores the type of converter you would 9 | /// like to add. Alternatively, you can do the same with a method called "Register_*"; just add 10 | /// the converter type to the `Converters` list. 11 | /// 12 | public partial class fsConverterRegistrar { 13 | static fsConverterRegistrar() { 14 | Converters = new List(); 15 | 16 | foreach (var field in typeof(fsConverterRegistrar).GetDeclaredFields()) { 17 | if (field.Name.StartsWith("Register_")) Converters.Add(field.FieldType); 18 | } 19 | 20 | foreach (var method in typeof(fsConverterRegistrar).GetDeclaredMethods()) { 21 | if (method.Name.StartsWith("Register_")) method.Invoke(null, null); 22 | } 23 | 24 | } 25 | 26 | public static List Converters; 27 | 28 | // Example field registration: 29 | //public static AnimationCurve_DirectConverter Register_AnimationCurve_DirectConverter; 30 | 31 | // Example method registration: 32 | //public static void Register_AnimationCurve_DirectConverter() { 33 | // Converters.Add(typeof(AnimationCurve_DirectConverter)); 34 | //} 35 | } 36 | } -------------------------------------------------------------------------------- /.src/Cradle.Editor/Editor/ThirdParty/FullSerializer/fsDirectConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace Cradle.Editor.ThirdParty.FullSerializer { 5 | /// 6 | /// The direct converter is similar to a regular converter, except that it targets specifically only one type. 7 | /// This means that it can be used without performance impact when discovering converters. It is strongly 8 | /// recommended that you derive from fsDirectConverter{TModel}. 9 | /// 10 | /// Due to the way that direct converters operate, inheritance is *not* supported. Direct converters 11 | /// will only be used with the exact ModelType object. 12 | public abstract class fsDirectConverter : fsBaseConverter { 13 | public abstract Type ModelType { get; } 14 | } 15 | 16 | public abstract class fsDirectConverter : fsDirectConverter { 17 | public override Type ModelType { get { return typeof(TModel); } } 18 | 19 | public sealed override fsResult TrySerialize(object instance, out fsData serialized, Type storageType) { 20 | var serializedDictionary = new Dictionary(); 21 | var result = DoSerialize((TModel)instance, serializedDictionary); 22 | serialized = new fsData(serializedDictionary); 23 | return result; 24 | } 25 | 26 | public sealed override fsResult TryDeserialize(fsData data, ref object instance, Type storageType) { 27 | var result = fsResult.Success; 28 | if ((result += CheckType(data, fsDataType.Object)).Failed) return result; 29 | 30 | var obj = (TModel)instance; 31 | result += DoDeserialize(data.AsDictionary, ref obj); 32 | instance = obj; 33 | return result; 34 | } 35 | 36 | protected abstract fsResult DoSerialize(TModel model, Dictionary serialized); 37 | protected abstract fsResult DoDeserialize(Dictionary data, ref TModel model); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /.src/Cradle.Editor/Editor/ThirdParty/FullSerializer/fsExceptions.cs: -------------------------------------------------------------------------------- 1 | // note: This file contains exceptions used by FullSerializer. Exceptions are never used at runtime 2 | // in FullSerializer; they are only used when validating annotations and code-based models. 3 | 4 | using System; 5 | 6 | namespace Cradle.Editor.ThirdParty.FullSerializer { 7 | public sealed class fsMissingVersionConstructorException : Exception { 8 | public fsMissingVersionConstructorException(Type versionedType, Type constructorType) : 9 | base(versionedType + " is missing a constructor for previous model type " + constructorType) { } 10 | } 11 | 12 | public sealed class fsDuplicateVersionNameException : Exception { 13 | public fsDuplicateVersionNameException(Type typeA, Type typeB, string version) : 14 | base(typeA + " and " + typeB + " have the same version string (" + version + "); please change one of them.") { } 15 | } 16 | } -------------------------------------------------------------------------------- /.src/Cradle.Editor/Editor/ThirdParty/FullSerializer/fsISerializationCallbacks.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | #if !NO_UNITY 3 | using UnityEngine; 4 | #endif 5 | 6 | namespace Cradle.Editor.ThirdParty.FullSerializer { 7 | /// 8 | /// Extend this interface on your type to receive notifications about serialization/deserialization events. If you don't 9 | /// have access to the type itself, then you can write an fsObjectProcessor instead. 10 | /// 11 | public interface fsISerializationCallbacks { 12 | /// 13 | /// Called before serialization. 14 | /// 15 | void OnBeforeSerialize(Type storageType); 16 | 17 | /// 18 | /// Called after serialization. 19 | /// 20 | /// The field/property type that is storing the instance. 21 | /// The data that was serialized. 22 | void OnAfterSerialize(Type storageType, ref fsData data); 23 | 24 | /// 25 | /// Called before deserialization. 26 | /// 27 | /// The field/property type that is storing the instance. 28 | /// The data that will be used for deserialization. 29 | void OnBeforeDeserialize(Type storageType, ref fsData data); 30 | 31 | /// 32 | /// Called after deserialization. 33 | /// 34 | /// The field/property type that is storing the instance. 35 | /// The type of the instance. 36 | void OnAfterDeserialize(Type storageType); 37 | } 38 | } 39 | 40 | namespace Cradle.Editor.ThirdParty.FullSerializer.Internal { 41 | public class fsSerializationCallbackProcessor : fsObjectProcessor { 42 | public override bool CanProcess(Type type) { 43 | return typeof(fsISerializationCallbacks).IsAssignableFrom(type); 44 | } 45 | 46 | public override void OnBeforeSerialize(Type storageType, object instance) { 47 | ((fsISerializationCallbacks)instance).OnBeforeSerialize(storageType); 48 | } 49 | 50 | public override void OnAfterSerialize(Type storageType, object instance, ref fsData data) { 51 | ((fsISerializationCallbacks)instance).OnAfterSerialize(storageType, ref data); 52 | } 53 | 54 | public override void OnBeforeDeserializeAfterInstanceCreation(Type storageType, object instance, ref fsData data) { 55 | if (instance is fsISerializationCallbacks == false) { 56 | throw new InvalidCastException("Please ensure the converter for " + storageType + " actually returns an instance of it, not an instance of " + instance.GetType()); 57 | } 58 | 59 | ((fsISerializationCallbacks)instance).OnBeforeDeserialize(storageType, ref data); 60 | } 61 | 62 | public override void OnAfterDeserialize(Type storageType, object instance) { 63 | ((fsISerializationCallbacks)instance).OnAfterDeserialize(storageType); 64 | } 65 | } 66 | 67 | #if !NO_UNITY 68 | public class fsSerializationCallbackReceiverProcessor : fsObjectProcessor { 69 | public override bool CanProcess(Type type) { 70 | return typeof(ISerializationCallbackReceiver).IsAssignableFrom(type); 71 | } 72 | 73 | public override void OnBeforeSerialize(Type storageType, object instance) { 74 | ((ISerializationCallbackReceiver)instance).OnBeforeSerialize(); 75 | } 76 | 77 | public override void OnAfterDeserialize(Type storageType, object instance) { 78 | ((ISerializationCallbackReceiver)instance).OnAfterDeserialize(); 79 | } 80 | } 81 | #endif 82 | } 83 | -------------------------------------------------------------------------------- /.src/Cradle.Editor/Editor/ThirdParty/FullSerializer/fsIgnoreAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Cradle.Editor.ThirdParty.FullSerializer { 4 | /// 5 | /// The given property or field annotated with [JsonIgnore] will not be serialized. 6 | /// 7 | [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)] 8 | public sealed class fsIgnoreAttribute : Attribute { 9 | } 10 | } -------------------------------------------------------------------------------- /.src/Cradle.Editor/Editor/ThirdParty/FullSerializer/fsMemberSerialization.cs: -------------------------------------------------------------------------------- 1 | namespace Cradle.Editor.ThirdParty.FullSerializer { 2 | /// 3 | /// Controls how the reflected converter handles member serialization. 4 | /// 5 | public enum fsMemberSerialization { 6 | /// 7 | /// Only members with [SerializeField] or [fsProperty] attributes are serialized. 8 | /// 9 | OptIn, 10 | 11 | /// 12 | /// Only members with [NotSerialized] or [fsIgnore] will not be serialized. 13 | /// 14 | OptOut, 15 | 16 | /// 17 | /// The default member serialization behavior is applied. 18 | /// 19 | Default 20 | } 21 | } -------------------------------------------------------------------------------- /.src/Cradle.Editor/Editor/ThirdParty/FullSerializer/fsObjectAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Cradle.Editor.ThirdParty.FullSerializer { 4 | /// 5 | /// This attribute controls some serialization behavior for a type. See the comments 6 | /// on each of the fields for more information. 7 | /// 8 | [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct)] 9 | public sealed class fsObjectAttribute : Attribute { 10 | /// 11 | /// The previous model that should be used if an old version of this 12 | /// object is encountered. Using this attribute also requires that the 13 | /// type have a public constructor that takes only one parameter, an object 14 | /// instance of the given type. Use of this parameter *requires* that 15 | /// the VersionString parameter is also set. 16 | /// 17 | public Type[] PreviousModels; 18 | 19 | /// 20 | /// The version string to use for this model. This should be unique among all 21 | /// prior versions of this model that is supported for importation. If PreviousModel 22 | /// is set, then this attribute must also be set. A good valid example for this 23 | /// is "v1", "v2", "v3", ... 24 | /// 25 | public string VersionString; 26 | 27 | /// 28 | /// This controls the behavior for member serialization. 29 | /// The default behavior is fsMemberSerialization.Default. 30 | /// 31 | public fsMemberSerialization MemberSerialization = fsMemberSerialization.Default; 32 | 33 | /// 34 | /// Specify a custom converter to use for serialization. The converter type needs 35 | /// to derive from fsBaseConverter. This defaults to null. 36 | /// 37 | public Type Converter; 38 | 39 | /// 40 | /// Specify a custom processor to use during serialization. The processor type needs 41 | /// to derive from fsObjectProcessor and the call to CanProcess is not invoked. This 42 | /// defaults to null. 43 | /// 44 | public Type Processor; 45 | 46 | public fsObjectAttribute() { } 47 | public fsObjectAttribute(string versionString, params Type[] previousModels) { 48 | VersionString = versionString; 49 | PreviousModels = previousModels; 50 | } 51 | } 52 | } -------------------------------------------------------------------------------- /.src/Cradle.Editor/Editor/ThirdParty/FullSerializer/fsObjectProcessor.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Cradle.Editor.ThirdParty.FullSerializer { 4 | /// 5 | /// 6 | /// Enables injecting code before/after an object has been serialized. This is most 7 | /// useful if you want to run the default serialization process but apply a pre/post 8 | /// processing step. 9 | /// 10 | /// 11 | /// Multiple object processors can be active at the same time. When running they are 12 | /// called in a "nested" fashion - if we have processor1 and process2 added to the 13 | /// serializer in that order (p1 then p2), then the execution order will be 14 | /// p1#Before p2#Before /serialization/ p2#After p1#After. 15 | /// 16 | /// 17 | public abstract class fsObjectProcessor { 18 | /// 19 | /// Is the processor interested in objects of the given type? 20 | /// 21 | /// The given type. 22 | /// True if the processor should be applied, false otherwise. 23 | public virtual bool CanProcess(Type type) { throw new NotImplementedException(); } 24 | 25 | /// 26 | /// Called before serialization. 27 | /// 28 | /// The field/property type that is storing the instance. 29 | /// The type of the instance. 30 | public virtual void OnBeforeSerialize(Type storageType, object instance) { } 31 | 32 | /// 33 | /// Called after serialization. 34 | /// 35 | /// The field/property type that is storing the instance. 36 | /// The type of the instance. 37 | /// The data that was serialized. 38 | public virtual void OnAfterSerialize(Type storageType, object instance, ref fsData data) { } 39 | 40 | /// 41 | /// Called before deserialization. 42 | /// 43 | /// The field/property type that is storing the instance. 44 | /// The data that will be used for deserialization. 45 | public virtual void OnBeforeDeserialize(Type storageType, ref fsData data) { } 46 | 47 | /// 48 | /// Called before deserialization has begun but *after* the object instance has been created. This will get 49 | /// invoked even if the user passed in an existing instance. 50 | /// 51 | /// 52 | /// **IMPORTANT**: The actual instance that gets passed here is *not* guaranteed to be an a subtype of storageType, since 53 | /// the value for instance is whatever the active converter returned for CreateInstance() - ie, some converters will return 54 | /// dummy types in CreateInstance() if instance creation cannot be separated from deserialization (ie, KeyValuePair). 55 | /// 56 | /// The field/property type that is storing the instance. 57 | /// The created object instance. No deserialization has been applied to it. 58 | /// The data that will be used for deserialization. 59 | public virtual void OnBeforeDeserializeAfterInstanceCreation(Type storageType, object instance, ref fsData data) { } 60 | 61 | /// 62 | /// Called after deserialization. 63 | /// 64 | /// The field/property type that is storing the instance. 65 | /// The type of the instance. 66 | public virtual void OnAfterDeserialize(Type storageType, object instance) { } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /.src/Cradle.Editor/Editor/ThirdParty/FullSerializer/fsPropertyAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Cradle.Editor.ThirdParty.FullSerializer { 4 | /// 5 | /// Explicitly mark a property to be serialized. This can also be used to give the name that the 6 | /// property should use during serialization. 7 | /// 8 | [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)] 9 | public sealed class fsPropertyAttribute : Attribute { 10 | /// 11 | /// The name of that the property will use in JSON serialization. 12 | /// 13 | public string Name; 14 | 15 | /// 16 | /// Use a custom converter for the given type. Specify the converter to use using typeof. 17 | /// 18 | public Type Converter; 19 | 20 | public fsPropertyAttribute() 21 | : this(string.Empty) { 22 | } 23 | 24 | public fsPropertyAttribute(string name) { 25 | Name = name; 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /.src/Cradle.Editor/Editor/Utils/CodeGenUtils.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections; 3 | using System.Text; 4 | 5 | namespace Cradle.Editor.Utils 6 | { 7 | public static class CodeGenUtils 8 | { 9 | public static string Indent(int num, StringBuilder buffer = null) 10 | { 11 | var tabsTemp = buffer ?? new StringBuilder(); 12 | for (int i = 0; i < Mathf.Max(0, num); i++) 13 | tabsTemp.Append('\t'); 14 | string tabs = tabsTemp.ToString(); 15 | return tabs; 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /.src/Cradle.Editor/Editor/Utils/EditorFileUtil.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using UnityEditor; 3 | using System; 4 | using System.IO; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.Text; 8 | using Cradle.Editor.ThirdParty.FullSerializer; 9 | 10 | namespace Cradle.Editor.Utils 11 | { 12 | public static class EditorFileUtil 13 | { 14 | public static string FindFile(string fileName, bool directoryOnly = false) 15 | { 16 | string[] paths = Directory.GetFiles(Application.dataPath, fileName, SearchOption.AllDirectories); 17 | if (paths.Length < 1) 18 | throw new StoryImportException(string.Format("Could not find the file '{0}'. Did you install Cradle correctly?", fileName)); 19 | 20 | if (paths.Length > 1) 21 | throw new StoryImportException(string.Format("Found more than one file called '{0}'. Did you install Cradle correctly?", fileName)); 22 | 23 | string file = paths[0]; 24 | return directoryOnly ? Path.GetDirectoryName(file) : file; 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /.src/Cradle.Editor/Editor/Utils/PhantomJS.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using UnityEditor; 3 | using System; 4 | using System.IO; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.Text; 8 | using Cradle.Editor.ThirdParty.FullSerializer; 9 | 10 | namespace Cradle.Editor.Utils 11 | { 12 | public static class PhantomJS 13 | { 14 | public static PhantomOutput Run(string url, string bridgeScriptFileName = null, bool throwExOnError = true) 15 | { 16 | // Get the location of the phantom exe 17 | string phantomExecutable = 18 | Application.platform == RuntimePlatform.OSXEditor ? "phantomjs" : 19 | Application.platform == RuntimePlatform.WindowsEditor ? "phantomjs.exe" : 20 | null; 21 | 22 | if (phantomExecutable == null) 23 | throw new NotSupportedException("Editor platform not supported."); 24 | 25 | string binPath = EditorFileUtil.FindFile(phantomExecutable); 26 | 27 | // Get the location of the phantom script 28 | const string phantomJs = "phantom.js_"; 29 | string jsPath = EditorFileUtil.FindFile(phantomJs, true); 30 | 31 | // Get the location of the bridge script 32 | string bridgePath = bridgeScriptFileName != null ? EditorFileUtil.FindFile(bridgeScriptFileName) : null; 33 | 34 | // Run the HTML in PhantomJS 35 | var phantomJS = new System.Diagnostics.Process(); 36 | phantomJS.StartInfo.UseShellExecute = false; 37 | phantomJS.StartInfo.CreateNoWindow = true; 38 | phantomJS.StartInfo.RedirectStandardOutput = true; 39 | phantomJS.StartInfo.WorkingDirectory = jsPath; 40 | phantomJS.StartInfo.FileName = binPath; 41 | phantomJS.StartInfo.Arguments = string.Format ("\"{0}\" \"{1}\"{2}", 42 | phantomJs, 43 | url, 44 | bridgePath == null ? null : string.Format(" \"{0}\"", bridgePath) 45 | ); 46 | 47 | // On Mac, the phantomjs binary requires execute permissions (755), this should be set by Install.cs in the Phantom directory 48 | phantomJS.Start(); 49 | 50 | string outputJson = phantomJS.StandardOutput.ReadToEnd(); 51 | phantomJS.WaitForExit(); 52 | 53 | //PhantomOutput output = JsonUtility.FromJson>(outputJson); 54 | var output = (PhantomOutput) FullSerializerWrapper.Deserialize(typeof(PhantomOutput), outputJson); 55 | 56 | bool hasErrors = false; 57 | 58 | foreach (PhantomConsoleMessage msg in output.console) 59 | { 60 | if (msg.type != "error") 61 | continue; 62 | 63 | hasErrors = true; 64 | Debug.LogErrorFormat("{0}\n\n{1}\n\n", msg.value, msg.trace); 65 | } 66 | if (hasErrors && throwExOnError) 67 | throw new StoryImportException("HTML errors detected"); 68 | 69 | return output; 70 | } 71 | } 72 | 73 | [Serializable] 74 | public class PhantomOutput 75 | { 76 | public PhantomConsoleMessage[] console; 77 | public ResultT result; 78 | } 79 | 80 | [Serializable] 81 | public class PhantomConsoleMessage 82 | { 83 | public string type; 84 | public string value; 85 | public string trace; 86 | } 87 | 88 | public static class FullSerializerWrapper { 89 | private static readonly fsSerializer _serializer = new fsSerializer(); 90 | 91 | public static string Serialize(Type type, object value) { 92 | // serialize the data 93 | fsData data; 94 | _serializer.TrySerialize(type, value, out data).AssertSuccessWithoutWarnings(); 95 | 96 | // emit the data via JSON 97 | return fsJsonPrinter.CompressedJson(data); 98 | } 99 | 100 | public static object Deserialize(Type type, string serializedState) { 101 | // step 1: parse the JSON data 102 | fsData data = fsJsonParser.Parse(serializedState); 103 | 104 | // step 2: deserialize the data 105 | object deserialized = null; 106 | _serializer.TryDeserialize(data, type, ref deserialized).AssertSuccessWithoutWarnings(); 107 | 108 | return deserialized; 109 | } 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /.src/Cradle.Editor/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | #if !UNITY_EDITOR 2 | using System.Reflection; 3 | using System.Runtime.CompilerServices; 4 | using System.Runtime.InteropServices; 5 | 6 | // General Information about an assembly is controlled through the following 7 | // set of attributes. Change these attribute values to modify the information 8 | // associated with an assembly. 9 | [assembly: AssemblyTitle("Cradle Editor")] 10 | [assembly: AssemblyDescription("")] 11 | [assembly: AssemblyConfiguration("")] 12 | [assembly: AssemblyCompany("D. A. Terre")] 13 | [assembly: AssemblyProduct("Cradle")] 14 | [assembly: AssemblyCopyright("Copyright © 2017")] 15 | [assembly: AssemblyTrademark("")] 16 | [assembly: AssemblyCulture("")] 17 | 18 | // Setting ComVisible to false makes the types in this assembly not visible 19 | // to COM components. If you need to access a type in this assembly from 20 | // COM, set the ComVisible attribute to true on that type. 21 | [assembly: ComVisible(false)] 22 | 23 | // The following GUID is for the ID of the typelib if this project is exposed to COM 24 | [assembly: Guid("ccfe4f3c-5377-4da6-838c-c95fe7b8202c")] 25 | 26 | // Version information for an assembly consists of the following four values: 27 | // 28 | // Major Version 29 | // Minor Version 30 | // Build Number 31 | // Revision 32 | // 33 | // You can specify all the values or you can default the Build and Revision Numbers 34 | // by using the '*' as shown below: 35 | // [assembly: AssemblyVersion("1.0.*")] 36 | [assembly: AssemblyVersion("2.0.2.0")] 37 | [assembly: AssemblyFileVersion("2.0.2.0")] 38 | #endif -------------------------------------------------------------------------------- /.src/Cradle.MD.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2013 4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnityTwine", "Cradle\Cradle.MD.csproj", "{37C652FC-470E-412B-A63D-452A216E0066}" 5 | EndProject 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnityTwine.Editor", "Cradle.Editor\Cradle.Editor.MD.csproj", "{6800AAA0-D6B3-4AC1-8AD2-77999B98EF7D}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {37C652FC-470E-412B-A63D-452A216E0066}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {37C652FC-470E-412B-A63D-452A216E0066}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {37C652FC-470E-412B-A63D-452A216E0066}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {37C652FC-470E-412B-A63D-452A216E0066}.Release|Any CPU.Build.0 = Release|Any CPU 18 | {6800AAA0-D6B3-4AC1-8AD2-77999B98EF7D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 19 | {6800AAA0-D6B3-4AC1-8AD2-77999B98EF7D}.Debug|Any CPU.Build.0 = Debug|Any CPU 20 | {6800AAA0-D6B3-4AC1-8AD2-77999B98EF7D}.Release|Any CPU.ActiveCfg = Release|Any CPU 21 | {6800AAA0-D6B3-4AC1-8AD2-77999B98EF7D}.Release|Any CPU.Build.0 = Release|Any CPU 22 | EndGlobalSection 23 | GlobalSection(SolutionProperties) = preSolution 24 | HideSolutionNode = FALSE 25 | EndGlobalSection 26 | EndGlobal 27 | -------------------------------------------------------------------------------- /.src/Cradle.VS.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2013 4 | VisualStudioVersion = 12.0.30723.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnityTwine", "Cradle\Cradle.VS.csproj", "{37C652FC-470E-412B-A63D-452A216E0066}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnityTwine.Editor", "Cradle.Editor\Cradle.Editor.VS.csproj", "{6800AAA0-D6B3-4AC1-8AD2-77999B98EF7D}" 9 | EndProject 10 | Global 11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 12 | Debug|Any CPU = Debug|Any CPU 13 | Release|Any CPU = Release|Any CPU 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {37C652FC-470E-412B-A63D-452A216E0066}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 17 | {37C652FC-470E-412B-A63D-452A216E0066}.Debug|Any CPU.Build.0 = Debug|Any CPU 18 | {37C652FC-470E-412B-A63D-452A216E0066}.Release|Any CPU.ActiveCfg = Release|Any CPU 19 | {37C652FC-470E-412B-A63D-452A216E0066}.Release|Any CPU.Build.0 = Release|Any CPU 20 | {6800AAA0-D6B3-4AC1-8AD2-77999B98EF7D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 21 | {6800AAA0-D6B3-4AC1-8AD2-77999B98EF7D}.Debug|Any CPU.Build.0 = Debug|Any CPU 22 | {6800AAA0-D6B3-4AC1-8AD2-77999B98EF7D}.Release|Any CPU.ActiveCfg = Release|Any CPU 23 | {6800AAA0-D6B3-4AC1-8AD2-77999B98EF7D}.Release|Any CPU.Build.0 = Release|Any CPU 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | EndGlobal 29 | -------------------------------------------------------------------------------- /.src/Cradle/Core/Attributes.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace Cradle 7 | { 8 | [AttributeUsage(AttributeTargets.Method, Inherited = false, AllowMultiple = true)] 9 | public sealed class StoryCueAttribute : Attribute 10 | { 11 | public string PassageName; 12 | public string LinkName; 13 | public CueType Cue; 14 | 15 | public StoryCueAttribute(string passageName, string cueName) : 16 | this(passageName, null, cueName) 17 | { 18 | } 19 | 20 | public StoryCueAttribute(string passageName, CueType cue) : 21 | this(passageName, null, cue) 22 | { 23 | } 24 | 25 | public StoryCueAttribute(string passageName, string linkName, string cueName): 26 | this(passageName, linkName, (CueType)Enum.Parse(typeof(CueType), cueName)) 27 | { 28 | } 29 | 30 | public StoryCueAttribute(string passageName, string linkName, CueType cue) 31 | { 32 | this.PassageName = passageName; 33 | this.LinkName = linkName; 34 | this.Cue = cue; 35 | } 36 | } 37 | 38 | 39 | [AttributeUsage(AttributeTargets.Class, Inherited = true, AllowMultiple = true)] 40 | public sealed class MacroLibraryAttribute : Attribute 41 | { 42 | public readonly Type StoryType; 43 | 44 | public MacroLibraryAttribute(Type storyType) 45 | { 46 | if (!typeof(Story).IsAssignableFrom(storyType)) 47 | throw new ArgumentException("MacroLibary attribute requires a type deriving from Story.", "storyType"); 48 | 49 | this.StoryType = storyType; 50 | } 51 | } 52 | 53 | [AttributeUsage(AttributeTargets.Method, Inherited = true, AllowMultiple = false)] 54 | public sealed class RuntimeMacroAttribute : Attribute 55 | { 56 | public readonly string TwineName; 57 | 58 | public RuntimeMacroAttribute(string twineName) 59 | { 60 | this.TwineName = twineName; 61 | } 62 | 63 | public RuntimeMacroAttribute() 64 | { 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /.src/Cradle/Core/Exceptions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Cradle 4 | { 5 | [Serializable] 6 | public class StoryException : Exception 7 | { 8 | public StoryException() { } 9 | public StoryException(string message) : base(message) { } 10 | public StoryException(string message, Exception inner) : base(message, inner) { } 11 | protected StoryException( 12 | System.Runtime.Serialization.SerializationInfo info, 13 | System.Runtime.Serialization.StreamingContext context) 14 | : base(info, context) { } 15 | } 16 | 17 | [Serializable] 18 | public class VarTypeException : StoryException 19 | { 20 | public VarTypeException() { } 21 | public VarTypeException(string message) : base(message) { } 22 | public VarTypeException(string message, Exception inner) : base(message, inner) { } 23 | protected VarTypeException( 24 | System.Runtime.Serialization.SerializationInfo info, 25 | System.Runtime.Serialization.StreamingContext context) 26 | : base(info, context) { } 27 | } 28 | 29 | [Serializable] 30 | public class MacroException : StoryException 31 | { 32 | public MacroException() { } 33 | public MacroException(string message) : base(message) { } 34 | public MacroException(string message, Exception inner) : base(message, inner) { } 35 | protected MacroException( 36 | System.Runtime.Serialization.SerializationInfo info, 37 | System.Runtime.Serialization.StreamingContext context) 38 | : base(info, context) { } 39 | } 40 | 41 | [Serializable] 42 | public class VarTypeMemberException : StoryException 43 | { 44 | public VarTypeMemberException() { } 45 | public VarTypeMemberException(string message) : base(message) { } 46 | public VarTypeMemberException(string message, Exception inner) : base(message, inner) { } 47 | protected VarTypeMemberException( 48 | System.Runtime.Serialization.SerializationInfo info, 49 | System.Runtime.Serialization.StreamingContext context) 50 | : base(info, context) { } 51 | } 52 | 53 | [Serializable] 54 | public class StrictModeException : StoryException 55 | { 56 | public StrictModeException() { } 57 | public StrictModeException(string message) : base(message) { } 58 | public StrictModeException(string message, Exception inner) : base(message, inner) { } 59 | protected StrictModeException( 60 | System.Runtime.Serialization.SerializationInfo info, 61 | System.Runtime.Serialization.StreamingContext context) 62 | : base(info, context) { } 63 | } 64 | } -------------------------------------------------------------------------------- /.src/Cradle/Core/Extensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using UnityEngine; 6 | 7 | namespace Cradle 8 | { 9 | public static class Extensions 10 | { 11 | // ................................. 12 | // Enums 13 | 14 | public static bool In(this Enum value, params Enum[] values) 15 | { 16 | for (int i = 0; i < values.Length; i++) 17 | if (object.Equals(values[i], value)) 18 | return true; 19 | return false; 20 | } 21 | 22 | public static bool HasFlag(this Enum val, Enum test) 23 | { 24 | try { return (Convert.ToInt32(val) & Convert.ToInt32(test)) > 0; } 25 | catch { Debug.LogError(val); throw; } 26 | } 27 | 28 | public static IEnumerable GetFlags(this Enum value) 29 | { 30 | return GetFlags(value, Enum.GetValues(value.GetType()).Cast().ToArray()); 31 | } 32 | 33 | public static IEnumerable GetIndividualFlags(this Enum value) 34 | { 35 | return GetFlags(value, GetFlagValues(value.GetType()).ToArray()); 36 | } 37 | 38 | private static IEnumerable GetFlags(Enum value, Enum[] values) 39 | { 40 | ulong bits = Convert.ToUInt64(value); 41 | List results = new List(); 42 | for (int i = values.Length - 1; i >= 0; i--) 43 | { 44 | ulong mask = Convert.ToUInt64(values[i]); 45 | if (i == 0 && mask == 0L) 46 | break; 47 | if ((bits & mask) == mask) 48 | { 49 | results.Add(values[i]); 50 | bits -= mask; 51 | } 52 | } 53 | if (bits != 0L) 54 | return Enumerable.Empty(); 55 | if (Convert.ToUInt64(value) != 0L) 56 | return results.Reverse(); 57 | if (bits == Convert.ToUInt64(value) && values.Length > 0 && Convert.ToUInt64(values[0]) == 0L) 58 | return values.Take(1); 59 | return Enumerable.Empty(); 60 | } 61 | 62 | private static IEnumerable GetFlagValues(Type enumType) 63 | { 64 | ulong flag = 0x1; 65 | foreach (var value in Enum.GetValues(enumType).Cast()) 66 | { 67 | ulong bits = Convert.ToUInt64(value); 68 | if (bits == 0L) 69 | //yield return value; 70 | continue; // skip the zero value 71 | while (flag < bits) flag <<= 1; 72 | if (flag == bits) 73 | yield return value; 74 | } 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /.src/Cradle/Core/OutputTypes/Abort.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Cradle 4 | { 5 | public class Abort: StoryOutput 6 | { 7 | public string GoToPassage = null; 8 | 9 | public Abort(string goToPassage) 10 | { 11 | this.GoToPassage = goToPassage; 12 | } 13 | } 14 | } 15 | 16 | -------------------------------------------------------------------------------- /.src/Cradle/Core/OutputTypes/Embed.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using IStoryThread = System.Collections.Generic.IEnumerable; 5 | 6 | namespace Cradle 7 | { 8 | public abstract class Embed: StoryOutput 9 | { 10 | } 11 | 12 | public class EmbedPassage : Embed 13 | { 14 | public StoryVar[] Parameters; 15 | 16 | public EmbedPassage(string passageName, params StoryVar[] parameters) 17 | { 18 | this.Name = passageName; 19 | this.Parameters = parameters; 20 | } 21 | } 22 | 23 | public class EmbedFragment : Embed 24 | { 25 | public Func GetThread; 26 | 27 | public EmbedFragment(Func fragment) 28 | { 29 | GetThread = fragment; 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /.src/Cradle/Core/OutputTypes/HtmlTag.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Cradle 4 | { 5 | public class HtmlTag: StoryOutput 6 | { 7 | public HtmlTag(string text) 8 | { 9 | this.Text = text; 10 | } 11 | 12 | public override string ToString() 13 | { 14 | if (this.Text != null && this.Text.Trim().Length < 1) 15 | return "(whitespace)"; 16 | else 17 | return string.Format("{0} (tag)", this.Text ?? "(null)"); 18 | } 19 | } 20 | } 21 | 22 | -------------------------------------------------------------------------------- /.src/Cradle/Core/OutputTypes/LineBreak.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Cradle 4 | { 5 | public class LineBreak: StoryOutput 6 | { 7 | public LineBreak() 8 | { 9 | } 10 | 11 | public override string ToString() 12 | { 13 | return "(br)"; 14 | } 15 | } 16 | } 17 | 18 | -------------------------------------------------------------------------------- /.src/Cradle/Core/OutputTypes/StoryLink.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System; 3 | using System.Collections; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using IStoryThread = System.Collections.Generic.IEnumerable; 7 | using System.Text.RegularExpressions; 8 | 9 | namespace Cradle 10 | { 11 | public class StoryLink: StoryOutput 12 | { 13 | public string PassageName; 14 | public Dictionary Parameters; 15 | public Func Action; 16 | public bool IsNamed; 17 | 18 | static Regex rx_Name = new Regex(@"^((?[^=]+?)\s*=\s*)", RegexOptions.ExplicitCapture); 19 | 20 | public StoryLink(string text, string passageName, Func action, bool useNameSyntax = true) 21 | { 22 | this.PassageName = passageName; 23 | this.Action = action; 24 | 25 | // If the name syntax extension is valid, use it 26 | if (useNameSyntax) 27 | { 28 | Match m = rx_Name.Match(text); 29 | if (m.Success) 30 | { 31 | this.Name = m.Success ? m.Groups["name"].Value : text; 32 | this.Text = text.Substring(m.Index + m.Length); 33 | this.IsNamed = true; 34 | return; 35 | } 36 | } 37 | 38 | // Name syntax didn't do anything so use the text as-is 39 | this.Name = text; 40 | this.Text = text; 41 | this.IsNamed = false; 42 | } 43 | 44 | public StoryLink(string text, string passageName, bool useNameSyntax = true) : 45 | this( text, passageName, null, useNameSyntax) 46 | { 47 | } 48 | 49 | public StoryLink(string text, Func action, bool useNameSyntax = true) : 50 | this(text, null, action, useNameSyntax) 51 | { 52 | } 53 | 54 | public static bool operator==(StoryLink a, StoryLink b) 55 | { 56 | bool anull = object.ReferenceEquals(a,null); 57 | bool bnull = object.ReferenceEquals(b,null); 58 | 59 | if (anull && bnull) 60 | return true; 61 | if ((anull && !bnull) || (!anull && bnull)) 62 | return false; 63 | 64 | return a.Text == b.Text && a.PassageName == b.PassageName && a.Action == b.Action; 65 | } 66 | 67 | public static bool operator!=(StoryLink a, StoryLink b) 68 | { 69 | return !(a == b); 70 | } 71 | 72 | public override bool Equals(object obj) 73 | { 74 | if (obj is StoryLink) { 75 | return ((StoryLink)obj) == this; 76 | } 77 | else 78 | return base.Equals(obj); 79 | } 80 | 81 | public override int GetHashCode() 82 | { 83 | throw new NotImplementedException(); 84 | } 85 | 86 | public override string ToString() 87 | { 88 | return string.Format("[[{0}{1}]]{2}{3}", 89 | this.Name != this.Text ? this.Name + " = " : null, 90 | this.Text, 91 | this.Action != null ? " --> (fragment)" : null, 92 | this.PassageName != null ? " --> " + PassageName : null 93 | ); 94 | } 95 | } 96 | } 97 | 98 | -------------------------------------------------------------------------------- /.src/Cradle/Core/OutputTypes/StoryPassage.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using IStoryThread = System.Collections.Generic.IEnumerable; 5 | 6 | namespace Cradle 7 | { 8 | public class StoryPassage: StoryOutput 9 | { 10 | public string[] Tags; 11 | public Func MainThread; 12 | 13 | public StoryPassage(string name, string[] tags, Func mainThread) 14 | { 15 | this.Name = name; 16 | this.Tags = tags; 17 | this.MainThread = mainThread; 18 | } 19 | 20 | public override string ToString() 21 | { 22 | return string.Format("{0} (passage)", this.Name); 23 | } 24 | } 25 | } 26 | 27 | -------------------------------------------------------------------------------- /.src/Cradle/Core/OutputTypes/StoryText.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Cradle 4 | { 5 | public class StoryText: StoryOutput 6 | { 7 | public StoryText(string text) 8 | { 9 | this.Text = text; 10 | } 11 | 12 | public override string ToString() 13 | { 14 | if (this.Text != null && this.Text.Trim().Length < 1) 15 | return "(whitespace)"; 16 | else 17 | return string.Format("{0} (text)", this.Text ?? "(null)"); 18 | } 19 | } 20 | } 21 | 22 | -------------------------------------------------------------------------------- /.src/Cradle/Core/OutputTypes/StyleGroup.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Text; 3 | 4 | namespace Cradle 5 | { 6 | public class StyleGroup: StoryOutput 7 | { 8 | public Style Style; 9 | 10 | public StyleGroup(Style style) 11 | { 12 | this.Style = style; 13 | } 14 | 15 | public override string ToString() 16 | { 17 | // This is just for debugging purposes 18 | StringBuilder buffer = new StringBuilder("(style-group: "); 19 | foreach (var entry in this.Style) 20 | { 21 | buffer.AppendFormat(" {0}='{1}'", entry.Key, entry.Value); 22 | } 23 | buffer.Append(")"); 24 | return buffer.ToString(); 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /.src/Cradle/Core/RuntimeMacros.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections; 3 | 4 | namespace Cradle 5 | { 6 | public abstract class RuntimeMacros 7 | { 8 | public Story Story; 9 | } 10 | } 11 | 12 | -------------------------------------------------------------------------------- /.src/Cradle/Core/RuntimeVars.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System; 3 | using System.Linq; 4 | using System.Collections; 5 | using System.Collections.Generic; 6 | 7 | namespace Cradle 8 | { 9 | public abstract class RuntimeVars: IDictionary 10 | { 11 | public Story Story; 12 | public bool StrictMode; 13 | 14 | protected class Accessor 15 | { 16 | public Func Get; 17 | public Action Set; 18 | } 19 | 20 | protected Dictionary accessors = new Dictionary(); 21 | 22 | protected void VarDef(string name, Func getter, Action setter) 23 | { 24 | accessors.Add(name, new Accessor() { Get = getter, Set = setter}); 25 | } 26 | 27 | internal void Reset() 28 | { 29 | foreach (Accessor accessor in accessors.Values) 30 | accessor.Set(default(StoryVar)); 31 | } 32 | 33 | public bool ContainsKey(string varName) 34 | { 35 | return accessors.ContainsKey(varName); 36 | } 37 | 38 | public ICollection Keys 39 | { 40 | get { return accessors.Keys; } 41 | } 42 | 43 | public bool TryGetValue(string varName, out StoryVar value) 44 | { 45 | value = default(StoryVar); 46 | Accessor accessor; 47 | if (!accessors.TryGetValue(varName, out accessor)) 48 | return false; 49 | 50 | value = accessor.Get(); 51 | return true; 52 | } 53 | 54 | public ICollection Values 55 | { 56 | get { return accessors.Values.Select(accessor => accessor.Get()).ToArray(); } 57 | } 58 | 59 | public StoryVar this[string varName] 60 | { 61 | get 62 | { 63 | return GetMember(varName); 64 | } 65 | set 66 | { 67 | SetMember(varName, value); 68 | } 69 | } 70 | 71 | public StoryVar GetMember(string varName) 72 | { 73 | var value = default(StoryVar); 74 | if (!TryGetValue(varName, out value)) 75 | throw new StoryException(string.Format("There is no variable with the name '{0}'.", varName)); 76 | return value; 77 | } 78 | 79 | public void SetMember(string varName, StoryVar value) 80 | { 81 | StoryVar prevValue = this[varName]; 82 | object v = value.Duplicate().Value; 83 | 84 | // Enfore strict mode 85 | if (StrictMode) 86 | { 87 | if (prevValue.Value != null && !StoryVar.TryConvertTo(v, prevValue.InnerType, out v)) 88 | throw new StrictModeException(string.Format("The variable '{0}' was previously assigned a value of type {1}, and so cannot be assigned a value of type {2}.", 89 | varName, 90 | prevValue.Value.GetType().Name, 91 | v == null ? "null" : v.GetType().Name 92 | )); 93 | } 94 | 95 | // Run the setter 96 | accessors[varName].Set(new StoryVar(v)); 97 | } 98 | 99 | public int Count 100 | { 101 | get { return accessors.Count; } 102 | } 103 | 104 | void IDictionary.Add(string key, StoryVar value) 105 | { 106 | throw new NotSupportedException(); 107 | } 108 | 109 | bool IDictionary.Remove(string key) 110 | { 111 | throw new NotSupportedException(); 112 | } 113 | 114 | IEnumerator IEnumerable.GetEnumerator() 115 | { 116 | throw new NotImplementedException(); 117 | } 118 | 119 | void ICollection>.Add(KeyValuePair item) 120 | { 121 | throw new NotSupportedException(); 122 | } 123 | 124 | void ICollection>.Clear() 125 | { 126 | throw new NotSupportedException(); 127 | } 128 | 129 | bool ICollection>.Contains(KeyValuePair item) 130 | { 131 | return ((ICollection>)accessors).Contains(item); 132 | } 133 | 134 | void ICollection>.CopyTo(KeyValuePair[] array, int arrayIndex) 135 | { 136 | ((ICollection>)accessors).CopyTo(array, arrayIndex); 137 | } 138 | 139 | bool ICollection>.IsReadOnly 140 | { 141 | get { return ((ICollection>)accessors).IsReadOnly; } 142 | } 143 | 144 | bool ICollection>.Remove(KeyValuePair item) 145 | { 146 | throw new NotSupportedException(); 147 | } 148 | 149 | IEnumerator> IEnumerable>.GetEnumerator() 150 | { 151 | return accessors.Select(pair => new KeyValuePair(pair.Key, pair.Value.Get())).GetEnumerator(); 152 | } 153 | 154 | StoryVar IDictionary.this[string key] 155 | { 156 | get 157 | { 158 | return GetMember(key); 159 | } 160 | set 161 | { 162 | SetMember(key, value); 163 | } 164 | } 165 | } 166 | } 167 | 168 | -------------------------------------------------------------------------------- /.src/Cradle/Core/StoryOutput.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Cradle 4 | { 5 | public abstract class StoryOutput 6 | { 7 | public string Name; 8 | public string Text; 9 | public int Index; 10 | 11 | public StyleGroup StyleGroup; 12 | public Embed EmbedInfo; 13 | 14 | 15 | public bool BelongsToStyleGroup(StyleGroup group) 16 | { 17 | if (group == null) 18 | throw new ArgumentNullException("group"); 19 | 20 | StyleGroup parentGroup = this.StyleGroup; 21 | if (parentGroup == group) 22 | return true; 23 | else if (parentGroup != null) 24 | return parentGroup.BelongsToStyleGroup(group); 25 | else 26 | return false; 27 | } 28 | 29 | public Style GetAppliedStyle() 30 | { 31 | Style style = new Style(); 32 | StyleGroup group = this.StyleGroup; 33 | while (group != null) 34 | { 35 | foreach (var entry in group.Style) 36 | if (!style.ContainsKey(entry.Key)) 37 | style.Add(entry.Key, entry.Value); 38 | 39 | group = group.StyleGroup; 40 | } 41 | 42 | return style; 43 | } 44 | } 45 | } 46 | 47 | -------------------------------------------------------------------------------- /.src/Cradle/Core/StyleScope.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Cradle 4 | { 5 | public class StyleScope : IDisposable 6 | { 7 | internal StyleGroup Group; 8 | internal event Action OnDisposed; 9 | 10 | public StyleScope(StyleGroup group) 11 | { 12 | this.Group = group; 13 | } 14 | 15 | void IDisposable.Dispose() 16 | { 17 | if (OnDisposed != null) 18 | OnDisposed(this); 19 | } 20 | } 21 | } 22 | 23 | -------------------------------------------------------------------------------- /.src/Cradle/Core/VarType.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Reflection; 5 | using System.Text; 6 | 7 | namespace Cradle 8 | { 9 | public interface IVarType 10 | { 11 | StoryVar GetMember(StoryVar member); 12 | void SetMember(StoryVar member, StoryVar value); 13 | void RemoveMember(StoryVar member); 14 | 15 | bool Compare(Operator op, object b, out bool result); 16 | bool Combine(Operator op, object b, out StoryVar result); 17 | bool Unary(Operator op, out StoryVar result); 18 | bool ConvertTo(Type t, out object result, bool strict = false); 19 | IVarType Duplicate(); 20 | } 21 | 22 | public abstract class VarType: IVarType 23 | { 24 | public abstract StoryVar GetMember(StoryVar member); 25 | public abstract void SetMember(StoryVar member, StoryVar value); 26 | public abstract void RemoveMember(StoryVar member); 27 | 28 | public abstract bool Compare(Operator op, object b, out bool result); 29 | public abstract bool Combine(Operator op, object b, out StoryVar result); 30 | public abstract bool Unary(Operator op, out StoryVar result); 31 | public abstract bool ConvertTo(Type t, out object result, bool strict = false); 32 | public abstract IVarType Duplicate(); 33 | } 34 | 35 | public interface IVarTypeService 36 | { 37 | StoryVar GetMember(object container, StoryVar member); 38 | void SetMember(object container, StoryVar member, StoryVar value); 39 | void RemoveMember(object container, StoryVar member); 40 | 41 | bool Compare(Operator op, object a, object b, out bool result); 42 | bool Combine(Operator op, object a, object b, out StoryVar result); 43 | bool Unary(Operator op, object a, out StoryVar result); 44 | bool ConvertTo(object a, Type t, out object result, bool strict = false); 45 | bool ConvertFrom(object a, out object result, bool strict = false); 46 | object Duplicate(object value); 47 | } 48 | 49 | public abstract class VarTypeService: IVarTypeService 50 | { 51 | public abstract StoryVar GetMember(T container, StoryVar member); 52 | public abstract void SetMember(T container, StoryVar member, StoryVar value); 53 | public abstract void RemoveMember(T container, StoryVar member); 54 | 55 | public abstract bool Compare(Operator op, T a, object b, out bool result); 56 | public abstract bool Combine(Operator op, T a, object b, out StoryVar result); 57 | public abstract bool Unary(Operator op, T a, out StoryVar result); 58 | public abstract bool ConvertTo(T a, Type t, out object result, bool strict = false); 59 | public abstract bool ConvertFrom(object a, out T result, bool strict = false); 60 | public abstract T Duplicate(T value); 61 | 62 | public bool ConvertTo(T a, out ResultT resultT) 63 | { 64 | resultT = default(ResultT); 65 | object result; 66 | if (ConvertTo(a, typeof(ResultT), out result)) 67 | { 68 | resultT = (ResultT)result; 69 | return true; 70 | } 71 | else 72 | return false; 73 | } 74 | 75 | bool IVarTypeService.Compare(Operator op, object a, object b, out bool result) 76 | { 77 | return Compare(op, (T)a, b, out result); 78 | } 79 | 80 | bool IVarTypeService.Combine(Operator op, object a, object b, out StoryVar result) 81 | { 82 | return Combine(op, (T)a, b, out result); 83 | } 84 | 85 | bool IVarTypeService.Unary(Operator op, object a, out StoryVar result) 86 | { 87 | return Unary(op, (T)a, out result); 88 | } 89 | 90 | bool IVarTypeService.ConvertTo(object a, Type t, out object result, bool strict) 91 | { 92 | return ConvertTo((T)a, t, out result, strict); 93 | } 94 | 95 | bool IVarTypeService.ConvertFrom(object a, out object result, bool strict) 96 | { 97 | T resultT; 98 | bool success = ConvertFrom(a, out resultT, strict); 99 | result = resultT; 100 | return success; 101 | } 102 | 103 | StoryVar IVarTypeService.GetMember(object container, StoryVar member) 104 | { 105 | return GetMember((T)container, member); 106 | } 107 | 108 | void IVarTypeService.SetMember(object container, StoryVar member, StoryVar value) 109 | { 110 | SetMember((T)container, member, value); 111 | } 112 | 113 | void IVarTypeService.RemoveMember(object container, StoryVar member) 114 | { 115 | RemoveMember((T)container, member); 116 | } 117 | 118 | object IVarTypeService.Duplicate(object value) 119 | { 120 | return Duplicate((T)value); 121 | } 122 | } 123 | 124 | public enum Operator 125 | { 126 | Equals, 127 | GreaterThan, 128 | GreaterThanOrEquals, 129 | LessThan, 130 | LessThanOrEquals, 131 | Contains, 132 | Add, 133 | Subtract, 134 | Multiply, 135 | Divide, 136 | Modulo, 137 | Increment, 138 | Decrement, 139 | LogicalAnd, 140 | LogicalOr 141 | } 142 | } 143 | -------------------------------------------------------------------------------- /.src/Cradle/Core/VarTypes/BoolService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using Cradle; 6 | 7 | namespace Cradle 8 | { 9 | public class BoolService: VarTypeService 10 | { 11 | public override StoryVar GetMember(bool container, StoryVar member) 12 | { 13 | throw new VarTypeMemberException("Cannot directly get any members of a boolean."); 14 | } 15 | 16 | public override void SetMember(bool container, StoryVar member, StoryVar value) 17 | { 18 | throw new VarTypeMemberException("Cannot directly set any members of a boolean."); 19 | } 20 | 21 | public override void RemoveMember(bool container, StoryVar member) 22 | { 23 | throw new VarTypeMemberException("Cannot directly remove any members of a boolean."); 24 | } 25 | 26 | // ............................ 27 | 28 | public override bool Compare(Operator op, bool a, object b, out bool result) 29 | { 30 | result = false; 31 | 32 | if (op == Operator.Equals) 33 | { 34 | // Equaliy, evaluate as bools 35 | bool bBool; 36 | if (!StoryVar.TryConvertTo(b, out bBool)) 37 | return false; 38 | 39 | result = a == bBool; 40 | return true; 41 | } 42 | else 43 | { 44 | // Evaluate as numbers for other operators 45 | double aDouble; 46 | return ConvertTo(a, out aDouble) && StoryVar.GetTypeService(true).Compare(op, aDouble, b, out result); 47 | } 48 | } 49 | 50 | public override bool Combine(Operator op, bool a, object b, out StoryVar result) 51 | { 52 | result = default(StoryVar); 53 | 54 | if (op == Operator.LogicalAnd || op == Operator.LogicalOr) 55 | { 56 | bool bBool; 57 | if (!StoryVar.TryConvertTo(b, out bBool)) 58 | return false; 59 | 60 | switch(op) 61 | { 62 | case Operator.LogicalAnd: 63 | result = a && bBool; break; 64 | case Operator.LogicalOr: 65 | result = a || bBool; break; 66 | default: 67 | break; 68 | } 69 | return true; 70 | } 71 | 72 | double aDouble; 73 | return ConvertTo(a, out aDouble) && StoryVar.GetTypeService(true).Combine(op, aDouble, b, out result); 74 | } 75 | 76 | public override bool Unary(Operator op, bool a, out StoryVar result) 77 | { 78 | result = default(StoryVar); 79 | 80 | double aDouble; 81 | return ConvertTo(a, out aDouble) && StoryVar.GetTypeService(true).Unary(op, aDouble, out result); 82 | } 83 | 84 | public override bool ConvertTo(bool a, Type t, out object result, bool strict = false) 85 | { 86 | result = null; 87 | if (t == typeof(bool)) 88 | { 89 | result = a; 90 | } 91 | else if (t == typeof(string)) 92 | { 93 | result = a ? "true" : "false"; 94 | } 95 | else if (t == typeof(double) || t == typeof(int)) 96 | { 97 | result = a ? 1 : 0; 98 | } 99 | else 100 | return false; 101 | 102 | return true; 103 | } 104 | 105 | public override bool ConvertFrom(object a, out bool result, bool strict = false) 106 | { 107 | result = false; 108 | if (a == null) 109 | return true; 110 | else 111 | return false; 112 | 113 | } 114 | 115 | public override bool Duplicate(bool value) 116 | { 117 | return value; 118 | } 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /.src/Cradle/Core/VarTypes/DoubleService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using Cradle; 6 | 7 | namespace Cradle 8 | { 9 | public class DoubleService: VarTypeService 10 | { 11 | public override StoryVar GetMember(double container, StoryVar member) 12 | { 13 | throw new VarTypeMemberException("Cannot directly get any members of a number."); 14 | } 15 | 16 | public override void SetMember(double container, StoryVar member, StoryVar value) 17 | { 18 | throw new VarTypeMemberException("Cannot directly set any members of a number."); 19 | } 20 | 21 | public override void RemoveMember(double container, StoryVar member) 22 | { 23 | throw new VarTypeMemberException("Cannot directly remove any members of a number."); 24 | } 25 | 26 | // ............................ 27 | 28 | public override bool Compare(Operator op, double a, object b, out bool result) 29 | { 30 | result = false; 31 | 32 | double bDouble; 33 | if (!StoryVar.TryConvertTo(b, out bDouble)) 34 | return false; 35 | 36 | switch(op) 37 | { 38 | case Operator.Equals: 39 | result = a == bDouble; break; 40 | case Operator.GreaterThan: 41 | result = a > bDouble; break; 42 | case Operator.GreaterThanOrEquals: 43 | result = a >= bDouble; break; 44 | case Operator.LessThan: 45 | result = a < bDouble; break; 46 | case Operator.LessThanOrEquals: 47 | result = a <= bDouble; break; 48 | default: 49 | return false; // comparison not possible 50 | } 51 | return true; 52 | } 53 | 54 | public override bool Combine(Operator op, double a, object b, out StoryVar result) 55 | { 56 | result = default(StoryVar); 57 | 58 | // Logical operators, treat as bool 59 | if (op == Operator.LogicalAnd || op == Operator.LogicalOr) 60 | { 61 | bool aBool; 62 | return ConvertTo(a, out aBool) && StoryVar.GetTypeService(true).Combine(op, aBool, b, out result); 63 | } 64 | 65 | double bDouble; 66 | if (!StoryVar.TryConvertTo(b, out bDouble)) 67 | return false; 68 | 69 | switch (op) 70 | { 71 | case Operator.Add: 72 | result = a + bDouble; break; 73 | case Operator.Subtract: 74 | result = a - bDouble; break; 75 | case Operator.Multiply: 76 | result = a * bDouble; break; 77 | case Operator.Divide: 78 | result = a / bDouble; break; 79 | case Operator.Modulo: 80 | result = a % bDouble; break; 81 | default: 82 | return false; // combination not possible 83 | } 84 | return true; 85 | } 86 | 87 | public override bool Unary(Operator op, double a, out StoryVar result) 88 | { 89 | result = default(StoryVar); 90 | 91 | switch (op) 92 | { 93 | case Operator.Increment: 94 | result = ++a; break; 95 | case Operator.Decrement: 96 | result = --a; break; 97 | default: 98 | return false; 99 | } 100 | return true; 101 | } 102 | 103 | public override bool ConvertTo(double a, Type t, out object result, bool strict = false) 104 | { 105 | result = null; 106 | if (t == typeof(double)) 107 | { 108 | result = a; 109 | } 110 | else if (t == typeof(string)) 111 | { 112 | if (strict) 113 | return false; 114 | result = a.ToString(); 115 | } 116 | else if (t == typeof(int)) 117 | { 118 | try { result = Convert.ToInt32(a); } 119 | catch { return false; } 120 | } 121 | else if (t == typeof(bool)) 122 | result = a != 0.0; 123 | else 124 | return false; 125 | 126 | return true; 127 | } 128 | 129 | public override bool ConvertFrom(object a, out double result, bool strict = false) 130 | { 131 | result = 0d; 132 | if (a == null) 133 | return true; 134 | else 135 | return false; 136 | 137 | } 138 | 139 | public override double Duplicate(double value) 140 | { 141 | return value; 142 | } 143 | } 144 | } 145 | -------------------------------------------------------------------------------- /.src/Cradle/Core/VarTypes/IntService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using Cradle; 6 | 7 | namespace Cradle 8 | { 9 | public class IntService: VarTypeService 10 | { 11 | /// 12 | /// All numeric operations are done as floating-point numbers, but are converted back to integers if the result is a whole number within this precision. 13 | /// 14 | public const int DecimalPrecision = 5; 15 | 16 | public override StoryVar GetMember(int container, StoryVar member) 17 | { 18 | throw new VarTypeMemberException("Cannot directly get any members of a number."); 19 | } 20 | 21 | public override void SetMember(int container, StoryVar member, StoryVar value) 22 | { 23 | throw new VarTypeMemberException("Cannot directly set any members of a number."); 24 | } 25 | 26 | public override void RemoveMember(int container, StoryVar member) 27 | { 28 | throw new VarTypeMemberException("Cannot directly remove any members of a number."); 29 | } 30 | 31 | // ............................ 32 | 33 | public override bool Compare(Operator op, int a, object b, out bool result) 34 | { 35 | // Always use double comparison 36 | result = false; 37 | double aDouble; 38 | return ConvertTo(a, out aDouble) && StoryVar.GetTypeService(true).Compare(op, aDouble, b, out result); 39 | } 40 | 41 | public override bool Combine(Operator op, int a, object b, out StoryVar result) 42 | { 43 | result = default(StoryVar); 44 | 45 | // Logical operators, treat as bool 46 | if (op == Operator.LogicalAnd || op == Operator.LogicalOr) 47 | { 48 | bool aBool; 49 | return ConvertTo(a, out aBool) && StoryVar.GetTypeService(true).Combine(op, aBool, b, out result); 50 | } 51 | 52 | // Always use double combinations 53 | double aDouble; 54 | if (!ConvertTo(a, out aDouble) || !StoryVar.GetTypeService(true).Combine(op, aDouble, b, out result)) 55 | return false; 56 | 57 | // Convert result back to int if it is whole number (or close to it in precision) 58 | double resultDouble = (double)result.Value; 59 | if (Math.Round(resultDouble) == Math.Round(resultDouble, DecimalPrecision)) 60 | result.Value = Convert.ToInt32(resultDouble); 61 | 62 | return true; 63 | } 64 | 65 | public override bool Unary(Operator op, int a, out StoryVar result) 66 | { 67 | result = default(StoryVar); 68 | 69 | // Always use double operations 70 | double aDouble; 71 | if (!ConvertTo(a, out aDouble) || !StoryVar.GetTypeService(true).Unary(op, aDouble, out result)) 72 | return false; 73 | 74 | // Convert result back to int if it is whole number (or close to it in precision) 75 | double resultDouble = (double)result.Value; 76 | if (Math.Round(resultDouble) == Math.Round(resultDouble, DecimalPrecision)) 77 | result.Value = Convert.ToInt32(resultDouble); 78 | 79 | return true; 80 | } 81 | 82 | public override bool ConvertTo(int a, Type t, out object result, bool strict = false) 83 | { 84 | result = null; 85 | if (t == typeof(int)) 86 | { 87 | result = a; 88 | } 89 | else if (t == typeof(string)) 90 | { 91 | if (strict) 92 | return false; 93 | result = a.ToString(); 94 | } 95 | else if (t == typeof(double)) 96 | { 97 | try { result = Convert.ToDouble(a); } 98 | catch (Exception ex) { UnityEngine.Debug.LogException(ex); return false; } 99 | } 100 | else if (t == typeof(bool)) 101 | result = a != 0; 102 | else 103 | return false; 104 | 105 | return true; 106 | } 107 | 108 | 109 | public override bool ConvertFrom(object a, out int result, bool strict = false) 110 | { 111 | result = 0; 112 | if (a == null) 113 | return true; 114 | else 115 | return false; 116 | 117 | } 118 | 119 | public override int Duplicate(int value) 120 | { 121 | return value; 122 | } 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /.src/Cradle/Core/VarTypes/StringService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using Cradle; 6 | 7 | namespace Cradle 8 | { 9 | public class StringService: VarTypeService 10 | { 11 | public override StoryVar GetMember(string container, StoryVar member) 12 | { 13 | string containerString = (string)container; 14 | 15 | StoryVar value; 16 | 17 | int pos; 18 | if (StoryVar.TryConvertTo(member, out pos)) 19 | value = containerString[pos]; 20 | else if (member.ToString() == "length") 21 | value = containerString.Length; 22 | else 23 | value = default(StoryVar); 24 | 25 | return value; 26 | } 27 | 28 | public override void SetMember(string container, StoryVar member, StoryVar value) 29 | { 30 | throw new VarTypeMemberException("Cannot directly set any members of a string."); 31 | } 32 | 33 | public override void RemoveMember(string container, StoryVar member) 34 | { 35 | throw new VarTypeMemberException("Cannot directly remove any members of a string."); 36 | } 37 | 38 | // ............................ 39 | 40 | public override bool Compare(Operator op, string a, object b, out bool result) 41 | { 42 | result = false; 43 | 44 | // Logical operators, treat as bool 45 | if (op == Operator.LogicalAnd || op == Operator.LogicalOr) 46 | { 47 | bool aBool; 48 | return ConvertTo(a, out aBool) && StoryVar.GetTypeService(true).Compare(op, aBool, b, out result); 49 | } 50 | 51 | // Try numeric comparison (in strict mode this won't work) 52 | double aDouble; 53 | if (ConvertTo(a, out aDouble) && StoryVar.GetTypeService(true).Compare(op, aDouble, b, out result)) 54 | return true; 55 | 56 | string bString; 57 | if (!StoryVar.TryConvertTo(b, out bString)) 58 | return false; 59 | 60 | switch(op) 61 | { 62 | case Operator.Equals: 63 | result = a == bString; break; 64 | case Operator.GreaterThan: 65 | result = String.Compare(a, bString) > 0; break; 66 | case Operator.GreaterThanOrEquals: 67 | result = String.Compare(a, bString) >= 0; break; 68 | case Operator.LessThan: 69 | result = String.Compare(a, bString) < 0; break; 70 | case Operator.LessThanOrEquals: 71 | result = String.Compare(a, bString) <= 0; break; 72 | case Operator.Contains: 73 | result = a.Contains(bString); break; 74 | default: 75 | return false; 76 | } 77 | 78 | return true; 79 | } 80 | 81 | public override bool Combine(Operator op, string a, object b, out StoryVar result) 82 | { 83 | result = default(StoryVar); 84 | 85 | // Logical operators, treat as bool 86 | if (op == Operator.LogicalAnd || op == Operator.LogicalOr) 87 | { 88 | bool aBool; 89 | return ConvertTo(a, out aBool) && StoryVar.GetTypeService(true).Combine(op, aBool, b, out result); 90 | } 91 | 92 | // To comply with Javascript comparison, concat if b is a string 93 | if (op == Operator.Add && b is string) 94 | { 95 | result = a + (string)b; 96 | return true; 97 | } 98 | 99 | // For other operators, try numeric comabinations if possible (in strict mode this won't work) 100 | double aDouble; 101 | if (ConvertTo(a, out aDouble)) 102 | return StoryVar.GetTypeService(true).Combine(op, aDouble, b, out result); 103 | else 104 | return false; 105 | } 106 | 107 | public override bool Unary(Operator op, string a, out StoryVar result) 108 | { 109 | result = default(StoryVar); 110 | 111 | // Try numeric unary if possible (in strict mode this won't work) 112 | double aDouble; 113 | if (ConvertTo(a, out aDouble)) 114 | return StoryVar.GetTypeService(true).Unary(op, aDouble, out result); 115 | else 116 | return false; 117 | } 118 | 119 | public override bool ConvertTo(string a, Type t, out object result, bool strict = false) 120 | { 121 | result = null; 122 | if (t == typeof(string)) 123 | { 124 | result = a; 125 | } 126 | else if (t == typeof(double)) 127 | { 128 | if (strict) 129 | return false; 130 | 131 | double d; 132 | if (!double.TryParse(a, out d)) 133 | return false; 134 | result = d; 135 | } 136 | else if (t == typeof(int)) 137 | { 138 | if (strict) 139 | return false; 140 | 141 | int i; 142 | if (!int.TryParse(a, out i)) 143 | return false; 144 | result = i; 145 | } 146 | else if (t == typeof(bool)) 147 | result = a != null; 148 | else 149 | return false; 150 | 151 | return true; 152 | } 153 | 154 | public override bool ConvertFrom(object a, out string result, bool strict = false) 155 | { 156 | result = null; 157 | 158 | if (a == null) 159 | { 160 | return true; 161 | } 162 | else 163 | return false; 164 | } 165 | 166 | public override string Duplicate(string value) 167 | { 168 | return value; 169 | } 170 | } 171 | } 172 | -------------------------------------------------------------------------------- /.src/Cradle/Cradle.MD.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | AnyCPU 6 | {37C652FC-470E-412B-A63D-452A216E0066} 7 | Library 8 | Cradle 9 | Cradle 10 | v3.5 11 | 12 | 13 | true 14 | full 15 | false 16 | ..\..\ 17 | DEBUG;TRACE 18 | prompt 19 | 4 20 | 21 | 22 | pdbonly 23 | true 24 | ..\..\ 25 | TRACE 26 | prompt 27 | 4 28 | 29 | 30 | 31 | 32 | \Applications\Unity\Unity.app\Contents\Managed\UnityEngine.dll 33 | \Applications\Unity\Unity.app\Contents\Frameworks\Managed\UnityEngine.dll 34 | False 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | false 78 | 79 | 80 | -------------------------------------------------------------------------------- /.src/Cradle/Cradle.VS.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | AnyCPU 6 | {37C652FC-470E-412B-A63D-452A216E0066} 7 | Library 8 | Cradle 9 | Cradle 10 | v3.5 11 | 12 | 13 | true 14 | full 15 | false 16 | ..\..\ 17 | DEBUG;TRACE 18 | prompt 19 | 4 20 | 21 | 22 | pdbonly 23 | true 24 | ..\..\ 25 | TRACE 26 | prompt 27 | 4 28 | 29 | 30 | 31 | 32 | ..\..\..\..\..\..\..\..\Program Files\Unity\Hub\Editor\2018.2.20f1\Editor\Data\Managed\UnityEngine.dll 33 | False 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 512 77 | false 78 | Unity Subset v3.5 79 | 80 | 81 | 82 | 83 | 84 | -------------------------------------------------------------------------------- /.src/Cradle/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | #if !UNITY_EDITOR 2 | using System.Reflection; 3 | using System.Runtime.CompilerServices; 4 | using System.Runtime.InteropServices; 5 | 6 | // General Information about an assembly is controlled through the following 7 | // set of attributes. Change these attribute values to modify the information 8 | // associated with an assembly. 9 | [assembly: AssemblyTitle("Cradle")] 10 | [assembly: AssemblyDescription("")] 11 | [assembly: AssemblyConfiguration("")] 12 | [assembly: AssemblyCompany("D. A. Terre")] 13 | [assembly: AssemblyProduct("Cradle")] 14 | [assembly: AssemblyCopyright("Copyright © 2017")] 15 | [assembly: AssemblyTrademark("")] 16 | [assembly: AssemblyCulture("")] 17 | 18 | // Setting ComVisible to false makes the types in this assembly not visible 19 | // to COM components. If you need to access a type in this assembly from 20 | // COM, set the ComVisible attribute to true on that type. 21 | [assembly: ComVisible(false)] 22 | 23 | // The following GUID is for the ID of the typelib if this project is exposed to COM 24 | [assembly: Guid("77e9a87e-6498-4168-82a7-21bfe951cc20")] 25 | 26 | // Version information for an assembly consists of the following four values: 27 | // 28 | // Major Version 29 | // Minor Version 30 | // Build Number 31 | // Revision 32 | // 33 | [assembly: AssemblyVersion("2.0.2.0")] 34 | [assembly: AssemblyFileVersion("2.0.2.0")] 35 | #endif -------------------------------------------------------------------------------- /.src/Cradle/StoryFormats/Harlowe/HarloweHook.cs: -------------------------------------------------------------------------------- 1 |  2 | /* 3 | using System; 4 | using System.Linq; 5 | using System.Collections.Generic; 6 | using System.Text.RegularExpressions; 7 | using IStoryThread = System.Collections.Generic.IEnumerable; 8 | 9 | namespace Cradle.StoryFormats.Harlowe 10 | { 11 | public class HarloweHook 12 | { 13 | public string HookName; 14 | 15 | public override string ToString() 16 | { 17 | return HookName + " (hook)"; 18 | } 19 | } 20 | 21 | } 22 | */ -------------------------------------------------------------------------------- /.src/Cradle/StoryFormats/Harlowe/HarloweUtils.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Text.RegularExpressions; 6 | 7 | namespace Cradle.StoryFormats.Harlowe 8 | { 9 | public static class HarloweUtils 10 | { 11 | static Regex rx_Position = new Regex(@"^(?'index'\d+)?(st|nd|rd|th)?(?'last'last)?$", RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture); 12 | 13 | public static bool TryPositionToIndex(StoryVar position, int total, out int index) 14 | { 15 | index = -1; 16 | bool fromEnd = false; 17 | 18 | if (StoryVar.TryConvertTo(position, out index)) 19 | { 20 | if (index <= 0) 21 | { 22 | index = Math.Abs(index); 23 | fromEnd = true; 24 | } 25 | else 26 | index -= 1; 27 | } 28 | else 29 | { 30 | string str; 31 | if (!StoryVar.TryConvertTo(position, out str)) 32 | return false; 33 | 34 | Match match = rx_Position.Match(str); 35 | if (!match.Success) 36 | return false; 37 | 38 | fromEnd = match.Groups["last"].Success; 39 | 40 | if (match.Groups["index"].Success) 41 | index = int.Parse(match.Groups["index"].Value) - 1; 42 | else if (fromEnd) 43 | index = 0; 44 | else 45 | return false; 46 | } 47 | 48 | if (fromEnd) 49 | index = total - 1 - index; 50 | 51 | return true; 52 | } 53 | 54 | public static int PositionToIndex(string position, int total) 55 | { 56 | int index = -1; 57 | if (!TryPositionToIndex(position, total, out index)) 58 | throw new VarTypeMemberException(string.Format("'{0}' is not a valid position", position)); 59 | return index; 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /.src/Cradle/StoryFormats/Harlowe/OutputTypes/HarloweLive.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Collections.Generic; 4 | using System.Text.RegularExpressions; 5 | using IStoryThread = System.Collections.Generic.IEnumerable; 6 | 7 | namespace Cradle.StoryFormats.Harlowe 8 | { 9 | public class HarloweLive : EmbedFragment 10 | { 11 | public float seconds; 12 | 13 | public HarloweLive(float seconds, Func fragment) 14 | : base(fragment) 15 | { 16 | } 17 | } 18 | 19 | public class HarloweLiveStop: StoryOutput 20 | { 21 | } 22 | } 23 | 24 | -------------------------------------------------------------------------------- /.src/Cradle/StoryFormats/Harlowe/VarTypes/HarloweCollection.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text.RegularExpressions; 6 | using System.Text; 7 | 8 | namespace Cradle.StoryFormats.Harlowe 9 | { 10 | public abstract class HarloweCollection : VarType 11 | { 12 | public abstract IEnumerable GetValues(); 13 | 14 | protected bool TryGetMemberArray(StoryVar member, out StoryVar val) 15 | { 16 | // Special case when member is an array 17 | if (member.Value is HarloweArray) 18 | { 19 | var memberArray = (HarloweArray)member.Value; 20 | StoryVar[] valueArray = new StoryVar[memberArray.Length]; 21 | for (int i = 0; i < memberArray.Length; i++) 22 | valueArray[i] = GetMember(memberArray.Values[i]); 23 | val = new HarloweArray(valueArray); 24 | return true; 25 | } 26 | else 27 | // Anything else treat as a property 28 | { 29 | val = default(StoryVar); 30 | return false; 31 | } 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /.src/Cradle/StoryFormats/Harlowe/VarTypes/HarloweDataset.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text.RegularExpressions; 6 | using System.Text; 7 | 8 | namespace Cradle.StoryFormats.Harlowe 9 | { 10 | public class HarloweDataset : HarloweCollection 11 | { 12 | internal HashSet Values; 13 | 14 | public HarloweDataset() 15 | { 16 | Values = new HashSet(); 17 | } 18 | 19 | public HarloweDataset(params StoryVar[] vals):this((IEnumerable)vals) 20 | { 21 | } 22 | 23 | public HarloweDataset(IEnumerable vals) 24 | { 25 | Values = new HashSet(HarloweSpread.Flatten(vals)); 26 | } 27 | 28 | public int Length 29 | { 30 | get { return Values.Count; } 31 | } 32 | 33 | public bool Contains(object value) 34 | { 35 | return Values.Contains(value is StoryVar ? (StoryVar)value : new StoryVar(value)); 36 | } 37 | 38 | public override IEnumerable GetValues() 39 | { 40 | foreach (StoryVar val in Values) 41 | yield return val; 42 | } 43 | 44 | public override IVarType Duplicate() 45 | { 46 | return new HarloweDataset(this.GetValues().Select(v => v.Duplicate())); 47 | } 48 | 49 | public override string ToString() 50 | { 51 | var str = new StringBuilder(); 52 | foreach(StoryVar value in Values.OrderBy(v => v)) 53 | { 54 | if (str.Length > 0) 55 | str.Append(','); 56 | str.Append(value.ToString()); 57 | } 58 | 59 | return str.ToString(); 60 | } 61 | 62 | void EnsureNotPosition(string memberName) 63 | { 64 | int index; 65 | if (HarloweUtils.TryPositionToIndex(memberName, Values.Count, out index)) 66 | throw new VarTypeMemberException("Datasets can't be accessed by position."); 67 | } 68 | 69 | public override StoryVar GetMember(StoryVar member) 70 | { 71 | var memberName = member.ToString().ToLower(); 72 | if (memberName == "length") 73 | return this.Length; 74 | 75 | EnsureNotPosition(memberName); 76 | throw new VarTypeMemberException(string.Format("The dataset doesn't have a member called {0}.", memberName)); 77 | } 78 | 79 | public override void SetMember(StoryVar member, StoryVar value) 80 | { 81 | var memberName = member.ToString().ToLower(); 82 | if (memberName == "length") 83 | throw new VarTypeMemberException("'length' cannot be modified."); 84 | 85 | EnsureNotPosition(memberName); 86 | throw new VarTypeMemberException(string.Format("The dataset doesn't have a member called {0}.", memberName)); 87 | } 88 | 89 | public override void RemoveMember(StoryVar member) 90 | { 91 | var memberName = member.ToString().ToLower(); 92 | if (memberName == "length") 93 | throw new VarTypeMemberException("'length' cannot be modified."); 94 | 95 | EnsureNotPosition(memberName); 96 | throw new VarTypeMemberException(string.Format("The dataset doesn't have a member called {0}.", memberName)); 97 | } 98 | 99 | public override bool Compare(Operator op, object b, out bool result) 100 | { 101 | result = false; 102 | 103 | switch (op) 104 | { 105 | case Operator.Equals: { 106 | if (!(b is HarloweDataset)) 107 | return false; 108 | 109 | var bSet = (HarloweDataset)b; 110 | result = Values.SetEquals(bSet.Values); 111 | break; 112 | } 113 | case Operator.Contains: { 114 | result = this.Contains(b); 115 | break; 116 | } 117 | } 118 | 119 | return true; 120 | } 121 | 122 | public override bool Combine(Operator op, object b, out StoryVar result) 123 | { 124 | result = default(StoryVar); 125 | if (!(b is HarloweDataset)) 126 | return false; 127 | var bSet = (HarloweDataset)b; 128 | 129 | switch (op) 130 | { 131 | case Operator.Add: 132 | result = new StoryVar(new HarloweDataset(Values.Concat(bSet.Values))); 133 | break; 134 | case Operator.Subtract: 135 | result = new StoryVar(new HarloweDataset(Values.Except(bSet.Values))); 136 | break; 137 | default: 138 | return false; 139 | } 140 | 141 | return true; 142 | } 143 | 144 | public override bool Unary(Operator op, out StoryVar result) 145 | { 146 | result = default(StoryVar); 147 | return false; 148 | } 149 | 150 | public override bool ConvertTo(System.Type t, out object result, bool strict = false) 151 | { 152 | result = null; 153 | 154 | if (!strict && t == typeof(string)) 155 | { 156 | result = this.ToString(); 157 | return true; 158 | } 159 | else 160 | return false; 161 | } 162 | } 163 | } -------------------------------------------------------------------------------- /.src/Cradle/StoryFormats/Harlowe/VarTypes/HarloweHookRef.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.Text.RegularExpressions; 5 | 6 | namespace Cradle.StoryFormats.Harlowe 7 | { 8 | public class HarloweHookRef: VarType 9 | { 10 | public string HookName; 11 | 12 | public HarloweHookRef(StoryVar hookName) 13 | { 14 | this.HookName = hookName; 15 | } 16 | 17 | public override StoryVar GetMember(StoryVar member) 18 | { 19 | throw new System.NotSupportedException(); 20 | } 21 | 22 | public override void SetMember(StoryVar member, StoryVar value) 23 | { 24 | throw new System.NotSupportedException(); 25 | } 26 | 27 | public override void RemoveMember(StoryVar member) 28 | { 29 | throw new System.NotSupportedException(); 30 | } 31 | 32 | public override bool Compare(Operator op, object b, out bool result) 33 | { 34 | throw new System.NotSupportedException(); 35 | } 36 | 37 | public override bool Combine(Operator op, object b, out StoryVar result) 38 | { 39 | throw new System.NotSupportedException(); 40 | } 41 | 42 | public override bool Unary(Operator op, out StoryVar result) 43 | { 44 | throw new System.NotSupportedException(); 45 | } 46 | 47 | public override bool ConvertTo(System.Type t, out object result, bool strict = false) 48 | { 49 | throw new System.NotSupportedException(); 50 | } 51 | 52 | public override IVarType Duplicate() 53 | { 54 | return new HarloweHookRef(this.HookName); 55 | } 56 | } 57 | } -------------------------------------------------------------------------------- /.src/Cradle/StoryFormats/Harlowe/VarTypes/HarloweSpread.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.Text.RegularExpressions; 5 | 6 | namespace Cradle.StoryFormats.Harlowe 7 | { 8 | public class HarloweSpread: VarType 9 | { 10 | public HarloweCollection Target; 11 | 12 | public HarloweSpread(object val) 13 | { 14 | object v = val is StoryVar ? ((StoryVar)val).Value : val; 15 | 16 | if (!(v is HarloweCollection)) 17 | throw new VarTypeException("Only an array, datamap or dataset can be spread"); 18 | 19 | this.Target = (HarloweCollection)v; 20 | } 21 | 22 | public static IEnumerable Flatten(IEnumerable vals) 23 | { 24 | foreach(StoryVar val in vals) 25 | { 26 | if (val.Value is HarloweSpread) 27 | { 28 | var spread = (HarloweSpread)val.Value; 29 | foreach (StoryVar innerVal in spread.Target.GetValues()) 30 | yield return innerVal.Duplicate(); 31 | 32 | } 33 | else 34 | yield return val.Duplicate(); 35 | } 36 | } 37 | 38 | public static explicit operator HarloweSpread(StoryVar val) 39 | { 40 | return new HarloweSpread(val); 41 | } 42 | 43 | public override StoryVar GetMember(StoryVar member) 44 | { 45 | throw new System.NotSupportedException(); 46 | } 47 | 48 | public override void SetMember(StoryVar member, StoryVar value) 49 | { 50 | throw new System.NotSupportedException(); 51 | } 52 | 53 | public override void RemoveMember(StoryVar member) 54 | { 55 | throw new System.NotSupportedException(); 56 | } 57 | 58 | public override bool Compare(Operator op, object b, out bool result) 59 | { 60 | throw new System.NotSupportedException(); 61 | } 62 | 63 | public override bool Combine(Operator op, object b, out StoryVar result) 64 | { 65 | throw new System.NotSupportedException(); 66 | } 67 | 68 | public override bool Unary(Operator op, out StoryVar result) 69 | { 70 | throw new System.NotSupportedException(); 71 | } 72 | 73 | public override bool ConvertTo(System.Type t, out object result, bool strict = false) 74 | { 75 | throw new System.NotSupportedException(); 76 | } 77 | 78 | public override IVarType Duplicate() 79 | { 80 | return new HarloweSpread(this.Target); 81 | } 82 | } 83 | } -------------------------------------------------------------------------------- /.src/Cradle/StoryFormats/Harlowe/VarTypes/HarloweStringService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using Cradle; 6 | 7 | namespace Cradle.StoryFormats.Harlowe 8 | { 9 | public class HarloweStringService: StringService 10 | { 11 | public override StoryVar GetMember(string container, StoryVar member) 12 | { 13 | // Special case when member is an array 14 | if (member.Value is HarloweArray) 15 | { 16 | var memberArray = (HarloweArray)member.Value; 17 | var buffer = new char[memberArray.Length]; 18 | for (int i = 0; i < memberArray.Length; i++) 19 | buffer[i] = GetMember(container, StoryVar.ConvertTo(memberArray.Values[i])).ToString()[0]; 20 | 21 | return new string(buffer); 22 | } 23 | 24 | int index; 25 | if (HarloweUtils.TryPositionToIndex(member, container.Length, out index)) 26 | return new StoryVar(container[index].ToString()); 27 | 28 | return base.GetMember(container, member); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Cradle.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daterre/Cradle/981be1cca368a3c21c26d6760402206e373fb890/Cradle.dll -------------------------------------------------------------------------------- /Cradle.dll.mdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daterre/Cradle/981be1cca368a3c21c26d6760402206e373fb890/Cradle.dll.mdb -------------------------------------------------------------------------------- /Cradle.dll.mdb.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 99d9d1b1ce6ac5842a91c5ef4e842a21 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Cradle.dll.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7340f46ada5004b4e8193cbddceec27d 3 | timeCreated: 1480860209 4 | licenseType: Pro 5 | PluginImporter: 6 | serializedVersion: 1 7 | iconMap: {} 8 | executionOrder: {} 9 | isPreloaded: 0 10 | platformData: 11 | Any: 12 | enabled: 1 13 | settings: {} 14 | Editor: 15 | enabled: 0 16 | settings: 17 | DefaultValueInitialized: true 18 | WindowsStoreApps: 19 | enabled: 0 20 | settings: 21 | CPU: AnyCPU 22 | userData: 23 | assetBundleName: 24 | assetBundleVariant: 25 | -------------------------------------------------------------------------------- /Cradle.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daterre/Cradle/981be1cca368a3c21c26d6760402206e373fb890/Cradle.pdb -------------------------------------------------------------------------------- /Cradle.pdb.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 09e34431edf23a3449645c3614ed7ee4 3 | timeCreated: 1480860205 4 | licenseType: Pro 5 | DefaultImporter: 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Documentation.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f3d56bac0d57c3b429952f143d31925e 3 | folderAsset: yes 4 | timeCreated: 1462955203 5 | licenseType: Pro 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Documentation/Harlowe.md: -------------------------------------------------------------------------------- 1 | # Harlowe - Cradle story format 2 | Supports [Harlowe 1.2.2 by Leon Arnott](https://twine2.neocities.org/) 3 | 4 | TODO 5 | -------------------------------------------------------------------------------- /Documentation/Harlowe.md.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e197755cc865b2946a55e2dfaae384f6 3 | timeCreated: 1469349131 4 | licenseType: Pro 5 | DefaultImporter: 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Documentation/Sugar.md.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b8eb468ae91f14640b932e3597f74bf4 3 | timeCreated: 1462955203 4 | licenseType: Pro 5 | DefaultImporter: 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Documentation/cradle-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daterre/Cradle/981be1cca368a3c21c26d6760402206e373fb890/Documentation/cradle-logo.png -------------------------------------------------------------------------------- /Documentation/cradle-logo.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5a38bbc4950d46b409b5fba76e806aee 3 | timeCreated: 1467901767 4 | licenseType: Pro 5 | TextureImporter: 6 | fileIDToRecycleName: {} 7 | serializedVersion: 2 8 | mipmaps: 9 | mipMapMode: 0 10 | enableMipMap: 1 11 | linearTexture: 0 12 | correctGamma: 0 13 | fadeOut: 0 14 | borderMipMap: 0 15 | mipMapFadeDistanceStart: 1 16 | mipMapFadeDistanceEnd: 3 17 | bumpmap: 18 | convertToNormalMap: 0 19 | externalNormalMap: 0 20 | heightScale: 0.25 21 | normalMapFilter: 0 22 | isReadable: 0 23 | grayScaleToAlpha: 0 24 | generateCubemap: 0 25 | cubemapConvolution: 0 26 | cubemapConvolutionSteps: 7 27 | cubemapConvolutionExponent: 1.5 28 | seamlessCubemap: 0 29 | textureFormat: -1 30 | maxTextureSize: 2048 31 | textureSettings: 32 | filterMode: -1 33 | aniso: -1 34 | mipBias: -1 35 | wrapMode: -1 36 | nPOTScale: 1 37 | lightmap: 0 38 | rGBM: 0 39 | compressionQuality: 50 40 | allowsAlphaSplitting: 0 41 | spriteMode: 0 42 | spriteExtrude: 1 43 | spriteMeshType: 1 44 | alignment: 0 45 | spritePivot: {x: 0.5, y: 0.5} 46 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 47 | spritePixelsToUnits: 100 48 | alphaIsTransparency: 0 49 | textureType: -1 50 | buildTargetSettings: [] 51 | spriteSheet: 52 | sprites: [] 53 | outline: [] 54 | spritePackingTag: 55 | userData: 56 | assetBundleName: 57 | assetBundleVariant: 58 | -------------------------------------------------------------------------------- /Editor.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f6f33c56b9eb16a4c90b90e45a221915 3 | folderAsset: yes 4 | timeCreated: 1462089647 5 | licenseType: Pro 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Editor/Cradle.Editor.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daterre/Cradle/981be1cca368a3c21c26d6760402206e373fb890/Editor/Cradle.Editor.dll -------------------------------------------------------------------------------- /Editor/Cradle.Editor.dll.mdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daterre/Cradle/981be1cca368a3c21c26d6760402206e373fb890/Editor/Cradle.Editor.dll.mdb -------------------------------------------------------------------------------- /Editor/Cradle.Editor.dll.mdb.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 879914ddbaadf8747bfa2ae3b5a51f63 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Editor/Cradle.Editor.dll.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6f7c916549b79c144920734d2bfb0d88 3 | timeCreated: 1470051901 4 | licenseType: Pro 5 | PluginImporter: 6 | serializedVersion: 1 7 | iconMap: {} 8 | executionOrder: {} 9 | isPreloaded: 0 10 | platformData: 11 | Any: 12 | enabled: 0 13 | settings: {} 14 | Editor: 15 | enabled: 1 16 | settings: 17 | DefaultValueInitialized: true 18 | WindowsStoreApps: 19 | enabled: 0 20 | settings: 21 | CPU: AnyCPU 22 | userData: 23 | assetBundleName: 24 | assetBundleVariant: 25 | -------------------------------------------------------------------------------- /Editor/Cradle.Editor.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daterre/Cradle/981be1cca368a3c21c26d6760402206e373fb890/Editor/Cradle.Editor.pdb -------------------------------------------------------------------------------- /Editor/Cradle.Editor.pdb.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a05464c21b335e045b64cbdc2dd554ef 3 | timeCreated: 1463336482 4 | licenseType: Pro 5 | DefaultImporter: 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Editor/Templates.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: caa9f1a0b6e8c3e4a9243860b5950f80 3 | folderAsset: yes 4 | timeCreated: 1462089647 5 | licenseType: Pro 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Editor/Templates/Story.template: -------------------------------------------------------------------------------- 1 | /* 2 | ------------------------------------------------ 3 | Generated by Cradle {{version}} 4 | https://github.com/daterre/Cradle 5 | 6 | Original file: {{originalFile}} 7 | Story format: {{storyFormatName}} 8 | ------------------------------------------------ 9 | */ 10 | 11 | using System.Collections; 12 | using System.Collections.Generic; 13 | using UnityEngine; 14 | using Cradle; 15 | using IStoryThread = System.Collections.Generic.IEnumerable; 16 | using {{storyFormatNamespace}}; 17 | 18 | public partial class @{{{storyName}}}: {{storyFormatClass}} 19 | { 20 | #region Variables 21 | // --------------- 22 | 23 | public class VarDefs: RuntimeVars 24 | { 25 | public VarDefs() 26 | { 27 | {{#vars}} 28 | VarDef("{{{.}}}", () => this.@{{{.}}}, val => this.@{{{.}}} = val); 29 | {{/vars}} 30 | } 31 | 32 | {{#vars}} 33 | public StoryVar @{{{.}}}; 34 | {{/vars}} 35 | } 36 | 37 | public new VarDefs Vars 38 | { 39 | get { return (VarDefs) base.Vars; } 40 | } 41 | 42 | // --------------- 43 | #endregion 44 | 45 | #region Initialization 46 | // --------------- 47 | 48 | {{#macroLibs}} 49 | public readonly {{Type}} {{Name}}; 50 | {{/macroLibs}} 51 | 52 | @{{storyName}}() 53 | { 54 | this.StartPassage = "{{{startPassage}}}"; 55 | 56 | base.Vars = new VarDefs() { Story = this, StrictMode = {{strictMode}} }; 57 | 58 | {{#macroLibs}} 59 | {{Name}} = new {{Type}}() { Story = this }; 60 | {{/macroLibs}} 61 | 62 | base.Init(); 63 | {{#passages}} 64 | passage{{Pid}}_Init(); 65 | {{/passages}} 66 | } 67 | 68 | // --------------- 69 | #endregion 70 | 71 | {{#passages}} 72 | // ............. 73 | // #{{Pid}}: {{{Name}}} 74 | 75 | void passage{{Pid}}_Init() 76 | { 77 | this.Passages[@"{{{Name}}}"] = new StoryPassage(@"{{{Name}}}", new string[]{ {{& Tags}} }, passage{{Pid}}_Main); 78 | } 79 | 80 | #line 1 "{{{DirectiveName}}}" 81 | IStoryThread passage{{Pid}}_Main() 82 | { 83 | {{#Code}} 84 | {{{& .}}} 85 | {{/Code}} 86 | } 87 | 88 | {{#Fragments}} 89 | #line 1 "{{{DirectiveName}}}#frag#{{FragId}}" 90 | IStoryThread passage{{Pid}}_Fragment_{{FragId}}() 91 | { 92 | {{#Code}} 93 | {{{& .}}} 94 | {{/Code}} 95 | } 96 | {{/Fragments}} 97 | 98 | {{/passages}} 99 | } -------------------------------------------------------------------------------- /Editor/Templates/Story.template.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6e4ce31b9ec856c41bb4cb8403c46dc8 3 | timeCreated: 1460917424 4 | licenseType: Pro 5 | DefaultImporter: 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Editor/ThirdParty.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: cea775b2d49acc743a41d75b22e93106 3 | folderAsset: yes 4 | timeCreated: 1462091484 5 | licenseType: Pro 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Editor/ThirdParty/Nustache.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f7a727d06423eb544ab115b073f50420 3 | folderAsset: yes 4 | timeCreated: 1457991700 5 | licenseType: Pro 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Editor/ThirdParty/Nustache/Nustache.Core.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daterre/Cradle/981be1cca368a3c21c26d6760402206e373fb890/Editor/ThirdParty/Nustache/Nustache.Core.dll -------------------------------------------------------------------------------- /Editor/ThirdParty/Nustache/Nustache.Core.dll.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a349f62d8a5c8c64ea46fd5c97fb46a1 3 | timeCreated: 1457970211 4 | licenseType: Pro 5 | PluginImporter: 6 | serializedVersion: 1 7 | iconMap: {} 8 | executionOrder: {} 9 | isPreloaded: 0 10 | platformData: 11 | Any: 12 | enabled: 0 13 | settings: {} 14 | Editor: 15 | enabled: 1 16 | settings: 17 | DefaultValueInitialized: true 18 | WindowsStoreApps: 19 | enabled: 0 20 | settings: 21 | CPU: AnyCPU 22 | userData: 23 | assetBundleName: 24 | assetBundleVariant: 25 | -------------------------------------------------------------------------------- /Editor/ThirdParty/Nustache/VERSION.md: -------------------------------------------------------------------------------- 1 | 1.15.3.5 -------------------------------------------------------------------------------- /Editor/ThirdParty/Nustache/VERSION.md.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d14983c10bf2bc0428b4b945396e79c6 3 | timeCreated: 1461314461 4 | licenseType: Pro 5 | DefaultImporter: 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Editor/ThirdParty/PhantomJS.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 412cf54ca6c8e9f43974c4ce9300f029 3 | folderAsset: yes 4 | timeCreated: 1457991715 5 | licenseType: Pro 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Editor/ThirdParty/PhantomJS/ChangeLog.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 680f0f134fdc1994b8f55f3b17945ef6 3 | timeCreated: 1457991746 4 | licenseType: Pro 5 | DefaultImporter: 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Editor/ThirdParty/PhantomJS/Install.cs: -------------------------------------------------------------------------------- 1 | #if UNITY_EDITOR_OSX 2 | // This class runs on editor startup and enforces executable permissions for the phantomjs binary on mac 3 | 4 | using UnityEngine; 5 | using UnityEditor; 6 | using System.Diagnostics; 7 | using Cradle.Editor.Utils; 8 | 9 | [InitializeOnLoad] 10 | public static class Install_PhantomJS { 11 | static Install_PhantomJS() 12 | { 13 | Process chmod = new Process(); 14 | chmod.StartInfo.UseShellExecute = false; 15 | chmod.StartInfo.WorkingDirectory = EditorFileUtil.FindFile("phantomjs", true); 16 | chmod.StartInfo.FileName = "chmod"; 17 | chmod.StartInfo.Arguments = "+x phantomjs"; 18 | chmod.StartInfo.RedirectStandardOutput = true; 19 | chmod.Start(); 20 | chmod.WaitForExit(); 21 | } 22 | } 23 | 24 | #endif -------------------------------------------------------------------------------- /Editor/ThirdParty/PhantomJS/Install.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 611cc4ec43ebf47b0ac1d3436e8c476b 3 | timeCreated: 1470054414 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Editor/ThirdParty/PhantomJS/LICENSE.BSD: -------------------------------------------------------------------------------- 1 | Redistribution and use in source and binary forms, with or without 2 | modification, are permitted provided that the following conditions are met: 3 | 4 | * Redistributions of source code must retain the above copyright 5 | notice, this list of conditions and the following disclaimer. 6 | * Redistributions in binary form must reproduce the above copyright 7 | notice, this list of conditions and the following disclaimer in the 8 | documentation and/or other materials provided with the distribution. 9 | * Neither the name of the nor the 10 | names of its contributors may be used to endorse or promote products 11 | derived from this software without specific prior written permission. 12 | 13 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 14 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16 | ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 17 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 18 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 19 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 20 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 21 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 22 | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 | -------------------------------------------------------------------------------- /Editor/ThirdParty/PhantomJS/LICENSE.BSD.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9482be9985684c04294debced907be5a 3 | timeCreated: 1457991746 4 | licenseType: Pro 5 | DefaultImporter: 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Editor/ThirdParty/PhantomJS/README.md: -------------------------------------------------------------------------------- 1 | # [PhantomJS](http://phantomjs.org) - Scriptable Headless WebKit 2 | 3 | PhantomJS ([phantomjs.org](http://phantomjs.org)) is a headless WebKit scriptable with JavaScript. The latest [stable release](http://phantomjs.org/release-2.0.html) is version 2.0. 4 | 5 | **Note**: Please **do not** create a GitHub pull request **without** reading the [Contribution Guide](https://github.com/ariya/phantomjs/blob/master/CONTRIBUTING.md) first. Failure to do so may result in the rejection of the pull request. 6 | 7 | ## Use Cases 8 | 9 | - **Headless web testing**. Lightning-fast testing without the browser is now possible! 10 | - **Page automation**. [Access and manipulate](http://phantomjs.org/page-automation.html) web pages with the standard DOM API, or with usual libraries like jQuery. 11 | - **Screen capture**. Programmatically [capture web contents](http://phantomjs.org/screen-capture.html), including CSS, SVG and Canvas. Build server-side web graphics apps, from a screenshot service to a vector chart rasterizer. 12 | - **Network monitoring**. Automate performance analysis, track [page loading](http://phantomjs.org/network-monitoring.html) and export as standard HAR format. 13 | 14 | ## Features 15 | 16 | - **Multiplatform**, available on major operating systems: Windows, Mac OS X, Linux, and other Unices. 17 | - **Fast and native implementation** of web standards: DOM, CSS, JavaScript, Canvas, and SVG. No emulation! 18 | - **Pure headless (no X11) on Linux**, ideal for continuous integration systems. Also runs on Amazon EC2, Heroku, and Iron.io. 19 | - **Easy to install**: [Download](http://phantomjs.org/download.html), unpack, and start having fun in just 5 minutes. 20 | 21 | ## Questions? 22 | 23 | - Explore the complete [documentation](http://phantomjs.org/documentation/). 24 | - Read tons of [user articles](http://phantomjs.org/buzz.html) on using PhantomJS. 25 | - Join the [mailing-list](http://groups.google.com/group/phantomjs) and discuss with other PhantomJS fans. 26 | 27 | PhantomJS is free software/open source, and is distributed under the [BSD license](http://opensource.org/licenses/BSD-3-Clause). It contains third-party code, see the included `third-party.txt` file for the license information on third-party code. 28 | 29 | PhantomJS is created and maintained by [Ariya Hidayat](http://ariya.ofilabs.com/about) (Twitter: [@ariyahidayat](http://twitter.com/ariyahidayat)), with the help of [many contributors](https://github.com/ariya/phantomjs/contributors). Follow the official Twitter stream [@PhantomJS](http://twitter.com/PhantomJS) to get the frequent development updates. 30 | -------------------------------------------------------------------------------- /Editor/ThirdParty/PhantomJS/README.md.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2fcb543b90af7ce44975d68a724c2f04 3 | timeCreated: 1457991746 4 | licenseType: Pro 5 | DefaultImporter: 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Editor/ThirdParty/PhantomJS/VERSION.md: -------------------------------------------------------------------------------- 1 | 2.1.1 -------------------------------------------------------------------------------- /Editor/ThirdParty/PhantomJS/VERSION.md.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: dfd0e13c077e7e142b824980e30b5981 3 | timeCreated: 1461314461 4 | licenseType: Pro 5 | DefaultImporter: 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Editor/ThirdParty/PhantomJS/bin.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 624898032d92b7f4980cf79f17d8708b 3 | folderAsset: yes 4 | timeCreated: 1457991746 5 | licenseType: Pro 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Editor/ThirdParty/PhantomJS/bin/osx.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7d63f01410fff4749846461b884aebd1 3 | folderAsset: yes 4 | timeCreated: 1458748774 5 | licenseType: Pro 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Editor/ThirdParty/PhantomJS/bin/osx/phantomjs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daterre/Cradle/981be1cca368a3c21c26d6760402206e373fb890/Editor/ThirdParty/PhantomJS/bin/osx/phantomjs -------------------------------------------------------------------------------- /Editor/ThirdParty/PhantomJS/bin/osx/phantomjs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 493dd247e04b44206bb99eb925950f94 3 | timeCreated: 1458748755 4 | licenseType: Pro 5 | DefaultImporter: 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Editor/ThirdParty/PhantomJS/bin/win.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a37f47456cc334c63b4c45466a187ef6 3 | folderAsset: yes 4 | timeCreated: 1458748767 5 | licenseType: Pro 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Editor/ThirdParty/PhantomJS/bin/win/phantomjs.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daterre/Cradle/981be1cca368a3c21c26d6760402206e373fb890/Editor/ThirdParty/PhantomJS/bin/win/phantomjs.exe -------------------------------------------------------------------------------- /Editor/ThirdParty/PhantomJS/bin/win/phantomjs.exe.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: eba0156ee60f3ab4aa2cd948a8a530e4 3 | timeCreated: 1457991750 4 | licenseType: Pro 5 | DefaultImporter: 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Editor/ThirdParty/PhantomJS/third-party.txt: -------------------------------------------------------------------------------- 1 | This document contains the list of Third Party Software included with 2 | PhantomJS, along with the license information. 3 | 4 | Third Party Software may impose additional restrictions and it is the 5 | user's responsibility to ensure that they have met the licensing 6 | requirements of PhantomJS and the relevant license of the Third Party 7 | Software they are using. 8 | 9 | Qt - http://qt-project.org/ 10 | License: GNU Lesser General Public License (LGPL) version 2.1. 11 | Reference: http://qt-project.org/doc/qt-4.8/lgpl.html. 12 | 13 | WebKit - http://www.webkit.org/ 14 | License: GNU Lesser General Public License (LGPL) version 2.1 and BSD. 15 | Reference: http://www.webkit.org/coding/lgpl-license.html and 16 | http://www.webkit.org/coding/bsd-license.html. 17 | 18 | Mongoose - https://github.com/cesanta/mongoose 19 | License: MIT 20 | Reference: https://github.com/cesanta/mongoose/commit/abbf27338ef554cce0281ac157aa71a9c1b82a55 21 | 22 | OpenSSL - http://www.openssl.org/ 23 | License: OpenSSL License, SSLeay License. 24 | Reference: http://www.openssl.org/source/license.html. 25 | 26 | Linenoise - https://github.com/tadmarshall/linenoise 27 | License: BSD. 28 | Reference: https://github.com/tadmarshall/linenoise/blob/master/linenoise.h. 29 | 30 | QCommandLine - http://xf.iksaif.net/dev/qcommandline.html 31 | License: GNU Lesser General Public License (LGPL) version 2.1. 32 | Reference: http://dev.iksaif.net/projects/qcommandline/repository/revisions/master/entry/COPYING 33 | 34 | wkhtmlpdf - http://code.google.com/p/wkhtmltopdf/ 35 | License: GNU Lesser General Public License (LGPL) 36 | Reference: http://code.google.com/p/wkhtmltopdf/ 37 | -------------------------------------------------------------------------------- /Editor/ThirdParty/PhantomJS/third-party.txt.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 79dcf7c8053265d4eb8665b7b4af4861 3 | timeCreated: 1457991751 4 | licenseType: Pro 5 | TextScriptImporter: 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Editor/js.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b0917858c1b715741981fc8275ae1b31 3 | folderAsset: yes 4 | timeCreated: 1473661083 5 | licenseType: Pro 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Editor/js/StoryFormats.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 47692398a9d38ff46ba28a66db1980ce 3 | folderAsset: yes 4 | timeCreated: 1473661084 5 | licenseType: Pro 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Editor/js/StoryFormats/Harlowe.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e83af11af2da4d947b22f702c58639f9 3 | folderAsset: yes 4 | timeCreated: 1473661084 5 | licenseType: Pro 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Editor/js/StoryFormats/Harlowe/harlowe.bridge.js_: -------------------------------------------------------------------------------- 1 | (function() { 2 | 'use strict'; 3 | 4 | var phantomExit = function(result) { 5 | if (window.callPhantom) 6 | window.callPhantom(result); 7 | else 8 | console.error('UnityTwine: PhantomJS context not available.'); 9 | }; 10 | 11 | var $storydata = $('tw-storydata'); 12 | if (!$storydata.length) 13 | { 14 | console.error("The file is not a valid Twine 2 story."); 15 | phantomExit(); 16 | return; 17 | } 18 | if ($storydata.attr("format") != "Harlowe") 19 | { 20 | console.error("The story was not created with the Harlowe story format."); 21 | phantomExit(); 22 | return; 23 | } 24 | 25 | var htmlDecoder = document.createElement('textarea'); 26 | function htmlDecode(text) 27 | { 28 | htmlDecoder.innerHTML = text; 29 | return htmlDecoder.value 30 | .replace(/\\n/g, "\n") 31 | .replace(/\\t/g, "\t"); 32 | } 33 | 34 | window.unityTwineHarloweBridge = function($, require) { 35 | 36 | require(['markup', 'utils'], function(TwineMarkup, utils){ 37 | "use strict"; 38 | 39 | function simplify(tokens) { 40 | var result = []; 41 | for (var i = 0; i < tokens.length; i++) { 42 | var complex = tokens[i]; 43 | var simple = {}; 44 | 45 | // // special cases 46 | // switch(complex.type) { 47 | // case "twineLink": { 48 | // // Desugar links 49 | // complex = TwineMarkup.lex("(link-goto:" 50 | // + utils.toJSLiteral(complex.innerText) + "," 51 | // + utils.toJSLiteral(complex.passage) + ")" 52 | // ).children[0]; 53 | // break; 54 | // } 55 | // } 56 | 57 | simple.type = complex.type; 58 | 59 | if (complex.children && complex.children.length && complex.type !== 'string' && complex.type !== 'verbatim') 60 | simple.tokens = simplify(complex.children); 61 | if (complex.text) 62 | simple.text = htmlDecode(complex.text); 63 | if (complex.innerText) 64 | simple.innerText = htmlDecode(complex.innerText); 65 | if (complex.value) 66 | simple.value = complex.value; 67 | if (complex.align) 68 | simple.align = complex.align; 69 | if (complex.depth) 70 | simple.depth = complex.depth; 71 | if (complex.passage) 72 | simple.passage = complex.passage; 73 | if (complex.name) 74 | simple.name = complex.type === "macro" ? 75 | utils.insensitiveName(complex.name) : 76 | complex.name; 77 | 78 | result.push(simple); 79 | } 80 | return result; 81 | } 82 | 83 | var result = { 84 | startPid: $('tw-storydata').attr('startnode'), 85 | passages:[] 86 | }; 87 | 88 | $('tw-passagedata').each(function(i,p){ 89 | var $p = $(p); 90 | var passage = { 91 | Pid: $p.attr('pid'), 92 | Name: htmlDecode($p.attr('name')), 93 | Tags: htmlDecode($p.attr('tags')), 94 | Tokens: simplify(TwineMarkup.lex(htmlDecode($p.html())).children) 95 | }; 96 | result.passages.push(passage); 97 | }); 98 | 99 | phantomExit(result); 100 | }); 101 | }; 102 | 103 | var req = $('