/*
* __newindex metafunction of CLR objects. Receives the object,
* the member name and the value to be stored as arguments. Throws
* and error if the assignment is invalid.
*/
private int setFieldOrProperty(KopiLua.Lua.lua_State luaState)
{
object target = translator.getRawNetObject(luaState, 1);
if (target == null)
{
translator.throwError(luaState, "trying to index and invalid object reference");
return(0);
}
Type type = target.GetType();
// First try to look up the parameter as a property name
string detailMessage;
bool didMember = trySetMember(luaState, type, target, BindingFlags.Instance | BindingFlags.IgnoreCase, out detailMessage);
if (didMember)
{
return(0); // Must have found the property name
}
// We didn't find a property name, now see if we can use a [] style this accessor to set array contents
try
{
if (type.IsArray && LuaDLL.lua_isnumber(luaState, 2))
{
int index = (int)LuaDLL.lua_tonumber(luaState, 2);
Array arr = (Array)target;
object val = translator.getAsType(luaState, 3, arr.GetType().GetElementType());
arr.SetValue(val, index);
}
else
{
// Try to see if we have a this[] accessor
MethodInfo setter = type.GetMethod("set_Item");
if (setter != null)
{
ParameterInfo[] args = setter.GetParameters();
Type valueType = args[1].ParameterType;
// The new val ue the user specified
object val = translator.getAsType(luaState, 3, valueType);
Type indexType = args[0].ParameterType;
object index = translator.getAsType(luaState, 2, indexType);
object[] methodArgs = new object[2];
// Just call the indexer - if out of bounds an exception will happen
methodArgs[0] = index;
methodArgs[1] = val;
setter.Invoke(target, methodArgs);
}
else
{
translator.throwError(luaState, detailMessage); // Pass the original message from trySetMember because it is probably best
}
}
}
catch (SEHException)
{
// If we are seeing a C++ exception - this must actually be for Lua's private use. Let it handle it
throw;
}
catch (Exception e)
{
ThrowError(luaState, e);
}
return(0);
}