IRegionModule

From OpenSimulator

(Difference between revisions)
Jump to: navigation, search
(The Base Interfaces)
(The Base Interfaces)
Line 47: Line 47:
 
<tr>
 
<tr>
 
   <td>Initialise</td>
 
   <td>Initialise</td>
   <td>This method is called immediately after the region module has been loaded into the runtime, before it has been added to a scene or scenes.  The configuration sources is a <a href="http://nini.sourceforge.net/">Nini</a> class which contains the concatentation of config parameters from OpenSim.ini, OpenSimDefaults.ini and the appropriate ini files in bin/config-include</td>
+
   <td>This method is called immediately after the region module has been loaded into the runtime, before it has been added to a scene or scenes.  IConfigSource is a [http://nini.sourceforge.net/ Nini] class that contains the concatentation of config parameters from OpenSim.ini, OpenSimDefaults.ini and the appropriate ini files in bin/config-include</td>
 
</tr>
 
</tr>
 
<tr>
 
<tr>

Revision as of 16:09, 3 December 2010


Introduction

Region modules are .net/mono DLLs. During initialization of the simulator, the OpenSim bin directory (bin/) and the scriptengines (bin/ScriptEngines) directory are scanned for DLLs, in an attempt to load region modules stored there.

Region modules execute within the heart of the simulator and have access to all its facilties. Typically, region modules register for a number of events, e.g. chat messages, user logins, texture transfers, and take what ever steps are appropriate for the purposes of the module.

There are two types of region module.

  • Non-shared modules where a separate module is created for each region/scene
  • Shared region modules, where a single module is shared between all regions/scenes running on the same simulator.

Region Modules require a few basic things:

  • The Base Interface
  • Some callbacks for OpenSim events

The Base Interfaces

Region modules must implement INonSharedRegionModule or ISharedRegionModule as appropriate. However, both these interfaces extend IRegionBase, defined as follows.

public interface IRegionModuleBase
{
    string Name { get; }
    Type ReplaceableInterface { get; }
    void Initialise(IConfigSource source);
    void Close();    
    bool IsSharedModule { get; }
}
Method Description
Name This name is shown when the console command "show modules" is run. For example, "Sim Chat Module" or "The Best Region Module Ever".
ReplaceableInterface If this is not null, then the module is not loaded if any other module implements the given interface. One use for this is to provide 'stub' functionality implementations that are only active if no other module is present
Initialise This method is called immediately after the region module has been loaded into the runtime, before it has been added to a scene or scenes. IConfigSource is a Nini class that contains the concatentation of config parameters from OpenSim.ini, OpenSimDefaults.ini and the appropriate ini files in bin/config-include
PostInitialise Once the sim is fully initialized and all region modules have been loaded, the sim will invoke PostInitialize on all loaded region modules. At this point the sim will be fully operational, and it should be safe to invoke any method on the scene. Note: PostInitialize will not be invoked on shared modules for regions created via XmlRpcCreateRegion or via the console command "create-region"!
Close This method will be invoked when the sim is closing down.
IsSharedModule The simulator process (OpenSim.exe) supports running multiple regions (internally, a Scene object) on a single simulator process. If this returns True, the module will only be loaded once and Initialize will be called for each Scene being simulated. If false, a separate copy of your RegionModule will be created for each Scene.

The base interface doesn't give you much beyond a piece of loaded code. In order to do anything useful you'll need to use a combination of events and calls to OpenSim interfaces and internals.

Accessible Objects

Note: these are internal interfaces, and will change in the future, probably for the better. We expect these to stabilize over time, but for now this point in time snapshot is probably helpful.

In the Initialise routine you get access to the scene object for the region, from here you can spider down into the scene and get access to many other objects of interest.

  • scene.GetEntities() - returns a list of all the Entities in the environment. This will be a combined list of SceneObjectGroups (prim sets) and ScenePresences (avatars).
  • scene.GetAvatars() - get only the avatars in the scene (very handy for sending messages to clients)
  • scene.EventManager - this is the object from which you can register callbacks for scene events. Some examples provided in a little bit
  • scene.RegionInfo - properties about the region

Registering for Events

Taking the SunModule as an example we can see the following code:

In Initialise():

...
m_scene.EventManager.OnFrame += SunUpdate;
...

Pretty simple, we just got the EventManager and registered the SunUpdate method as a callback for the OnFrame event. OnFrame is triggered every time there is a render frame in opensim, which is about 20 times per second. If you are firing on the OnFrame event you need to do something small, or punt most of the time, as you'll negatively impact the performance of the system otherwise.

Now, for that function...

public void SunUpdate()
{
    // this code just means only do this on every 1000th frame, and don't do it if the sun is in a fixed possition
    if (((m_frame++%m_frame_mod) != 0) || !ready || sunFixed)
    {
        return;
    }
 
    GenSunPos();        // Generate shared values once
 
    List<ScenePresence> avatars = m_scene.GetAvatars();
    foreach (ScenePresence avatar in avatars)
    {
        if (!avatar.IsChildAgent)
            avatar.ControllingClient.SendSunPos(Position, Velocity, CurrentTime, SecondsPerSunCycle, SecondsPerYear, OrbitalPosition);
    }
 
    // set estate settings for region access to sun position
    m_scene.RegionInfo.RegionSettings.SunVector = Position;
}

SunUpdate() takes no parameter (some events may require them). It only fires every 1000th frame by default (m_frame_mod = 1000 in this module), so it doesn't take too many cycles.

In order for the sun position to change for the clients, they need to be told that it changes. This is done by getting a list of all the Avatars from the scene, then sending the Sun Position to each of them in turn. It is important to check to see if the avatar is a ChildAgent, otherwise you will generate zombies in opensim world.

Where to go from here

  • Getting Started with Region Modules -- the Hello World of OpenSim application development
  • Read the source for existing opensim core modules. You can do it here via view svn.
  • Read the source for EventManager. It will tell you what events exist.
  • Help write more examples here. OpenSim grows with your contributions.
Personal tools
General
About This Wiki