private void LoadAsset(ScriptableObject asset)
        {
            var settings = ProjectUtility.GetProjectSettings <ActionGraphGlobalSettings>();

            if (settings != null)
            {
                var graphView = rootVisualElement.Q <ActionGraphView>("graphView");
                if (asset is ActionAsset actionAsset)
                {
                    if (ActionDefinitionAsset.Load(actionAsset.actionId, out var definitionAsset))
                    {
                        graphView.LoadModule(new ActionModule(actionAsset, definitionAsset, definitionAsset.Name));
                        EditorPrefs.SetString(PrefKey, JsonConvert.SerializeObject(graphView.model.context));
                    }
                    else
                    {
                        Debug.LogError($"Unknown Action Type with guid '{actionAsset.actionId}' in {actionAsset.name}");
                    }
                }
                else
                {
                    var actionModules = new List <ActionModule>();

                    foreach (var fieldInfo in asset.GetType().GetSerializableFields(fieldInfo => typeof(ActionAsset).IsAssignableFrom(fieldInfo.FieldType)))
                    {
                        var attr = fieldInfo.GetCustomAttribute <ActionTypeAttribute>();
                        if (attr != null && ActionDefinitionAsset.Load(attr.type, out var definitionAsset))
                        {
                            actionModules.Add(new ActionModule((ActionAsset)fieldInfo.GetValue(asset) ?? settings.CreateTemporaryActionAsset(definitionAsset.id), definitionAsset, $"{fieldInfo.Name} [{definitionAsset.Name}]"));
                        }
                    }
                    if (actionModules.Count > 0)
                    {
                        graphView.LoadModules(actionModules, asset);
                        EditorPrefs.SetString(PrefKey, JsonConvert.SerializeObject(graphView.model.context));
                    }
                    else
                    {
                        Debug.LogError("No Action Assets found!");
                    }
                }
            }
        }
        public static void CreateAssembly()
        {
            var settings = ProjectUtility.GetOrCreateProjectSettings <ActionGraphGlobalSettings>();
            var output   = settings.actionSystemsDLLDirectory + "/" + AssemblyName + ".dll";

            if (!Directory.Exists(settings.actionSystemsDLLDirectory))
            {
                Directory.CreateDirectory(settings.actionSystemsDLLDirectory);
            }
            var definitions = ActionDefinitionAsset.LoadAll().ToArray();

            using var resolver = new DefaultAssemblyResolver();
            resolver.AddSearchDirectory("Library/ScriptAssemblies");
            using (var assembly = AssemblyDefinition.CreateAssembly(new AssemblyNameDefinition(AssemblyName, new Version(1, 0, 0, 0)), AssemblyName, new ModuleParameters {
                Kind = ModuleKind.Dll, AssemblyResolver = resolver, Runtime = TargetRuntime.Net_4_0,
            })) {
                var actionAssetMenusType = new TypeDefinition("NeroWeNeed.ActionGraph.Generated", ActionAssetMenuTypeName, TypeAttributes.NotPublic | TypeAttributes.Abstract | TypeAttributes.Sealed, assembly.MainModule.TypeSystem.Object);
                GenerateMenus(assembly, assembly.MainModule, actionAssetMenusType, definitions);
                assembly.MainModule.Types.Add(actionAssetMenusType);
                assembly.Write(output);
            }
            AssetDatabase.ImportAsset(output);
        }
 public IEnumerable <Action> this[ActionDefinitionAsset asset]
 {
     get => data[asset.delegateType].Values;
        private static void GenerateMenu(AssemblyDefinition assemblyDefinition, ModuleDefinition moduleDefinition, TypeDefinition typeDefinition, ActionDefinitionAsset definitionAsset, MethodReference attrConstructor, MethodReference createAssetMethod)
        {
            var method = new MethodDefinition($"CreateActionAsset_{definitionAsset.id.guid}", MethodAttributes.Private | MethodAttributes.Static, moduleDefinition.TypeSystem.Void);
            var attr   = new CustomAttribute(attrConstructor);

            attr.ConstructorArguments.Add(new CustomAttributeArgument(moduleDefinition.TypeSystem.String, $"Assets/Create/Actions/{definitionAsset.Name}"));
            method.CustomAttributes.Add(attr);
            method.Body.InitLocals = true;
            method.Body.SimplifyMacros();
            var processor = method.Body.GetILProcessor();

            processor.Emit(OpCodes.Ldstr, definitionAsset.id.guid);
            processor.Emit(OpCodes.Call, createAssetMethod);
            processor.Emit(OpCodes.Ret);
            method.Body.OptimizeMacros();
            typeDefinition.Methods.Add(method);
        }