diff --git a/.gitignore b/.gitignore
index af7e18beae..dc4087e488 100644
--- a/.gitignore
+++ b/.gitignore
@@ -33,6 +33,10 @@ bin/*.db-journal
bin/addin-db-*
bin/*.dll
bin/OpenSim.vshost.exe.config
+bin/OpenSim.32BitLaunch.vshost.exe.config
+bin/OpenSim.32BitLaunch.log
+UpgradeLog.XML
+_UpgradeReport_Files/
bin/ScriptEngines/*-*-*-*-*
bin/ScriptEngines/*.dll
bin/ScriptEngines/*/*.dll
diff --git a/OpenSim/Data/IXInventoryData.cs b/OpenSim/Data/IXInventoryData.cs
index 85a5c08d37..e64a82820d 100644
--- a/OpenSim/Data/IXInventoryData.cs
+++ b/OpenSim/Data/IXInventoryData.cs
@@ -40,6 +40,11 @@ namespace OpenSim.Data
public UUID folderID;
public UUID agentID;
public UUID parentFolderID;
+
+ public XInventoryFolder Clone()
+ {
+ return (XInventoryFolder)MemberwiseClone();
+ }
}
public class XInventoryItem
@@ -64,6 +69,11 @@ namespace OpenSim.Data
public UUID avatarID;
public UUID parentFolderID;
public int inventoryGroupPermissions;
+
+ public XInventoryItem Clone()
+ {
+ return (XInventoryItem)MemberwiseClone();
+ }
}
public interface IXInventoryData
diff --git a/OpenSim/Framework/InventoryFolderBase.cs b/OpenSim/Framework/InventoryFolderBase.cs
index a12183c535..b3457a65b9 100644
--- a/OpenSim/Framework/InventoryFolderBase.cs
+++ b/OpenSim/Framework/InventoryFolderBase.cs
@@ -73,33 +73,27 @@ namespace OpenSim.Framework
{
}
- public InventoryFolderBase(UUID id)
+ public InventoryFolderBase(UUID id) : this()
{
ID = id;
}
- public InventoryFolderBase(UUID id, UUID owner)
+ public InventoryFolderBase(UUID id, UUID owner) : this(id)
{
- ID = id;
Owner = owner;
}
- public InventoryFolderBase(UUID id, string name, UUID owner, UUID parent)
+ public InventoryFolderBase(UUID id, string name, UUID owner, UUID parent) : this(id, owner)
{
- ID = id;
Name = name;
- Owner = owner;
ParentID = parent;
}
- public InventoryFolderBase(UUID id, string name, UUID owner, short type, UUID parent, ushort version)
+ public InventoryFolderBase(
+ UUID id, string name, UUID owner, short type, UUID parent, ushort version) : this(id, name, owner, parent)
{
- ID = id;
- Name = name;
- Owner = owner;
Type = type;
- ParentID = parent;
Version = version;
}
}
-}
+}
\ No newline at end of file
diff --git a/OpenSim/Framework/Serialization/External/OspResolver.cs b/OpenSim/Framework/Serialization/External/OspResolver.cs
index d31d27c4a6..fa7160f874 100644
--- a/OpenSim/Framework/Serialization/External/OspResolver.cs
+++ b/OpenSim/Framework/Serialization/External/OspResolver.cs
@@ -65,9 +65,14 @@ namespace OpenSim.Framework.Serialization
UserAccount account = userService.GetUserAccount(UUID.Zero, userId);
if (account != null)
+ {
return MakeOspa(account.FirstName, account.LastName);
+ }
// else
+// {
// m_log.WarnFormat("[OSP RESOLVER]: No user account for {0}", userId);
+// System.Console.WriteLine("[OSP RESOLVER]: No user account for {0}", userId);
+// }
return null;
}
@@ -79,10 +84,13 @@ namespace OpenSim.Framework.Serialization
///
public static string MakeOspa(string firstName, string lastName)
{
-// m_log.DebugFormat("[OSP RESOLVER]: Making OSPA for {0} {1}", firstName, lastName);
+ string ospa
+ = OSPA_PREFIX + OSPA_NAME_KEY + OSPA_PAIR_SEPARATOR + firstName + OSPA_NAME_VALUE_SEPARATOR + lastName;
+
+// m_log.DebugFormat("[OSP RESOLVER]: Made OSPA {0} for {1} {2}", ospa, firstName, lastName);
+// System.Console.WriteLine("[OSP RESOLVER]: Made OSPA {0} for {1} {2}", ospa, firstName, lastName);
- return
- OSPA_PREFIX + OSPA_NAME_KEY + OSPA_PAIR_SEPARATOR + firstName + OSPA_NAME_VALUE_SEPARATOR + lastName;
+ return ospa;
}
///
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs
index b112b6db52..12a05b3df5 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs
@@ -350,38 +350,38 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
Assert.That(sog1.RootPart.CreatorID, Is.EqualTo(m_uaLL1.PrincipalID));
}
- ///
- /// Test loading a V0.1 OpenSim Inventory Archive (subject to change since there is no fixed format yet) where
- /// an account exists with the same name as the creator, though not the same id.
- ///
- [Test]
- public void TestLoadIarV0_1SameNameCreator()
- {
- TestHelpers.InMethod();
-// log4net.Config.XmlConfigurator.Configure();
-
- UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaMT, "meowfood");
- UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaLL2, "hampshire");
-
- m_archiverModule.DearchiveInventory(m_uaMT.FirstName, m_uaMT.LastName, "/", "meowfood", m_iarStream);
- InventoryItemBase foundItem1
- = InventoryArchiveUtils.FindItemByPath(m_scene.InventoryService, m_uaMT.PrincipalID, m_item1Name);
-
- Assert.That(
- foundItem1.CreatorId, Is.EqualTo(m_uaLL2.PrincipalID.ToString()),
- "Loaded item non-uuid creator doesn't match original");
- Assert.That(
- foundItem1.CreatorIdAsUuid, Is.EqualTo(m_uaLL2.PrincipalID),
- "Loaded item uuid creator doesn't match original");
- Assert.That(foundItem1.Owner, Is.EqualTo(m_uaMT.PrincipalID),
- "Loaded item owner doesn't match inventory reciever");
-
- AssetBase asset1 = m_scene.AssetService.Get(foundItem1.AssetID.ToString());
- string xmlData = Utils.BytesToString(asset1.Data);
- SceneObjectGroup sog1 = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
-
- Assert.That(sog1.RootPart.CreatorID, Is.EqualTo(m_uaLL2.PrincipalID));
- }
+// ///
+// /// Test loading a V0.1 OpenSim Inventory Archive (subject to change since there is no fixed format yet) where
+// /// an account exists with the same name as the creator, though not the same id.
+// ///
+// [Test]
+// public void TestLoadIarV0_1SameNameCreator()
+// {
+// TestHelpers.InMethod();
+// TestHelpers.EnableLogging();
+//
+// UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaMT, "meowfood");
+// UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaLL2, "hampshire");
+//
+// m_archiverModule.DearchiveInventory(m_uaMT.FirstName, m_uaMT.LastName, "/", "meowfood", m_iarStream);
+// InventoryItemBase foundItem1
+// = InventoryArchiveUtils.FindItemByPath(m_scene.InventoryService, m_uaMT.PrincipalID, m_item1Name);
+//
+// Assert.That(
+// foundItem1.CreatorId, Is.EqualTo(m_uaLL2.PrincipalID.ToString()),
+// "Loaded item non-uuid creator doesn't match original");
+// Assert.That(
+// foundItem1.CreatorIdAsUuid, Is.EqualTo(m_uaLL2.PrincipalID),
+// "Loaded item uuid creator doesn't match original");
+// Assert.That(foundItem1.Owner, Is.EqualTo(m_uaMT.PrincipalID),
+// "Loaded item owner doesn't match inventory reciever");
+//
+// AssetBase asset1 = m_scene.AssetService.Get(foundItem1.AssetID.ToString());
+// string xmlData = Utils.BytesToString(asset1.Data);
+// SceneObjectGroup sog1 = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
+//
+// Assert.That(sog1.RootPart.CreatorID, Is.EqualTo(m_uaLL2.PrincipalID));
+// }
///
/// Test loading a V0.1 OpenSim Inventory Archive (subject to change since there is no fixed format yet) where
diff --git a/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs b/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs
index 18bd0186b8..13b74983b1 100644
--- a/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs
+++ b/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs
@@ -49,6 +49,11 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
public const int DISP_EXPIRE = 1;
public const int DISP_TEMP = 2;
+ ///
+ /// If true then where possible dynamic textures are reused.
+ ///
+ public bool ReuseTextures { get; set; }
+
private Dictionary RegisteredScenes = new Dictionary();
private Dictionary RenderPlugins =
@@ -56,6 +61,15 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
private Dictionary Updaters = new Dictionary();
+ ///
+ /// Record dynamic textures that we can reuse for a given data and parameter combination rather than
+ /// regenerate.
+ ///
+ ///
+ /// Key is string.Format("{0}{1}", data
+ ///
+ private Cache m_reuseableDynamicTextures;
+
#region IDynamicTextureManager Members
public void RegisterRender(string handleType, IDynamicTextureRender render)
@@ -71,7 +85,8 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
///
///
///
- public void ReturnData(UUID id, byte[] data)
+ /// True if the data generated can be reused for subsequent identical requests
+ public void ReturnData(UUID id, byte[] data, bool isReuseable)
{
DynamicTextureUpdater updater = null;
@@ -88,7 +103,11 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
if (RegisteredScenes.ContainsKey(updater.SimUUID))
{
Scene scene = RegisteredScenes[updater.SimUUID];
- updater.DataReceived(data, scene);
+ UUID newTextureID = updater.DataReceived(data, scene);
+
+ if (ReuseTextures && isReuseable && !updater.BlendWithOldTexture)
+ m_reuseableDynamicTextures.Store(
+ GenerateReusableTextureKey(updater.BodyData, updater.Params), newTextureID);
}
}
@@ -169,6 +188,11 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
{
if (RenderPlugins.ContainsKey(contentType))
{
+ // If we want to reuse dynamic textures then we have to ignore any request from the caller to expire
+ // them.
+ if (ReuseTextures)
+ disp = disp & ~DISP_EXPIRE;
+
DynamicTextureUpdater updater = new DynamicTextureUpdater();
updater.SimUUID = simID;
updater.PrimID = primID;
@@ -183,21 +207,49 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
updater.Url = "Local image";
updater.Disp = disp;
- lock (Updaters)
+ object reusableTextureUUID = null;
+
+ if (ReuseTextures)
+ reusableTextureUUID
+ = m_reuseableDynamicTextures.Get(GenerateReusableTextureKey(data, extraParams));
+
+ // We cannot reuse a dynamic texture if the data is going to be blended with something already there.
+ if (reusableTextureUUID == null || updater.BlendWithOldTexture)
{
- if (!Updaters.ContainsKey(updater.UpdaterID))
+ lock (Updaters)
{
- Updaters.Add(updater.UpdaterID, updater);
+ if (!Updaters.ContainsKey(updater.UpdaterID))
+ {
+ Updaters.Add(updater.UpdaterID, updater);
+ }
+ }
+
+ RenderPlugins[contentType].AsyncConvertData(updater.UpdaterID, data, extraParams);
+ }
+ else
+ {
+ // No need to add to updaters as the texture is always the same. Not that this functionality
+ // apppears to be implemented anyway.
+ if (RegisteredScenes.ContainsKey(updater.SimUUID))
+ {
+ SceneObjectPart part = RegisteredScenes[updater.SimUUID].GetSceneObjectPart(updater.PrimID);
+
+ if (part != null)
+ updater.UpdatePart(part, (UUID)reusableTextureUUID);
}
}
- RenderPlugins[contentType].AsyncConvertData(updater.UpdaterID, data, extraParams);
return updater.UpdaterID;
}
return UUID.Zero;
}
+ private string GenerateReusableTextureKey(string data, string extraParams)
+ {
+ return string.Format("{0}{1}", data, extraParams);
+ }
+
public void GetDrawStringSize(string contentType, string text, string fontName, int fontSize,
out double xSize, out double ySize)
{
@@ -224,6 +276,12 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
public void PostInitialise()
{
+// ReuseTextures = true;
+ if (ReuseTextures)
+ {
+ m_reuseableDynamicTextures = new Cache(CacheMedium.Memory, CacheStrategy.Conservative);
+ m_reuseableDynamicTextures.DefaultTTL = new TimeSpan(24, 0, 0);
+ }
}
public void Close()
@@ -268,10 +326,61 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
BodyData = null;
}
+ ///
+ /// Update the given part with the new texture.
+ ///
+ ///
+ /// The old texture UUID.
+ ///
+ public UUID UpdatePart(SceneObjectPart part, UUID textureID)
+ {
+ UUID oldID;
+
+ lock (part)
+ {
+ // mostly keep the values from before
+ Primitive.TextureEntry tmptex = part.Shape.Textures;
+
+ // FIXME: Need to return the appropriate ID if only a single face is replaced.
+ oldID = tmptex.DefaultTexture.TextureID;
+
+ if (Face == ALL_SIDES)
+ {
+ oldID = tmptex.DefaultTexture.TextureID;
+ tmptex.DefaultTexture.TextureID = textureID;
+ }
+ else
+ {
+ try
+ {
+ Primitive.TextureEntryFace texface = tmptex.CreateFace((uint)Face);
+ texface.TextureID = textureID;
+ tmptex.FaceTextures[Face] = texface;
+ }
+ catch (Exception)
+ {
+ tmptex.DefaultTexture.TextureID = textureID;
+ }
+ }
+
+ // I'm pretty sure we always want to force this to true
+ // I'm pretty sure noone whats to set fullbright true if it wasn't true before.
+ // tmptex.DefaultTexture.Fullbright = true;
+
+ part.UpdateTextureEntry(tmptex.GetBytes());
+ }
+
+ return oldID;
+ }
+
///
/// Called once new texture data has been received for this updater.
///
- public void DataReceived(byte[] data, Scene scene)
+ ///
+ ///
+ /// True if the data given is reuseable.
+ /// The asset UUID given to the incoming data.
+ public UUID DataReceived(byte[] data, Scene scene)
{
SceneObjectPart part = scene.GetSceneObjectPart(PrimID);
@@ -281,7 +390,8 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
String.Format("DynamicTextureModule: Error preparing image using URL {0}", Url);
scene.SimChat(Utils.StringToBytes(msg), ChatTypeEnum.Say,
0, part.ParentGroup.RootPart.AbsolutePosition, part.Name, part.UUID, false);
- return;
+
+ return UUID.Zero;
}
byte[] assetData = null;
@@ -323,52 +433,23 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
cacheLayerDecode = null;
}
- UUID oldID = UUID.Zero;
-
- lock (part)
- {
- // mostly keep the values from before
- Primitive.TextureEntry tmptex = part.Shape.Textures;
-
- // remove the old asset from the cache
- oldID = tmptex.DefaultTexture.TextureID;
-
- if (Face == ALL_SIDES)
- {
- tmptex.DefaultTexture.TextureID = asset.FullID;
- }
- else
- {
- try
- {
- Primitive.TextureEntryFace texface = tmptex.CreateFace((uint)Face);
- texface.TextureID = asset.FullID;
- tmptex.FaceTextures[Face] = texface;
- }
- catch (Exception)
- {
- tmptex.DefaultTexture.TextureID = asset.FullID;
- }
- }
-
- // I'm pretty sure we always want to force this to true
- // I'm pretty sure noone whats to set fullbright true if it wasn't true before.
- // tmptex.DefaultTexture.Fullbright = true;
-
- part.UpdateTextureEntry(tmptex.GetBytes());
- }
+ UUID oldID = UpdatePart(part, asset.FullID);
if (oldID != UUID.Zero && ((Disp & DISP_EXPIRE) != 0))
{
- if (oldAsset == null) oldAsset = scene.AssetService.Get(oldID.ToString());
+ if (oldAsset == null)
+ oldAsset = scene.AssetService.Get(oldID.ToString());
+
if (oldAsset != null)
{
- if (oldAsset.Temporary == true)
+ if (oldAsset.Temporary)
{
scene.AssetService.Delete(oldID.ToString());
}
}
}
+
+ return asset.FullID;
}
private byte[] BlendTextures(byte[] frontImage, byte[] backImage, bool setNewAlpha, byte newAlpha)
diff --git a/OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs b/OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs
index 6f839485ec..2b3a0f29ff 100644
--- a/OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs
+++ b/OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs
@@ -67,12 +67,18 @@ namespace OpenSim.Region.CoreModules.Scripting.LoadImageURL
return true;
}
+// public bool AlwaysIdenticalConversion(string bodyData, string extraParams)
+// {
+// // We don't support conversion of body data.
+// return false;
+// }
+
public byte[] ConvertUrl(string url, string extraParams)
{
return null;
}
- public byte[] ConvertStream(Stream data, string extraParams)
+ public byte[] ConvertData(string bodyData, string extraParams)
{
return null;
}
@@ -236,9 +242,11 @@ namespace OpenSim.Region.CoreModules.Scripting.LoadImageURL
stream.Close();
}
}
+
m_log.DebugFormat("[LOADIMAGEURLMODULE] Returning {0} bytes of image data for request {1}",
imageJ2000.Length, state.RequestID);
- m_textureManager.ReturnData(state.RequestID, imageJ2000);
+
+ m_textureManager.ReturnData(state.RequestID, imageJ2000, false);
}
#region Nested type: RequestState
diff --git a/OpenSim/Region/CoreModules/Scripting/VectorRender/Tests/VectorRenderModuleTests.cs b/OpenSim/Region/CoreModules/Scripting/VectorRender/Tests/VectorRenderModuleTests.cs
index 9787c8c173..b50c0bd7cd 100644
--- a/OpenSim/Region/CoreModules/Scripting/VectorRender/Tests/VectorRenderModuleTests.cs
+++ b/OpenSim/Region/CoreModules/Scripting/VectorRender/Tests/VectorRenderModuleTests.cs
@@ -45,31 +45,250 @@ using OpenSim.Tests.Common.Mock;
namespace OpenSim.Region.CoreModules.Scripting.VectorRender.Tests
{
[TestFixture]
- public class VectorRenderModuleTests
+ public class VectorRenderModuleTests : OpenSimTestCase
{
+ Scene m_scene;
+ DynamicTextureModule m_dtm;
+ VectorRenderModule m_vrm;
+
+ private void SetupScene(bool reuseTextures)
+ {
+ m_scene = new SceneHelpers().SetupScene();
+
+ m_dtm = new DynamicTextureModule();
+ m_dtm.ReuseTextures = reuseTextures;
+
+ m_vrm = new VectorRenderModule();
+
+ SceneHelpers.SetupSceneModules(m_scene, m_dtm, m_vrm);
+ }
+
[Test]
public void TestDraw()
{
TestHelpers.InMethod();
- Scene scene = new SceneHelpers().SetupScene();
- DynamicTextureModule dtm = new DynamicTextureModule();
- VectorRenderModule vrm = new VectorRenderModule();
- SceneHelpers.SetupSceneModules(scene, dtm, vrm);
-
- SceneObjectGroup so = SceneHelpers.AddSceneObject(scene);
+ SetupScene(false);
+ SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene);
UUID originalTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID;
- dtm.AddDynamicTextureData(
- scene.RegionInfo.RegionID,
+ m_dtm.AddDynamicTextureData(
+ m_scene.RegionInfo.RegionID,
so.UUID,
- vrm.GetContentType(),
+ m_vrm.GetContentType(),
"PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World;",
"",
0);
+ Assert.That(originalTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID));
+ }
+
+ [Test]
+ public void TestRepeatSameDraw()
+ {
+ TestHelpers.InMethod();
+
+ string dtText = "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World;";
+
+ SetupScene(false);
+ SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene);
+
+ m_dtm.AddDynamicTextureData(
+ m_scene.RegionInfo.RegionID,
+ so.UUID,
+ m_vrm.GetContentType(),
+ dtText,
+ "",
+ 0);
+
+ UUID firstDynamicTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID;
+
+ m_dtm.AddDynamicTextureData(
+ m_scene.RegionInfo.RegionID,
+ so.UUID,
+ m_vrm.GetContentType(),
+ dtText,
+ "",
+ 0);
+
+ Assert.That(firstDynamicTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID));
+ }
+
+ [Test]
+ public void TestRepeatSameDrawDifferentExtraParams()
+ {
+ TestHelpers.InMethod();
+
+ string dtText = "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World;";
+
+ SetupScene(false);
+ SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene);
+
+ m_dtm.AddDynamicTextureData(
+ m_scene.RegionInfo.RegionID,
+ so.UUID,
+ m_vrm.GetContentType(),
+ dtText,
+ "",
+ 0);
+
+ UUID firstDynamicTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID;
+
+ m_dtm.AddDynamicTextureData(
+ m_scene.RegionInfo.RegionID,
+ so.UUID,
+ m_vrm.GetContentType(),
+ dtText,
+ "alpha:250",
+ 0);
+
+ Assert.That(firstDynamicTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID));
+ }
+
+ [Test]
+ public void TestRepeatSameDrawContainingImage()
+ {
+ TestHelpers.InMethod();
+
+ string dtText
+ = "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World; Image http://localhost/shouldnotexist.png";
+
+ SetupScene(false);
+ SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene);
+
+ m_dtm.AddDynamicTextureData(
+ m_scene.RegionInfo.RegionID,
+ so.UUID,
+ m_vrm.GetContentType(),
+ dtText,
+ "",
+ 0);
+
+ UUID firstDynamicTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID;
+
+ m_dtm.AddDynamicTextureData(
+ m_scene.RegionInfo.RegionID,
+ so.UUID,
+ m_vrm.GetContentType(),
+ dtText,
+ "",
+ 0);
+
+ Assert.That(firstDynamicTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID));
+ }
+
+ [Test]
+ public void TestDrawReusingTexture()
+ {
+ TestHelpers.InMethod();
+
+ SetupScene(true);
+ SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene);
+ UUID originalTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID;
+
+ m_dtm.AddDynamicTextureData(
+ m_scene.RegionInfo.RegionID,
+ so.UUID,
+ m_vrm.GetContentType(),
+ "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World;",
+ "",
+ 0);
Assert.That(originalTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID));
}
+
+ [Test]
+ public void TestRepeatSameDrawReusingTexture()
+ {
+ TestHelpers.InMethod();
+
+ string dtText = "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World;";
+
+ SetupScene(true);
+ SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene);
+
+ m_dtm.AddDynamicTextureData(
+ m_scene.RegionInfo.RegionID,
+ so.UUID,
+ m_vrm.GetContentType(),
+ dtText,
+ "",
+ 0);
+
+ UUID firstDynamicTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID;
+
+ m_dtm.AddDynamicTextureData(
+ m_scene.RegionInfo.RegionID,
+ so.UUID,
+ m_vrm.GetContentType(),
+ dtText,
+ "",
+ 0);
+
+ Assert.That(firstDynamicTextureID, Is.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID));
+ }
+
+ [Test]
+ public void TestRepeatSameDrawDifferentExtraParamsReusingTexture()
+ {
+ TestHelpers.InMethod();
+
+ string dtText = "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World;";
+
+ SetupScene(true);
+ SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene);
+
+ m_dtm.AddDynamicTextureData(
+ m_scene.RegionInfo.RegionID,
+ so.UUID,
+ m_vrm.GetContentType(),
+ dtText,
+ "",
+ 0);
+
+ UUID firstDynamicTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID;
+
+ m_dtm.AddDynamicTextureData(
+ m_scene.RegionInfo.RegionID,
+ so.UUID,
+ m_vrm.GetContentType(),
+ dtText,
+ "alpha:250",
+ 0);
+
+ Assert.That(firstDynamicTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID));
+ }
+
+ [Test]
+ public void TestRepeatSameDrawContainingImageReusingTexture()
+ {
+ TestHelpers.InMethod();
+
+ string dtText
+ = "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World; Image http://localhost/shouldnotexist.png";
+
+ SetupScene(true);
+ SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene);
+
+ m_dtm.AddDynamicTextureData(
+ m_scene.RegionInfo.RegionID,
+ so.UUID,
+ m_vrm.GetContentType(),
+ dtText,
+ "",
+ 0);
+
+ UUID firstDynamicTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID;
+
+ m_dtm.AddDynamicTextureData(
+ m_scene.RegionInfo.RegionID,
+ so.UUID,
+ m_vrm.GetContentType(),
+ dtText,
+ "",
+ 0);
+
+ Assert.That(firstDynamicTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID));
+ }
}
}
\ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs b/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs
index 05eaaeceb0..f687646e76 100644
--- a/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs
+++ b/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs
@@ -30,6 +30,7 @@ using System.Drawing;
using System.Drawing.Imaging;
using System.Globalization;
using System.IO;
+using System.Linq;
using System.Net;
using Nini.Config;
using OpenMetaverse;
@@ -47,7 +48,6 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
- private string m_name = "VectorRenderModule";
private Scene m_scene;
private IDynamicTextureManager m_textureManager;
private Graphics m_graph;
@@ -61,12 +61,12 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
public string GetContentType()
{
- return ("vector");
+ return "vector";
}
public string GetName()
{
- return m_name;
+ return Name;
}
public bool SupportsAsynchronous()
@@ -74,14 +74,26 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
return true;
}
+// public bool AlwaysIdenticalConversion(string bodyData, string extraParams)
+// {
+// string[] lines = GetLines(bodyData);
+// return lines.Any((str, r) => str.StartsWith("Image"));
+// }
+
public byte[] ConvertUrl(string url, string extraParams)
{
return null;
}
- public byte[] ConvertStream(Stream data, string extraParams)
+ public byte[] ConvertData(string bodyData, string extraParams)
{
- return null;
+ bool reuseable;
+ return Draw(bodyData, extraParams, out reuseable);
+ }
+
+ private byte[] ConvertData(string bodyData, string extraParams, out bool reuseable)
+ {
+ return Draw(bodyData, extraParams, out reuseable);
}
public bool AsyncConvertUrl(UUID id, string url, string extraParams)
@@ -91,7 +103,12 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
public bool AsyncConvertData(UUID id, string bodyData, string extraParams)
{
- Draw(bodyData, id, extraParams);
+ // XXX: This isn't actually being done asynchronously!
+ bool reuseable;
+ byte[] data = ConvertData(bodyData, extraParams, out reuseable);
+
+ m_textureManager.ReturnData(id, data, reuseable);
+
return true;
}
@@ -152,7 +169,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
public string Name
{
- get { return m_name; }
+ get { return "VectorRenderModule"; }
}
public bool IsSharedModule
@@ -162,7 +179,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
#endregion
- private void Draw(string data, UUID id, string extraParams)
+ private byte[] Draw(string data, string extraParams, out bool reuseable)
{
// We need to cater for old scripts that didnt use extraParams neatly, they use either an integer size which represents both width and height, or setalpha
// we will now support multiple comma seperated params in the form width:256,height:512,alpha:255
@@ -343,7 +360,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
}
}
- GDIDraw(data, graph, altDataDelim);
+ GDIDraw(data, graph, altDataDelim, out reuseable);
}
byte[] imageJ2000 = new byte[0];
@@ -359,7 +376,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
e.Message, e.StackTrace);
}
- m_textureManager.ReturnData(id, imageJ2000);
+ return imageJ2000;
}
finally
{
@@ -434,8 +451,21 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
}
*/
- private void GDIDraw(string data, Graphics graph, char dataDelim)
+ ///
+ /// Split input data into discrete command lines.
+ ///
+ ///
+ ///
+ ///
+ private string[] GetLines(string data, char dataDelim)
{
+ char[] lineDelimiter = { dataDelim };
+ return data.Split(lineDelimiter);
+ }
+
+ private void GDIDraw(string data, Graphics graph, char dataDelim, out bool reuseable)
+ {
+ reuseable = true;
Point startPoint = new Point(0, 0);
Point endPoint = new Point(0, 0);
Pen drawPen = null;
@@ -450,11 +480,9 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
myFont = new Font(fontName, fontSize);
myBrush = new SolidBrush(Color.Black);
- char[] lineDelimiter = {dataDelim};
char[] partsDelimiter = {','};
- string[] lines = data.Split(lineDelimiter);
- foreach (string line in lines)
+ foreach (string line in GetLines(data, dataDelim))
{
string nextLine = line.Trim();
//replace with switch, or even better, do some proper parsing
@@ -485,6 +513,10 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
}
else if (nextLine.StartsWith("Image"))
{
+ // We cannot reuse any generated texture involving fetching an image via HTTP since that image
+ // can change.
+ reuseable = false;
+
float x = 0;
float y = 0;
GetParams(partsDelimiter, ref nextLine, 5, ref x, ref y);
diff --git a/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs b/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs
index 402b9fb0fe..d99567cd4b 100644
--- a/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs
+++ b/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs
@@ -414,6 +414,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain
private void LoadPlugins()
{
m_plugineffects = new Dictionary();
+ LoadPlugins(Assembly.GetCallingAssembly());
string plugineffectsPath = "Terrain";
// Load the files in the Terrain/ dir
@@ -427,32 +428,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain
try
{
Assembly library = Assembly.LoadFrom(file);
- foreach (Type pluginType in library.GetTypes())
- {
- try
- {
- if (pluginType.IsAbstract || pluginType.IsNotPublic)
- continue;
-
- string typeName = pluginType.Name;
-
- if (pluginType.GetInterface("ITerrainEffect", false) != null)
- {
- ITerrainEffect terEffect = (ITerrainEffect) Activator.CreateInstance(library.GetType(pluginType.ToString()));
-
- InstallPlugin(typeName, terEffect);
- }
- else if (pluginType.GetInterface("ITerrainLoader", false) != null)
- {
- ITerrainLoader terLoader = (ITerrainLoader) Activator.CreateInstance(library.GetType(pluginType.ToString()));
- m_loaders[terLoader.FileExtension] = terLoader;
- m_log.Info("L ... " + typeName);
- }
- }
- catch (AmbiguousMatchException)
- {
- }
- }
+ LoadPlugins(library);
}
catch (BadImageFormatException)
{
@@ -460,6 +436,36 @@ namespace OpenSim.Region.CoreModules.World.Terrain
}
}
+ private void LoadPlugins(Assembly library)
+ {
+ foreach (Type pluginType in library.GetTypes())
+ {
+ try
+ {
+ if (pluginType.IsAbstract || pluginType.IsNotPublic)
+ continue;
+
+ string typeName = pluginType.Name;
+
+ if (pluginType.GetInterface("ITerrainEffect", false) != null)
+ {
+ ITerrainEffect terEffect = (ITerrainEffect)Activator.CreateInstance(library.GetType(pluginType.ToString()));
+
+ InstallPlugin(typeName, terEffect);
+ }
+ else if (pluginType.GetInterface("ITerrainLoader", false) != null)
+ {
+ ITerrainLoader terLoader = (ITerrainLoader)Activator.CreateInstance(library.GetType(pluginType.ToString()));
+ m_loaders[terLoader.FileExtension] = terLoader;
+ m_log.Info("L ... " + typeName);
+ }
+ }
+ catch (AmbiguousMatchException)
+ {
+ }
+ }
+ }
+
public void InstallPlugin(string pluginName, ITerrainEffect effect)
{
lock (m_plugineffects)
@@ -1178,7 +1184,8 @@ namespace OpenSim.Region.CoreModules.World.Terrain
private void InterfaceRunPluginEffect(Object[] args)
{
- if ((string) args[0] == "list")
+ string firstArg = (string)args[0];
+ if (firstArg == "list")
{
m_log.Info("List of loaded plugins");
foreach (KeyValuePair kvp in m_plugineffects)
@@ -1187,14 +1194,14 @@ namespace OpenSim.Region.CoreModules.World.Terrain
}
return;
}
- if ((string) args[0] == "reload")
+ if (firstArg == "reload")
{
LoadPlugins();
return;
}
- if (m_plugineffects.ContainsKey((string) args[0]))
+ if (m_plugineffects.ContainsKey(firstArg))
{
- m_plugineffects[(string) args[0]].RunEffect(m_channel);
+ m_plugineffects[firstArg].RunEffect(m_channel);
CheckForTerrainUpdates();
}
else
diff --git a/OpenSim/Region/Framework/Interfaces/IDynamicTextureManager.cs b/OpenSim/Region/Framework/Interfaces/IDynamicTextureManager.cs
index 8954513c06..1a3bcbbc71 100644
--- a/OpenSim/Region/Framework/Interfaces/IDynamicTextureManager.cs
+++ b/OpenSim/Region/Framework/Interfaces/IDynamicTextureManager.cs
@@ -33,7 +33,7 @@ namespace OpenSim.Region.Framework.Interfaces
public interface IDynamicTextureManager
{
void RegisterRender(string handleType, IDynamicTextureRender render);
- void ReturnData(UUID id, byte[] data);
+ void ReturnData(UUID id, byte[] data, bool isReuseable);
UUID AddDynamicTextureURL(UUID simID, UUID primID, string contentType, string url, string extraParams,
int updateTimer);
@@ -113,8 +113,20 @@ namespace OpenSim.Region.Framework.Interfaces
string GetName();
string GetContentType();
bool SupportsAsynchronous();
+
+// ///
+// /// Return true if converting the input body and extra params data will always result in the same byte[] array
+// ///
+// ///
+// /// This method allows the caller to use a previously generated asset if it has one.
+// ///
+// ///
+// ///
+// ///
+// bool AlwaysIdenticalConversion(string bodyData, string extraParams);
+
byte[] ConvertUrl(string url, string extraParams);
- byte[] ConvertStream(Stream data, string extraParams);
+ byte[] ConvertData(string bodyData, string extraParams);
bool AsyncConvertUrl(UUID id, string url, string extraParams);
bool AsyncConvertData(UUID id, string bodyData, string extraParams);
void GetDrawStringSize(string text, string fontName, int fontSize,
diff --git a/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs b/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs
index 44d2d452d5..9457ebb374 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs
@@ -50,8 +50,40 @@ using OpenSim.Tests.Common.Mock;
namespace OpenSim.Region.Framework.Tests
{
[TestFixture]
- public class UserInventoryTests
+ public class UserInventoryTests : OpenSimTestCase
{
+ [Test]
+ public void TestCreateInventoryFolders()
+ {
+ TestHelpers.InMethod();
+// TestHelpers.EnableLogging();
+
+ // For this test both folders will have the same name which is legal in SL user inventories.
+ string foldersName = "f1";
+
+ Scene scene = new SceneHelpers().SetupScene();
+ UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene, TestHelpers.ParseTail(1001));
+
+ UserInventoryHelpers.CreateInventoryFolder(scene.InventoryService, user1.PrincipalID, foldersName);
+
+ List oneFolder
+ = UserInventoryHelpers.GetInventoryFolders(scene.InventoryService, user1.PrincipalID, foldersName);
+
+ Assert.That(oneFolder.Count, Is.EqualTo(1));
+ InventoryFolderBase firstRetrievedFolder = oneFolder[0];
+ Assert.That(firstRetrievedFolder.Name, Is.EqualTo(foldersName));
+
+ UserInventoryHelpers.CreateInventoryFolder(scene.InventoryService, user1.PrincipalID, foldersName);
+
+ List twoFolders
+ = UserInventoryHelpers.GetInventoryFolders(scene.InventoryService, user1.PrincipalID, foldersName);
+
+ Assert.That(twoFolders.Count, Is.EqualTo(2));
+ Assert.That(twoFolders[0].Name, Is.EqualTo(foldersName));
+ Assert.That(twoFolders[1].Name, Is.EqualTo(foldersName));
+ Assert.That(twoFolders[0].ID, Is.Not.EqualTo(twoFolders[1].ID));
+ }
+
[Test]
public void TestGiveInventoryItem()
{
@@ -83,7 +115,7 @@ namespace OpenSim.Region.Framework.Tests
public void TestGiveInventoryFolder()
{
TestHelpers.InMethod();
-// log4net.Config.XmlConfigurator.Configure();
+// TestHelpers.EnableLogging();
Scene scene = new SceneHelpers().SetupScene();
UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene, TestHelpers.ParseTail(1001));
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index 5316d085a5..61e8a28f65 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -7701,7 +7701,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
{
m_host.AddScriptLPS(1);
- setLinkPrimParams(ScriptBaseClass.LINK_THIS, rules);
+ setLinkPrimParams(ScriptBaseClass.LINK_THIS, rules, "llSetPrimitiveParams");
ScriptSleep(200);
}
@@ -7710,10 +7710,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
{
m_host.AddScriptLPS(1);
- setLinkPrimParams(linknumber, rules);
+ setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParamsFast");
+
+ ScriptSleep(200);
}
- private void setLinkPrimParams(int linknumber, LSL_List rules)
+ private void setLinkPrimParams(int linknumber, LSL_List rules, string originFunc)
{
List