Beispiel #1
0
        /// <summary>
        /// Creates a list of TDefinitions, loading defintitions found in Categories and Includes.
        /// </summary>
        /// <typeparam name="TDefinition"></typeparam>
        /// <param name="sourceDefinitions"></param>
        /// <returns></returns>
        public static List <TDefinition> Flatten <TDefinition>(List <DefinitionBase> sourceDefinitions) where TDefinition : DefinitionBase
        {
            var result = new List <TDefinition>(sourceDefinitions.Count);

            foreach (var baseDef in sourceDefinitions)
            {
                var def = baseDef as TDefinition;

                if (def != null)
                {
                    result.Add(def);
                }
                else if (baseDef is CategoryDefinition)
                {
                    var category = (CategoryDefinition)baseDef;

                    foreach (var kvp in category.DefinitionIncludes)
                    {
                        result.AddRange(DefinitionInclude.Flatten <TDefinition>(kvp.Value));
                    }
                }
            }

            return(result);
        }
        /// <summary>
        /// Loads in json definition files, and attempts to compile and link to any related scripts.
        /// </summary>
        protected virtual void LoadDefinitions()
        {
            //CustomNpcsPlugin.Instance.LogPrint("Using new definition loading, include paths aren't 100% reliable yet!",TraceLevel.Warning);

            var include = DefinitionInclude.Load <TCustomType>(ConfigPath);

            Definitions = DefinitionInclude.Flatten <TCustomType>(include);

            var rootResult = new ValidationResult(ConfigPath);

            rootResult.Source = ConfigPath;

            foreach (var def in Definitions)
            {
                var name   = "";
                var result = def.Validate();

                if (!string.IsNullOrWhiteSpace(def.Name))
                {
                    name = $" - '{def.Name}'";
                }

                //result.Source = $"{def.FilePath}[{def.LineNumber},{def.LinePosition}]{name}";

                //CustomNpcsPlugin.Instance.LogPrint(result);
                rootResult.Children.Add(result);
            }

            CustomNpcsPlugin.Instance.LogPrint(rootResult);

            //Definitions = DefinitionLoader.LoadFromFile<TCustomType>(ConfigPath);

            CustomNpcsPlugin.Instance.LogPrint("Compiling scripts...", TraceLevel.Info);

            //get script files paths
            var booScripts = Definitions.Where(d => !string.IsNullOrWhiteSpace(d.ScriptPath))
                             .Select(d => Path.Combine(BasePath, d.ScriptPath))
                             .ToList();

            var newModuleManager = new BooModuleManager(CustomNpcsPlugin.Instance,
                                                        ScriptHelpers.GetReferences(),
                                                        ScriptHelpers.GetDefaultImports(),
                                                        GetEnsuredMethodSignatures());

            newModuleManager.AssemblyNamePrefix = AssemblyNamePrefix;

            foreach (var f in booScripts)
            {
                newModuleManager.Add(f);
            }

            Dictionary <string, CompilerContext> results = null;

            if (ModuleManager != null)
            {
                results = newModuleManager.IncrementalCompile(ModuleManager);
            }
            else
            {
                results = newModuleManager.Compile();
            }

            ModuleManager = newModuleManager;

            var scriptedDefinitions = Definitions.Where(d => !string.IsNullOrWhiteSpace(d.ScriptPath));

            foreach (var def in scriptedDefinitions)
            {
                var fileName = Path.Combine(BasePath, def.ScriptPath);

                //if newly compile assembly, examine the context, and try to link to the new assembly
                if (results.TryGetValue(fileName, out var context))
                {
                    var scriptAssembly = context.GeneratedAssembly;

                    if (scriptAssembly != null)
                    {
                        var result = def.LinkToScriptAssembly(scriptAssembly);

                        //if(!result)
                        //	//	CustomNpcsPlugin.Instance.LogPrint($"Failed to link {kvp.Key}.", TraceLevel.Info);
                    }
                }
                else
                {
                    var scriptAssembly = ModuleManager[fileName];

                    if (scriptAssembly != null)
                    {
                        var result = def.LinkToScriptAssembly(scriptAssembly);

                        //if(!result)
                        //	//	CustomNpcsPlugin.Instance.LogPrint($"Failed to link {kvp.Key}.", TraceLevel.Info);
                    }
                }
            }

            definitionMap = new Dictionary <string, TCustomType>();

            foreach (var def in Definitions)
            {
                definitionMap.Add(def.Name.ToLowerInvariant(), def);
            }
        }
Beispiel #3
0
        public static DefinitionInclude Load <TDefinition>(string filePath) where TDefinition : DefinitionBase
        {
            if (!File.Exists(filePath))
            {
                throw new FileNotFoundException($"Unable to find file '{filePath}'.", filePath);
            }

            var result = new DefinitionInclude();

            result.FilePath = filePath;
            var definitionType = typeof(TDefinition);
            var typeName       = definitionType.Name;

            var json     = File.ReadAllText(filePath);
            var array    = JArray.Parse(json);
            var children = array.Children().Where(jt => jt.Type == JTokenType.Object);

            DefinitionBase baseDef = null;

            foreach (var child in children)
            {
                if (child["Category"] != null)
                {
                    var category = child.ToObject <CategoryDefinition>();
                    //do category specific things...
                    baseDef = category;
                }
                else
                {
                    var def = child.ToObject <TDefinition>();
                    //do TDefinition specific things...
                    baseDef = def;
                }

                //set file and line info
                var filePos  = baseDef.FilePosition = new FilePosition(filePath);
                var lineInfo = child as IJsonLineInfo;

                if (lineInfo?.HasLineInfo() == true)
                {
                    filePos.Line   = lineInfo.LineNumber;
                    filePos.Column = lineInfo.LinePosition;

                    //Debug.Print($"{filePath} [{baseDef.LineNumber},{baseDef.LinePosition}] {baseDef.Name}");
                    Debug.Print($"{filePos} {baseDef.Name}");
                }

                result.Add(baseDef);
            }

            //load includes
            //Debug.Print("Categories are currently disabled.");
            var categories = result.OfType <CategoryDefinition>();

            foreach (var category in categories)
            {
                foreach (var inc in category.Includes)
                {
                    var relativeIncludePath = Path.Combine(Path.GetDirectoryName(filePath), inc);
                    var defInclude          = DefinitionInclude.Load <TDefinition>(relativeIncludePath);
                    category.DefinitionIncludes.Add(inc, defInclude);
                }
            }

            return(result);
        }