public void Promote(TaskImplementation implementation)
 {
     label = implementation.memberInfo.Name;
     parameters.Clear();
     foreach (var p in implementation.parameterTypes)
     {
         Parameters_Add(new GUINodeParameter(p));
     }
     DefineType();
 }
        public static TaskImplementation[] Get(object[] implementers)
        {
            var tasks = new List <TaskImplementation>();

            foreach (var implementer in implementers)
            {
                Task[] typeTasks = null;

                var type = implementer.GetType();

                if (taskCache.ContainsKey(type))
                {
                    typeTasks = taskCache[type];
                }
                else
                {
                    var typeTaskList = new List <Task>();
                    var members      = implementer.GetType().GetMembers(bindingFlags);
                    foreach (var m in members)
                    {
                        var attributes = m.GetCustomAttributes(typeof(Task), true);
                        foreach (var attr in attributes)
                        {
                            var implementationAttribute = attr as Task;
                            if (implementationAttribute != null)
                            {
                                implementationAttribute._memberInfo = m;
                                typeTaskList.Add(implementationAttribute);
                            }
                        }
                    }

                    typeTasks       = typeTaskList.ToArray();
                    taskCache[type] = typeTasks;
                }

                if (typeTasks != null)
                {
                    foreach (var t in typeTasks)
                    {
                        var ti = new TaskImplementation();
                        ti.target     = implementer;
                        ti.memberInfo = t._memberInfo;
                        tasks.Add(ti);
                    }
                }
            }

            return(tasks.ToArray());
        }
        static bool Bind(BTTask task, TaskImplementation implementation)
        {
            bool bindingSucceeded = false;

            var member          = implementation.memberInfo;
            var taskImplementer = implementation.target;

            MethodInfo   method   = member as MethodInfo;
            FieldInfo    field    = member as FieldInfo;
            PropertyInfo property = member as PropertyInfo;

            System.Action taskAction = null;
            if (method != null)
            {
                object[] parameters       = new object[task.i_parameters.Length];
                var      methodParameters = method.GetParameters();
                for (int i = 0; i < parameters.Length; i++)
                {
                    var enumParameter = task.i_parameters[i] as EnumParameter;
                    if (enumParameter != null)
                    {
                        parameters[i] = enumParameter.Parse(methodParameters[i].ParameterType);
                    }
                    else
                    {
                        parameters[i] = task.i_parameters[i];
                    }
                }

                if (method.ReturnType == typeof(void))
                {
                    if (parameters.Length > 0)
                    {
                        taskAction = () => method.Invoke(taskImplementer, parameters);
                    }
                    else
                    {
                        taskAction = System.Delegate.CreateDelegate(typeof(System.Action), taskImplementer, method) as System.Action;
                    }
                }

                if (method.ReturnType == typeof(bool))
                {
                    if (parameters.Length > 0)
                    {
                        taskAction = () => Task.current.Complete((bool)method.Invoke(taskImplementer, parameters));
                    }
                    else
                    {
                        var del = System.Delegate.CreateDelegate(typeof(System.Func <bool>), taskImplementer, method) as System.Func <bool>;
                        taskAction = () => Task.current.Complete(del());
                    }
                }
            }

            if (field != null)
            {
                taskAction = () => Task.current.Complete((bool)field.GetValue(taskImplementer));
            }

            if (property != null)
            {
                taskAction = () => Task.current.Complete((bool)property.GetValue(taskImplementer, null));
            }

            if (taskAction != null)
            {
                task.m_boundObject = taskImplementer;
                task.m_boundMember = member;
                task.m_taskAction  = taskAction;
                task.m_boundState  = BoundState.Bound;

                bindingSucceeded = true;
            }

            return(bindingSucceeded);
        }
        public static void Bind(BTProgram program, object[] implementers)
        {
            // Get all the [Task]s.
            var taskImplementations = TaskImplementation.Get(implementers);

            // Find for each task the corresponding implementations.
            var taskImplementationCandidates = new Dictionary <BTTask, List <TaskImplementation> >();
            var tasks = program.tasks;

            foreach (var task in tasks)
            {
                taskImplementationCandidates[task] = new List <TaskImplementation>();
                foreach (var ti in taskImplementations)
                {
                    if (ti.IsMatch(task))
                    {
                        taskImplementationCandidates[task].Add(ti);
                    }
                }
            }

            // Check whether all the task are unambiguously defined.
            var unimplementedTasks    = new List <BTTask>();
            var over_implementedTasks = new List <BTTask>();

            foreach (var kv  in taskImplementationCandidates)
            {
                var task       = kv.Key;
                var candidates = kv.Value;

                if (candidates.Count == 0)
                {
                    unimplementedTasks.Add(task);
                }

                if (candidates.Count > 1)
                {
                    over_implementedTasks.Add(task);
                }
            }

            // Generate eventual exceptions.

            var exceptions = new List <System.Exception>();

            if (unimplementedTasks.Count > 0)
            {
                int    line = 0;
                string path = null;
                foreach (var task in unimplementedTasks)
                {
                    var    m   = GetMethodSignatureString(task);
                    string msg = string.Format("The task `{0}' is not defined.\n", m);
                    msg += string.Format("\nA method as follow is expected:\n");

                    string tpl = taskTpl;
                    tpl  = tpl.Replace("{!methodSignature}", m);
                    tpl  = tpl.Replace("{!statusType}", "Status");
                    msg += tpl;

                    if (Locate(BehaviourTree._current, task, out path, out line))
                    {
                        exceptions.Add(new PandaScriptException(msg, path, line));
                    }
                    else
                    {
                        exceptions.Add(new System.NotImplementedException(msg));
                    }
                }
            }


            if (over_implementedTasks.Count > 0)
            {
                int    line = 0;
                string path = null;
                foreach (var task in over_implementedTasks)
                {
                    var    m   = GetMethodSignatureString(task);
                    string msg = string.Format("The task `{0}' has too many definitions.\n", m);
                    msg += string.Format("The task is implemented in:\n");

                    foreach (var o in taskImplementationCandidates[task])
                    {
                        msg += string.Format(" - `{0}'\n", o.target.GetType().ToString());
                    }

                    if (Locate(BehaviourTree._current, task, out path, out line))
                    {
                        exceptions.Add(new PandaScriptException(msg, path, line));
                    }
                    else
                    {
                        exceptions.Add(new System.Exception(msg));
                    }
                }
            }

            if (exceptions.Count == 0)
            {
                exceptions.AddRange(CheckRootTree(program));
            }

            program._exceptions = exceptions.ToArray();

            // Bind the tasks.
            foreach (var kv in taskImplementationCandidates)
            {
                var task       = kv.Key;
                var candidates = kv.Value;

                if (candidates.Count == 1)
                {
                    var ti = candidates[0];
                    Bind(task, ti);
                }
                else
                {
                    task.Unbind();
                }
            }
        }
 public GUINode(TaskImplementation implementation)
 {
     Promote(implementation);
 }