Exemple #1
0
        public void TestNestedSequential()
        {
            ActionCreator actionCreator = new ActionCreator();
            List <Action> Actions       = new List <Action>();

            int count = 0;

            actionCreator.StartSequence();
            Actions.Add(actionCreator.Sequential(() => { count++; })); // +1

            actionCreator.StartSequence();
            Actions.Add(actionCreator.Sequential(() => { count++; })); // +2
            Actions.Add(actionCreator.Sequential(() => { count++; })); // +3
            actionCreator.EndSequence();

            Actions.Add(actionCreator.Sequential(() => { count++; })); // +2
            actionCreator.EndSequence();

            foreach (Action a in Actions)
            {
                a.Invoke();
            }

            Assert.AreEqual(8, count);
        }
        public void GettingTagAction()
        {
            IActionStrategy action = new ActionCreator()
                                     .GetAction(ProgramAction.ToTag);

            Assert.AreEqual(typeof(TagAction), action.GetType());
        }
Exemple #3
0
        public void TestNestedSequentialExecutionOrder()
        {
            ActionCreator actionCreator = new ActionCreator();
            List <Action> Actions       = new List <Action>();

            List <int> actual = new List <int>();

            actionCreator.StartSequence();
            Actions.Add(actionCreator.Sequential(() => { actual.Add(0); })); // Should add 0
            Actions.Add(actionCreator.Sequential(() => { actual.Add(1); })); // Should add 0, 1 (in this order)

            actionCreator.StartSequence();
            Actions.Add(actionCreator.Sequential(() => { actual.Add(2); })); // Should add 0, 1, 2 (in this order)
            Actions.Add(actionCreator.Sequential(() => { actual.Add(3); })); // Should add 0, 1, 2, 3 (in this order)
            actionCreator.EndSequence();

            Actions.Add(actionCreator.Sequential(() => { actual.Add(4); })); // Should add 0, 1, 4 (in this order)
            Actions.Add(actionCreator.Sequential(() => { actual.Add(5); })); // Should add 0, 1, 4, 5 (in this order)

            foreach (Action a in Actions)
            {
                a.Invoke();
            }

            List <int> expected = new List <int>(new int[] { 0, 0, 1, 0, 1, 2, 0, 1, 2, 3, 0, 1, 4, 0, 1, 4, 5 });

            CollectionAssert.AreEqual(expected, actual);
        }
    static void OnCreate(ActionCreator instnace)
    {
        if (Name == null)
        {
            throw new MissingComponentException("Name was not given!");
        }
        string FilePath = $"{FileFolderPath}/{Name}Action.cs";

        if (File.Exists(FilePath))
        {
            int option = EditorUtility.DisplayDialogComplex("Action already exists!",
                                                            "Do you want to overwrite it?",
                                                            "Yes, do it!",
                                                            "Cancel",
                                                            "");

            if (option == 0)
            {
                CreateFile(FilePath);
                instnace.Close();
            }
        }
        else
        {
            CreateFile(FilePath);
            instnace.Close();
        }
    }
        public void GettingFileNameAction()
        {
            IActionStrategy action = new ActionCreator()
                                     .GetAction(ProgramAction.ToFileName);

            Assert.AreEqual(typeof(FileNameAction), action.GetType());
        }
    static void Init()
    {
        FileFolderPath = GetAssetPath();
        ActionCreator window = CreateInstance <ActionCreator>();

        window.position = new Rect(Screen.width / 2, Screen.height / 2, Screen.width, 100);
        window.ShowUtility();
    }
Exemple #7
0
 public BeginPageVm()
 {
     dispatcher        = new Dispatcher.Dispatcher();
     actionCreator     = ActionCreator.Get(dispatcher);
     bookDataStore     = BookDataStore.Get(dispatcher);
     AddCommand.action = () => actionCreator.Begin(BookTitle);
     EndCommand.action = () => actionCreator.End(BookTitle);
     bookDataStore.ReadingBookEventHandler += BookDataStore_ReadingBookEventHandler;
     bookDataStore.EndBookEventHandler     += BookDataStore_EndBookEventHandler;
 }
Exemple #8
0
        public void DispatchNullActionCreatorTest()
        {
            var store = new Store <AppState>(AppReducer.Invoke);
            ActionCreator <AppState> actionCreator = null;

            Assert.Throws <ArgumentNullException>(() =>
            {
                store.Dispatch(actionCreator);
            });
        }
        public void ActionReversed2()
        {
            IBaseHelper baseHelper = new BaseHelper();
            var         list       = new ActionCreator(baseHelper).DoAction("reversed2", @"C:\stuff\", new List <string>
            {
                @"c:\stuff\te\t.dat"
            });

            list.First().Should().Be(@"dat.t\te");
        }
        public bool WriteFile()
        {
            if (Directory.Exists(Path.GetDirectoryName(ScanLocation)))
            {
                var list = new ActionCreator(new BaseHelper()).DoAction(Command, ScanLocation);
                File.WriteAllLines(ResultLocation, list);
                return(true);
            }

            Console.WriteLine("Folder not found");
            return(false);
        }
Exemple #11
0
        public void ActionCppTest()
        {
            IBaseHelper baseHelper = new BaseHelper();
            var         list       = new ActionCreator(baseHelper).DoAction("cs", @"C:\folder\", new List <string>
            {
                @"C:\folder\file.txt",
                @"C:\folder\file2.cs",
                @"C:\folder\sub_folder\file3.cs"
            });

            list.Count().Should().Be(3);
            list.All(f => f.EndsWith(" /")).Should().BeTrue();
        }
Exemple #12
0
        public void ActionAllTest()
        {
            IBaseHelper baseHelper = new BaseHelper();
            var         list       = new ActionCreator(baseHelper).DoAction("all", @"C:\folder\", new List <string>
            {
                @"C:\folder\file1.txt",
                @"C:\folder\file2.cs",
                @"C:\folder\sub_folder\file3.cs",
                @"C:\folder\sub_foler\file1.txt"
            });

            list.Count().Should().Be(4);
            list.All(f => !f.Contains(@"C:\")).Should().BeTrue();
        }
        private static object Invoke(PSInvokeMemberBinder binder, object o, int numArgs)
        {
#if BINDERS_RUNTIME_STATS
            Stats.Increment(StatsCounter.InvokeMemberBinderInvoked);
#endif
            // We can't cache the delegate related to property (has it could have been changed since last call)
            // We could workaround this limitation if we did have version number in the dynamic object (and detect if it changed - or changed function - since last call)
            var dc = o as IDynamicClass;
            if (dc != null)
            {
                var func = dc.__GetDynamicValue(binder.name) as Delegate;
                if (func != null)
                {
                    // Use function, but let's compare with previous invoker if we can reuse it
                    Delegate previousDelegate = binder.mPreviousDelegate;
                    if ((previousDelegate == null) || (func.Target != previousDelegate.Target) || (func.Method != previousDelegate.Method))
                    {
                        binder.mPreviousDelegate = func;
                        binder.mInvoker          = ActionCreator.CreateInvoker(func);                   // This is going to use an invoker factory (can be registered by user too for more optimal code).
                    }
                    return(binder.mInvoker.SafeInvokeWith(binder.mArgs));                               // Now invoke, there is no parameters here
                }
            }

            if (o == binder.mPreviousTarget)
            {
                // If the object is the same, we directly invoke (no conversion needed in this case)
                return(binder.mInvoker.SafeInvokeWith(binder.mArgs));
            }

            // Otherwise we have to find the corresponding method
            object result = binder.ResolveAndInvoke(o, numArgs);

            if (binder.mDelegate != null)
            {
                binder.mInvoker = ActionCreator.CreateInvoker(binder.mDelegate);
            }
            else
            {
                binder.mInvoker = ActionCreator.CreateInvoker(o, binder.mMethod.Method);
            }
            binder.mPreviousTarget = o;

            return(result);
        }
        public static T Create <T>(IDefaultData defaultData, ObjectCreationStrategy objectCreationStrategy)
        {
            var type         = typeof(T);
            var defaultValue = type.GetDefaultValue(defaultData);

            if (defaultValue != null)
            {
                return((T)defaultValue);
            }

            if (type.IsInterface)
            {
                return(InterfaceCreator.Create <T>(type, defaultData, objectCreationStrategy));
            }

            if (type.IsAbstract)
            {
                return(AbstractClassCreator.Create <T>(type, defaultData, objectCreationStrategy));
            }

            if (type.IsArray)
            {
                return(ArrayCreator.Create <T>(type, defaultData, objectCreationStrategy));
            }

            if (type.IsAction())
            {
                return(ActionCreator.Create <T>(type));
            }

            if (type.IsFunc())
            {
                return(FuncCreator.Create <T>(type, defaultData, objectCreationStrategy));
            }

            if (type.IsTask())
            {
                return(TaskCreator.Create <T>(type, defaultData, objectCreationStrategy));
            }

            return(UnknownTypeCreator.CreateDynamicFrom <T>(type, defaultData, objectCreationStrategy));
        }
Exemple #15
0
        /// <summary>
        /// Dispatches an action creator.
        /// </summary>
        /// <param name="actionCreator">
        /// A function that creates an action.
        /// </param>
        public void Dispatch(ActionCreator <TState> actionCreator)
        {
            if (actionCreator == null)
            {
                throw new ArgumentNullException(nameof(actionCreator));
            }

            try
            {
                var action = actionCreator(State, this);
                if (action != null)
                {
                    dispatcher(action);
                }
            }
            catch (Exception ex)
            {
                OnError(ex);
            }
        }
Exemple #16
0
        /// <summary>
        /// This is the most generic method for setting a member's value.
        /// It will attempt to resolve the member by name and the set its value by invoking the
        /// callsite's delegate
        /// </summary>
        private static void SetMember <T> (CallSite site, object o, T value)
        {
#if BINDERS_RUNTIME_STATS
            Stats.Increment(StatsCounter.SetMemberBinderInvoked);
#endif

            var binder = (PSSetMemberBinder)site.Binder;

            // resolve as dictionary
            var dict = o as IDictionary;
            if (dict != null)
            {
                // special case this since it happens so much in object initialization
                dict[binder.name] = value;
                return;
            }

            // determine if this is a instance member or a static member
            bool isStatic;
            Type otype;

            if (o is System.Type)
            {
                // static member
                otype    = (System.Type)o;
                o        = null;
                isStatic = true;
            }
            else
            {
                // instance member

                otype    = o.GetType();
                isStatic = false;
            }

            // see if binding type is the same
            if (otype == binder.type)
            {
                // use cached resolve
                if (binder.property != null)
                {
                    Action <T> action;
                    if (o == binder.previousTarget)
                    {
                        action = (Action <T>)binder.previousAction;
                    }
                    else
                    {
                        binder.previousAction = action = ActionCreator.CreatePropertySetAction <T>(o, binder.property);
                        binder.previousTarget = o;
                    }
                    action(value);
                    return;
                }

                if (binder.field != null)
                {
                    object newValue = PlayScript.Dynamic.ConvertValue(value, binder.field.FieldType);
                    binder.field.SetValue(o, newValue);
                    return;
                }

                // resolve as dynamic class
                var dc = o as IDynamicClass;
                if (dc != null)
                {
                    dc.__SetDynamicValue(binder.name, value);
                    return;
                }

                throw new System.InvalidOperationException("Unhandled member type in PSSetMemberBinder");
            }

            // resolve name

#if BINDERS_RUNTIME_STATS
            Stats.Increment(StatsCounter.SetMemberBinder_Resolve_Invoked);
#endif

            otype    = o.GetType();
            isStatic = false;

            // resolve as property
            var property = otype.GetProperty(binder.name);
            if (property != null)
            {
                // found property
                var setter = property.GetSetMethod();
                if (setter != null && setter.IsPublic && setter.IsStatic == isStatic)
                {
                    // setup binding to property
                    binder.type     = otype;
                    binder.property = property;
                    binder.field    = null;
                    object newValue = PlayScript.Dynamic.ConvertValue(value, binder.property.PropertyType);
                    binder.property.SetValue(o, newValue, null);
                    return;
                }
            }

            // resolve as field
            var field = otype.GetField(binder.name);
            if (field != null)
            {
                // found field
                if (field.IsPublic && field.IsStatic == isStatic)
                {
                    // setup binding to field
                    binder.type     = otype;
                    binder.property = null;
                    binder.field    = field;
                    object newValue = PlayScript.Dynamic.ConvertValue(value, binder.field.FieldType);
                    binder.field.SetValue(o, newValue);
                    return;
                }
            }

            if (o is IDynamicClass)
            {
                // dynamic class
                binder.type     = otype;
                binder.property = null;
                binder.field    = null;
                ((IDynamicClass)o).__SetDynamicValue(binder.name, value);
                return;
            }

            // could not resolve name as property or field, and is not dynamic class or dictionary
            // invoke callback
            if (Binder.OnSetMemberError != null)
            {
                Binder.OnSetMemberError(o, binder.name, value);
            }
        }
 void Awake()
 {
     instance = gameObject.GetComponent <ActionCreator> ();
 }
        /// <summary>
        /// This is the most generic method for getting a member's value.
        /// It will attempt to resolve the member by name and the get its value by invoking the
        /// callsite's delegate
        /// </summary>
        public T GetMember <T> (object o)
        {
            Stats.Increment(StatsCounter.GetMemberBinderInvoked);

            TypeLogger.LogType(o);

            // resolve as dictionary (this is usually an expando)
            var dict = o as IDictionary <string, object>;

            if (dict != null)
            {
                Stats.Increment(StatsCounter.GetMemberBinder_Expando);

                // special case this for expando objects
                object value;
                if (dict.TryGetValue(mName, out value))
                {
                    // fast path empty cast just in case
                    if (value is T)
                    {
                        return((T)value);
                    }
                    else
                    {
                        return(PlayScript.Dynamic.ConvertValue <T>(value));
                    }
                }

                // key not found
                return(default(T));
            }

            if (o == null)
            {
                return(default(T));
            }

            // determine if this is a instance member or a static member
            bool isStatic;
            Type otype;

            if (o is System.Type)
            {
                // static member
                otype    = (System.Type)o;
                o        = null;
                isStatic = true;
            }
            else
            {
                // instance member
                otype    = o.GetType();
                isStatic = false;
            }

            if (otype == mType)
            {
                // use cached resolve
                if (mProperty != null)
                {
                    Func <T> func;
                    if (o == mPreviousTarget)
                    {
                        func = (Func <T>)mPreviousFunc;
                    }
                    else
                    {
                        mPreviousFunc   = func = ActionCreator.CreatePropertyGetAction <T>(o, mProperty);
                        mPreviousTarget = o;
                    }
                    return(func());
                }

                if (mField != null)
                {
                    return(PlayScript.Dynamic.ConvertValue <T>(mField.GetValue(o)));
                }

                if (mMethod != null)
                {
                    // construct method delegate
                    return(PlayScript.Dynamic.ConvertValue <T>(Delegate.CreateDelegate(mTargetType, o, mMethod)));
                }

                // resolve as dynamic class
                var dc = o as IDynamicClass;
                if (dc != null)
                {
                    object result = dc.__GetDynamicValue(mName);
                    return(PlayScript.Dynamic.ConvertValue <T>(result));
                }

                throw new System.InvalidOperationException("Unhandled member type in PSGetMemberBinder");
            }

            // resolve name
            Stats.Increment(StatsCounter.GetMemberBinder_Resolve_Invoked);

            // resolve as property
            var property = otype.GetProperty(mName);

            if (property != null)
            {
                // found property
                var getter = property.GetGetMethod();
                if (getter != null && getter.IsPublic && getter.IsStatic == isStatic)
                {
                    // setup binding to property
                    mType           = otype;
                    mPreviousFunc   = null;
                    mPreviousTarget = null;
                    mProperty       = property;
                    mPropertyGetter = property.GetGetMethod();
                    mField          = null;
                    mMethod         = null;
                    mTargetType     = property.PropertyType;
                    return(PlayScript.Dynamic.ConvertValue <T>(mPropertyGetter.Invoke(o, null)));
                }
            }

            // resolve as field
            var field = otype.GetField(mName);

            if (field != null)
            {
                // found field
                if (field.IsPublic && field.IsStatic == isStatic)
                {
                    // setup binding to field
                    mType           = otype;
                    mPreviousFunc   = null;
                    mPreviousTarget = null;
                    mProperty       = null;
                    mField          = field;
                    mMethod         = null;
                    mTargetType     = field.FieldType;
                    return(PlayScript.Dynamic.ConvertValue <T>(field.GetValue(o)));
                }
            }

            // resolve as method
            BindingFlags flags = BindingFlags.NonPublic | BindingFlags.Public;

            if (isStatic)
            {
                flags |= BindingFlags.Static;
            }
            else
            {
                flags |= BindingFlags.Instance;
            }
            var method = otype.GetMethod(mName, flags);

            if (method != null)
            {
                // setup binding to method
                mType           = otype;
                mPreviousFunc   = null;
                mPreviousTarget = null;
                mProperty       = null;
                mField          = null;
                mMethod         = method;
                mTargetType     = PlayScript.Dynamic.GetDelegateTypeForMethod(mMethod);

                // construct method delegate
                return(PlayScript.Dynamic.ConvertValue <T>(Delegate.CreateDelegate(mTargetType, o, mMethod)));
            }

            if (o is IDynamicClass)
            {
                // dynamic class
                mType           = otype;
                mPreviousFunc   = null;
                mPreviousTarget = null;
                mProperty       = null;
                mField          = null;
                mMethod         = null;
                object result = ((IDynamicClass)o).__GetDynamicValue(mName);
                return(PlayScript.Dynamic.ConvertValue <T>(result));
            }

            return(default(T));
        }
Exemple #19
0
        /// <summary>
        /// This is the most generic method for getting a member's value.
        /// It will attempt to resolve the member by name and the get its value by invoking the
        /// callsite's delegate
        /// </summary>
        public T GetMember <T> (object o)
        {
            Stats.Increment(StatsCounter.GetMemberBinderInvoked);

            TypeLogger.LogType(o);

            // get accessor for value type T
            var accessor = o as IDynamicAccessor <T>;

            if (accessor != null)
            {
                return(accessor.GetMember(mName, ref mNameHint));
            }

            // fallback on object accessor and cast it to T
            var untypedAccessor = o as IDynamicAccessorUntyped;

            if (untypedAccessor != null)
            {
                // value can be null, undefined, or of type T
                object value = untypedAccessor.GetMember(mName, ref mNameHint);
                // convert value to T
                if (value == null)
                {
                    return(default(T));
                }
                else if (value is T)
                {
                    return((T)value);
                }
                else if (Dynamic.IsUndefined(value))
                {
                    return(Dynamic.GetUndefinedValue <T>());
                }
                else
                {
                    return(PlayScript.Dynamic.ConvertValue <T>(value));
                }
            }

            // resolve as dictionary (this is usually an expando)
            var dict = o as IDictionary <string, object>;

            if (dict != null)
            {
                Stats.Increment(StatsCounter.GetMemberBinder_Expando);

                // special case this for expando objects
                object value;
                if (dict.TryGetValue(mName, out value))
                {
                    // fast path empty cast just in case
                    if (value is T)
                    {
                        return((T)value);
                    }
                    else
                    {
                        return(PlayScript.Dynamic.ConvertValue <T>(value));
                    }
                }

                // key not found
                return(Dynamic.GetUndefinedValue <T>());
            }

            if (PlayScript.Dynamic.IsNullOrUndefined(o))
            {
                return(Dynamic.GetUndefinedValue <T>());
            }

            // determine if this is a instance member or a static member
            bool isStatic;
            Type otype;

            if (o is System.Type)
            {
                // static member
                otype    = (System.Type)o;
                o        = null;
                isStatic = true;
            }
            else
            {
                // instance member
                otype    = o.GetType();
                isStatic = false;
            }

            if (otype == mType)
            {
                // use cached resolve
                if (mProperty != null)
                {
                    Func <T> func;
                    if (o == mPreviousTarget)
                    {
                        func = (Func <T>)mPreviousFunc;
                    }
                    else
                    {
                        mPreviousFunc   = func = ActionCreator.CreatePropertyGetAction <T>(o, mProperty);
                        mPreviousTarget = o;
                    }
                    return(func());
                }

                if (mField != null)
                {
                    return(PlayScript.Dynamic.ConvertValue <T>(mField.GetValue(o)));
                }

                if (mMethod != null)
                {
                    // construct method delegate
                    return(PlayScript.Dynamic.ConvertValue <T>(Delegate.CreateDelegate(mTargetType, o, mMethod)));
                }

                // resolve as dynamic class
                var dc = o as IDynamicClass;
                if (dc != null)
                {
                    object result = dc.__GetDynamicValue(mName);
                    return(PlayScript.Dynamic.ConvertValue <T>(result));
                }

                if (mName == "constructor")
                {
                    return(PlayScript.Dynamic.ConvertValue <T> (otype));
                }

                throw new System.InvalidOperationException("Unhandled member type in PSGetMemberBinder");
            }

            // resolve name
            Stats.Increment(StatsCounter.GetMemberBinder_Resolve_Invoked);
            Stats.Start(StatsCounter.GetMemberBinder_Resolve_Time);

            // The constructor is a special synthetic property - we have to handle this for AS compatibility
            if (mName == "constructor")
            {
                // setup binding to field
                mType           = otype;
                mPreviousFunc   = null;
                mPreviousTarget = null;
                mProperty       = null;
                mField          = null;
                mMethod         = null;
                mTargetType     = typeof(Type);
                Stats.Stop(StatsCounter.GetMemberBinder_Resolve_Time);
                return(PlayScript.Dynamic.ConvertValue <T> (otype));
            }

            // resolve as property
            // TODO: we allow access to non-public properties for simplicity,
            // should cleanup to check access levels
            var property = otype.GetProperty(mName, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);

            if (property != null)
            {
                // found property
                var getter = property.GetGetMethod();
                if (getter != null && getter.IsStatic == isStatic)
                {
                    // setup binding to property
                    mType           = otype;
                    mPreviousFunc   = null;
                    mPreviousTarget = null;
                    mProperty       = property;
                    mPropertyGetter = property.GetGetMethod();
                    mField          = null;
                    mMethod         = null;
                    mTargetType     = property.PropertyType;
                    Stats.Stop(StatsCounter.GetMemberBinder_Resolve_Time);
                    return(PlayScript.Dynamic.ConvertValue <T>(mPropertyGetter.Invoke(o, null)));
                }
            }

            // resolve as field
            // TODO: we allow access to non-public fields for simplicity,
            // should cleanup to check access levels
            var field = otype.GetField(mName, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);

            if (field != null)
            {
                // found field
                if (field.IsStatic == isStatic)
                {
                    // setup binding to field
                    mType           = otype;
                    mPreviousFunc   = null;
                    mPreviousTarget = null;
                    mProperty       = null;
                    mField          = field;
                    mMethod         = null;
                    mTargetType     = field.FieldType;
                    Stats.Stop(StatsCounter.GetMemberBinder_Resolve_Time);
                    return(PlayScript.Dynamic.ConvertValue <T>(field.GetValue(o)));
                }
            }

            // resolve as method
            BindingFlags flags = BindingFlags.NonPublic | BindingFlags.Public;

            if (isStatic)
            {
                flags |= BindingFlags.Static;
            }
            else
            {
                flags |= BindingFlags.Instance;
            }
            var method = otype.GetMethod(mName, flags);

            if (method != null)
            {
                // setup binding to method
                mType           = otype;
                mPreviousFunc   = null;
                mPreviousTarget = null;
                mProperty       = null;
                mField          = null;
                mMethod         = method;
                mTargetType     = PlayScript.Dynamic.GetDelegateTypeForMethod(mMethod);
                Stats.Stop(StatsCounter.GetMemberBinder_Resolve_Time);
                return(PlayScript.Dynamic.ConvertValue <T>(Delegate.CreateDelegate(mTargetType, o, mMethod)));
            }

            if (o is IDynamicClass)
            {
                // dynamic class
                mType           = otype;
                mPreviousFunc   = null;
                mPreviousTarget = null;
                mProperty       = null;
                mField          = null;
                mMethod         = null;
                object result = ((IDynamicClass)o).__GetDynamicValue(mName);
                Stats.Stop(StatsCounter.GetMemberBinder_Resolve_Time);
                return(PlayScript.Dynamic.ConvertValue <T>(result));
            }

            Stats.Stop(StatsCounter.GetMemberBinder_Resolve_Time);

            return(Dynamic.GetUndefinedValue <T>());
        }
Exemple #20
0
        public T SetMember <T>(object o, T value, bool valueTypeIsConstant = false)
        {
            Stats.Increment(StatsCounter.SetMemberBinderInvoked);

            TypeLogger.LogType(o);

            // get accessor for value type T
            var accessor = o as IDynamicAccessor <T>;

            if (accessor != null)
            {
                accessor.SetMember(mName, ref mNameHint, value);
                return(value);
            }

            // fallback on untyped accessor
            var untypedAccessor = o as IDynamicAccessorUntyped;

            if (untypedAccessor != null)
            {
                untypedAccessor.SetMember(mName, ref mNameHint, (object)value);
                return(value);
            }

            // resolve as dictionary
            var dict = o as IDictionary;

            if (dict != null)
            {
                // special case this since it happens so much in object initialization
                dict[mName] = value;
                return(value);
            }

            // determine if this is a instance member or a static member
            bool isStatic;
            Type otype;

            if (o is System.Type)
            {
                // static member
                otype    = (System.Type)o;
                o        = null;
                isStatic = true;
            }
            else
            {
                // instance member
                otype    = o.GetType();
                isStatic = false;
            }

            // see if binding type is the same
            if (otype == mType)
            {
                // use cached resolve
                if (mProperty != null)
                {
                    Action <T> action;
                    if (o == mPreviousTarget)
                    {
                        action = (Action <T>)mPreviousAction;
                    }
                    else
                    {
                        mPreviousAction = action = ActionCreator.CreatePropertySetAction <T>(o, mProperty);
                        mPreviousTarget = o;
                    }
                    action(value);
                    return(value);
                }

                // use cached resolve
                if (mProperty != null)
                {
                    mArgs[0] = value;
                    mPropertySetter.Invoke(o, BindingFlags.SuppressChangeType, null, mArgs, null);
                    return(value);
                }

                if (mField != null)
                {
                    mField.SetValue(o, value);
                    return(value);
                }

                // resolve as dynamic class
                var dc = o as IDynamicClass;
                if (dc != null)
                {
                    dc.__SetDynamicValue(mName, value);
                    return(value);
                }

                throw new System.InvalidOperationException("Unhandled member type in PSSetMemberBinder");
            }

            // resolve name
            Stats.Increment(StatsCounter.SetMemberBinder_Resolve_Invoked);
            Stats.Start(StatsCounter.SetMemberBinder_Resolve_Time);

            // resolve as property
            // TODO: we allow access to non-public properties for simplicity,
            // should cleanup to check access levels
            var property = otype.GetProperty(mName, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);

            if (property != null)
            {
                // found property
                var setter = property.GetSetMethod();
                if (setter != null && setter.IsStatic == isStatic)
                {
                    // setup binding to property
                    mType           = otype;
                    mProperty       = property;
                    mPropertySetter = property.GetSetMethod();
                    mField          = null;
                    mPreviousAction = null;
                    mPreviousTarget = null;

                    mArgs[0] = PlayScript.Dynamic.ConvertValue(value, property.PropertyType);
                    mPropertySetter.Invoke(o, mArgs);
                    Stats.Stop(StatsCounter.SetMemberBinder_Resolve_Time);
                    return(value);
                }
            }

            // resolve as field
            // TODO: we allow access to non-public fields for simplicity,
            // should cleanup to check access levels
            var field = otype.GetField(mName, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);

            if (field != null)
            {
                // found field
                if (field.IsStatic == isStatic)
                {
                    // setup binding to field
                    mType           = otype;
                    mProperty       = null;
                    mField          = field;
                    mPreviousAction = null;
                    mPreviousTarget = null;

                    // resolve conversion function
                    object newValue = PlayScript.Dynamic.ConvertValue(value, mField.FieldType);
                    mField.SetValue(o, newValue);
                    Stats.Stop(StatsCounter.SetMemberBinder_Resolve_Time);
                    return(value);
                }
            }

            if (o is IDynamicClass)
            {
                // dynamic class
                mType           = otype;
                mProperty       = null;
                mField          = null;
                mPreviousAction = null;
                mPreviousTarget = null;
                ((IDynamicClass)o).__SetDynamicValue(mName, value);
                Stats.Stop(StatsCounter.SetMemberBinder_Resolve_Time);
                return(value);
            }

            Stats.Stop(StatsCounter.SetMemberBinder_Resolve_Time);

            // failed
            return(default(T));
        }
        /// <summary>
        /// This is the most generic method for getting a member's value.
        /// It will attempt to resolve the member by name and the get its value by invoking the
        /// callsite's delegate
        /// </summary>
        private static T GetMember <T> (CallSite site, object o)
        {
#if BINDERS_RUNTIME_STATS
            Stats.Increment(StatsCounter.GetMemberBinderInvoked);
#endif

            if (o == null)
            {
                return(default(T));
            }

            var binder = (PSGetMemberBinder)site.Binder;

            // resolve as dictionary
            var dict = o as IDictionary <string, object>;
            if (dict != null)
            {
                // special case this for expando objects
                object value;
                if (dict.TryGetValue(binder.name, out value))
                {
                    return(PlayScript.Dynamic.ConvertValue <T>(value));
                }

                // fall through if key not found
            }


            // determine if this is a instance member or a static member
            bool isStatic;
            Type otype;
            if (o is System.Type)
            {
                // static member
                otype    = (System.Type)o;
                o        = null;
                isStatic = true;
            }
            else
            {
                // instance member
                otype    = o.GetType();
                isStatic = false;
            }

            if (otype == binder.type)
            {
                // use cached resolve
                if (binder.property != null)
                {
                    Func <T> func;
                    if (o == binder.previousTarget)
                    {
                        func = (Func <T>)binder.previousFunc;
                    }
                    else
                    {
                        binder.previousFunc   = func = ActionCreator.CreatePropertyGetAction <T>(o, binder.property);
                        binder.previousTarget = o;
                    }
                    return(func());
                }

                if (binder.field != null)
                {
                    return(PlayScript.Dynamic.ConvertValue <T>(binder.field.GetValue(o)));
                }

                if (binder.method != null)
                {
                    // construct method delegate
                    return(PlayScript.Dynamic.ConvertValue <T>(Delegate.CreateDelegate(PlayScript.Dynamic.GetDelegateTypeForMethod(binder.method), o, binder.method)));
                }

                // resolve as dynamic class
                var dc = o as IDynamicClass;
                if (dc != null)
                {
                    object result = dc.__GetDynamicValue(binder.name);
                    return(PlayScript.Dynamic.ConvertValue <T>(result));
                }

                throw new System.InvalidOperationException("Unhandled member type in PSGetMemberBinder");
            }

            // resolve name

#if BINDERS_RUNTIME_STATS
            Stats.Increment(StatsCounter.GetMemberBinder_Resolve_Invoked);
#endif

            // resolve as property
            var property = otype.GetProperty(binder.name);
            if (property != null)
            {
                // found property
                var getter = property.GetGetMethod();
                if (getter != null && getter.IsPublic && getter.IsStatic == isStatic)
                {
                    // setup binding to property
                    binder.type     = otype;
                    binder.property = property;
                    binder.field    = null;
                    binder.method   = null;
                    return(PlayScript.Dynamic.ConvertValue <T>(property.GetValue(o, null)));
                }
            }

            // resolve as field
            var field = otype.GetField(binder.name);
            if (field != null)
            {
                // found field
                if (field.IsPublic && field.IsStatic == isStatic)
                {
                    // setup binding to field
                    binder.type     = otype;
                    binder.property = null;
                    binder.field    = field;
                    binder.method   = null;
                    return(PlayScript.Dynamic.ConvertValue <T>(field.GetValue(o)));
                }
            }

            // resolve as method
            BindingFlags flags = BindingFlags.NonPublic | BindingFlags.Public;
            if (isStatic)
            {
                flags |= BindingFlags.Static;
            }
            else
            {
                flags |= BindingFlags.Instance;
            }
            var method = otype.GetMethod(binder.name, flags);
            if (method != null)
            {
                // setup binding to method
                binder.type     = otype;
                binder.property = null;
                binder.field    = null;
                binder.method   = method;
                // construct method delegate
                return(PlayScript.Dynamic.ConvertValue <T>(Delegate.CreateDelegate(PlayScript.Dynamic.GetDelegateTypeForMethod(binder.method), o, binder.method)));
            }

            if (o is IDynamicClass)
            {
                // dynamic class
                binder.type     = otype;
                binder.property = null;
                binder.field    = null;
                binder.method   = null;
                object result = ((IDynamicClass)o).__GetDynamicValue(binder.name);
                return(PlayScript.Dynamic.ConvertValue <T>(result));
            }

            // could not resolve name as property or field, and is not dynamic class or dictionary
            // invoke callback
            if (Binder.OnGetMemberError != null)
            {
                return(PlayScript.Dynamic.ConvertValue <T>(Binder.OnGetMemberError(o, binder.name, null)));
            }
            else
            {
                return(default(T));
            }
        }
        /// <summary>
        /// Invokes the method on o (potentially using a previous invoker as a hint).
        ///
        /// Note that this method works if the parameters haven been boxed, return value is also boxed.
        /// </summary>
        /// <param name="invoker">The previous invoker as a hint, null if we could not get the invoker during the fast path.</param>
        /// <param name="o">The target of the invocation.</param>
        private object ResolveAndInvoke(object o, bool invokeOnly)
        {
            // Property and same target, or same type has already been checked earlier (by the fast path)
            // So here we have a new target type, we have an overloading, or this is the first time
            // Parameters have been boxed and stored in mArgs already.

            // Note that if we are overloading, we still do a full CreateDelegate work, even if we had the same type, target and method...
            // This is slow, however it should pretty much never happen in game code.

            if ((mInvoker == null) && (invokeOnly == false))
            {
                // It means that we did not get the invoker from the fast path (overloaded - rare - or it is the first time - very common).
                var dc = o as IDynamicClass;
                if (dc != null)
                {
                    object value;
                    if (dc.__TryGetDynamicValue(mName, out value) && value is Delegate)
                    {
                        var func = value as Delegate;
                        // Assume that most time, it is due to the first execution, so don't compare with previous version
                        mInvoker   = ActionCreator.CreateInvoker(func);                         // This is going to use an invoker factory (can be registered by user too for more optimal code).
                        invokeOnly = true;
                    }
                }
            }
            if (invokeOnly)
            {
                Stats.Increment(StatsCounter.InvokeMemberBinderInvoked_Slow);

                return(mInvoker.SafeInvokeWith(mArgs));
            }

            // If we reached this point, we have to do a new resolve, then invoke

            // determine object type
            Type otype;
            bool isStatic;

            if (o is Type)
            {
                // this is a static method invocation where o is the class
                otype    = (Type)o;
                isStatic = true;
            }
            else
            {
                // this is a instance method invocation
                otype    = o.GetType();
                isStatic = false;
            }

            // see if type has changed
            if (otype != mType)
            {
                // re-resolve method list if type has changed
                mType = otype;

                // get method list for type and method name
                BindingFlags flags = BindingFlags.NonPublic | BindingFlags.Public;
                if (isStatic)
                {
                    flags |= BindingFlags.Static;
                }
                else
                {
                    flags |= BindingFlags.Instance;
                }

                mMethodList = MethodBinder.LookupMethodList(mType, mName, flags, mArgs.Length);

                // select new method to use, this will try to reuse
                mInvoker = SelectMethod(o);
            }
            else if (mOverloadState == OverloadState.HasOverload)
            {
                // if there are overloads we select the method every time
                // we could look into a more optimal way of doing this if it becomes a problem
                mInvoker = SelectMethod(o);
            }
            else
            {
                // Same instance type, no overload, so should be the same method (or none).
                // We might be able to update the invoker if only the target changed
                mInvoker = InvokerBase.UpdateOrCreate(mInvoker, o, mMethod.Method);
            }

            Stats.Increment(StatsCounter.InvokeMemberBinderInvoked_Slow);

            TypeLogger.LogType(o);

            return(mInvoker.SafeInvokeWith(mArgs));
        }
Exemple #23
0
 /// <summary>
 /// Convenience method for Actions.Add(ActionCreator.Sequential(action))
 /// </summary>
 protected void Seq(Action action)
 {
     Actions.Add(ActionCreator.Sequential(action));
 }