예제 #1
0
        public override void RegisterPort()
        {
            register.onExecute = () => {
                if (target.isAssigned)
                {
                    object val = target.Get();
                    if (val == null)
                    {
                        val = new MemberData.Event(target.CreateRuntimeEvent(), null);
                    }
                    if (val is MemberData.Event)
                    {
                        MemberData.Event e = val as MemberData.Event;
                        if (e.eventInfo != null)
                        {
                            if (m_Delegate == null)
                            {
                                if (e.eventInfo is RuntimeEvent)
                                {
                                    var returnType = target.type.GetMethod("Invoke").ReturnType;
                                    m_Delegate = new MemberData.EventCallback((obj => {
                                        if (owner == null)
                                        {
                                            return(null);
                                        }
                                        if (obj != null && parameters.Count == obj.Length)
                                        {
                                            for (int i = 0; i < obj.Length; i++)
                                            {
                                                parameters[i] = obj[i];
                                            }
                                        }
                                        if (returnType == typeof(void))
                                        {
                                            body.InvokeFlow();
                                            return(null);
                                        }
                                        else
                                        {
                                            Node n;
                                            WaitUntil w;
                                            if (!body.ActivateFlowNode(out n, out w))
                                            {
                                                throw new uNodeException("Coroutine aren't supported by EventHook node in runtime.", this);
                                            }
                                            if (n == null)
                                            {
                                                throw new uNodeException("No return value", this);
                                            }
                                            JumpStatement js = n.GetJumpState();
                                            if (js == null || js.jumpType != JumpStatementType.Return || !(js.from is NodeReturn))
                                            {
                                                throw new uNodeException("No return value", this);
                                            }
                                            return((js.from as NodeReturn).GetReturnValue());
                                        }
                                    }));
                                }
                                else
                                {
                                    var method = e.eventInfo.EventHandlerType.GetMethod("Invoke");
                                    var type   = method.ReturnType;
                                    if (type == typeof(void))
                                    {
                                        m_Delegate = CustomDelegate.CreateActionDelegate((obj) => {
                                            if (owner == null)
                                            {
                                                return;
                                            }
                                            if (obj != null && parameters.Count == obj.Length)
                                            {
                                                for (int i = 0; i < obj.Length; i++)
                                                {
                                                    parameters[i] = obj[i];
                                                }
                                            }
                                            body.InvokeFlow();
                                        }, method.GetParameters().Select(i => i.ParameterType).ToArray());
                                    }
                                    else
                                    {
                                        var types = method.GetParameters().Select(i => i.ParameterType).ToList();
                                        types.Add(type);
                                        m_Delegate = CustomDelegate.CreateFuncDelegate((obj) => {
                                            if (owner == null)
                                            {
                                                return(null);
                                            }
                                            if (obj != null && parameters.Count == obj.Length)
                                            {
                                                for (int i = 0; i < obj.Length; i++)
                                                {
                                                    parameters[i] = obj[i];
                                                }
                                            }
                                            Node n;
                                            WaitUntil w;
                                            if (!body.ActivateFlowNode(out n, out w))
                                            {
                                                throw new uNodeException("Coroutine aren't supported by EventHook node in runtime.", this);
                                            }
                                            if (n == null)
                                            {
                                                throw new uNodeException("No return value", this);
                                            }
                                            JumpStatement js = n.GetJumpState();
                                            if (js == null || js.jumpType != JumpStatementType.Return || !(js.from is NodeReturn))
                                            {
                                                throw new uNodeException("No return value", this);
                                            }
                                            return((js.from as NodeReturn).GetReturnValue());
                                        }, types.ToArray());
                                    }
                                    m_Delegate = ReflectionUtils.ConvertDelegate(m_Delegate, e.eventInfo.EventHandlerType);
                                }
                            }
                            e.eventInfo.AddEventHandler(e.instance, m_Delegate);
                        }
                    }
                    else if (val is UnityEventBase)
                    {
                        var method = val.GetType().GetMethod("AddListener");
                        if (m_Delegate == null)
                        {
                            var param = method.GetParameters()[0].ParameterType;
                            var gType = param.GetGenericArguments();
                            m_Delegate = CustomDelegate.CreateActionDelegate((obj) => {
                                if (owner == null)
                                {
                                    return;
                                }
                                if (obj != null && parameters.Count == obj.Length)
                                {
                                    for (int i = 0; i < obj.Length; i++)
                                    {
                                        parameters[i] = obj[i];
                                    }
                                }
                                body.InvokeFlow();
                            }, gType);
                            m_Delegate = System.Delegate.CreateDelegate(param, m_Delegate.Target, m_Delegate.Method);
                        }
                        method.InvokeOptimized(val, new object[] { m_Delegate });
                    }
                    else
                    {
                        if (val == null)
                        {
                            throw new uNodeException("The target event is null", this);
                        }
                        throw new uNodeException("Invalid target value: " + val, this);
                    }
                }
            };
            unregister.onExecute = () => {
                if (m_Delegate != null && target.isAssigned)
                {
                    object val = target.Get();
                    if (val is MemberData.Event)
                    {
                        MemberData.Event e = val as MemberData.Event;
                        if (e.eventInfo != null)
                        {
                            e.eventInfo.RemoveEventHandler(e.instance, m_Delegate);
                        }
                    }
                    else if (val is UnityEventBase)
                    {
                        var method = val.GetType().GetMethod("RemoveListener");
                        method.InvokeOptimized(val, new object[] { m_Delegate });
                    }
                }
            };

            if (CodeGenerator.isGenerating)
            {
                CodeGenerator.RegisterFlowNode(this);
                register.codeGeneration = () => {
                    if (target.type.IsCastableTo(typeof(UnityEventBase)))
                    {
                        return(target.ParseValue().AddFunction("AddListener", GenerateEventCodes()).AddSemicolon());
                    }
                    return(CodeGenerator.GenerateSetCode(target, GenerateEventCodes(), SetType.Add, target.type));
                };
                unregister.codeGeneration = () => {
                    if (target.type.IsCastableTo(typeof(UnityEventBase)))
                    {
                        return(target.ParseValue().AddFunction("RemoveListener", GenerateEventCodes()).AddSemicolon());
                    }
                    return(CodeGenerator.GenerateSetCode(target, GenerateEventCodes(), SetType.Subtract, target.type));
                };
            }
        }