/// <summary> /// Gets a "meta" operation on this userdata. If a descriptor does not support this functionality, /// it should return "null" (not a nil). /// See <see cref="IUserDataDescriptor.MetaIndex" /> for further details. /// /// If a method exists marked with <see cref="MoonSharpUserDataMetamethodAttribute" /> for the specific /// metamethod requested, that method is returned. /// /// If the above fails, the following dispatching occur: /// /// __add, __sub, __mul, __div, __mod and __unm are dispatched to C# operator overloads (if they exist) /// __eq is dispatched to System.Object.Equals. /// __lt and __le are dispatched IComparable.Compare, if the type implements IComparable or IComparable{object} /// __len is dispatched to Length and Count properties, if those exist. /// __iterator is handled if the object implements IEnumerable or IEnumerator. /// __tonumber is dispatched to implicit or explicit conversion operators to standard numeric types. /// __tobool is dispatched to an implicit or explicit conversion operator to bool. If that fails, operator true is used. /// /// <param name="script">The script originating the request</param> /// <param name="obj">The object (null if a static request is done)</param> /// <param name="metaname">The name of the metamember.</param> /// </summary> /// <returns></returns> public virtual DynValue MetaIndex(Script script, object obj, string metaname) { StandardUserDataOverloadedMethodDescriptor desc = m_MetaMethods.GetOrDefault(metaname); if (desc != null) { return(desc.GetCallbackAsDynValue(script, obj)); } switch (metaname) { case "__add": return(DispatchMetaOnMethod(script, obj, "op_Addition")); case "__sub": return(DispatchMetaOnMethod(script, obj, "op_Subtraction")); case "__mul": return(DispatchMetaOnMethod(script, obj, "op_Multiply")); case "__div": return(DispatchMetaOnMethod(script, obj, "op_Division")); case "__mod": return(DispatchMetaOnMethod(script, obj, "op_Modulus")); case "__unm": return(DispatchMetaOnMethod(script, obj, "op_UnaryNegation")); case "__eq": return(MultiDispatchEqual(script, obj)); case "__lt": return(MultiDispatchLessThan(script, obj)); case "__le": return(MultiDispatchLessThanOrEqual(script, obj)); case "__len": return(TryDispatchLength(script, obj)); case "__tonumber": return(TryDispatchToNumber(script, obj)); case "__tobool": return(TryDispatchToBool(script, obj)); case "__iterator": return(ClrToScriptConversions.EnumerationToDynValue(script, obj)); default: return(null); } }
private DynValue DispatchMetaOnMethod(Script script, object obj, string methodName) { StandardUserDataOverloadedMethodDescriptor desc = m_Methods.GetOrDefault(methodName); if (desc != null) { return(desc.GetCallbackAsDynValue(script, obj)); } else { return(null); } }