OpenSim.Region.ScriptEngine.Common

From OpenSimulator

Revision as of 10:55, 20 January 2008 by Tedd (Talk | contribs)

Jump to: navigation, search

Contents

OpenSim.Region.ScriptEngine.Common

How to implement your own script engine

Creating a new script engine for OpenSim is simple (haha).
What I mean by simple is that if you already have a VM (Virtual Machine) or script engine of some sort then integrating it as a OpenSim ScriptEngine plugin is simple.

How do I get started?

1. Create a new project named "OpenSim.Region.MySuperScriptEngine" (replace "MySuperScriptEngine" with the name of your scriptengine).
2. Create a new class (file) named "ScriptEngine". It must be named exactly ScriptEngine for OpenSim to use it. ScriptEngine must inherit from "OpenSim.Region.ScriptEngine.Common.ScriptEngineBase.ScriptEngine".
3. You need to override a couple of functions. Most probably you don't want to do any special work here, so look below for a sample default file. 4. Create a new class (file) named "ScriptManager" that inherits from "OpenSim.Region.ScriptEngine.Common.ScriptEngineBase.ScriptManager".
5. Your ScriptManager class needs to override two functions. One to start a script and one to stop a script.


ScriptEngine class

The main purpose of ScriptEngine class is to be able to intercept scene, for example starting with a "fake" scene instead of OpenSim's scene. You probably don't want this, so just go for the standard initialization.
A standard class would look like this:

using System;
using Nini.Config;
using OpenSim.Framework.Console;
using OpenSim.Region.Environment.Scenes;
namespace OpenSim.Region.ScriptEngine.MySuperScriptEngine
{
    [Serializable]
    public class ScriptEngine : OpenSim.Region.ScriptEngine.Common.ScriptEngineBase.ScriptEngine
    {
        public override void Initialise(Scene scene, IConfigSource config)
        {
           InitializeEngine(scene, MainLog.Instance, true, GetScriptManager());
        }
        public override OpenSim.Region.ScriptEngine.Common.ScriptEngineBase.ScriptManager _GetScriptManager()
        {
            return new ScriptManager(this);
        }
    }
}

ScriptManager class

A script is refecenced by object id "localID" (the object/prim it is inside) and script id "itemID" (the particular (unique) instance of that script). These parameters along with a string "Script" containing the script text (source code) are passed to your (overriden) start script function in your ScriptManager class.

Keeping track of active scripts is done automatically, so your job is simply to create a new script and hand it over. After that your work is done until the script is asked to stop, then you have to do a few simple tasks to remove it again.
Here is a sample on a minimal script startup:

public override void _StartScript(uint localID, LLUUID itemID, string Script)
{
    SceneObjectPart m_host = World.GetSceneObjectPart(localID);
    try
    {
        IScript CompiledScript = MySpecialCompiler.DoCompile(Script);  // Compile and return an IScript object that is the actual script
        CompiledScript.Source = ScriptSource;                          // Store source for recompile on script reset events
        SetScript(localID, itemID, CompiledScript);                    // All is ok. Add script to OpenSim's script manager. From here on its on autopilot.
        // Create a private instance of LSL commands (note that m_scriptEngine, m_host are from baseclass, so you don't need to change them)
        LSL_BuiltIn_Commands LSLB = new LSL_BuiltIn_Commands(m_scriptEngine, m_host, localID, itemID);
        CompiledScript.Start(LSLB);                                    // Start the script - giving it LSL commands
        // Fire the first start-event, this is the event run on LSL scripts when they first start
        m_scriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "state_entry", EventQueueManager.llDetectNull, new object[] { });
    }
    catch (Exception e)
    {
      // To see how you can send the compile error in-world, have a look at OpenSim.Region.ScriptEngine.DotNetEngine.ScriptManager
    }
}

And your minimal script shutdown would be:

public override void _StopScript(uint localID, LLUUID itemID)
{
    m_scriptEngine.m_LSLLongCmdHandler.RemoveScript(localID, itemID);   // Stop long command on script like timers, http requests, etc.
    IScript LSLBC = GetScript(localID, itemID);                         // Get the script we are stopping
    if (LSLBC == null)                                                  // Nothing to do? Exit.
        return;
    try
    {
        LSLBC.Exec.StopScript();                                        // Tell script to stop
        RemoveScript(localID, itemID);                                  // Remove script from internal memory structure
   }
    catch (Exception e)
    {
      // You probably want to log this to console or something
    }
}
Personal tools
General
About This Wiki