Example #1
0
        /// <summary>
        /// Подписывает элемент графического интерфейса на получение событий, которые для него доступны.
        ///
        /// Например, у стандартного грфического элемента Toggle есть событие onValueChanged, которое принимает делегат UnityAction&lt;bool&gt;
        /// Пусть у источника данных есть свойство MyToggle, которое связано с соответствующим GuiToggleBind. Тогда подписка на событие может выглядеть так:
        /// AddEventListener("MyToggle", "onValueChanged", (proxydata, args) => Debug.Log("MyToggle changed: " + (bool)args[0]));
        /// </summary>
        public GuiEventData AddEventListener(string bindName, string eventName, UniversalGuiEventDelegate callback)
        {
            GuiEventData guiEventData = null;

            IGuiBindable bindableData = _bindableGuiComponents.SingleOrDefault(data => data.GetBindName() == bindName);

            if (bindableData != null)
            {
                object unityEvent =
                    bindableData.GetGuiComponent()
                    .GetType()
                    .GetProperyOrFieldValue(bindableData.GetGuiComponent(), eventName);

                if (unityEvent != null)
                {
                    Type unityEventType = unityEvent.GetType();

                    UnityActionProxy proxyHandler = UnityActionProxy.Create(unityEventType, callback);
                    guiEventData = new GuiEventData(bindName, eventName, bindableData, proxyHandler);
                    RegisteredEvents.Add(guiEventData);


                    unityEventType.GetMethod("AddListener")
                    .Invoke(unityEvent, new object[] { proxyHandler.UnityActionDelegate });
                }
            }

            return(guiEventData);
        }
Example #2
0
        /// <param name="unityEventType">Любой тип UnityEvent или производный от UnityEvent</param>
        /// <param name="universalGuiEventHandler">Универсальный делегат для событий</param>
        public static UnityActionProxy Create(Type unityEventType, UniversalGuiEventDelegate universalGuiEventHandler)
        {
            // список параметров делегата, который принимает AddListener
            ParameterInfo[] callbackParameters =
                unityEventType.GetMethod("AddListener").GetParameters()[0]
                .ParameterType.GetMethod("Invoke").GetParameters();

            // список типов параметров делегата
            Type[] parametersTypes = (from arg in callbackParameters
                                      select arg.ParameterType).ToArray();

            UnityActionProxy proxyHandler = new UnityActionProxy {
                UniversalGuiEventHandler = universalGuiEventHandler
            };

            // Далее необходимо собрать делегат для конвертирования параметров
            ParameterExpression[] args          = new ParameterExpression[parametersTypes.Length]; // аргументы, соответствующие аргументам UnityAction<>
            Expression[]          convertedArgs = new Expression[parametersTypes.Length];          // конвертированные аргументы в object
            for (int i = 0; i < args.Length; i++)
            {
                args[i]          = Expression.Parameter(parametersTypes[i], "arg" + i);
                convertedArgs[i] = Expression.Convert(args[i], typeof(object));
            }

            Expression[] handlerEventArgs = new Expression[2]; // список параметров для передачи в универсальный делегат
            handlerEventArgs[0] = Expression.Constant(proxyHandler.Data);
            handlerEventArgs[1] = Expression.NewArrayInit(typeof(object), convertedArgs);

            Expression callHandlerExpression;

            if (universalGuiEventHandler.Target != null)
            {
                callHandlerExpression = Expression.Call(Expression.Constant(universalGuiEventHandler.Target), universalGuiEventHandler.Method, handlerEventArgs);
            }
            else
            {
                callHandlerExpression = Expression.Call(universalGuiEventHandler.Method, handlerEventArgs);
            }

            // делегат, который принимает параметры нужных типов, конвертирует их в object и вызывает универсальный делегат
            Delegate typesConverter = Expression.Lambda(callHandlerExpression, args).Compile();


            // конструирование делегата UnityAction<> с телом typesConverter
            Type unityEventDelegateType = parametersTypes.Length > 0
                ? typeof(UnityAction <>).MakeGenericType(parametersTypes)
                : typeof(UnityAction);

            proxyHandler.UnityActionDelegate = Delegate.CreateDelegate(unityEventDelegateType, typesConverter.Target, typesConverter.Method);

            return(proxyHandler);
        }
        public void AddEventListener(string bindName, string eventName, UniversalGuiEventDelegate callback)
        {
            _registeredEvents.Add(new EventData(bindName, eventName, callback));

            int i = 0;
            foreach (var guiComponent in this)
            {
                GuiComponent.GuiEventData guiEventData = guiComponent.AddEventListener(bindName, eventName, callback);
                if (guiEventData == null)
                    throw new Exception("eventName or bindName not found"); // TODO custom type exception

                guiEventData.UnityActionProxy.Data.Index = i++;
            }
        }
        public void RemoveEventListener(string bindName, string eventName, UniversalGuiEventDelegate callback, bool throwIfEventNotRegistered = false)
        {
            EventData ev =
                _registeredEvents.SingleOrDefault(
                    data => data.BindName == bindName &&
                    data.EventName == eventName &&
                    data.Callback == callback);

            if (ev != null)
            {
                foreach (var guiComponent in this)
                    guiComponent.RemoveEventListener(bindName, eventName, callback, throwIfEventNotRegistered);

                _registeredEvents.Remove(ev);
            }
            else if (throwIfEventNotRegistered)
                throw new Exception("Event " + eventName + " isn\'t registered for collection"); // TODO custom type exception
        }
Example #5
0
        public void RemoveEventListener(string bindName, string eventName, UniversalGuiEventDelegate callback, bool throwIfEventNotRegistered = false)
        {
            var ev = _registeredEvents.SingleOrDefault(
                data =>
                data.BindName == bindName &&
                data.EventName == eventName &&
                data.UnityActionProxy.UniversalGuiEventHandler == callback);

            if (ev != null)
            {
                CallRemoveListenerOnUnityEvent(ev);
                _registeredEvents.Remove(ev);
            }
            else if (throwIfEventNotRegistered)
            {
                throw new Exception("Event " + eventName + " not registered"); // TODO custom type exception
            }
        }
 public EventData(string bindName, string eventName, UniversalGuiEventDelegate callback)
 {
     BindName = bindName;
     EventName = eventName;
     Callback = callback;
 }
 public void RemoveEventListener(string bindName, string eventName, UniversalGuiEventDelegate callback, bool throwIfEventNotRegistered = false)
 {
     _bindableGuiElementCollection.RemoveEventListener(bindName, eventName, callback, throwIfEventNotRegistered);
 }
 public void AddEventListener(string bindName, string eventName, UniversalGuiEventDelegate callback)
 {
     _bindableGuiElementCollection.AddEventListener(bindName, eventName, callback);
 }