aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim')
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs19
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs66
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs5
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs19
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs8
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSParam.cs7
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs60
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSScene.cs4
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt2
-rw-r--r--OpenSim/Region/ScriptEngine/Interfaces/IScriptApi.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Interfaces/IScriptEngine.cs43
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs16
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs133
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs74
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs98
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs250
-rw-r--r--OpenSim/Region/ScriptEngine/XEngine/Api/Runtime/XEngineScriptBase.cs61
-rw-r--r--OpenSim/Region/ScriptEngine/XEngine/EventManager.cs4
-rw-r--r--OpenSim/Region/ScriptEngine/XEngine/Tests/XEngineBasicTests.cs (renamed from OpenSim/Region/ScriptEngine/XEngine/Tests/XEngineTest.cs)0
-rw-r--r--OpenSim/Region/ScriptEngine/XEngine/XEngine.cs54
24 files changed, 688 insertions, 245 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs b/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs
index bc163eb..2828cab 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs
@@ -140,6 +140,25 @@ public struct EntityProperties
140 public Vector3 Velocity; 140 public Vector3 Velocity;
141 public Vector3 Acceleration; 141 public Vector3 Acceleration;
142 public Vector3 RotationalVelocity; 142 public Vector3 RotationalVelocity;
143
144 public override string ToString()
145 {
146 StringBuilder buff = new StringBuilder();
147 buff.Append("<i=");
148 buff.Append(ID.ToString());
149 buff.Append(",p=");
150 buff.Append(Position.ToString());
151 buff.Append(",r=");
152 buff.Append(Rotation.ToString());
153 buff.Append(",v=");
154 buff.Append(Velocity.ToString());
155 buff.Append(",a=");
156 buff.Append(Acceleration.ToString());
157 buff.Append(",rv=");
158 buff.Append(RotationalVelocity.ToString());
159 buff.Append(">");
160 return buff.ToString();
161 }
143} 162}
144 163
145// Format of this structure must match the definition in the C++ code 164// Format of this structure must match the definition in the C++ code
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
index dbe44de..fe7891e 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
@@ -690,7 +690,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
690 // Bullet does a bunch of smoothing for changing parameters. 690 // Bullet does a bunch of smoothing for changing parameters.
691 // Since the vehicle is demanding this setting, we override Bullet's smoothing 691 // Since the vehicle is demanding this setting, we override Bullet's smoothing
692 // by telling Bullet the value was the same last time. 692 // by telling Bullet the value was the same last time.
693 PhysicsScene.PE.SetInterpolationLinearVelocity(Prim.PhysBody, m_knownVelocity); 693 // PhysicsScene.PE.SetInterpolationLinearVelocity(Prim.PhysBody, m_knownVelocity);
694 } 694 }
695 695
696 if ((m_knownChanged & m_knownChangedForce) != 0) 696 if ((m_knownChanged & m_knownChangedForce) != 0)
@@ -702,7 +702,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
702 if ((m_knownChanged & m_knownChangedRotationalVelocity) != 0) 702 if ((m_knownChanged & m_knownChangedRotationalVelocity) != 0)
703 { 703 {
704 Prim.ForceRotationalVelocity = m_knownRotationalVelocity; 704 Prim.ForceRotationalVelocity = m_knownRotationalVelocity;
705 PhysicsScene.PE.SetInterpolationAngularVelocity(Prim.PhysBody, m_knownRotationalVelocity); 705 // PhysicsScene.PE.SetInterpolationAngularVelocity(Prim.PhysBody, m_knownRotationalVelocity);
706 } 706 }
707 707
708 if ((m_knownChanged & m_knownChangedRotationalImpulse) != 0) 708 if ((m_knownChanged & m_knownChangedRotationalImpulse) != 0)
@@ -963,23 +963,23 @@ namespace OpenSim.Region.Physics.BulletSPlugin
963 { 963 {
964 // Step the motor from the current value. Get the correction needed this step. 964 // Step the motor from the current value. Get the correction needed this step.
965 Vector3 currentVel = VehicleVelocity * Quaternion.Inverse(VehicleOrientation); 965 Vector3 currentVel = VehicleVelocity * Quaternion.Inverse(VehicleOrientation);
966 Vector3 linearMotorCorrection = m_linearMotor.Step(pTimestep, currentVel); 966 Vector3 linearMotorCorrectionV = m_linearMotor.Step(pTimestep, currentVel);
967 967
968 // Motor is vehicle coordinates. Rotate it to world coordinates 968 // Motor is vehicle coordinates. Rotate it to world coordinates
969 Vector3 linearMotorVelocity = linearMotorCorrection * VehicleOrientation; 969 Vector3 linearMotorVelocityW = linearMotorCorrectionV * VehicleOrientation;
970 970
971 // If we're a ground vehicle, don't add any upward Z movement 971 // If we're a ground vehicle, don't add any upward Z movement
972 if ((m_flags & VehicleFlag.LIMIT_MOTOR_UP) != 0) 972 if ((m_flags & VehicleFlag.LIMIT_MOTOR_UP) != 0)
973 { 973 {
974 if (linearMotorVelocity.Z > 0f) 974 if (linearMotorVelocityW.Z > 0f)
975 linearMotorVelocity.Z = 0f; 975 linearMotorVelocityW.Z = 0f;
976 } 976 }
977 977
978 // Add this correction to the velocity to make it faster/slower. 978 // Add this correction to the velocity to make it faster/slower.
979 VehicleVelocity += linearMotorVelocity; 979 VehicleVelocity += linearMotorVelocityW;
980 980
981 VDetailLog("{0}, MoveLinear,velocity,vehVel={1},correction={2},force={3}", 981 VDetailLog("{0}, MoveLinear,velocity,vehVel={1},correction={2},force={3}",
982 Prim.LocalID, VehicleVelocity, linearMotorCorrection, linearMotorVelocity); 982 Prim.LocalID, VehicleVelocity, linearMotorCorrectionV, linearMotorVelocityW);
983 } 983 }
984 984
985 public void ComputeLinearTerrainHeightCorrection(float pTimestep) 985 public void ComputeLinearTerrainHeightCorrection(float pTimestep)
@@ -1123,8 +1123,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1123 // a downward raycast to find what is below. 1123 // a downward raycast to find what is below.
1124 public void ComputeLinearMotorUp(float pTimestep) 1124 public void ComputeLinearMotorUp(float pTimestep)
1125 { 1125 {
1126 Vector3 ret = Vector3.Zero;
1127
1128 if ((m_flags & (VehicleFlag.LIMIT_MOTOR_UP)) != 0) 1126 if ((m_flags & (VehicleFlag.LIMIT_MOTOR_UP)) != 0)
1129 { 1127 {
1130 // This code tries to decide if the object is not on the ground and then pushing down 1128 // This code tries to decide if the object is not on the ground and then pushing down
@@ -1250,8 +1248,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1250 private void ComputeAngularTurning(float pTimestep) 1248 private void ComputeAngularTurning(float pTimestep)
1251 { 1249 {
1252 // The user wants this many radians per second angular change? 1250 // The user wants this many radians per second angular change?
1253 Vector3 currentAngular = VehicleRotationalVelocity * Quaternion.Inverse(VehicleOrientation); 1251 Vector3 currentAngularV = VehicleRotationalVelocity * Quaternion.Inverse(VehicleOrientation);
1254 Vector3 angularMotorContribution = m_angularMotor.Step(pTimestep, currentAngular); 1252 Vector3 angularMotorContributionV = m_angularMotor.Step(pTimestep, currentAngularV);
1255 1253
1256 // ================================================================== 1254 // ==================================================================
1257 // From http://wiki.secondlife.com/wiki/LlSetVehicleFlags : 1255 // From http://wiki.secondlife.com/wiki/LlSetVehicleFlags :
@@ -1263,12 +1261,12 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1263 // is a linear effect. Where should this check go? 1261 // is a linear effect. Where should this check go?
1264 if ((m_flags & (VehicleFlag.NO_DEFLECTION_UP)) != 0) 1262 if ((m_flags & (VehicleFlag.NO_DEFLECTION_UP)) != 0)
1265 { 1263 {
1266 angularMotorContribution.X = 0f; 1264 angularMotorContributionV.X = 0f;
1267 angularMotorContribution.Y = 0f; 1265 angularMotorContributionV.Y = 0f;
1268 } 1266 }
1269 1267
1270 VehicleRotationalVelocity += angularMotorContribution * VehicleOrientation; 1268 VehicleRotationalVelocity += angularMotorContributionV * VehicleOrientation;
1271 VDetailLog("{0}, MoveAngular,angularTurning,angularMotorContrib={1}", Prim.LocalID, angularMotorContribution); 1269 VDetailLog("{0}, MoveAngular,angularTurning,angularMotorContrib={1}", Prim.LocalID, angularMotorContributionV);
1272 } 1270 }
1273 1271
1274 // From http://wiki.secondlife.com/wiki/Linden_Vehicle_Tutorial: 1272 // From http://wiki.secondlife.com/wiki/Linden_Vehicle_Tutorial:
@@ -1284,7 +1282,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1284 // If vertical attaction timescale is reasonable 1282 // If vertical attaction timescale is reasonable
1285 if (enableAngularVerticalAttraction && m_verticalAttractionTimescale < m_verticalAttractionCutoff) 1283 if (enableAngularVerticalAttraction && m_verticalAttractionTimescale < m_verticalAttractionCutoff)
1286 { 1284 {
1287 Vector3 vertContribution = Vector3.Zero; 1285 Vector3 vertContributionV = Vector3.Zero;
1288 1286
1289 // Take a vector pointing up and convert it from world to vehicle relative coords. 1287 // Take a vector pointing up and convert it from world to vehicle relative coords.
1290 Vector3 verticalError = Vector3.UnitZ * VehicleOrientation; 1288 Vector3 verticalError = Vector3.UnitZ * VehicleOrientation;
@@ -1299,26 +1297,26 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1299 1297
1300 // Y error means needed rotation around X axis and visa versa. 1298 // Y error means needed rotation around X axis and visa versa.
1301 // Since the error goes from zero to one, the asin is the corresponding angle. 1299 // Since the error goes from zero to one, the asin is the corresponding angle.
1302 vertContribution.X = (float)Math.Asin(verticalError.Y); 1300 vertContributionV.X = (float)Math.Asin(verticalError.Y);
1303 // (Tilt forward (positive X) needs to tilt back (rotate negative) around Y axis.) 1301 // (Tilt forward (positive X) needs to tilt back (rotate negative) around Y axis.)
1304 vertContribution.Y = -(float)Math.Asin(verticalError.X); 1302 vertContributionV.Y = -(float)Math.Asin(verticalError.X);
1305 1303
1306 // If verticalError.Z is negative, the vehicle is upside down. Add additional push. 1304 // If verticalError.Z is negative, the vehicle is upside down. Add additional push.
1307 if (verticalError.Z < 0f) 1305 if (verticalError.Z < 0f)
1308 { 1306 {
1309 vertContribution.X += PIOverFour; 1307 vertContributionV.X += PIOverFour;
1310 // vertContribution.Y -= PIOverFour; 1308 // vertContribution.Y -= PIOverFour;
1311 } 1309 }
1312 1310
1313 // 'vertContrbution' is now the necessary angular correction to correct tilt in one second. 1311 // 'vertContrbution' is now the necessary angular correction to correct tilt in one second.
1314 // Correction happens over a number of seconds. 1312 // Correction happens over a number of seconds.
1315 Vector3 unscaledContrib = vertContribution; // DEBUG DEBUG 1313 Vector3 unscaledContrib = vertContributionV; // DEBUG DEBUG
1316 vertContribution /= m_verticalAttractionTimescale; 1314 vertContributionV /= m_verticalAttractionTimescale;
1317 1315
1318 VehicleRotationalVelocity += vertContribution * VehicleOrientation; 1316 VehicleRotationalVelocity += vertContributionV * VehicleOrientation;
1319 1317
1320 VDetailLog("{0}, MoveAngular,verticalAttraction,,verticalError={1},unscaled={2},eff={3},ts={4},vertAttr={5}", 1318 VDetailLog("{0}, MoveAngular,verticalAttraction,,verticalError={1},unscaled={2},eff={3},ts={4},vertAttr={5}",
1321 Prim.LocalID, verticalError, unscaledContrib, m_verticalAttractionEfficiency, m_verticalAttractionTimescale, vertContribution); 1319 Prim.LocalID, verticalError, unscaledContrib, m_verticalAttractionEfficiency, m_verticalAttractionTimescale, vertContributionV);
1322 } 1320 }
1323 } 1321 }
1324 1322
@@ -1336,7 +1334,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1336 1334
1337 if (enableAngularDeflection && m_angularDeflectionEfficiency != 0 && VehicleForwardSpeed > 0.2) 1335 if (enableAngularDeflection && m_angularDeflectionEfficiency != 0 && VehicleForwardSpeed > 0.2)
1338 { 1336 {
1339 Vector3 deflectContribution = Vector3.Zero; 1337 Vector3 deflectContributionV = Vector3.Zero;
1340 1338
1341 // The direction the vehicle is moving 1339 // The direction the vehicle is moving
1342 Vector3 movingDirection = VehicleVelocity; 1340 Vector3 movingDirection = VehicleVelocity;
@@ -1363,13 +1361,13 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1363 // ret = m_angularDeflectionCorrectionMotor(1f, deflectionError); 1361 // ret = m_angularDeflectionCorrectionMotor(1f, deflectionError);
1364 1362
1365 // Scale the correction by recovery timescale and efficiency 1363 // Scale the correction by recovery timescale and efficiency
1366 deflectContribution = (-deflectionError) * m_angularDeflectionEfficiency; 1364 deflectContributionV = (-deflectionError) * m_angularDeflectionEfficiency;
1367 deflectContribution /= m_angularDeflectionTimescale; 1365 deflectContributionV /= m_angularDeflectionTimescale;
1368 1366
1369 VehicleRotationalVelocity += deflectContribution * VehicleOrientation; 1367 VehicleRotationalVelocity += deflectContributionV * VehicleOrientation;
1370 1368
1371 VDetailLog("{0}, MoveAngular,Deflection,movingDir={1},pointingDir={2},deflectError={3},ret={4}", 1369 VDetailLog("{0}, MoveAngular,Deflection,movingDir={1},pointingDir={2},deflectError={3},ret={4}",
1372 Prim.LocalID, movingDirection, pointingDirection, deflectionError, deflectContribution); 1370 Prim.LocalID, movingDirection, pointingDirection, deflectionError, deflectContributionV);
1373 VDetailLog("{0}, MoveAngular,Deflection,fwdSpd={1},defEff={2},defTS={3}", 1371 VDetailLog("{0}, MoveAngular,Deflection,fwdSpd={1},defEff={2},defTS={3}",
1374 Prim.LocalID, VehicleForwardSpeed, m_angularDeflectionEfficiency, m_angularDeflectionTimescale); 1372 Prim.LocalID, VehicleForwardSpeed, m_angularDeflectionEfficiency, m_angularDeflectionTimescale);
1375 } 1373 }
@@ -1410,7 +1408,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1410 { 1408 {
1411 if (enableAngularBanking && m_bankingEfficiency != 0 && m_verticalAttractionTimescale < m_verticalAttractionCutoff) 1409 if (enableAngularBanking && m_bankingEfficiency != 0 && m_verticalAttractionTimescale < m_verticalAttractionCutoff)
1412 { 1410 {
1413 Vector3 bankingContribution = Vector3.Zero; 1411 Vector3 bankingContributionV = Vector3.Zero;
1414 1412
1415 // Rotate a UnitZ vector (pointing up) to how the vehicle is oriented. 1413 // Rotate a UnitZ vector (pointing up) to how the vehicle is oriented.
1416 // As the vehicle rolls to the right or left, the Y value will increase from 1414 // As the vehicle rolls to the right or left, the Y value will increase from
@@ -1428,15 +1426,15 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1428 mixedYawAngle = ClampInRange(-20f, mixedYawAngle, 20f); 1426 mixedYawAngle = ClampInRange(-20f, mixedYawAngle, 20f);
1429 1427
1430 // Build the force vector to change rotation from what it is to what it should be 1428 // Build the force vector to change rotation from what it is to what it should be
1431 bankingContribution.Z = -mixedYawAngle; 1429 bankingContributionV.Z = -mixedYawAngle;
1432 1430
1433 // Don't do it all at once. 1431 // Don't do it all at once.
1434 bankingContribution /= m_bankingTimescale; 1432 bankingContributionV /= m_bankingTimescale;
1435 1433
1436 VehicleRotationalVelocity += bankingContribution * VehicleOrientation; 1434 VehicleRotationalVelocity += bankingContributionV * VehicleOrientation;
1437 1435
1438 VDetailLog("{0}, MoveAngular,Banking,rollComp={1},speed={2},rollComp={3},yAng={4},mYAng={5},ret={6}", 1436 VDetailLog("{0}, MoveAngular,Banking,rollComp={1},speed={2},rollComp={3},yAng={4},mYAng={5},ret={6}",
1439 Prim.LocalID, rollComponents, VehicleForwardSpeed, rollComponents, yawAngle, mixedYawAngle, bankingContribution); 1437 Prim.LocalID, rollComponents, VehicleForwardSpeed, rollComponents, yawAngle, mixedYawAngle, bankingContributionV);
1440 } 1438 }
1441 } 1439 }
1442 1440
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs
index 580ea4e..1e3e5d8 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs
@@ -261,11 +261,6 @@ public abstract class BSLinkset
261 // Called at taint-time!! 261 // Called at taint-time!!
262 public abstract bool RemoveBodyDependencies(BSPrim child); 262 public abstract bool RemoveBodyDependencies(BSPrim child);
263 263
264 // Companion to RemoveBodyDependencies(). If RemoveBodyDependencies() returns 'true',
265 // this routine will restore the removed constraints.
266 // Called at taint-time!!
267 public abstract void RestoreBodyDependencies(BSPrim child);
268
269 // ================================================================ 264 // ================================================================
270 protected virtual float ComputeLinksetMass() 265 protected virtual float ComputeLinksetMass()
271 { 266 {
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs
index 27d8ad0..2c8dd23 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs
@@ -290,13 +290,6 @@ public sealed class BSLinksetCompound : BSLinkset
290 return ret; 290 return ret;
291 } 291 }
292 292
293 // Companion to RemoveBodyDependencies(). If RemoveBodyDependencies() returns 'true',
294 // this routine will restore the removed constraints.
295 // Called at taint-time!!
296 public override void RestoreBodyDependencies(BSPrim child)
297 {
298 }
299
300 // When the linkset is built, the child shape is added to the compound shape relative to the 293 // When the linkset is built, the child shape is added to the compound shape relative to the
301 // root shape. The linkset then moves around but this does not move the actual child 294 // root shape. The linkset then moves around but this does not move the actual child
302 // prim. The child prim's location must be recomputed based on the location of the root shape. 295 // prim. The child prim's location must be recomputed based on the location of the root shape.
@@ -384,7 +377,7 @@ public sealed class BSLinksetCompound : BSLinkset
384 // Constraint linksets are rebuilt every time. 377 // Constraint linksets are rebuilt every time.
385 // Note that this works for rebuilding just the root after a linkset is taken apart. 378 // Note that this works for rebuilding just the root after a linkset is taken apart.
386 // Called at taint time!! 379 // Called at taint time!!
387 private bool disableCOM = true; // disable until we get this debugged 380 private bool disableCOM = false; // disable until we get this debugged
388 private void RecomputeLinksetCompound() 381 private void RecomputeLinksetCompound()
389 { 382 {
390 try 383 try
@@ -407,12 +400,16 @@ public sealed class BSLinksetCompound : BSLinkset
407 } // DEBUG DEBUG 400 } // DEBUG DEBUG
408 else 401 else
409 { 402 {
410 centerOfMass = ComputeLinksetGeometricCenter(); 403 centerOfMass = ComputeLinksetCenterOfMass();
411 centerDisplacement = centerOfMass - LinksetRoot.RawPosition; 404 // 'centerDisplacement' is the value to *add* to all the shape offsets
405 centerDisplacement = LinksetRoot.RawPosition - centerOfMass;
412 406
413 // Since we're displacing the center of the shape, we need to move the body in the world 407 // Since we're displacing the center of the shape, we need to move the body in the world
414 LinksetRoot.PositionDisplacement = centerDisplacement; 408 LinksetRoot.PositionDisplacement = centerDisplacement;
415 409
410 // This causes the root prim position to be set properly based on the new PositionDisplacement
411 LinksetRoot.ForcePosition = LinksetRoot.RawPosition;
412 // Update the local transform for the root child shape so it is offset from the <0,0,0> which is COM
416 PhysicsScene.PE.UpdateChildTransform(LinksetRoot.PhysShape, 0, -centerDisplacement, OMV.Quaternion.Identity, false); 413 PhysicsScene.PE.UpdateChildTransform(LinksetRoot.PhysShape, 0, -centerDisplacement, OMV.Quaternion.Identity, false);
417 DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,COM,com={1},rootPos={2},centerDisp={3}", 414 DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,COM,com={1},rootPos={2},centerDisp={3}",
418 LinksetRoot.LocalID, centerOfMass, LinksetRoot.RawPosition, centerDisplacement); 415 LinksetRoot.LocalID, centerOfMass, LinksetRoot.RawPosition, centerDisplacement);
@@ -444,7 +441,7 @@ public sealed class BSLinksetCompound : BSLinkset
444 441
445 if (cPrim.PhysShape.isNativeShape) 442 if (cPrim.PhysShape.isNativeShape)
446 { 443 {
447 // A native shape is turning into a hull collision shape because native 444 // A native shape is turned into a hull collision shape because native
448 // shapes are not shared so we have to hullify it so it will be tracked 445 // shapes are not shared so we have to hullify it so it will be tracked
449 // and freed at the correct time. This also solves the scaling problem 446 // and freed at the correct time. This also solves the scaling problem
450 // (native shapes scaled but hull/meshes are assumed to not be). 447 // (native shapes scaled but hull/meshes are assumed to not be).
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs
index 89f186c..3011465 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs
@@ -110,14 +110,6 @@ public sealed class BSLinksetConstraints : BSLinkset
110 return ret; 110 return ret;
111 } 111 }
112 112
113 // Companion to RemoveBodyDependencies(). If RemoveBodyDependencies() returns 'true',
114 // this routine will restore the removed constraints.
115 // Called at taint-time!!
116 public override void RestoreBodyDependencies(BSPrim child)
117 {
118 // The Refresh operation queued by RemoveBodyDependencies() will build any missing constraints.
119 }
120
121 // ================================================================ 113 // ================================================================
122 114
123 // Add a new child to the linkset. 115 // Add a new child to the linkset.
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs
index da7438a..9460daf 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs
@@ -645,11 +645,8 @@ public static class BSParam
645 entries.Add(new PhysParameterEntry(pd.name, pd.desc)); 645 entries.Add(new PhysParameterEntry(pd.name, pd.desc));
646 } 646 }
647 647
648 // make the list in alphabetical order for estetic reasons 648 // make the list alphabetical for estetic reasons
649 entries.Sort(delegate(PhysParameterEntry ppe1, PhysParameterEntry ppe2) 649 entries.Sort((ppe1, ppe2) => { return ppe1.name.CompareTo(ppe2.name); });
650 {
651 return ppe1.name.CompareTo(ppe2.name);
652 });
653 650
654 SettableParameters = entries.ToArray(); 651 SettableParameters = entries.ToArray();
655 } 652 }
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
index e6b8507..f80084a 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
@@ -322,6 +322,7 @@ public sealed class BSPrim : BSPhysObject
322 }); 322 });
323 } 323 }
324 } 324 }
325
325 public override OMV.Vector3 ForcePosition { 326 public override OMV.Vector3 ForcePosition {
326 get { 327 get {
327 _position = PhysicsScene.PE.GetPosition(PhysBody) - PositionDisplacement; 328 _position = PhysicsScene.PE.GetPosition(PhysBody) - PositionDisplacement;
@@ -336,25 +337,6 @@ public sealed class BSPrim : BSPhysObject
336 } 337 }
337 } 338 }
338 } 339 }
339 // Override to have position displacement immediately update the physical position.
340 // A feeble attempt to keep the sim and physical positions in sync
341 // Must be called at taint time.
342 public override OMV.Vector3 PositionDisplacement
343 {
344 get
345 {
346 return base.PositionDisplacement;
347 }
348 set
349 {
350 base.PositionDisplacement = value;
351 PhysicsScene.TaintedObject(PhysicsScene.InTaintTime, "BSPrim.setPosition", delegate()
352 {
353 if (PhysBody.HasPhysicalBody)
354 PhysicsScene.PE.SetTranslation(PhysBody, _position + base.PositionDisplacement, _orientation);
355 });
356 }
357 }
358 340
359 // Check that the current position is sane and, if not, modify the position to make it so. 341 // Check that the current position is sane and, if not, modify the position to make it so.
360 // Check for being below terrain and being out of bounds. 342 // Check for being below terrain and being out of bounds.
@@ -371,11 +353,11 @@ public sealed class BSPrim : BSPhysObject
371 return ret; 353 return ret;
372 } 354 }
373 355
374 float terrainHeight = PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(_position); 356 float terrainHeight = PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(RawPosition);
375 OMV.Vector3 upForce = OMV.Vector3.Zero; 357 OMV.Vector3 upForce = OMV.Vector3.Zero;
376 if (RawPosition.Z < terrainHeight) 358 if (RawPosition.Z < terrainHeight)
377 { 359 {
378 DetailLog("{0},BSPrim.PositionAdjustUnderGround,call,pos={1},terrain={2}", LocalID, _position, terrainHeight); 360 DetailLog("{0},BSPrim.PositionAdjustUnderGround,call,pos={1},terrain={2}", LocalID, RawPosition, terrainHeight);
379 float targetHeight = terrainHeight + (Size.Z / 2f); 361 float targetHeight = terrainHeight + (Size.Z / 2f);
380 // If the object is below ground it just has to be moved up because pushing will 362 // If the object is below ground it just has to be moved up because pushing will
381 // not get it through the terrain 363 // not get it through the terrain
@@ -1606,11 +1588,6 @@ public sealed class BSPrim : BSPhysObject
1606 // Called at taint-time!!! 1588 // Called at taint-time!!!
1607 public void CreateGeomAndObject(bool forceRebuild) 1589 public void CreateGeomAndObject(bool forceRebuild)
1608 { 1590 {
1609 // If this prim is part of a linkset, we must remove and restore the physical
1610 // links if the body is rebuilt.
1611 bool needToRestoreLinkset = false;
1612 bool needToRestoreVehicle = false;
1613
1614 // Create the correct physical representation for this type of object. 1591 // Create the correct physical representation for this type of object.
1615 // Updates PhysBody and PhysShape with the new information. 1592 // Updates PhysBody and PhysShape with the new information.
1616 // Ignore 'forceRebuild'. This routine makes the right choices and changes of necessary. 1593 // Ignore 'forceRebuild'. This routine makes the right choices and changes of necessary.
@@ -1619,21 +1596,10 @@ public sealed class BSPrim : BSPhysObject
1619 // Called if the current prim body is about to be destroyed. 1596 // Called if the current prim body is about to be destroyed.
1620 // Remove all the physical dependencies on the old body. 1597 // Remove all the physical dependencies on the old body.
1621 // (Maybe someday make the changing of BSShape an event to be subscribed to by BSLinkset, ...) 1598 // (Maybe someday make the changing of BSShape an event to be subscribed to by BSLinkset, ...)
1622 needToRestoreLinkset = Linkset.RemoveBodyDependencies(this); 1599 Linkset.RemoveBodyDependencies(this);
1623 needToRestoreVehicle = _vehicle.RemoveBodyDependencies(this); 1600 _vehicle.RemoveBodyDependencies(this);
1624 }); 1601 });
1625 1602
1626 if (needToRestoreLinkset)
1627 {
1628 // If physical body dependencies were removed, restore them
1629 Linkset.RestoreBodyDependencies(this);
1630 }
1631 if (needToRestoreVehicle)
1632 {
1633 // If physical body dependencies were removed, restore them
1634 _vehicle.RestoreBodyDependencies(this);
1635 }
1636
1637 // Make sure the properties are set on the new object 1603 // Make sure the properties are set on the new object
1638 UpdatePhysicalParameters(); 1604 UpdatePhysicalParameters();
1639 return; 1605 return;
@@ -1653,14 +1619,25 @@ public sealed class BSPrim : BSPhysObject
1653 // entprop.RotationalVelocity = OMV.Vector3.Zero; 1619 // entprop.RotationalVelocity = OMV.Vector3.Zero;
1654 } 1620 }
1655 1621
1622 // DetailLog("{0},BSPrim.UpdateProperties,entry,entprop={1}", LocalID, entprop); // DEBUG DEBUG
1623
1624 // Undo any center-of-mass displacement that might have been done.
1625 if (PositionDisplacement != OMV.Vector3.Zero)
1626 {
1627 // Correct for any rotation around the center-of-mass
1628 // TODO!!!
1629 entprop.Position -= PositionDisplacement;
1630 }
1631
1656 // Assign directly to the local variables so the normal set actions do not happen 1632 // Assign directly to the local variables so the normal set actions do not happen
1657 entprop.Position -= PositionDisplacement;
1658 _position = entprop.Position; 1633 _position = entprop.Position;
1659 _orientation = entprop.Rotation; 1634 _orientation = entprop.Rotation;
1660 _velocity = entprop.Velocity; 1635 _velocity = entprop.Velocity;
1661 _acceleration = entprop.Acceleration; 1636 _acceleration = entprop.Acceleration;
1662 _rotationalVelocity = entprop.RotationalVelocity; 1637 _rotationalVelocity = entprop.RotationalVelocity;
1663 1638
1639 // DetailLog("{0},BSPrim.UpdateProperties,afterAssign,entprop={1}", LocalID, entprop); // DEBUG DEBUG
1640
1664 // The sanity check can change the velocity and/or position. 1641 // The sanity check can change the velocity and/or position.
1665 if (IsPhysical && PositionSanityCheck(true)) 1642 if (IsPhysical && PositionSanityCheck(true))
1666 { 1643 {
@@ -1669,8 +1646,7 @@ public sealed class BSPrim : BSPhysObject
1669 } 1646 }
1670 1647
1671 OMV.Vector3 direction = OMV.Vector3.UnitX * _orientation; // DEBUG DEBUG DEBUG 1648 OMV.Vector3 direction = OMV.Vector3.UnitX * _orientation; // DEBUG DEBUG DEBUG
1672 DetailLog("{0},BSPrim.UpdateProperties,call,pos={1},orient={2},dir={3},vel={4},rotVel={5}", 1649 DetailLog("{0},BSPrim.UpdateProperties,call,entProp={1},dir={2}", LocalID, entprop, direction);
1673 LocalID, _position, _orientation, direction, _velocity, _rotationalVelocity);
1674 1650
1675 // remember the current and last set values 1651 // remember the current and last set values
1676 LastEntityProperties = CurrentEntityProperties; 1652 LastEntityProperties = CurrentEntityProperties;
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
index 8075b73..34fd2a0 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
@@ -708,8 +708,8 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
708 // TriggerPreStepEvent 708 // TriggerPreStepEvent
709 // DoOneTimeTaints 709 // DoOneTimeTaints
710 // Step() 710 // Step()
711 // ProcessAndForwardCollisions 711 // ProcessAndSendToSimulatorCollisions
712 // ProcessAndForwardPropertyUpdates 712 // ProcessAndSendToSimulatorPropertyUpdates
713 // TriggerPostStepEvent 713 // TriggerPostStepEvent
714 714
715 // Calls to the PhysicsActors can't directly call into the physics engine 715 // Calls to the PhysicsActors can't directly call into the physics engine
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt
index 41bab26..801f690 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt
+++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt
@@ -1,5 +1,7 @@
1CURRENT PRIORITIES 1CURRENT PRIORITIES
2================================================= 2=================================================
3Deleting a linkset while standing on the root will leave the physical shape of the root behind.
4 Not sure if it is because standing on it. Done with large prim linksets.
3Child movement in linkset (don't rebuild linkset) 5Child movement in linkset (don't rebuild linkset)
4Vehicle angular vertical attraction 6Vehicle angular vertical attraction
5vehicle angular banking 7vehicle angular banking
diff --git a/OpenSim/Region/ScriptEngine/Interfaces/IScriptApi.cs b/OpenSim/Region/ScriptEngine/Interfaces/IScriptApi.cs
index d2323f5..30e99b0 100644
--- a/OpenSim/Region/ScriptEngine/Interfaces/IScriptApi.cs
+++ b/OpenSim/Region/ScriptEngine/Interfaces/IScriptApi.cs
@@ -46,6 +46,6 @@ namespace OpenSim.Region.ScriptEngine.Interfaces
46 /// <param name='item'>/param> 46 /// <param name='item'>/param>
47 /// <param name='coopSleepHandle'>/param> 47 /// <param name='coopSleepHandle'>/param>
48 void Initialize( 48 void Initialize(
49 IScriptEngine scriptEngine, SceneObjectPart host, TaskInventoryItem item, EventWaitHandle coopSleepHandle); 49 IScriptEngine scriptEngine, SceneObjectPart host, TaskInventoryItem item, WaitHandle coopSleepHandle);
50 } 50 }
51} \ No newline at end of file 51} \ No newline at end of file
diff --git a/OpenSim/Region/ScriptEngine/Interfaces/IScriptEngine.cs b/OpenSim/Region/ScriptEngine/Interfaces/IScriptEngine.cs
index 17c2708..b8fdd01 100644
--- a/OpenSim/Region/ScriptEngine/Interfaces/IScriptEngine.cs
+++ b/OpenSim/Region/ScriptEngine/Interfaces/IScriptEngine.cs
@@ -25,16 +25,17 @@
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */ 26 */
27 27
28using log4net;
29using System; 28using System;
30using OpenSim.Region.ScriptEngine.Shared; 29using System.Reflection;
30using OpenSim.Framework;
31using OpenSim.Region.Framework.Scenes; 31using OpenSim.Region.Framework.Scenes;
32using OpenSim.Region.Framework.Interfaces; 32using OpenSim.Region.Framework.Interfaces;
33using OpenMetaverse;
34using Nini.Config;
35using OpenSim.Region.ScriptEngine.Interfaces; 33using OpenSim.Region.ScriptEngine.Interfaces;
34using OpenSim.Region.ScriptEngine.Shared;
36using Amib.Threading; 35using Amib.Threading;
37using OpenSim.Framework; 36using log4net;
37using Nini.Config;
38using OpenMetaverse;
38 39
39namespace OpenSim.Region.ScriptEngine.Interfaces 40namespace OpenSim.Region.ScriptEngine.Interfaces
40{ 41{
@@ -76,6 +77,38 @@ namespace OpenSim.Region.ScriptEngine.Interfaces
76 IConfigSource ConfigSource { get; } 77 IConfigSource ConfigSource { get; }
77 string ScriptEngineName { get; } 78 string ScriptEngineName { get; }
78 string ScriptEnginePath { get; } 79 string ScriptEnginePath { get; }
80
81 /// <summary>
82 /// Return the name of the class that will be used for all running scripts.
83 /// </summary>
84 /// <remarks>
85 /// Each class goes in its own assembly so we don't need to otherwise distinguish the class name.
86 /// </remarks>
87 string ScriptClassName { get; }
88
89 /// <summary>
90 /// Return the name of the base class that will be used for all running scripts.
91 /// </summary>
92 string ScriptBaseClassName { get; }
93
94 /// <summary>
95 /// Assemblies that need to be referenced when compiling scripts.
96 /// </summary>
97 /// <remarks>
98 /// These are currently additional to those always referenced by the compiler, BUT THIS MAY CHANGE IN THE
99 /// FUTURE.
100 /// This can be null if there are no additional assemblies.
101 /// </remarks>
102 string[] ScriptReferencedAssemblies { get; }
103
104 /// <summary>
105 /// Parameters for the generated script's constructor.
106 /// </summary>
107 /// <remarks>
108 /// Can be null if there are no parameters
109 /// </remarks>
110 ParameterInfo[] ScriptBaseClassParameters { get; }
111
79 IScriptApi GetApi(UUID itemID, string name); 112 IScriptApi GetApi(UUID itemID, string name);
80 } 113 }
81} 114}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs
index d03955b..fce8ff8 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs
@@ -63,7 +63,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
63 internal TaskInventoryItem m_item; 63 internal TaskInventoryItem m_item;
64 internal bool m_CMFunctionsEnabled = false; 64 internal bool m_CMFunctionsEnabled = false;
65 65
66 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item, EventWaitHandle coopSleepHandle) 66 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item, WaitHandle coopSleepHandle)
67 { 67 {
68 m_ScriptEngine = ScriptEngine; 68 m_ScriptEngine = ScriptEngine;
69 m_host = host; 69 m_host = host;
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index 9df04df..70dea08 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -95,7 +95,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
95 /// Used for script sleeps when we are using co-operative script termination. 95 /// Used for script sleeps when we are using co-operative script termination.
96 /// </summary> 96 /// </summary>
97 /// <remarks>null if co-operative script termination is not active</remarks> 97 /// <remarks>null if co-operative script termination is not active</remarks>
98 EventWaitHandle m_coopSleepHandle; 98 WaitHandle m_coopSleepHandle;
99 99
100 /// <summary> 100 /// <summary>
101 /// The item that hosts this script 101 /// The item that hosts this script
@@ -150,7 +150,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
150 }; 150 };
151 151
152 public void Initialize( 152 public void Initialize(
153 IScriptEngine scriptEngine, SceneObjectPart host, TaskInventoryItem item, EventWaitHandle coopSleepHandle) 153 IScriptEngine scriptEngine, SceneObjectPart host, TaskInventoryItem item, WaitHandle coopSleepHandle)
154 { 154 {
155 m_lastSayShoutCheck = DateTime.UtcNow; 155 m_lastSayShoutCheck = DateTime.UtcNow;
156 156
@@ -227,7 +227,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
227 { 227 {
228 if (m_coopSleepHandle == null) 228 if (m_coopSleepHandle == null)
229 System.Threading.Thread.Sleep(delay); 229 System.Threading.Thread.Sleep(delay);
230 else if (m_coopSleepHandle.WaitOne(delay)) 230 else
231 CheckForCoopTermination(delay);
232 }
233
234 /// <summary>
235 /// Check for co-operative termination.
236 /// </summary>
237 /// <param name='delay'>If called with 0, then just the check is performed with no wait.</param>
238 protected virtual void CheckForCoopTermination(int delay)
239 {
240 if (m_coopSleepHandle.WaitOne(delay))
231 throw new ScriptCoopStopException(); 241 throw new ScriptCoopStopException();
232 } 242 }
233 243
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs
index a08ccc8..1d6cb6d 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs
@@ -63,7 +63,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
63 internal IScriptModuleComms m_comms = null; 63 internal IScriptModuleComms m_comms = null;
64 64
65 public void Initialize( 65 public void Initialize(
66 IScriptEngine scriptEngine, SceneObjectPart host, TaskInventoryItem item, EventWaitHandle coopSleepHandle) 66 IScriptEngine scriptEngine, SceneObjectPart host, TaskInventoryItem item, WaitHandle coopSleepHandle)
67 { 67 {
68 m_ScriptEngine = scriptEngine; 68 m_ScriptEngine = scriptEngine;
69 m_host = host; 69 m_host = host;
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs
index 981499e..9045672 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs
@@ -63,7 +63,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
63 internal IScriptModuleComms m_comms = null; 63 internal IScriptModuleComms m_comms = null;
64 64
65 public void Initialize( 65 public void Initialize(
66 IScriptEngine scriptEngine, SceneObjectPart host, TaskInventoryItem item, EventWaitHandle coopSleepHandle) 66 IScriptEngine scriptEngine, SceneObjectPart host, TaskInventoryItem item, WaitHandle coopSleepHandle)
67 { 67 {
68 m_ScriptEngine = scriptEngine; 68 m_ScriptEngine = scriptEngine;
69 m_host = host; 69 m_host = host;
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
index 10ec34d..6ff6b00 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
@@ -144,7 +144,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
144 protected IUrlModule m_UrlModule = null; 144 protected IUrlModule m_UrlModule = null;
145 145
146 public void Initialize( 146 public void Initialize(
147 IScriptEngine scriptEngine, SceneObjectPart host, TaskInventoryItem item, EventWaitHandle coopSleepHandle) 147 IScriptEngine scriptEngine, SceneObjectPart host, TaskInventoryItem item, WaitHandle coopSleepHandle)
148 { 148 {
149 m_ScriptEngine = scriptEngine; 149 m_ScriptEngine = scriptEngine;
150 m_host = host; 150 m_host = host;
diff --git a/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs b/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs
index 97dd0f6..985e598 100644
--- a/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs
@@ -49,6 +49,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
49 private List<string> m_warnings = new List<string>(); 49 private List<string> m_warnings = new List<string>();
50 private IScriptModuleComms m_comms = null; 50 private IScriptModuleComms m_comms = null;
51 51
52 private bool m_insertCoopTerminationChecks;
53 private static string m_coopTerminationCheck = "opensim_reserved_CheckForCoopTermination();";
54
55 /// <summary>
56 /// Keep a record of the previous node when we do the parsing.
57 /// </summary>
58 /// <remarks>
59 /// We do this here because the parser generated by CSTools does not retain a reference to its parent node.
60 /// The previous node is required so we can correctly insert co-op termination checks when required.
61 /// </remarks>
62// private SYMBOL m_previousNode;
63
52 /// <summary> 64 /// <summary>
53 /// Creates an 'empty' CSCodeGenerator instance. 65 /// Creates an 'empty' CSCodeGenerator instance.
54 /// </summary> 66 /// </summary>
@@ -58,9 +70,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
58 ResetCounters(); 70 ResetCounters();
59 } 71 }
60 72
61 public CSCodeGenerator(IScriptModuleComms comms) 73 public CSCodeGenerator(IScriptModuleComms comms, bool insertCoopTerminationChecks)
62 { 74 {
63 m_comms = comms; 75 m_comms = comms;
76 m_insertCoopTerminationChecks = insertCoopTerminationChecks;
64 ResetCounters(); 77 ResetCounters();
65 } 78 }
66 79
@@ -155,7 +168,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
155 // here's the payload 168 // here's the payload
156 retstr += GenerateLine(); 169 retstr += GenerateLine();
157 foreach (SYMBOL s in m_astRoot.kids) 170 foreach (SYMBOL s in m_astRoot.kids)
158 retstr += GenerateNode(s); 171 retstr += GenerateNode(m_astRoot, s);
159 172
160 // close braces! 173 // close braces!
161 m_braceCount--; 174 m_braceCount--;
@@ -165,7 +178,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
165 178
166 // Removes all carriage return characters which may be generated in Windows platform. Is there 179 // Removes all carriage return characters which may be generated in Windows platform. Is there
167 // cleaner way of doing this? 180 // cleaner way of doing this?
168 retstr=retstr.Replace("\r", ""); 181 retstr = retstr.Replace("\r", "");
169 182
170 return retstr; 183 return retstr;
171 } 184 }
@@ -191,9 +204,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
191 /// Recursively called to generate each type of node. Will generate this 204 /// Recursively called to generate each type of node. Will generate this
192 /// node, then all it's children. 205 /// node, then all it's children.
193 /// </summary> 206 /// </summary>
207 /// <param name="previousSymbol">The parent node.</param>
194 /// <param name="s">The current node to generate code for.</param> 208 /// <param name="s">The current node to generate code for.</param>
195 /// <returns>String containing C# code for SYMBOL s.</returns> 209 /// <returns>String containing C# code for SYMBOL s.</returns>
196 private string GenerateNode(SYMBOL s) 210 private string GenerateNode(SYMBOL previousSymbol, SYMBOL s)
197 { 211 {
198 string retstr = String.Empty; 212 string retstr = String.Empty;
199 213
@@ -207,11 +221,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
207 else if (s is State) 221 else if (s is State)
208 retstr += GenerateState((State) s); 222 retstr += GenerateState((State) s);
209 else if (s is CompoundStatement) 223 else if (s is CompoundStatement)
210 retstr += GenerateCompoundStatement((CompoundStatement) s); 224 retstr += GenerateCompoundStatement(previousSymbol, (CompoundStatement) s);
211 else if (s is Declaration) 225 else if (s is Declaration)
212 retstr += GenerateDeclaration((Declaration) s); 226 retstr += GenerateDeclaration((Declaration) s);
213 else if (s is Statement) 227 else if (s is Statement)
214 retstr += GenerateStatement((Statement) s); 228 retstr += GenerateStatement(previousSymbol, (Statement) s);
215 else if (s is ReturnStatement) 229 else if (s is ReturnStatement)
216 retstr += GenerateReturnStatement((ReturnStatement) s); 230 retstr += GenerateReturnStatement((ReturnStatement) s);
217 else if (s is JumpLabel) 231 else if (s is JumpLabel)
@@ -261,7 +275,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
261 else 275 else
262 { 276 {
263 foreach (SYMBOL kid in s.kids) 277 foreach (SYMBOL kid in s.kids)
264 retstr += GenerateNode(kid); 278 retstr += GenerateNode(s, kid);
265 } 279 }
266 280
267 return retstr; 281 return retstr;
@@ -295,7 +309,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
295 retstr += GenerateLine(")"); 309 retstr += GenerateLine(")");
296 310
297 foreach (SYMBOL kid in remainingKids) 311 foreach (SYMBOL kid in remainingKids)
298 retstr += GenerateNode(kid); 312 retstr += GenerateNode(gf, kid);
299 313
300 return retstr; 314 return retstr;
301 } 315 }
@@ -312,7 +326,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
312 foreach (SYMBOL s in gv.kids) 326 foreach (SYMBOL s in gv.kids)
313 { 327 {
314 retstr += Indent(); 328 retstr += Indent();
315 retstr += GenerateNode(s); 329 retstr += GenerateNode(gv, s);
316 retstr += GenerateLine(";"); 330 retstr += GenerateLine(";");
317 } 331 }
318 332
@@ -365,7 +379,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
365 retstr += GenerateLine(")"); 379 retstr += GenerateLine(")");
366 380
367 foreach (SYMBOL kid in remainingKids) 381 foreach (SYMBOL kid in remainingKids)
368 retstr += GenerateNode(kid); 382 retstr += GenerateNode(se, kid);
369 383
370 return retstr; 384 return retstr;
371 } 385 }
@@ -404,7 +418,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
404 418
405 foreach (SYMBOL s in al.kids) 419 foreach (SYMBOL s in al.kids)
406 { 420 {
407 retstr += GenerateNode(s); 421 retstr += GenerateNode(al, s);
408 if (0 < comma--) 422 if (0 < comma--)
409 retstr += Generate(", "); 423 retstr += Generate(", ");
410 } 424 }
@@ -417,7 +431,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
417 /// </summary> 431 /// </summary>
418 /// <param name="cs">The CompoundStatement node.</param> 432 /// <param name="cs">The CompoundStatement node.</param>
419 /// <returns>String containing C# code for CompoundStatement cs.</returns> 433 /// <returns>String containing C# code for CompoundStatement cs.</returns>
420 private string GenerateCompoundStatement(CompoundStatement cs) 434 private string GenerateCompoundStatement(SYMBOL previousSymbol, CompoundStatement cs)
421 { 435 {
422 string retstr = String.Empty; 436 string retstr = String.Empty;
423 437
@@ -425,8 +439,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
425 retstr += GenerateIndentedLine("{"); 439 retstr += GenerateIndentedLine("{");
426 m_braceCount++; 440 m_braceCount++;
427 441
442 if (m_insertCoopTerminationChecks)
443 {
444 // We have to check in event functions as well because the user can manually call these.
445 if (previousSymbol is GlobalFunctionDefinition
446 || previousSymbol is WhileStatement
447 || previousSymbol is DoWhileStatement
448 || previousSymbol is ForLoop
449 || previousSymbol is StateEvent)
450 retstr += GenerateIndentedLine(m_coopTerminationCheck);
451 }
452
428 foreach (SYMBOL kid in cs.kids) 453 foreach (SYMBOL kid in cs.kids)
429 retstr += GenerateNode(kid); 454 retstr += GenerateNode(cs, kid);
430 455
431 // closing brace 456 // closing brace
432 m_braceCount--; 457 m_braceCount--;
@@ -450,13 +475,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
450 /// </summary> 475 /// </summary>
451 /// <param name="s">The Statement node.</param> 476 /// <param name="s">The Statement node.</param>
452 /// <returns>String containing C# code for Statement s.</returns> 477 /// <returns>String containing C# code for Statement s.</returns>
453 private string GenerateStatement(Statement s) 478 private string GenerateStatement(SYMBOL previousSymbol, Statement s)
454 { 479 {
455 string retstr = String.Empty; 480 string retstr = String.Empty;
456 bool printSemicolon = true; 481 bool printSemicolon = true;
457 482
458 retstr += Indent(); 483 retstr += Indent();
459 484
485 if (m_insertCoopTerminationChecks)
486 {
487 // We have to check in event functions as well because the user can manually call these.
488 if (previousSymbol is GlobalFunctionDefinition
489 || previousSymbol is WhileStatement
490 || previousSymbol is DoWhileStatement
491 || previousSymbol is ForLoop
492 || previousSymbol is StateEvent)
493 retstr += Generate(m_coopTerminationCheck);
494 }
495
460 if (0 < s.kids.Count) 496 if (0 < s.kids.Count)
461 { 497 {
462 // Jump label prints its own colon, we don't need a semicolon. 498 // Jump label prints its own colon, we don't need a semicolon.
@@ -466,7 +502,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
466 // (MONO) error. 502 // (MONO) error.
467 if (!(s.kids.Top is IdentExpression && 1 == s.kids.Count)) 503 if (!(s.kids.Top is IdentExpression && 1 == s.kids.Count))
468 foreach (SYMBOL kid in s.kids) 504 foreach (SYMBOL kid in s.kids)
469 retstr += GenerateNode(kid); 505 retstr += GenerateNode(s, kid);
470 } 506 }
471 507
472 if (printSemicolon) 508 if (printSemicolon)
@@ -487,10 +523,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
487 List<string> identifiers = new List<string>(); 523 List<string> identifiers = new List<string>();
488 checkForMultipleAssignments(identifiers, a); 524 checkForMultipleAssignments(identifiers, a);
489 525
490 retstr += GenerateNode((SYMBOL) a.kids.Pop()); 526 retstr += GenerateNode(a, (SYMBOL) a.kids.Pop());
491 retstr += Generate(String.Format(" {0} ", a.AssignmentType), a); 527 retstr += Generate(String.Format(" {0} ", a.AssignmentType), a);
492 foreach (SYMBOL kid in a.kids) 528 foreach (SYMBOL kid in a.kids)
493 retstr += GenerateNode(kid); 529 retstr += GenerateNode(a, kid);
494 530
495 return retstr; 531 return retstr;
496 } 532 }
@@ -563,7 +599,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
563 retstr += Generate("return ", rs); 599 retstr += Generate("return ", rs);
564 600
565 foreach (SYMBOL kid in rs.kids) 601 foreach (SYMBOL kid in rs.kids)
566 retstr += GenerateNode(kid); 602 retstr += GenerateNode(rs, kid);
567 603
568 return retstr; 604 return retstr;
569 } 605 }
@@ -575,7 +611,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
575 /// <returns>String containing C# code for JumpLabel jl.</returns> 611 /// <returns>String containing C# code for JumpLabel jl.</returns>
576 private string GenerateJumpLabel(JumpLabel jl) 612 private string GenerateJumpLabel(JumpLabel jl)
577 { 613 {
578 return Generate(String.Format("{0}:", CheckName(jl.LabelName)), jl) + " NoOp();\n"; 614 string labelStatement;
615
616 if (m_insertCoopTerminationChecks)
617 labelStatement = m_coopTerminationCheck + "\n";
618 else
619 labelStatement = "NoOp();\n";
620
621 return Generate(String.Format("{0}: ", CheckName(jl.LabelName)), jl) + labelStatement;
579 } 622 }
580 623
581 /// <summary> 624 /// <summary>
@@ -598,14 +641,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
598 string retstr = String.Empty; 641 string retstr = String.Empty;
599 642
600 retstr += GenerateIndented("if (", ifs); 643 retstr += GenerateIndented("if (", ifs);
601 retstr += GenerateNode((SYMBOL) ifs.kids.Pop()); 644 retstr += GenerateNode(ifs, (SYMBOL) ifs.kids.Pop());
602 retstr += GenerateLine(")"); 645 retstr += GenerateLine(")");
603 646
604 // CompoundStatement handles indentation itself but we need to do it 647 // CompoundStatement handles indentation itself but we need to do it
605 // otherwise. 648 // otherwise.
606 bool indentHere = ifs.kids.Top is Statement; 649 bool indentHere = ifs.kids.Top is Statement;
607 if (indentHere) m_braceCount++; 650 if (indentHere) m_braceCount++;
608 retstr += GenerateNode((SYMBOL) ifs.kids.Pop()); 651 retstr += GenerateNode(ifs, (SYMBOL) ifs.kids.Pop());
609 if (indentHere) m_braceCount--; 652 if (indentHere) m_braceCount--;
610 653
611 if (0 < ifs.kids.Count) // do it again for an else 654 if (0 < ifs.kids.Count) // do it again for an else
@@ -614,7 +657,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
614 657
615 indentHere = ifs.kids.Top is Statement; 658 indentHere = ifs.kids.Top is Statement;
616 if (indentHere) m_braceCount++; 659 if (indentHere) m_braceCount++;
617 retstr += GenerateNode((SYMBOL) ifs.kids.Pop()); 660 retstr += GenerateNode(ifs, (SYMBOL) ifs.kids.Pop());
618 if (indentHere) m_braceCount--; 661 if (indentHere) m_braceCount--;
619 } 662 }
620 663
@@ -641,14 +684,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
641 string retstr = String.Empty; 684 string retstr = String.Empty;
642 685
643 retstr += GenerateIndented("while (", ws); 686 retstr += GenerateIndented("while (", ws);
644 retstr += GenerateNode((SYMBOL) ws.kids.Pop()); 687 retstr += GenerateNode(ws, (SYMBOL) ws.kids.Pop());
645 retstr += GenerateLine(")"); 688 retstr += GenerateLine(")");
646 689
647 // CompoundStatement handles indentation itself but we need to do it 690 // CompoundStatement handles indentation itself but we need to do it
648 // otherwise. 691 // otherwise.
649 bool indentHere = ws.kids.Top is Statement; 692 bool indentHere = ws.kids.Top is Statement;
650 if (indentHere) m_braceCount++; 693 if (indentHere) m_braceCount++;
651 retstr += GenerateNode((SYMBOL) ws.kids.Pop()); 694 retstr += GenerateNode(ws, (SYMBOL) ws.kids.Pop());
652 if (indentHere) m_braceCount--; 695 if (indentHere) m_braceCount--;
653 696
654 return retstr; 697 return retstr;
@@ -669,11 +712,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
669 // otherwise. 712 // otherwise.
670 bool indentHere = dws.kids.Top is Statement; 713 bool indentHere = dws.kids.Top is Statement;
671 if (indentHere) m_braceCount++; 714 if (indentHere) m_braceCount++;
672 retstr += GenerateNode((SYMBOL) dws.kids.Pop()); 715 retstr += GenerateNode(dws, (SYMBOL) dws.kids.Pop());
673 if (indentHere) m_braceCount--; 716 if (indentHere) m_braceCount--;
674 717
675 retstr += GenerateIndented("while (", dws); 718 retstr += GenerateIndented("while (", dws);
676 retstr += GenerateNode((SYMBOL) dws.kids.Pop()); 719 retstr += GenerateNode(dws, (SYMBOL) dws.kids.Pop());
677 retstr += GenerateLine(");"); 720 retstr += GenerateLine(");");
678 721
679 return retstr; 722 return retstr;
@@ -702,7 +745,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
702 retstr += Generate("; "); 745 retstr += Generate("; ");
703 // for (x = 0; x < 10; x++) 746 // for (x = 0; x < 10; x++)
704 // ^^^^^^ 747 // ^^^^^^
705 retstr += GenerateNode((SYMBOL) fl.kids.Pop()); 748 retstr += GenerateNode(fl, (SYMBOL) fl.kids.Pop());
706 retstr += Generate("; "); 749 retstr += Generate("; ");
707 // for (x = 0; x < 10; x++) 750 // for (x = 0; x < 10; x++)
708 // ^^^ 751 // ^^^
@@ -713,7 +756,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
713 // otherwise. 756 // otherwise.
714 bool indentHere = fl.kids.Top is Statement; 757 bool indentHere = fl.kids.Top is Statement;
715 if (indentHere) m_braceCount++; 758 if (indentHere) m_braceCount++;
716 retstr += GenerateNode((SYMBOL) fl.kids.Pop()); 759 retstr += GenerateNode(fl, (SYMBOL) fl.kids.Pop());
717 if (indentHere) m_braceCount--; 760 if (indentHere) m_braceCount--;
718 761
719 return retstr; 762 return retstr;
@@ -758,7 +801,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
758 while (s is ParenthesisExpression) 801 while (s is ParenthesisExpression)
759 s = (SYMBOL)s.kids.Pop(); 802 s = (SYMBOL)s.kids.Pop();
760 803
761 retstr += GenerateNode(s); 804 retstr += GenerateNode(fls, s);
762 if (0 < comma--) 805 if (0 < comma--)
763 retstr += Generate(", "); 806 retstr += Generate(", ");
764 } 807 }
@@ -779,20 +822,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
779 { 822 {
780 // special case handling for logical and/or, see Mantis 3174 823 // special case handling for logical and/or, see Mantis 3174
781 retstr += "((bool)("; 824 retstr += "((bool)(";
782 retstr += GenerateNode((SYMBOL)be.kids.Pop()); 825 retstr += GenerateNode(be, (SYMBOL)be.kids.Pop());
783 retstr += "))"; 826 retstr += "))";
784 retstr += Generate(String.Format(" {0} ", be.ExpressionSymbol.Substring(0,1)), be); 827 retstr += Generate(String.Format(" {0} ", be.ExpressionSymbol.Substring(0,1)), be);
785 retstr += "((bool)("; 828 retstr += "((bool)(";
786 foreach (SYMBOL kid in be.kids) 829 foreach (SYMBOL kid in be.kids)
787 retstr += GenerateNode(kid); 830 retstr += GenerateNode(be, kid);
788 retstr += "))"; 831 retstr += "))";
789 } 832 }
790 else 833 else
791 { 834 {
792 retstr += GenerateNode((SYMBOL)be.kids.Pop()); 835 retstr += GenerateNode(be, (SYMBOL)be.kids.Pop());
793 retstr += Generate(String.Format(" {0} ", be.ExpressionSymbol), be); 836 retstr += Generate(String.Format(" {0} ", be.ExpressionSymbol), be);
794 foreach (SYMBOL kid in be.kids) 837 foreach (SYMBOL kid in be.kids)
795 retstr += GenerateNode(kid); 838 retstr += GenerateNode(be, kid);
796 } 839 }
797 840
798 return retstr; 841 return retstr;
@@ -808,7 +851,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
808 string retstr = String.Empty; 851 string retstr = String.Empty;
809 852
810 retstr += Generate(ue.UnarySymbol, ue); 853 retstr += Generate(ue.UnarySymbol, ue);
811 retstr += GenerateNode((SYMBOL) ue.kids.Pop()); 854 retstr += GenerateNode(ue, (SYMBOL) ue.kids.Pop());
812 855
813 return retstr; 856 return retstr;
814 } 857 }
@@ -824,7 +867,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
824 867
825 retstr += Generate("("); 868 retstr += Generate("(");
826 foreach (SYMBOL kid in pe.kids) 869 foreach (SYMBOL kid in pe.kids)
827 retstr += GenerateNode(kid); 870 retstr += GenerateNode(pe, kid);
828 retstr += Generate(")"); 871 retstr += Generate(")");
829 872
830 return retstr; 873 return retstr;
@@ -861,7 +904,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
861 904
862 // we wrap all typecasted statements in parentheses 905 // we wrap all typecasted statements in parentheses
863 retstr += Generate(String.Format("({0}) (", te.TypecastType), te); 906 retstr += Generate(String.Format("({0}) (", te.TypecastType), te);
864 retstr += GenerateNode((SYMBOL) te.kids.Pop()); 907 retstr += GenerateNode(te, (SYMBOL) te.kids.Pop());
865 retstr += Generate(")"); 908 retstr += Generate(")");
866 909
867 return retstr; 910 return retstr;
@@ -931,7 +974,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
931 } 974 }
932 975
933 foreach (SYMBOL kid in fc.kids) 976 foreach (SYMBOL kid in fc.kids)
934 retstr += GenerateNode(kid); 977 retstr += GenerateNode(fc, kid);
935 978
936 retstr += Generate(")"); 979 retstr += Generate(")");
937 980
@@ -980,11 +1023,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
980 string retstr = String.Empty; 1023 string retstr = String.Empty;
981 1024
982 retstr += Generate(String.Format("new {0}(", vc.Type), vc); 1025 retstr += Generate(String.Format("new {0}(", vc.Type), vc);
983 retstr += GenerateNode((SYMBOL) vc.kids.Pop()); 1026 retstr += GenerateNode(vc, (SYMBOL) vc.kids.Pop());
984 retstr += Generate(", "); 1027 retstr += Generate(", ");
985 retstr += GenerateNode((SYMBOL) vc.kids.Pop()); 1028 retstr += GenerateNode(vc, (SYMBOL) vc.kids.Pop());
986 retstr += Generate(", "); 1029 retstr += Generate(", ");
987 retstr += GenerateNode((SYMBOL) vc.kids.Pop()); 1030 retstr += GenerateNode(vc, (SYMBOL) vc.kids.Pop());
988 retstr += Generate(")"); 1031 retstr += Generate(")");
989 1032
990 return retstr; 1033 return retstr;
@@ -1000,13 +1043,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
1000 string retstr = String.Empty; 1043 string retstr = String.Empty;
1001 1044
1002 retstr += Generate(String.Format("new {0}(", rc.Type), rc); 1045 retstr += Generate(String.Format("new {0}(", rc.Type), rc);
1003 retstr += GenerateNode((SYMBOL) rc.kids.Pop()); 1046 retstr += GenerateNode(rc, (SYMBOL) rc.kids.Pop());
1004 retstr += Generate(", "); 1047 retstr += Generate(", ");
1005 retstr += GenerateNode((SYMBOL) rc.kids.Pop()); 1048 retstr += GenerateNode(rc, (SYMBOL) rc.kids.Pop());
1006 retstr += Generate(", "); 1049 retstr += Generate(", ");
1007 retstr += GenerateNode((SYMBOL) rc.kids.Pop()); 1050 retstr += GenerateNode(rc, (SYMBOL) rc.kids.Pop());
1008 retstr += Generate(", "); 1051 retstr += Generate(", ");
1009 retstr += GenerateNode((SYMBOL) rc.kids.Pop()); 1052 retstr += GenerateNode(rc, (SYMBOL) rc.kids.Pop());
1010 retstr += Generate(")"); 1053 retstr += Generate(")");
1011 1054
1012 return retstr; 1055 return retstr;
@@ -1024,7 +1067,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
1024 retstr += Generate(String.Format("new {0}(", lc.Type), lc); 1067 retstr += Generate(String.Format("new {0}(", lc.Type), lc);
1025 1068
1026 foreach (SYMBOL kid in lc.kids) 1069 foreach (SYMBOL kid in lc.kids)
1027 retstr += GenerateNode(kid); 1070 retstr += GenerateNode(lc, kid);
1028 1071
1029 retstr += Generate(")"); 1072 retstr += Generate(")");
1030 1073
diff --git a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs
index 03be2ab..002e852 100644
--- a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs
@@ -31,6 +31,7 @@ using System.Collections.Generic;
31using System.Globalization; 31using System.Globalization;
32using System.Reflection; 32using System.Reflection;
33using System.IO; 33using System.IO;
34using System.Linq;
34using System.Text; 35using System.Text;
35using Microsoft.CSharp; 36using Microsoft.CSharp;
36//using Microsoft.JScript; 37//using Microsoft.JScript;
@@ -72,6 +73,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
72 private bool CompileWithDebugInformation; 73 private bool CompileWithDebugInformation;
73 private Dictionary<string, bool> AllowedCompilers = new Dictionary<string, bool>(StringComparer.CurrentCultureIgnoreCase); 74 private Dictionary<string, bool> AllowedCompilers = new Dictionary<string, bool>(StringComparer.CurrentCultureIgnoreCase);
74 private Dictionary<string, enumCompileType> LanguageMapping = new Dictionary<string, enumCompileType>(StringComparer.CurrentCultureIgnoreCase); 75 private Dictionary<string, enumCompileType> LanguageMapping = new Dictionary<string, enumCompileType>(StringComparer.CurrentCultureIgnoreCase);
76 private bool m_insertCoopTerminationCalls;
75 77
76 private string FilePrefix; 78 private string FilePrefix;
77 private string ScriptEnginesPath = null; 79 private string ScriptEnginesPath = null;
@@ -95,20 +97,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
95 private Dictionary<string, Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>>> m_lineMaps = 97 private Dictionary<string, Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>>> m_lineMaps =
96 new Dictionary<string, Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>>>(); 98 new Dictionary<string, Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>>>();
97 99
100 public bool in_startup = true;
101
98 public Compiler(IScriptEngine scriptEngine) 102 public Compiler(IScriptEngine scriptEngine)
99 { 103 {
100 m_scriptEngine = scriptEngine;; 104 m_scriptEngine = scriptEngine;
101 ScriptEnginesPath = scriptEngine.ScriptEnginePath; 105 ScriptEnginesPath = scriptEngine.ScriptEnginePath;
102 ReadConfig(); 106 ReadConfig();
103 } 107 }
104 108
105 public bool in_startup = true;
106 public void ReadConfig() 109 public void ReadConfig()
107 { 110 {
108 // Get some config 111 // Get some config
109 WriteScriptSourceToDebugFile = m_scriptEngine.Config.GetBoolean("WriteScriptSourceToDebugFile", false); 112 WriteScriptSourceToDebugFile = m_scriptEngine.Config.GetBoolean("WriteScriptSourceToDebugFile", false);
110 CompileWithDebugInformation = m_scriptEngine.Config.GetBoolean("CompileWithDebugInformation", true); 113 CompileWithDebugInformation = m_scriptEngine.Config.GetBoolean("CompileWithDebugInformation", true);
111 bool DeleteScriptsOnStartup = m_scriptEngine.Config.GetBoolean("DeleteScriptsOnStartup", true); 114 bool DeleteScriptsOnStartup = m_scriptEngine.Config.GetBoolean("DeleteScriptsOnStartup", true);
115 m_insertCoopTerminationCalls = m_scriptEngine.Config.GetString("ScriptStopStrategy", "abort") == "co-op";
112 116
113 // Get file prefix from scriptengine name and make it file system safe: 117 // Get file prefix from scriptengine name and make it file system safe:
114 FilePrefix = "CommonCompiler"; 118 FilePrefix = "CommonCompiler";
@@ -386,7 +390,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
386 if (language == enumCompileType.lsl) 390 if (language == enumCompileType.lsl)
387 { 391 {
388 // Its LSL, convert it to C# 392 // Its LSL, convert it to C#
389 LSL_Converter = (ICodeConverter)new CSCodeGenerator(comms); 393 LSL_Converter = (ICodeConverter)new CSCodeGenerator(comms, m_insertCoopTerminationCalls);
390 compileScript = LSL_Converter.Convert(Script); 394 compileScript = LSL_Converter.Convert(Script);
391 395
392 // copy converter warnings into our warnings. 396 // copy converter warnings into our warnings.
@@ -411,16 +415,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
411 { 415 {
412 case enumCompileType.cs: 416 case enumCompileType.cs:
413 case enumCompileType.lsl: 417 case enumCompileType.lsl:
414 compileScript = CreateCSCompilerScript(compileScript); 418 compileScript = CreateCSCompilerScript(
419 compileScript,
420 m_scriptEngine.ScriptClassName,
421 m_scriptEngine.ScriptBaseClassName,
422 m_scriptEngine.ScriptBaseClassParameters);
415 break; 423 break;
416 case enumCompileType.vb: 424 case enumCompileType.vb:
417 compileScript = CreateVBCompilerScript(compileScript); 425 compileScript = CreateVBCompilerScript(
426 compileScript, m_scriptEngine.ScriptClassName, m_scriptEngine.ScriptBaseClassName);
418 break; 427 break;
419// case enumCompileType.js: 428// case enumCompileType.js:
420// compileScript = CreateJSCompilerScript(compileScript); 429// compileScript = CreateJSCompilerScript(compileScript, m_scriptEngine.ScriptBaseClassName);
421// break; 430// break;
422 case enumCompileType.yp: 431 case enumCompileType.yp:
423 compileScript = CreateYPCompilerScript(compileScript); 432 compileScript = CreateYPCompilerScript(
433 compileScript, m_scriptEngine.ScriptClassName,m_scriptEngine.ScriptBaseClassName);
424 break; 434 break;
425 } 435 }
426 436
@@ -451,43 +461,60 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
451// return compileScript; 461// return compileScript;
452// } 462// }
453 463
454 private static string CreateCSCompilerScript(string compileScript) 464 private static string CreateCSCompilerScript(
465 string compileScript, string className, string baseClassName, ParameterInfo[] constructorParameters)
455 { 466 {
456 compileScript = String.Empty + 467 compileScript = string.Format(
457 "using OpenSim.Region.ScriptEngine.Shared; using System.Collections.Generic;\r\n" + 468@"using OpenSim.Region.ScriptEngine.Shared;
458 String.Empty + "namespace SecondLife { " + 469using System.Collections.Generic;
459 String.Empty + "public class Script : OpenSim.Region.ScriptEngine.Shared.ScriptBase.ScriptBaseClass { \r\n" + 470
460 @"public Script() { } " + 471namespace SecondLife
461 compileScript + 472{{
462 "} }\r\n"; 473 public class {0} : {1}
474 {{
475 public {0}({2}) : base({3}) {{}}
476{4}
477 }}
478}}",
479 className,
480 baseClassName,
481 constructorParameters != null
482 ? string.Join(", ", Array.ConvertAll<ParameterInfo, string>(constructorParameters, pi => pi.ToString()))
483 : "",
484 constructorParameters != null
485 ? string.Join(", ", Array.ConvertAll<ParameterInfo, string>(constructorParameters, pi => pi.Name))
486 : "",
487 compileScript);
488
463 return compileScript; 489 return compileScript;
464 } 490 }
465 491
466 private static string CreateYPCompilerScript(string compileScript) 492 private static string CreateYPCompilerScript(string compileScript, string className, string baseClassName)
467 { 493 {
468 compileScript = String.Empty + 494 compileScript = String.Empty +
469 "using OpenSim.Region.ScriptEngine.Shared.YieldProlog; " + 495 "using OpenSim.Region.ScriptEngine.Shared.YieldProlog; " +
470 "using OpenSim.Region.ScriptEngine.Shared; using System.Collections.Generic;\r\n" + 496 "using OpenSim.Region.ScriptEngine.Shared; using System.Collections.Generic;\r\n" +
471 String.Empty + "namespace SecondLife { " + 497 String.Empty + "namespace SecondLife { " +
472 String.Empty + "public class Script : OpenSim.Region.ScriptEngine.Shared.ScriptBase.ScriptBaseClass { \r\n" + 498 String.Empty + "public class " + className + " : " + baseClassName + " { \r\n" +
473 //@"public Script() { } " + 499 //@"public Script() { } " +
474 @"static OpenSim.Region.ScriptEngine.Shared.YieldProlog.YP YP=null; " + 500 @"static OpenSim.Region.ScriptEngine.Shared.YieldProlog.YP YP=null; " +
475 @"public Script() { YP= new OpenSim.Region.ScriptEngine.Shared.YieldProlog.YP(); } " + 501 @"public " + className + "() { YP= new OpenSim.Region.ScriptEngine.Shared.YieldProlog.YP(); } " +
476
477 compileScript + 502 compileScript +
478 "} }\r\n"; 503 "} }\r\n";
504
479 return compileScript; 505 return compileScript;
480 } 506 }
481 507
482 private static string CreateVBCompilerScript(string compileScript) 508 private static string CreateVBCompilerScript(string compileScript, string className, string baseClassName)
483 { 509 {
484 compileScript = String.Empty + 510 compileScript = String.Empty +
485 "Imports OpenSim.Region.ScriptEngine.Shared: Imports System.Collections.Generic: " + 511 "Imports OpenSim.Region.ScriptEngine.Shared: Imports System.Collections.Generic: " +
486 String.Empty + "NameSpace SecondLife:" + 512 String.Empty + "NameSpace SecondLife:" +
487 String.Empty + "Public Class Script: Inherits OpenSim.Region.ScriptEngine.Shared.ScriptBase.ScriptBaseClass: " + 513 String.Empty + "Public Class " + className + ": Inherits " + baseClassName +
488 "\r\nPublic Sub New()\r\nEnd Sub: " + 514 "\r\nPublic Sub New()\r\nEnd Sub: " +
489 compileScript + 515 compileScript +
490 ":End Class :End Namespace\r\n"; 516 ":End Class :End Namespace\r\n";
517
491 return compileScript; 518 return compileScript;
492 } 519 }
493 520
@@ -549,6 +576,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
549 parameters.ReferencedAssemblies.Add(Path.Combine(rootPath, 576 parameters.ReferencedAssemblies.Add(Path.Combine(rootPath,
550 "OpenMetaverseTypes.dll")); 577 "OpenMetaverseTypes.dll"));
551 578
579 if (m_scriptEngine.ScriptReferencedAssemblies != null)
580 Array.ForEach<string>(
581 m_scriptEngine.ScriptReferencedAssemblies,
582 a => parameters.ReferencedAssemblies.Add(Path.Combine(rootPath, a)));
583
552 if (lang == enumCompileType.yp) 584 if (lang == enumCompileType.yp)
553 { 585 {
554 parameters.ReferencedAssemblies.Add(Path.Combine(rootPath, 586 parameters.ReferencedAssemblies.Add(Path.Combine(rootPath,
diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
index a869a6a..891e453 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
@@ -252,7 +252,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
252 /// <param name='dom'></param> 252 /// <param name='dom'></param>
253 /// <param name='assembly'></param> 253 /// <param name='assembly'></param>
254 /// <param name='stateSource'></param> 254 /// <param name='stateSource'></param>
255 public void Load(AppDomain dom, string assembly, StateSource stateSource) 255 /// <returns>false if load failed, true if suceeded</returns>
256 public bool Load(AppDomain dom, string assembly, StateSource stateSource)
256 { 257 {
257 m_Assembly = assembly; 258 m_Assembly = assembly;
258 m_stateSource = stateSource; 259 m_stateSource = stateSource;
@@ -267,14 +268,56 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
267 268
268 try 269 try
269 { 270 {
271 object[] constructorParams;
272
273 Assembly scriptAssembly = dom.Load(Path.GetFileNameWithoutExtension(assembly));
274 Type scriptType = scriptAssembly.GetType("SecondLife.XEngineScript");
275
276 if (scriptType != null)
277 {
278 constructorParams = new object[] { m_coopSleepHandle };
279 }
280 else if (!m_coopTermination)
281 {
282 scriptType = scriptAssembly.GetType("SecondLife.Script");
283 constructorParams = null;
284 }
285 else
286 {
287 m_log.ErrorFormat(
288 "[SCRIPT INSTANCE]: Not starting script {0} (id {1}) in part {2} (id {3}) in object {4} in {5}. You must remove all existing {6}* script DLL files before using enabling co-op termination"
289 + ", either by setting DeleteScriptsOnStartup = true in [XEngine] for one run"
290 + " or by deleting these files manually.",
291 ScriptTask.Name, ScriptTask.ItemID, Part.Name, Part.UUID, Part.ParentGroup.Name, Engine.World.Name, assembly);
292
293 return false;
294 }
295
296// m_log.DebugFormat(
297// "[SCRIPT INSTANCE]: Looking to load {0} from assembly {1} in {2}",
298// scriptType.FullName, Path.GetFileNameWithoutExtension(assembly), Engine.World.Name);
299
270 if (dom != System.AppDomain.CurrentDomain) 300 if (dom != System.AppDomain.CurrentDomain)
271 m_Script = (IScript)dom.CreateInstanceAndUnwrap( 301 m_Script
302 = (IScript)dom.CreateInstanceAndUnwrap(
272 Path.GetFileNameWithoutExtension(assembly), 303 Path.GetFileNameWithoutExtension(assembly),
273 "SecondLife.Script"); 304 scriptType.FullName,
305 false,
306 BindingFlags.Default,
307 null,
308 constructorParams,
309 null,
310 null);
274 else 311 else
275 m_Script = (IScript)Assembly.Load( 312 m_Script
276 Path.GetFileNameWithoutExtension(assembly)).CreateInstance( 313 = (IScript)scriptAssembly.CreateInstance(
277 "SecondLife.Script"); 314 scriptType.FullName,
315 false,
316 BindingFlags.Default,
317 null,
318 constructorParams,
319 null,
320 null);
278 321
279 //ILease lease = (ILease)RemotingServices.GetLifetimeService(m_Script as ScriptBaseClass); 322 //ILease lease = (ILease)RemotingServices.GetLifetimeService(m_Script as ScriptBaseClass);
280 //RemotingServices.GetLifetimeService(m_Script as ScriptBaseClass); 323 //RemotingServices.GetLifetimeService(m_Script as ScriptBaseClass);
@@ -283,8 +326,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
283 catch (Exception e) 326 catch (Exception e)
284 { 327 {
285 m_log.ErrorFormat( 328 m_log.ErrorFormat(
286 "[SCRIPT INSTANCE]: Error loading assembly {0}. Exception {1}{2}", 329 "[SCRIPT INSTANCE]: Not starting script {0} (id {1}) in part {2} (id {3}) in object {4} in {5}. Error loading assembly {6}. Exception {7}{8}",
287 assembly, e.Message, e.StackTrace); 330 ScriptTask.Name, ScriptTask.ItemID, Part.Name, Part.UUID, Part.ParentGroup.Name, Engine.World.Name, assembly, e.Message, e.StackTrace);
331
332 return false;
288 } 333 }
289 334
290 try 335 try
@@ -302,10 +347,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
302 catch (Exception e) 347 catch (Exception e)
303 { 348 {
304 m_log.ErrorFormat( 349 m_log.ErrorFormat(
305 "[SCRIPT INSTANCE]: Error loading script instance from assembly {0}. Exception {1}{2}", 350 "[SCRIPT INSTANCE]: Not starting script {0} (id {1}) in part {2} (id {3}) in object {4} in {5}. Error initializing script instance. Exception {6}{7}",
306 assembly, e.Message, e.StackTrace); 351 ScriptTask.Name, ScriptTask.ItemID, Part.Name, Part.UUID, Part.ParentGroup.Name, Engine.World.Name, e.Message, e.StackTrace);
307 352
308 return; 353 return false;
309 } 354 }
310 355
311 m_SaveState = true; 356 m_SaveState = true;
@@ -358,15 +403,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
358 else 403 else
359 { 404 {
360 m_log.WarnFormat( 405 m_log.WarnFormat(
361 "[SCRIPT INSTANCE]: Unable to load script state file {0} for script {1} {2} in {3} {4} (assembly {5}). Memory limit exceeded", 406 "[SCRIPT INSTANCE]: Not starting script {0} (id {1}) in part {2} (id {3}) in object {4} in {5}. Unable to load script state file {6}. Memory limit exceeded.",
362 savedState, ScriptName, ItemID, PrimName, ObjectID, assembly); 407 ScriptTask.Name, ScriptTask.ItemID, Part.Name, Part.UUID, Part.ParentGroup.Name, Engine.World.Name, savedState);
363 } 408 }
364 } 409 }
365 catch (Exception e) 410 catch (Exception e)
366 { 411 {
367 m_log.ErrorFormat( 412 m_log.ErrorFormat(
368 "[SCRIPT INSTANCE]: Unable to load script state file {0} for script {1} {2} in {3} {4} (assembly {5}). XML is {6}. Exception {7}{8}", 413 "[SCRIPT INSTANCE]: Not starting script {0} (id {1}) in part {2} (id {3}) in object {4} in {5}. Unable to load script state file {6}. XML is {7}. Exception {8}{9}",
369 savedState, ScriptName, ItemID, PrimName, ObjectID, assembly, xml, e.Message, e.StackTrace); 414 ScriptTask.Name, ScriptTask.ItemID, Part.Name, Part.UUID, Part.ParentGroup.Name, Engine.World.Name, savedState, xml, e.Message, e.StackTrace);
370 } 415 }
371 } 416 }
372// else 417// else
@@ -377,6 +422,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
377// presence.ControllingClient.SendAgentAlertMessage("Compile successful", false); 422// presence.ControllingClient.SendAgentAlertMessage("Compile successful", false);
378 423
379// } 424// }
425
426 return true;
380 } 427 }
381 428
382 public void Init() 429 public void Init()
@@ -560,9 +607,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
560 } 607 }
561 else 608 else
562 { 609 {
563 m_log.DebugFormat( 610 if (DebugLevel >= 1)
564 "[SCRIPT INSTANCE]: Co-operatively stopping script {0} {1} in {2} {3}", 611 m_log.DebugFormat(
565 ScriptName, ItemID, PrimName, ObjectID); 612 "[SCRIPT INSTANCE]: Co-operatively stopping script {0} {1} in {2} {3}",
613 ScriptName, ItemID, PrimName, ObjectID);
566 614
567 // This will terminate the event on next handle check by the script. 615 // This will terminate the event on next handle check by the script.
568 m_coopSleepHandle.Set(); 616 m_coopSleepHandle.Set();
@@ -571,9 +619,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
571 // checking is implemented. May want to allow a shorter timeout option later. 619 // checking is implemented. May want to allow a shorter timeout option later.
572 if (workItem.Wait(TimeSpan.MaxValue)) 620 if (workItem.Wait(TimeSpan.MaxValue))
573 { 621 {
574 m_log.DebugFormat( 622 if (DebugLevel >= 1)
575 "[SCRIPT INSTANCE]: Co-operatively stopped script {0} {1} in {2} {3}", 623 m_log.DebugFormat(
576 ScriptName, ItemID, PrimName, ObjectID); 624 "[SCRIPT INSTANCE]: Co-operatively stopped script {0} {1} in {2} {3}",
625 ScriptName, ItemID, PrimName, ObjectID);
577 626
578 return true; 627 return true;
579 } 628 }
@@ -894,9 +943,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
894 } 943 }
895 else if ((e is TargetInvocationException) && (e.InnerException is ScriptCoopStopException)) 944 else if ((e is TargetInvocationException) && (e.InnerException is ScriptCoopStopException))
896 { 945 {
897 m_log.DebugFormat( 946 if (DebugLevel >= 1)
898 "[SCRIPT INSTANCE]: Script {0}.{1} in event {2}, state {3} stopped co-operatively.", 947 m_log.DebugFormat(
899 PrimName, ScriptName, data.EventName, State); 948 "[SCRIPT INSTANCE]: Script {0}.{1} in event {2}, state {3} stopped co-operatively.",
949 PrimName, ScriptName, data.EventName, State);
900 } 950 }
901 } 951 }
902 } 952 }
diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs
index 8c3e9e0..52d75a0 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs
@@ -50,14 +50,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance.Tests
50 private TestScene m_scene; 50 private TestScene m_scene;
51 private OpenSim.Region.ScriptEngine.XEngine.XEngine m_xEngine; 51 private OpenSim.Region.ScriptEngine.XEngine.XEngine m_xEngine;
52 52
53 private AutoResetEvent m_chatEvent = new AutoResetEvent(false); 53 private AutoResetEvent m_chatEvent;
54 private AutoResetEvent m_stoppedEvent = new AutoResetEvent(false); 54 private AutoResetEvent m_stoppedEvent;
55 55
56 private OSChatMessage m_osChatMessageReceived; 56 private OSChatMessage m_osChatMessageReceived;
57 57
58 [TestFixtureSetUp] 58 [SetUp]
59 public void Init() 59 public void Init()
60 { 60 {
61 m_osChatMessageReceived = null;
62 m_chatEvent = new AutoResetEvent(false);
63 m_stoppedEvent = new AutoResetEvent(false);
64
61 //AppDomain.CurrentDomain.SetData("APPBASE", Environment.CurrentDirectory + "/bin"); 65 //AppDomain.CurrentDomain.SetData("APPBASE", Environment.CurrentDirectory + "/bin");
62// Console.WriteLine(AppDomain.CurrentDomain.BaseDirectory); 66// Console.WriteLine(AppDomain.CurrentDomain.BaseDirectory);
63 m_xEngine = new OpenSim.Region.ScriptEngine.XEngine.XEngine(); 67 m_xEngine = new OpenSim.Region.ScriptEngine.XEngine.XEngine();
@@ -77,7 +81,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance.Tests
77 81
78 xEngineConfig.Set("ScriptStopStrategy", "co-op"); 82 xEngineConfig.Set("ScriptStopStrategy", "co-op");
79 83
80 m_scene = new SceneHelpers().SetupScene("My Test", UUID.Random(), 1000, 1000, configSource); 84 // Make sure loops aren't actually being terminated by a script delay wait.
85 xEngineConfig.Set("ScriptDelayFactor", 0);
86
87 // This is really just set for debugging the test.
88 xEngineConfig.Set("WriteScriptSourceToDebugFile", true);
89
90 // Set to false if we need to debug test so the old scripts don't get wiped before each separate test
91// xEngineConfig.Set("DeleteScriptsOnStartup", false);
92
93 // This is not currently used at all for co-op termination. Bumping up to demonstrate that co-op termination
94 // has an effect - without it tests will fail due to a 120 second wait for the event to finish.
95 xEngineConfig.Set("WaitForEventCompletionOnScriptStop", 120000);
96
97 m_scene = new SceneHelpers().SetupScene("My Test", TestHelpers.ParseTail(0x9999), 1000, 1000, configSource);
81 SceneHelpers.SetupSceneModules(m_scene, configSource, m_xEngine); 98 SceneHelpers.SetupSceneModules(m_scene, configSource, m_xEngine);
82 m_scene.StartScripts(); 99 m_scene.StartScripts();
83 } 100 }
@@ -95,12 +112,218 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance.Tests
95 TestHelpers.InMethod(); 112 TestHelpers.InMethod();
96// TestHelpers.EnableLogging(); 113// TestHelpers.EnableLogging();
97 114
115 string script =
116@"default
117{
118 state_entry()
119 {
120 llSay(0, ""Thin Lizzy"");
121 llSleep(60);
122 }
123}";
124
125 TestStop(script);
126 }
127
128 [Test]
129 public void TestStopOnLongSingleStatementForLoop()
130 {
131 TestHelpers.InMethod();
132// TestHelpers.EnableLogging();
133
134 string script =
135@"default
136{
137 state_entry()
138 {
139 integer i = 0;
140 llSay(0, ""Thin Lizzy"");
141
142 for (i = 0; i < 2147483647; i++)
143 llSay(0, ""Iter "" + (string)i);
144 }
145}";
146
147 TestStop(script);
148 }
149
150 [Test]
151 public void TestStopOnLongCompoundStatementForLoop()
152 {
153 TestHelpers.InMethod();
154// TestHelpers.EnableLogging();
155
156 string script =
157@"default
158{
159 state_entry()
160 {
161 integer i = 0;
162 llSay(0, ""Thin Lizzy"");
163
164 for (i = 0; i < 2147483647; i++)
165 {
166 llSay(0, ""Iter "" + (string)i);
167 }
168 }
169}";
170
171 TestStop(script);
172 }
173
174 [Test]
175 public void TestStopOnLongSingleStatementWhileLoop()
176 {
177 TestHelpers.InMethod();
178// TestHelpers.EnableLogging();
179
180 string script =
181@"default
182{
183 state_entry()
184 {
185 integer i = 0;
186 llSay(0, ""Thin Lizzy"");
187
188 while (1 == 1)
189 llSay(0, ""Iter "" + (string)i++);
190 }
191}";
192
193 TestStop(script);
194 }
195
196 [Test]
197 public void TestStopOnLongCompoundStatementWhileLoop()
198 {
199 TestHelpers.InMethod();
200// TestHelpers.EnableLogging();
201
202 string script =
203@"default
204{
205 state_entry()
206 {
207 integer i = 0;
208 llSay(0, ""Thin Lizzy"");
209
210 while (1 == 1)
211 {
212 llSay(0, ""Iter "" + (string)i++);
213 }
214 }
215}";
216
217 TestStop(script);
218 }
219
220 [Test]
221 public void TestStopOnLongDoWhileLoop()
222 {
223 TestHelpers.InMethod();
224// TestHelpers.EnableLogging();
225
226 string script =
227@"default
228{
229 state_entry()
230 {
231 integer i = 0;
232 llSay(0, ""Thin Lizzy"");
233
234 do
235 {
236 llSay(0, ""Iter "" + (string)i++);
237} while (1 == 1);
238 }
239}";
240
241 TestStop(script);
242 }
243
244 [Test]
245 public void TestStopOnInfiniteJumpLoop()
246 {
247 TestHelpers.InMethod();
248 TestHelpers.EnableLogging();
249
250 string script =
251@"default
252{
253 state_entry()
254 {
255 integer i = 0;
256 llSay(0, ""Thin Lizzy"");
257
258 @p1;
259 llSay(0, ""Iter "" + (string)i++);
260 jump p1;
261 }
262}";
263
264 TestStop(script);
265 }
266
267 [Test]
268 public void TestStopOnInfiniteUserFunctionCallLoop()
269 {
270 TestHelpers.InMethod();
271// TestHelpers.EnableLogging();
272
273 string script =
274@"
275integer i = 0;
276
277ufn1()
278{
279 llSay(0, ""Iter ufn1() "" + (string)i++);
280 ufn1();
281}
282
283default
284{
285 state_entry()
286 {
287 integer i = 0;
288 llSay(0, ""Thin Lizzy"");
289
290 ufn1();
291 }
292}";
293
294 TestStop(script);
295 }
296
297 [Test]
298 public void TestStopOnInfiniteManualEventCallLoop()
299 {
300 TestHelpers.InMethod();
301// TestHelpers.EnableLogging();
302
303 string script =
304@"default
305{
306 state_entry()
307 {
308 integer i = 0;
309 llSay(0, ""Thin Lizzy"");
310
311 llSay(0, ""Iter"" + (string)i++);
312 default_event_state_entry();
313 }
314}";
315
316 TestStop(script);
317 }
318
319 private void TestStop(string script)
320 {
98 UUID userId = TestHelpers.ParseTail(0x1); 321 UUID userId = TestHelpers.ParseTail(0x1);
99// UUID objectId = TestHelpers.ParseTail(0x100); 322// UUID objectId = TestHelpers.ParseTail(0x100);
100// UUID itemId = TestHelpers.ParseTail(0x3); 323// UUID itemId = TestHelpers.ParseTail(0x3);
101 string itemName = "TestStopOnObjectDerezLongSleep() Item"; 324 string itemName = "TestStop() Item";
102 325
103 SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, userId, "TestStopOnObjectDerezLongSleep", 0x100); 326 SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, userId, "TestStop", 0x100);
104 m_scene.AddNewSceneObject(so, true); 327 m_scene.AddNewSceneObject(so, true);
105 328
106 InventoryItemBase itemTemplate = new InventoryItemBase(); 329 InventoryItemBase itemTemplate = new InventoryItemBase();
@@ -111,15 +334,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance.Tests
111 334
112 m_scene.EventManager.OnChatFromWorld += OnChatFromWorld; 335 m_scene.EventManager.OnChatFromWorld += OnChatFromWorld;
113 336
114 SceneObjectPart partWhereRezzed = m_scene.RezNewScript(userId, itemTemplate, 337 SceneObjectPart partWhereRezzed = m_scene.RezNewScript(userId, itemTemplate, script);
115@"default
116{
117 state_entry()
118 {
119 llSay(0, ""Thin Lizzy"");
120 llSleep(60);
121 }
122}");
123 338
124 TaskInventoryItem rezzedItem = partWhereRezzed.Inventory.GetInventoryItem(itemName); 339 TaskInventoryItem rezzedItem = partWhereRezzed.Inventory.GetInventoryItem(itemName);
125 340
@@ -129,7 +344,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance.Tests
129 Console.WriteLine("Script started with message [{0}]", m_osChatMessageReceived.Message); 344 Console.WriteLine("Script started with message [{0}]", m_osChatMessageReceived.Message);
130 345
131 // FIXME: This is a very poor way of trying to avoid a low-probability race condition where the script 346 // FIXME: This is a very poor way of trying to avoid a low-probability race condition where the script
132 // executes llSay() but has not started the sleep before we try to stop it. 347 // executes llSay() but has not started the next statement before we try to stop it.
133 Thread.Sleep(1000); 348 Thread.Sleep(1000);
134 349
135 // We need a way of carrying on if StopScript() fail, since it won't return if the script isn't actually 350 // We need a way of carrying on if StopScript() fail, since it won't return if the script isn't actually
@@ -148,7 +363,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance.Tests
148 363
149 private void OnChatFromWorld(object sender, OSChatMessage oscm) 364 private void OnChatFromWorld(object sender, OSChatMessage oscm)
150 { 365 {
151// Console.WriteLine("Got chat [{0}]", oscm.Message); 366 m_scene.EventManager.OnChatFromWorld -= OnChatFromWorld;
367 Console.WriteLine("Got chat [{0}]", oscm.Message);
152 368
153 m_osChatMessageReceived = oscm; 369 m_osChatMessageReceived = oscm;
154 m_chatEvent.Set(); 370 m_chatEvent.Set();
diff --git a/OpenSim/Region/ScriptEngine/XEngine/Api/Runtime/XEngineScriptBase.cs b/OpenSim/Region/ScriptEngine/XEngine/Api/Runtime/XEngineScriptBase.cs
new file mode 100644
index 0000000..f4211c8
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/XEngine/Api/Runtime/XEngineScriptBase.cs
@@ -0,0 +1,61 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Runtime.Remoting;
30using System.Runtime.Remoting.Lifetime;
31using System.Security.Permissions;
32using System.Threading;
33using System.Reflection;
34using System.Collections;
35using System.Collections.Generic;
36using OpenSim.Region.ScriptEngine.Interfaces;
37using OpenSim.Region.ScriptEngine.Shared;
38using OpenSim.Region.ScriptEngine.Shared.ScriptBase;
39
40namespace OpenSim.Region.ScriptEngine.XEngine.ScriptBase
41{
42 public class XEngineScriptBase : ScriptBaseClass
43 {
44 /// <summary>
45 /// Used for script sleeps when we are using co-operative script termination.
46 /// </summary>
47 /// <remarks>null if co-operative script termination is not active</remarks>
48 WaitHandle m_coopSleepHandle;
49
50 public XEngineScriptBase(WaitHandle coopSleepHandle) : base()
51 {
52 m_coopSleepHandle = coopSleepHandle;
53 }
54
55 public void opensim_reserved_CheckForCoopTermination()
56 {
57 if (m_coopSleepHandle != null && m_coopSleepHandle.WaitOne(0))
58 throw new ScriptCoopStopException();
59 }
60 }
61} \ No newline at end of file
diff --git a/OpenSim/Region/ScriptEngine/XEngine/EventManager.cs b/OpenSim/Region/ScriptEngine/XEngine/EventManager.cs
index 9405075..afde685 100644
--- a/OpenSim/Region/ScriptEngine/XEngine/EventManager.cs
+++ b/OpenSim/Region/ScriptEngine/XEngine/EventManager.cs
@@ -52,7 +52,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
52 { 52 {
53 myScriptEngine = _ScriptEngine; 53 myScriptEngine = _ScriptEngine;
54 54
55 m_log.Info("[XEngine] Hooking up to server events"); 55// m_log.Info("[XEngine] Hooking up to server events");
56 myScriptEngine.World.EventManager.OnAttach += attach; 56 myScriptEngine.World.EventManager.OnAttach += attach;
57 myScriptEngine.World.EventManager.OnObjectGrab += touch_start; 57 myScriptEngine.World.EventManager.OnObjectGrab += touch_start;
58 myScriptEngine.World.EventManager.OnObjectGrabbing += touch; 58 myScriptEngine.World.EventManager.OnObjectGrabbing += touch;
@@ -69,7 +69,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
69 myScriptEngine.World.EventManager.OnScriptLandColliderStart += land_collision_start; 69 myScriptEngine.World.EventManager.OnScriptLandColliderStart += land_collision_start;
70 myScriptEngine.World.EventManager.OnScriptLandColliding += land_collision; 70 myScriptEngine.World.EventManager.OnScriptLandColliding += land_collision;
71 myScriptEngine.World.EventManager.OnScriptLandColliderEnd += land_collision_end; 71 myScriptEngine.World.EventManager.OnScriptLandColliderEnd += land_collision_end;
72 IMoneyModule money=myScriptEngine.World.RequestModuleInterface<IMoneyModule>(); 72 IMoneyModule money = myScriptEngine.World.RequestModuleInterface<IMoneyModule>();
73 if (money != null) 73 if (money != null)
74 { 74 {
75 money.OnObjectPaid+=HandleObjectPaid; 75 money.OnObjectPaid+=HandleObjectPaid;
diff --git a/OpenSim/Region/ScriptEngine/XEngine/Tests/XEngineTest.cs b/OpenSim/Region/ScriptEngine/XEngine/Tests/XEngineBasicTests.cs
index 5abfe9a..5abfe9a 100644
--- a/OpenSim/Region/ScriptEngine/XEngine/Tests/XEngineTest.cs
+++ b/OpenSim/Region/ScriptEngine/XEngine/Tests/XEngineBasicTests.cs
diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
index 816d8ba..6e04e79 100644
--- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
+++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
@@ -47,13 +47,15 @@ using OpenSim.Framework;
47using OpenSim.Framework.Console; 47using OpenSim.Framework.Console;
48using OpenSim.Region.Framework.Scenes; 48using OpenSim.Region.Framework.Scenes;
49using OpenSim.Region.Framework.Interfaces; 49using OpenSim.Region.Framework.Interfaces;
50using OpenSim.Region.ScriptEngine.Interfaces;
50using OpenSim.Region.ScriptEngine.Shared; 51using OpenSim.Region.ScriptEngine.Shared;
51using OpenSim.Region.ScriptEngine.Shared.ScriptBase; 52using OpenSim.Region.ScriptEngine.Shared.ScriptBase;
52using OpenSim.Region.ScriptEngine.Shared.CodeTools; 53using OpenSim.Region.ScriptEngine.Shared.CodeTools;
53using OpenSim.Region.ScriptEngine.Shared.Instance; 54using OpenSim.Region.ScriptEngine.Shared.Instance;
54using OpenSim.Region.ScriptEngine.Shared.Api; 55using OpenSim.Region.ScriptEngine.Shared.Api;
55using OpenSim.Region.ScriptEngine.Shared.Api.Plugins; 56using OpenSim.Region.ScriptEngine.Shared.Api.Plugins;
56using OpenSim.Region.ScriptEngine.Interfaces; 57using OpenSim.Region.ScriptEngine.Shared.ScriptBase;
58using OpenSim.Region.ScriptEngine.XEngine.ScriptBase;
57using Timer = OpenSim.Region.ScriptEngine.Shared.Api.Plugins.Timer; 59using Timer = OpenSim.Region.ScriptEngine.Shared.Api.Plugins.Timer;
58 60
59using ScriptCompileQueue = OpenSim.Framework.LocklessQueue<object[]>; 61using ScriptCompileQueue = OpenSim.Framework.LocklessQueue<object[]>;
@@ -244,6 +246,14 @@ namespace OpenSim.Region.ScriptEngine.XEngine
244 get { return "XEngine"; } 246 get { return "XEngine"; }
245 } 247 }
246 248
249 public string ScriptClassName { get; private set; }
250
251 public string ScriptBaseClassName { get; private set; }
252
253 public ParameterInfo[] ScriptBaseClassParameters { get; private set; }
254
255 public string[] ScriptReferencedAssemblies { get; private set; }
256
247 public Scene World 257 public Scene World
248 { 258 {
249 get { return m_Scene; } 259 get { return m_Scene; }
@@ -298,21 +308,35 @@ namespace OpenSim.Region.ScriptEngine.XEngine
298 308
299 m_ScriptConfig = configSource.Configs["XEngine"]; 309 m_ScriptConfig = configSource.Configs["XEngine"];
300 m_ConfigSource = configSource; 310 m_ConfigSource = configSource;
311
312 string rawScriptStopStrategy = m_ScriptConfig.GetString("ScriptStopStrategy", "abort");
313
314 m_log.InfoFormat("[XEngine]: Script stop strategy is {0}", rawScriptStopStrategy);
315
316 if (rawScriptStopStrategy == "co-op")
317 {
318 ScriptClassName = "XEngineScript";
319 ScriptBaseClassName = typeof(XEngineScriptBase).FullName;
320 ScriptBaseClassParameters = typeof(XEngineScriptBase).GetConstructor(new Type[] { typeof(WaitHandle) }).GetParameters();
321 ScriptReferencedAssemblies = new string[] { Path.GetFileName(typeof(XEngineScriptBase).Assembly.Location) };
322 }
323 else
324 {
325 ScriptClassName = "Script";
326 ScriptBaseClassName = typeof(ScriptBaseClass).FullName;
327 }
328
329// Console.WriteLine("ASSEMBLY NAME: {0}", ScriptReferencedAssemblies[0]);
301 } 330 }
302 331
303 public void AddRegion(Scene scene) 332 public void AddRegion(Scene scene)
304 { 333 {
305 if (m_ScriptConfig == null) 334 if (m_ScriptConfig == null)
306 return; 335 return;
336
307 m_ScriptFailCount = 0; 337 m_ScriptFailCount = 0;
308 m_ScriptErrorMessage = String.Empty; 338 m_ScriptErrorMessage = String.Empty;
309 339
310 if (m_ScriptConfig == null)
311 {
312// m_log.ErrorFormat("[XEngine] No script configuration found. Scripts disabled");
313 return;
314 }
315
316 m_Enabled = m_ScriptConfig.GetBoolean("Enabled", true); 340 m_Enabled = m_ScriptConfig.GetBoolean("Enabled", true);
317 341
318 if (!m_Enabled) 342 if (!m_Enabled)
@@ -1180,7 +1204,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1180 } 1204 }
1181 1205
1182 m_log.DebugFormat( 1206 m_log.DebugFormat(
1183 "[XEngine] Loading script {0}.{1}, item UUID {2}, prim UUID {3} @ {4}.{5}", 1207 "[XEngine]: Loading script {0}.{1}, item UUID {2}, prim UUID {3} @ {4}.{5}",
1184 part.ParentGroup.RootPart.Name, item.Name, itemID, part.UUID, 1208 part.ParentGroup.RootPart.Name, item.Name, itemID, part.UUID,
1185 part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName); 1209 part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName);
1186 1210
@@ -1201,6 +1225,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1201 lock (m_AddingAssemblies) 1225 lock (m_AddingAssemblies)
1202 { 1226 {
1203 m_Compiler.PerformScriptCompile(script, assetID.ToString(), item.OwnerID, out assembly, out linemap); 1227 m_Compiler.PerformScriptCompile(script, assetID.ToString(), item.OwnerID, out assembly, out linemap);
1228
1204 if (!m_AddingAssemblies.ContainsKey(assembly)) { 1229 if (!m_AddingAssemblies.ContainsKey(assembly)) {
1205 m_AddingAssemblies[assembly] = 1; 1230 m_AddingAssemblies[assembly] = 1;
1206 } else { 1231 } else {
@@ -1250,7 +1275,9 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1250 } 1275 }
1251 catch (Exception e) 1276 catch (Exception e)
1252 { 1277 {
1253// m_log.ErrorFormat("[XEngine]: Exception when rezzing script {0}{1}", e.Message, e.StackTrace); 1278// m_log.ErrorFormat(
1279// "[XEngine]: Exception when rezzing script with item ID {0}, {1}{2}",
1280// itemID, e.Message, e.StackTrace);
1254 1281
1255 // try 1282 // try
1256 // { 1283 // {
@@ -1329,13 +1356,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1329 sandbox = AppDomain.CurrentDomain; 1356 sandbox = AppDomain.CurrentDomain;
1330 } 1357 }
1331 1358
1332 //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel(); 1359 if (!instance.Load(m_AppDomains[appDomain], assembly, stateSource))
1333 //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition(); 1360 return false;
1334 //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet");
1335 //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet);
1336 //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement);
1337 //sandboxPolicy.RootCodeGroup = sandboxCodeGroup;
1338 //sandbox.SetAppDomainPolicy(sandboxPolicy);
1339 1361
1340 m_AppDomains[appDomain] = sandbox; 1362 m_AppDomains[appDomain] = sandbox;
1341 1363