From a14437ad5abf4d4dc95897216224548515a599e7 Mon Sep 17 00:00:00 2001 From: Mic Bowman Date: Sat, 24 Mar 2012 22:43:42 -0700 Subject: Add support for key, vector, rotation and list types for both arguments and return values to the modInvoke family of functions. See http://opensimulator.org/wiki/OSSL_Script_Library/ModInvoke --- .../Shared/Api/Implementation/MOD_Api.cs | 245 ++++++++++++++++----- .../ScriptEngine/Shared/Api/Interface/IMOD_Api.cs | 24 +- .../ScriptEngine/Shared/Api/Runtime/MOD_Stub.cs | 34 ++- 3 files changed, 229 insertions(+), 74 deletions(-) (limited to 'OpenSim/Region/ScriptEngine/Shared') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs index 2942104..1bcbcd3 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs @@ -120,33 +120,101 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api /// /// /// The name of the function to invoke - /// List of parameters + /// List of parameters /// string result of the invocation - public string modInvokeS(string fname, params object[] parms) + public LSL_String modInvokeS(string fname, params object[] parms) { Type returntype = m_comms.LookupReturnType(fname); if (returntype != typeof(string)) MODError(String.Format("return type mismatch for {0}",fname)); - return (string)modInvoke(fname,parms); + string result = (string)modInvoke(fname,parms); + return new LSL_String(result); } - public int modInvokeI(string fname, params object[] parms) + public LSL_Integer modInvokeI(string fname, params object[] parms) { Type returntype = m_comms.LookupReturnType(fname); if (returntype != typeof(int)) MODError(String.Format("return type mismatch for {0}",fname)); - return (int)modInvoke(fname,parms); + int result = (int)modInvoke(fname,parms); + return new LSL_Integer(result); } - public float modInvokeF(string fname, params object[] parms) + public LSL_Float modInvokeF(string fname, params object[] parms) { Type returntype = m_comms.LookupReturnType(fname); if (returntype != typeof(float)) MODError(String.Format("return type mismatch for {0}",fname)); - return (float)modInvoke(fname,parms); + float result = (float)modInvoke(fname,parms); + return new LSL_Float(result); + } + + public LSL_Key modInvokeK(string fname, params object[] parms) + { + Type returntype = m_comms.LookupReturnType(fname); + if (returntype != typeof(UUID)) + MODError(String.Format("return type mismatch for {0}",fname)); + + UUID result = (UUID)modInvoke(fname,parms); + return new LSL_Key(result.ToString()); + } + + public LSL_Vector modInvokeV(string fname, params object[] parms) + { + Type returntype = m_comms.LookupReturnType(fname); + if (returntype != typeof(OpenMetaverse.Vector3)) + MODError(String.Format("return type mismatch for {0}",fname)); + + OpenMetaverse.Vector3 result = (OpenMetaverse.Vector3)modInvoke(fname,parms); + return new LSL_Vector(result.X,result.Y,result.Z); + } + + public LSL_Rotation modInvokeR(string fname, params object[] parms) + { + Type returntype = m_comms.LookupReturnType(fname); + if (returntype != typeof(OpenMetaverse.Quaternion)) + MODError(String.Format("return type mismatch for {0}",fname)); + + OpenMetaverse.Quaternion result = (OpenMetaverse.Quaternion)modInvoke(fname,parms); + return new LSL_Rotation(result.X,result.Y,result.Z,result.W); + } + + public LSL_List modInvokeL(string fname, params object[] parms) + { + Type returntype = m_comms.LookupReturnType(fname); + if (returntype != typeof(object[])) + MODError(String.Format("return type mismatch for {0}",fname)); + + object[] result = (object[])modInvoke(fname,parms); + object[] llist = new object[result.Length]; + for (int i = 0; i < result.Length; i++) + { + if (result[i] is string) + llist[i] = new LSL_String((string)result[i]); + else if (result[i] is int) + llist[i] = new LSL_Integer((int)result[i]); + else if (result[i] is float) + llist[i] = new LSL_Float((float)result[i]); + else if (result[i] is OpenMetaverse.Vector3) + { + OpenMetaverse.Vector3 vresult = (OpenMetaverse.Vector3)result[i]; + llist[i] = new LSL_Vector(vresult.X,vresult.Y,vresult.Z); + } + else if (result[i] is OpenMetaverse.Quaternion) + { + OpenMetaverse.Quaternion qresult = (OpenMetaverse.Quaternion)result[i]; + llist[i] = new LSL_Rotation(qresult.X,qresult.Y,qresult.Z,qresult.W); + } + else + { + MODError(String.Format("unknown list element returned by {0}",fname)); + } + } + + return new LSL_List(llist); } /// @@ -168,63 +236,30 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api MODError(String.Format("wrong number of parameters to function {0}",fname)); object[] convertedParms = new object[parms.Length]; - for (int i = 0; i < parms.Length; i++) - { - if (parms[i] is LSL_String) - { - if (signature[i] != typeof(string)) - MODError(String.Format("parameter type mismatch in {0}; expecting {1}",fname,signature[i].Name)); - - convertedParms[i] = (string)(LSL_String)parms[i]; - } - else if (parms[i] is LSL_Integer) - { - if (signature[i] != typeof(int)) - MODError(String.Format("parameter type mismatch in {0}; expecting {1}",fname,signature[i].Name)); - - convertedParms[i] = (int)(LSL_Integer)parms[i]; - } - else if (parms[i] is LSL_Float) - { - if (signature[i] != typeof(float)) - MODError(String.Format("parameter type mismatch in {0}; expecting {1}",fname,signature[i].Name)); - - convertedParms[i] = (float)(LSL_Float)parms[i]; - } - else if (parms[i] is LSL_Key) - { - if (signature[i] != typeof(string)) - MODError(String.Format("parameter type mismatch in {0}; expecting {1}",fname,signature[i].Name)); - - convertedParms[i] = (string)(LSL_Key)parms[i]; - } - else if (parms[i] is LSL_Rotation) - { - if (signature[i] != typeof(string)) - MODError(String.Format("parameter type mismatch in {0}; expecting {1}",fname,signature[i].Name)); - - convertedParms[i] = (string)(LSL_Rotation)parms[i]; - } - else if (parms[i] is LSL_Vector) - { - if (signature[i] != typeof(string)) - MODError(String.Format("parameter type mismatch in {0}; expecting {1}",fname,signature[i].Name)); + convertedParms[i] = ConvertFromLSL(parms[i],signature[i]); - convertedParms[i] = (string)(LSL_Vector)parms[i]; - } - else - { - if (signature[i] != parms[i].GetType()) - MODError(String.Format("parameter type mismatch in {0}; expecting {1}",fname,signature[i].Name)); + // now call the function, the contract with the function is that it will always return + // non-null but don't trust it completely + try + { + object result = m_comms.InvokeOperation(m_itemID,fname,convertedParms); + if (result != null) + return result; - convertedParms[i] = parms[i]; - } + MODError(String.Format("Invocation of {0} failed; null return value",fname)); + } + catch (Exception e) + { + MODError(String.Format("Invocation of {0} failed; {1}",fname,e.Message)); } - return m_comms.InvokeOperation(m_itemID,fname,convertedParms); + return null; } + /// + /// Send a command to functions registered on an event + /// public string modSendCommand(string module, string command, string k) { if (!m_MODFunctionsEnabled) @@ -239,5 +274,101 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return req.ToString(); } + + /// + /// + protected object ConvertFromLSL(object lslparm, Type type) + { + // ---------- String ---------- + if (lslparm is LSL_String) + { + if (type == typeof(string)) + return (string)(LSL_String)lslparm; + + // Need to check for UUID since keys are often treated as strings + if (type == typeof(UUID)) + return new UUID((string)(LSL_String)lslparm); + } + + // ---------- Integer ---------- + else if (lslparm is LSL_Integer) + { + if (type == typeof(int)) + return (int)(LSL_Integer)lslparm; + } + + // ---------- Float ---------- + else if (lslparm is LSL_Float) + { + if (type == typeof(float)) + return (float)(LSL_Float)lslparm; + } + + // ---------- Key ---------- + else if (lslparm is LSL_Key) + { + if (type == typeof(UUID)) + return new UUID((LSL_Key)lslparm); + } + + // ---------- Rotation ---------- + else if (lslparm is LSL_Rotation) + { + if (type == typeof(OpenMetaverse.Quaternion)) + { + LSL_Rotation rot = (LSL_Rotation)lslparm; + return new OpenMetaverse.Quaternion((float)rot.x,(float)rot.y,(float)rot.z,(float)rot.s); + } + } + + // ---------- Vector ---------- + else if (lslparm is LSL_Vector) + { + if (type == typeof(OpenMetaverse.Vector3)) + { + LSL_Vector vect = (LSL_Vector)lslparm; + return new OpenMetaverse.Vector3((float)vect.x,(float)vect.y,(float)vect.z); + } + } + + // ---------- List ---------- + else if (lslparm is LSL_List) + { + if (type == typeof(object[])) + { + object[] plist = (lslparm as LSL_List).Data; + object[] result = new object[plist.Length]; + for (int i = 0; i < plist.Length; i++) + { + if (plist[i] is LSL_String) + result[i] = (string)(LSL_String)plist[i]; + else if (plist[i] is LSL_Integer) + result[i] = (int)(LSL_Integer)plist[i]; + else if (plist[i] is LSL_Float) + result[i] = (float)(LSL_Float)plist[i]; + else if (plist[i] is LSL_Key) + result[i] = new UUID((LSL_Key)plist[i]); + else if (plist[i] is LSL_Rotation) + { + LSL_Rotation rot = (LSL_Rotation)plist[i]; + result[i] = new OpenMetaverse.Quaternion((float)rot.x,(float)rot.y,(float)rot.z,(float)rot.s); + } + else if (plist[i] is LSL_Vector) + { + LSL_Vector vect = (LSL_Vector)plist[i]; + result[i] = new OpenMetaverse.Vector3((float)vect.x,(float)vect.y,(float)vect.z); + } + else + MODError("unknown LSL list element type"); + } + + return result; + } + } + + MODError(String.Format("parameter type mismatch; expecting {0}",type.Name)); + return null; + } + } } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IMOD_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IMOD_Api.cs index 756a59f..d258f76 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IMOD_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IMOD_Api.cs @@ -28,26 +28,26 @@ using System.Collections; using OpenSim.Region.ScriptEngine.Interfaces; -using key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; -using rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion; -using vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; +using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat; +using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger; +using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list; +using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion; using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; -using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger; -using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat; +using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces { public interface IMOD_Api { // Invocation functions - string modInvokeS(string fname, params object[] parms); - int modInvokeI(string fname, params object[] parms); - float modInvokeF(string fname, params object[] parms); - // vector modInvokeV(string fname, params object[] parms); - // rotation modInvokeV(string fname, params object[] parms); - // key modInvokeK(string fname, params object[] parms); - // list modInvokeL(string fname, params object[] parms); + LSL_String modInvokeS(string fname, params object[] parms); + LSL_Integer modInvokeI(string fname, params object[] parms); + LSL_Float modInvokeF(string fname, params object[] parms); + LSL_Key modInvokeK(string fname, params object[] parms); + LSL_Vector modInvokeV(string fname, params object[] parms); + LSL_Rotation modInvokeR(string fname, params object[] parms); + LSL_List modInvokeL(string fname, params object[] parms); //Module functions string modSendCommand(string modules, string command, string k); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/MOD_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/MOD_Stub.cs index 04b7f14..e7a4b2b 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/MOD_Stub.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/MOD_Stub.cs @@ -39,10 +39,14 @@ using integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger; using vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; using rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion; using key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; -using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list; -using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; + using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat; using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger; +using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; +using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list; +using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion; +using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; +using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase { @@ -58,21 +62,41 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase m_MOD_Functions = (IMOD_Api)api; } - public string modInvokeS(string fname, params object[] parms) + public LSL_String modInvokeS(string fname, params object[] parms) { return m_MOD_Functions.modInvokeS(fname, parms); } - public int modInvokeI(string fname, params object[] parms) + public LSL_Integer modInvokeI(string fname, params object[] parms) { return m_MOD_Functions.modInvokeI(fname, parms); } - public float modInvokeF(string fname, params object[] parms) + public LSL_Float modInvokeF(string fname, params object[] parms) { return m_MOD_Functions.modInvokeF(fname, parms); } + public LSL_Key modInvokeK(string fname, params object[] parms) + { + return m_MOD_Functions.modInvokeK(fname, parms); + } + + public LSL_Vector modInvokeV(string fname, params object[] parms) + { + return m_MOD_Functions.modInvokeV(fname, parms); + } + + public LSL_Rotation modInvokeR(string fname, params object[] parms) + { + return m_MOD_Functions.modInvokeR(fname, parms); + } + + public LSL_List modInvokeL(string fname, params object[] parms) + { + return m_MOD_Functions.modInvokeL(fname, parms); + } + public string modSendCommand(string module, string command, string k) { return m_MOD_Functions.modSendCommand(module, command, k); -- cgit v1.1