(Untested) Scripts are individually loaded into objects (on rez), and event fired likewise. Bugfixes coming in next commit.
parent
283468caa0
commit
5a86fd2c31
|
@ -183,8 +183,6 @@ namespace OpenSim
|
||||||
|
|
||||||
OpenSim.Region.Environment.Scenes.Scripting.ScriptEngineInterface ScriptEngine = ScriptEngineLoader.LoadScriptEngine("DotNetEngine");
|
OpenSim.Region.Environment.Scenes.Scripting.ScriptEngineInterface ScriptEngine = ScriptEngineLoader.LoadScriptEngine("DotNetEngine");
|
||||||
scene.AddScriptEngine(ScriptEngine, m_log);
|
scene.AddScriptEngine(ScriptEngine, m_log);
|
||||||
// TODO: TEMP load default script
|
|
||||||
ScriptEngine.StartScript(Path.Combine("ScriptEngines", "Default.lsl"), new OpenSim.Region.Environment.Scenes.Scripting.NullScriptHost());
|
|
||||||
|
|
||||||
//Server side object editing permissions checking
|
//Server side object editing permissions checking
|
||||||
if (m_permissions)
|
if (m_permissions)
|
||||||
|
|
|
@ -38,6 +38,6 @@ namespace OpenSim.Region.Environment.Scenes.Scripting
|
||||||
{
|
{
|
||||||
void InitializeEngine(OpenSim.Region.Environment.Scenes.Scene Sceneworld, OpenSim.Framework.Console.LogBase logger);
|
void InitializeEngine(OpenSim.Region.Environment.Scenes.Scene Sceneworld, OpenSim.Framework.Console.LogBase logger);
|
||||||
void Shutdown();
|
void Shutdown();
|
||||||
void StartScript(string ScriptID, IScriptHost ObjectID);
|
// void StartScript(string ScriptID, IScriptHost ObjectID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@ using OpenSim.Region.Environment.Scenes;
|
||||||
using OpenSim.Region.Environment.Scenes.Scripting;
|
using OpenSim.Region.Environment.Scenes.Scripting;
|
||||||
using OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL;
|
using OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL;
|
||||||
using OpenSim.Region.ScriptEngine.Common;
|
using OpenSim.Region.ScriptEngine.Common;
|
||||||
|
using libsecondlife;
|
||||||
|
|
||||||
namespace OpenSim.Region.ScriptEngine.DotNetEngine
|
namespace OpenSim.Region.ScriptEngine.DotNetEngine
|
||||||
{
|
{
|
||||||
|
|
|
@ -13,39 +13,51 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL
|
||||||
{
|
{
|
||||||
private LSL2CSConverter LSL_Converter = new LSL2CSConverter();
|
private LSL2CSConverter LSL_Converter = new LSL2CSConverter();
|
||||||
private CSharpCodeProvider codeProvider = new CSharpCodeProvider();
|
private CSharpCodeProvider codeProvider = new CSharpCodeProvider();
|
||||||
|
private int ScriptCompileCounter = 0;
|
||||||
//private ICodeCompiler icc = codeProvider.CreateCompiler();
|
//private ICodeCompiler icc = codeProvider.CreateCompiler();
|
||||||
public string Compile(string LSOFileName)
|
public string CompileFromFile(string LSOFileName)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
// Output assembly name
|
|
||||||
string OutFile = Path.Combine("ScriptEngines", Path.GetFileNameWithoutExtension(LSOFileName) + ".dll");
|
|
||||||
//string OutFile = Path.Combine("ScriptEngines", "SecondLife.Script.dll");
|
|
||||||
|
|
||||||
Common.SendToDebug("Reading source code into memory");
|
|
||||||
// TODO: Add error handling
|
|
||||||
string CS_Code;
|
string CS_Code;
|
||||||
switch (System.IO.Path.GetExtension(LSOFileName).ToLower())
|
switch (System.IO.Path.GetExtension(LSOFileName).ToLower())
|
||||||
{
|
{
|
||||||
case ".txt":
|
case ".txt":
|
||||||
case ".lsl":
|
case ".lsl":
|
||||||
Common.SendToDebug("Source code is LSL, converting to CS");
|
Common.SendToDebug("Source code is LSL, converting to CS");
|
||||||
CS_Code = LSL_Converter.Convert(File.ReadAllText(LSOFileName));
|
return CompileFromLSLText(File.ReadAllText(LSOFileName));
|
||||||
break;
|
|
||||||
case ".cs":
|
case ".cs":
|
||||||
Common.SendToDebug("Source code is CS");
|
Common.SendToDebug("Source code is CS");
|
||||||
CS_Code = File.ReadAllText(LSOFileName);
|
return CompileFromCSText(File.ReadAllText(LSOFileName));
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
throw new Exception("Unknown script type.");
|
throw new Exception("Unknown script type.");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// Converts script from LSL to CS and calls CompileFromCSText
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="Script">LSL script</param>
|
||||||
|
/// <returns>Filename to .dll assembly</returns>
|
||||||
|
public string CompileFromLSLText(string Script)
|
||||||
|
{
|
||||||
|
return CompileFromCSText(LSL_Converter.Convert(Script));
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// Compile CS script to .Net assembly (.dll)
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="Script">CS script</param>
|
||||||
|
/// <returns>Filename to .dll assembly</returns>
|
||||||
|
public string CompileFromCSText(string Script)
|
||||||
|
{
|
||||||
|
|
||||||
Common.SendToDebug("Compiling");
|
|
||||||
|
// Output assembly name
|
||||||
|
ScriptCompileCounter++;
|
||||||
|
string OutFile = Path.Combine("ScriptEngines", "Script_" + ScriptCompileCounter + ".dll");
|
||||||
|
//string OutFile = Path.Combine("ScriptEngines", "SecondLife.Script.dll");
|
||||||
|
|
||||||
// DEBUG - write source to disk
|
// DEBUG - write source to disk
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
File.WriteAllText(Path.Combine("ScriptEngines", "debug_" + Path.GetFileNameWithoutExtension(LSOFileName) + ".cs"), CS_Code);
|
File.WriteAllText(Path.Combine("ScriptEngines", "debug_" + Path.GetFileNameWithoutExtension(OutFile) + ".cs"), Script);
|
||||||
}
|
}
|
||||||
catch { }
|
catch { }
|
||||||
|
|
||||||
|
@ -68,7 +80,7 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL
|
||||||
//parameters.ReferencedAssemblies.Add("OpenSim.Region.Environment");
|
//parameters.ReferencedAssemblies.Add("OpenSim.Region.Environment");
|
||||||
parameters.GenerateExecutable = false;
|
parameters.GenerateExecutable = false;
|
||||||
parameters.OutputAssembly = OutFile;
|
parameters.OutputAssembly = OutFile;
|
||||||
CompilerResults results = codeProvider.CompileAssemblyFromSource(parameters, CS_Code);
|
CompilerResults results = codeProvider.CompileAssemblyFromSource(parameters, Script);
|
||||||
|
|
||||||
// Go through errors
|
// Go through errors
|
||||||
// TODO: Return errors to user somehow
|
// TODO: Return errors to user somehow
|
||||||
|
|
|
@ -42,7 +42,7 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine
|
||||||
class EventManager
|
class EventManager
|
||||||
{
|
{
|
||||||
private ScriptEngine myScriptEngine;
|
private ScriptEngine myScriptEngine;
|
||||||
public IScriptHost TEMP_OBJECT_ID;
|
//public IScriptHost TEMP_OBJECT_ID;
|
||||||
public EventManager(ScriptEngine _ScriptEngine)
|
public EventManager(ScriptEngine _ScriptEngine)
|
||||||
{
|
{
|
||||||
myScriptEngine = _ScriptEngine;
|
myScriptEngine = _ScriptEngine;
|
||||||
|
@ -51,19 +51,47 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine
|
||||||
// TODO: ADD SERVER HOOK TO LOAD A SCRIPT THROUGH myScriptEngine.ScriptManager
|
// TODO: ADD SERVER HOOK TO LOAD A SCRIPT THROUGH myScriptEngine.ScriptManager
|
||||||
|
|
||||||
// Hook up a test event to our test form
|
// Hook up a test event to our test form
|
||||||
myScriptEngine.Log.Verbose("ScriptEngine", "EventManager Hooking up dummy-event: touch_start");
|
//myScriptEngine.Log.Verbose("ScriptEngine", "EventManager Hooking up to server events");
|
||||||
// TODO: REPLACE THIS WITH A REAL TOUCH_START EVENT IN SERVER
|
|
||||||
myScriptEngine.World.EventManager.OnObjectGrab += new OpenSim.Region.Environment.Scenes.EventManager.ObjectGrabDelegate(touch_start);
|
myScriptEngine.World.EventManager.OnObjectGrab += new OpenSim.Region.Environment.Scenes.EventManager.ObjectGrabDelegate(touch_start);
|
||||||
//myScriptEngine.World.touch_start += new TempWorldInterfaceEventDelegates.touch_start(touch_start);
|
myScriptEngine.World.EventManager.OnRezScript += new OpenSim.Region.Environment.Scenes.EventManager.NewRezScript(OnRezScript);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void touch_start(uint localID, LLVector3 offsetPos, IClientAPI remoteClient)
|
public void touch_start(uint localID, LLVector3 offsetPos, IClientAPI remoteClient)
|
||||||
{
|
{
|
||||||
// Add to queue for all scripts in ObjectID object
|
// Add to queue for all scripts in ObjectID object
|
||||||
//myScriptEngine.m_logger.Verbose("ScriptEngine", "EventManager Event: touch_start");
|
//myScriptEngine.m_logger.Verbose("ScriptEngine", "EventManager Event: touch_start");
|
||||||
myScriptEngine.myEventQueueManager.AddToObjectQueue(TEMP_OBJECT_ID, "touch_start", new object[] { (int)0 });
|
myScriptEngine.myEventQueueManager.AddToObjectQueue(localID, "touch_start", new object[] { (int)1 });
|
||||||
}
|
}
|
||||||
|
public void OnRezScript(uint localID, LLUUID itemID, string script)
|
||||||
|
{
|
||||||
|
// TODO: Add code to compile script and wire up script to object
|
||||||
|
// Either the script is a stand-alone entity with a reference to public host,
|
||||||
|
// Or the host has a reference to the script because it was in its inventory.
|
||||||
|
|
||||||
|
//myScriptEngine.myScriptManager.StartScript(
|
||||||
|
// Path.Combine("ScriptEngines", "Default.lsl"),
|
||||||
|
// new OpenSim.Region.Environment.Scenes.Scripting.NullScriptHost()
|
||||||
|
//);
|
||||||
|
myScriptEngine.myScriptManager.StartScript(
|
||||||
|
localID,
|
||||||
|
itemID,
|
||||||
|
script
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
public void OnDeRezScript(uint localID, LLUUID itemID)
|
||||||
|
{
|
||||||
|
//myScriptEngine.myScriptManager.StartScript(
|
||||||
|
// Path.Combine("ScriptEngines", "Default.lsl"),
|
||||||
|
// new OpenSim.Region.Environment.Scenes.Scripting.NullScriptHost()
|
||||||
|
//);
|
||||||
|
myScriptEngine.myScriptManager.StopScript(
|
||||||
|
localID,
|
||||||
|
itemID
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: Replace placeholders below
|
// TODO: Replace placeholders below
|
||||||
// These needs to be hooked up to OpenSim during init of this class
|
// These needs to be hooked up to OpenSim during init of this class
|
||||||
|
|
|
@ -32,6 +32,7 @@ using System.Text;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using OpenSim.Region.Environment.Scenes.Scripting;
|
using OpenSim.Region.Environment.Scenes.Scripting;
|
||||||
|
using libsecondlife;
|
||||||
|
|
||||||
namespace OpenSim.Region.ScriptEngine.DotNetEngine
|
namespace OpenSim.Region.ScriptEngine.DotNetEngine
|
||||||
{
|
{
|
||||||
|
@ -64,16 +65,16 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private struct QueueItemStruct
|
private struct QueueItemStruct
|
||||||
{
|
{
|
||||||
public IScriptHost ObjectID;
|
public uint localID;
|
||||||
public string ScriptID;
|
public LLUUID itemID;
|
||||||
public string FunctionName;
|
public string FunctionName;
|
||||||
public object[] param;
|
public object[] param;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// List of ObjectID locks for mutex processing of script events
|
/// List of localID locks for mutex processing of script events
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private List<IScriptHost> ObjectLocks = new List<IScriptHost>();
|
private List<uint> ObjectLocks = new List<uint>();
|
||||||
private object TryLockLock = new object(); // Mutex lock object
|
private object TryLockLock = new object(); // Mutex lock object
|
||||||
|
|
||||||
private ScriptEngine myScriptEngine;
|
private ScriptEngine myScriptEngine;
|
||||||
|
@ -140,7 +141,7 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Something in queue, process
|
// Something in queue, process
|
||||||
//myScriptEngine.m_logger.Verbose("ScriptEngine", "Processing event for ObjectID: " + QIS.ObjectID + ", ScriptID: " + QIS.ScriptID + ", FunctionName: " + QIS.FunctionName);
|
//myScriptEngine.m_logger.Verbose("ScriptEngine", "Processing event for localID: " + QIS.localID + ", itemID: " + QIS.itemID + ", FunctionName: " + QIS.FunctionName);
|
||||||
|
|
||||||
// OBJECT BASED LOCK - TWO THREADS WORKING ON SAME OBJECT IS NOT GOOD
|
// OBJECT BASED LOCK - TWO THREADS WORKING ON SAME OBJECT IS NOT GOOD
|
||||||
lock (QueueLock)
|
lock (QueueLock)
|
||||||
|
@ -152,7 +153,7 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine
|
||||||
QIS = EventQueue.Dequeue();
|
QIS = EventQueue.Dequeue();
|
||||||
|
|
||||||
// Check if object is being processed by someone else
|
// Check if object is being processed by someone else
|
||||||
if (TryLock(QIS.ObjectID) == false)
|
if (TryLock(QIS.localID) == false)
|
||||||
{
|
{
|
||||||
// Object is already being processed, requeue it
|
// Object is already being processed, requeue it
|
||||||
EventQueue.Enqueue(QIS);
|
EventQueue.Enqueue(QIS);
|
||||||
|
@ -169,8 +170,14 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine
|
||||||
if (GotItem == true)
|
if (GotItem == true)
|
||||||
{
|
{
|
||||||
// Execute function
|
// Execute function
|
||||||
myScriptEngine.myScriptManager.ExecuteEvent(QIS.ObjectID, QIS.ScriptID, QIS.FunctionName, QIS.param);
|
try
|
||||||
ReleaseLock(QIS.ObjectID);
|
{
|
||||||
|
myScriptEngine.myScriptManager.ExecuteEvent(QIS.localID, QIS.itemID, QIS.FunctionName, QIS.param);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
ReleaseLock(QIS.localID);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // Something in queue
|
} // Something in queue
|
||||||
|
@ -183,37 +190,37 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Try to get a mutex lock on ObjectID
|
/// Try to get a mutex lock on localID
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="ObjectID"></param>
|
/// <param name="localID"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
private bool TryLock(IScriptHost ObjectID)
|
private bool TryLock(uint localID)
|
||||||
{
|
{
|
||||||
lock (TryLockLock)
|
lock (TryLockLock)
|
||||||
{
|
{
|
||||||
if (ObjectLocks.Contains(ObjectID) == true)
|
if (ObjectLocks.Contains(localID) == true)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ObjectLocks.Add(ObjectID);
|
ObjectLocks.Add(localID);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Release mutex lock on ObjectID
|
/// Release mutex lock on localID
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="ObjectID"></param>
|
/// <param name="localID"></param>
|
||||||
private void ReleaseLock(IScriptHost ObjectID)
|
private void ReleaseLock(uint localID)
|
||||||
{
|
{
|
||||||
lock (TryLockLock)
|
lock (TryLockLock)
|
||||||
{
|
{
|
||||||
if (ObjectLocks.Contains(ObjectID) == true)
|
if (ObjectLocks.Contains(localID) == true)
|
||||||
{
|
{
|
||||||
ObjectLocks.Remove(ObjectID);
|
ObjectLocks.Remove(localID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -221,26 +228,26 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Add event to event execution queue
|
/// Add event to event execution queue
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="ObjectID"></param>
|
/// <param name="localID"></param>
|
||||||
/// <param name="FunctionName">Name of the function, will be state + "_event_" + FunctionName</param>
|
/// <param name="FunctionName">Name of the function, will be state + "_event_" + FunctionName</param>
|
||||||
/// <param name="param">Array of parameters to match event mask</param>
|
/// <param name="param">Array of parameters to match event mask</param>
|
||||||
public void AddToObjectQueue(IScriptHost ObjectID, string FunctionName, object[] param)
|
public void AddToObjectQueue(uint localID, string FunctionName, object[] param)
|
||||||
{
|
{
|
||||||
// Determine all scripts in Object and add to their queue
|
// Determine all scripts in Object and add to their queue
|
||||||
//myScriptEngine.m_logger.Verbose("ScriptEngine", "EventQueueManager Adding ObjectID: " + ObjectID + ", FunctionName: " + FunctionName);
|
//myScriptEngine.m_logger.Verbose("ScriptEngine", "EventQueueManager Adding localID: " + localID + ", FunctionName: " + FunctionName);
|
||||||
|
|
||||||
lock (QueueLock)
|
lock (QueueLock)
|
||||||
{
|
{
|
||||||
|
|
||||||
foreach (string ScriptID in myScriptEngine.myScriptManager.GetScriptKeys(ObjectID))
|
foreach (LLUUID itemID in myScriptEngine.myScriptManager.GetScriptKeys(localID))
|
||||||
{
|
{
|
||||||
// Add to each script in that object
|
// Add to each script in that object
|
||||||
// TODO: Some scripts may not subscribe to this event. Should we NOT add it? Does it matter?
|
// TODO: Some scripts may not subscribe to this event. Should we NOT add it? Does it matter?
|
||||||
|
|
||||||
// Create a structure and add data
|
// Create a structure and add data
|
||||||
QueueItemStruct QIS = new QueueItemStruct();
|
QueueItemStruct QIS = new QueueItemStruct();
|
||||||
QIS.ObjectID = ObjectID;
|
QIS.localID = localID;
|
||||||
QIS.ScriptID = ScriptID;
|
QIS.itemID = itemID;
|
||||||
QIS.FunctionName = FunctionName;
|
QIS.FunctionName = FunctionName;
|
||||||
QIS.param = param;
|
QIS.param = param;
|
||||||
|
|
||||||
|
|
|
@ -64,9 +64,12 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine
|
||||||
|
|
||||||
public void InitializeEngine(OpenSim.Region.Environment.Scenes.Scene Sceneworld, OpenSim.Framework.Console.LogBase logger)
|
public void InitializeEngine(OpenSim.Region.Environment.Scenes.Scene Sceneworld, OpenSim.Framework.Console.LogBase logger)
|
||||||
{
|
{
|
||||||
|
|
||||||
World = Sceneworld;
|
World = Sceneworld;
|
||||||
m_log = logger;
|
m_log = logger;
|
||||||
|
|
||||||
|
Log.Verbose("ScriptEngine", "DotNet & LSL ScriptEngine initializing");
|
||||||
|
|
||||||
//m_logger.Status("ScriptEngine", "InitializeEngine");
|
//m_logger.Status("ScriptEngine", "InitializeEngine");
|
||||||
|
|
||||||
// Create all objects we'll be using
|
// Create all objects we'll be using
|
||||||
|
@ -78,30 +81,21 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine
|
||||||
// Should we iterate the region for scripts that needs starting?
|
// Should we iterate the region for scripts that needs starting?
|
||||||
// Or can we assume we are loaded before anything else so we can use proper events?
|
// Or can we assume we are loaded before anything else so we can use proper events?
|
||||||
|
|
||||||
// Event hook for when scripts are dragged to script inventory
|
|
||||||
World.EventManager.OnRezScript += NewRezScriptHandler;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void NewRezScriptHandler(uint localID, LLUUID itemID, string script)
|
|
||||||
{
|
|
||||||
// TODO: Add code to compile script and wire up script to object
|
|
||||||
// Either the script is a stand-alone entity with a reference to public host,
|
|
||||||
// Or the host has a reference to the script because it was in its inventory.
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Shutdown()
|
public void Shutdown()
|
||||||
{
|
{
|
||||||
// We are shutting down
|
// We are shutting down
|
||||||
}
|
}
|
||||||
|
|
||||||
// !!!FOR DEBUGGING ONLY!!! (for executing script directly from test app)
|
//// !!!FOR DEBUGGING ONLY!!! (for executing script directly from test app)
|
||||||
[Obsolete("!!!FOR DEBUGGING ONLY!!!")]
|
//[Obsolete("!!!FOR DEBUGGING ONLY!!!")]
|
||||||
public void StartScript(string ScriptID, IScriptHost ObjectID)
|
//public void StartScript(string ScriptID, IScriptHost ObjectID)
|
||||||
{
|
//{
|
||||||
this.myEventManager.TEMP_OBJECT_ID = ObjectID;
|
// this.myEventManager.TEMP_OBJECT_ID = ObjectID;
|
||||||
Log.Status("ScriptEngine", "DEBUG FUNCTION: StartScript: " + ScriptID);
|
// Log.Status("ScriptEngine", "DEBUG FUNCTION: StartScript: " + ScriptID);
|
||||||
myScriptManager.StartScript(ScriptID, ObjectID);
|
// myScriptManager.StartScript(ScriptID, ObjectID);
|
||||||
}
|
//}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,6 +37,7 @@ using OpenSim.Region.Environment.Scenes.Scripting;
|
||||||
using OpenSim.Region.ScriptEngine.DotNetEngine.Compiler;
|
using OpenSim.Region.ScriptEngine.DotNetEngine.Compiler;
|
||||||
using OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL;
|
using OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL;
|
||||||
using OpenSim.Region.ScriptEngine.Common;
|
using OpenSim.Region.ScriptEngine.Common;
|
||||||
|
using libsecondlife;
|
||||||
|
|
||||||
namespace OpenSim.Region.ScriptEngine.DotNetEngine
|
namespace OpenSim.Region.ScriptEngine.DotNetEngine
|
||||||
{
|
{
|
||||||
|
@ -53,7 +54,6 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine
|
||||||
public ScriptManager(ScriptEngine scriptEngine)
|
public ScriptManager(ScriptEngine scriptEngine)
|
||||||
{
|
{
|
||||||
m_scriptEngine = scriptEngine;
|
m_scriptEngine = scriptEngine;
|
||||||
m_scriptEngine.Log.Verbose("ScriptEngine", "ScriptManager Start");
|
|
||||||
AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
|
AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,7 +69,7 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine
|
||||||
// Object<string, Script<string, script>>
|
// Object<string, Script<string, script>>
|
||||||
// IMPORTANT: Types and MemberInfo-derived objects require a LOT of memory.
|
// IMPORTANT: Types and MemberInfo-derived objects require a LOT of memory.
|
||||||
// Instead use RuntimeTypeHandle, RuntimeFieldHandle and RunTimeHandle (IntPtr) instead!
|
// Instead use RuntimeTypeHandle, RuntimeFieldHandle and RunTimeHandle (IntPtr) instead!
|
||||||
internal Dictionary<IScriptHost, Dictionary<string, LSL_BaseClass>> Scripts = new Dictionary<IScriptHost, Dictionary<string, LSL_BaseClass>>();
|
internal Dictionary<uint, Dictionary<LLUUID, LSL_BaseClass>> Scripts = new Dictionary<uint, Dictionary<LLUUID, LSL_BaseClass>>();
|
||||||
public Scene World
|
public Scene World
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
|
@ -79,75 +79,75 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
internal Dictionary<string, LSL_BaseClass>.KeyCollection GetScriptKeys(IScriptHost ObjectID)
|
internal Dictionary<LLUUID, LSL_BaseClass>.KeyCollection GetScriptKeys(uint localID)
|
||||||
{
|
{
|
||||||
if (Scripts.ContainsKey(ObjectID) == false)
|
if (Scripts.ContainsKey(localID) == false)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
Dictionary<string, LSL_BaseClass> Obj;
|
Dictionary<LLUUID, LSL_BaseClass> Obj;
|
||||||
Scripts.TryGetValue(ObjectID, out Obj);
|
Scripts.TryGetValue(localID, out Obj);
|
||||||
|
|
||||||
return Obj.Keys;
|
return Obj.Keys;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal LSL_BaseClass GetScript(IScriptHost ObjectID, string ScriptID)
|
internal LSL_BaseClass GetScript(uint localID, LLUUID itemID)
|
||||||
{
|
{
|
||||||
if (Scripts.ContainsKey(ObjectID) == false)
|
if (Scripts.ContainsKey(localID) == false)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
Dictionary<string, LSL_BaseClass> Obj;
|
Dictionary<LLUUID, LSL_BaseClass> Obj;
|
||||||
Scripts.TryGetValue(ObjectID, out Obj);
|
Scripts.TryGetValue(localID, out Obj);
|
||||||
if (Obj.ContainsKey(ScriptID) == false)
|
if (Obj.ContainsKey(itemID) == false)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
// Get script
|
// Get script
|
||||||
LSL_BaseClass Script;
|
LSL_BaseClass Script;
|
||||||
Obj.TryGetValue(ScriptID, out Script);
|
Obj.TryGetValue(itemID, out Script);
|
||||||
|
|
||||||
return Script;
|
return Script;
|
||||||
|
|
||||||
}
|
}
|
||||||
internal void SetScript(IScriptHost ObjectID, string ScriptID, LSL_BaseClass Script)
|
internal void SetScript(uint localID, LLUUID itemID, LSL_BaseClass Script)
|
||||||
{
|
{
|
||||||
// Create object if it doesn't exist
|
// Create object if it doesn't exist
|
||||||
if (Scripts.ContainsKey(ObjectID) == false)
|
if (Scripts.ContainsKey(localID) == false)
|
||||||
{
|
{
|
||||||
Scripts.Add(ObjectID, new Dictionary<string, LSL_BaseClass>());
|
Scripts.Add(localID, new Dictionary<LLUUID, LSL_BaseClass>());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete script if it exists
|
// Delete script if it exists
|
||||||
Dictionary<string, LSL_BaseClass> Obj;
|
Dictionary<LLUUID, LSL_BaseClass> Obj;
|
||||||
Scripts.TryGetValue(ObjectID, out Obj);
|
Scripts.TryGetValue(localID, out Obj);
|
||||||
if (Obj.ContainsKey(ScriptID) == true)
|
if (Obj.ContainsKey(itemID) == true)
|
||||||
Obj.Remove(ScriptID);
|
Obj.Remove(itemID);
|
||||||
|
|
||||||
// Add to object
|
// Add to object
|
||||||
Obj.Add(ScriptID, Script);
|
Obj.Add(itemID, Script);
|
||||||
|
|
||||||
}
|
}
|
||||||
internal void RemoveScript(IScriptHost ObjectID, string ScriptID)
|
internal void RemoveScript(uint localID, LLUUID itemID)
|
||||||
{
|
{
|
||||||
// Don't have that object?
|
// Don't have that object?
|
||||||
if (Scripts.ContainsKey(ObjectID) == false)
|
if (Scripts.ContainsKey(localID) == false)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Delete script if it exists
|
// Delete script if it exists
|
||||||
Dictionary<string, LSL_BaseClass> Obj;
|
Dictionary<LLUUID, LSL_BaseClass> Obj;
|
||||||
Scripts.TryGetValue(ObjectID, out Obj);
|
Scripts.TryGetValue(localID, out Obj);
|
||||||
if (Obj.ContainsKey(ScriptID) == true)
|
if (Obj.ContainsKey(itemID) == true)
|
||||||
Obj.Remove(ScriptID);
|
Obj.Remove(itemID);
|
||||||
|
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Fetches, loads and hooks up a script to an objects events
|
/// Fetches, loads and hooks up a script to an objects events
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="ScriptID"></param>
|
/// <param name="itemID"></param>
|
||||||
/// <param name="ObjectID"></param>
|
/// <param name="localID"></param>
|
||||||
public void StartScript(string ScriptID, IScriptHost ObjectID)
|
public void StartScript(uint localID, LLUUID itemID, string Script)
|
||||||
{
|
{
|
||||||
//IScriptHost root = host.GetRoot();
|
//IScriptHost root = host.GetRoot();
|
||||||
m_scriptEngine.Log.Verbose("ScriptEngine", "ScriptManager StartScript: ScriptID: " + ScriptID + ", ObjectID: " + ObjectID);
|
m_scriptEngine.Log.Verbose("ScriptEngine", "ScriptManager StartScript: localID: " + localID + ", itemID: " + itemID);
|
||||||
|
|
||||||
// We will initialize and start the script.
|
// We will initialize and start the script.
|
||||||
// It will be up to the script itself to hook up the correct events.
|
// It will be up to the script itself to hook up the correct events.
|
||||||
|
@ -157,59 +157,39 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
// * Fetch script from server
|
// Create a new instance of the compiler (currently we don't want reuse)
|
||||||
// DEBUG - ScriptID is an actual filename during debug
|
OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL.Compiler LSLCompiler = new OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL.Compiler();
|
||||||
// (therefore we can also check type by looking at extension)
|
// Compile (We assume LSL)
|
||||||
FileName = ScriptID;
|
FileName = LSLCompiler.CompileFromLSLText(Script);
|
||||||
|
m_scriptEngine.Log.Verbose("ScriptEngine", "Compilation of " + FileName + " done");
|
||||||
// * Does script need compile? Send it to LSL compiler first. (TODO: Use (and clean) compiler cache)
|
|
||||||
//myScriptEngine.m_logger.Verbose("ScriptEngine", "ScriptManager Script extension: " + System.IO.Path.GetExtension(FileName).ToLower());
|
|
||||||
switch (System.IO.Path.GetExtension(FileName).ToLower())
|
|
||||||
{
|
|
||||||
case ".txt":
|
|
||||||
case ".lsl":
|
|
||||||
case ".cs":
|
|
||||||
m_scriptEngine.Log.Verbose("ScriptEngine", "ScriptManager Script is CS/LSL, compiling to .Net Assembly");
|
|
||||||
// Create a new instance of the compiler (currently we don't want reuse)
|
|
||||||
OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL.Compiler LSLCompiler = new OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL.Compiler();
|
|
||||||
// Compile
|
|
||||||
FileName = LSLCompiler.Compile(FileName);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new Exception("Unknown script type.");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
m_scriptEngine.Log.Verbose("ScriptEngine", "Compilation done");
|
|
||||||
// * Insert yield into code
|
// * Insert yield into code
|
||||||
FileName = ProcessYield(FileName);
|
FileName = ProcessYield(FileName);
|
||||||
|
|
||||||
|
|
||||||
//OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSO.LSL_BaseClass Script = LoadAndInitAssembly(FreeAppDomain, FileName);
|
//OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSO.LSL_BaseClass Script = LoadAndInitAssembly(FreeAppDomain, FileName);
|
||||||
|
|
||||||
//OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL.LSL_BaseClass Script = LoadAndInitAssembly(FreeAppDomain, FileName, ObjectID);
|
//OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL.LSL_BaseClass Script = LoadAndInitAssembly(FreeAppDomain, FileName, localID);
|
||||||
long before;
|
long before;
|
||||||
before = GC.GetTotalMemory(true);
|
before = GC.GetTotalMemory(true);
|
||||||
LSL_BaseClass Script = m_scriptEngine.myAppDomainManager.LoadScript(FileName);
|
LSL_BaseClass CompiledScript = m_scriptEngine.myAppDomainManager.LoadScript(FileName);
|
||||||
Console.WriteLine("Script occupies {0} bytes", GC.GetTotalMemory(true) - before);
|
Console.WriteLine("Script " + itemID + " occupies {0} bytes", GC.GetTotalMemory(true) - before);
|
||||||
before = GC.GetTotalMemory(true);
|
before = GC.GetTotalMemory(true);
|
||||||
Script = m_scriptEngine.myAppDomainManager.LoadScript(FileName);
|
//Script = m_scriptEngine.myAppDomainManager.LoadScript(FileName);
|
||||||
Console.WriteLine("Script occupies {0} bytes", GC.GetTotalMemory(true) - before);
|
//Console.WriteLine("Script occupies {0} bytes", GC.GetTotalMemory(true) - before);
|
||||||
//before = GC.GetTotalMemory(true);
|
//before = GC.GetTotalMemory(true);
|
||||||
//Script = m_scriptEngine.myAppDomainManager.LoadScript(FileName);
|
//Script = m_scriptEngine.myAppDomainManager.LoadScript(FileName);
|
||||||
//Console.WriteLine("Script occupies {0} bytes", GC.GetTotalMemory(true) - before);
|
//Console.WriteLine("Script occupies {0} bytes", GC.GetTotalMemory(true) - before);
|
||||||
|
|
||||||
|
|
||||||
// Add it to our temporary active script keeper
|
// Add it to our temporary active script keeper
|
||||||
//Scripts.Add(FullScriptID, Script);
|
//Scripts.Add(FullitemID, Script);
|
||||||
SetScript(ObjectID, ScriptID, Script);
|
SetScript(localID, itemID, CompiledScript);
|
||||||
// We need to give (untrusted) assembly a private instance of BuiltIns
|
// We need to give (untrusted) assembly a private instance of BuiltIns
|
||||||
// this private copy will contain Read-Only FullScriptID so that it can bring that on to the server whenever needed.
|
// this private copy will contain Read-Only FullitemID so that it can bring that on to the server whenever needed.
|
||||||
LSL_BuiltIn_Commands LSLB = new LSL_BuiltIn_Commands(this, ObjectID);
|
LSL_BuiltIn_Commands LSLB = new LSL_BuiltIn_Commands(this, World.GetSceneObjectPart(localID));
|
||||||
|
|
||||||
// Start the script - giving it BuiltIns
|
// Start the script - giving it BuiltIns
|
||||||
Script.Start(LSLB);
|
CompiledScript.Start(LSLB);
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
|
@ -219,16 +199,16 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
public void StopScript(string ScriptID, IScriptHost ObjectID)
|
public void StopScript(uint localID, LLUUID itemID)
|
||||||
{
|
{
|
||||||
// Stop script
|
// Stop script
|
||||||
|
|
||||||
// Get AppDomain
|
// Get AppDomain
|
||||||
AppDomain ad = GetScript(ObjectID, ScriptID).Exec.GetAppDomain();
|
AppDomain ad = GetScript(localID, itemID).Exec.GetAppDomain();
|
||||||
// Tell script not to accept new requests
|
// Tell script not to accept new requests
|
||||||
GetScript(ObjectID, ScriptID).Exec.StopScript();
|
GetScript(localID, itemID).Exec.StopScript();
|
||||||
// Remove from internal structure
|
// Remove from internal structure
|
||||||
RemoveScript(ObjectID, ScriptID);
|
RemoveScript(localID, itemID);
|
||||||
// Tell AppDomain that we have stopped script
|
// Tell AppDomain that we have stopped script
|
||||||
m_scriptEngine.myAppDomainManager.StopScript(ad);
|
m_scriptEngine.myAppDomainManager.StopScript(ad);
|
||||||
}
|
}
|
||||||
|
@ -244,16 +224,16 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Execute a LL-event-function in Script
|
/// Execute a LL-event-function in Script
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="ObjectID">Object the script is located in</param>
|
/// <param name="localID">Object the script is located in</param>
|
||||||
/// <param name="ScriptID">Script ID</param>
|
/// <param name="itemID">Script ID</param>
|
||||||
/// <param name="FunctionName">Name of function</param>
|
/// <param name="FunctionName">Name of function</param>
|
||||||
/// <param name="args">Arguments to pass to function</param>
|
/// <param name="args">Arguments to pass to function</param>
|
||||||
internal void ExecuteEvent(IScriptHost ObjectID, string ScriptID, string FunctionName, object[] args)
|
internal void ExecuteEvent(uint localID, LLUUID itemID, string FunctionName, object[] args)
|
||||||
{
|
{
|
||||||
|
|
||||||
// Execute a function in the script
|
// Execute a function in the script
|
||||||
m_scriptEngine.Log.Verbose("ScriptEngine", "Executing Function ObjectID: " + ObjectID + ", ScriptID: " + ScriptID + ", FunctionName: " + FunctionName);
|
m_scriptEngine.Log.Verbose("ScriptEngine", "Executing Function localID: " + localID + ", itemID: " + itemID + ", FunctionName: " + FunctionName);
|
||||||
LSL_BaseClass Script = m_scriptEngine.myScriptManager.GetScript(ObjectID, ScriptID);
|
LSL_BaseClass Script = m_scriptEngine.myScriptManager.GetScript(localID, itemID);
|
||||||
|
|
||||||
// Must be done in correct AppDomain, so leaving it up to the script itself
|
// Must be done in correct AppDomain, so leaving it up to the script itself
|
||||||
Script.Exec.ExecuteEvent(FunctionName, args);
|
Script.Exec.ExecuteEvent(FunctionName, args);
|
||||||
|
|
Loading…
Reference in New Issue