Beispiel #1
0
        /// <summary>Recursive component of quadl</summary>
        /// <remarks>This funciton was also taken from Gander and Gautschi,
        /// http://www.inf.ethz.ch/personal/gander/ .</remarks>
        private static double quadlStep(MulticastDelegate f, double a, double b, double fa, double fb, double i0)
        {
            double h     = (b - a) / 2.0;
            double m     = (a + b) / 2.0;
            double alpha = Math.Sqrt(2.0 / 3.0);
            double beta  = 1.0 / Math.Sqrt(5.0);

            double mll = m - alpha * h;
            double ml  = m - beta * h;
            double mr  = m + beta * h;
            double mrr = m + alpha * h;

            double fmll = (double)f.DynamicInvoke(mll),
                   fml  = (double)f.DynamicInvoke(ml),
                   fm   = (double)f.DynamicInvoke(m),
                   fmr  = (double)f.DynamicInvoke(mr),
                   fmrr = (double)f.DynamicInvoke(mrr);

            double i2 = (h / 6.0) * (fa + fb + 5 * (fml + fmr));
            double i1 = (h / 1470.0) * (77 * (fa + fb) + 432 * (fmll + fmrr) + 625 * (fml + fmr) + 672 * fm);

            if ((i0 + (i1 - i2) == i0) || (mll <= a) || (b <= mrr))
            {
                return(i1);
            }
            else
            {
                return(quadlStep(f, a, mll, fa, fmll, i0) +
                       quadlStep(f, mll, ml, fmll, fml, i0) +
                       quadlStep(f, ml, m, fml, fm, i0) +
                       quadlStep(f, m, mr, fm, fmr, i0) +
                       quadlStep(f, mr, mrr, fmr, fmrr, i0) +
                       quadlStep(f, mrr, b, fmrr, fb, i0));
            }
        }
Beispiel #2
0
        static object DoFunc(MulticastDelegate func, object value, object parameter)
        {
            if (func == null)
            {
                return(value);
            }

            if (func.Method.ContainsGenericParameters)
            {
                return(Binding.DoNothing);
            }

            var parameterInfoes = func.Method.GetParameters();

            switch (parameterInfoes.Length)
            {
            case 0: return(func.DynamicInvoke());

            case 1: return(func.DynamicInvoke(value));

            case 2: return(func.DynamicInvoke(value, parameter));

            default: return(Binding.DoNothing);
            }
        }
Beispiel #3
0
        private R RecursiveInvoke(object parameter, MulticastDelegate del)
        {
            var parameters = del.Method.GetParameters().Length;
            var result     = parameters > 0 ? del.DynamicInvoke(parameter) : del.DynamicInvoke(null);

            if (result is MulticastDelegate)
            {
                return(RecursiveInvoke(parameter, result as MulticastDelegate));
            }

            return((R)result);
        }
Beispiel #4
0
        /// <summary>
        /// Instantiates the service type using the given delegate.
        /// </summary>
        /// <param name="request">The <see cref="IFactoryRequest"/> that describes the service that needs to be created.</param>
        /// <returns>The service instance.</returns>
        public object CreateInstance(IFactoryRequest request)
        {
            object result = null;

            try
            {
                object     target         = _targetDelegate.Target;
                MethodInfo method         = _targetDelegate.Method;
                int        argCount       = request.Arguments.Length;
                int        methodArgCount = method.GetParameters().Count();

                if (argCount != methodArgCount)
                {
                    throw new ArgumentException("Parameter Count Mismatch");
                }

                result = _targetDelegate.DynamicInvoke(request.Arguments);
            }
            catch (TargetInvocationException ex)
            {
                // Unroll the exception
                throw ex.InnerException;
            }

            return(result);
        }
Beispiel #5
0
        public static void ApplyWindowChanges(
            IntPtr window,
            int clientWidth,
            int clientHeight,
            bool wantsFullscreen,
            string screenDeviceName,
            ref string resultDeviceName
            )
        {
            object[] args = { window, clientWidth, clientHeight, wantsFullscreen, screenDeviceName, resultDeviceName };

            if (MainActivity.SDL2DCS_Fullscreen)
            {
                // Real display size
                Android.Graphics.Point size = new Android.Graphics.Point();
                MainActivity.SDL2DCS_Instance.WindowManager.DefaultDisplay.GetRealSize(size);
                args[1] = size.X;
                args[2] = size.Y;
                GraphicsDeviceManager gdm = Game?.Services.GetService(typeof(IGraphicsDeviceManager)) as GraphicsDeviceManager;
                if (gdm != null)
                {
                    gdm.PreferredBackBufferWidth  = size.X;
                    gdm.PreferredBackBufferHeight = size.Y;
                }
            }

            fna_ApplyWindowChanges.DynamicInvoke(args);
            resultDeviceName = (string)args[5];
        }
Beispiel #6
0
        static public void CallEvent(string objMgPath, string eventName, MulticastDelegate delgt, params object[] eventParams)
        {
            try
            {
                delgt.DynamicInvoke(eventParams);
                if (!PurviewMgr.IsMainHost)
                {
                    object[] newparams = new object[eventParams.Length];

                    for (int i = 0; i < eventParams.Length; i++)
                    {
                        if (eventParams[i] is IGameObj)
                        {
                            newparams[i] = new GameObjSyncInfo(((IGameObj)eventParams[i]).MgPath);
                        }
                        else
                        {
                            newparams[i] = eventParams[i];
                        }
                    }

                    // 通过网络协议传递给主机
                    SyncCasheWriter.SubmitNewEvent(objMgPath, eventName, newparams);
                }
            }
            catch (Exception ex)
            {
                Log.Write(ex.ToString());
            }
        }
Beispiel #7
0
        /// <summary>
        /// Instantiates the service type using the given delegate.
        /// </summary>
        /// <param name="request">The <see cref="IFactoryRequest"/> that describes the service that needs to be created.</param>
        /// <returns>The service instance.</returns>
        public object CreateInstance(IFactoryRequest request)
        {
            object result = null;

            try
            {
                var target         = _targetDelegate.Target;
                var method         = _targetDelegate.Method;
                var argCount       = request.Arguments.Length;
                var methodArgCount = method.GetParameters().Count();

                if (argCount != methodArgCount)
                {
                    Console.WriteLine("Parameter Count Mismatch");
                }
                result = _targetDelegate.DynamicInvoke(request.Arguments);
                //result = method.Invoke(target, request.Arguments);
            }
            catch (TargetInvocationException ex)
            {
                // Unroll the exception
                throw ex.InnerException;
            }

            return(result);
        }
Beispiel #8
0
        public void Call <T>(T obj)
        {
            IEnumerable enumerable = list as IEnumerable;

            foreach (var item in enumerable)
            {
                del.DynamicInvoke(obj, item);
            }
        }
Beispiel #9
0
 public override object Execute(MulticastDelegate dele, ParameterCollection parameters)
 {
     try
     {
         return(dele.DynamicInvoke(parameters.AllParameterValues));
     }
     catch (Exception ex)
     {
         return(this.ExecuteOnException(ex, parameters));
     }
 }
Beispiel #10
0
 public static void SoftRaiseEvent(MulticastDelegate @event, object sender, EventArgs e)
 {
     try
     {
         @event.DynamicInvoke(sender, e);
     }
     catch (Exception ex)
     {
         log.Warn(ex);
     }
 }
        public static int GetMaximumTouchCount()
        {
            string maxEnv = Environment.GetEnvironmentVariable(
                "FNA_TOUCH_FORCE_MAXIMUM"
                );
            int max;

            if (int.TryParse(maxEnv, out max) && max == 0)
            {
                return(FNADroidLib.GetMaximumTouchCount());
            }
            return((int)fna_GetMaximumTouchCount.DynamicInvoke());
        }
        public static GamePadCapabilities GetGamePadCapabilities(int index)
        {
            //Mute gamepad 0, move everything; Completely replace the GamePadCapabilities
            if (index == 0 && PhoneAsGamePad)
            {
                if (GetPhoneGamePadStateHook != null)
                {
                    return(GetPhoneGamePadCapabilitiesHook());
                }

                return(PhoneGamePadCapabilities);
            }

            return((GamePadCapabilities)fna_GetGamePadCapabilities.DynamicInvoke(PhoneAsGamePad ? index - 1 : index));
        }
        public override object Execute(MulticastDelegate dele, ParameterCollection parameters)
        {
            try
            {
                return(dele.DynamicInvoke(parameters.AllParameterValues));
            }
            catch (Exception ex)
            {
                Console.ForegroundColor = ConsoleColor.Black;
                Console.BackgroundColor = ConsoleColor.Red;

                Console.WriteLine(ex.Message);

                Console.ResetColor();

                throw;
            }
        }
 public static bool SetGamePadVibration(int index, float leftMotor, float rightMotor)
 {
     if ((Environment.GetEnvironmentVariable(
              "FNA_GAMEPAD_VIBRATION_PHONE"
              ) == "1") || PhoneAsGamePad && index == 0)
     {
         long time = (long)(325f * ((leftMotor + rightMotor) / 2f));
         if (time < 100)
         {
             Vibration.Cancel();
         }
         else
         {
             Vibration.Vibrate(time);
         }
         return(true);
     }
     return((bool)fna_SetGamePadVibration.DynamicInvoke(PhoneAsGamePad ? index - 1 : index, leftMotor, rightMotor));
 }
Beispiel #15
0
        public override object Execute(MulticastDelegate dele, ParameterCollection parameters)
        {
            Console.ForegroundColor = ConsoleColor.Green;

            Console.WriteLine("Prefix: {0}", _prefix);
            Console.WriteLine("Suffix: {0}", _suffix);
            Console.WriteLine("Name: {0}", this.Name);

            if (_allTypes != null)
            {
                Console.WriteLine("All types: {0}", _allTypes);
            }

            Console.WriteLine("Intercepted {0}::{1}", dele.Target.GetType().FullName, dele.Method.Name);

            if (parameters.Dictionary.Count > 0)
            {
                Console.WriteLine("Args:");

                foreach (KeyValuePair <string, object> kvp in parameters.Dictionary)
                {
                    Console.WriteLine("  {0} -> {1}", kvp.Key, kvp.Value);
                }
            }

            Console.ResetColor();

            // invoke the intercepted method
            object result = dele.DynamicInvoke(parameters.AllParameterValues);

            Console.ForegroundColor = ConsoleColor.Green;

            if (dele.Method.ReturnType != typeof(void))
            {
                Console.WriteLine("Return:");
                Console.WriteLine("  {0}", result);
            }

            Console.ResetColor();

            return(result);
        }
Beispiel #16
0
        public static void ApplyWindowChanges(
            IntPtr window,
            int clientWidth,
            int clientHeight,
            bool wantsFullscreen,
            string screenDeviceName,
            ref string resultDeviceName
            )
        {
            object[] args = { window, clientWidth, clientHeight, wantsFullscreen, screenDeviceName, resultDeviceName };
            fna_ApplyWindowChanges.DynamicInvoke(args);
            resultDeviceName = (string)args[5];

            GameForm.Instance?.SDLWindowChanged(window, clientWidth, clientHeight, wantsFullscreen, screenDeviceName, ref resultDeviceName);

            if (resultDeviceName != screenDeviceName)
            {
                // TODO: Does a WM_ message exist for this? Why did I put this empty check in here? git blame myself.
            }
        }
Beispiel #17
0
            private void MainWorkerThread()
            {
                while (true)
                {
                    if (disposed)
                    {
                        return;
                    }
                    startNewWorkItem.WaitOne();
                    if (disposed)
                    {
                        return;
                    }

                    try
                    {
                        Thread.CurrentPrincipal = principal;
                        object result = task.DynamicInvoke(null);
                        if (asyncResult != null)
                        {
                            asyncResult.SetCompleted(result);
                        }
                    }
                    catch (Exception ex)
                    {
                        if (asyncResult != null)
                        {
                            asyncResult.SetCompletedException(ex);
                        }
                    }
                    isAvailable = true;
                    asyncResult = null;
                    task        = null;
                    if (disposed)
                    {
                        return;
                    }
                    workItemComplete.Set();
                }
            }
Beispiel #18
0
        public static void RaiseEvent <T>(T target, string eventName)
        {
            if (target == null)
            {
                throw new ArgumentNullException("target");
            }
            if (eventName == null)
            {
                throw new ArgumentNullException("eventName");
            }

            EventInfo eventInfo = typeof(T).GetEvent(eventName,
                                                     BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);

            if (eventInfo == null)
            {
                string msg = string.Format("Type {0} does not have event " +
                                           "named '{1}'.", typeof(T), eventName);
                throw new ArgumentException(msg);
            }

            FieldInfo delegateField = target.GetType().GetField(
                eventInfo.Name, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public);

            if (delegateField == null)
            {
                string msg = string.Format("Type {0} does not have backing field for the event " +
                                           "named '{1}'. Events with add/remove handlers specified cannot be used this way.",
                                           target.GetType(), eventName);
                throw new ArgumentException(msg);
            }

            MulticastDelegate eventDelegate = (MulticastDelegate)delegateField.GetValue(target);

            if (eventDelegate != null)
            {
                eventDelegate.DynamicInvoke(null);
            }
        }
Beispiel #19
0
        internal static Task InvokeAsync <T>(MulticastDelegate @delegate, T arg)
        {
            switch (@delegate)
            {
            case null:
                return(Task.CompletedTask);

            case Action action:
                action.Invoke();
                return(Task.CompletedTask);

            case Action <T> actionEventArgs:
                actionEventArgs.Invoke(arg);
                return(Task.CompletedTask);

            case Func <Task> func:
                return(func.Invoke());

            case Func <T, Task> funcEventArgs:
                return(funcEventArgs.Invoke(arg));

            default:
            {
                try
                {
                    return(@delegate.DynamicInvoke(arg) as Task ?? Task.CompletedTask);
                }
                catch (TargetInvocationException e)
                {
                    // Since we fell into the DynamicInvoke case, any exception will be wrapped
                    // in a TIE. We can expect this to be thrown synchronously, so it's low overhead
                    // to unwrap it.
                    return(Task.FromException(e.InnerException));
                }
            }
            }
        }
        public void RaisePostBackEvent(String eventName)
        {
            LoadPostData();

            Type type = Widget.GetType();

            foreach (EventDescriptor @event in TypeDescriptor.GetEvents(type).OfType <EventDescriptor>())
            {
                WidgetEventAttribute attribute = @event.Attributes.OfType <WidgetEventAttribute>().SingleOrDefault();

                if (attribute == null || attribute.Name != eventName)
                {
                    continue;
                }

                FieldInfo         delegateField = type.GetField(@event.Name, BindingFlags.Instance | BindingFlags.NonPublic);
                MulticastDelegate @delegate     = delegateField.GetValue(Widget) as MulticastDelegate;

                if (@delegate != null && @delegate.GetInvocationList().Length > 0)
                {
                    @delegate.DynamicInvoke(new object[] { Widget, EventArgs.Empty });
                }
            }
        }
Beispiel #21
0
        public object Invoke(IInvocationInfo invocationInfo)
        {
            var arguments = invocationInfo.Arguments;

            return(_targetDelegate.DynamicInvoke(arguments));
        }
Beispiel #22
0
        public override object Execute(MulticastDelegate dele, ParameterCollection parameters)
        {
            this.ExecuteBefore(parameters);

            return(dele.DynamicInvoke(parameters.AllParameterValues));
        }
        public override object Execute(MulticastDelegate dele, ParameterCollection parameters)
        {
            object result = dele.DynamicInvoke(parameters.AllParameterValues);

            return(this.ExecuteAfter(result, parameters));
        }
Beispiel #24
0
        public static void RunLoop(Game game)
        {
            Initialize(game);

            fna_RunLoop.DynamicInvoke(game);
        }
 public object Execute(params object[] p)
 {
     return(del.DynamicInvoke(p));
 }
Beispiel #26
0
        /// <summary>Find integral using Lobatto Rule</summary>
        /// <param name="f">Function to integrate. Must be of the
        /// form y = f(x) where x and y are of type "double".</param>
        /// <param name="a">Lower bound of integral</param>
        /// <param name="b">Upper bound of integral</param>
        /// <returns>Area under funciton curve with an error of +- 1e-6</returns>
        ///
        /// <remarks>
        /// Derived from "W. Gander and W. Gautschi: Adaptive Quadrature -
        /// Revisited, BIT Vol. 40, No. 1, March 2000, pp. 84--101. CS technical
        /// report: Report (gzipped, 82K). Programs: adaptsim.m, adaptlob.m", which
        /// can be found at: http://www.inf.ethz.ch/personal/gander/.
        ///
        /// The defualt error of 1e-6 was chosen in order to give results
        /// comparible in speed and precision to Matlab R2009a.
        /// </remarks>
        public static double quadl(MulticastDelegate f, double a, double b)
        {
            double tol = 1e-6; // to have the same level of precision as Matlab
            // in the future, this could be an input?

            double m     = (a + b) / 2.0;
            double h     = (b - a) / 2.0;
            double alpha = Math.Sqrt(2.0 / 3.0);
            double beta  = 1.0 / Math.Sqrt(5.0);

            double c1 = 0.942882415695480;
            double c2 = 0.641853342345781;
            double c3 = 0.236383199662150;

            double y1  = (double)f.DynamicInvoke(a),
                   y2  = (double)f.DynamicInvoke(m - c1 * h),
                   y3  = (double)f.DynamicInvoke(m - alpha * h),
                   y4  = (double)f.DynamicInvoke(m - c2 * h),
                   y5  = (double)f.DynamicInvoke(m - beta * h),
                   y6  = (double)f.DynamicInvoke(m - c3 * h),
                   y7  = (double)f.DynamicInvoke(m),
                   y8  = (double)f.DynamicInvoke(m + c3 * h),
                   y9  = (double)f.DynamicInvoke(m + beta * h),
                   y10 = (double)f.DynamicInvoke(m + c2 * h),
                   y11 = (double)f.DynamicInvoke(m + alpha * h),
                   y12 = (double)f.DynamicInvoke(m + c1 * h),
                   y13 = (double)f.DynamicInvoke(b);

            double fa = y1;
            double fb = y13;

            double i2 = (h / 6.0) * (y1 + y13 + 5 * (y5 + y9));
            double i1 = (h / 1470.0) * (77 * (y1 + y13) + 432 * (y3 + y11) + 625 * (y5 + y9) + 672 * y7);

            double i0 = h * (
                0.0158271919734802 * (y1 + y13) +
                0.0942738402188500 * (y2 + y12) +
                0.155071987336585 * (y3 + y11) +
                0.188821573960182 * (y4 + y10) +
                0.199773405226859 * (y5 + y9) +
                0.224926465333340 * (y6 + y8) +
                0.242611071901408 * y7);

            double s = (i0 >= 0) ? 1 : -1;

            double erri1 = Math.Abs(i1 - i0);
            double erri2 = Math.Abs(i2 - i0);

            double R = (erri2 == 0) ? 1 : erri1 / erri2;

            i0 = s * Math.Abs(i0) * tol / double.Epsilon;
            if (i0 == 0)
            {
                i0 = b - a;
            }

            return(quadlStep(f, a, b, fa, fb, i0));
        }
Beispiel #27
0
        /// <summary>
        ///     Evaluates this instance. (at the moment, only two explicit lamda forms are supported)
        /// </summary>
        /// <returns> </returns>
        bool IOperationEvaluator.Evaluate( )
        {
            if (Expression != null)
            {
                EditableExpression expression = Expression;

                LambdaExpression delegateExpression = ( LambdaExpression )expression.ToExpression( );

                object compiledDelegate = delegateExpression.Compile( );

                if (compiledDelegate is MulticastDelegate)
                {
                    MulticastDelegate multicastDelegate = ( MulticastDelegate )compiledDelegate;

                    compiledDelegate = multicastDelegate.DynamicInvoke(null);
                }

                if (compiledDelegate is Func <bool> )
                {
                    Func <bool> delegateMethod = (Func <bool>)compiledDelegate;

                    return(delegateMethod( ));
                }
                if (compiledDelegate is Action <IExpressionEvaluator> )
                {
                    Action <IExpressionEvaluator> evaluatorDelegate = (Action <IExpressionEvaluator>)compiledDelegate;

                    evaluatorDelegate(this);
                }
            }

            bool?evaluation = null;

            foreach (ExpressionContainer container in  _conditionChains)
            {
                if (container.Type == ExpressionType.Evaluate)
                {
                    evaluation = container.Evaluate( );
                }

                if (container.Type == ExpressionType.And)
                {
                    evaluation = evaluation.GetValueOrDefault( ) && container.Evaluate( );
                }

                if (container.Type == ExpressionType.Or)
                {
                    evaluation = evaluation.GetValueOrDefault( ) || container.Evaluate( );
                }

                if (container.Type == ExpressionType.Is)
                {
                    evaluation = container.Evaluate( );
                }

                if (container.Type == ExpressionType.Not)
                {
                    evaluation = !container.Evaluate( );
                }

                if (container.Type == ExpressionType.Custom)
                {
                    evaluation = container.Evaluate( );
                }
            }

            return(evaluation.GetValueOrDefault( ));
        }
        public static GamePadState GetGamePadState(int index, GamePadDeadZone deadZoneMode)
        {
            bool backPressed = false;

            if (index == 0)
            {
                int    numkeys;
                IntPtr pKeys = SDL2.SDL.SDL_GetKeyboardState(out numkeys);
                backPressed = 1 == Marshal.ReadByte(pKeys + (int)SDL2.SDL.SDL_Scancode.SDL_SCANCODE_AC_BACK);
                //TODO "It will be valid for the whole lifetime of the application and should not be freed by the caller." Uhh...
            }

            //Mute gamepad 0, move everything; Completely replace the GamePadState
            if (index == 0 && PhoneAsGamePad)
            {
                if (GetPhoneGamePadStateHook != null)
                {
                    return(GetPhoneGamePadStateHook());
                }

                Vector3 accelerometerData = Accelerometer.Data;

                Vector2 leftStick  = new Vector2(accelerometerData.X, accelerometerData.Y);
                Vector2 rightStick = Vector2.Zero;

                float leftTrigger  = 0f;
                float rightTrigger = 0f;

                ButtonState dpadUp    = ButtonState.Released;
                ButtonState dpadDown  = ButtonState.Released;
                ButtonState dpadLeft  = ButtonState.Released;
                ButtonState dpadRight = ButtonState.Released;

                Buttons buttons = (Buttons)0;

                if (backPressed)
                {
                    buttons |= Buttons.Back;
                }

                GamePadState newState = new GamePadState(
                    new GamePadThumbSticks(leftStick, rightStick),
                    new GamePadTriggers(leftTrigger, rightTrigger),
                    new GamePadButtons(buttons),
                    new GamePadDPad(dpadUp, dpadDown, dpadLeft, dpadRight)
                    );
                //newState.IsConnected = state.IsConnected; //true by default
                //newState.PacketNumber = state.PacketNumber; //uhh...
                return(newState);
            }

            GamePadState state = (GamePadState)fna_GetGamePadState.DynamicInvoke(PhoneAsGamePad ? index - 1 : index, deadZoneMode);

            //Just "enhance" the first controller
            if (index == 0)
            {
                GamePadButtons buttons    = state.Buttons;
                Buttons        tmpButtons = (Buttons)0;

                if (buttons.A == ButtonState.Pressed)
                {
                    tmpButtons |= Buttons.A;
                }
                if (buttons.B == ButtonState.Pressed)
                {
                    tmpButtons |= Buttons.B;
                }
                if (buttons.X == ButtonState.Pressed)
                {
                    tmpButtons |= Buttons.X;
                }
                if (buttons.Y == ButtonState.Pressed)
                {
                    tmpButtons |= Buttons.Y;
                }
                if (buttons.Back == ButtonState.Pressed)
                {
                    tmpButtons |= Buttons.Back;
                }
                if (buttons.BigButton == ButtonState.Pressed)
                {
                    tmpButtons |= Buttons.BigButton;
                }
                if (buttons.Start == ButtonState.Pressed)
                {
                    tmpButtons |= Buttons.Start;
                }
                if (buttons.LeftStick == ButtonState.Pressed)
                {
                    tmpButtons |= Buttons.LeftStick;
                }
                if (buttons.RightStick == ButtonState.Pressed)
                {
                    tmpButtons |= Buttons.RightStick;
                }
                if (buttons.LeftShoulder == ButtonState.Pressed)
                {
                    tmpButtons |= Buttons.LeftShoulder;
                }
                if (buttons.RightShoulder == ButtonState.Pressed)
                {
                    tmpButtons |= Buttons.RightShoulder;
                }

                if (backPressed)
                {
                    tmpButtons |= Buttons.Back;
                }

                GamePadState newState = new GamePadState(
                    state.ThumbSticks,
                    state.Triggers,
                    new GamePadButtons(tmpButtons),
                    state.DPad
                    );
                //newState.IsConnected = state.IsConnected; //true by default
                //newState.PacketNumber = state.PacketNumber; //uhh...
                return(newState);
            }

            return(state);
        }
        void ITypeContributor.Contribute(TypeBuilder typeBuilder, FieldBuilder implementationField, RuntimeImplementation delegatedImplementation)
        {
            // Define the method
            var methodBuilder = typeBuilder.DefineMethod(_name, _accessibility | MethodAttributes.HideBySig);

            methodBuilder.SetReturnType(_callback.Method.ReturnType);
            methodBuilder.SetParameters(_callback.Method.GetParameters().Select(x => x.ParameterType).ToArray());

            // Define attributes
            foreach (var attribute in _attributes)
            {
                var types         = attribute.Value.Select(x => x.GetType()).ToArray();
                var attributeCtor = attribute.Key.GetConstructor(types);
                methodBuilder.SetCustomAttribute(
                    new CustomAttributeBuilder(attributeCtor, attribute.Value)
                    );
            }

            // Define parameters
            var parameters = new List <ParameterBuilder>();

            foreach (var param in _callback.Method.GetParameters())
            {
                parameters.Add(methodBuilder.DefineParameter(param.Position + 1, ParameterAttributes.None, param.Name));
            }

            // Prepare the implementation
            var bodyWriter = methodBuilder.GetILGenerator();

            bodyWriter.Emit(OpCodes.Ldarg_0);
            bodyWriter.Emit(OpCodes.Ldfld, implementationField);
            bodyWriter.Emit(OpCodes.Ldstr, _name);

            // Build the array of objects
            var arguments = bodyWriter.DeclareLocal(typeof(object[]));

            bodyWriter.Emit(OpCodes.Ldc_I4, parameters.Count);
            bodyWriter.Emit(OpCodes.Newarr, typeof(object));
            bodyWriter.Emit(OpCodes.Stloc, arguments);

            // Set the array
            foreach (var parameter in _callback.Method.GetParameters())
            {
                bodyWriter.Emit(OpCodes.Ldloc, arguments);
                bodyWriter.Emit(OpCodes.Ldc_I4, parameter.Position);
                bodyWriter.Emit(OpCodes.Ldarg, parameter.Position + 1);
                if (parameter.ParameterType.IsValueType)
                {
                    bodyWriter.Emit(OpCodes.Box, parameter.ParameterType);
                }
                bodyWriter.Emit(OpCodes.Stelem_Ref);
            }

            // Call Invoke and return the result
            bodyWriter.Emit(OpCodes.Ldloc, arguments);
            bodyWriter.EmitCall(OpCodes.Callvirt, typeof(IImplementation).GetMethod("Invoke"), new Type[0]);
            bodyWriter.Emit(OpCodes.Unbox_Any, _callback.Method.ReturnType);
            bodyWriter.Emit(OpCodes.Stloc_0);
            bodyWriter.Emit(OpCodes.Ldloc_0);
            bodyWriter.Emit(OpCodes.Ret);

            delegatedImplementation.RegisterCallback(_name, methodBuilder,
                                                     args =>
            {
                _wasCalled = true;
                try
                {
                    return(_callback.DynamicInvoke(args));
                }
                catch (TargetInvocationException ex)
                {
                    throw ex.InnerException;
                }
            }
                                                     );
        }