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()); }
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(); }
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; }
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); }
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(); }
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)); }
/// <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); } }
/// <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)); }
/// <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>()); }
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)); }
/// <summary> /// Convenience method for Actions.Add(ActionCreator.Sequential(action)) /// </summary> protected void Seq(Action action) { Actions.Add(ActionCreator.Sequential(action)); }