Merge branch 'master' into careminster

Conflicts:
	OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
	OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
	OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs
avinationmerge
Melanie 2013-01-16 17:05:37 +00:00
commit 206bfe0657
11 changed files with 243 additions and 63 deletions

View File

@ -47,9 +47,6 @@ namespace OpenSim.Framework
Texture = 5,
/// <summary>Non-texture assets</summary>
Asset = 6,
/// <summary>Avatar and primitive data</summary>
/// <remarks>This is a sub-category of Task</remarks>
State = 7,
}
[Flags]
@ -61,6 +58,5 @@ namespace OpenSim.Framework
Task = 1 << 3,
Texture = 1 << 4,
Asset = 1 << 5,
State = 1 << 6,
}
}

View File

@ -1607,7 +1607,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
if (localIDs.Count == 1 && m_scene.GetScenePresence(localIDs[0]) != null)
{
OutPacket(kill, ThrottleOutPacketType.State);
OutPacket(kill, ThrottleOutPacketType.Task);
}
else
{
@ -2788,7 +2788,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
Transfer.TransferInfo.Size = req.AssetInf.Data.Length;
Transfer.TransferInfo.TransferID = req.TransferRequestID;
Transfer.Header.Zerocoded = true;
OutPacket(Transfer, isWearable ? ThrottleOutPacketType.State : ThrottleOutPacketType.Asset);
OutPacket(Transfer, isWearable ? ThrottleOutPacketType.Task : ThrottleOutPacketType.Asset);
if (req.NumPackets == 1)
{
@ -2799,7 +2799,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
TransferPacket.TransferData.Data = req.AssetInf.Data;
TransferPacket.TransferData.Status = 1;
TransferPacket.Header.Zerocoded = true;
OutPacket(TransferPacket, isWearable ? ThrottleOutPacketType.State : ThrottleOutPacketType.Asset);
OutPacket(TransferPacket, isWearable ? ThrottleOutPacketType.Task : ThrottleOutPacketType.Asset);
}
else
{
@ -2832,7 +2832,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
TransferPacket.TransferData.Status = 1;
}
TransferPacket.Header.Zerocoded = true;
OutPacket(TransferPacket, isWearable ? ThrottleOutPacketType.State : ThrottleOutPacketType.Asset);
OutPacket(TransferPacket, isWearable ? ThrottleOutPacketType.Task : ThrottleOutPacketType.Asset);
processedLength += chunkSize;
packetNumber++;
@ -3605,7 +3605,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
}
}
OutPacket(aw, ThrottleOutPacketType.State);
OutPacket(aw, ThrottleOutPacketType.Task);
}
public void SendAppearance(UUID agentID, byte[] visualParams, byte[] textureEntry)
@ -3630,7 +3630,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
avp.Sender.IsTrial = false;
avp.Sender.ID = agentID;
m_log.DebugFormat("[CLIENT]: Sending appearance for {0} to {1}", agentID.ToString(), AgentId.ToString());
OutPacket(avp, ThrottleOutPacketType.State);
OutPacket(avp, ThrottleOutPacketType.Task);
}
public void SendAnimations(UUID[] animations, int[] seqs, UUID sourceAgentId, UUID[] objectIDs)

View File

@ -279,7 +279,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
public string GetStats()
{
return string.Format(
"{0,7} {1,7} {2,7} {3,9} {4,7} {5,7} {6,7} {7,7} {8,7} {9,8} {10,7} {11,7} {12,7}",
"{0,7} {1,7} {2,7} {3,9} {4,7} {5,7} {6,7} {7,7} {8,7} {9,8} {10,7} {11,7}",
Util.EnvironmentTickCountSubtract(TickLastPacketReceived),
PacketsReceived,
PacketsSent,
@ -291,8 +291,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
m_packetOutboxes[(int)ThrottleOutPacketType.Cloud].Count,
m_packetOutboxes[(int)ThrottleOutPacketType.Task].Count,
m_packetOutboxes[(int)ThrottleOutPacketType.Texture].Count,
m_packetOutboxes[(int)ThrottleOutPacketType.Asset].Count,
m_packetOutboxes[(int)ThrottleOutPacketType.State].Count);
m_packetOutboxes[(int)ThrottleOutPacketType.Asset].Count);
}
public void SendPacketStats()
@ -338,8 +337,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
int task = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f); pos += 4;
int texture = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f); pos += 4;
int asset = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f);
// State is a subcategory of task that we allocate a percentage to
int state = 0;
// Make sure none of the throttles are set below our packet MTU,
// otherwise a throttle could become permanently clogged
@ -376,9 +373,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
bucket = m_throttleCategories[(int)ThrottleOutPacketType.Task];
bucket.RequestedDripRate = task;
bucket = m_throttleCategories[(int)ThrottleOutPacketType.State];
bucket.RequestedDripRate = state;
bucket = m_throttleCategories[(int)ThrottleOutPacketType.Texture];
bucket.RequestedDripRate = texture;
@ -709,9 +703,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
Texture = 5,
/// <summary>Non-texture assets</summary>
Asset = 6,
/// <summary>Avatar and primitive data</summary>
/// <remarks>This is a sub-category of Task</remarks>
State = 7,
*/
switch (category)
@ -728,8 +719,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
return ThrottleOutPacketTypeFlags.Texture;
case ThrottleOutPacketType.Asset:
return ThrottleOutPacketTypeFlags.Asset;
case ThrottleOutPacketType.State:
return ThrottleOutPacketTypeFlags.State;
default:
return 0;
}

View File

@ -212,11 +212,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
protected override GridRegion GetFinalDestination(GridRegion region)
{
int flags = Scene.GridService.GetRegionFlags(Scene.RegionInfo.ScopeID, region.RegionID);
m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: region {0} flags: {1}", region.RegionID, flags);
m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: region {0} flags: {1}", region.RegionName, flags);
if ((flags & (int)OpenSim.Framework.RegionFlags.Hyperlink) != 0)
{
m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Destination region {0} is hyperlink", region.RegionID);
m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Destination region is hyperlink");
GridRegion real_destination = m_GatekeeperConnector.GetHyperlinkRegion(region, region.RegionID);
if (real_destination != null)
m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: GetFinalDestination serveruri -> {0}", real_destination.ServerURI);

View File

@ -215,7 +215,7 @@ public sealed class BSCharacter : BSPhysObject
// Add special movement force to allow avatars to walk up stepped surfaces.
moveForce += WalkUpStairs();
DetailLog("{0},BSCharacter.MoveMotor,move,stepVel={1},vel={2},mass={3},moveForce={4}", LocalID, stepVelocity, _velocity, Mass, moveForce);
// DetailLog("{0},BSCharacter.MoveMotor,move,stepVel={1},vel={2},mass={3},moveForce={4}", LocalID, stepVelocity, _velocity, Mass, moveForce);
PhysicsScene.PE.ApplyCentralImpulse(PhysBody, moveForce);
});
}
@ -855,7 +855,10 @@ public sealed class BSCharacter : BSPhysObject
_rotationalVelocity = entprop.RotationalVelocity;
// Do some sanity checking for the avatar. Make sure it's above ground and inbounds.
PositionSanityCheck(true);
if (PositionSanityCheck(true))
{
entprop.Position = _position;
}
// remember the current and last set values
LastEntityProperties = CurrentEntityProperties;

View File

@ -1160,8 +1160,10 @@ namespace OpenSim.Region.Physics.BulletSPlugin
if (!Prim.IsColliding && VehicleVelocity.Z > 0.1)
{
// Get rid of any of the velocity vector that is pushing us up.
VehicleVelocity += new Vector3(0, 0, -VehicleVelocity.Z);
float upVelocity = VehicleVelocity.Z;
VehicleVelocity += new Vector3(0, 0, -upVelocity);
/*
// If we're pointed up into the air, we should nose down
Vector3 pointingDirection = Vector3.UnitX * VehicleOrientation;
// The rotation around the Y axis is pitch up or down
@ -1175,11 +1177,9 @@ namespace OpenSim.Region.Physics.BulletSPlugin
VDetailLog("{0}, MoveLinear,limitMotorUp,newVel={1},pntDir={2},corrFrc={3},aCorr={4}",
Prim.LocalID, VehicleVelocity, pointingDirection, angularCorrectionForce, angularCorrectionVector);
}
else
{
VDetailLog("{0}, MoveLinear,limitMotorUp,newVel={1},pntDir={2}",
Prim.LocalID, VehicleVelocity, pointingDirection);
}
*/
VDetailLog("{0}, MoveLinear,limitMotorUp,collide={1},upVel={2},newVel={3}",
Prim.LocalID, Prim.IsColliding, upVelocity, VehicleVelocity);
}
}
}

View File

@ -108,8 +108,8 @@ public sealed class BSLinksetCompound : BSLinkset
// Schedule a refresh to happen after all the other taint processing.
private void ScheduleRebuild(BSPhysObject requestor)
{
DetailLog("{0},BSLinksetCompound.ScheduleRebuild,,rebuilding={1},hasChildren={2}",
requestor.LocalID, Rebuilding, HasAnyChildren);
DetailLog("{0},BSLinksetCompound.ScheduleRebuild,,rebuilding={1},hasChildren={2},actuallyScheduling={3}",
requestor.LocalID, Rebuilding, HasAnyChildren, (!Rebuilding && HasAnyChildren));
// When rebuilding, it is possible to set properties that would normally require a rebuild.
// If already rebuilding, don't request another rebuild.
// If a linkset with just a root prim (simple non-linked prim) don't bother rebuilding.
@ -311,7 +311,7 @@ public sealed class BSLinksetCompound : BSLinkset
else
{
// Rebuild the compound shape with the child removed
ScheduleRebuild(child);
ScheduleRebuild(LinksetRoot);
}
}
return;

View File

@ -94,16 +94,16 @@ public static class BSParam
public static float PID_D { get; private set; } // derivative
public static float PID_P { get; private set; } // proportional
// Various constants that come from that other virtual world that shall not be named
// Various constants that come from that other virtual world that shall not be named.
public const float MinGravityZ = -1f;
public const float MaxGravityZ = 28f;
public const float MinFriction = 0f;
public const float MaxFriction = 255f;
public const float MinDensity = 0f;
public const float MinDensity = 0.01f;
public const float MaxDensity = 22587f;
public const float MinRestitution = 0f;
public const float MaxRestitution = 1f;
public const float MaxAddForceMagnitude = 20000f;
public const float MaxAddForceMagnitude = 20f;
// ===========================================================================
public delegate void ParamUser(BSScene scene, IConfig conf, string paramName, float val);

View File

@ -442,7 +442,8 @@ public sealed class BSShapeCollection : IDisposable
return ret;
}
// Create a mesh/hull shape or a native shape if 'nativeShapePossible' is 'true'.
// Create a mesh, hull or native shape.
// Return 'true' if the prim's shape was changed.
public bool CreateGeomNonSpecial(bool forceRebuild, BSPhysObject prim, ShapeDestructionCallback shapeCallback)
{
bool ret = false;
@ -472,7 +473,7 @@ public sealed class BSShapeCollection : IDisposable
if (DDetail) DetailLog("{0},BSShapeCollection.CreateGeom,maybeNative,force={1},primScale={2},primSize={3},primShape={4}",
prim.LocalID, forceRebuild, prim.Scale, prim.Size, prim.PhysShape.type);
// It doesn't look like Bullet scales spheres so make sure the scales are all equal
// It doesn't look like Bullet scales native spheres so make sure the scales are all equal
if ((pbs.ProfileShape == ProfileShape.HalfCircle && pbs.PathCurve == (byte)Extrusion.Curve1)
&& pbs.Scale.X == pbs.Scale.Y && pbs.Scale.Y == pbs.Scale.Z)
{
@ -484,9 +485,9 @@ public sealed class BSShapeCollection : IDisposable
{
ret = GetReferenceToNativeShape(prim, BSPhysicsShapeType.SHAPE_SPHERE,
FixedShapeKey.KEY_SPHERE, shapeCallback);
if (DDetail) DetailLog("{0},BSShapeCollection.CreateGeom,sphere,force={1},shape={2}",
prim.LocalID, forceRebuild, prim.PhysShape);
}
if (DDetail) DetailLog("{0},BSShapeCollection.CreateGeom,sphere,force={1},rebuilt={2},shape={3}",
prim.LocalID, forceRebuild, ret, prim.PhysShape);
}
if (!haveShape && pbs.ProfileShape == ProfileShape.Square && pbs.PathCurve == (byte)Extrusion.Straight)
{
@ -498,9 +499,9 @@ public sealed class BSShapeCollection : IDisposable
{
ret = GetReferenceToNativeShape( prim, BSPhysicsShapeType.SHAPE_BOX,
FixedShapeKey.KEY_BOX, shapeCallback);
if (DDetail) DetailLog("{0},BSShapeCollection.CreateGeom,box,force={1},shape={2}",
prim.LocalID, forceRebuild, prim.PhysShape);
}
if (DDetail) DetailLog("{0},BSShapeCollection.CreateGeom,box,force={1},rebuilt={2},shape={3}",
prim.LocalID, forceRebuild, ret, prim.PhysShape);
}
}
@ -513,6 +514,7 @@ public sealed class BSShapeCollection : IDisposable
return ret;
}
// return 'true' if the prim's shape was changed.
public bool CreateGeomMeshOrHull(BSPhysObject prim, ShapeDestructionCallback shapeCallback)
{
@ -872,8 +874,7 @@ public sealed class BSShapeCollection : IDisposable
{
prim.LastAssetBuildFailed = true;
BSPhysObject xprim = prim;
DetailLog("{0},BSShapeCollection.VerifyMeshCreated,fetchAsset,lID={1},lastFailed={2}",
LogHeader, prim.LocalID, prim.LastAssetBuildFailed);
DetailLog("{0},BSShapeCollection.VerifyMeshCreated,fetchAsset,lastFailed={1}", prim.LocalID, prim.LastAssetBuildFailed);
Util.FireAndForget(delegate
{
RequestAssetDelegate assetProvider = PhysicsScene.RequestAssetMethod;
@ -882,19 +883,34 @@ public sealed class BSShapeCollection : IDisposable
BSPhysObject yprim = xprim; // probably not necessary, but, just in case.
assetProvider(yprim.BaseShape.SculptTexture, delegate(AssetBase asset)
{
if (!yprim.BaseShape.SculptEntry)
return;
if (yprim.BaseShape.SculptTexture.ToString() != asset.ID)
return;
yprim.BaseShape.SculptData = asset.Data;
// This will cause the prim to see that the filler shape is not the right
// one and try again to build the object.
// No race condition with the normal shape setting since the rebuild is at taint time.
yprim.ForceBodyShapeRebuild(false);
bool assetFound = false; // DEBUG DEBUG
string mismatchIDs = String.Empty; // DEBUG DEBUG
if (yprim.BaseShape.SculptEntry)
{
if (yprim.BaseShape.SculptTexture.ToString() == asset.ID)
{
yprim.BaseShape.SculptData = asset.Data;
// This will cause the prim to see that the filler shape is not the right
// one and try again to build the object.
// No race condition with the normal shape setting since the rebuild is at taint time.
yprim.ForceBodyShapeRebuild(false /* inTaintTime */);
assetFound = true;
}
else
{
mismatchIDs = yprim.BaseShape.SculptTexture.ToString() + "/" + asset.ID;
}
}
DetailLog("{0},BSShapeCollection,fetchAssetCallback,found={1},isSculpt={2},ids={3}",
yprim.LocalID, assetFound, yprim.BaseShape.SculptEntry, mismatchIDs );
});
}
else
{
PhysicsScene.Logger.ErrorFormat("{0} Physical object requires asset but no asset provider. Name={1}",
LogHeader, PhysicsScene.Name);
}
});
}
else
@ -906,9 +922,9 @@ public sealed class BSShapeCollection : IDisposable
}
}
// While we figure out the real problem, stick in a simple box for the object.
BulletShape fillinShape =
BuildPhysicalNativeShape(prim, BSPhysicsShapeType.SHAPE_BOX, FixedShapeKey.KEY_BOX);
// While we wait for the mesh defining asset to be loaded, stick in a simple box for the object.
BulletShape fillinShape = BuildPhysicalNativeShape(prim, BSPhysicsShapeType.SHAPE_BOX, FixedShapeKey.KEY_BOX);
DetailLog("{0},BSShapeCollection.VerifyMeshCreated,boxTempShape", prim.LocalID);
return fillinShape;
}

View File

@ -1,7 +1,14 @@
CURRENT PRIORITIES
=================================================
Mantis 6040 script http://opensimulator.org/mantis/view.php?id=6040
Msg Kayaker on OSGrid when working
Teravus llMoveToTarget script debug
Mixing of hover, buoyancy/gravity, moveToTarget, into one force
Boats floating at proper level
Nebadon vehicles turning funny in arena
limitMotorUp calibration (more down?)
llRotLookAt
llLookAt
Vehicle angular vertical attraction
Vehicle angular deflection
Preferred orientation angular correction fix
@ -9,8 +16,6 @@ vehicle angular banking
Avatars walking up stairs (HALF DONE)
Radius of the capsule affects ability to climb edges.
Vehicle movement on terrain smoothness
Surfboard go wonky when turning
Angular motor direction is global coordinates rather than local coordinates?
Boats float low in the water (DONE)
Avatar movement
flying into a wall doesn't stop avatar who keeps appearing to move through the obstacle (DONE)
@ -27,6 +32,10 @@ Add material densities to the material types
CRASHES
=================================================
Crazyness during 20130115 office hours was PositionAdjustUnderground for both char and prim
m1:logs/20130115.0934/physics-BulletSim-20130115083613.log
Creation of Neb's terrain made the terrain "disappear". Everything started to fall
and then get restored to be above terrain.
20121129.1411: editting/moving phys object across region boundries causes crash
getPos-> btRigidBody::upcast -> getBodyType -> BOOM
20121128.1600: mesh object not rezzing (no physics mesh).
@ -111,6 +120,8 @@ Physical and phantom will drop through the terrain
LINKSETS
======================================================
Editing a child of a linkset causes the child to go phantom
Move a child prim once when it is physical and can never move it again without it going phantom
Offset the center of the linkset to be the geometric center of all the prims
Not quite the same as the center-of-gravity
Linksets should allow collisions to individual children
@ -133,6 +144,10 @@ Eliminate collisions between objects in a linkset. (LinksetConstraint)
MORE
======================================================
Create tests for different interface components
Have test objects/scripts measure themselves and turn color if correct/bad
Test functions in SL and calibrate correctness there
Create auto rezzer and tracker to run through the tests
Use the HACD convex hull routine in Bullet rather than the C# version.
Do we need to do convex hulls all the time? Can complex meshes be left meshes?
There is some problem with meshes and collisions
@ -167,6 +182,7 @@ Enforce physical parameter min/max:
Restitution [0, 1]
http://wiki.secondlife.com/wiki/Physics_Material_Settings_test
Avatar attachments have no mass? http://forums-archive.secondlife.com/54/f0/31796/1.html
Keep avatar scaling correct. http://pennycow.blogspot.fr/2011/07/matter-of-scale.html
INTERNAL IMPROVEMENT/CLEANUP
=================================================
@ -287,4 +303,7 @@ Disable activity of passive linkset children. (DONE)
Since the linkset is a compound object, the old prims are left lying
around and need to be phantomized so they don't collide, ...
Remove HeightmapInfo from terrain specification (DONE)
Since C++ code does not need terrain height, this structure et al are not needed.
Since C++ code does not need terrain height, this structure et al are not needed.
Surfboard go wonky when turning (DONE)
Angular motor direction is global coordinates rather than local coordinates?
(Resolution: made angular motor direction correct coordinate system)

View File

@ -0,0 +1,157 @@
/*
* 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 OpenSimulator 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.Threading;
using Nini.Config;
using NUnit.Framework;
using OpenMetaverse;
using OpenSim.Framework;
using OpenSim.Region.CoreModules.Scripting.WorldComm;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.ScriptEngine.XEngine;
using OpenSim.Tests.Common;
using OpenSim.Tests.Common.Mock;
namespace OpenSim.Region.ScriptEngine.Shared.Instance.Tests
{
/// <summary>
/// Test that co-operative script thread termination is working correctly.
/// </summary>
[TestFixture]
public class CoopTerminationTests : OpenSimTestCase
{
private TestScene m_scene;
private OpenSim.Region.ScriptEngine.XEngine.XEngine m_xEngine;
private AutoResetEvent m_chatEvent = new AutoResetEvent(false);
private AutoResetEvent m_stoppedEvent = new AutoResetEvent(false);
private OSChatMessage m_osChatMessageReceived;
[TestFixtureSetUp]
public void Init()
{
//AppDomain.CurrentDomain.SetData("APPBASE", Environment.CurrentDirectory + "/bin");
// Console.WriteLine(AppDomain.CurrentDomain.BaseDirectory);
m_xEngine = new OpenSim.Region.ScriptEngine.XEngine.XEngine();
IniConfigSource configSource = new IniConfigSource();
IConfig startupConfig = configSource.AddConfig("Startup");
startupConfig.Set("DefaultScriptEngine", "XEngine");
IConfig xEngineConfig = configSource.AddConfig("XEngine");
xEngineConfig.Set("Enabled", "true");
xEngineConfig.Set("StartDelay", "0");
// These tests will not run with AppDomainLoading = true, at least on mono. For unknown reasons, the call
// to AssemblyResolver.OnAssemblyResolve fails.
xEngineConfig.Set("AppDomainLoading", "false");
xEngineConfig.Set("ScriptStopStrategy", "co-op");
m_scene = new SceneHelpers().SetupScene("My Test", UUID.Random(), 1000, 1000, configSource);
SceneHelpers.SetupSceneModules(m_scene, configSource, m_xEngine);
m_scene.StartScripts();
}
/// <summary>
/// Test co-operative termination on derez of an object containing a script with a long-running event.
/// </summary>
/// <remarks>
/// TODO: Actually compiling the script is incidental to this test. Really want a way to compile test scripts
/// within the build itself.
/// </remarks>
[Test]
public void TestStopOnLongSleep()
{
TestHelpers.InMethod();
// TestHelpers.EnableLogging();
UUID userId = TestHelpers.ParseTail(0x1);
// UUID objectId = TestHelpers.ParseTail(0x100);
// UUID itemId = TestHelpers.ParseTail(0x3);
string itemName = "TestStopOnObjectDerezLongSleep() Item";
SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, userId, "TestStopOnObjectDerezLongSleep", 0x100);
m_scene.AddNewSceneObject(so, true);
InventoryItemBase itemTemplate = new InventoryItemBase();
// itemTemplate.ID = itemId;
itemTemplate.Name = itemName;
itemTemplate.Folder = so.UUID;
itemTemplate.InvType = (int)InventoryType.LSL;
m_scene.EventManager.OnChatFromWorld += OnChatFromWorld;
SceneObjectPart partWhereRezzed = m_scene.RezNewScript(userId, itemTemplate,
@"default
{
state_entry()
{
llSay(0, ""Thin Lizzy"");
llSleep(60);
}
}");
TaskInventoryItem rezzedItem = partWhereRezzed.Inventory.GetInventoryItem(itemName);
// Wait for the script to start the event before we try stopping it.
m_chatEvent.WaitOne(60000);
Console.WriteLine("Script started with message [{0}]", m_osChatMessageReceived.Message);
// FIXME: This is a very poor way of trying to avoid a low-probability race condition where the script
// executes llSay() but has not started the sleep before we try to stop it.
Thread.Sleep(1000);
// We need a way of carrying on if StopScript() fail, since it won't return if the script isn't actually
// stopped. This kind of multi-threading is far from ideal in a regression test.
new Thread(() => { m_xEngine.StopScript(rezzedItem.ItemID); m_stoppedEvent.Set(); }).Start();
if (!m_stoppedEvent.WaitOne(30000))
Assert.Fail("Script did not co-operatively stop.");
bool running;
TaskInventoryItem scriptItem = partWhereRezzed.Inventory.GetInventoryItem(itemName);
Assert.That(
SceneObjectPartInventory.TryGetScriptInstanceRunning(m_scene, scriptItem, out running), Is.True);
Assert.That(running, Is.False);
}
private void OnChatFromWorld(object sender, OSChatMessage oscm)
{
// Console.WriteLine("Got chat [{0}]", oscm.Message);
m_osChatMessageReceived = oscm;
m_chatEvent.Set();
}
}
}