* This is Melanie's XEngine script engine. I've not tested this real well, however, it's confirmed to compile and OpenSimulator to run successfully without this script engine active.

0.6.0-stable
Teravus Ovares 2008-05-30 12:27:06 +00:00
parent 334d05db05
commit 1a47ff8094
39 changed files with 21507 additions and 0 deletions

View File

@ -0,0 +1,270 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections;
using System.Collections.Generic;
using System.Threading;
using libsecondlife;
using OpenSim.Framework;
using OpenSim.Region.Environment.Interfaces;
using OpenSim.Region.ScriptEngine.XEngine.AsyncCommandPlugins;
using Timer=OpenSim.Region.ScriptEngine.XEngine.AsyncCommandPlugins.Timer;
using Dataserver=OpenSim.Region.ScriptEngine.XEngine.AsyncCommandPlugins.Dataserver;
namespace OpenSim.Region.ScriptEngine.XEngine
{
/// <summary>
/// Handles LSL commands that takes long time and returns an event, for example timers, HTTP requests, etc.
/// </summary>
public class AsyncCommandManager
{
private static Thread cmdHandlerThread;
private static int cmdHandlerThreadCycleSleepms;
public XEngine m_ScriptEngine;
public Dataserver m_Dataserver;
public Timer m_Timer;
public HttpRequest m_HttpRequest;
public Listener m_Listener;
public SensorRepeat m_SensorRepeat;
public XmlRequest m_XmlRequest;
public AsyncCommandManager(XEngine _ScriptEngine)
{
m_ScriptEngine = _ScriptEngine;
ReadConfig();
// Create instances of all plugins
m_Dataserver = new Dataserver(this);
m_Timer = new Timer(this);
m_HttpRequest = new HttpRequest(this);
m_Listener = new Listener(this);
m_SensorRepeat = new SensorRepeat(this);
m_XmlRequest = new XmlRequest(this);
StartThread();
}
private static void StartThread()
{
if (cmdHandlerThread == null)
{
// Start the thread that will be doing the work
cmdHandlerThread = new Thread(CmdHandlerThreadLoop);
cmdHandlerThread.Name = "AsyncLSLCmdHandlerThread";
cmdHandlerThread.Priority = ThreadPriority.BelowNormal;
cmdHandlerThread.IsBackground = true;
cmdHandlerThread.Start();
ThreadTracker.Add(cmdHandlerThread);
}
}
public void ReadConfig()
{
cmdHandlerThreadCycleSleepms = m_ScriptEngine.ScriptConfigSource.GetInt("AsyncLLCommandLoopms", 100);
}
~AsyncCommandManager()
{
// Shut down thread
try
{
if (cmdHandlerThread != null)
{
if (cmdHandlerThread.IsAlive == true)
{
cmdHandlerThread.Abort();
//cmdHandlerThread.Join();
}
}
}
catch
{
}
}
private static void CmdHandlerThreadLoop()
{
while (true)
{
try
{
while (true)
{
Thread.Sleep(cmdHandlerThreadCycleSleepms);
foreach (XEngine xe in XEngine.ScriptEngines)
{
xe.m_ASYNCLSLCommandManager.DoOneCmdHandlerPass();
}
}
}
catch
{
}
}
}
internal void DoOneCmdHandlerPass()
{
// Check timers
m_Timer.CheckTimerEvents();
// Check HttpRequests
m_HttpRequest.CheckHttpRequests();
// Check XMLRPCRequests
m_XmlRequest.CheckXMLRPCRequests();
// Check Listeners
m_Listener.CheckListeners();
// Check Sensors
m_SensorRepeat.CheckSenseRepeaterEvents();
// Check dataserver
m_Dataserver.ExpireRequests();
}
/// <summary>
/// Remove a specific script (and all its pending commands)
/// </summary>
/// <param name="localID"></param>
/// <param name="itemID"></param>
public void RemoveScript(uint localID, LLUUID itemID)
{
// Remove a specific script
// Remove dataserver events
m_Dataserver.RemoveEvents(localID, itemID);
// Remove from: Timers
m_Timer.UnSetTimerEvents(localID, itemID);
// Remove from: HttpRequest
IHttpRequests iHttpReq =
m_ScriptEngine.World.RequestModuleInterface<IHttpRequests>();
iHttpReq.StopHttpRequest(localID, itemID);
IWorldComm comms = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
comms.DeleteListener(itemID);
IXMLRPC xmlrpc = m_ScriptEngine.World.RequestModuleInterface<IXMLRPC>();
xmlrpc.DeleteChannels(itemID);
xmlrpc.CancelSRDRequests(itemID);
// Remove Sensors
m_SensorRepeat.UnSetSenseRepeaterEvents(localID, itemID);
}
public Object[] GetSerializationData(LLUUID itemID)
{
List<Object> data = new List<Object>();
Object[] listeners=m_Listener.GetSerializationData(itemID);
if(listeners.Length > 0)
{
data.Add("listener");
data.Add(listeners.Length);
data.AddRange(listeners);
}
Object[] timers=m_Timer.GetSerializationData(itemID);
if(timers.Length > 0)
{
data.Add("timer");
data.Add(timers.Length);
data.AddRange(timers);
}
Object[] sensors=m_SensorRepeat.GetSerializationData(itemID);
if(sensors.Length > 0)
{
data.Add("sensor");
data.Add(sensors.Length);
data.AddRange(sensors);
}
return data.ToArray();
}
public void CreateFromData(uint localID, LLUUID itemID, LLUUID hostID,
Object[] data)
{
int idx=0;
int len;
while(idx < data.Length)
{
string type = data[idx].ToString();
len = (int)data[idx+1];
idx+=2;
if(len > 0)
{
Object[] item = new Object[len];
Array.Copy(data, idx, item, 0, len);
idx+=len;
switch(type)
{
case "listener":
m_Listener.CreateFromData(localID, itemID, hostID,
item);
break;
case "timer":
m_Timer.CreateFromData(localID, itemID, hostID, item);
break;
case "sensor":
m_SensorRepeat.CreateFromData(localID, itemID, hostID,
item);
break;
}
}
}
}
#region Check llRemoteData channels
#endregion
#region Check llListeners
#endregion
/// <summary>
/// If set to true then threads and stuff should try to make a graceful exit
/// </summary>
public bool PleaseShutdown
{
get { return _PleaseShutdown; }
set { _PleaseShutdown = value; }
}
private bool _PleaseShutdown = false;
}
}

View File

@ -0,0 +1,127 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections;
using System.Collections.Generic;
using libsecondlife;
using OpenSim.Region.ScriptEngine.XEngine.Script;
namespace OpenSim.Region.ScriptEngine.XEngine.AsyncCommandPlugins
{
public class Dataserver
{
public AsyncCommandManager m_CmdManager;
private Dictionary<string, DataserverRequest> DataserverRequests =
new Dictionary<string, DataserverRequest>();
public Dataserver(AsyncCommandManager CmdManager)
{
m_CmdManager = CmdManager;
}
private class DataserverRequest
{
public uint localID;
public LLUUID itemID;
public LLUUID ID;
public string handle;
public DateTime startTime;
}
public LLUUID RegisterRequest(uint localID, LLUUID itemID,
string identifier)
{
lock(DataserverRequests)
{
if(DataserverRequests.ContainsKey(identifier))
return LLUUID.Zero;
DataserverRequest ds = new DataserverRequest();
ds.localID = localID;
ds.itemID = itemID;
ds.ID = LLUUID.Random();
ds.handle = identifier;
ds.startTime = DateTime.Now;
DataserverRequests[identifier]=ds;
return ds.ID;
}
}
public void DataserverReply(string identifier, string reply)
{
DataserverRequest ds;
lock(DataserverRequests)
{
if(!DataserverRequests.ContainsKey(identifier))
return;
ds=DataserverRequests[identifier];
DataserverRequests.Remove(identifier);
}
m_CmdManager.m_ScriptEngine.PostObjectEvent(ds.localID,
new XEventParams( "dataserver", new Object[]
{ new LSL_Types.LSLString(ds.ID.ToString()),
new LSL_Types.LSLString(reply)},
new XDetectParams[0]));
}
public void RemoveEvents(uint localID, LLUUID itemID)
{
lock(DataserverRequests)
{
foreach (DataserverRequest ds in new List<DataserverRequest>(DataserverRequests.Values))
{
if(ds.itemID == itemID)
DataserverRequests.Remove(ds.handle);
}
}
}
public void ExpireRequests()
{
lock(DataserverRequests)
{
foreach (DataserverRequest ds in new List<DataserverRequest>(DataserverRequests.Values))
{
if(ds.startTime > DateTime.Now.AddSeconds(30))
DataserverRequests.Remove(ds.handle);
}
}
}
}
}

View File

@ -0,0 +1,76 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections;
using System.Collections.Generic;
using libsecondlife;
using OpenSim.Region.Environment.Scenes;
namespace OpenSim.Region.ScriptEngine.XEngine.AsyncCommandPlugins
{
public class Eventstream
{
public AsyncCommandManager m_CmdManager;
private class Event
{
public uint LocalID;
public string EventName;
public Dictionary<LLUUID, XDetectParams> DetectParams;
}
private Dictionary<uint, Dictionary<string, Event> > m_Events =
new Dictionary<uint, Dictionary<string, Event> >();
public Eventstream(AsyncCommandManager CmdManager)
{
m_CmdManager = CmdManager;
}
public void AddObjectEvent(uint localID, string eventName, XDetectParams det)
{
SceneObjectPart part = m_CmdManager.m_ScriptEngine.World.
GetSceneObjectPart(localID);
if(part == null) // Can't register events for non-prims
return;
if(!part.ContainsScripts())
return;
}
public void RemoveObjectEvent(uint localID, string eventName, LLUUID id)
{
}
public void RemoveObjects(uint localID)
{
}
}
}

View File

@ -0,0 +1,89 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using OpenSim.Region.Environment.Interfaces;
using OpenSim.Region.Environment.Modules.Scripting.HttpRequest;
using OpenSim.Region.ScriptEngine.XEngine.Script;
namespace OpenSim.Region.ScriptEngine.XEngine.AsyncCommandPlugins
{
public class HttpRequest
{
public AsyncCommandManager m_CmdManager;
public HttpRequest(AsyncCommandManager CmdManager)
{
m_CmdManager = CmdManager;
}
public void CheckHttpRequests()
{
if (m_CmdManager.m_ScriptEngine.World == null)
return;
IHttpRequests iHttpReq =
m_CmdManager.m_ScriptEngine.World.RequestModuleInterface<IHttpRequests>();
HttpRequestClass httpInfo = null;
if (iHttpReq != null)
httpInfo = iHttpReq.GetNextCompletedRequest();
while (httpInfo != null)
{
//m_ScriptEngine.Log.Info("[AsyncLSL]:" + httpInfo.response_body + httpInfo.status);
// Deliver data to prim's remote_data handler
//
// TODO: Returning null for metadata, since the lsl function
// only returns the byte for HTTP_BODY_TRUNCATED, which is not
// implemented here yet anyway. Should be fixed if/when maxsize
// is supported
iHttpReq.RemoveCompletedRequest(httpInfo.reqID);
object[] resobj = new object[]
{
new LSL_Types.LSLString(httpInfo.reqID.ToString()),
new LSL_Types.LSLInteger(httpInfo.status),
new LSL_Types.list(),
new LSL_Types.LSLString(httpInfo.response_body)
};
foreach (XEngine xe in XEngine.ScriptEngines)
{
if(xe.PostObjectEvent(httpInfo.localID,
new XEventParams("http_response",
resobj, new XDetectParams[0])))
break;
}
httpInfo = iHttpReq.GetNextCompletedRequest();
}
}
}
}

View File

@ -0,0 +1,91 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using libsecondlife;
using OpenSim.Region.Environment.Interfaces;
using OpenSim.Region.Environment.Modules.Scripting.WorldComm;
using OpenSim.Region.ScriptEngine.XEngine.Script;
namespace OpenSim.Region.ScriptEngine.XEngine.AsyncCommandPlugins
{
public class Listener
{
// private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
public AsyncCommandManager m_CmdManager;
public Listener(AsyncCommandManager CmdManager)
{
m_CmdManager = CmdManager;
}
public void CheckListeners()
{
if (m_CmdManager.m_ScriptEngine.World == null)
return;
IWorldComm comms = m_CmdManager.m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
if (comms != null)
{
while (comms.HasMessages())
{
ListenerInfo lInfo = comms.GetNextMessage();
//Deliver data to prim's listen handler
object[] resobj = new object[]
{
new LSL_Types.LSLInteger(lInfo.GetChannel()),
new LSL_Types.LSLString(lInfo.GetName()),
new LSL_Types.LSLString(lInfo.GetID().ToString()),
new LSL_Types.LSLString(lInfo.GetMessage())
};
m_CmdManager.m_ScriptEngine.PostScriptEvent(
lInfo.GetItemID(), new XEventParams(
"listen", resobj,
new XDetectParams[0]));
}
}
}
public Object[] GetSerializationData(LLUUID itemID)
{
IWorldComm comms = m_CmdManager.m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
return comms.GetSerializationData(itemID);
}
public void CreateFromData(uint localID, LLUUID itemID, LLUUID hostID,
Object[] data)
{
IWorldComm comms = m_CmdManager.m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
comms.CreateFromData(localID, itemID, hostID, data);
}
}
}

View File

@ -0,0 +1,391 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections.Generic;
using libsecondlife;
using OpenSim.Framework;
using OpenSim.Region.Environment.Scenes;
using OpenSim.Region.ScriptEngine.XEngine.Script;
namespace OpenSim.Region.ScriptEngine.XEngine.AsyncCommandPlugins
{
public class SensorRepeat
{
public AsyncCommandManager m_CmdManager;
public SensorRepeat(AsyncCommandManager CmdManager)
{
m_CmdManager = CmdManager;
}
public Dictionary<uint, Dictionary<LLUUID, LSL_Types.list>> SenseEvents =
new Dictionary<uint, Dictionary<LLUUID, LSL_Types.list>>();
private Object SenseLock = new Object();
//
// SenseRepeater and Sensors
//
private class SenseRepeatClass
{
public uint localID;
public LLUUID itemID;
public double interval;
public DateTime next;
public string name;
public LLUUID keyID;
public int type;
public double range;
public double arc;
public SceneObjectPart host;
}
private List<SenseRepeatClass> SenseRepeaters = new List<SenseRepeatClass>();
private object SenseRepeatListLock = new object();
public void SetSenseRepeatEvent(uint m_localID, LLUUID m_itemID,
string name, LLUUID keyID, int type, double range, double arc, double sec, SceneObjectPart host)
{
Console.WriteLine("SetSensorEvent");
// Always remove first, in case this is a re-set
UnSetSenseRepeaterEvents(m_localID, m_itemID);
if (sec == 0) // Disabling timer
return;
// Add to timer
SenseRepeatClass ts = new SenseRepeatClass();
ts.localID = m_localID;
ts.itemID = m_itemID;
ts.interval = sec;
ts.name = name;
ts.keyID = keyID;
ts.type = type;
ts.range = range;
ts.arc = arc;
ts.host = host;
ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
lock (SenseRepeatListLock)
{
SenseRepeaters.Add(ts);
}
}
public void UnSetSenseRepeaterEvents(uint m_localID, LLUUID m_itemID)
{
// Remove from timer
lock (SenseRepeatListLock)
{
List<SenseRepeatClass> NewSensors = new List<SenseRepeatClass>();
foreach (SenseRepeatClass ts in SenseRepeaters)
{
if (ts.localID != m_localID && ts.itemID != m_itemID)
{
NewSensors.Add(ts);
}
}
SenseRepeaters.Clear();
SenseRepeaters = NewSensors;
}
}
public void CheckSenseRepeaterEvents()
{
// Nothing to do here?
if (SenseRepeaters.Count == 0)
return;
lock (SenseRepeatListLock)
{
// Go through all timers
foreach (SenseRepeatClass ts in SenseRepeaters)
{
// Time has passed?
if (ts.next.ToUniversalTime() < DateTime.Now.ToUniversalTime())
{
SensorSweep(ts);
// set next interval
ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
}
}
} // lock
}
public void SenseOnce(uint m_localID, LLUUID m_itemID,
string name, LLUUID keyID, int type,
double range, double arc, SceneObjectPart host)
{
// Add to timer
SenseRepeatClass ts = new SenseRepeatClass();
ts.localID = m_localID;
ts.itemID = m_itemID;
ts.interval = 0;
ts.name = name;
ts.keyID = keyID;
ts.type = type;
ts.range = range;
ts.arc = arc;
ts.host = host;
SensorSweep(ts);
}
public LSL_Types.list GetSensorList(uint m_localID, LLUUID m_itemID)
{
lock (SenseLock)
{
Dictionary<LLUUID, LSL_Types.list> Obj = null;
if (!SenseEvents.TryGetValue(m_localID, out Obj))
{
m_CmdManager.m_ScriptEngine.Log.Info("[AsyncLSL]: GetSensorList missing localID: " + m_localID);
return null;
}
lock (Obj)
{
// Get script
LSL_Types.list SenseList = null;
if (!Obj.TryGetValue(m_itemID, out SenseList))
{
m_CmdManager.m_ScriptEngine.Log.Info("[AsyncLSL]: GetSensorList missing itemID: " + m_itemID);
return null;
}
return SenseList;
}
}
}
private void SensorSweep(SenseRepeatClass ts)
{
//m_ScriptEngine.Log.Info("[AsyncLSL]:Enter SensorSweep");
SceneObjectPart SensePoint = ts.host;
if (SensePoint == null)
{
//m_ScriptEngine.Log.Info("[AsyncLSL]: Enter SensorSweep (SensePoint == null) for "+ts.itemID.ToString());
return;
}
//m_ScriptEngine.Log.Info("[AsyncLSL]: Enter SensorSweep Scan");
LLVector3 sensorPos = SensePoint.AbsolutePosition;
LLVector3 regionPos = new LLVector3(m_CmdManager.m_ScriptEngine.World.RegionInfo.RegionLocX * Constants.RegionSize, m_CmdManager.m_ScriptEngine.World.RegionInfo.RegionLocY * Constants.RegionSize, 0);
LLVector3 fromRegionPos = sensorPos + regionPos;
LLQuaternion q = SensePoint.RotationOffset;
LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W);
LSL_Types.Vector3 forward_dir = (new LSL_Types.Vector3(1, 0, 0) * r);
double mag_fwd = LSL_Types.Vector3.Mag(forward_dir);
// Here we should do some smart culling ...
// math seems quicker than strings so try that first
LSL_Types.list SensedObjects = new LSL_Types.list();
LSL_Types.Vector3 ZeroVector = new LSL_Types.Vector3(0, 0, 0);
foreach (EntityBase ent in m_CmdManager.m_ScriptEngine.World.Entities.Values)
{
LLVector3 toRegionPos = ent.AbsolutePosition + regionPos;
double dis = Math.Abs((double)Util.GetDistanceTo(toRegionPos, fromRegionPos));
if (dis <= ts.range)
{
// In Range, is it the right Type ?
int objtype = 0;
if (m_CmdManager.m_ScriptEngine.World.GetScenePresence(ent.UUID) != null) objtype |= 0x01; // actor
if (ent.Velocity.Equals(ZeroVector))
objtype |= 0x04; // passive non-moving
else
objtype |= 0x02; // active moving
if (ent is IScript) objtype |= 0x08; // Scripted. It COULD have one hidden ...
if (((ts.type & objtype) != 0) || ((ts.type & objtype) == ts.type))
{
// docs claim AGENT|ACTIVE should find agent objects OR active objects
// so the bitwise AND with object type should be non-zero
// Right type too, what about the other params , key and name ?
bool keep = true;
if (ts.arc < Math.PI)
{
// not omni-directional. Can you see it ?
// vec forward_dir = llRot2Fwd(llGetRot())
// vec obj_dir = toRegionPos-fromRegionPos
// dot=dot(forward_dir,obj_dir)
// mag_fwd = mag(forward_dir)
// mag_obj = mag(obj_dir)
// ang = acos(dot /(mag_fwd*mag_obj))
double ang_obj = 0;
try
{
LLVector3 diff = toRegionPos - fromRegionPos;
LSL_Types.Vector3 obj_dir = new LSL_Types.Vector3(diff.X, diff.Y, diff.Z);
double dot = LSL_Types.Vector3.Dot(forward_dir, obj_dir);
double mag_obj = LSL_Types.Vector3.Mag(obj_dir);
ang_obj = Math.Acos(dot / (mag_fwd * mag_obj));
}
catch
{
}
if (ang_obj > ts.arc) keep = false;
}
if (keep && (ts.keyID != LLUUID.Zero) && (ts.keyID != ent.UUID))
{
keep = false;
}
if (keep && (ts.name.Length > 0))
{
string avatarname=null;
string objectname=null;
string entname =ent.Name;
// try avatar username surname
UserProfileData profile = m_CmdManager.m_ScriptEngine.World.CommsManager.UserService.GetUserProfile(ent.UUID);
if (profile != null)
{
avatarname = profile.FirstName + " " + profile.SurName;
}
// try an scene object
SceneObjectPart SOP = m_CmdManager.m_ScriptEngine.World.GetSceneObjectPart(ent.UUID);
if (SOP != null)
{
objectname = SOP.Name;
}
if ((ts.name != entname) && (ts.name != avatarname) && (ts.name != objectname))
{
keep = false;
}
}
if (keep == true) SensedObjects.Add(ent.UUID);
}
}
}
//m_ScriptEngine.Log.Info("[AsyncLSL]: Enter SensorSweep SenseLock");
lock (SenseLock)
{
// Create object if it doesn't exist
if (SenseEvents.ContainsKey(ts.localID) == false)
{
SenseEvents.Add(ts.localID, new Dictionary<LLUUID, LSL_Types.list>());
}
// clear if previous traces exist
Dictionary<LLUUID, LSL_Types.list> Obj;
SenseEvents.TryGetValue(ts.localID, out Obj);
if (Obj.ContainsKey(ts.itemID) == true)
Obj.Remove(ts.itemID);
// note list may be zero length
Obj.Add(ts.itemID, SensedObjects);
if (SensedObjects.Length == 0)
{
// send a "no_sensor"
// Add it to queue
m_CmdManager.m_ScriptEngine.PostScriptEvent(ts.itemID,
new XEventParams("no_sensor", new Object[0],
new XDetectParams[0]));
}
else
{
XDetectParams[] detect =
new XDetectParams[SensedObjects.Length];
int idx;
for(idx = 0 ; idx < SensedObjects.Length; idx++)
{
detect[idx].Key=(LLUUID)(SensedObjects.Data[idx]);
}
m_CmdManager.m_ScriptEngine.PostScriptEvent(ts.itemID,
new XEventParams("sensor",
new Object[] {
new LSL_Types.LSLInteger(SensedObjects.Length) },
detect));
}
}
}
public Object[] GetSerializationData(LLUUID itemID)
{
List<Object> data = new List<Object>();
foreach (SenseRepeatClass ts in SenseRepeaters)
{
if(ts.itemID == itemID)
{
data.Add(ts.interval);
data.Add(ts.name);
data.Add(ts.keyID);
data.Add(ts.type);
data.Add(ts.range);
data.Add(ts.arc);
}
}
return data.ToArray();
}
public void CreateFromData(uint localID, LLUUID itemID, LLUUID objectID,
Object[] data)
{
SceneObjectPart part =
m_CmdManager.m_ScriptEngine.World.GetSceneObjectPart(
objectID);
if(part == null)
return;
int idx=0;
while(idx < data.Length)
{
SenseRepeatClass ts = new SenseRepeatClass();
ts.localID = localID;
ts.itemID = itemID;
ts.interval = (double)data[idx];
ts.name = (string)data[idx+1];
ts.keyID = (LLUUID)data[idx+2];
ts.type = (int)data[idx+3];
ts.range = (double)data[idx+4];
ts.arc = (double)data[idx+5];
ts.host = part;
ts.next =
DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
SenseRepeaters.Add(ts);
idx += 6;
}
}
}
}

View File

@ -0,0 +1,163 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections;
using System.Collections.Generic;
using libsecondlife;
namespace OpenSim.Region.ScriptEngine.XEngine.AsyncCommandPlugins
{
public class Timer
{
public AsyncCommandManager m_CmdManager;
public Timer(AsyncCommandManager CmdManager)
{
m_CmdManager = CmdManager;
}
//
// TIMER
//
private class TimerClass
{
public uint localID;
public LLUUID itemID;
//public double interval;
public long interval;
//public DateTime next;
public long next;
}
private List<TimerClass> Timers = new List<TimerClass>();
private object TimerListLock = new object();
public void SetTimerEvent(uint m_localID, LLUUID m_itemID, double sec)
{
Console.WriteLine("SetTimerEvent");
// Always remove first, in case this is a re-set
UnSetTimerEvents(m_localID, m_itemID);
if (sec == 0) // Disabling timer
return;
// Add to timer
TimerClass ts = new TimerClass();
ts.localID = m_localID;
ts.itemID = m_itemID;
ts.interval = Convert.ToInt64(sec * 10000000); // How many 100 nanoseconds (ticks) should we wait
// 2193386136332921 ticks
// 219338613 seconds
//ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
ts.next = DateTime.Now.Ticks + ts.interval;
lock (TimerListLock)
{
Timers.Add(ts);
}
}
public void UnSetTimerEvents(uint m_localID, LLUUID m_itemID)
{
// Remove from timer
lock (TimerListLock)
{
foreach (TimerClass ts in new ArrayList(Timers))
{
if (ts.localID == m_localID && ts.itemID == m_itemID)
Timers.Remove(ts);
}
}
}
public void CheckTimerEvents()
{
// Nothing to do here?
if (Timers.Count == 0)
return;
lock (TimerListLock)
{
// Go through all timers
foreach (TimerClass ts in Timers)
{
// Time has passed?
if (ts.next < DateTime.Now.Ticks)
{
// Console.WriteLine("Time has passed: Now: " + DateTime.Now.Ticks + ", Passed: " + ts.next);
// Add it to queue
m_CmdManager.m_ScriptEngine.PostScriptEvent(ts.itemID,
new XEventParams("timer", new Object[0],
new XDetectParams[0]));
// set next interval
//ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
ts.next = DateTime.Now.Ticks + ts.interval;
}
}
}
}
public Object[] GetSerializationData(LLUUID itemID)
{
List<Object> data = new List<Object>();
lock (TimerListLock)
{
foreach (TimerClass ts in Timers)
{
if(ts.itemID == itemID)
{
data.Add(ts.interval);
data.Add(ts.next-DateTime.Now.Ticks);
}
}
}
return data.ToArray();
}
public void CreateFromData(uint localID, LLUUID itemID, LLUUID objectID,
Object[] data)
{
int idx=0;
while(idx < data.Length)
{
TimerClass ts = new TimerClass();
ts.localID = localID;
ts.itemID = itemID;
ts.interval = (long)data[idx];
ts.next = DateTime.Now.Ticks + (long)data[idx+1];
idx += 2;
Timers.Add(ts);
}
}
}
}

View File

@ -0,0 +1,115 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using OpenSim.Region.Environment.Interfaces;
using OpenSim.Region.Environment.Modules.Scripting.XMLRPC;
using OpenSim.Region.ScriptEngine.XEngine.Script;
namespace OpenSim.Region.ScriptEngine.XEngine.AsyncCommandPlugins
{
public class XmlRequest
{
public AsyncCommandManager m_CmdManager;
public XmlRequest(AsyncCommandManager CmdManager)
{
m_CmdManager = CmdManager;
}
public void CheckXMLRPCRequests()
{
if (m_CmdManager.m_ScriptEngine.World == null)
return;
IXMLRPC xmlrpc = m_CmdManager.m_ScriptEngine.World.RequestModuleInterface<IXMLRPC>();
if (xmlrpc != null)
{
RPCRequestInfo rInfo = xmlrpc.GetNextCompletedRequest();
while (rInfo != null)
{
xmlrpc.RemoveCompletedRequest(rInfo.GetMessageID());
//Deliver data to prim's remote_data handler
object[] resobj = new object[]
{
new LSL_Types.LSLInteger(2),
new LSL_Types.LSLString(
rInfo.GetChannelKey().ToString()),
new LSL_Types.LSLString(
rInfo.GetMessageID().ToString()),
new LSL_Types.LSLString(String.Empty),
new LSL_Types.LSLInteger(rInfo.GetIntValue()),
new LSL_Types.LSLString(rInfo.GetStrVal())
};
foreach (XEngine xe in XEngine.ScriptEngines)
{
if(xe.PostScriptEvent(
rInfo.GetItemID(), new XEventParams(
"remote_data", resobj,
new XDetectParams[0])))
break;
}
rInfo = xmlrpc.GetNextCompletedRequest();
}
SendRemoteDataRequest srdInfo = xmlrpc.GetNextCompletedSRDRequest();
while (srdInfo != null)
{
xmlrpc.RemoveCompletedSRDRequest(srdInfo.GetReqID());
//Deliver data to prim's remote_data handler
object[] resobj = new object[]
{
new LSL_Types.LSLInteger(3),
new LSL_Types.LSLString(srdInfo.channel.ToString()),
new LSL_Types.LSLString(srdInfo.GetReqID().ToString()),
new LSL_Types.LSLString(String.Empty),
new LSL_Types.LSLInteger(srdInfo.idata),
new LSL_Types.LSLString(srdInfo.sdata)
};
foreach (XEngine xe in XEngine.ScriptEngines)
{
if(xe.PostScriptEvent(
srdInfo.m_itemID, new XEventParams(
"remote_data", resobj,
new XDetectParams[0])))
break;
}
srdInfo = xmlrpc.GetNextCompletedSRDRequest();
}
}
}
}
}

View File

@ -0,0 +1,515 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using Microsoft.CSharp;
using Microsoft.JScript;
using Microsoft.VisualBasic;
using OpenSim.Region.Environment.Interfaces;
namespace OpenSim.Region.ScriptEngine.XEngine
{
public class Compiler
{
private static readonly log4net.ILog m_log
= log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
// * Uses "LSL2Converter" to convert LSL to C# if necessary.
// * Compiles C#-code into an assembly
// * Returns assembly name ready for AppDomain load.
//
// Assembly is compiled using LSL_BaseClass as base. Look at debug C# code file created when LSL script is compiled for full details.
//
internal enum enumCompileType
{
lsl = 0,
cs = 1,
vb = 2,
js = 3
}
/// <summary>
/// This contains number of lines WE use for header when compiling script. User will get error in line x-LinesToRemoveOnError when error occurs.
/// </summary>
public int LinesToRemoveOnError = 3;
private enumCompileType DefaultCompileLanguage;
private bool WriteScriptSourceToDebugFile;
private bool CompileWithDebugInformation;
private Dictionary<string, bool> AllowedCompilers = new Dictionary<string, bool>(StringComparer.CurrentCultureIgnoreCase);
private Dictionary<string, enumCompileType> LanguageMapping = new Dictionary<string, enumCompileType>(StringComparer.CurrentCultureIgnoreCase);
private string FilePrefix;
private string ScriptEnginesPath = "ScriptEngines";
private static LSL2CSConverter LSL_Converter = new LSL2CSConverter();
private static CSharpCodeProvider CScodeProvider = new CSharpCodeProvider();
private static VBCodeProvider VBcodeProvider = new VBCodeProvider();
private static JScriptCodeProvider JScodeProvider = new JScriptCodeProvider();
private static int instanceID = new Random().Next(0, int.MaxValue); // Unique number to use on our compiled files
private static UInt64 scriptCompileCounter = 0; // And a counter
public XEngine m_scriptEngine;
public Compiler(XEngine scriptEngine)
{
m_scriptEngine = scriptEngine;
ReadConfig();
}
public bool in_startup = true;
public void ReadConfig()
{
// Get some config
WriteScriptSourceToDebugFile = m_scriptEngine.ScriptConfigSource.GetBoolean("WriteScriptSourceToDebugFile", true);
CompileWithDebugInformation = m_scriptEngine.ScriptConfigSource.GetBoolean("CompileWithDebugInformation", true);
// Get file prefix from scriptengine name and make it file system safe:
FilePrefix = m_scriptEngine.ScriptEngineName;
foreach (char c in Path.GetInvalidFileNameChars())
{
FilePrefix = FilePrefix.Replace(c, '_');
}
// First time we start? Delete old files
if (in_startup)
{
in_startup = false;
DeleteOldFiles();
}
// Map name and enum type of our supported languages
LanguageMapping.Add(enumCompileType.cs.ToString(), enumCompileType.cs);
LanguageMapping.Add(enumCompileType.vb.ToString(), enumCompileType.vb);
LanguageMapping.Add(enumCompileType.lsl.ToString(), enumCompileType.lsl);
LanguageMapping.Add(enumCompileType.js.ToString(), enumCompileType.js);
// Allowed compilers
string allowComp = m_scriptEngine.ScriptConfigSource.GetString("AllowedCompilers", "lsl,cs,vb,js");
AllowedCompilers.Clear();
#if DEBUG
m_scriptEngine.Log.Debug("[" + m_scriptEngine.ScriptEngineName + "]: Allowed languages: " + allowComp);
#endif
foreach (string strl in allowComp.Split(','))
{
string strlan = strl.Trim(" \t".ToCharArray()).ToLower();
if (!LanguageMapping.ContainsKey(strlan))
{
m_scriptEngine.Log.Error("[" + m_scriptEngine.ScriptEngineName + "]: Config error. Compiler is unable to recognize language type \"" + strlan + "\" specified in \"AllowedCompilers\".");
}
else
{
#if DEBUG
//m_scriptEngine.Log.Debug("[" + m_scriptEngine.ScriptEngineName + "]: Config OK. Compiler recognized language type \"" + strlan + "\" specified in \"AllowedCompilers\".");
#endif
}
AllowedCompilers.Add(strlan, true);
}
if (AllowedCompilers.Count == 0)
m_scriptEngine.Log.Error("[" + m_scriptEngine.ScriptEngineName + "]: Config error. Compiler could not recognize any language in \"AllowedCompilers\". Scripts will not be executed!");
// Default language
string defaultCompileLanguage = m_scriptEngine.ScriptConfigSource.GetString("DefaultCompileLanguage", "lsl").ToLower();
// Is this language recognized at all?
if (!LanguageMapping.ContainsKey(defaultCompileLanguage))
{
m_scriptEngine.Log.Error("[" + m_scriptEngine.ScriptEngineName + "]: " +
"Config error. Default language \"" + defaultCompileLanguage + "\" specified in \"DefaultCompileLanguage\" is not recognized as a valid language. Changing default to: \"lsl\".");
defaultCompileLanguage = "lsl";
}
// Is this language in allow-list?
if (!AllowedCompilers.ContainsKey(defaultCompileLanguage))
{
m_scriptEngine.Log.Error("[" + m_scriptEngine.ScriptEngineName + "]: " +
"Config error. Default language \"" + defaultCompileLanguage + "\"specified in \"DefaultCompileLanguage\" is not in list of \"AllowedCompilers\". Scripts may not be executed!");
}
else
{
#if DEBUG
// m_scriptEngine.Log.Debug("[" + m_scriptEngine.ScriptEngineName + "]: " +
// "Config OK. Default language \"" + defaultCompileLanguage + "\" specified in \"DefaultCompileLanguage\" is recognized as a valid language.");
#endif
// LANGUAGE IS IN ALLOW-LIST
DefaultCompileLanguage = LanguageMapping[defaultCompileLanguage];
}
// We now have an allow-list, a mapping list, and a default language
}
/// <summary>
/// Delete old script files
/// </summary>
private void DeleteOldFiles()
{
// CREATE FOLDER IF IT DOESNT EXIST
if (!Directory.Exists(ScriptEnginesPath))
{
try
{
Directory.CreateDirectory(ScriptEnginesPath);
}
catch (Exception ex)
{
m_scriptEngine.Log.Error("[" + m_scriptEngine.ScriptEngineName + "]: Exception trying to create ScriptEngine directory \"" + ScriptEnginesPath + "\": " + ex.ToString());
}
}
if (!Directory.Exists(Path.Combine(ScriptEnginesPath,
m_scriptEngine.World.RegionInfo.RegionID.ToString())))
{
try
{
Directory.CreateDirectory(Path.Combine(ScriptEnginesPath,
m_scriptEngine.World.RegionInfo.RegionID.ToString()));
}
catch (Exception ex)
{
m_scriptEngine.Log.Error("[" + m_scriptEngine.ScriptEngineName + "]: Exception trying to create ScriptEngine directory \"" + Path.Combine(ScriptEnginesPath,
m_scriptEngine.World.RegionInfo.RegionID.ToString())+ "\": " + ex.ToString());
}
}
foreach (string file in Directory.GetFiles(Path.Combine(ScriptEnginesPath,
m_scriptEngine.World.RegionInfo.RegionID.ToString())))
{
//m_scriptEngine.Log.Error("[" + m_scriptEngine.ScriptEngineName + "]: FILE FOUND: " + file);
if (file.ToLower().StartsWith(FilePrefix + "_compiled_") ||
file.ToLower().StartsWith(FilePrefix + "_source_"))
{
try
{
File.Delete(file);
}
catch (Exception ex)
{
m_scriptEngine.Log.Error("[" + m_scriptEngine.ScriptEngineName + "]: Exception trying delete old script file \"" + file + "\": " + ex.ToString());
}
}
}
}
////private ICodeCompiler icc = codeProvider.CreateCompiler();
//public string CompileFromFile(string LSOFileName)
//{
// switch (Path.GetExtension(LSOFileName).ToLower())
// {
// case ".txt":
// case ".lsl":
// Common.ScriptEngineBase.Common.SendToDebug("Source code is LSL, converting to CS");
// return CompileFromLSLText(File.ReadAllText(LSOFileName));
// case ".cs":
// Common.ScriptEngineBase.Common.SendToDebug("Source code is CS");
// return CompileFromCSText(File.ReadAllText(LSOFileName));
// default:
// 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 PerformScriptCompile(string Script, string asset)
{
string OutFile = Path.Combine(ScriptEnginesPath, Path.Combine(
m_scriptEngine.World.RegionInfo.RegionID.ToString(),
FilePrefix + "_compiled_" + asset + ".dll"));
// string OutFile = Path.Combine(ScriptEnginesPath,
// FilePrefix + "_compiled_" + asset + ".dll");
if(File.Exists(OutFile))
return OutFile;
if (!Directory.Exists(ScriptEnginesPath))
{
try
{
Directory.CreateDirectory(ScriptEnginesPath);
}
catch (Exception ex)
{
}
}
if (!Directory.Exists(Path.Combine(ScriptEnginesPath,
m_scriptEngine.World.RegionInfo.RegionID.ToString())))
{
try
{
Directory.CreateDirectory(ScriptEnginesPath);
}
catch (Exception ex)
{
}
}
enumCompileType l = DefaultCompileLanguage;
if (Script.StartsWith("//c#", true, CultureInfo.InvariantCulture))
l = enumCompileType.cs;
if (Script.StartsWith("//vb", true, CultureInfo.InvariantCulture))
{
l = enumCompileType.vb;
// We need to remove //vb, it won't compile with that
Script = Script.Substring(4, Script.Length - 4);
}
if (Script.StartsWith("//lsl", true, CultureInfo.InvariantCulture))
l = enumCompileType.lsl;
if (Script.StartsWith("//js", true, CultureInfo.InvariantCulture))
l = enumCompileType.js;
if (!AllowedCompilers.ContainsKey(l.ToString()))
{
// Not allowed to compile to this language!
string errtext = String.Empty;
errtext += "The compiler for language \"" + l.ToString() + "\" is not in list of allowed compilers. Script will not be executed!";
throw new Exception(errtext);
}
string compileScript = Script;
if (l == enumCompileType.lsl)
{
// Its LSL, convert it to C#
compileScript = LSL_Converter.Convert(Script);
l = enumCompileType.cs;
}
// Insert additional assemblies here
//ADAM: Disabled for the moment until it's working right.
bool enableCommanderLSL = false;
if (enableCommanderLSL == true && l == enumCompileType.cs)
{
foreach (KeyValuePair<string,
ICommander> com
in m_scriptEngine.World.GetCommanders())
{
compileScript = com.Value.GenerateRuntimeAPI() + compileScript;
}
}
// End of insert
switch (l)
{
case enumCompileType.cs:
compileScript = CreateCSCompilerScript(compileScript);
break;
case enumCompileType.vb:
compileScript = CreateVBCompilerScript(compileScript);
break;
case enumCompileType.js:
compileScript = CreateJSCompilerScript(compileScript);
break;
}
// m_log.Debug("[ScriptEngine.DotNetEngine]: Preparing to compile the following LSL to C# translated code");
// m_log.Debug("");
// m_log.Debug(compileScript);
return CompileFromDotNetText(compileScript, l, asset);
}
private static string CreateJSCompilerScript(string compileScript)
{
compileScript = String.Empty +
"import OpenSim.Region.ScriptEngine.XEngine.Script; import System.Collections.Generic;\r\n" +
"package SecondLife {\r\n" +
"class Script extends OpenSim.Region.ScriptEngine.XEngine.Script.BuiltIn_Commands_BaseClass { \r\n" +
compileScript +
"} }\r\n";
return compileScript;
}
private static string CreateCSCompilerScript(string compileScript)
{
compileScript = String.Empty +
"using OpenSim.Region.ScriptEngine.XEngine.Script; using System.Collections.Generic;\r\n" +
String.Empty + "namespace SecondLife { " +
String.Empty + "public class Script : OpenSim.Region.ScriptEngine.XEngine.Script.BuiltIn_Commands_BaseClass { \r\n" +
@"public Script() { } " +
compileScript +
"} }\r\n";
return compileScript;
}
private static string CreateVBCompilerScript(string compileScript)
{
compileScript = String.Empty +
"Imports OpenSim.Region.ScriptEngine.XEngine.Script: Imports System.Collections.Generic: " +
String.Empty + "NameSpace SecondLife:" +
String.Empty + "Public Class Script: Inherits OpenSim.Region.ScriptEngine.XEngine.Script.BuiltIn_Commands_BaseClass: " +
"\r\nPublic Sub New()\r\nEnd Sub: " +
compileScript +
":End Class :End Namespace\r\n";
return compileScript;
}
/// <summary>
/// Compile .NET script to .Net assembly (.dll)
/// </summary>
/// <param name="Script">CS script</param>
/// <returns>Filename to .dll assembly</returns>
internal string CompileFromDotNetText(string Script, enumCompileType lang, string asset)
{
string ext = "." + lang.ToString();
// Output assembly name
scriptCompileCounter++;
string OutFile = Path.Combine(ScriptEnginesPath, Path.Combine(
m_scriptEngine.World.RegionInfo.RegionID.ToString(),
FilePrefix + "_compiled_" + asset + ".dll"));
#if DEBUG
// m_scriptEngine.Log.Debug("[" + m_scriptEngine.ScriptEngineName + "]: Starting compile of \"" + OutFile + "\".");
#endif
try
{
File.Delete(OutFile);
}
catch (Exception e) // NOTLEGIT - Should be just catching FileIOException
{
//m_scriptEngine.Log.Error("[" + m_scriptEngine.ScriptEngineName + "]: Unable to delete old existring script-file before writing new. Compile aborted: " + e.ToString());
throw new Exception("Unable to delete old existring script-file before writing new. Compile aborted: " + e.ToString());
}
//string OutFile = Path.Combine("ScriptEngines", "SecondLife.Script.dll");
// DEBUG - write source to disk
if (WriteScriptSourceToDebugFile)
{
string srcFileName = FilePrefix + "_source_" + Path.GetFileNameWithoutExtension(OutFile) + ext;
try
{
File.WriteAllText(
Path.Combine("ScriptEngines", srcFileName),
Script);
}
catch (Exception ex) // NOTLEGIT - Should be just catching FileIOException
{
m_scriptEngine.Log.Error("[" + m_scriptEngine.ScriptEngineName + "]: Exception while trying to write script source to file \"" + srcFileName + "\": " + ex.ToString());
}
}
// Do actual compile
CompilerParameters parameters = new CompilerParameters();
parameters.IncludeDebugInformation = true;
// Add all available assemblies
// foreach (Assembly asm in AppDomain.CurrentDomain.GetAssemblies())
// {
// Console.WriteLine("Adding assembly: " + asm.Location);
// parameters.ReferencedAssemblies.Add(asm.Location);
// }
string rootPath = Path.GetDirectoryName(AppDomain.CurrentDomain.BaseDirectory);
string rootPathSE = Path.GetDirectoryName(GetType().Assembly.Location);
//Console.WriteLine("Assembly location: " + rootPath);
parameters.ReferencedAssemblies.Add(Path.Combine(rootPath, "OpenSim.Region.ScriptEngine.XEngine.Script.dll"));
// parameters.ReferencedAssemblies.Add(Path.Combine(rootPathSE, "OpenSim.Region.ScriptEngine.XEngine.dll"));
//parameters.ReferencedAssemblies.Add("OpenSim.Region.Environment");
parameters.GenerateExecutable = false;
parameters.OutputAssembly = OutFile;
parameters.IncludeDebugInformation = CompileWithDebugInformation;
//parameters.WarningLevel = 1; // Should be 4?
parameters.TreatWarningsAsErrors = false;
//Console.WriteLine(Script);
CompilerResults results;
switch (lang)
{
case enumCompileType.vb:
results = VBcodeProvider.CompileAssemblyFromSource(parameters, Script);
break;
case enumCompileType.cs:
results = CScodeProvider.CompileAssemblyFromSource(parameters, Script);
break;
case enumCompileType.js:
results = JScodeProvider.CompileAssemblyFromSource(parameters, Script);
break;
default:
throw new Exception("Compiler is not able to recongnize language type \"" + lang.ToString() + "\"");
}
// Check result
// Go through errors
//
// WARNINGS AND ERRORS
//
if (results.Errors.Count > 0)
{
string errtext = String.Empty;
foreach (CompilerError CompErr in results.Errors)
{
errtext += "Line number " + (CompErr.Line - LinesToRemoveOnError) +
", Error Number: " + CompErr.ErrorNumber +
", '" + CompErr.ErrorText + "'\r\n";
}
if (!File.Exists(OutFile))
{
throw new Exception(errtext);
}
}
//
// NO ERRORS, BUT NO COMPILED FILE
//
if (!File.Exists(OutFile))
{
string errtext = String.Empty;
errtext += "No compile error. But not able to locate compiled file.";
throw new Exception(errtext);
}
return OutFile;
}
}
}

View File

@ -0,0 +1,293 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using libsecondlife;
using OpenSim.Framework;
using OpenSim.Region.Environment.Modules.Avatar.Currency.SampleMoney;
using OpenSim.Region.Environment.Scenes;
using OpenSim.Region.Environment.Interfaces;
using OpenSim.Region.ScriptEngine.XEngine.Script;
using Axiom.Math;
namespace OpenSim.Region.ScriptEngine.XEngine
{
/// <summary>
/// Prepares events so they can be directly executed upon a script by EventQueueManager, then queues it.
/// </summary>
public class EventManager
{
private XEngine myScriptEngine;
public EventManager(XEngine _ScriptEngine)
{
myScriptEngine = _ScriptEngine;
myScriptEngine.Log.Info("[XEngine] Hooking up to server events");
myScriptEngine.World.EventManager.OnObjectGrab += touch_start;
myScriptEngine.World.EventManager.OnObjectDeGrab += touch_end;
myScriptEngine.World.EventManager.OnScriptChangedEvent += changed;
myScriptEngine.World.EventManager.OnScriptAtTargetEvent += at_target;
myScriptEngine.World.EventManager.OnScriptNotAtTargetEvent += not_at_target;
myScriptEngine.World.EventManager.OnScriptControlEvent += control;
IMoneyModule money=myScriptEngine.World.RequestModuleInterface<IMoneyModule>();
if (money != null)
{
money.OnObjectPaid+=HandleObjectPaid;
}
}
private void HandleObjectPaid(LLUUID objectID, LLUUID agentID,
int amount)
{
SceneObjectPart part =
myScriptEngine.World.GetSceneObjectPart(objectID);
if (part != null)
{
money(part.LocalId, agentID, amount);
}
}
public void touch_start(uint localID, LLVector3 offsetPos,
IClientAPI remoteClient)
{
// Add to queue for all scripts in ObjectID object
XDetectParams[] det = new XDetectParams[1];
det[0].Key = remoteClient.AgentId;
myScriptEngine.PostObjectEvent(localID, new XEventParams(
"touch_start", new Object[] { new LSL_Types.LSLInteger(1) },
det));
}
public void touch(uint localID, LLVector3 offsetPos,
IClientAPI remoteClient)
{
// Add to queue for all scripts in ObjectID object
XDetectParams[] det = new XDetectParams[1];
det[0].Key = remoteClient.AgentId;
det[0].OffsetPos = new LSL_Types.Vector3(offsetPos.X,
offsetPos.Y,
offsetPos.Z);
myScriptEngine.PostObjectEvent(localID, new XEventParams(
"touch", new Object[] { new LSL_Types.LSLInteger(1) },
det));
}
public void touch_end(uint localID, IClientAPI remoteClient)
{
// Add to queue for all scripts in ObjectID object
XDetectParams[] det = new XDetectParams[1];
det[0].Key = remoteClient.AgentId;
myScriptEngine.PostObjectEvent(localID, new XEventParams(
"touch_end", new Object[] { new LSL_Types.LSLInteger(1) },
det));
}
public void changed(uint localID, uint change)
{
// Add to queue for all scripts in localID, Object pass change.
myScriptEngine.PostObjectEvent(localID, new XEventParams(
"changed",new object[] { new LSL_Types.LSLInteger(change) },
new XDetectParams[0]));
}
// state_entry: not processed here
// state_exit: not processed here
public void money(uint localID, LLUUID agentID, int amount)
{
myScriptEngine.PostObjectEvent(localID, new XEventParams(
"money", new object[] {
new LSL_Types.LSLString(agentID.ToString()),
new LSL_Types.LSLInteger(amount) },
new XDetectParams[0]));
}
public void collision_start(uint localID, LLUUID itemID,
IClientAPI remoteClient)
{
// Add to queue for all scripts in ObjectID object
XDetectParams[] det = new XDetectParams[1];
det[0].Key = remoteClient.AgentId;
myScriptEngine.PostObjectEvent(localID, new XEventParams(
"collision_start",
new Object[] { new LSL_Types.LSLInteger(1) },
det));
}
public void collision(uint localID, LLUUID itemID,
IClientAPI remoteClient)
{
// Add to queue for all scripts in ObjectID object
XDetectParams[] det = new XDetectParams[1];
det[0].Key = remoteClient.AgentId;
myScriptEngine.PostObjectEvent(localID, new XEventParams(
"collision", new Object[] { new LSL_Types.LSLInteger(1) },
det));
}
public void collision_end(uint localID, LLUUID itemID,
IClientAPI remoteClient)
{
// Add to queue for all scripts in ObjectID object
XDetectParams[] det = new XDetectParams[1];
det[0].Key = remoteClient.AgentId;
myScriptEngine.PostObjectEvent(localID, new XEventParams(
"collision_end",
new Object[] { new LSL_Types.LSLInteger(1) },
det));
}
public void land_collision_start(uint localID, LLUUID itemID)
{
myScriptEngine.PostObjectEvent(localID, new XEventParams(
"land_collision_start",
new object[0],
new XDetectParams[0]));
}
public void land_collision(uint localID, LLUUID itemID)
{
myScriptEngine.PostObjectEvent(localID, new XEventParams(
"land_collision",
new object[0],
new XDetectParams[0]));
}
public void land_collision_end(uint localID, LLUUID itemID)
{
myScriptEngine.PostObjectEvent(localID, new XEventParams(
"land_collision_end",
new object[0],
new XDetectParams[0]));
}
// timer: not handled here
// listen: not handled here
public void on_rez(uint localID, LLUUID itemID, int startParam)
{
myScriptEngine.PostObjectEvent(localID, new XEventParams(
"on_rez",new object[] {
new LSL_Types.LSLInteger(startParam)},
new XDetectParams[0]));
}
public void control(uint localID, LLUUID itemID, LLUUID agentID, uint held, uint change)
{
myScriptEngine.PostObjectEvent(localID, new XEventParams(
"control",new object[] {
new LSL_Types.LSLString(agentID.ToString()),
new LSL_Types.LSLInteger(held),
new LSL_Types.LSLInteger(change)},
new XDetectParams[0]));
}
public void email(uint localID, LLUUID itemID, string timeSent,
string address, string subject, string message, int numLeft)
{
myScriptEngine.PostObjectEvent(localID, new XEventParams(
"email",new object[] {
new LSL_Types.LSLString(timeSent),
new LSL_Types.LSLString(address),
new LSL_Types.LSLString(subject),
new LSL_Types.LSLString(message),
new LSL_Types.LSLInteger(numLeft)},
new XDetectParams[0]));
}
public void at_target(uint localID, uint handle, LLVector3 targetpos,
LLVector3 atpos)
{
myScriptEngine.PostObjectEvent(localID, new XEventParams(
"at_target", new object[] {
new LSL_Types.LSLInteger(handle),
new LSL_Types.Vector3(targetpos.X,targetpos.Y,targetpos.Z),
new LSL_Types.Vector3(atpos.X,atpos.Y,atpos.Z) },
new XDetectParams[0]));
}
public void not_at_target(uint localID)
{
myScriptEngine.PostObjectEvent(localID, new XEventParams(
"not_at_target",new object[0],
new XDetectParams[0]));
}
public void at_rot_target(uint localID, LLUUID itemID)
{
myScriptEngine.PostObjectEvent(localID, new XEventParams(
"at_rot_target",new object[0],
new XDetectParams[0]));
}
public void not_at_rot_target(uint localID, LLUUID itemID)
{
myScriptEngine.PostObjectEvent(localID, new XEventParams(
"not_at_rot_target",new object[0],
new XDetectParams[0]));
}
// run_time_permissions: not handled here
public void attach(uint localID, LLUUID itemID, LLUUID avatar)
{
myScriptEngine.PostObjectEvent(localID, new XEventParams(
"attach",new object[] {
new LSL_Types.LSLString(avatar.ToString()) },
new XDetectParams[0]));
}
// dataserver: not handled here
// link_message: not handled here
public void moving_start(uint localID, LLUUID itemID)
{
myScriptEngine.PostObjectEvent(localID, new XEventParams(
"moving_start",new object[0],
new XDetectParams[0]));
}
public void moving_end(uint localID, LLUUID itemID)
{
myScriptEngine.PostObjectEvent(localID, new XEventParams(
"moving_end",new object[0],
new XDetectParams[0]));
}
// object_rez: not handled here
// remote_data: not handled here
// http_response: not handled here
}
}

View File

@ -0,0 +1,136 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections.Generic;
using System.Reflection;
using OpenSim.Region.ScriptEngine.XEngine.Script;
namespace OpenSim.Region.ScriptEngine.XEngine
{
public class Executor : ExecutorBase
{
// Cache functions by keeping a reference to them in a dictionary
private Dictionary<string, MethodInfo> Events = new Dictionary<string, MethodInfo>();
private Dictionary<string, scriptEvents> m_stateEvents = new Dictionary<string, scriptEvents>();
public Executor(IScript script) : base(script)
{
initEventFlags();
}
protected override scriptEvents DoGetStateEventFlags()
{
//Console.WriteLine("Get event flags for " + m_Script.State);
// Check to see if we've already computed the flags for this state
scriptEvents eventFlags = scriptEvents.None;
if (m_stateEvents.ContainsKey(m_Script.State))
{
m_stateEvents.TryGetValue(m_Script.State, out eventFlags);
return eventFlags;
}
Type type=m_Script.GetType();
// Fill in the events for this state, cache the results in the map
foreach (KeyValuePair<string, scriptEvents> kvp in m_eventFlagsMap)
{
string evname = m_Script.State + "_event_" + kvp.Key;
//Console.WriteLine("Trying event "+evname);
try
{
MethodInfo mi = type.GetMethod(evname);
if (mi != null)
{
//Console.WriteLine("Found handler for " + kvp.Key);
eventFlags |= kvp.Value;
}
}
catch(Exception e)
{
//Console.WriteLine("Exeption in GetMethod:\n"+e.ToString());
}
}
// Save the flags we just computed and return the result
if(eventFlags != 0)
m_stateEvents.Add(m_Script.State, eventFlags);
//Console.WriteLine("Returning {0:x}", eventFlags);
return (eventFlags);
}
protected override void DoExecuteEvent(string FunctionName, object[] args)
{
// IMPORTANT: Types and MemberInfo-derived objects require a LOT of memory.
// Instead use RuntimeTypeHandle, RuntimeFieldHandle and RunTimeHandle (IntPtr) instead!
string EventName = m_Script.State + "_event_" + FunctionName;
//#if DEBUG
// Console.WriteLine("ScriptEngine: Script event function name: " + EventName);
//#endif
if (Events.ContainsKey(EventName) == false)
{
// Not found, create
Type type = m_Script.GetType();
try
{
MethodInfo mi = type.GetMethod(EventName);
Events.Add(EventName, mi);
}
catch
{
Console.WriteLine("Event {0}not found", EventName);
// Event name not found, cache it as not found
Events.Add(EventName, null);
}
}
// Get event
MethodInfo ev = null;
Events.TryGetValue(EventName, out ev);
if (ev == null) // No event by that name!
{
//Console.WriteLine("ScriptEngine Can not find any event named: \String.Empty + EventName + "\String.Empty);
return;
}
//cfk 2-7-08 dont need this right now and the default Linux build has DEBUG defined
#if DEBUG
//Console.WriteLine("ScriptEngine: Executing function name: " + EventName);
#endif
// Found
ev.Invoke(m_Script, args);
}
}
}

View File

@ -0,0 +1,181 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections.Generic;
using System.Runtime.Remoting.Lifetime;
using OpenSim.Region.ScriptEngine.XEngine.Script;
namespace OpenSim.Region.ScriptEngine.XEngine
{
public abstract class ExecutorBase : MarshalByRefObject
{
/// <summary>
/// Contains the script to execute functions in.
/// </summary>
protected IScript m_Script;
protected Dictionary<string, scriptEvents> m_eventFlagsMap = new Dictionary<string, scriptEvents>();
[Flags]
public enum scriptEvents : int
{
None = 0,
attach = 1,
collision = 15,
collision_end = 32,
collision_start = 64,
control = 128,
dataserver = 256,
email = 512,
http_response = 1024,
land_collision = 2048,
land_collision_end = 4096,
land_collision_start = 8192,
at_target = 16384,
listen = 32768,
money = 65536,
moving_end = 131072,
moving_start = 262144,
not_at_rot_target = 524288,
not_at_target = 1048576,
remote_data = 8388608,
run_time_permissions = 268435456,
state_entry = 1073741824,
state_exit = 2,
timer = 4,
touch = 8,
touch_end = 536870912,
touch_start = 2097152,
object_rez = 4194304
}
/// <summary>
/// Create a new instance of ExecutorBase
/// </summary>
/// <param name="Script"></param>
public ExecutorBase(IScript Script)
{
m_Script = Script;
initEventFlags();
}
/// <summary>
/// Make sure our object does not timeout when in AppDomain. (Called by ILease base class)
/// </summary>
/// <returns></returns>
public override Object InitializeLifetimeService()
{
//Console.WriteLine("Executor: InitializeLifetimeService()");
// return null;
ILease lease = (ILease)base.InitializeLifetimeService();
if (lease.CurrentState == LeaseState.Initial)
{
lease.InitialLeaseTime = TimeSpan.Zero; // TimeSpan.FromMinutes(1);
// lease.SponsorshipTimeout = TimeSpan.FromMinutes(2);
// lease.RenewOnCallTime = TimeSpan.FromSeconds(2);
}
return lease;
}
/// <summary>
/// Get current AppDomain
/// </summary>
/// <returns>Current AppDomain</returns>
public AppDomain GetAppDomain()
{
return AppDomain.CurrentDomain;
}
/// <summary>
/// Execute a specific function/event in script.
/// </summary>
/// <param name="FunctionName">Name of function to execute</param>
/// <param name="args">Arguments to pass to function</param>
public void ExecuteEvent(string FunctionName, object[] args)
{
DoExecuteEvent(FunctionName, args);
}
protected abstract void DoExecuteEvent(string FunctionName, object[] args);
/// <summary>
/// Compute the events handled by the current state of the script
/// </summary>
/// <returns>state mask</returns>
public scriptEvents GetStateEventFlags()
{
return DoGetStateEventFlags();
}
protected abstract scriptEvents DoGetStateEventFlags();
protected void initEventFlags()
{
// Initialize the table if it hasn't already been done
if (m_eventFlagsMap.Count > 0)
{
return;
}
m_eventFlagsMap.Add("attach", scriptEvents.attach);
// m_eventFlagsMap.Add("at_rot_target",(long)scriptEvents.at_rot_target);
m_eventFlagsMap.Add("at_target", scriptEvents.at_target);
// m_eventFlagsMap.Add("changed",(long)scriptEvents.changed);
m_eventFlagsMap.Add("collision", scriptEvents.collision);
m_eventFlagsMap.Add("collision_end", scriptEvents.collision_end);
m_eventFlagsMap.Add("collision_start", scriptEvents.collision_start);
m_eventFlagsMap.Add("control", scriptEvents.control);
m_eventFlagsMap.Add("dataserver", scriptEvents.dataserver);
m_eventFlagsMap.Add("email", scriptEvents.email);
m_eventFlagsMap.Add("http_response", scriptEvents.http_response);
m_eventFlagsMap.Add("land_collision", scriptEvents.land_collision);
m_eventFlagsMap.Add("land_collision_end", scriptEvents.land_collision_end);
m_eventFlagsMap.Add("land_collision_start", scriptEvents.land_collision_start);
// m_eventFlagsMap.Add("link_message",scriptEvents.link_message);
m_eventFlagsMap.Add("listen", scriptEvents.listen);
m_eventFlagsMap.Add("money", scriptEvents.money);
m_eventFlagsMap.Add("moving_end", scriptEvents.moving_end);
m_eventFlagsMap.Add("moving_start", scriptEvents.moving_start);
m_eventFlagsMap.Add("not_at_rot_target", scriptEvents.not_at_rot_target);
m_eventFlagsMap.Add("not_at_target", scriptEvents.not_at_target);
// m_eventFlagsMap.Add("no_sensor",(long)scriptEvents.no_sensor);
// m_eventFlagsMap.Add("on_rez",(long)scriptEvents.on_rez);
m_eventFlagsMap.Add("remote_data", scriptEvents.remote_data);
m_eventFlagsMap.Add("run_time_permissions", scriptEvents.run_time_permissions);
// m_eventFlagsMap.Add("sensor",(long)scriptEvents.sensor);
m_eventFlagsMap.Add("state_entry", scriptEvents.state_entry);
m_eventFlagsMap.Add("state_exit", scriptEvents.state_exit);
m_eventFlagsMap.Add("timer", scriptEvents.timer);
m_eventFlagsMap.Add("touch", scriptEvents.touch);
m_eventFlagsMap.Add("touch_end", scriptEvents.touch_end);
m_eventFlagsMap.Add("touch_start", scriptEvents.touch_start);
m_eventFlagsMap.Add("object_rez", scriptEvents.object_rez);
}
}
}

View File

@ -0,0 +1,363 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS AS IS AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
namespace OpenSim.Region.ScriptEngine.XEngine
{
public class LSL2CSConverter
{
// Uses regex to convert LSL code to C# code.
//private Regex rnw = new Regex(@"[a-zA-Z0-9_\-]", RegexOptions.Compiled);
private Dictionary<string, string> dataTypes = new Dictionary<string, string>();
private Dictionary<string, string> quotes = new Dictionary<string, string>();
// c Style
private Regex cstylecomments = new Regex(@"/\*(.|[\r\n])*?\*/", RegexOptions.Compiled | RegexOptions.Multiline);
// c# one liners
private Regex nonCommentFwsl = new Regex("\"[a-zA-Z0-9.,:/\\n ]+//[^\"+]+([\\\\\\\"+]+)?(\\s+)?[\"+](\\s+)?(;)?", RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline);
private Regex conelinecomments = new Regex(@"[^:].?([\/]{2}[^\n]*)|([\n]{1,}[\/]{2}[^\n]*)", RegexOptions.Compiled | RegexOptions.Multiline);
// ([^\"])((?:[a-zA-Z])\.[a-zA-Z].?)([^\"])
// value we're looking for: (?:[a-zA-Z])\.[a-zA-Z]
public LSL2CSConverter()
{
// Only the types we need to convert
dataTypes.Add("void", "void");
dataTypes.Add("integer", "LSL_Types.LSLInteger");
dataTypes.Add("float", "double");
dataTypes.Add("string", "LSL_Types.LSLString");
dataTypes.Add("key", "LSL_Types.LSLString");
dataTypes.Add("vector", "LSL_Types.Vector3");
dataTypes.Add("rotation", "LSL_Types.Quaternion");
dataTypes.Add("list", "LSL_Types.list");
dataTypes.Add("null", "null");
}
public string Convert(string Script)
{
quotes.Clear();
string Return = String.Empty;
Script = " \r\n" + Script;
//
// Prepare script for processing
//
// Clean up linebreaks
Script = Regex.Replace(Script, @"\r\n", "\n");
Script = Regex.Replace(Script, @"\n", "\r\n");
// QUOTE REPLACEMENT
// temporarily replace quotes so we can work our magic on the script without
// always considering if we are inside our outside quotes's
// TODO: Does this work on half-quotes in strings? ;)
string _Script = String.Empty;
string C;
bool in_quote = false;
bool quote_replaced = false;
string quote_replacement_string = "Q_U_O_T_E_REPLACEMENT_";
string quote = String.Empty;
bool last_was_escape = false;
int quote_replaced_count = 0;
string removefwnoncomments = nonCommentFwsl.Replace(Script, "\"\";");
string removecomments = conelinecomments.Replace(removefwnoncomments, "");
removecomments = cstylecomments.Replace(removecomments, "");
string[] localscript = removecomments.Split('"');
string checkscript = String.Empty;
bool flip = true;
for (int p = 0; p < localscript.Length; p++)
{
//if (localscript[p].Length >= 1)
//{
if (!localscript[p].EndsWith(@"\"))
{
flip = !flip;
//System.Console.WriteLine("Flip:" + flip.ToString() + " - " + localscript[p] + " ! " + localscript[p].EndsWith(@"\").ToString());
}
//}
//else
//{
// flip = !flip;
// System.Console.WriteLine("Flip:" + flip.ToString() + " - " + localscript[p]);
//}
if (!flip)
checkscript += localscript[p];
}
//System.Console.WriteLine("SCRIPT:" + checkscript);
// checks for alpha.alpha way of referring to objects in C#
// ignores alpha.x alpha.y, alpha.z for refering to vector components
Match SecurityM;
// BROKEN: this check is very wrong. It block's any url in strings.
SecurityM = Regex.Match(checkscript, @"(?:[a-zA-Z])\.(?:[a-wA-Z]|[a-zA-Z][a-zA-Z])", RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline);
if (SecurityM.Success)
throw new Exception("CS0103: 'The . symbol cannot be used in LSL except in float values or vector components'. Detected around: " + SecurityM.Captures[0].Value);
SecurityM = Regex.Match(checkscript, @"typeof\s", RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline);
if (SecurityM.Success)
throw new Exception("CS0103: 'The object.typeof method isn't allowed in LSL'");
SecurityM = Regex.Match(checkscript, @"GetType\(", RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline);
if (SecurityM.Success)
throw new Exception("CS0103: 'The object.GetType method isn't allowed in LSL'");
for (int p = 0; p < Script.Length; p++)
{
C = Script.Substring(p, 1);
while (true)
{
// found " and last was not \ so this is not an escaped \"
if (C == "\"" && last_was_escape == false)
{
// Toggle inside/outside quote
in_quote = !in_quote;
if (in_quote)
{
quote_replaced_count++;
}
else
{
if (quote == String.Empty)
{
// We didn't replace quote, probably because of empty string?
_Script += quote_replacement_string +
quote_replaced_count.ToString().PadLeft(5, "0".ToCharArray()[0]);
}
// We just left a quote
quotes.Add(
quote_replacement_string +
quote_replaced_count.ToString().PadLeft(5, "0".ToCharArray()[0]), quote);
quote = String.Empty;
}
break;
}
if (!in_quote)
{
// We are not inside a quote
quote_replaced = false;
}
else
{
// We are inside a quote
if (!quote_replaced)
{
// Replace quote
_Script += quote_replacement_string +
quote_replaced_count.ToString().PadLeft(5, "0".ToCharArray()[0]);
quote_replaced = true;
}
quote += C;
break;
}
_Script += C;
break;
}
last_was_escape = false;
if (C == @"\")
{
last_was_escape = true;
}
}
Script = _Script;
//
// END OF QUOTE REPLACEMENT
//
//
// PROCESS STATES
// Remove state definitions and add state names to start of each event within state
//
int ilevel = 0;
int lastlevel = 0;
string ret = String.Empty;
string cache = String.Empty;
bool in_state = false;
string current_statename = String.Empty;
for (int p = 0; p < Script.Length; p++)
{
C = Script.Substring(p, 1);
while (true)
{
// inc / dec level
if (C == @"{")
ilevel++;
if (C == @"}")
ilevel--;
if (ilevel < 0)
ilevel = 0;
cache += C;
// if level == 0, add to return
if (ilevel == 1 && lastlevel == 0)
{
// 0 => 1: Get last
Match m =
//Regex.Match(cache, @"(?![a-zA-Z_]+)\s*([a-zA-Z_]+)[^a-zA-Z_\(\)]*{",
Regex.Match(cache, @"(?![a-zA-Z_]+)\s*(state\s+)?(?<statename>[a-zA-Z_][a-zA-Z_0-9]*)[^a-zA-Z_0-9\(\)]*{",
RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline);
in_state = false;
if (m.Success)
{
// Go back to level 0, this is not a state
in_state = true;
current_statename = m.Groups["statename"].Captures[0].Value;
//Console.WriteLine("Current statename: " + current_statename);
cache =
//@"(?<s1>(?![a-zA-Z_]+)\s*)" + @"([a-zA-Z_]+)(?<s2>[^a-zA-Z_\(\)]*){",
Regex.Replace(cache,
@"(?<s1>(?![a-zA-Z_]+)\s*)" + @"(state\s+)?([a-zA-Z_][a-zA-Z_0-9]*)(?<s2>[^a-zA-Z_0-9\(\)]*){",
"${s1}${s2}",
RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline | RegexOptions.IgnoreCase);
}
ret += cache;
cache = String.Empty;
}
if (ilevel == 0 && lastlevel == 1)
{
// 1 => 0: Remove last }
if (in_state == true)
{
cache = cache.Remove(cache.Length - 1, 1);
//cache = Regex.Replace(cache, "}$", String.Empty, RegexOptions.Multiline | RegexOptions.Singleline);
//Replace function names
// void dataserver(key query_id, string data) {
//cache = Regex.Replace(cache, @"([^a-zA-Z_]\s*)((?!if|switch|for)[a-zA-Z_]+\s*\([^\)]*\)[^{]*{)", "$1" + "<STATE>" + "$2", RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline);
//Console.WriteLine("Replacing using statename: " + current_statename);
cache =
Regex.Replace(cache,
@"^(\s*)((?!(if|switch|for|while)[^a-zA-Z0-9_])[a-zA-Z0-9_]*\s*\([^\)]*\)[^;]*\{)",
@"$1public " + current_statename + "_event_$2",
RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline | RegexOptions.IgnoreCase);
}
ret += cache;
cache = String.Empty;
in_state = true;
current_statename = String.Empty;
}
break;
}
lastlevel = ilevel;
}
ret += cache;
cache = String.Empty;
Script = ret;
ret = String.Empty;
foreach (string key in dataTypes.Keys)
{
string val;
dataTypes.TryGetValue(key, out val);
// Replace CAST - (integer) with (int)
Script =
Regex.Replace(Script, @"\(" + key + @"\)", @"(" + val + ")",
RegexOptions.Compiled | RegexOptions.Multiline);
// Replace return types and function variables - integer a() and f(integer a, integer a)
Script =
Regex.Replace(Script, @"(^|;|}|[\(,])(\s*)" + key + @"(\s+)", @"$1$2" + val + "$3",
RegexOptions.Compiled | RegexOptions.Multiline);
Script =
Regex.Replace(Script, @"(^|;|}|[\(,])(\s*)" + key + @"(\s*)[,]", @"$1$2" + val + "$3,",
RegexOptions.Compiled | RegexOptions.Multiline);
}
// Add "void" in front of functions that needs it
Script =
Regex.Replace(Script,
@"^(\s*public\s+)?((?!(if|switch|for)[^a-zA-Z0-9_])[a-zA-Z0-9_]*\s*\([^\)]*\)[^;]*\{)",
@"$1void $2", RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline);
// Replace <x,y,z> and <x,y,z,r>
Script =
Regex.Replace(Script, @"<([^,>;]*,[^,>;]*,[^,>;]*,[^,>;]*)>", @"new LSL_Types.Quaternion($1)",
RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline);
Script =
Regex.Replace(Script, @"<([^,>;)]*,[^,>;]*,[^,>;]*)>", @"new LSL_Types.Vector3($1)",
RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline);
// Replace List []'s
Script =
Regex.Replace(Script, @"\[([^\]]*)\]", @"new LSL_Types.list($1)",
RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline);
// Replace (string) to .ToString() //
Script =
Regex.Replace(Script, @"\(string\)\s*([a-zA-Z0-9_.]+(\s*\([^\)]*\))?)", @"$1.ToString()",
RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline);
Script =
Regex.Replace(Script, @"\((float|int)\)\s*([a-zA-Z0-9_.]+(\s*\([^\)]*\))?)", @"$1.Parse($2)",
RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline);
// Replace "state STATENAME" with "state("statename")"
Script =
Regex.Replace(Script, @"(state)\s+([^;\n\r]+)(;[\r\n\s])", "$1(\"$2\")$3",
RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline | RegexOptions.IgnoreCase);
// REPLACE BACK QUOTES
foreach (string key in quotes.Keys)
{
string val;
quotes.TryGetValue(key, out val);
Script = Script.Replace(key, "\"" + val + "\"");
}
//System.Console.WriteLine(Script);
Return = String.Empty;// +
//"using OpenSim.Region.ScriptEngine.Common; using System.Collections.Generic;";
//Return += String.Empty +
// "namespace SecondLife { ";
//Return += String.Empty +
// //"[Serializable] " +
// "public class Script : OpenSim.Region.ScriptEngine.Common.LSL_BaseClass { ";
//Return += @"public Script() { } ";
Return += Script;
//Return += "} }\r\n";
quotes.Clear();
return Return;
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,553 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using Axiom.Math;
using libsecondlife;
using Nini.Config;
using OpenSim.Framework.Console;
using OpenSim.Region.Environment.Interfaces;
using OpenSim.Region.Environment.Scenes;
using OpenSim.Region.ScriptEngine.XEngine.Script;
namespace OpenSim.Region.ScriptEngine.XEngine
{
[Serializable]
public class OSSL_ScriptCommands : MarshalByRefObject, IOSSL_ScriptCommands
{
internal XEngine m_ScriptEngine;
internal XScriptInstance m_Instance;
internal SceneObjectPart m_host;
internal uint m_localID;
internal LLUUID m_itemID;
public OSSL_ScriptCommands(XEngine scriptEngine,
XScriptInstance instance, SceneObjectPart host,
uint localID, LLUUID itemID)
{
m_ScriptEngine = scriptEngine;
m_Instance = instance;
m_host = host;
m_localID = localID;
m_itemID = itemID;
}
//
// OpenSim functions
//
public int osTerrainSetHeight(int x, int y, double val)
{
if (!m_ScriptEngine.ScriptConfigSource.GetBoolean("AllowOSFunctions", false))
{
OSSLError("osTerrainSetHeight: permission denied");
return 0;
}
m_host.AddScriptLPS(1);
if (x > 255 || x < 0 || y > 255 || y < 0)
OSSLError("osTerrainSetHeight: Coordinate out of bounds");
if (World.ExternalChecks.ExternalChecksCanTerraformLand(m_host.OwnerID, new LLVector3(x, y, 0)))
{
World.Heightmap[x, y] = val;
return 1;
}
else
{
return 0;
}
}
public double osTerrainGetHeight(int x, int y)
{
if (!m_ScriptEngine.ScriptConfigSource.GetBoolean("AllowOSFunctions", false))
{
OSSLError("osTerrainGetHeight: permission denied");
return 0.0;
}
m_host.AddScriptLPS(1);
if (x > 255 || x < 0 || y > 255 || y < 0)
OSSLError("osTerrainGetHeight: Coordinate out of bounds");
return World.Heightmap[x, y];
}
public int osRegionRestart(double seconds)
{
if (!m_ScriptEngine.ScriptConfigSource.GetBoolean("AllowOSFunctions", false))
{
OSSLError("osRegionRestart: permission denied");
return 0;
}
m_host.AddScriptLPS(1);
if (World.ExternalChecks.ExternalChecksCanIssueEstateCommand(m_host.OwnerID))
{
World.Restart((float)seconds);
return 1;
}
else
{
return 0;
}
}
public void osRegionNotice(string msg)
{
if (!m_ScriptEngine.ScriptConfigSource.GetBoolean("AllowOSFunctions", false))
{
OSSLError("osRegionNotice: permission denied");
return;
}
m_host.AddScriptLPS(1);
World.SendGeneralAlert(msg);
}
public void osSetRot(LLUUID target, Quaternion rotation)
{
if (!m_ScriptEngine.ScriptConfigSource.GetBoolean("AllowOSFunctions", false))
{
OSSLError("osSetRot: permission denied");
return;
}
m_host.AddScriptLPS(1);
if (World.Entities.ContainsKey(target))
{
World.Entities[target].Rotation = rotation;
}
else
{
OSSLError("osSetRot: Invalid target");
}
}
public string osSetDynamicTextureURL(string dynamicID, string contentType, string url, string extraParams,
int timer)
{
if (!m_ScriptEngine.ScriptConfigSource.GetBoolean("AllowOSFunctions", false))
{
OSSLError("osSetDynamicTextureURL: permission denied");
return String.Empty;
}
m_host.AddScriptLPS(1);
if (dynamicID == String.Empty)
{
IDynamicTextureManager textureManager = World.RequestModuleInterface<IDynamicTextureManager>();
LLUUID createdTexture =
textureManager.AddDynamicTextureURL(World.RegionInfo.RegionID, m_host.UUID, contentType, url,
extraParams, timer);
return createdTexture.ToString();
}
else
{
//TODO update existing dynamic textures
}
return LLUUID.Zero.ToString();
}
public string osSetDynamicTextureURLBlend(string dynamicID, string contentType, string url, string extraParams,
int timer, int alpha)
{
if (!m_ScriptEngine.ScriptConfigSource.GetBoolean("AllowOSFunctions", false))
{
OSSLError("osSetDynamicTextureURLBlend: permission denied");
return String.Empty;
}
m_host.AddScriptLPS(1);
if (dynamicID == String.Empty)
{
IDynamicTextureManager textureManager = World.RequestModuleInterface<IDynamicTextureManager>();
LLUUID createdTexture =
textureManager.AddDynamicTextureURL(World.RegionInfo.RegionID, m_host.UUID, contentType, url,
extraParams, timer, true, (byte) alpha);
return createdTexture.ToString();
}
else
{
//TODO update existing dynamic textures
}
return LLUUID.Zero.ToString();
}
public string osSetDynamicTextureData(string dynamicID, string contentType, string data, string extraParams,
int timer)
{
if (!m_ScriptEngine.ScriptConfigSource.GetBoolean("AllowOSFunctions", false))
{
OSSLError("osSetDynamicTextureData: permission denied");
return String.Empty;
}
m_host.AddScriptLPS(1);
if (dynamicID == String.Empty)
{
IDynamicTextureManager textureManager = World.RequestModuleInterface<IDynamicTextureManager>();
if (textureManager != null)
{
LLUUID createdTexture =
textureManager.AddDynamicTextureData(World.RegionInfo.RegionID, m_host.UUID, contentType, data,
extraParams, timer);
return createdTexture.ToString();
}
}
else
{
//TODO update existing dynamic textures
}
return LLUUID.Zero.ToString();
}
public string osSetDynamicTextureDataBlend(string dynamicID, string contentType, string data, string extraParams,
int timer, int alpha)
{
if (!m_ScriptEngine.ScriptConfigSource.GetBoolean("AllowOSFunctions", false))
{
OSSLError("osSetDynamicTextureDataBlend: permission denied");
return String.Empty;
}
m_host.AddScriptLPS(1);
if (dynamicID == String.Empty)
{
IDynamicTextureManager textureManager = World.RequestModuleInterface<IDynamicTextureManager>();
if (textureManager != null)
{
LLUUID createdTexture =
textureManager.AddDynamicTextureData(World.RegionInfo.RegionID, m_host.UUID, contentType, data,
extraParams, timer, true, (byte) alpha);
return createdTexture.ToString();
}
}
else
{
//TODO update existing dynamic textures
}
return LLUUID.Zero.ToString();
}
public bool osConsoleCommand(string command)
{
m_host.AddScriptLPS(1);
if (m_ScriptEngine.ScriptConfigSource.GetBoolean("AllowosConsoleCommand", false))
{
if (World.ExternalChecks.ExternalChecksCanRunConsoleCommand(m_host.OwnerID))
{
MainConsole.Instance.RunCommand(command);
return true;
}
return false;
}
return false;
}
public void osSetPrimFloatOnWater(int floatYN)
{
if (!m_ScriptEngine.ScriptConfigSource.GetBoolean("AllowOSFunctions", false))
{
OSSLError("osSetPrimFloatOnWater: permission denied");
return;
}
m_host.AddScriptLPS(1);
if (m_host.ParentGroup != null)
{
if (m_host.ParentGroup.RootPart != null)
{
m_host.ParentGroup.RootPart.SetFloatOnWater(floatYN);
}
}
}
// Adam's super super custom animation functions
public void osAvatarPlayAnimation(string avatar, string animation)
{
if (!m_ScriptEngine.ScriptConfigSource.GetBoolean("AllowOSFunctions", false))
{
OSSLError("osAvatarPlayAnimation: permission denied");
return;
}
m_host.AddScriptLPS(1);
if (World.Entities.ContainsKey(avatar) && World.Entities[avatar] is ScenePresence)
{
ScenePresence target = (ScenePresence)World.Entities[avatar];
target.AddAnimation(avatar);
}
}
public void osAvatarStopAnimation(string avatar, string animation)
{
if (!m_ScriptEngine.ScriptConfigSource.GetBoolean("AllowOSFunctions", false))
{
OSSLError("osAvatarStopAnimation: permission denied");
return;
}
m_host.AddScriptLPS(1);
if (World.Entities.ContainsKey(avatar) && World.Entities[avatar] is ScenePresence)
{
ScenePresence target = (ScenePresence)World.Entities[avatar];
target.RemoveAnimation(animation);
}
}
//Texture draw functions
public string osMovePen(string drawList, int x, int y)
{
if (!m_ScriptEngine.ScriptConfigSource.GetBoolean("AllowOSFunctions", false))
{
OSSLError("osMovePen: permission denied");
return String.Empty;
}
m_host.AddScriptLPS(1);
drawList += "MoveTo " + x + "," + y + ";";
return drawList;
}
public string osDrawLine(string drawList, int startX, int startY, int endX, int endY)
{
if (!m_ScriptEngine.ScriptConfigSource.GetBoolean("AllowOSFunctions", false))
{
OSSLError("osDrawLine: permission denied");
return String.Empty;
}
m_host.AddScriptLPS(1);
drawList += "MoveTo "+ startX+","+ startY +"; LineTo "+endX +","+endY +"; ";
return drawList;
}
public string osDrawLine(string drawList, int endX, int endY)
{
if (!m_ScriptEngine.ScriptConfigSource.GetBoolean("AllowOSFunctions", false))
{
OSSLError("osDrawLine: permission denied");
return String.Empty;
}
m_host.AddScriptLPS(1);
drawList += "LineTo " + endX + "," + endY + "; ";
return drawList;
}
public string osDrawText(string drawList, string text)
{
if (!m_ScriptEngine.ScriptConfigSource.GetBoolean("AllowOSFunctions", false))
{
OSSLError("osDrawText: permission denied");
return String.Empty;
}
m_host.AddScriptLPS(1);
drawList += "Text " + text + "; ";
return drawList;
}
public string osDrawEllipse(string drawList, int width, int height)
{
if (!m_ScriptEngine.ScriptConfigSource.GetBoolean("AllowOSFunctions", false))
{
OSSLError("osDrawEllipse: permission denied");
return String.Empty;
}
m_host.AddScriptLPS(1);
drawList += "Ellipse " + width + "," + height + "; ";
return drawList;
}
public string osDrawRectangle(string drawList, int width, int height)
{
if (!m_ScriptEngine.ScriptConfigSource.GetBoolean("AllowOSFunctions", false))
{
OSSLError("osDrawRectangle: permission denied");
return String.Empty;
}
m_host.AddScriptLPS(1);
drawList += "Rectangle " + width + "," + height + "; ";
return drawList;
}
public string osDrawFilledRectangle(string drawList, int width, int height)
{
if (!m_ScriptEngine.ScriptConfigSource.GetBoolean("AllowOSFunctions", false))
{
OSSLError("osDrawFilledRectangle: permission denied");
return String.Empty;
}
m_host.AddScriptLPS(1);
drawList += "FillRectangle " + width + "," + height + "; ";
return drawList;
}
public string osSetFontSize(string drawList, int fontSize)
{
if (!m_ScriptEngine.ScriptConfigSource.GetBoolean("AllowOSFunctions", false))
{
OSSLError("osSetFontSize: permission denied");
return String.Empty;
}
m_host.AddScriptLPS(1);
drawList += "FontSize "+ fontSize +"; ";
return drawList;
}
public string osSetPenSize(string drawList, int penSize)
{
if (!m_ScriptEngine.ScriptConfigSource.GetBoolean("AllowOSFunctions", false))
{
OSSLError("osSetPenSize: permission denied");
return String.Empty;
}
m_host.AddScriptLPS(1);
drawList += "PenSize " + penSize + "; ";
return drawList;
}
public string osSetPenColour(string drawList, string colour)
{
if (!m_ScriptEngine.ScriptConfigSource.GetBoolean("AllowOSFunctions", false))
{
OSSLError("osSetPenColour: permission denied");
return String.Empty;
}
m_host.AddScriptLPS(1);
drawList += "PenColour " + colour + "; ";
return drawList;
}
public string osDrawImage(string drawList, int width, int height, string imageUrl)
{
if (!m_ScriptEngine.ScriptConfigSource.GetBoolean("AllowOSFunctions", false))
{
OSSLError("osDrawImage: permission denied");
return String.Empty;
}
m_host.AddScriptLPS(1);
drawList +="Image " +width + "," + height+ ","+ imageUrl +"; " ;
return drawList;
}
public void osSetStateEvents(int events)
{
if (!m_ScriptEngine.ScriptConfigSource.GetBoolean("AllowOSFunctions", false))
{
OSSLError("osSetStateEvents: permission denied");
return;
}
m_host.SetScriptEvents(m_itemID, events);
}
public void osSetRegionWaterHeight(double height)
{
if (!m_ScriptEngine.ScriptConfigSource.GetBoolean("AllowOSFunctions", false))
{
OSSLError("osSetRegionWaterHeight: permission denied");
return;
}
m_host.AddScriptLPS(1);
//Check to make sure that the script's owner is the estate manager/master
//World.Permissions.GenericEstatePermission(
if (World.ExternalChecks.ExternalChecksCanBeGodLike(m_host.OwnerID))
{
World.EventManager.TriggerRequestChangeWaterHeight((float)height);
}
}
public double osList2Double(LSL_Types.list src, int index)
{
if (!m_ScriptEngine.ScriptConfigSource.GetBoolean("AllowOSFunctions", false))
{
OSSLError("osList2Double: permission denied");
return 0.0;
}
m_host.AddScriptLPS(1);
if (index < 0)
{
index = src.Length + index;
}
if (index >= src.Length)
{
return 0.0;
}
return Convert.ToDouble(src.Data[index]);
}
public void osSetParcelMediaURL(string url)
{
if (!m_ScriptEngine.ScriptConfigSource.GetBoolean("AllowOSFunctions", false))
{
OSSLError("osSetParcelMediaURL: permission denied");
return;
}
m_host.AddScriptLPS(1);
LLUUID landowner = World.GetLandOwner(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y);
if (landowner == LLUUID.Zero)
{
return;
}
if (landowner != m_host.ObjectOwner)
{
return;
}
World.SetLandMediaURL(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y, url);
}
public Scene World
{
get { return m_ScriptEngine.World; }
}
internal void OSSLError(string msg)
{
throw new Exception("OSSL Runtime Error: " + msg);
}
}
}

View File

@ -0,0 +1,65 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.IO;
using System.Reflection;
namespace OpenSim.Region.ScriptEngine.XEngine.Script
{
[Serializable]
public class AssemblyResolver
{
public static Assembly OnAssemblyResolve(object sender,
ResolveEventArgs args)
{
if(!(sender is System.AppDomain))
return null;
AppDomain myDomain = (AppDomain)sender;
string dirName = myDomain.FriendlyName;
string[] pathList=new string[] {"bin", "ScriptEngines",
Path.Combine("ScriptEngines", dirName)};
string assemblyName = args.Name;
if(assemblyName.IndexOf(",") != -1)
assemblyName=args.Name.Substring(0, args.Name.IndexOf(","));
foreach (string s in pathList)
{
string path=Path.Combine(Directory.GetCurrentDirectory(),
Path.Combine(s, assemblyName))+".dll";
if(File.Exists(path))
return Assembly.LoadFrom(path);
}
return null;
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,653 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using OpenSim.Region.Environment.Interfaces;
namespace OpenSim.Region.ScriptEngine.XEngine.Script
{
public interface ILSL_ScriptCommands
{
// Interface used for loading and executing scripts
string State { get; set ; }
void state(string newState);
ICommander GetCommander(string name);
void llSay(int channelID, string text);
double llSin(double f);
double llCos(double f);
double llTan(double f);
double llAtan2(double x, double y);
double llSqrt(double f);
double llPow(double fbase, double fexponent);
LSL_Types.LSLInteger llAbs(int i);
double llFabs(double f);
double llFrand(double mag);
LSL_Types.LSLInteger llFloor(double f);
LSL_Types.LSLInteger llCeil(double f);
LSL_Types.LSLInteger llRound(double f);
double llVecMag(LSL_Types.Vector3 v);
LSL_Types.Vector3 llVecNorm(LSL_Types.Vector3 v);
double llVecDist(LSL_Types.Vector3 a, LSL_Types.Vector3 b);
LSL_Types.Vector3 llRot2Euler(LSL_Types.Quaternion r);
LSL_Types.Quaternion llEuler2Rot(LSL_Types.Vector3 v);
LSL_Types.Quaternion llAxes2Rot(LSL_Types.Vector3 fwd, LSL_Types.Vector3 left, LSL_Types.Vector3 up);
LSL_Types.Vector3 llRot2Fwd(LSL_Types.Quaternion r);
LSL_Types.Vector3 llRot2Left(LSL_Types.Quaternion r);
LSL_Types.Vector3 llRot2Up(LSL_Types.Quaternion r);
LSL_Types.Quaternion llRotBetween(LSL_Types.Vector3 start, LSL_Types.Vector3 end);
void llWhisper(int channelID, string text);
//void llSay(int channelID, string text);
void llShout(int channelID, string text);
void llRegionSay(int channelID, string text);
LSL_Types.LSLInteger llListen(int channelID, string name, string ID, string msg);
void llListenControl(int number, int active);
void llListenRemove(int number);
void llSensor(string name, string id, int type, double range, double arc);
void llSensorRepeat(string name, string id, int type, double range, double arc, double rate);
void llSensorRemove();
string llDetectedName(int number);
string llDetectedKey(int number);
string llDetectedOwner(int number);
LSL_Types.LSLInteger llDetectedType(int number);
LSL_Types.Vector3 llDetectedPos(int number);
LSL_Types.Vector3 llDetectedVel(int number);
LSL_Types.Vector3 llDetectedGrab(int number);
LSL_Types.Quaternion llDetectedRot(int number);
LSL_Types.LSLInteger llDetectedGroup(int number);
LSL_Types.LSLInteger llDetectedLinkNumber(int number);
void llDie();
double llGround(LSL_Types.Vector3 offset);
double llCloud(LSL_Types.Vector3 offset);
LSL_Types.Vector3 llWind(LSL_Types.Vector3 offset);
void llSetStatus(int status, int value);
LSL_Types.LSLInteger llGetStatus(int status);
void llSetScale(LSL_Types.Vector3 scale);
LSL_Types.Vector3 llGetScale();
void llSetColor(LSL_Types.Vector3 color, int face);
double llGetAlpha(int face);
void llSetAlpha(double alpha, int face);
LSL_Types.Vector3 llGetColor(int face);
void llSetTexture(string texture, int face);
void llScaleTexture(double u, double v, int face);
void llOffsetTexture(double u, double v, int face);
void llRotateTexture(double rotation, int face);
string llGetTexture(int face);
void llSetPos(LSL_Types.Vector3 pos);
//wiki: vector llGetPos()
LSL_Types.Vector3 llGetPos();
//wiki: vector llGetLocalPos()
LSL_Types.Vector3 llGetLocalPos();
//wiki: llSetRot(rotation rot)
void llSetRot(LSL_Types.Quaternion rot);
//wiki: rotation llGetRot()
LSL_Types.Quaternion llGetRot();
//wiki: rotation llGetLocalRot()
LSL_Types.Quaternion llGetLocalRot();
//wiki: llSetForce(vector force, integer local)
void llSetForce(LSL_Types.Vector3 force, int local);
//wiki: vector llGetForce()
LSL_Types.Vector3 llGetForce();
//wiki: integer llTarget(vector position, double range)
LSL_Types.LSLInteger llTarget(LSL_Types.Vector3 position, double range);
//wiki: llTargetRemove(integer number)
void llTargetRemove(int number);
//wiki: integer llRotTarget(rotation rot, double error)
LSL_Types.LSLInteger llRotTarget(LSL_Types.Quaternion rot, double error);
//wiki: integer llRotTargetRemove(integer number)
void llRotTargetRemove(int number);
//wiki: llMoveToTarget(vector target, double tau)
void llMoveToTarget(LSL_Types.Vector3 target, double tau);
//wiki: llStopMoveToTarget()
void llStopMoveToTarget();
//wiki: llApplyImpulse(vector force, integer local)
void llApplyImpulse(LSL_Types.Vector3 force, int local);
//wiki: llapplyRotationalImpulse(vector force, integer local)
void llApplyRotationalImpulse(LSL_Types.Vector3 force, int local);
//wiki: llSetTorque(vector torque, integer local)
void llSetTorque(LSL_Types.Vector3 torque, int local);
//wiki: vector llGetTorque()
LSL_Types.Vector3 llGetTorque();
//wiki: llSeForceAndTorque(vector force, vector torque, integer local)
void llSetForceAndTorque(LSL_Types.Vector3 force, LSL_Types.Vector3 torque, int local);
//wiki: vector llGetVel()
LSL_Types.Vector3 llGetVel();
//wiki: vector llGetAccel()
LSL_Types.Vector3 llGetAccel();
//wiki: vector llGetOmega()
LSL_Types.Vector3 llGetOmega();
//wiki: double llGetTimeOfDay()
double llGetTimeOfDay();
//wiki: double llGetWallclock()
double llGetWallclock();
//wiki: double llGetTime()
double llGetTime();
//wiki: llResetTime()
void llResetTime();
//wiki: double llGetAndResetTime()
double llGetAndResetTime();
//wiki (deprecated) llSound(string sound, double volume, integer queue, integer loop)
void llSound();
//wiki: llPlaySound(string sound, double volume)
void llPlaySound(string sound, double volume);
//wiki: llLoopSound(string sound, double volume)
void llLoopSound(string sound, double volume);
//wiki: llLoopSoundMaster(string sound, double volume)
void llLoopSoundMaster(string sound, double volume);
//wiki: llLoopSoundSlave(string sound, double volume)
void llLoopSoundSlave(string sound, double volume);
//wiki llPlaySoundSlave(string sound, double volume)
void llPlaySoundSlave(string sound, double volume);
//wiki: llTriggerSound(string sound, double volume)
void llTriggerSound(string sound, double volume);
//wiki: llStopSound()
void llStopSound();
//wiki: llPreloadSound(string sound)
void llPreloadSound(string sound);
//wiki: string llGetSubString(string src, integer start, integer end)
string llGetSubString(string src, int start, int end);
//wiki: string llDeleteSubString(string src, integer start, integer end)
string llDeleteSubString(string src, int start, int end);
//wiki string llInsertString(string dst, integer position, string src)
string llInsertString(string dst, int position, string src);
//wiki: string llToUpper(string source)
string llToUpper(string source);
//wiki: string llToLower(string source)
string llToLower(string source);
//wiki: integer llGiveMoney(key destination, integer amount)
LSL_Types.LSLInteger llGiveMoney(string destination, int amount);
//wiki: (deprecated)
void llMakeExplosion();
//wiki: (deprecated)
void llMakeFountain();
//wiki: (deprecated)
void llMakeSmoke();
//wiki: (deprecated)
void llMakeFire();
//wiki: llRezObject(string inventory, vector pos, vector rel, rotation rot, integer param)
void llRezObject(string inventory, LSL_Types.Vector3 pos, LSL_Types.Vector3 vel, LSL_Types.Quaternion rot, int param);
//wiki: llLookAt(vector target, double strength, double damping)
void llLookAt(LSL_Types.Vector3 target, double strength, double damping);
//wiki: llStopLookAt()
void llStopLookAt();
//wiki: llSetTimerEvent(double sec)
void llSetTimerEvent(double sec);
//wiki: llSleep(double sec)
void llSleep(double sec);
//wiki: double llGetMass()
double llGetMass();
//wiki: llCollisionFilter(string name, key id, integer accept)
void llCollisionFilter(string name, string id, int accept);
//wiki: llTakeControls(integer controls, integer accept, integer pass_on)
void llTakeControls(int controls, int accept, int pass_on);
//wiki: llReleaseControls()
void llReleaseControls();
//wiki: llAttachToAvatar(integer attachment)
void llAttachToAvatar(int attachment);
//wiki: llDetachFromAvatar()
void llDetachFromAvatar();
//wiki: (deprecated) llTakeCamera()
void llTakeCamera();
//wiki: (deprecated) llReleaseCamera()
void llReleaseCamera();
//wiki: key llGetOwner()
string llGetOwner();
//wiki: llInstantMessage(key user, string message)
void llInstantMessage(string user, string message);
//wiki: llEmail(string address, string subject, string message)
void llEmail(string address, string subject, string message);
//wiki: llGetNextEmail(string address, string subject)
void llGetNextEmail(string address, string subject);
//wiki: key llGetKey()
string llGetKey();
//wiki: llSetBuoyancy(double buoyancy)
void llSetBuoyancy(double buoyancy);
//wiki: llSetHoverHeight(double height, integer water, double tau)
void llSetHoverHeight(double height, int water, double tau);
//wiki: llStopHover
void llStopHover();
//wiki: llMinEventDelay(double delay)
void llMinEventDelay(double delay);
//wiki: (deprecated) llSoundPreload()
void llSoundPreload();
//wiki: llRotLookAt(rotation target, double strength, double damping)
void llRotLookAt(LSL_Types.Quaternion target, double strength, double damping);
//wiki: integer llStringLength(string str)
LSL_Types.LSLInteger llStringLength(string str);
//wiki: llStartAnimation(string anim)
void llStartAnimation(string anim);
//wiki: llStopAnimation(string anim)
void llStopAnimation(string anim);
//wiki: (deprecated) llPointAt
void llPointAt();
//wiki: (deprecated) llStopPointAt
void llStopPointAt();
//wiki: llTargetOmega(vector axis, double spinrate, double gain)
void llTargetOmega(LSL_Types.Vector3 axis, double spinrate, double gain);
//wiki: integer llGetStartParameter()
LSL_Types.LSLInteger llGetStartParameter();
//wiki: llGodLikeRezObject(key inventory, vector pos)
void llGodLikeRezObject(string inventory, LSL_Types.Vector3 pos);
//wiki: llRequestPermissions(key agent, integer perm)
void llRequestPermissions(string agent, int perm);
//wiki: key llGetPermissionsKey()
string llGetPermissionsKey();
//wiki: integer llGetPermissions()
LSL_Types.LSLInteger llGetPermissions();
//wiki integer llGetLinkNumber()
LSL_Types.LSLInteger llGetLinkNumber();
//wiki: llSetLinkColor(integer linknumber, vector color, integer face)
void llSetLinkColor(int linknumber, LSL_Types.Vector3 color, int face);
//wiki: llCreateLink(key target, integer parent)
void llCreateLink(string target, int parent);
//wiki: llBreakLink(integer linknum)
void llBreakLink(int linknum);
//wiki: llBreakAllLinks()
void llBreakAllLinks();
//wiki: key llGetLinkKey(integer linknum)
string llGetLinkKey(int linknum);
//wiki: llGetLinkName(integer linknum)
string llGetLinkName(int linknum);
//wiki: integer llGetInventoryNumber(integer type)
LSL_Types.LSLInteger llGetInventoryNumber(int type);
//wiki: string llGetInventoryName(integer type, integer number)
string llGetInventoryName(int type, int number);
//wiki: llSetScriptState(string name, integer run)
void llSetScriptState(string name, int run);
//wiki: double llGetEnergy()
double llGetEnergy();
//wiki: llGiveInventory(key destination, string inventory)
void llGiveInventory(string destination, string inventory);
//wiki: llRemoveInventory(string item)
void llRemoveInventory(string item);
//wiki: llSetText(string text, vector color, double alpha)
void llSetText(string text, LSL_Types.Vector3 color, double alpha);
//wiki: double llWater(vector offset)
double llWater(LSL_Types.Vector3 offset);
//wiki: llPassTouches(integer pass)
void llPassTouches(int pass);
//wiki: key llRequestAgentData(key id, integer data)
string llRequestAgentData(string id, int data);
//wiki: key llRequestInventoryData(string name)
string llRequestInventoryData(string name);
//wiki: llSetDamage(double damage)
void llSetDamage(double damage);
//wiki: llTeleportAgentHome(key agent)
void llTeleportAgentHome(string agent);
//wiki: llModifyLand(integer action, integer brush)
void llModifyLand(int action, int brush);
//wiki: llCollisionSound(string impact_sound, double impact_volume)
void llCollisionSound(string impact_sound, double impact_volume);
//wiki: llCollisionSprite(string impact_sprite)
void llCollisionSprite(string impact_sprite);
//wiki: string llGetAnimation(key id)
string llGetAnimation(string id);
//wiki: llResetScript()
void llResetScript();
//wiki: llMessageLinked(integer linknum, integer num, string str, key id)
void llMessageLinked(int linknum, int num, string str, string id);
//wiki: llPushObject(key target, vector impulse, vector ang_impulse, integer local)
void llPushObject(string target, LSL_Types.Vector3 impulse, LSL_Types.Vector3 ang_impulse, int local);
//wiki: llPassCollisions(integer pass)
void llPassCollisions(int pass);
//wiki: string llGetScriptName()
string llGetScriptName();
//wiki: integer llGetNumberOfSides()
LSL_Types.LSLInteger llGetNumberOfSides();
//wiki: rotation llAxisAngle2Rot(vector axis, double angle)
LSL_Types.Quaternion llAxisAngle2Rot(LSL_Types.Vector3 axis, double angle);
//wiki: vector llRot2Axis(rotation rot)
LSL_Types.Vector3 llRot2Axis(LSL_Types.Quaternion rot);
//wiki: double llRot2Angle(rotation rot);
double llRot2Angle(LSL_Types.Quaternion rot);
//wiki: double llAcos(double val)
double llAcos(double val);
//wiki: double llAsin(double val)
double llAsin(double val);
//wiki: double llAngleBetween(rotation a, rotation b)
double llAngleBetween(LSL_Types.Quaternion a, LSL_Types.Quaternion b);
//wiki: string llGetInventoryKey(string name)
string llGetInventoryKey(string name);
//wiki: llAllowInventoryDrop(integer add)
void llAllowInventoryDrop(int add);
//wiki: vector llGetSunDirection()
LSL_Types.Vector3 llGetSunDirection();
//wiki: vector llGetTextureOffset(integer face)
LSL_Types.Vector3 llGetTextureOffset(int face);
//wiki: vector llGetTextureScale(integer side)
LSL_Types.Vector3 llGetTextureScale(int side);
//wiki: double llGetTextureRot(integer side)
double llGetTextureRot(int side);
//wiki: integer llSubStringIndex(string source, string pattern)
LSL_Types.LSLInteger llSubStringIndex(string source, string pattern);
//wiki: key llGetOwnerKey(key id)
string llGetOwnerKey(string id);
//wiki: vector llGetCenterOfMass()
LSL_Types.Vector3 llGetCenterOfMass();
//wiki: list llListSort(list src, integer stride, integer ascending)
LSL_Types.list llListSort(LSL_Types.list src, int stride, int ascending);
//integer llGetListLength(list src)
LSL_Types.LSLInteger llGetListLength(LSL_Types.list src);
//wiki: integer llList2Integer(list src, integer index)
LSL_Types.LSLInteger llList2Integer(LSL_Types.list src, int index);
//wiki: double llList2double(list src, integer index)
double llList2Float(LSL_Types.list src, int index);
//wiki: string llList2String(list src, integer index)
string llList2String(LSL_Types.list src, int index);
//wiki: key llList2Key(list src, integer index)
string llList2Key(LSL_Types.list src, int index);
//wiki: vector llList2Vector(list src, integer index)
LSL_Types.Vector3 llList2Vector(LSL_Types.list src, int index);
//wiki rotation llList2Rot(list src, integer index)
LSL_Types.Quaternion llList2Rot(LSL_Types.list src, int index);
//wiki: list llList2List(list src, integer start, integer end)
LSL_Types.list llList2List(LSL_Types.list src, int start, int end);
//wiki: llDeleteSubList(list src, integer start, integer end)
LSL_Types.list llDeleteSubList(LSL_Types.list src, int start, int end);
//wiki: integer llGetListEntryType(list src, integer index)
LSL_Types.LSLInteger llGetListEntryType(LSL_Types.list src, int index);
//wiki: string llList2CSV(list src)
string llList2CSV(LSL_Types.list src);
//wiki: list llCSV2List(string src)
LSL_Types.list llCSV2List(string src);
//wiki: list llListRandomize(list src, integer stride)
LSL_Types.list llListRandomize(LSL_Types.list src, int stride);
//wiki: list llList2ListStrided(list src, integer start, integer end, integer stride)
LSL_Types.list llList2ListStrided(LSL_Types.list src, int start, int end, int stride);
//wiki: vector llGetRegionCorner()
LSL_Types.Vector3 llGetRegionCorner();
//wiki: list llListInsertList(list dest, list src, integer start)
LSL_Types.list llListInsertList(LSL_Types.list dest, LSL_Types.list src, int start);
//wiki: integer llListFindList(list src, list test)
LSL_Types.LSLInteger llListFindList(LSL_Types.list src, LSL_Types.list test);
//wiki: string llGetObjectName()
string llGetObjectName();
//wiki: llSetObjectName(string name)
void llSetObjectName(string name);
//wiki: string llGetDate()
string llGetDate();
//wiki: integer llEdgeOfWorld(vector pos, vector dir)
LSL_Types.LSLInteger llEdgeOfWorld(LSL_Types.Vector3 pos, LSL_Types.Vector3 dir);
//wiki: integer llGetAgentInfo(key id)
LSL_Types.LSLInteger llGetAgentInfo(string id);
//wiki: llAdjustSoundVolume(double volume)
void llAdjustSoundVolume(double volume);
//wiki: llSetSoundQueueing(integer queue)
void llSetSoundQueueing(int queue);
//wiki: llSetSoundRadius(double radius)
void llSetSoundRadius(double radius);
//wiki: string llKey2Name(key id)
string llKey2Name(string id);
//wiki: llSetTextureAnim(integer mode, integer face, integer sizex, integer sizey, double start, double length, double rate)
void llSetTextureAnim(int mode, int face, int sizex, int sizey, double start, double length, double rate);
//wiki: llTriggerSoundLimited(string sound, double volume, vector top_north_east, vector bottom_south_west)
void llTriggerSoundLimited(string sound, double volume, LSL_Types.Vector3 top_north_east,
LSL_Types.Vector3 bottom_south_west);
//wiki: llEjectFromLand(key pest)
void llEjectFromLand(string pest);
LSL_Types.list llParseString2List(string str, LSL_Types.list separators, LSL_Types.list spacers);
//wiki: integer llOverMyLand(key id)
LSL_Types.LSLInteger llOverMyLand(string id);
//wiki: key llGetLandOwnerAt(vector pos)
string llGetLandOwnerAt(LSL_Types.Vector3 pos);
//wiki: key llGetNotecardLine(string name, integer line)
string llGetNotecardLine(string name, int line);
//wiki: vector llGetAgentSize(key id)
LSL_Types.Vector3 llGetAgentSize(string id);
//wiki: integer llSameGroup(key agent)
LSL_Types.LSLInteger llSameGroup(string agent);
//wiki: llUnSit(key id)
void llUnSit(string id);
//wiki: vector llGroundSlope(vector offset)
LSL_Types.Vector3 llGroundSlope(LSL_Types.Vector3 offset);
//wiki: vector llGroundNormal(vector offset)
LSL_Types.Vector3 llGroundNormal(LSL_Types.Vector3 offset);
//wiki: vector llGroundContour(vector offset)
LSL_Types.Vector3 llGroundContour(LSL_Types.Vector3 offset);
//wiki: integer llGetAttached()
LSL_Types.LSLInteger llGetAttached();
//wiki: integer llGetFreeMemory()
LSL_Types.LSLInteger llGetFreeMemory();
//wiki: string llGetRegionName()
string llGetRegionName();
//wiki: double llGetRegionTimeDilation()
double llGetRegionTimeDilation();
//wiki: double llGetRegionFPS()
double llGetRegionFPS();
//wiki: llParticleSystem(List<Object> rules
void llParticleSystem(LSL_Types.list rules);
//wiki: llGroundRepel(double height, integer water, double tau)
void llGroundRepel(double height, int water, double tau);
//wiki: llGiveInventoryList(string destination, string category, LSL_Types.list inventory)
void llGiveInventoryList(string destination, string category, LSL_Types.list inventory);
//wiki: llSetVehicleType(integer type)
void llSetVehicleType(int type);
//wiki: llSetVehicledoubleParam(integer param, double value)
void llSetVehicledoubleParam(int param, double value);
// wiki: llSetVehicleFloatParam(integer param, float value)
void llSetVehicleFloatParam(int param, float value);
//wiki: llSetVehicleVectorParam(integer param, vector vec)
void llSetVehicleVectorParam(int param, LSL_Types.Vector3 vec);
//wiki: llSetVehicleRotationParam(integer param, rotation rot)
void llSetVehicleRotationParam(int param, LSL_Types.Quaternion rot);
//wiki: llSetVehicleFlags(integer flags)
void llSetVehicleFlags(int flags);
//wiki: llRemoveVehicleFlags(integer flags)
void llRemoveVehicleFlags(int flags);
//wiki: llSitTarget(vector offset, rotation rot)
void llSitTarget(LSL_Types.Vector3 offset, LSL_Types.Quaternion rot);
//wiki key llAvatarOnSitTarget()
string llAvatarOnSitTarget();
//wiki: llAddToLandPassList(key avatar, double hours)
void llAddToLandPassList(string avatar, double hours);
//wiki: llSetTouchText(string text)
void llSetTouchText(string text);
//wiki: llSetSitText(string text)
void llSetSitText(string text);
//wiki: llSetCameraEyeOffset(vector offset)
void llSetCameraEyeOffset(LSL_Types.Vector3 offset);
//wiki: llSeteCameraAtOffset(vector offset)
void llSetCameraAtOffset(LSL_Types.Vector3 offset);
//
string llDumpList2String(LSL_Types.list src, string seperator);
//wiki: integer llScriptDanger(vector pos)
LSL_Types.LSLInteger llScriptDanger(LSL_Types.Vector3 pos);
//wiki: llDialog(key avatar, string message, list buttons, integer chat_channel)
void llDialog(string avatar, string message, LSL_Types.list buttons, int chat_channel);
//wiki: llVolumeDetect(integer detect)
void llVolumeDetect(int detect);
//wiki: llResetOtherScript(string name)
void llResetOtherScript(string name);
//wiki: integer llGetScriptState(string name)
LSL_Types.LSLInteger llGetScriptState(string name);
//wiki: (deprecated)
void llRemoteLoadScript();
//wiki: llSetRemoteScriptAccessPin(integer pin)
void llSetRemoteScriptAccessPin(int pin);
//wiki: llRemoteLoadScriptPin(key target, string name, integer pin, integer running, integer start_param)
void llRemoteLoadScriptPin(string target, string name, int pin, int running, int start_param);
//wiki: llOpenRemoteDataChannel()
void llOpenRemoteDataChannel();
//wiki: key llSendRemoteData(key channel, string dest, integer idata, string sdata)
string llSendRemoteData(string channel, string dest, int idata, string sdata);
//wiki: llRemoteDataReply(key channel, key message_id, string sdata, integer idata)
void llRemoteDataReply(string channel, string message_id, string sdata, int idata);
//wiki: llCloseRemoteDataChannel(key channel)
void llCloseRemoteDataChannel(string channel);
//wiki: string llMD5String(string src, integer nonce)
string llMD5String(string src, int nonce);
//wiki: llSetPrimitiveParams(list rules)
void llSetPrimitiveParams(LSL_Types.list rules);
//wiki: llSetLinkPrimitiveParams(integer linknumber, list rules)
void llSetLinkPrimitiveParams(int linknumber, LSL_Types.list rules);
//wiki: string llStringToBase64(string str)
string llStringToBase64(string str);
//wiki: string llBase64ToString(string str)
string llBase64ToString(string str);
//wiki: (deprecated)
void llXorBase64Strings();
//wiki: llRemoteDataSetRegion()
void llRemoteDataSetRegion();
//wiki: double llLog10(double val)
double llLog10(double val);
//wiki: double llLog(double val)
double llLog(double val);
//wiki: list llGetAnimationList(key id)
LSL_Types.list llGetAnimationList(string id);
//wiki: llSetParcelMusicURL(string url)
void llSetParcelMusicURL(string url);
//wiki: vector llGetRootPosition()
LSL_Types.Vector3 llGetRootPosition();
//wiki: rotation llGetRootRotation()
LSL_Types.Quaternion llGetRootRotation();
//wiki: string llGetObjectDesc()
string llGetObjectDesc();
//wiki: llSetObjectDesc(string desc)
void llSetObjectDesc(string desc);
//wiki: key llGetCreator()
string llGetCreator();
//wiki: string llGetTimestamp()
string llGetTimestamp();
//wiki: llSetLinkAlpha(integer linknumber, double alpha, integer face)
void llSetLinkAlpha(int linknumber, double alpha, int face);
//wiki: integer llGetNumberOfPrims()
LSL_Types.LSLInteger llGetNumberOfPrims();
//wiki: key llGetNumberOfNotecardLines(string name)
string llGetNumberOfNotecardLines(string name);
//wiki: list llGetBoundingBox(key object)
LSL_Types.list llGetBoundingBox(string obj);
//wiki: vector llGetGeometricCenter()
LSL_Types.Vector3 llGetGeometricCenter();
//wiki: list llGetPrimitiveParams(list rules)
LSL_Types.list llGetPrimitiveParams(LSL_Types.list rules);
//wiki: string llIntegerToBase64(integer number)
string llIntegerToBase64(int number);
//wiki integer llBase64ToInteger(string str)
LSL_Types.LSLInteger llBase64ToInteger(string str);
//wiki: double llGetGMTclock()
double llGetGMTclock();
//wiki: string llGetSimulatorHostname()
string llGetSimulatorHostname();
//llSetLocalRot(rotation rot)
void llSetLocalRot(LSL_Types.Quaternion rot);
//wiki: list llParseStringKeepNulls(string src, list separators, list spacers)
LSL_Types.list llParseStringKeepNulls(string src, LSL_Types.list seperators, LSL_Types.list spacers);
//wiki: llRezAtRoot(string inventory, vector position, vector velocity, rotation rot, integer param)
void llRezAtRoot(string inventory, LSL_Types.Vector3 position, LSL_Types.Vector3 velocity,
LSL_Types.Quaternion rot, int param);
//wiki: integer llGetObjectPermMask(integer mask)
LSL_Types.LSLInteger llGetObjectPermMask(int mask);
//wiki: llSetObjectPermMask(integer mask, integer value)
void llSetObjectPermMask(int mask, int value);
//wiki integer llGetInventoryPermMask(string item, integer mask)
LSL_Types.LSLInteger llGetInventoryPermMask(string item, int mask);
//wiki: llSetInventoryPermMask(string item, integer mask, integer value)
void llSetInventoryPermMask(string item, int mask, int value);
//wiki: key llGetInventoryCreator(string item)
string llGetInventoryCreator(string item);
//wiki: llOwnerSay(string msg)
void llOwnerSay(string msg);
//wiki: key llRequestSimulatorData(string simulator, integer data)
string llRequestSimulatorData(string simulator, int data);
//wiki: llForceMouselook(integer mouselook)
void llForceMouselook(int mouselook);
//wiki: double llGetObjectMass(key id)
double llGetObjectMass(string id);
LSL_Types.list llListReplaceList(LSL_Types.list dest, LSL_Types.list src, int start, int end);
//wiki: llLoadURL(key avatar_id, string message, string url)
void llLoadURL(string avatar_id, string message, string url);
//wiki: llParcelMediaCommandList(list commandList)
void llParcelMediaCommandList(LSL_Types.list commandList);
void llParcelMediaQuery();
//wiki integer llModPow(integer a, integer b, integer c)
LSL_Types.LSLInteger llModPow(int a, int b, int c);
//wiki: integer llGetInventoryType(string name)
LSL_Types.LSLInteger llGetInventoryType(string name);
//wiki: llSetPayPrice(integer price, list quick_pay_buttons)
void llSetPayPrice(int price, LSL_Types.list quick_pay_buttons);
//wiki: vector llGetCameraPos()
LSL_Types.Vector3 llGetCameraPos();
//wiki rotation llGetCameraRot()
LSL_Types.Quaternion llGetCameraRot();
//wiki: (deprecated)
void llSetPrimURL();
//wiki: (deprecated)
void llRefreshPrimURL();
//wiki: string llEscapeURL(string url)
string llEscapeURL(string url);
//wiki: string llUnescapeURL(string url)
string llUnescapeURL(string url);
//wiki: llMapDestination(string simname, vector pos, vector look_at)
void llMapDestination(string simname, LSL_Types.Vector3 pos, LSL_Types.Vector3 look_at);
//wiki: llAddToLandBanList(key avatar, double hours)
void llAddToLandBanList(string avatar, double hours);
//wiki: llRemoveFromLandPassList(key avatar)
void llRemoveFromLandPassList(string avatar);
//wiki: llRemoveFromLandBanList(key avatar)
void llRemoveFromLandBanList(string avatar);
//wiki: llSetCameraParams(list rules)
void llSetCameraParams(LSL_Types.list rules);
//wiki: llClearCameraParams()
void llClearCameraParams();
//wiki: double llListStatistics(integer operation, list src)
double llListStatistics(int operation, LSL_Types.list src);
//wiki: integer llGetUnixTime()
LSL_Types.LSLInteger llGetUnixTime();
//wiki: integer llGetParcelFlags(vector pos)
LSL_Types.LSLInteger llGetParcelFlags(LSL_Types.Vector3 pos);
//wiki: integer llGetRegionFlags()
LSL_Types.LSLInteger llGetRegionFlags();
//wiki: string llXorBase64StringsCorrect(string str1, string str2)
string llXorBase64StringsCorrect(string str1, string str2);
string llHTTPRequest(string url, LSL_Types.list parameters, string body);
//wiki: llResetLandBanList()
void llResetLandBanList();
//wiki: llResetLandPassList()
void llResetLandPassList();
//wiki: integer llGetParcelPrimCount(vector pos, integer category, integer sim_wide)
LSL_Types.LSLInteger llGetParcelPrimCount(LSL_Types.Vector3 pos, int category, int sim_wide);
//wiki: list llGetParcelPrimOwners(vector pos)
LSL_Types.list llGetParcelPrimOwners(LSL_Types.Vector3 pos);
//wiki: integer llGetObjectPrimCount(key object_id)
LSL_Types.LSLInteger llGetObjectPrimCount(string object_id);
//wiki: integer llGetParcelMaxPrims(vector pos, integer sim_wide)
LSL_Types.LSLInteger llGetParcelMaxPrims(LSL_Types.Vector3 pos, int sim_wide);
//wiki: llGetParcelDetails(vector pos, list params)
LSL_Types.list llGetParcelDetails(LSL_Types.Vector3 pos, LSL_Types.list param);
//wiki: llSetLinkTexture(integer linknumber, string texture, integer face)
void llSetLinkTexture(int linknumber, string texture, int face);
//wiki: string llStringTrim(string src, int type)
string llStringTrim(string src, int type);
//wiki: LSL_Types.list llGetObjectDetails(string id, LSL_Types.list args)
LSL_Types.list llGetObjectDetails(string id, LSL_Types.list args);
}
}

View File

@ -0,0 +1,68 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
namespace OpenSim.Region.ScriptEngine.XEngine.Script
{
public interface IOSSL_ScriptCommands
{
//OpenSim functions
string osSetDynamicTextureURL(string dynamicID, string contentType, string url, string extraParams, int timer);
string osSetDynamicTextureURLBlend(string dynamicID, string contentType, string url, string extraParams,
int timer, int alpha);
string osSetDynamicTextureData(string dynamicID, string contentType, string data, string extraParams, int timer);
string osSetDynamicTextureDataBlend(string dynamicID, string contentType, string data, string extraParams,
int timer, int alpha);
double osTerrainGetHeight(int x, int y);
int osTerrainSetHeight(int x, int y, double val);
int osRegionRestart(double seconds);
void osRegionNotice(string msg);
bool osConsoleCommand(string Command);
void osSetParcelMediaURL(string url);
void osSetPrimFloatOnWater(int floatYN);
// Animation commands
void osAvatarPlayAnimation(string avatar, string animation);
void osAvatarStopAnimation(string avatar, string animation);
//texture draw functions
string osMovePen(string drawList, int x, int y);
string osDrawLine(string drawList, int startX, int startY, int endX, int endY);
string osDrawLine(string drawList, int endX, int endY);
string osDrawText(string drawList, string text);
string osDrawEllipse(string drawList, int width, int height);
string osDrawRectangle(string drawList, int width, int height);
string osDrawFilledRectangle(string drawList, int width, int height);
string osSetFontSize(string drawList, int fontSize);
string osSetPenSize(string drawList, int penSize);
string osSetPenColour(string drawList, string colour);
string osDrawImage(string drawList, int width, int height, string imageUrl);
void osSetStateEvents(int events);
double osList2Double(LSL_Types.list src, int index);
void osSetRegionWaterHeight(double height);
}
}

View File

@ -0,0 +1,46 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System.Reflection;
using System;
using System.Collections;
using System.Collections.Generic;
using OpenSim.Region.Environment.Interfaces;
namespace OpenSim.Region.ScriptEngine.XEngine.Script
{
public interface IScript
{
Type Start(ILSL_ScriptCommands lsl, IOSSL_ScriptCommands ossl);
Dictionary<string, object> GetVars();
void SetVars(Dictionary<string, object> vars);
void ResetVars();
string State { get; set; }
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,61 @@
using System;
using System.Reflection;
using System.Runtime.InteropServices;
//
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
//
[assembly: AssemblyTitle("")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("")]
[assembly: AssemblyCopyright("")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: ComVisible(false)]
[assembly: CLSCompliant(true)]
//
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Revision and Build Numbers
// by using the '*' as shown below:
[assembly: AssemblyVersion("1.0.*")]
//
// In order to sign your assembly you must specify a key to use. Refer to the
// Microsoft .NET Framework documentation for more information on assembly signing.
//
// Use the attributes below to control which key is used for signing.
//
// Notes:
// (*) If no key is specified, the assembly is not signed.
// (*) KeyName refers to a key that has been installed in the Crypto Service
// Provider (CSP) on your machine. KeyFile refers to a file which contains
// a key.
// (*) If the KeyFile and the KeyName values are both specified, the
// following processing occurs:
// (1) If the KeyName can be found in the CSP, that key is used.
// (2) If the KeyName does not exist and the KeyFile does exist, the key
// in the KeyFile is installed into the CSP and used.
// (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility.
// When specifying the KeyFile, the location of the KeyFile should be
// relative to the project output directory which is
// %Project Directory%\obj\<configuration>. For example, if your KeyFile is
// located in the project directory, you would specify the AssemblyKeyFile
// attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")]
// (*) Delay Signing is an advanced option - see the Microsoft .NET Framework
// documentation for more information on this.
//
[assembly: AssemblyDelaySign(false)]
[assembly: AssemblyKeyFile("")]
[assembly: AssemblyKeyName("")]

View File

@ -0,0 +1,223 @@
using System;
using System.Diagnostics;
using System.Threading;
using System.Reflection;
using System.Web;
using System.Runtime.Remoting.Messaging;
namespace Amib.Threading
{
#region CallerThreadContext class
/// <summary>
/// This class stores the caller call context in order to restore
/// it when the work item is executed in the thread pool environment.
/// </summary>
internal class CallerThreadContext
{
#region Prepare reflection information
// Cached type information.
private static MethodInfo getLogicalCallContextMethodInfo =
typeof(Thread).GetMethod("GetLogicalCallContext", BindingFlags.Instance | BindingFlags.NonPublic);
private static MethodInfo setLogicalCallContextMethodInfo =
typeof(Thread).GetMethod("SetLogicalCallContext", BindingFlags.Instance | BindingFlags.NonPublic);
private static string HttpContextSlotName = GetHttpContextSlotName();
private static string GetHttpContextSlotName()
{
FieldInfo fi = typeof(HttpContext).GetField("CallContextSlotName", BindingFlags.Static | BindingFlags.NonPublic);
if( fi != null )
return (string)fi.GetValue(null);
else // Use the default "HttpContext" slot name
return "HttpContext";
}
#endregion
#region Private fields
private HttpContext _httpContext = null;
private LogicalCallContext _callContext = null;
#endregion
/// <summary>
/// Constructor
/// </summary>
private CallerThreadContext()
{
}
public bool CapturedCallContext
{
get
{
return (null != _callContext);
}
}
public bool CapturedHttpContext
{
get
{
return (null != _httpContext);
}
}
/// <summary>
/// Captures the current thread context
/// </summary>
/// <returns></returns>
public static CallerThreadContext Capture(
bool captureCallContext,
bool captureHttpContext)
{
Debug.Assert(captureCallContext || captureHttpContext);
CallerThreadContext callerThreadContext = new CallerThreadContext();
// TODO: In NET 2.0, redo using the new feature of ExecutionContext class - Capture()
// Capture Call Context
if(captureCallContext && (getLogicalCallContextMethodInfo != null))
{
callerThreadContext._callContext = (LogicalCallContext)getLogicalCallContextMethodInfo.Invoke(Thread.CurrentThread, null);
if (callerThreadContext._callContext != null)
{
callerThreadContext._callContext = (LogicalCallContext)callerThreadContext._callContext.Clone();
}
}
// Capture httpContext
if (captureHttpContext && (null != HttpContext.Current))
{
callerThreadContext._httpContext = HttpContext.Current;
}
return callerThreadContext;
}
/// <summary>
/// Applies the thread context stored earlier
/// </summary>
/// <param name="callerThreadContext"></param>
public static void Apply(CallerThreadContext callerThreadContext)
{
if (null == callerThreadContext)
{
throw new ArgumentNullException("callerThreadContext");
}
// Todo: In NET 2.0, redo using the new feature of ExecutionContext class - Run()
// Restore call context
if ((callerThreadContext._callContext != null) && (setLogicalCallContextMethodInfo != null))
{
setLogicalCallContextMethodInfo.Invoke(Thread.CurrentThread, new object[] { callerThreadContext._callContext });
}
// Restore HttpContext
if (callerThreadContext._httpContext != null)
{
CallContext.SetData(HttpContextSlotName, callerThreadContext._httpContext);
}
}
}
#endregion
}
/*
// Ami Bar
// amibar@gmail.com
using System;
using System.Threading;
using System.Globalization;
using System.Security.Principal;
using System.Reflection;
using System.Runtime.Remoting.Contexts;
namespace Amib.Threading.Internal
{
#region CallerThreadContext class
/// <summary>
/// This class stores the caller thread context in order to restore
/// it when the work item is executed in the context of the thread
/// from the pool.
/// Note that we can't store the thread's CompressedStack, because
/// it throws a security exception
/// </summary>
public class CallerThreadContext
{
private CultureInfo _culture = null;
private CultureInfo _cultureUI = null;
private IPrincipal _principal;
private System.Runtime.Remoting.Contexts.Context _context;
private static FieldInfo _fieldInfo = GetFieldInfo();
private static FieldInfo GetFieldInfo()
{
Type threadType = typeof(Thread);
return threadType.GetField(
"m_Context",
BindingFlags.Instance | BindingFlags.NonPublic);
}
/// <summary>
/// Constructor
/// </summary>
private CallerThreadContext()
{
}
/// <summary>
/// Captures the current thread context
/// </summary>
/// <returns></returns>
public static CallerThreadContext Capture()
{
CallerThreadContext callerThreadContext = new CallerThreadContext();
Thread thread = Thread.CurrentThread;
callerThreadContext._culture = thread.CurrentCulture;
callerThreadContext._cultureUI = thread.CurrentUICulture;
callerThreadContext._principal = Thread.CurrentPrincipal;
callerThreadContext._context = Thread.CurrentContext;
return callerThreadContext;
}
/// <summary>
/// Applies the thread context stored earlier
/// </summary>
/// <param name="callerThreadContext"></param>
public static void Apply(CallerThreadContext callerThreadContext)
{
Thread thread = Thread.CurrentThread;
thread.CurrentCulture = callerThreadContext._culture;
thread.CurrentUICulture = callerThreadContext._cultureUI;
Thread.CurrentPrincipal = callerThreadContext._principal;
// Uncomment the following block to enable the Thread.CurrentThread
/*
if (null != _fieldInfo)
{
_fieldInfo.SetValue(
Thread.CurrentThread,
callerThreadContext._context);
}
* /
}
}
#endregion
}
*/

View File

@ -0,0 +1,81 @@
// Ami Bar
// amibar@gmail.com
using System;
using System.Runtime.Serialization;
namespace Amib.Threading
{
#region Exceptions
/// <summary>
/// Represents an exception in case IWorkItemResult.GetResult has been canceled
/// </summary>
[Serializable]
public sealed class WorkItemCancelException : ApplicationException
{
public WorkItemCancelException() : base()
{
}
public WorkItemCancelException(string message) : base(message)
{
}
public WorkItemCancelException(string message, Exception e) : base(message, e)
{
}
public WorkItemCancelException(SerializationInfo si, StreamingContext sc) : base(si, sc)
{
}
}
/// <summary>
/// Represents an exception in case IWorkItemResult.GetResult has been timed out
/// </summary>
[Serializable]
public sealed class WorkItemTimeoutException : ApplicationException
{
public WorkItemTimeoutException() : base()
{
}
public WorkItemTimeoutException(string message) : base(message)
{
}
public WorkItemTimeoutException(string message, Exception e) : base(message, e)
{
}
public WorkItemTimeoutException(SerializationInfo si, StreamingContext sc) : base(si, sc)
{
}
}
/// <summary>
/// Represents an exception in case IWorkItemResult.GetResult has been timed out
/// </summary>
[Serializable]
public sealed class WorkItemResultException : ApplicationException
{
public WorkItemResultException() : base()
{
}
public WorkItemResultException(string message) : base(message)
{
}
public WorkItemResultException(string message, Exception e) : base(message, e)
{
}
public WorkItemResultException(SerializationInfo si, StreamingContext sc) : base(si, sc)
{
}
}
#endregion
}

271
ThirdParty/SmartThreadPool/Interfaces.cs vendored Normal file
View File

@ -0,0 +1,271 @@
// Ami Bar
// amibar@gmail.com
using System;
using System.Threading;
namespace Amib.Threading
{
#region Delegates
/// <summary>
/// A delegate that represents the method to run as the work item
/// </summary>
/// <param name="state">A state object for the method to run</param>
public delegate object WorkItemCallback(object state);
/// <summary>
/// A delegate to call after the WorkItemCallback completed
/// </summary>
/// <param name="wir">The work item result object</param>
public delegate void PostExecuteWorkItemCallback(IWorkItemResult wir);
/// <summary>
/// A delegate to call when a WorkItemsGroup becomes idle
/// </summary>
/// <param name="workItemsGroup">A reference to the WorkItemsGroup that became idle</param>
public delegate void WorkItemsGroupIdleHandler(IWorkItemsGroup workItemsGroup);
#endregion
#region WorkItem Priority
public enum WorkItemPriority
{
Lowest,
BelowNormal,
Normal,
AboveNormal,
Highest,
}
#endregion
#region IHasWorkItemPriority interface
public interface IHasWorkItemPriority
{
WorkItemPriority WorkItemPriority { get; }
}
#endregion
#region IWorkItemsGroup interface
/// <summary>
/// IWorkItemsGroup interface
/// </summary>
public interface IWorkItemsGroup
{
/// <summary>
/// Get/Set the name of the WorkItemsGroup
/// </summary>
string Name { get; set; }
IWorkItemResult QueueWorkItem(WorkItemCallback callback);
IWorkItemResult QueueWorkItem(WorkItemCallback callback, WorkItemPriority workItemPriority);
IWorkItemResult QueueWorkItem(WorkItemCallback callback, object state);
IWorkItemResult QueueWorkItem(WorkItemCallback callback, object state, WorkItemPriority workItemPriority);
IWorkItemResult QueueWorkItem(WorkItemCallback callback, object state, PostExecuteWorkItemCallback postExecuteWorkItemCallback);
IWorkItemResult QueueWorkItem(WorkItemCallback callback, object state, PostExecuteWorkItemCallback postExecuteWorkItemCallback, WorkItemPriority workItemPriority);
IWorkItemResult QueueWorkItem(WorkItemCallback callback, object state, PostExecuteWorkItemCallback postExecuteWorkItemCallback, CallToPostExecute callToPostExecute);
IWorkItemResult QueueWorkItem(WorkItemCallback callback, object state, PostExecuteWorkItemCallback postExecuteWorkItemCallback, CallToPostExecute callToPostExecute, WorkItemPriority workItemPriority);
IWorkItemResult QueueWorkItem(WorkItemInfo workItemInfo, WorkItemCallback callback);
IWorkItemResult QueueWorkItem(WorkItemInfo workItemInfo, WorkItemCallback callback, object state);
void WaitForIdle();
bool WaitForIdle(TimeSpan timeout);
bool WaitForIdle(int millisecondsTimeout);
int WaitingCallbacks { get; }
event WorkItemsGroupIdleHandler OnIdle;
void Cancel();
void Start();
}
#endregion
#region CallToPostExecute enumerator
[Flags]
public enum CallToPostExecute
{
Never = 0x00,
WhenWorkItemCanceled = 0x01,
WhenWorkItemNotCanceled = 0x02,
Always = WhenWorkItemCanceled | WhenWorkItemNotCanceled,
}
#endregion
#region IWorkItemResult interface
/// <summary>
/// IWorkItemResult interface
/// </summary>
public interface IWorkItemResult
{
/// <summary>
/// Get the result of the work item.
/// If the work item didn't run yet then the caller waits.
/// </summary>
/// <returns>The result of the work item</returns>
object GetResult();
/// <summary>
/// Get the result of the work item.
/// If the work item didn't run yet then the caller waits until timeout.
/// </summary>
/// <returns>The result of the work item</returns>
/// On timeout throws WorkItemTimeoutException
object GetResult(
int millisecondsTimeout,
bool exitContext);
/// <summary>
/// Get the result of the work item.
/// If the work item didn't run yet then the caller waits until timeout.
/// </summary>
/// <returns>The result of the work item</returns>
/// On timeout throws WorkItemTimeoutException
object GetResult(
TimeSpan timeout,
bool exitContext);
void Abort();
/// <summary>
/// Get the result of the work item.
/// If the work item didn't run yet then the caller waits until timeout or until the cancelWaitHandle is signaled.
/// </summary>
/// <param name="millisecondsTimeout">Timeout in milliseconds, or -1 for infinite</param>
/// <param name="exitContext">
/// true to exit the synchronization domain for the context before the wait (if in a synchronized context), and reacquire it; otherwise, false.
/// </param>
/// <param name="cancelWaitHandle">A cancel wait handle to interrupt the blocking if needed</param>
/// <returns>The result of the work item</returns>
/// On timeout throws WorkItemTimeoutException
/// On cancel throws WorkItemCancelException
object GetResult(
int millisecondsTimeout,
bool exitContext,
WaitHandle cancelWaitHandle);
/// <summary>
/// Get the result of the work item.
/// If the work item didn't run yet then the caller waits until timeout or until the cancelWaitHandle is signaled.
/// </summary>
/// <returns>The result of the work item</returns>
/// On timeout throws WorkItemTimeoutException
/// On cancel throws WorkItemCancelException
object GetResult(
TimeSpan timeout,
bool exitContext,
WaitHandle cancelWaitHandle);
/// <summary>
/// Get the result of the work item.
/// If the work item didn't run yet then the caller waits.
/// </summary>
/// <param name="e">Filled with the exception if one was thrown</param>
/// <returns>The result of the work item</returns>
object GetResult(out Exception e);
/// <summary>
/// Get the result of the work item.
/// If the work item didn't run yet then the caller waits until timeout.
/// </summary>
/// <param name="e">Filled with the exception if one was thrown</param>
/// <returns>The result of the work item</returns>
/// On timeout throws WorkItemTimeoutException
object GetResult(
int millisecondsTimeout,
bool exitContext,
out Exception e);
/// <summary>
/// Get the result of the work item.
/// If the work item didn't run yet then the caller waits until timeout.
/// </summary>
/// <param name="e">Filled with the exception if one was thrown</param>
/// <returns>The result of the work item</returns>
/// On timeout throws WorkItemTimeoutException
object GetResult(
TimeSpan timeout,
bool exitContext,
out Exception e);
/// <summary>
/// Get the result of the work item.
/// If the work item didn't run yet then the caller waits until timeout or until the cancelWaitHandle is signaled.
/// </summary>
/// <param name="millisecondsTimeout">Timeout in milliseconds, or -1 for infinite</param>
/// <param name="exitContext">
/// true to exit the synchronization domain for the context before the wait (if in a synchronized context), and reacquire it; otherwise, false.
/// </param>
/// <param name="cancelWaitHandle">A cancel wait handle to interrupt the blocking if needed</param>
/// <param name="e">Filled with the exception if one was thrown</param>
/// <returns>The result of the work item</returns>
/// On timeout throws WorkItemTimeoutException
/// On cancel throws WorkItemCancelException
object GetResult(
int millisecondsTimeout,
bool exitContext,
WaitHandle cancelWaitHandle,
out Exception e);
/// <summary>
/// Get the result of the work item.
/// If the work item didn't run yet then the caller waits until timeout or until the cancelWaitHandle is signaled.
/// </summary>
/// <returns>The result of the work item</returns>
/// <param name="e">Filled with the exception if one was thrown</param>
/// On timeout throws WorkItemTimeoutException
/// On cancel throws WorkItemCancelException
object GetResult(
TimeSpan timeout,
bool exitContext,
WaitHandle cancelWaitHandle,
out Exception e);
/// <summary>
/// Gets an indication whether the asynchronous operation has completed.
/// </summary>
bool IsCompleted { get; }
/// <summary>
/// Gets an indication whether the asynchronous operation has been canceled.
/// </summary>
bool IsCanceled { get; }
/// <summary>
/// Gets a user-defined object that qualifies or contains information about an asynchronous operation.
/// </summary>
object State { get; }
/// <summary>
/// Cancel the work item if it didn't start running yet.
/// </summary>
/// <returns>Returns true on success or false if the work item is in progress or already completed</returns>
bool Cancel();
/// <summary>
/// Get the work item's priority
/// </summary>
WorkItemPriority WorkItemPriority { get; }
/// <summary>
/// Return the result, same as GetResult()
/// </summary>
object Result { get; }
/// <summary>
/// Returns the exception if occured otherwise returns null.
/// </summary>
object Exception { get; }
}
#endregion
}

View File

@ -0,0 +1,240 @@
// Ami Bar
// amibar@gmail.com
using System;
using System.Collections;
using System.Diagnostics;
namespace Amib.Threading.Internal
{
#region PriorityQueue class
/// <summary>
/// PriorityQueue class
/// This class is not thread safe because we use external lock
/// </summary>
public sealed class PriorityQueue : IEnumerable
{
#region Private members
/// <summary>
/// The number of queues, there is one for each type of priority
/// </summary>
private const int _queuesCount = WorkItemPriority.Highest-WorkItemPriority.Lowest+1;
/// <summary>
/// Work items queues. There is one for each type of priority
/// </summary>
private Queue [] _queues = new Queue[_queuesCount];
/// <summary>
/// The total number of work items within the queues
/// </summary>
private int _workItemsCount = 0;
/// <summary>
/// Use with IEnumerable interface
/// </summary>
private int _version = 0;
#endregion
#region Contructor
public PriorityQueue()
{
for(int i = 0; i < _queues.Length; ++i)
{
_queues[i] = new Queue();
}
}
#endregion
#region Methods
/// <summary>
/// Enqueue a work item.
/// </summary>
/// <param name="workItem">A work item</param>
public void Enqueue(IHasWorkItemPriority workItem)
{
Debug.Assert(null != workItem);
int queueIndex = _queuesCount-(int)workItem.WorkItemPriority-1;
Debug.Assert(queueIndex >= 0);
Debug.Assert(queueIndex < _queuesCount);
_queues[queueIndex].Enqueue(workItem);
++_workItemsCount;
++_version;
}
/// <summary>
/// Dequeque a work item.
/// </summary>
/// <returns>Returns the next work item</returns>
public IHasWorkItemPriority Dequeue()
{
IHasWorkItemPriority workItem = null;
if(_workItemsCount > 0)
{
int queueIndex = GetNextNonEmptyQueue(-1);
Debug.Assert(queueIndex >= 0);
workItem = _queues[queueIndex].Dequeue() as IHasWorkItemPriority;
Debug.Assert(null != workItem);
--_workItemsCount;
++_version;
}
return workItem;
}
/// <summary>
/// Find the next non empty queue starting at queue queueIndex+1
/// </summary>
/// <param name="queueIndex">The index-1 to start from</param>
/// <returns>
/// The index of the next non empty queue or -1 if all the queues are empty
/// </returns>
private int GetNextNonEmptyQueue(int queueIndex)
{
for(int i = queueIndex+1; i < _queuesCount; ++i)
{
if(_queues[i].Count > 0)
{
return i;
}
}
return -1;
}
/// <summary>
/// The number of work items
/// </summary>
public int Count
{
get
{
return _workItemsCount;
}
}
/// <summary>
/// Clear all the work items
/// </summary>
public void Clear()
{
if (_workItemsCount > 0)
{
foreach(Queue queue in _queues)
{
queue.Clear();
}
_workItemsCount = 0;
++_version;
}
}
#endregion
#region IEnumerable Members
/// <summary>
/// Returns an enumerator to iterate over the work items
/// </summary>
/// <returns>Returns an enumerator</returns>
public IEnumerator GetEnumerator()
{
return new PriorityQueueEnumerator(this);
}
#endregion
#region PriorityQueueEnumerator
/// <summary>
/// The class the implements the enumerator
/// </summary>
private class PriorityQueueEnumerator : IEnumerator
{
private PriorityQueue _priorityQueue;
private int _version;
private int _queueIndex;
private IEnumerator _enumerator;
public PriorityQueueEnumerator(PriorityQueue priorityQueue)
{
_priorityQueue = priorityQueue;
_version = _priorityQueue._version;
_queueIndex = _priorityQueue.GetNextNonEmptyQueue(-1);
if (_queueIndex >= 0)
{
_enumerator = _priorityQueue._queues[_queueIndex].GetEnumerator();
}
else
{
_enumerator = null;
}
}
#region IEnumerator Members
public void Reset()
{
_version = _priorityQueue._version;
_queueIndex = _priorityQueue.GetNextNonEmptyQueue(-1);
if (_queueIndex >= 0)
{
_enumerator = _priorityQueue._queues[_queueIndex].GetEnumerator();
}
else
{
_enumerator = null;
}
}
public object Current
{
get
{
Debug.Assert(null != _enumerator);
return _enumerator.Current;
}
}
public bool MoveNext()
{
if (null == _enumerator)
{
return false;
}
if(_version != _priorityQueue._version)
{
throw new InvalidOperationException("The collection has been modified");
}
if (!_enumerator.MoveNext())
{
_queueIndex = _priorityQueue.GetNextNonEmptyQueue(_queueIndex);
if(-1 == _queueIndex)
{
return false;
}
_enumerator = _priorityQueue._queues[_queueIndex].GetEnumerator();
_enumerator.MoveNext();
return true;
}
return true;
}
#endregion
}
#endregion
}
#endregion
}

View File

@ -0,0 +1,352 @@
using System;
using System.Diagnostics;
namespace Amib.Threading.Internal
{
internal enum STPPerformanceCounterType
{
// Fields
ActiveThreads = 0,
InUseThreads = 1,
OverheadThreads = 2,
OverheadThreadsPercent = 3,
OverheadThreadsPercentBase = 4,
WorkItems = 5,
WorkItemsInQueue = 6,
WorkItemsProcessed = 7,
WorkItemsQueuedPerSecond = 8,
WorkItemsProcessedPerSecond = 9,
AvgWorkItemWaitTime = 10,
AvgWorkItemWaitTimeBase = 11,
AvgWorkItemProcessTime = 12,
AvgWorkItemProcessTimeBase = 13,
WorkItemsGroups = 14,
LastCounter = 14,
}
/// <summary>
/// Summary description for STPPerformanceCounter.
/// </summary>
internal class STPPerformanceCounter
{
// Fields
private PerformanceCounterType _pcType;
protected string _counterHelp;
protected string _counterName;
// Methods
public STPPerformanceCounter(
string counterName,
string counterHelp,
PerformanceCounterType pcType)
{
this._counterName = counterName;
this._counterHelp = counterHelp;
this._pcType = pcType;
}
public void AddCounterToCollection(CounterCreationDataCollection counterData)
{
CounterCreationData counterCreationData = new CounterCreationData(
_counterName,
_counterHelp,
_pcType);
counterData.Add(counterCreationData);
}
// Properties
public string Name
{
get
{
return _counterName;
}
}
}
internal class STPPerformanceCounters
{
// Fields
internal STPPerformanceCounter[] _stpPerformanceCounters;
private static STPPerformanceCounters _instance;
internal const string _stpCategoryHelp = "SmartThreadPool performance counters";
internal const string _stpCategoryName = "SmartThreadPool";
// Methods
static STPPerformanceCounters()
{
_instance = new STPPerformanceCounters();
}
private STPPerformanceCounters()
{
STPPerformanceCounter[] stpPerformanceCounters = new STPPerformanceCounter[]
{
new STPPerformanceCounter("Active threads", "The current number of available in the thread pool.", PerformanceCounterType.NumberOfItems32),
new STPPerformanceCounter("In use threads", "The current number of threads that execute a work item.", PerformanceCounterType.NumberOfItems32),
new STPPerformanceCounter("Overhead threads", "The current number of threads that are active, but are not in use.", PerformanceCounterType.NumberOfItems32),
new STPPerformanceCounter("% overhead threads", "The current number of threads that are active, but are not in use in percents.", PerformanceCounterType.RawFraction),
new STPPerformanceCounter("% overhead threads base", "The current number of threads that are active, but are not in use in percents.", PerformanceCounterType.RawBase),
new STPPerformanceCounter("Work Items", "The number of work items in the Smart Thread Pool. Both queued and processed.", PerformanceCounterType.NumberOfItems32),
new STPPerformanceCounter("Work Items in queue", "The current number of work items in the queue", PerformanceCounterType.NumberOfItems32),
new STPPerformanceCounter("Work Items processed", "The number of work items already processed", PerformanceCounterType.NumberOfItems32),
new STPPerformanceCounter("Work Items queued/sec", "The number of work items queued per second", PerformanceCounterType.RateOfCountsPerSecond32),
new STPPerformanceCounter("Work Items processed/sec", "The number of work items processed per second", PerformanceCounterType.RateOfCountsPerSecond32),
new STPPerformanceCounter("Avg. Work Item wait time/sec", "The average time a work item supends in the queue waiting for its turn to execute.", PerformanceCounterType.AverageCount64),
new STPPerformanceCounter("Avg. Work Item wait time base", "The average time a work item supends in the queue waiting for its turn to execute.", PerformanceCounterType.AverageBase),
new STPPerformanceCounter("Avg. Work Item process time/sec", "The average time it takes to process a work item.", PerformanceCounterType.AverageCount64),
new STPPerformanceCounter("Avg. Work Item process time base", "The average time it takes to process a work item.", PerformanceCounterType.AverageBase),
new STPPerformanceCounter("Work Items Groups", "The current number of work item groups associated with the Smart Thread Pool.", PerformanceCounterType.NumberOfItems32),
};
_stpPerformanceCounters = stpPerformanceCounters;
SetupCategory();
}
private void SetupCategory()
{
if (!PerformanceCounterCategory.Exists(_stpCategoryName))
{
CounterCreationDataCollection counters = new CounterCreationDataCollection();
for (int i = 0; i < _stpPerformanceCounters.Length; i++)
{
_stpPerformanceCounters[i].AddCounterToCollection(counters);
}
// *********** Remark for .NET 2.0 ***********
// If you are here, it means you got the warning that this overload
// of the method is deprecated in .NET 2.0. To use the correct
// method overload, uncomment the third argument of the method.
PerformanceCounterCategory.Create(
_stpCategoryName,
_stpCategoryHelp,
//PerformanceCounterCategoryType.MultiInstance,
counters);
}
}
// Properties
public static STPPerformanceCounters Instance
{
get
{
return _instance;
}
}
}
internal class STPInstancePerformanceCounter : IDisposable
{
// Fields
private PerformanceCounter _pcs;
// Methods
protected STPInstancePerformanceCounter()
{
}
public STPInstancePerformanceCounter(
string instance,
STPPerformanceCounterType spcType)
{
STPPerformanceCounters counters = STPPerformanceCounters.Instance;
_pcs = new PerformanceCounter(
STPPerformanceCounters._stpCategoryName,
counters._stpPerformanceCounters[(int) spcType].Name,
instance,
false);
_pcs.RawValue = _pcs.RawValue;
}
~STPInstancePerformanceCounter()
{
Close();
}
public void Close()
{
if (_pcs != null)
{
_pcs.RemoveInstance();
_pcs.Close();
_pcs = null;
}
}
public void Dispose()
{
Close();
GC.SuppressFinalize(this);
}
public virtual void Increment()
{
_pcs.Increment();
}
public virtual void IncrementBy(long val)
{
_pcs.IncrementBy(val);
}
public virtual void Set(long val)
{
_pcs.RawValue = val;
}
}
internal class STPInstanceNullPerformanceCounter : STPInstancePerformanceCounter
{
// Methods
public STPInstanceNullPerformanceCounter() {}
public override void Increment() {}
public override void IncrementBy(long value) {}
public override void Set(long val) {}
}
internal interface ISTPInstancePerformanceCounters : IDisposable
{
void Close();
void SampleThreads(long activeThreads, long inUseThreads);
void SampleWorkItems(long workItemsQueued, long workItemsProcessed);
void SampleWorkItemsWaitTime(TimeSpan workItemWaitTime);
void SampleWorkItemsProcessTime(TimeSpan workItemProcessTime);
}
internal class STPInstancePerformanceCounters : ISTPInstancePerformanceCounters, IDisposable
{
// Fields
private STPInstancePerformanceCounter[] _pcs;
private static STPInstancePerformanceCounter _stpInstanceNullPerformanceCounter;
// Methods
static STPInstancePerformanceCounters()
{
_stpInstanceNullPerformanceCounter = new STPInstanceNullPerformanceCounter();
}
public STPInstancePerformanceCounters(string instance)
{
_pcs = new STPInstancePerformanceCounter[(int)STPPerformanceCounterType.LastCounter];
STPPerformanceCounters counters = STPPerformanceCounters.Instance;
for (int i = 0; i < _pcs.Length; i++)
{
if (instance != null)
{
_pcs[i] = new STPInstancePerformanceCounter(
instance,
(STPPerformanceCounterType) i);
}
else
{
_pcs[i] = _stpInstanceNullPerformanceCounter;
}
}
}
public void Close()
{
if (null != _pcs)
{
for (int i = 0; i < _pcs.Length; i++)
{
if (null != _pcs[i])
{
_pcs[i].Close();
}
}
_pcs = null;
}
}
~STPInstancePerformanceCounters()
{
Close();
}
public void Dispose()
{
Close();
GC.SuppressFinalize(this);
}
private STPInstancePerformanceCounter GetCounter(STPPerformanceCounterType spcType)
{
return _pcs[(int) spcType];
}
public void SampleThreads(long activeThreads, long inUseThreads)
{
GetCounter(STPPerformanceCounterType.ActiveThreads).Set(activeThreads);
GetCounter(STPPerformanceCounterType.InUseThreads).Set(inUseThreads);
GetCounter(STPPerformanceCounterType.OverheadThreads).Set(activeThreads-inUseThreads);
GetCounter(STPPerformanceCounterType.OverheadThreadsPercentBase).Set(activeThreads-inUseThreads);
GetCounter(STPPerformanceCounterType.OverheadThreadsPercent).Set(inUseThreads);
}
public void SampleWorkItems(long workItemsQueued, long workItemsProcessed)
{
GetCounter(STPPerformanceCounterType.WorkItems).Set(workItemsQueued+workItemsProcessed);
GetCounter(STPPerformanceCounterType.WorkItemsInQueue).Set(workItemsQueued);
GetCounter(STPPerformanceCounterType.WorkItemsProcessed).Set(workItemsProcessed);
GetCounter(STPPerformanceCounterType.WorkItemsQueuedPerSecond).Set(workItemsQueued);
GetCounter(STPPerformanceCounterType.WorkItemsProcessedPerSecond).Set(workItemsProcessed);
}
public void SampleWorkItemsWaitTime(TimeSpan workItemWaitTime)
{
GetCounter(STPPerformanceCounterType.AvgWorkItemWaitTime).IncrementBy((long)workItemWaitTime.TotalMilliseconds);
GetCounter(STPPerformanceCounterType.AvgWorkItemWaitTimeBase).Increment();
}
public void SampleWorkItemsProcessTime(TimeSpan workItemProcessTime)
{
GetCounter(STPPerformanceCounterType.AvgWorkItemProcessTime).IncrementBy((long)workItemProcessTime.TotalMilliseconds);
GetCounter(STPPerformanceCounterType.AvgWorkItemProcessTimeBase).Increment();
}
}
internal class NullSTPInstancePerformanceCounters : ISTPInstancePerformanceCounters, IDisposable
{
static NullSTPInstancePerformanceCounters()
{
}
private static NullSTPInstancePerformanceCounters _instance = new NullSTPInstancePerformanceCounters(null);
public static NullSTPInstancePerformanceCounters Instance
{
get { return _instance; }
}
public NullSTPInstancePerformanceCounters(string instance) {}
public void Close() {}
public void Dispose() {}
public void SampleThreads(long activeThreads, long inUseThreads) {}
public void SampleWorkItems(long workItemsQueued, long workItemsProcessed) {}
public void SampleWorkItemsWaitTime(TimeSpan workItemWaitTime) {}
public void SampleWorkItemsProcessTime(TimeSpan workItemProcessTime) {}
}
}

View File

@ -0,0 +1,99 @@
// Ami Bar
// amibar@gmail.com
using System.Threading;
namespace Amib.Threading
{
/// <summary>
/// Summary description for STPStartInfo.
/// </summary>
public class STPStartInfo : WIGStartInfo
{
/// <summary>
/// Idle timeout in milliseconds.
/// If a thread is idle for _idleTimeout milliseconds then
/// it may quit.
/// </summary>
private int _idleTimeout;
/// <summary>
/// The lower limit of threads in the pool.
/// </summary>
private int _minWorkerThreads;
/// <summary>
/// The upper limit of threads in the pool.
/// </summary>
private int _maxWorkerThreads;
/// <summary>
/// The priority of the threads in the pool
/// </summary>
private ThreadPriority _threadPriority;
/// <summary>
/// If this field is not null then the performance counters are enabled
/// and use the string as the name of the instance.
/// </summary>
private string _pcInstanceName;
private int _stackSize;
public STPStartInfo() : base()
{
_idleTimeout = SmartThreadPool.DefaultIdleTimeout;
_minWorkerThreads = SmartThreadPool.DefaultMinWorkerThreads;
_maxWorkerThreads = SmartThreadPool.DefaultMaxWorkerThreads;
_threadPriority = SmartThreadPool.DefaultThreadPriority;
_pcInstanceName = SmartThreadPool.DefaultPerformanceCounterInstanceName;
_stackSize = SmartThreadPool.DefaultStackSize;
}
public STPStartInfo(STPStartInfo stpStartInfo) : base(stpStartInfo)
{
_idleTimeout = stpStartInfo._idleTimeout;
_minWorkerThreads = stpStartInfo._minWorkerThreads;
_maxWorkerThreads = stpStartInfo._maxWorkerThreads;
_threadPriority = stpStartInfo._threadPriority;
_pcInstanceName = stpStartInfo._pcInstanceName;
_stackSize = stpStartInfo._stackSize;
}
public int IdleTimeout
{
get { return _idleTimeout; }
set { _idleTimeout = value; }
}
public int MinWorkerThreads
{
get { return _minWorkerThreads; }
set { _minWorkerThreads = value; }
}
public int MaxWorkerThreads
{
get { return _maxWorkerThreads; }
set { _maxWorkerThreads = value; }
}
public ThreadPriority ThreadPriority
{
get { return _threadPriority; }
set { _threadPriority = value; }
}
public string PerformanceCounterInstanceName
{
get { return _pcInstanceName; }
set { _pcInstanceName = value; }
}
public int StackSize
{
get { return _stackSize; }
set { _stackSize = value; }
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,99 @@
// Ami Bar
// amibar@gmail.com
namespace Amib.Threading
{
/// <summary>
/// Summary description for WIGStartInfo.
/// </summary>
public class WIGStartInfo
{
/// <summary>
/// Use the caller's security context
/// </summary>
private bool _useCallerCallContext;
/// <summary>
/// Use the caller's HTTP context
/// </summary>
private bool _useCallerHttpContext;
/// <summary>
/// Dispose of the state object of a work item
/// </summary>
private bool _disposeOfStateObjects;
/// <summary>
/// The option to run the post execute
/// </summary>
private CallToPostExecute _callToPostExecute;
/// <summary>
/// A post execute callback to call when none is provided in
/// the QueueWorkItem method.
/// </summary>
private PostExecuteWorkItemCallback _postExecuteWorkItemCallback;
/// <summary>
/// Indicate the WorkItemsGroup to suspend the handling of the work items
/// until the Start() method is called.
/// </summary>
private bool _startSuspended;
public WIGStartInfo()
{
_useCallerCallContext = SmartThreadPool.DefaultUseCallerCallContext;
_useCallerHttpContext = SmartThreadPool.DefaultUseCallerHttpContext;
_disposeOfStateObjects = SmartThreadPool.DefaultDisposeOfStateObjects;
_callToPostExecute = SmartThreadPool.DefaultCallToPostExecute;
_postExecuteWorkItemCallback = SmartThreadPool.DefaultPostExecuteWorkItemCallback;
_startSuspended = SmartThreadPool.DefaultStartSuspended;
}
public WIGStartInfo(WIGStartInfo wigStartInfo)
{
_useCallerCallContext = wigStartInfo._useCallerCallContext;
_useCallerHttpContext = wigStartInfo._useCallerHttpContext;
_disposeOfStateObjects = wigStartInfo._disposeOfStateObjects;
_callToPostExecute = wigStartInfo._callToPostExecute;
_postExecuteWorkItemCallback = wigStartInfo._postExecuteWorkItemCallback;
_startSuspended = wigStartInfo._startSuspended;
}
public bool UseCallerCallContext
{
get { return _useCallerCallContext; }
set { _useCallerCallContext = value; }
}
public bool UseCallerHttpContext
{
get { return _useCallerHttpContext; }
set { _useCallerHttpContext = value; }
}
public bool DisposeOfStateObjects
{
get { return _disposeOfStateObjects; }
set { _disposeOfStateObjects = value; }
}
public CallToPostExecute CallToPostExecute
{
get { return _callToPostExecute; }
set { _callToPostExecute = value; }
}
public PostExecuteWorkItemCallback PostExecuteWorkItemCallback
{
get { return _postExecuteWorkItemCallback; }
set { _postExecuteWorkItemCallback = value; }
}
public bool StartSuspended
{
get { return _startSuspended; }
set { _startSuspended = value; }
}
}
}

1035
ThirdParty/SmartThreadPool/WorkItem.cs vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,333 @@
// Ami Bar
// amibar@gmail.com
using System;
namespace Amib.Threading.Internal
{
#region WorkItemFactory class
public class WorkItemFactory
{
/// <summary>
/// Create a new work item
/// </summary>
/// <param name="wigStartInfo">Work item group start information</param>
/// <param name="callback">A callback to execute</param>
/// <returns>Returns a work item</returns>
public static WorkItem CreateWorkItem(
IWorkItemsGroup workItemsGroup,
WIGStartInfo wigStartInfo,
WorkItemCallback callback)
{
return CreateWorkItem(workItemsGroup, wigStartInfo, callback, null);
}
/// <summary>
/// Create a new work item
/// </summary>
/// <param name="wigStartInfo">Work item group start information</param>
/// <param name="callback">A callback to execute</param>
/// <param name="workItemPriority">The priority of the work item</param>
/// <returns>Returns a work item</returns>
public static WorkItem CreateWorkItem(
IWorkItemsGroup workItemsGroup,
WIGStartInfo wigStartInfo,
WorkItemCallback callback,
WorkItemPriority workItemPriority)
{
return CreateWorkItem(workItemsGroup, wigStartInfo, callback, null, workItemPriority);
}
/// <summary>
/// Create a new work item
/// </summary>
/// <param name="wigStartInfo">Work item group start information</param>
/// <param name="workItemInfo">Work item info</param>
/// <param name="callback">A callback to execute</param>
/// <returns>Returns a work item</returns>
public static WorkItem CreateWorkItem(
IWorkItemsGroup workItemsGroup,
WIGStartInfo wigStartInfo,
WorkItemInfo workItemInfo,
WorkItemCallback callback)
{
return CreateWorkItem(
workItemsGroup,
wigStartInfo,
workItemInfo,
callback,
null);
}
/// <summary>
/// Create a new work item
/// </summary>
/// <param name="wigStartInfo">Work item group start information</param>
/// <param name="callback">A callback to execute</param>
/// <param name="state">
/// The context object of the work item. Used for passing arguments to the work item.
/// </param>
/// <returns>Returns a work item</returns>
public static WorkItem CreateWorkItem(
IWorkItemsGroup workItemsGroup,
WIGStartInfo wigStartInfo,
WorkItemCallback callback,
object state)
{
ValidateCallback(callback);
WorkItemInfo workItemInfo = new WorkItemInfo();
workItemInfo.UseCallerCallContext = wigStartInfo.UseCallerCallContext;
workItemInfo.UseCallerHttpContext = wigStartInfo.UseCallerHttpContext;
workItemInfo.PostExecuteWorkItemCallback = wigStartInfo.PostExecuteWorkItemCallback;
workItemInfo.CallToPostExecute = wigStartInfo.CallToPostExecute;
workItemInfo.DisposeOfStateObjects = wigStartInfo.DisposeOfStateObjects;
WorkItem workItem = new WorkItem(
workItemsGroup,
workItemInfo,
callback,
state);
return workItem;
}
/// <summary>
/// Create a new work item
/// </summary>
/// <param name="wigStartInfo">Work item group start information</param>
/// <param name="callback">A callback to execute</param>
/// <param name="state">
/// The context object of the work item. Used for passing arguments to the work item.
/// </param>
/// <param name="workItemPriority">The work item priority</param>
/// <returns>Returns a work item</returns>
public static WorkItem CreateWorkItem(
IWorkItemsGroup workItemsGroup,
WIGStartInfo wigStartInfo,
WorkItemCallback callback,
object state,
WorkItemPriority workItemPriority)
{
ValidateCallback(callback);
WorkItemInfo workItemInfo = new WorkItemInfo();
workItemInfo.UseCallerCallContext = wigStartInfo.UseCallerCallContext;
workItemInfo.UseCallerHttpContext = wigStartInfo.UseCallerHttpContext;
workItemInfo.PostExecuteWorkItemCallback = wigStartInfo.PostExecuteWorkItemCallback;
workItemInfo.CallToPostExecute = wigStartInfo.CallToPostExecute;
workItemInfo.DisposeOfStateObjects = wigStartInfo.DisposeOfStateObjects;
workItemInfo.WorkItemPriority = workItemPriority;
WorkItem workItem = new WorkItem(
workItemsGroup,
workItemInfo,
callback,
state);
return workItem;
}
/// <summary>
/// Create a new work item
/// </summary>
/// <param name="wigStartInfo">Work item group start information</param>
/// <param name="workItemInfo">Work item information</param>
/// <param name="callback">A callback to execute</param>
/// <param name="state">
/// The context object of the work item. Used for passing arguments to the work item.
/// </param>
/// <returns>Returns a work item</returns>
public static WorkItem CreateWorkItem(
IWorkItemsGroup workItemsGroup,
WIGStartInfo wigStartInfo,
WorkItemInfo workItemInfo,
WorkItemCallback callback,
object state)
{
ValidateCallback(callback);
ValidateCallback(workItemInfo.PostExecuteWorkItemCallback);
WorkItem workItem = new WorkItem(
workItemsGroup,
new WorkItemInfo(workItemInfo),
callback,
state);
return workItem;
}
/// <summary>
/// Create a new work item
/// </summary>
/// <param name="wigStartInfo">Work item group start information</param>
/// <param name="callback">A callback to execute</param>
/// <param name="state">
/// The context object of the work item. Used for passing arguments to the work item.
/// </param>
/// <param name="postExecuteWorkItemCallback">
/// A delegate to call after the callback completion
/// </param>
/// <returns>Returns a work item</returns>
public static WorkItem CreateWorkItem(
IWorkItemsGroup workItemsGroup,
WIGStartInfo wigStartInfo,
WorkItemCallback callback,
object state,
PostExecuteWorkItemCallback postExecuteWorkItemCallback)
{
ValidateCallback(callback);
ValidateCallback(postExecuteWorkItemCallback);
WorkItemInfo workItemInfo = new WorkItemInfo();
workItemInfo.UseCallerCallContext = wigStartInfo.UseCallerCallContext;
workItemInfo.UseCallerHttpContext = wigStartInfo.UseCallerHttpContext;
workItemInfo.PostExecuteWorkItemCallback = postExecuteWorkItemCallback;
workItemInfo.CallToPostExecute = wigStartInfo.CallToPostExecute;
workItemInfo.DisposeOfStateObjects = wigStartInfo.DisposeOfStateObjects;
WorkItem workItem = new WorkItem(
workItemsGroup,
workItemInfo,
callback,
state);
return workItem;
}
/// <summary>
/// Create a new work item
/// </summary>
/// <param name="wigStartInfo">Work item group start information</param>
/// <param name="callback">A callback to execute</param>
/// <param name="state">
/// The context object of the work item. Used for passing arguments to the work item.
/// </param>
/// <param name="postExecuteWorkItemCallback">
/// A delegate to call after the callback completion
/// </param>
/// <param name="workItemPriority">The work item priority</param>
/// <returns>Returns a work item</returns>
public static WorkItem CreateWorkItem(
IWorkItemsGroup workItemsGroup,
WIGStartInfo wigStartInfo,
WorkItemCallback callback,
object state,
PostExecuteWorkItemCallback postExecuteWorkItemCallback,
WorkItemPriority workItemPriority)
{
ValidateCallback(callback);
ValidateCallback(postExecuteWorkItemCallback);
WorkItemInfo workItemInfo = new WorkItemInfo();
workItemInfo.UseCallerCallContext = wigStartInfo.UseCallerCallContext;
workItemInfo.UseCallerHttpContext = wigStartInfo.UseCallerHttpContext;
workItemInfo.PostExecuteWorkItemCallback = postExecuteWorkItemCallback;
workItemInfo.CallToPostExecute = wigStartInfo.CallToPostExecute;
workItemInfo.DisposeOfStateObjects = wigStartInfo.DisposeOfStateObjects;
workItemInfo.WorkItemPriority = workItemPriority;
WorkItem workItem = new WorkItem(
workItemsGroup,
workItemInfo,
callback,
state);
return workItem;
}
/// <summary>
/// Create a new work item
/// </summary>
/// <param name="wigStartInfo">Work item group start information</param>
/// <param name="callback">A callback to execute</param>
/// <param name="state">
/// The context object of the work item. Used for passing arguments to the work item.
/// </param>
/// <param name="postExecuteWorkItemCallback">
/// A delegate to call after the callback completion
/// </param>
/// <param name="callToPostExecute">Indicates on which cases to call to the post execute callback</param>
/// <returns>Returns a work item</returns>
public static WorkItem CreateWorkItem(
IWorkItemsGroup workItemsGroup,
WIGStartInfo wigStartInfo,
WorkItemCallback callback,
object state,
PostExecuteWorkItemCallback postExecuteWorkItemCallback,
CallToPostExecute callToPostExecute)
{
ValidateCallback(callback);
ValidateCallback(postExecuteWorkItemCallback);
WorkItemInfo workItemInfo = new WorkItemInfo();
workItemInfo.UseCallerCallContext = wigStartInfo.UseCallerCallContext;
workItemInfo.UseCallerHttpContext = wigStartInfo.UseCallerHttpContext;
workItemInfo.PostExecuteWorkItemCallback = postExecuteWorkItemCallback;
workItemInfo.CallToPostExecute = callToPostExecute;
workItemInfo.DisposeOfStateObjects = wigStartInfo.DisposeOfStateObjects;
WorkItem workItem = new WorkItem(
workItemsGroup,
workItemInfo,
callback,
state);
return workItem;
}
/// <summary>
/// Create a new work item
/// </summary>
/// <param name="wigStartInfo">Work item group start information</param>
/// <param name="callback">A callback to execute</param>
/// <param name="state">
/// The context object of the work item. Used for passing arguments to the work item.
/// </param>
/// <param name="postExecuteWorkItemCallback">
/// A delegate to call after the callback completion
/// </param>
/// <param name="callToPostExecute">Indicates on which cases to call to the post execute callback</param>
/// <param name="workItemPriority">The work item priority</param>
/// <returns>Returns a work item</returns>
public static WorkItem CreateWorkItem(
IWorkItemsGroup workItemsGroup,
WIGStartInfo wigStartInfo,
WorkItemCallback callback,
object state,
PostExecuteWorkItemCallback postExecuteWorkItemCallback,
CallToPostExecute callToPostExecute,
WorkItemPriority workItemPriority)
{
ValidateCallback(callback);
ValidateCallback(postExecuteWorkItemCallback);
WorkItemInfo workItemInfo = new WorkItemInfo();
workItemInfo.UseCallerCallContext = wigStartInfo.UseCallerCallContext;
workItemInfo.UseCallerHttpContext = wigStartInfo.UseCallerHttpContext;
workItemInfo.PostExecuteWorkItemCallback = postExecuteWorkItemCallback;
workItemInfo.CallToPostExecute = callToPostExecute;
workItemInfo.WorkItemPriority = workItemPriority;
workItemInfo.DisposeOfStateObjects = wigStartInfo.DisposeOfStateObjects;
WorkItem workItem = new WorkItem(
workItemsGroup,
workItemInfo,
callback,
state);
return workItem;
}
private static void ValidateCallback(Delegate callback)
{
if(callback.GetInvocationList().Length > 1)
{
throw new NotSupportedException("SmartThreadPool doesn't support delegates chains");
}
}
}
#endregion
}

View File

@ -0,0 +1,102 @@
// Ami Bar
// amibar@gmail.com
namespace Amib.Threading
{
#region WorkItemInfo class
/// <summary>
/// Summary description for WorkItemInfo.
/// </summary>
public class WorkItemInfo
{
/// <summary>
/// Use the caller's security context
/// </summary>
private bool _useCallerCallContext;
/// <summary>
/// Use the caller's security context
/// </summary>
private bool _useCallerHttpContext;
/// <summary>
/// Dispose of the state object of a work item
/// </summary>
private bool _disposeOfStateObjects;
/// <summary>
/// The option to run the post execute
/// </summary>
private CallToPostExecute _callToPostExecute;
/// <summary>
/// A post execute callback to call when none is provided in
/// the QueueWorkItem method.
/// </summary>
private PostExecuteWorkItemCallback _postExecuteWorkItemCallback;
/// <summary>
/// The priority of the work item
/// </summary>
private WorkItemPriority _workItemPriority;
public WorkItemInfo()
{
_useCallerCallContext = SmartThreadPool.DefaultUseCallerCallContext;
_useCallerHttpContext = SmartThreadPool.DefaultUseCallerHttpContext;
_disposeOfStateObjects = SmartThreadPool.DefaultDisposeOfStateObjects;
_callToPostExecute = SmartThreadPool.DefaultCallToPostExecute;
_postExecuteWorkItemCallback = SmartThreadPool.DefaultPostExecuteWorkItemCallback;
_workItemPriority = SmartThreadPool.DefaultWorkItemPriority;
}
public WorkItemInfo(WorkItemInfo workItemInfo)
{
_useCallerCallContext = workItemInfo._useCallerCallContext;
_useCallerHttpContext = workItemInfo._useCallerHttpContext;
_disposeOfStateObjects = workItemInfo._disposeOfStateObjects;
_callToPostExecute = workItemInfo._callToPostExecute;
_postExecuteWorkItemCallback = workItemInfo._postExecuteWorkItemCallback;
_workItemPriority = workItemInfo._workItemPriority;
}
public bool UseCallerCallContext
{
get { return _useCallerCallContext; }
set { _useCallerCallContext = value; }
}
public bool UseCallerHttpContext
{
get { return _useCallerHttpContext; }
set { _useCallerHttpContext = value; }
}
public bool DisposeOfStateObjects
{
get { return _disposeOfStateObjects; }
set { _disposeOfStateObjects = value; }
}
public CallToPostExecute CallToPostExecute
{
get { return _callToPostExecute; }
set { _callToPostExecute = value; }
}
public PostExecuteWorkItemCallback PostExecuteWorkItemCallback
{
get { return _postExecuteWorkItemCallback; }
set { _postExecuteWorkItemCallback = value; }
}
public WorkItemPriority WorkItemPriority
{
get { return _workItemPriority; }
set { _workItemPriority = value; }
}
}
#endregion
}

View File

@ -0,0 +1,512 @@
// Ami Bar
// amibar@gmail.com
using System;
using System.Threading;
using System.Runtime.CompilerServices;
using System.Diagnostics;
namespace Amib.Threading.Internal
{
#region WorkItemsGroup class
/// <summary>
/// Summary description for WorkItemsGroup.
/// </summary>
public class WorkItemsGroup : IWorkItemsGroup
{
#region Private members
private object _lock = new object();
/// <summary>
/// Contains the name of this instance of SmartThreadPool.
/// Can be changed by the user.
/// </summary>
private string _name = "WorkItemsGroup";
/// <summary>
/// A reference to the SmartThreadPool instance that created this
/// WorkItemsGroup.
/// </summary>
private SmartThreadPool _stp;
/// <summary>
/// The OnIdle event
/// </summary>
private event WorkItemsGroupIdleHandler _onIdle;
/// <summary>
/// Defines how many work items of this WorkItemsGroup can run at once.
/// </summary>
private int _concurrency;
/// <summary>
/// Priority queue to hold work items before they are passed
/// to the SmartThreadPool.
/// </summary>
private PriorityQueue _workItemsQueue;
/// <summary>
/// Indicate how many work items are waiting in the SmartThreadPool
/// queue.
/// This value is used to apply the concurrency.
/// </summary>
private int _workItemsInStpQueue;
/// <summary>
/// Indicate how many work items are currently running in the SmartThreadPool.
/// This value is used with the Cancel, to calculate if we can send new
/// work items to the STP.
/// </summary>
private int _workItemsExecutingInStp = 0;
/// <summary>
/// WorkItemsGroup start information
/// </summary>
private WIGStartInfo _workItemsGroupStartInfo;
/// <summary>
/// Signaled when all of the WorkItemsGroup's work item completed.
/// </summary>
private ManualResetEvent _isIdleWaitHandle = new ManualResetEvent(true);
/// <summary>
/// A common object for all the work items that this work items group
/// generate so we can mark them to cancel in O(1)
/// </summary>
private CanceledWorkItemsGroup _canceledWorkItemsGroup = new CanceledWorkItemsGroup();
#endregion
#region Construction
public WorkItemsGroup(
SmartThreadPool stp,
int concurrency,
WIGStartInfo wigStartInfo)
{
if (concurrency <= 0)
{
throw new ArgumentOutOfRangeException("concurrency", concurrency, "concurrency must be greater than zero");
}
_stp = stp;
_concurrency = concurrency;
_workItemsGroupStartInfo = new WIGStartInfo(wigStartInfo);
_workItemsQueue = new PriorityQueue();
// The _workItemsInStpQueue gets the number of currently executing work items,
// because once a work item is executing, it cannot be cancelled.
_workItemsInStpQueue = _workItemsExecutingInStp;
}
#endregion
#region IWorkItemsGroup implementation
/// <summary>
/// Get/Set the name of the SmartThreadPool instance
/// </summary>
public string Name
{
get
{
return _name;
}
set
{
_name = value;
}
}
/// <summary>
/// Queue a work item
/// </summary>
/// <param name="callback">A callback to execute</param>
/// <returns>Returns a work item result</returns>
public IWorkItemResult QueueWorkItem(WorkItemCallback callback)
{
WorkItem workItem = WorkItemFactory.CreateWorkItem(this, _workItemsGroupStartInfo, callback);
EnqueueToSTPNextWorkItem(workItem);
return workItem.GetWorkItemResult();
}
/// <summary>
/// Queue a work item
/// </summary>
/// <param name="callback">A callback to execute</param>
/// <param name="workItemPriority">The priority of the work item</param>
/// <returns>Returns a work item result</returns>
public IWorkItemResult QueueWorkItem(WorkItemCallback callback, WorkItemPriority workItemPriority)
{
WorkItem workItem = WorkItemFactory.CreateWorkItem(this, _workItemsGroupStartInfo, callback, workItemPriority);
EnqueueToSTPNextWorkItem(workItem);
return workItem.GetWorkItemResult();
}
/// <summary>
/// Queue a work item
/// </summary>
/// <param name="workItemInfo">Work item info</param>
/// <param name="callback">A callback to execute</param>
/// <returns>Returns a work item result</returns>
public IWorkItemResult QueueWorkItem(WorkItemInfo workItemInfo, WorkItemCallback callback)
{
WorkItem workItem = WorkItemFactory.CreateWorkItem(this, _workItemsGroupStartInfo, workItemInfo, callback);
EnqueueToSTPNextWorkItem(workItem);
return workItem.GetWorkItemResult();
}
/// <summary>
/// Queue a work item
/// </summary>
/// <param name="callback">A callback to execute</param>
/// <param name="state">
/// The context object of the work item. Used for passing arguments to the work item.
/// </param>
/// <returns>Returns a work item result</returns>
public IWorkItemResult QueueWorkItem(WorkItemCallback callback, object state)
{
WorkItem workItem = WorkItemFactory.CreateWorkItem(this, _workItemsGroupStartInfo, callback, state);
EnqueueToSTPNextWorkItem(workItem);
return workItem.GetWorkItemResult();
}
/// <summary>
/// Queue a work item
/// </summary>
/// <param name="callback">A callback to execute</param>
/// <param name="state">
/// The context object of the work item. Used for passing arguments to the work item.
/// </param>
/// <param name="workItemPriority">The work item priority</param>
/// <returns>Returns a work item result</returns>
public IWorkItemResult QueueWorkItem(WorkItemCallback callback, object state, WorkItemPriority workItemPriority)
{
WorkItem workItem = WorkItemFactory.CreateWorkItem(this, _workItemsGroupStartInfo, callback, state, workItemPriority);
EnqueueToSTPNextWorkItem(workItem);
return workItem.GetWorkItemResult();
}
/// <summary>
/// Queue a work item
/// </summary>
/// <param name="workItemInfo">Work item information</param>
/// <param name="callback">A callback to execute</param>
/// <param name="state">
/// The context object of the work item. Used for passing arguments to the work item.
/// </param>
/// <returns>Returns a work item result</returns>
public IWorkItemResult QueueWorkItem(WorkItemInfo workItemInfo, WorkItemCallback callback, object state)
{
WorkItem workItem = WorkItemFactory.CreateWorkItem(this, _workItemsGroupStartInfo, workItemInfo, callback, state);
EnqueueToSTPNextWorkItem(workItem);
return workItem.GetWorkItemResult();
}
/// <summary>
/// Queue a work item
/// </summary>
/// <param name="callback">A callback to execute</param>
/// <param name="state">
/// The context object of the work item. Used for passing arguments to the work item.
/// </param>
/// <param name="postExecuteWorkItemCallback">
/// A delegate to call after the callback completion
/// </param>
/// <returns>Returns a work item result</returns>
public IWorkItemResult QueueWorkItem(
WorkItemCallback callback,
object state,
PostExecuteWorkItemCallback postExecuteWorkItemCallback)
{
WorkItem workItem = WorkItemFactory.CreateWorkItem(this, _workItemsGroupStartInfo, callback, state, postExecuteWorkItemCallback);
EnqueueToSTPNextWorkItem(workItem);
return workItem.GetWorkItemResult();
}
/// <summary>
/// Queue a work item
/// </summary>
/// <param name="callback">A callback to execute</param>
/// <param name="state">
/// The context object of the work item. Used for passing arguments to the work item.
/// </param>
/// <param name="postExecuteWorkItemCallback">
/// A delegate to call after the callback completion
/// </param>
/// <param name="workItemPriority">The work item priority</param>
/// <returns>Returns a work item result</returns>
public IWorkItemResult QueueWorkItem(
WorkItemCallback callback,
object state,
PostExecuteWorkItemCallback postExecuteWorkItemCallback,
WorkItemPriority workItemPriority)
{
WorkItem workItem = WorkItemFactory.CreateWorkItem(this, _workItemsGroupStartInfo, callback, state, postExecuteWorkItemCallback, workItemPriority);
EnqueueToSTPNextWorkItem(workItem);
return workItem.GetWorkItemResult();
}
/// <summary>
/// Queue a work item
/// </summary>
/// <param name="callback">A callback to execute</param>
/// <param name="state">
/// The context object of the work item. Used for passing arguments to the work item.
/// </param>
/// <param name="postExecuteWorkItemCallback">
/// A delegate to call after the callback completion
/// </param>
/// <param name="callToPostExecute">Indicates on which cases to call to the post execute callback</param>
/// <returns>Returns a work item result</returns>
public IWorkItemResult QueueWorkItem(
WorkItemCallback callback,
object state,
PostExecuteWorkItemCallback postExecuteWorkItemCallback,
CallToPostExecute callToPostExecute)
{
WorkItem workItem = WorkItemFactory.CreateWorkItem(this, _workItemsGroupStartInfo, callback, state, postExecuteWorkItemCallback, callToPostExecute);
EnqueueToSTPNextWorkItem(workItem);
return workItem.GetWorkItemResult();
}
/// <summary>
/// Queue a work item
/// </summary>
/// <param name="callback">A callback to execute</param>
/// <param name="state">
/// The context object of the work item. Used for passing arguments to the work item.
/// </param>
/// <param name="postExecuteWorkItemCallback">
/// A delegate to call after the callback completion
/// </param>
/// <param name="callToPostExecute">Indicates on which cases to call to the post execute callback</param>
/// <param name="workItemPriority">The work item priority</param>
/// <returns>Returns a work item result</returns>
public IWorkItemResult QueueWorkItem(
WorkItemCallback callback,
object state,
PostExecuteWorkItemCallback postExecuteWorkItemCallback,
CallToPostExecute callToPostExecute,
WorkItemPriority workItemPriority)
{
WorkItem workItem = WorkItemFactory.CreateWorkItem(this, _workItemsGroupStartInfo, callback, state, postExecuteWorkItemCallback, callToPostExecute, workItemPriority);
EnqueueToSTPNextWorkItem(workItem);
return workItem.GetWorkItemResult();
}
/// <summary>
/// Wait for the thread pool to be idle
/// </summary>
public void WaitForIdle()
{
WaitForIdle(Timeout.Infinite);
}
/// <summary>
/// Wait for the thread pool to be idle
/// </summary>
public bool WaitForIdle(TimeSpan timeout)
{
return WaitForIdle((int)timeout.TotalMilliseconds);
}
/// <summary>
/// Wait for the thread pool to be idle
/// </summary>
public bool WaitForIdle(int millisecondsTimeout)
{
_stp.ValidateWorkItemsGroupWaitForIdle(this);
return _isIdleWaitHandle.WaitOne(millisecondsTimeout, false);
}
public int WaitingCallbacks
{
get
{
return _workItemsQueue.Count;
}
}
public event WorkItemsGroupIdleHandler OnIdle
{
add
{
_onIdle += value;
}
remove
{
_onIdle -= value;
}
}
public void Cancel()
{
lock(_lock)
{
_canceledWorkItemsGroup.IsCanceled = true;
_workItemsQueue.Clear();
_workItemsInStpQueue = 0;
_canceledWorkItemsGroup = new CanceledWorkItemsGroup();
}
}
public void Start()
{
lock (this)
{
if (!_workItemsGroupStartInfo.StartSuspended)
{
return;
}
_workItemsGroupStartInfo.StartSuspended = false;
}
for(int i = 0; i < _concurrency; ++i)
{
EnqueueToSTPNextWorkItem(null, false);
}
}
#endregion
#region Private methods
private void RegisterToWorkItemCompletion(IWorkItemResult wir)
{
IInternalWorkItemResult iwir = wir as IInternalWorkItemResult;
iwir.OnWorkItemStarted += new WorkItemStateCallback(OnWorkItemStartedCallback);
iwir.OnWorkItemCompleted += new WorkItemStateCallback(OnWorkItemCompletedCallback);
}
public void OnSTPIsStarting()
{
lock (this)
{
if (_workItemsGroupStartInfo.StartSuspended)
{
return;
}
}
for(int i = 0; i < _concurrency; ++i)
{
EnqueueToSTPNextWorkItem(null, false);
}
}
private object FireOnIdle(object state)
{
FireOnIdleImpl(_onIdle);
return null;
}
[MethodImpl(MethodImplOptions.NoInlining)]
private void FireOnIdleImpl(WorkItemsGroupIdleHandler onIdle)
{
if(null == onIdle)
{
return;
}
Delegate[] delegates = onIdle.GetInvocationList();
foreach(WorkItemsGroupIdleHandler eh in delegates)
{
try
{
eh(this);
}
// Ignore exceptions
catch{}
}
}
private void OnWorkItemStartedCallback(WorkItem workItem)
{
lock(_lock)
{
++_workItemsExecutingInStp;
}
}
private void OnWorkItemCompletedCallback(WorkItem workItem)
{
EnqueueToSTPNextWorkItem(null, true);
}
private void EnqueueToSTPNextWorkItem(WorkItem workItem)
{
EnqueueToSTPNextWorkItem(workItem, false);
}
private void EnqueueToSTPNextWorkItem(WorkItem workItem, bool decrementWorkItemsInStpQueue)
{
lock(_lock)
{
// Got here from OnWorkItemCompletedCallback()
if (decrementWorkItemsInStpQueue)
{
--_workItemsInStpQueue;
if(_workItemsInStpQueue < 0)
{
_workItemsInStpQueue = 0;
}
--_workItemsExecutingInStp;
if(_workItemsExecutingInStp < 0)
{
_workItemsExecutingInStp = 0;
}
}
// If the work item is not null then enqueue it
if (null != workItem)
{
workItem.CanceledWorkItemsGroup = _canceledWorkItemsGroup;
RegisterToWorkItemCompletion(workItem.GetWorkItemResult());
_workItemsQueue.Enqueue(workItem);
//_stp.IncrementWorkItemsCount();
if ((1 == _workItemsQueue.Count) &&
(0 == _workItemsInStpQueue))
{
_stp.RegisterWorkItemsGroup(this);
Trace.WriteLine("WorkItemsGroup " + Name + " is NOT idle");
_isIdleWaitHandle.Reset();
}
}
// If the work items queue of the group is empty than quit
if (0 == _workItemsQueue.Count)
{
if (0 == _workItemsInStpQueue)
{
_stp.UnregisterWorkItemsGroup(this);
Trace.WriteLine("WorkItemsGroup " + Name + " is idle");
_isIdleWaitHandle.Set();
_stp.QueueWorkItem(new WorkItemCallback(this.FireOnIdle));
}
return;
}
if (!_workItemsGroupStartInfo.StartSuspended)
{
if (_workItemsInStpQueue < _concurrency)
{
WorkItem nextWorkItem = _workItemsQueue.Dequeue() as WorkItem;
_stp.Enqueue(nextWorkItem, true);
++_workItemsInStpQueue;
}
}
}
}
#endregion
}
#endregion
}

View File

@ -0,0 +1,600 @@
// Ami Bar
// amibar@gmail.com
using System;
using System.Threading;
namespace Amib.Threading.Internal
{
#region WorkItemsQueue class
/// <summary>
/// WorkItemsQueue class.
/// </summary>
public class WorkItemsQueue : IDisposable
{
#region Member variables
/// <summary>
/// Waiters queue (implemented as stack).
/// </summary>
private WaiterEntry _headWaiterEntry = new WaiterEntry();
/// <summary>
/// Waiters count
/// </summary>
private int _waitersCount = 0;
/// <summary>
/// Work items queue
/// </summary>
private PriorityQueue _workItems = new PriorityQueue();
/// <summary>
/// Indicate that work items are allowed to be queued
/// </summary>
private bool _isWorkItemsQueueActive = true;
/// <summary>
/// Each thread in the thread pool keeps its own waiter entry.
/// </summary>
[ThreadStatic]
private static WaiterEntry _waiterEntry;
/// <summary>
/// A flag that indicates if the WorkItemsQueue has been disposed.
/// </summary>
private bool _isDisposed = false;
#endregion
#region Public properties
/// <summary>
/// Returns the current number of work items in the queue
/// </summary>
public int Count
{
get
{
lock(this)
{
ValidateNotDisposed();
return _workItems.Count;
}
}
}
/// <summary>
/// Returns the current number of waiters
/// </summary>
public int WaitersCount
{
get
{
lock(this)
{
ValidateNotDisposed();
return _waitersCount;
}
}
}
#endregion
#region Public methods
/// <summary>
/// Enqueue a work item to the queue.
/// </summary>
public bool EnqueueWorkItem(WorkItem workItem)
{
// A work item cannot be null, since null is used in the
// WaitForWorkItem() method to indicate timeout or cancel
if (null == workItem)
{
throw new ArgumentNullException("workItem" , "workItem cannot be null");
}
bool enqueue = true;
// First check if there is a waiter waiting for work item. During
// the check, timed out waiters are ignored. If there is no
// waiter then the work item is queued.
lock(this)
{
ValidateNotDisposed();
if (!_isWorkItemsQueueActive)
{
return false;
}
while(_waitersCount > 0)
{
// Dequeue a waiter.
WaiterEntry waiterEntry = PopWaiter();
// Signal the waiter. On success break the loop
if (waiterEntry.Signal(workItem))
{
enqueue = false;
break;
}
}
if (enqueue)
{
// Enqueue the work item
_workItems.Enqueue(workItem);
}
}
return true;
}
/// <summary>
/// Waits for a work item or exits on timeout or cancel
/// </summary>
/// <param name="millisecondsTimeout">Timeout in milliseconds</param>
/// <param name="cancelEvent">Cancel wait handle</param>
/// <returns>Returns true if the resource was granted</returns>
public WorkItem DequeueWorkItem(
int millisecondsTimeout,
WaitHandle cancelEvent)
{
/// This method cause the caller to wait for a work item.
/// If there is at least one waiting work item then the
/// method returns immidiately with true.
///
/// If there are no waiting work items then the caller
/// is queued between other waiters for a work item to arrive.
///
/// If a work item didn't come within millisecondsTimeout or
/// the user canceled the wait by signaling the cancelEvent
/// then the method returns false to indicate that the caller
/// didn't get a work item.
WaiterEntry waiterEntry = null;
WorkItem workItem = null;
lock(this)
{
ValidateNotDisposed();
// If there are waiting work items then take one and return.
if (_workItems.Count > 0)
{
workItem = _workItems.Dequeue() as WorkItem;
return workItem;
}
// No waiting work items ...
else
{
// Get the wait entry for the waiters queue
waiterEntry = GetThreadWaiterEntry();
// Put the waiter with the other waiters
PushWaiter(waiterEntry);
}
}
// Prepare array of wait handle for the WaitHandle.WaitAny()
WaitHandle [] waitHandles = new WaitHandle [] {
waiterEntry.WaitHandle,
cancelEvent };
// Wait for an available resource, cancel event, or timeout.
// During the wait we are supposes to exit the synchronization
// domain. (Placing true as the third argument of the WaitAny())
// It just doesn't work, I don't know why, so I have lock(this)
// statments insted of one.
int index = WaitHandle.WaitAny(
waitHandles,
millisecondsTimeout,
true);
lock(this)
{
// success is true if it got a work item.
bool success = (0 == index);
// The timeout variable is used only for readability.
// (We treat cancel as timeout)
bool timeout = !success;
// On timeout update the waiterEntry that it is timed out
if (timeout)
{
// The Timeout() fails if the waiter has already been signaled
timeout = waiterEntry.Timeout();
// On timeout remove the waiter from the queue.
// Note that the complexity is O(1).
if(timeout)
{
RemoveWaiter(waiterEntry, false);
}
// Again readability
success = !timeout;
}
// On success return the work item
if (success)
{
workItem = waiterEntry.WorkItem;
if (null == workItem)
{
workItem = _workItems.Dequeue() as WorkItem;
}
}
}
// On failure return null.
return workItem;
}
/// <summary>
/// Cleanup the work items queue, hence no more work
/// items are allowed to be queue
/// </summary>
protected virtual void Cleanup()
{
lock(this)
{
// Deactivate only once
if (!_isWorkItemsQueueActive)
{
return;
}
// Don't queue more work items
_isWorkItemsQueueActive = false;
foreach(WorkItem workItem in _workItems)
{
workItem.DisposeOfState();
}
// Clear the work items that are already queued
_workItems.Clear();
// Note:
// I don't iterate over the queue and dispose of work items's states,
// since if a work item has a state object that is still in use in the
// application then I must not dispose it.
// Tell the waiters that they were timed out.
// It won't signal them to exit, but to ignore their
// next work item.
while(_waitersCount > 0)
{
WaiterEntry waiterEntry = PopWaiter();
waiterEntry.Timeout();
}
}
}
#endregion
#region Private methods
/// <summary>
/// Returns the WaiterEntry of the current thread
/// </summary>
/// <returns></returns>
/// In order to avoid creation and destuction of WaiterEntry
/// objects each thread has its own WaiterEntry object.
private WaiterEntry GetThreadWaiterEntry()
{
if (null == _waiterEntry)
{
_waiterEntry = new WaiterEntry();
}
_waiterEntry.Reset();
return _waiterEntry;
}
#region Waiters stack methods
/// <summary>
/// Push a new waiter into the waiter's stack
/// </summary>
/// <param name="newWaiterEntry">A waiter to put in the stack</param>
public void PushWaiter(WaiterEntry newWaiterEntry)
{
// Remove the waiter if it is already in the stack and
// update waiter's count as needed
RemoveWaiter(newWaiterEntry, false);
// If the stack is empty then newWaiterEntry is the new head of the stack
if (null == _headWaiterEntry._nextWaiterEntry)
{
_headWaiterEntry._nextWaiterEntry = newWaiterEntry;
newWaiterEntry._prevWaiterEntry = _headWaiterEntry;
}
// If the stack is not empty then put newWaiterEntry as the new head
// of the stack.
else
{
// Save the old first waiter entry
WaiterEntry oldFirstWaiterEntry = _headWaiterEntry._nextWaiterEntry;
// Update the links
_headWaiterEntry._nextWaiterEntry = newWaiterEntry;
newWaiterEntry._nextWaiterEntry = oldFirstWaiterEntry;
newWaiterEntry._prevWaiterEntry = _headWaiterEntry;
oldFirstWaiterEntry._prevWaiterEntry = newWaiterEntry;
}
// Increment the number of waiters
++_waitersCount;
}
/// <summary>
/// Pop a waiter from the waiter's stack
/// </summary>
/// <returns>Returns the first waiter in the stack</returns>
private WaiterEntry PopWaiter()
{
// Store the current stack head
WaiterEntry oldFirstWaiterEntry = _headWaiterEntry._nextWaiterEntry;
// Store the new stack head
WaiterEntry newHeadWaiterEntry = oldFirstWaiterEntry._nextWaiterEntry;
// Update the old stack head list links and decrement the number
// waiters.
RemoveWaiter(oldFirstWaiterEntry, true);
// Update the new stack head
_headWaiterEntry._nextWaiterEntry = newHeadWaiterEntry;
if (null != newHeadWaiterEntry)
{
newHeadWaiterEntry._prevWaiterEntry = _headWaiterEntry;
}
// Return the old stack head
return oldFirstWaiterEntry;
}
/// <summary>
/// Remove a waiter from the stack
/// </summary>
/// <param name="waiterEntry">A waiter entry to remove</param>
/// <param name="popDecrement">If true the waiter count is always decremented</param>
private void RemoveWaiter(WaiterEntry waiterEntry, bool popDecrement)
{
// Store the prev entry in the list
WaiterEntry prevWaiterEntry = waiterEntry._prevWaiterEntry;
// Store the next entry in the list
WaiterEntry nextWaiterEntry = waiterEntry._nextWaiterEntry;
// A flag to indicate if we need to decrement the waiters count.
// If we got here from PopWaiter then we must decrement.
// If we got here from PushWaiter then we decrement only if
// the waiter was already in the stack.
bool decrementCounter = popDecrement;
// Null the waiter's entry links
waiterEntry._prevWaiterEntry = null;
waiterEntry._nextWaiterEntry = null;
// If the waiter entry had a prev link then update it.
// It also means that the waiter is already in the list and we
// need to decrement the waiters count.
if (null != prevWaiterEntry)
{
prevWaiterEntry._nextWaiterEntry = nextWaiterEntry;
decrementCounter = true;
}
// If the waiter entry had a next link then update it.
// It also means that the waiter is already in the list and we
// need to decrement the waiters count.
if (null != nextWaiterEntry)
{
nextWaiterEntry._prevWaiterEntry = prevWaiterEntry;
decrementCounter = true;
}
// Decrement the waiters count if needed
if (decrementCounter)
{
--_waitersCount;
}
}
#endregion
#endregion
#region WaiterEntry class
// A waiter entry in the _waiters queue.
public class WaiterEntry : IDisposable
{
#region Member variables
/// <summary>
/// Event to signal the waiter that it got the work item.
/// </summary>
private AutoResetEvent _waitHandle = new AutoResetEvent(false);
/// <summary>
/// Flag to know if this waiter already quited from the queue
/// because of a timeout.
/// </summary>
private bool _isTimedout = false;
/// <summary>
/// Flag to know if the waiter was signaled and got a work item.
/// </summary>
private bool _isSignaled = false;
/// <summary>
/// A work item that passed directly to the waiter withou going
/// through the queue
/// </summary>
private WorkItem _workItem = null;
private bool _isDisposed = false;
// Linked list members
internal WaiterEntry _nextWaiterEntry = null;
internal WaiterEntry _prevWaiterEntry = null;
#endregion
#region Construction
public WaiterEntry()
{
Reset();
}
#endregion
#region Public methods
public WaitHandle WaitHandle
{
get { return _waitHandle; }
}
public WorkItem WorkItem
{
get
{
lock(this)
{
return _workItem;
}
}
}
/// <summary>
/// Signal the waiter that it got a work item.
/// </summary>
/// <returns>Return true on success</returns>
/// The method fails if Timeout() preceded its call
public bool Signal(WorkItem workItem)
{
lock(this)
{
if (!_isTimedout)
{
_workItem = workItem;
_isSignaled = true;
_waitHandle.Set();
return true;
}
}
return false;
}
/// <summary>
/// Mark the wait entry that it has been timed out
/// </summary>
/// <returns>Return true on success</returns>
/// The method fails if Signal() preceded its call
public bool Timeout()
{
lock(this)
{
// Time out can happen only if the waiter wasn't marked as
// signaled
if (!_isSignaled)
{
// We don't remove the waiter from the queue, the DequeueWorkItem
// method skips _waiters that were timed out.
_isTimedout = true;
return true;
}
}
return false;
}
/// <summary>
/// Reset the wait entry so it can be used again
/// </summary>
public void Reset()
{
_workItem = null;
_isTimedout = false;
_isSignaled = false;
_waitHandle.Reset();
}
/// <summary>
/// Free resources
/// </summary>
public void Close()
{
if (null != _waitHandle)
{
_waitHandle.Close();
_waitHandle = null;
}
}
#endregion
#region IDisposable Members
public void Dispose()
{
if (!_isDisposed)
{
Close();
_isDisposed = true;
}
}
~WaiterEntry()
{
Dispose();
}
#endregion
}
#endregion
#region IDisposable Members
public void Dispose()
{
if (!_isDisposed)
{
Cleanup();
_isDisposed = true;
GC.SuppressFinalize(this);
}
}
~WorkItemsQueue()
{
Cleanup();
}
private void ValidateNotDisposed()
{
if(_isDisposed)
{
throw new ObjectDisposedException(GetType().ToString(), "The SmartThreadPool has been shutdown");
}
}
#endregion
}
#endregion
}

View File

@ -0,0 +1,22 @@
Microsoft Public License (Ms-PL)
This license governs use of the accompanying software. If you use the software, you
accept this license. If you do not accept the license, do not use the software.
1. Definitions
The terms "reproduce," "reproduction," "derivative works," and "distribution" have the
same meaning here as under U.S. copyright law.
A "contribution" is the original software, or any additions or changes to the software.
A "contributor" is any person that distributes its contribution under this license.
"Licensed patents" are a contributor's patent claims that read directly on its contribution.
2. Grant of Rights
(A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works that you create.
(B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution in the software or derivative works of the contribution in the software.
3. Conditions and Limitations
(A) No Trademark License- This license does not grant you rights to use any contributors' name, logo, or trademarks.
(B) If you bring a patent claim against any contributor over patents that you claim are infringed by the software, your patent license from such contributor to the software ends automatically.
(C) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution notices that are present in the software.
(D) If you distribute any portion of the software in source code form, you may do so only under this license by including a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or object code form, you may only do so under a license that complies with this license.
(E) The software is licensed "as-is." You bear the risk of using it. The contributors give no express warranties, guarantees or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent permitted under your local laws, the contributors exclude the implied warranties of merchantability, fitness for a particular purpose and non-infringement.

View File

@ -535,3 +535,40 @@ Password = "password"
ImportOnStartup = false
Autosave = false
AutoSavePeriod = 15 ; Number of minutes between autosave backups
[XEngine]
; How many threads to keep alive even if nothing is happening
MinThreads = 2
; How many threads to start at maximum load
MaxThreads = 100
; Time a thread must be idle (in seconds) before it dies
IdleTimeout = 60
; Thread priority ("Lowest", "BelowNormal", "Normal", "AboveNormal", "Highest")
Priority = "BelowNormal"
; Maximum number of events to queue for a script (excluding timers)
MaxScriptEventQueue = 300
; Stack size per thread created
ThreadStackSize = 262144
; Rate to poll for asynchronous command replies (ms)
AsyncLLCommandLoopms = 50
; Save the source of all compiled scripts
WriteScriptSourceToDebugFile = false
; Default language for scripts
DefaultCompileLanguage = lsl
; List of allowed languages (lsl,vb,js,cs)
AllowedCompilers = lsl
; Compile debug info (line numbers) into the script assemblies
CompileWithDebugInformation = true
; Allow the use of os* functions (some are dangerous)
AllowOSFunctions = false
; Interval (s) between background save of script states
SaveInterval = 120
; Interval (s) between maintenance runs (0 = disable)
MaintenanceInterval = 10
; Time a script can spend in an event handler before it is interrupted
EventLimit = 30
; If a script overruns it's event limit, kill the script?
KillTimedOutScripts = false
; Allow OS console command functionality (VERY DANGEROUS!!)
AllowosConsoleCommand = false

View File

@ -1345,6 +1345,63 @@
</Files>
</Project>
<Project name="OpenSim.Region.ScriptEngine.XEngine.Script" path="OpenSim/Region/ScriptEngine/XEngine/Script" type="Library">
<Configuration name="Debug">
<Options>
<OutputPath>../../../../../bin/</OutputPath>
</Options>
</Configuration>
<Configuration name="Release">
<Options>
<OutputPath>../../../../../bin/</OutputPath>
</Options>
</Configuration>
<ReferencePath>../../../../../bin/</ReferencePath>
<Reference name="System" localCopy="false"/>
<Reference name="System.Data" localCopy="false"/>
<Reference name="System.Web" localCopy="false"/>
<Reference name="System.Xml" localCopy="false"/>
<Reference name="libsecondlife.dll"/>
<Reference name="OpenSim" />
<Reference name="OpenSim.Framework"/>
<Reference name="OpenSim.Framework.Communications"/>
<Reference name="OpenSim.Region.Environment" />
<Reference name="OpenSim.Framework.Console"/>
<Reference name="Axiom.MathLib.dll" localCopy="false"/>
<Reference name="Nini.dll" />
<Reference name="RAIL.dll"/>
<Reference name="Nini.dll" />
<Reference name="log4net"/>
<Files>
<Match pattern="*.cs" recurse="true"/>
</Files>
</Project>
<Project name="SmartThreadPool" path="ThirdParty/SmartThreadPool" type="Library">
<Configuration name="Debug">
<Options>
<OutputPath>../../bin/</OutputPath>
</Options>
</Configuration>
<Configuration name="Release">
<Options>
<OutputPath>../../bin/</OutputPath>
</Options>
</Configuration>
<ReferencePath>../../bin/</ReferencePath>
<Reference name="System" localCopy="false"/>
<Reference name="System.Xml"/>
<Reference name="System.Data"/>
<Reference name="System.Web"/>
<Files>
<Match pattern="*.cs" recurse="false"/>
</Files>
</Project>
<!-- OGS projects -->
@ -1571,6 +1628,43 @@
</Files>
</Project>
<Project name="OpenSim.Region.ScriptEngine.XEngine" path="OpenSim/Region/ScriptEngine/XEngine" type="Library">
<Configuration name="Debug">
<Options>
<OutputPath>../../../../bin/ScriptEngines/</OutputPath>
</Options>
</Configuration>
<Configuration name="Release">
<Options>
<OutputPath>../../../../bin/ScriptEngines/</OutputPath>
</Options>
</Configuration>
<ReferencePath>../../../../bin/</ReferencePath>
<Reference name="System" localCopy="false"/>
<Reference name="System.Data" localCopy="false"/>
<Reference name="System.Xml" localCopy="false"/>
<Reference name="System.Runtime.Remoting" localCopy="false"/>
<Reference name="libsecondlife.dll"/>
<Reference name="RAIL.dll"/>
<Reference name="OpenSim.Framework"/>
<Reference name="OpenSim.Framework.Console"/>
<Reference name="OpenSim.Framework.Communications"/>
<Reference name="OpenSim.Region.Environment" />
<Reference name="OpenSim.Region.ScriptEngine.XEngine.Script" />
<Reference name="Microsoft.JScript"/>
<Reference name="Axiom.MathLib.dll" localCopy="false"/>
<Reference name="Nini.dll" />
<Reference name="SmartThreadPool" />
<Reference name="log4net"/>
<Files>
<Match path="AsyncCommandPlugins" pattern="*.cs" recurse="false"/>
<Match pattern="*.cs" recurse="false"/>
</Files>
</Project>
<Project name="OpenSim.Grid.ScriptServer" path="OpenSim/Grid/ScriptServer" type="Exe">
<Configuration name="Debug">