From 1369058280c4cf399d46df1508b80cad99f1247e Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 22 Aug 2012 23:04:17 +0100 Subject: Lock disposal of separate gdi+ objects under different threads since this prevents malloc heap corruption seen under Ubuntu 10.04.1 and 11.04 - probably a libcairo issue In testing, it appears that if multiple threads dispose of separate GDI+ objects simultaneously, the native malloc heap can become corrupted, possibly due to a double free(). This may be due to bugs in the underlying libcairo used by mono's libgdiplus.dll on Linux/OSX. These problems were seen with both libcario 1.10.2-6.1ubuntu3 and 1.8.10-2ubuntu1. They go away if disposal is perfomed under lock. --- .../Scripting/VectorRender/VectorRenderModule.cs | 68 +++++++++++++--------- 1 file changed, 42 insertions(+), 26 deletions(-) (limited to 'OpenSim/Region/CoreModules/Scripting') diff --git a/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs b/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs index ca320e1..c48a703 100644 --- a/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs @@ -308,36 +308,44 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender try { - if (alpha == 256) - bitmap = new Bitmap(width, height, PixelFormat.Format32bppRgb); - else - bitmap = new Bitmap(width, height, PixelFormat.Format32bppArgb); - - graph = Graphics.FromImage(bitmap); - - // this is really just to save people filling the - // background color in their scripts, only do when fully opaque - if (alpha >= 255) + // XXX: In testing, it appears that if multiple threads dispose of separate GDI+ objects simultaneously, + // the native malloc heap can become corrupted, possibly due to a double free(). This may be due to + // bugs in the underlying libcairo used by mono's libgdiplus.dll on Linux/OSX. These problems were + // seen with both libcario 1.10.2-6.1ubuntu3 and 1.8.10-2ubuntu1. They go away if disposal is perfomed + // under lock. + lock (this) { - using (SolidBrush bgFillBrush = new SolidBrush(bgColor)) + if (alpha == 256) + bitmap = new Bitmap(width, height, PixelFormat.Format32bppRgb); + else + bitmap = new Bitmap(width, height, PixelFormat.Format32bppArgb); + + graph = Graphics.FromImage(bitmap); + + // this is really just to save people filling the + // background color in their scripts, only do when fully opaque + if (alpha >= 255) { - graph.FillRectangle(bgFillBrush, 0, 0, width, height); + using (SolidBrush bgFillBrush = new SolidBrush(bgColor)) + { + graph.FillRectangle(bgFillBrush, 0, 0, width, height); + } } - } - - for (int w = 0; w < bitmap.Width; w++) - { - if (alpha <= 255) + + for (int w = 0; w < bitmap.Width; w++) { - for (int h = 0; h < bitmap.Height; h++) + if (alpha <= 255) { - bitmap.SetPixel(w, h, Color.FromArgb(alpha, bitmap.GetPixel(w, h))); + for (int h = 0; h < bitmap.Height; h++) + { + bitmap.SetPixel(w, h, Color.FromArgb(alpha, bitmap.GetPixel(w, h))); + } } } + + GDIDraw(data, graph, altDataDelim); } - GDIDraw(data, graph, altDataDelim); - byte[] imageJ2000 = new byte[0]; try @@ -355,11 +363,19 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender } finally { - if (graph != null) - graph.Dispose(); - - if (bitmap != null) - bitmap.Dispose(); + // XXX: In testing, it appears that if multiple threads dispose of separate GDI+ objects simultaneously, + // the native malloc heap can become corrupted, possibly due to a double free(). This may be due to + // bugs in the underlying libcairo used by mono's libgdiplus.dll on Linux/OSX. These problems were + // seen with both libcario 1.10.2-6.1ubuntu3 and 1.8.10-2ubuntu1. They go away if disposal is perfomed + // under lock. + lock (this) + { + if (graph != null) + graph.Dispose(); + + if (bitmap != null) + bitmap.Dispose(); + } } } -- cgit v1.1 From e90168c7382f7750faa001542652e2316841c961 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 27 Aug 2012 22:42:40 +0100 Subject: Add VectorRenderModuleTests.TestRepeatDraw() --- .../VectorRender/Tests/VectorRenderModuleTests.cs | 59 ++++++++++++++++++---- 1 file changed, 48 insertions(+), 11 deletions(-) (limited to 'OpenSim/Region/CoreModules/Scripting') diff --git a/OpenSim/Region/CoreModules/Scripting/VectorRender/Tests/VectorRenderModuleTests.cs b/OpenSim/Region/CoreModules/Scripting/VectorRender/Tests/VectorRenderModuleTests.cs index 9787c8c..f9b5a59 100644 --- a/OpenSim/Region/CoreModules/Scripting/VectorRender/Tests/VectorRenderModuleTests.cs +++ b/OpenSim/Region/CoreModules/Scripting/VectorRender/Tests/VectorRenderModuleTests.cs @@ -45,31 +45,68 @@ 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; + + [SetUp] + public void SetUp() + { + m_scene = new SceneHelpers().SetupScene(); + m_dtm = new DynamicTextureModule(); + 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); + 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 TestRepeatDraw() + { + TestHelpers.InMethod(); + + string dtText = "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World;"; + + 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 -- cgit v1.1 From 3082fdd0f6d73fa07fe2266170fcd3e5e572f2a2 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 27 Aug 2012 22:58:20 +0100 Subject: Add VectorRenderModuleTests.TestRepeatDrawContainingImage() --- .../VectorRender/Tests/VectorRenderModuleTests.cs | 31 ++++++++++++++++++++++ 1 file changed, 31 insertions(+) (limited to 'OpenSim/Region/CoreModules/Scripting') diff --git a/OpenSim/Region/CoreModules/Scripting/VectorRender/Tests/VectorRenderModuleTests.cs b/OpenSim/Region/CoreModules/Scripting/VectorRender/Tests/VectorRenderModuleTests.cs index f9b5a59..21e1d54 100644 --- a/OpenSim/Region/CoreModules/Scripting/VectorRender/Tests/VectorRenderModuleTests.cs +++ b/OpenSim/Region/CoreModules/Scripting/VectorRender/Tests/VectorRenderModuleTests.cs @@ -108,5 +108,36 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender.Tests Assert.That(firstDynamicTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID)); } + + [Test] + public void TestRepeatDrawContainingImage() + { + TestHelpers.InMethod(); + + string dtText + = "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World; Image http://localhost/shouldnotexist.png"; + + 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 -- cgit v1.1 From 4e26d039d6ffe03ae9509120015b39692bad44f9 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 27 Aug 2012 23:03:21 +0100 Subject: Add VectorRenderModule.TestRepeatSameDrawDifferentExtraParams() --- .../VectorRender/Tests/VectorRenderModuleTests.cs | 34 ++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region/CoreModules/Scripting') diff --git a/OpenSim/Region/CoreModules/Scripting/VectorRender/Tests/VectorRenderModuleTests.cs b/OpenSim/Region/CoreModules/Scripting/VectorRender/Tests/VectorRenderModuleTests.cs index 21e1d54..180ea9f 100644 --- a/OpenSim/Region/CoreModules/Scripting/VectorRender/Tests/VectorRenderModuleTests.cs +++ b/OpenSim/Region/CoreModules/Scripting/VectorRender/Tests/VectorRenderModuleTests.cs @@ -80,7 +80,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender.Tests } [Test] - public void TestRepeatDraw() + public void TestRepeatSameDraw() { TestHelpers.InMethod(); @@ -110,7 +110,37 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender.Tests } [Test] - public void TestRepeatDrawContainingImage() + public void TestRepeatSameDrawDifferentExtraParams() + { + TestHelpers.InMethod(); + + string dtText = "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World;"; + + 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(); -- cgit v1.1 From ab9bfe5156d955ca02b7cfcb0ccb5919f6b0743d Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 27 Aug 2012 23:06:37 +0100 Subject: minor: Simplify return of vector render module name and some very minor removal of unncessary syntax clutter --- .../CoreModules/Scripting/VectorRender/VectorRenderModule.cs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'OpenSim/Region/CoreModules/Scripting') diff --git a/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs b/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs index c48a703..f988c0e 100644 --- a/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs @@ -47,7 +47,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 +60,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() @@ -152,7 +151,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender public string Name { - get { return m_name; } + get { return "VectorRenderModule"; } } public bool IsSharedModule -- cgit v1.1 From aa44df9c04658cfa0af9a0f203faea5e493c6f25 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 28 Aug 2012 20:35:17 +0100 Subject: Add IDynamicTextureManager.ConvertData() to match AsyncConvertData(). Remove mismatching ConvertStream() where there is no AsyncConvertStream and neither IDynamicTextureManager implementer implements this method. --- .../CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs | 2 +- .../CoreModules/Scripting/VectorRender/VectorRenderModule.cs | 11 ++++++----- 2 files changed, 7 insertions(+), 6 deletions(-) (limited to 'OpenSim/Region/CoreModules/Scripting') diff --git a/OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs b/OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs index 6f83948..6e38b3f 100644 --- a/OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs @@ -72,7 +72,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LoadImageURL return null; } - public byte[] ConvertStream(Stream data, string extraParams) + public byte[] ConvertData(string bodyData, string extraParams) { return null; } diff --git a/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs b/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs index f988c0e..3a758c5 100644 --- a/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs @@ -78,9 +78,9 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender return null; } - public byte[] ConvertStream(Stream data, string extraParams) + public byte[] ConvertData(string bodyData, string extraParams) { - return null; + return Draw(bodyData, extraParams); } public bool AsyncConvertUrl(UUID id, string url, string extraParams) @@ -90,7 +90,8 @@ 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! + m_textureManager.ReturnData(id, ConvertData(bodyData, extraParams)); return true; } @@ -161,7 +162,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender #endregion - private void Draw(string data, UUID id, string extraParams) + private byte[] Draw(string data, string extraParams) { // 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 @@ -358,7 +359,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender e.Message, e.StackTrace); } - m_textureManager.ReturnData(id, imageJ2000); + return imageJ2000; } finally { -- cgit v1.1 From c1cece4b82d24a17a09b66c9ec3975190cc05d95 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 28 Aug 2012 23:06:53 +0100 Subject: Add experimental DynamicTextureModule.ReuseTextures flag, currently only configurable on compile. Disabled (status quo) by default. This flag makes the dynamic texture module reuse cache previously dynamically generated textures given the same input commands and extra params for 24 hours. This occurs as long as those commands would always generate the same texture (e.g. they do not contain commands to fetch data from the web). This makes texture changing faster as a viewer-cached texture uuid is sent and may reduce simulator load in regions with generation of lots of dynamic textures. A downside is that this stops expiry of old temporary dynamic textures from the cache, Another downside is that a jpeg2000 generation that partially failed is currently not regenerated until restart or after 24 hours. --- .../DynamicTexture/DynamicTextureModule.cs | 169 +++++++++++++++------ .../Scripting/LoadImageURL/LoadImageURLModule.cs | 10 +- .../VectorRender/Tests/VectorRenderModuleTests.cs | 125 ++++++++++++++- .../Scripting/VectorRender/VectorRenderModule.cs | 48 +++++- 4 files changed, 297 insertions(+), 55 deletions(-) (limited to 'OpenSim/Region/CoreModules/Scripting') diff --git a/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs b/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs index 18bd018..13b7498 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() @@ -269,9 +327,60 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture } /// + /// 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 6e38b3f..2b3a0f2 100644 --- a/OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs @@ -67,6 +67,12 @@ 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; @@ -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 180ea9f..b50c0bd 100644 --- a/OpenSim/Region/CoreModules/Scripting/VectorRender/Tests/VectorRenderModuleTests.cs +++ b/OpenSim/Region/CoreModules/Scripting/VectorRender/Tests/VectorRenderModuleTests.cs @@ -51,12 +51,15 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender.Tests DynamicTextureModule m_dtm; VectorRenderModule m_vrm; - [SetUp] - public void SetUp() + 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); } @@ -65,6 +68,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender.Tests { TestHelpers.InMethod(); + SetupScene(false); SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene); UUID originalTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID; @@ -86,6 +90,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender.Tests string dtText = "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World;"; + SetupScene(false); SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene); m_dtm.AddDynamicTextureData( @@ -116,6 +121,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender.Tests string dtText = "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World;"; + SetupScene(false); SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene); m_dtm.AddDynamicTextureData( @@ -147,6 +153,121 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender.Tests 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( diff --git a/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs b/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs index 3a758c5..4268f2e 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; @@ -73,6 +74,12 @@ 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; @@ -80,7 +87,13 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender public byte[] ConvertData(string bodyData, string extraParams) { - return Draw(bodyData, extraParams); + 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 +104,11 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender public bool AsyncConvertData(UUID id, string bodyData, string extraParams) { // XXX: This isn't actually being done asynchronously! - m_textureManager.ReturnData(id, ConvertData(bodyData, extraParams)); + bool reuseable; + byte[] data = ConvertData(bodyData, extraParams, out reuseable); + + m_textureManager.ReturnData(id, data, reuseable); + return true; } @@ -162,7 +179,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender #endregion - private byte[] Draw(string data, 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]; @@ -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); -- cgit v1.1 From 3d736d575ff9670ac813f13eb1cff07dea10328b Mon Sep 17 00:00:00 2001 From: Mic Bowman Date: Wed, 29 Aug 2012 14:56:51 -0700 Subject: This partially implements the LSL function to set the response type for an HTTP request. Since the "official" LSL function limits the use of the response type, it is implemented as osSetContentType with a string for the content mime type and a threat level of high. With this function you should be able to implement rather functional media-on-a-prim application with much less difficulty. --- .../CoreModules/Scripting/LSLHttp/UrlModule.cs | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region/CoreModules/Scripting') diff --git a/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs b/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs index 05d54f0..53a9679 100644 --- a/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs @@ -84,6 +84,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp public string body; public int responseCode; public string responseBody; + public string responseType = "text/plain"; //public ManualResetEvent ev; public bool requestDone; public int startTime; @@ -302,6 +303,22 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp } } + public void HttpContentType(UUID request, string type) + { + lock (m_UrlMap) + { + if (m_RequestMap.ContainsKey(request)) + { + UrlData urlData = m_RequestMap[request]; + urlData.requests[request].responseType = type; + } + else + { + m_log.Info("[HttpRequestHandler] There is no http-in request with id " + request.ToString()); + } + } + } + public void HttpResponse(UUID request, int status, string body) { lock (m_UrlMap) @@ -504,7 +521,8 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp //put response response["int_response_code"] = requestData.responseCode; response["str_response_string"] = requestData.responseBody; - response["content_type"] = "text/plain"; + response["content_type"] = requestData.responseType; + // response["content_type"] = "text/plain"; response["keepalive"] = false; response["reusecontext"] = false; -- cgit v1.1 From d89b974680af52a2d950237962240dde82ff4a85 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 30 Aug 2012 22:28:45 +0100 Subject: If the compile-time DynamicTextureModule.ReuseTextures flag is set, check metadata still exists for any reused asset in case some other process has removed it from the cache. --- .../DynamicTexture/DynamicTextureModule.cs | 102 ++++++++++++--------- 1 file changed, 59 insertions(+), 43 deletions(-) (limited to 'OpenSim/Region/CoreModules/Scripting') diff --git a/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs b/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs index 13b7498..f169117 100644 --- a/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs @@ -186,63 +186,79 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture public UUID AddDynamicTextureData(UUID simID, UUID primID, string contentType, string data, string extraParams, int updateTimer, bool SetBlending, int disp, byte AlphaValue, int face) { - 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; + if (!RenderPlugins.ContainsKey(contentType)) + return UUID.Zero; - DynamicTextureUpdater updater = new DynamicTextureUpdater(); - updater.SimUUID = simID; - updater.PrimID = primID; - updater.ContentType = contentType; - updater.BodyData = data; - updater.UpdateTimer = updateTimer; - updater.UpdaterID = UUID.Random(); - updater.Params = extraParams; - updater.BlendWithOldTexture = SetBlending; - updater.FrontAlpha = AlphaValue; - updater.Face = face; - updater.Url = "Local image"; - updater.Disp = disp; + Scene scene; + RegisteredScenes.TryGetValue(simID, out scene); + + if (scene == null) + return UUID.Zero; - object reusableTextureUUID = null; + SceneObjectPart part = scene.GetSceneObjectPart(primID); - if (ReuseTextures) - reusableTextureUUID - = m_reuseableDynamicTextures.Get(GenerateReusableTextureKey(data, extraParams)); + if (part == null) + return UUID.Zero; + + // 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; + updater.ContentType = contentType; + updater.BodyData = data; + updater.UpdateTimer = updateTimer; + updater.UpdaterID = UUID.Random(); + updater.Params = extraParams; + updater.BlendWithOldTexture = SetBlending; + updater.FrontAlpha = AlphaValue; + updater.Face = face; + updater.Url = "Local image"; + updater.Disp = disp; + + object objReusableTextureUUID = null; + + if (ReuseTextures && !updater.BlendWithOldTexture) + { + string reuseableTextureKey = GenerateReusableTextureKey(data, extraParams); + objReusableTextureUUID = m_reuseableDynamicTextures.Get(reuseableTextureKey); - // We cannot reuse a dynamic texture if the data is going to be blended with something already there. - if (reusableTextureUUID == null || updater.BlendWithOldTexture) + if (objReusableTextureUUID != null) { - lock (Updaters) + // If something else has removed this temporary asset from the cache, detect and invalidate + // our cached uuid. + if (scene.AssetService.GetMetadata(objReusableTextureUUID.ToString()) == null) { - if (!Updaters.ContainsKey(updater.UpdaterID)) - { - Updaters.Add(updater.UpdaterID, updater); - } + m_reuseableDynamicTextures.Invalidate(reuseableTextureKey); + objReusableTextureUUID = null; } - - RenderPlugins[contentType].AsyncConvertData(updater.UpdaterID, data, extraParams); } - else + } + + // We cannot reuse a dynamic texture if the data is going to be blended with something already there. + if (objReusableTextureUUID == null) + { + lock (Updaters) { - // 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)) + if (!Updaters.ContainsKey(updater.UpdaterID)) { - SceneObjectPart part = RegisteredScenes[updater.SimUUID].GetSceneObjectPart(updater.PrimID); - - if (part != null) - updater.UpdatePart(part, (UUID)reusableTextureUUID); + Updaters.Add(updater.UpdaterID, updater); } } - return updater.UpdaterID; + RenderPlugins[contentType].AsyncConvertData(updater.UpdaterID, data, extraParams); } - - return UUID.Zero; + else + { + // No need to add to updaters as the texture is always the same. Not that this functionality + // apppears to be implemented anyway. + updater.UpdatePart(part, (UUID)objReusableTextureUUID); + } + + return updater.UpdaterID; } private string GenerateReusableTextureKey(string data, string extraParams) -- cgit v1.1 From 3ed0d79b00c313eacb2a7df7d5519e840d2fc5c4 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 30 Aug 2012 22:57:40 +0100 Subject: Make ReuseDynamicTextures an experimental config setting in [Textures]. Default is false, as before. If true, this setting reuses dynamically generated textures (i.e. created through osSetDynamicTextureData() and similar OSSL functions) where possible rather than always regenerating them. This results in much quicker updates viewer-side but may bloat the asset cache (though this is fixable). Also, sometimes issue have been seen where dynamic textures do not transfer to the viewer properly (permanently blurry). If this happens and that flag is set then they are not regenerated, the viewer has to clear cache or wait for 24 hours before all cached uuids are invalidated. CUrrently experimental. Default is false, as before. --- .../CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region/CoreModules/Scripting') diff --git a/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs b/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs index f169117..3eedf49 100644 --- a/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs @@ -283,6 +283,10 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture public void Initialise(Scene scene, IConfigSource config) { + IConfig texturesConfig = config.Configs["Textures"]; + if (texturesConfig != null) + ReuseTextures = texturesConfig.GetBoolean("ReuseDynamicTextures", false); + if (!RegisteredScenes.ContainsKey(scene.RegionInfo.RegionID)) { RegisteredScenes.Add(scene.RegionInfo.RegionID, scene); @@ -292,7 +296,6 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture public void PostInitialise() { -// ReuseTextures = true; if (ReuseTextures) { m_reuseableDynamicTextures = new Cache(CacheMedium.Memory, CacheStrategy.Conservative); -- cgit v1.1 From a0d0c9f751f45d54772af2e33866b27c9be33511 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 6 Sep 2012 00:11:47 +0100 Subject: If the GetTexture capability receives a request for a range of data beyond that of an otherwise valid asset, return HTTP PartialContent rather than RequestedRangeNotSatisfiable. This is because recent viewers (3.2.1, 3.3.4) and probably earlier ones using the http GetTexture capability will sometimes make such invalid range requests. This appears to happen if the viewer's estimate of texture sizes at discard levels > 0 (chiefly 2) exceeds the total texture size. I believe this does not normally happen but can occur for dynamic textures with are large but mainly blank. If this happens, returning a RequestedRangeNotSatisfiable will cause the viewer to not render the texture at the final resolution. However, returning a PartialContent (or OK) even with 0 data will allow the viewer to render the final texture. --- .../Scripting/DynamicTexture/DynamicTextureModule.cs | 16 +++++++++++++--- .../Scripting/VectorRender/VectorRenderModule.cs | 20 ++++++++++++++++++++ 2 files changed, 33 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region/CoreModules/Scripting') diff --git a/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs b/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs index 3eedf49..e09f1a9 100644 --- a/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs @@ -42,7 +42,7 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture { public class DynamicTextureModule : IRegionModule, IDynamicTextureManager { - //private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); +// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private const int ALL_SIDES = -1; @@ -249,10 +249,18 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture } } +// m_log.DebugFormat( +// "[DYNAMIC TEXTURE MODULE]: Requesting generation of new dynamic texture for {0} in {1}", +// part.Name, part.ParentGroup.Scene.Name); + RenderPlugins[contentType].AsyncConvertData(updater.UpdaterID, data, extraParams); } else { +// m_log.DebugFormat( +// "[DYNAMIC TEXTURE MODULE]: Reusing cached texture {0} for {1} in {2}", +// objReusableTextureUUID, part.Name, part.ParentGroup.Scene.Name); + // No need to add to updaters as the texture is always the same. Not that this functionality // apppears to be implemented anyway. updater.UpdatePart(part, (UUID)objReusableTextureUUID); @@ -448,8 +456,10 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture IJ2KDecoder cacheLayerDecode = scene.RequestModuleInterface(); if (cacheLayerDecode != null) { - cacheLayerDecode.Decode(asset.FullID, asset.Data); - cacheLayerDecode = null; + if (!cacheLayerDecode.Decode(asset.FullID, asset.Data)) + m_log.WarnFormat( + "[DYNAMIC TEXTURE MODULE]: Decoding of dynamically generated asset {0} for {1} in {2} failed", + asset.ID, part.Name, part.ParentGroup.Scene.Name); } UUID oldID = UpdatePart(part, asset.FullID); diff --git a/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs b/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs index 4268f2e..0e7051e 100644 --- a/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs @@ -46,6 +46,11 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender { public class VectorRenderModule : IRegionModule, IDynamicTextureRender { + // These fields exist for testing purposes, please do not remove. +// private static bool s_flipper; +// private static byte[] s_asset1Data; +// private static byte[] s_asset2Data; + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private Scene m_scene; @@ -161,6 +166,13 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender { m_textureManager.RegisterRender(GetContentType(), this); } + + // This code exists for testing purposes, please do not remove. +// s_asset1Data = m_scene.AssetService.Get("00000000-0000-1111-9999-000000000001").Data; +// s_asset1Data = m_scene.AssetService.Get("9f4acf0d-1841-4e15-bdb8-3a12efc9dd8f").Data; + + // Terrain dirt - smallest bin/assets file (6004 bytes) +// s_asset2Data = m_scene.AssetService.Get("b8d3965a-ad78-bf43-699b-bff8eca6c975").Data; } public void Close() @@ -364,6 +376,14 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender } byte[] imageJ2000 = new byte[0]; + + // This code exists for testing purposes, please do not remove. +// if (s_flipper) +// imageJ2000 = s_asset1Data; +// else +// imageJ2000 = s_asset2Data; +// +// s_flipper = !s_flipper; try { -- cgit v1.1 From 8f02fd926e14dfad7f5eb77a67a6701f449511e0 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 6 Sep 2012 22:12:05 +0100 Subject: If reusing dynamic textures, do not reuse small data length textures that fall below current viewer discard level 2 thresholds. Viewer LL 3.3.4 and before sometimes fail to properly redisplay dynamic textures that have a small data length compared to pixel size when pulled from cache. This appears to happen when the data length is smaller than the estimate discard level 2 size the viewer uses when making this GetTexture request. This commit works around this by always regenerating dynamic textures that fall below this threshold rather than reusing them if ReuseDynamicTextures = true This can be controlled by the [Textures] ReuseDynamicLowDataTextures config setting which defaults to false. --- .../DynamicTexture/DynamicTextureModule.cs | 59 ++++++++++++++++++---- .../Scripting/LoadImageURL/LoadImageURLModule.cs | 41 +++++++++------ .../VectorRender/Tests/VectorRenderModuleTests.cs | 42 +++++++++++++++ .../Scripting/VectorRender/VectorRenderModule.cs | 24 ++++----- 4 files changed, 125 insertions(+), 41 deletions(-) (limited to 'OpenSim/Region/CoreModules/Scripting') diff --git a/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs b/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs index e09f1a9..1f340df 100644 --- a/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs @@ -42,7 +42,7 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture { public class DynamicTextureModule : IRegionModule, IDynamicTextureManager { -// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private const int ALL_SIDES = -1; @@ -54,6 +54,17 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture /// public bool ReuseTextures { get; set; } + /// + /// If false, then textures which have a low data size are not reused when ReuseTextures = true. + /// + /// + /// LL viewers 3.3.4 and before appear to not fully render textures pulled from the viewer cache if those + /// textures have a relatively high pixel surface but a small data size. Typically, this appears to happen + /// if the data size is smaller than the viewer's discard level 2 size estimate. So if this is setting is + /// false, textures smaller than the calculation in IsSizeReuseable are always regenerated rather than reused + /// to work around this problem. + public bool ReuseLowDataTextures { get; set; } + private Dictionary RegisteredScenes = new Dictionary(); private Dictionary RenderPlugins = @@ -83,18 +94,17 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture /// /// Called by code which actually renders the dynamic texture to supply texture data. /// - /// - /// - /// True if the data generated can be reused for subsequent identical requests - public void ReturnData(UUID id, byte[] data, bool isReuseable) + /// + /// + public void ReturnData(UUID updaterId, IDynamicTexture texture) { DynamicTextureUpdater updater = null; lock (Updaters) { - if (Updaters.ContainsKey(id)) + if (Updaters.ContainsKey(updaterId)) { - updater = Updaters[id]; + updater = Updaters[updaterId]; } } @@ -103,11 +113,16 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture if (RegisteredScenes.ContainsKey(updater.SimUUID)) { Scene scene = RegisteredScenes[updater.SimUUID]; - UUID newTextureID = updater.DataReceived(data, scene); + UUID newTextureID = updater.DataReceived(texture.Data, scene); - if (ReuseTextures && isReuseable && !updater.BlendWithOldTexture) + if (ReuseTextures + && !updater.BlendWithOldTexture + && texture.IsReuseable + && (ReuseLowDataTextures || IsDataSizeReuseable(texture))) + { m_reuseableDynamicTextures.Store( - GenerateReusableTextureKey(updater.BodyData, updater.Params), newTextureID); + GenerateReusableTextureKey(texture.InputCommands, texture.InputParams), newTextureID); + } } } @@ -123,6 +138,27 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture } } + /// + /// Determines whether the texture is reuseable based on its data size. + /// + /// + /// This is a workaround for a viewer bug where very small data size textures relative to their pixel size + /// are not redisplayed properly when pulled from cache. The calculation here is based on the typical discard + /// level of 2, a 'rate' of 0.125 and 4 components (which makes for a factor of 0.5). + /// + /// + private bool IsDataSizeReuseable(IDynamicTexture texture) + { +// Console.WriteLine("{0} {1}", texture.Size.Width, texture.Size.Height); + int discardLevel2DataThreshold = (int)Math.Ceiling((texture.Size.Width >> 2) * (texture.Size.Height >> 2) * 0.5); + +// m_log.DebugFormat( +// "[DYNAMIC TEXTURE MODULE]: Discard level 2 threshold {0}, texture data length {1}", +// discardLevel2DataThreshold, texture.Data.Length); + + return discardLevel2DataThreshold < texture.Data.Length; + } + public UUID AddDynamicTextureURL(UUID simID, UUID primID, string contentType, string url, string extraParams, int updateTimer) { @@ -293,7 +329,10 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture { IConfig texturesConfig = config.Configs["Textures"]; if (texturesConfig != null) + { ReuseTextures = texturesConfig.GetBoolean("ReuseDynamicTextures", false); + ReuseLowDataTextures = texturesConfig.GetBoolean("ReuseDynamicLowDataTextures", false); + } if (!RegisteredScenes.ContainsKey(scene.RegionInfo.RegionID)) { diff --git a/OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs b/OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs index 2b3a0f2..45e6527 100644 --- a/OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs @@ -32,6 +32,7 @@ using System.Net; using Nini.Config; using OpenMetaverse; using OpenMetaverse.Imaging; +using OpenSim.Region.CoreModules.Scripting.DynamicTexture; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; using log4net; @@ -73,12 +74,12 @@ namespace OpenSim.Region.CoreModules.Scripting.LoadImageURL // return false; // } - public byte[] ConvertUrl(string url, string extraParams) + public IDynamicTexture ConvertUrl(string url, string extraParams) { return null; } - public byte[] ConvertData(string bodyData, string extraParams) + public IDynamicTexture ConvertData(string bodyData, string extraParams) { return null; } @@ -171,11 +172,11 @@ namespace OpenSim.Region.CoreModules.Scripting.LoadImageURL private void HttpRequestReturn(IAsyncResult result) { - RequestState state = (RequestState) result.AsyncState; WebRequest request = (WebRequest) state.Request; Stream stream = null; byte[] imageJ2000 = new byte[0]; + Size newSize = new Size(0, 0); try { @@ -188,37 +189,43 @@ namespace OpenSim.Region.CoreModules.Scripting.LoadImageURL try { Bitmap image = new Bitmap(stream); - Size newsize; // TODO: make this a bit less hard coded if ((image.Height < 64) && (image.Width < 64)) { - newsize = new Size(32, 32); + newSize.Width = 32; + newSize.Height = 32; } else if ((image.Height < 128) && (image.Width < 128)) { - newsize = new Size(64, 64); + newSize.Width = 64; + newSize.Height = 64; } else if ((image.Height < 256) && (image.Width < 256)) { - newsize = new Size(128, 128); + newSize.Width = 128; + newSize.Height = 128; } else if ((image.Height < 512 && image.Width < 512)) { - newsize = new Size(256, 256); + newSize.Width = 256; + newSize.Height = 256; } else if ((image.Height < 1024 && image.Width < 1024)) { - newsize = new Size(512, 512); + newSize.Width = 512; + newSize.Height = 512; } else { - newsize = new Size(1024, 1024); + newSize.Width = 1024; + newSize.Height = 1024; } - Bitmap resize = new Bitmap(image, newsize); - - imageJ2000 = OpenJPEG.EncodeFromImage(resize, true); + using (Bitmap resize = new Bitmap(image, newSize)) + { + imageJ2000 = OpenJPEG.EncodeFromImage(resize, true); + } } catch (Exception) { @@ -233,7 +240,6 @@ namespace OpenSim.Region.CoreModules.Scripting.LoadImageURL } catch (WebException) { - } finally { @@ -243,10 +249,13 @@ namespace OpenSim.Region.CoreModules.Scripting.LoadImageURL } } - m_log.DebugFormat("[LOADIMAGEURLMODULE] Returning {0} bytes of image data for request {1}", + m_log.DebugFormat("[LOADIMAGEURLMODULE]: Returning {0} bytes of image data for request {1}", imageJ2000.Length, state.RequestID); - m_textureManager.ReturnData(state.RequestID, imageJ2000, false); + m_textureManager.ReturnData( + state.RequestID, + new OpenSim.Region.CoreModules.Scripting.DynamicTexture.DynamicTexture( + request.RequestUri, null, imageJ2000, newSize, 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 b50c0bd..41baccc 100644 --- a/OpenSim/Region/CoreModules/Scripting/VectorRender/Tests/VectorRenderModuleTests.cs +++ b/OpenSim/Region/CoreModules/Scripting/VectorRender/Tests/VectorRenderModuleTests.cs @@ -57,6 +57,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender.Tests m_dtm = new DynamicTextureModule(); m_dtm.ReuseTextures = reuseTextures; +// m_dtm.ReuseLowDataTextures = reuseTextures; m_vrm = new VectorRenderModule(); @@ -201,6 +202,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender.Tests public void TestRepeatSameDrawReusingTexture() { TestHelpers.InMethod(); +// TestHelpers.EnableLogging(); string dtText = "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World;"; @@ -228,6 +230,46 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender.Tests Assert.That(firstDynamicTextureID, Is.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID)); } + /// + /// Test a low data dynamically generated texture such that it is treated as a low data texture that causes + /// problems for current viewers. + /// + /// + /// As we do not set DynamicTextureModule.ReuseLowDataTextures = true in this test, it should not reuse the + /// texture + /// + [Test] + public void TestRepeatSameDrawLowDataTexture() + { + TestHelpers.InMethod(); +// TestHelpers.EnableLogging(); + + 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, + "1024", + 0); + + UUID firstDynamicTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID; + + m_dtm.AddDynamicTextureData( + m_scene.RegionInfo.RegionID, + so.UUID, + m_vrm.GetContentType(), + dtText, + "1024", + 0); + + Assert.That(firstDynamicTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID)); + } + [Test] public void TestRepeatSameDrawDifferentExtraParamsReusingTexture() { diff --git a/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs b/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs index 0e7051e..d82551e 100644 --- a/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs @@ -35,6 +35,7 @@ using System.Net; using Nini.Config; using OpenMetaverse; using OpenMetaverse.Imaging; +using OpenSim.Region.CoreModules.Scripting.DynamicTexture; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; using log4net; @@ -85,20 +86,14 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender // return lines.Any((str, r) => str.StartsWith("Image")); // } - public byte[] ConvertUrl(string url, string extraParams) + public IDynamicTexture ConvertUrl(string url, string extraParams) { return null; } - public byte[] ConvertData(string bodyData, string extraParams) + public IDynamicTexture ConvertData(string bodyData, string extraParams) { - bool reuseable; - return Draw(bodyData, extraParams, out reuseable); - } - - private byte[] ConvertData(string bodyData, string extraParams, out bool reuseable) - { - return Draw(bodyData, extraParams, out reuseable); + return Draw(bodyData, extraParams); } public bool AsyncConvertUrl(UUID id, string url, string extraParams) @@ -109,10 +104,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender public bool AsyncConvertData(UUID id, string bodyData, string extraParams) { // XXX: This isn't actually being done asynchronously! - bool reuseable; - byte[] data = ConvertData(bodyData, extraParams, out reuseable); - - m_textureManager.ReturnData(id, data, reuseable); + m_textureManager.ReturnData(id, ConvertData(bodyData, extraParams)); return true; } @@ -191,7 +183,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender #endregion - private byte[] Draw(string data, string extraParams, out bool reuseable) + private IDynamicTexture Draw(string data, string extraParams) { // 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 @@ -334,6 +326,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender Bitmap bitmap = null; Graphics graph = null; + bool reuseable = false; try { @@ -396,7 +389,8 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender e.Message, e.StackTrace); } - return imageJ2000; + return new OpenSim.Region.CoreModules.Scripting.DynamicTexture.DynamicTexture( + data, extraParams, imageJ2000, new Size(width, height), reuseable); } finally { -- cgit v1.1 From d2b00749ef71729555d393da7fef1dcdb84f5cbc Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 6 Sep 2012 23:14:48 +0100 Subject: Add missing DynamicTexture.cs file from last commit --- .../Scripting/DynamicTexture/DynamicTexture.cs | 61 ++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTexture.cs (limited to 'OpenSim/Region/CoreModules/Scripting') diff --git a/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTexture.cs b/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTexture.cs new file mode 100644 index 0000000..fce9490 --- /dev/null +++ b/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTexture.cs @@ -0,0 +1,61 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Drawing; +using OpenSim.Region.Framework.Interfaces; + +namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture +{ + public class DynamicTexture : IDynamicTexture + { + public string InputCommands { get; private set; } + public Uri InputUri { get; private set; } + public string InputParams { get; private set; } + public byte[] Data { get; private set; } + public Size Size { get; private set; } + public bool IsReuseable { get; private set; } + + public DynamicTexture(string inputCommands, string inputParams, byte[] data, Size size, bool isReuseable) + { + InputCommands = inputCommands; + InputParams = inputParams; + Data = data; + Size = size; + IsReuseable = isReuseable; + } + + public DynamicTexture(Uri inputUri, string inputParams, byte[] data, Size size, bool isReuseable) + { + InputUri = inputUri; + InputParams = inputParams; + Data = data; + Size = size; + IsReuseable = isReuseable; + } + } +} \ No newline at end of file -- cgit v1.1 From 91312daeb2974c75ede3e53c9d7a1d9ca0300201 Mon Sep 17 00:00:00 2001 From: Mic Bowman Date: Mon, 17 Sep 2012 09:04:54 -0700 Subject: Moving ScriptModuleComms into the CoreModules tree. --- .../ScriptModuleComms/ScriptModuleCommsModule.cs | 367 +++++++++++++++++++++ 1 file changed, 367 insertions(+) create mode 100644 OpenSim/Region/CoreModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs (limited to 'OpenSim/Region/CoreModules/Scripting') diff --git a/OpenSim/Region/CoreModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs b/OpenSim/Region/CoreModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs new file mode 100644 index 0000000..98396ff --- /dev/null +++ b/OpenSim/Region/CoreModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs @@ -0,0 +1,367 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Reflection; +using System.Collections.Generic; +using Nini.Config; +using log4net; +using OpenSim.Framework; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; +using Mono.Addins; +using OpenMetaverse; +using System.Linq; +using System.Linq.Expressions; + +namespace OpenSim.Region.OptionalModules.Scripting.ScriptModuleComms +{ + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "ScriptModuleCommsModule")] + class ScriptModuleCommsModule : INonSharedRegionModule, IScriptModuleComms + { + private static readonly ILog m_log = + LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + private Dictionary m_constants = new Dictionary(); + +#region ScriptInvocation + protected class ScriptInvocationData + { + public Delegate ScriptInvocationDelegate { get; private set; } + public string FunctionName { get; private set; } + public Type[] TypeSignature { get; private set; } + public Type ReturnType { get; private set; } + + public ScriptInvocationData(string fname, Delegate fn, Type[] callsig, Type returnsig) + { + FunctionName = fname; + ScriptInvocationDelegate = fn; + TypeSignature = callsig; + ReturnType = returnsig; + } + } + + private Dictionary m_scriptInvocation = new Dictionary(); +#endregion + + private IScriptModule m_scriptModule = null; + public event ScriptCommand OnScriptCommand; + +#region RegionModuleInterface + public void Initialise(IConfigSource config) + { + } + + public void AddRegion(Scene scene) + { + scene.RegisterModuleInterface(this); + } + + public void RemoveRegion(Scene scene) + { + } + + public void RegionLoaded(Scene scene) + { + m_scriptModule = scene.RequestModuleInterface(); + + if (m_scriptModule != null) + m_log.Info("[MODULE COMMANDS]: Script engine found, module active"); + } + + public string Name + { + get { return "ScriptModuleCommsModule"; } + } + + public Type ReplaceableInterface + { + get { return null; } + } + + public void Close() + { + } +#endregion + +#region ScriptModuleComms + + public void RaiseEvent(UUID script, string id, string module, string command, string k) + { + ScriptCommand c = OnScriptCommand; + + if (c == null) + return; + + c(script, id, module, command, k); + } + + public void DispatchReply(UUID script, int code, string text, string k) + { + if (m_scriptModule == null) + return; + + Object[] args = new Object[] {-1, code, text, k}; + + m_scriptModule.PostScriptEvent(script, "link_message", args); + } + + private static MethodInfo GetMethodInfoFromType(Type target, string meth, bool searchInstanceMethods) + { + BindingFlags getMethodFlags = + BindingFlags.NonPublic | BindingFlags.Public; + + if (searchInstanceMethods) + getMethodFlags |= BindingFlags.Instance; + else + getMethodFlags |= BindingFlags.Static; + + return target.GetMethod(meth, getMethodFlags); + } + + public void RegisterScriptInvocation(object target, string meth) + { + MethodInfo mi = GetMethodInfoFromType(target.GetType(), meth, true); + if (mi == null) + { + m_log.WarnFormat("[MODULE COMMANDS] Failed to register method {0}", meth); + return; + } + + RegisterScriptInvocation(target, mi); + } + + public void RegisterScriptInvocation(object target, string[] meth) + { + foreach (string m in meth) + RegisterScriptInvocation(target, m); + } + + public void RegisterScriptInvocation(object target, MethodInfo mi) + { + m_log.DebugFormat("[MODULE COMMANDS] Register method {0} from type {1}", mi.Name, (target is Type) ? ((Type)target).Name : target.GetType().Name); + + Type delegateType; + List typeArgs = mi.GetParameters() + .Select(p => p.ParameterType) + .ToList(); + + if (mi.ReturnType == typeof(void)) + { + delegateType = Expression.GetActionType(typeArgs.ToArray()); + } + else + { + typeArgs.Add(mi.ReturnType); + delegateType = Expression.GetFuncType(typeArgs.ToArray()); + } + + Delegate fcall; + if (!(target is Type)) + fcall = Delegate.CreateDelegate(delegateType, target, mi); + else + fcall = Delegate.CreateDelegate(delegateType, (Type)target, mi.Name); + + lock (m_scriptInvocation) + { + ParameterInfo[] parameters = fcall.Method.GetParameters(); + if (parameters.Length < 2) // Must have two UUID params + return; + + // Hide the first two parameters + Type[] parmTypes = new Type[parameters.Length - 2]; + for (int i = 2; i < parameters.Length; i++) + parmTypes[i - 2] = parameters[i].ParameterType; + m_scriptInvocation[fcall.Method.Name] = new ScriptInvocationData(fcall.Method.Name, fcall, parmTypes, fcall.Method.ReturnType); + } + } + + public void RegisterScriptInvocation(Type target, string[] methods) + { + foreach (string method in methods) + { + MethodInfo mi = GetMethodInfoFromType(target, method, false); + if (mi == null) + m_log.WarnFormat("[MODULE COMMANDS] Failed to register method {0}", method); + else + RegisterScriptInvocation(target, mi); + } + } + + public void RegisterScriptInvocations(IRegionModuleBase target) + { + foreach(MethodInfo method in target.GetType().GetMethods( + BindingFlags.Public | BindingFlags.Instance | + BindingFlags.Static)) + { + if(method.GetCustomAttributes( + typeof(ScriptInvocationAttribute), true).Any()) + { + if(method.IsStatic) + RegisterScriptInvocation(target.GetType(), method); + else + RegisterScriptInvocation(target, method); + } + } + } + + public Delegate[] GetScriptInvocationList() + { + List ret = new List(); + + lock (m_scriptInvocation) + { + foreach (ScriptInvocationData d in m_scriptInvocation.Values) + ret.Add(d.ScriptInvocationDelegate); + } + return ret.ToArray(); + } + + public string LookupModInvocation(string fname) + { + lock (m_scriptInvocation) + { + ScriptInvocationData sid; + if (m_scriptInvocation.TryGetValue(fname,out sid)) + { + if (sid.ReturnType == typeof(string)) + return "modInvokeS"; + else if (sid.ReturnType == typeof(int)) + return "modInvokeI"; + else if (sid.ReturnType == typeof(float)) + return "modInvokeF"; + else if (sid.ReturnType == typeof(UUID)) + return "modInvokeK"; + else if (sid.ReturnType == typeof(OpenMetaverse.Vector3)) + return "modInvokeV"; + else if (sid.ReturnType == typeof(OpenMetaverse.Quaternion)) + return "modInvokeR"; + else if (sid.ReturnType == typeof(object[])) + return "modInvokeL"; + + m_log.WarnFormat("[MODULE COMMANDS] failed to find match for {0} with return type {1}",fname,sid.ReturnType.Name); + } + } + + return null; + } + + public Delegate LookupScriptInvocation(string fname) + { + lock (m_scriptInvocation) + { + ScriptInvocationData sid; + if (m_scriptInvocation.TryGetValue(fname,out sid)) + return sid.ScriptInvocationDelegate; + } + + return null; + } + + public Type[] LookupTypeSignature(string fname) + { + lock (m_scriptInvocation) + { + ScriptInvocationData sid; + if (m_scriptInvocation.TryGetValue(fname,out sid)) + return sid.TypeSignature; + } + + return null; + } + + public Type LookupReturnType(string fname) + { + lock (m_scriptInvocation) + { + ScriptInvocationData sid; + if (m_scriptInvocation.TryGetValue(fname,out sid)) + return sid.ReturnType; + } + + return null; + } + + public object InvokeOperation(UUID hostid, UUID scriptid, string fname, params object[] parms) + { + List olist = new List(); + olist.Add(hostid); + olist.Add(scriptid); + foreach (object o in parms) + olist.Add(o); + Delegate fn = LookupScriptInvocation(fname); + return fn.DynamicInvoke(olist.ToArray()); + } + + /// + /// Operation to for a region module to register a constant to be used + /// by the script engine + /// + public void RegisterConstant(string cname, object value) + { + m_log.DebugFormat("[MODULE COMMANDS] register constant <{0}> with value {1}",cname,value.ToString()); + lock (m_constants) + { + m_constants.Add(cname,value); + } + } + + public void RegisterConstants(IRegionModuleBase target) + { + foreach (FieldInfo field in target.GetType().GetFields( + BindingFlags.Public | BindingFlags.Static | + BindingFlags.Instance)) + { + if (field.GetCustomAttributes( + typeof(ScriptConstantAttribute), true).Any()) + { + RegisterConstant(field.Name, field.GetValue(target)); + } + } + } + + /// + /// Operation to check for a registered constant + /// + public object LookupModConstant(string cname) + { + // m_log.DebugFormat("[MODULE COMMANDS] lookup constant <{0}>",cname); + + lock (m_constants) + { + object value = null; + if (m_constants.TryGetValue(cname,out value)) + return value; + } + + return null; + } + +#endregion + + } +} -- cgit v1.1 From 3db10fdbefa94509d318b9574e5a96c9567d5377 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 28 Sep 2012 01:50:21 +0100 Subject: Lock GDI+ portion og VectorRenderModule.GetDrawStringSize() to prevent concurrent thread use provoking mono crashes. Same rationale as commit 13690582. --- .../Scripting/VectorRender/VectorRenderModule.cs | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) (limited to 'OpenSim/Region/CoreModules/Scripting') diff --git a/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs b/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs index d82551e..b4e3d77 100644 --- a/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs @@ -112,14 +112,19 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender public void GetDrawStringSize(string text, string fontName, int fontSize, out double xSize, out double ySize) { - using (Font myFont = new Font(fontName, fontSize)) + lock (this) { - SizeF stringSize = new SizeF(); - lock (m_graph) + using (Font myFont = new Font(fontName, fontSize)) { - stringSize = m_graph.MeasureString(text, myFont); - xSize = stringSize.Width; - ySize = stringSize.Height; + SizeF stringSize = new SizeF(); + + // XXX: This lock may be unnecessary. + lock (m_graph) + { + stringSize = m_graph.MeasureString(text, myFont); + xSize = stringSize.Width; + ySize = stringSize.Height; + } } } } -- cgit v1.1 From 531edd51d82ecd6a842a2611c99e9919634491ef Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sun, 30 Sep 2012 07:22:55 -0700 Subject: Added request.Proxy=null everywhere, as discussed in http://stackoverflow.com/questions/2519655/httpwebrequest-is-extremely-slow. Thanks R.Gunther (rigun@rigutech.nl) https://lists.berlios.de/pipermail/opensim-users/2012-September/010986.html --- .../CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs | 1 + .../CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs | 12 +++++++----- .../CoreModules/Scripting/VectorRender/VectorRenderModule.cs | 1 + 3 files changed, 9 insertions(+), 5 deletions(-) (limited to 'OpenSim/Region/CoreModules/Scripting') diff --git a/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs b/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs index d328eb3..2be91c0 100644 --- a/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs +++ b/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs @@ -384,6 +384,7 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest Request = (HttpWebRequest) WebRequest.Create(Url); Request.Method = HttpMethod; Request.ContentType = HttpMIMEType; + Request.Proxy = null; if(!HttpVerifyCert) { diff --git a/OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs b/OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs index 45e6527..5af3326 100644 --- a/OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs @@ -148,19 +148,21 @@ namespace OpenSim.Region.CoreModules.Scripting.LoadImageURL private void MakeHttpRequest(string url, UUID requestID) { WebRequest request = HttpWebRequest.Create(url); - - if (m_proxyurl != null && m_proxyurl.Length > 0) + + if (m_proxyurl != null && m_proxyurl.Length > 0) { - if (m_proxyexcepts != null && m_proxyexcepts.Length > 0) + if (m_proxyexcepts != null && m_proxyexcepts.Length > 0) { string[] elist = m_proxyexcepts.Split(';'); request.Proxy = new WebProxy(m_proxyurl, true, elist); - } - else + } + else { request.Proxy = new WebProxy(m_proxyurl, true); } } + else + request.Proxy = null; RequestState state = new RequestState((HttpWebRequest) request, requestID); // IAsyncResult result = request.BeginGetResponse(new AsyncCallback(HttpRequestReturn), state); diff --git a/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs b/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs index b4e3d77..9def6ee 100644 --- a/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs @@ -826,6 +826,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender try { WebRequest request = HttpWebRequest.Create(url); + request.Proxy = null; //Ckrinke: Comment out for now as 'str' is unused. Bring it back into play later when it is used. //Ckrinke Stream str = null; HttpWebResponse response = (HttpWebResponse)(request).GetResponse(); -- cgit v1.1 From 91a5c602e313b96ffaf1d50b7f0d2923a2e141ba Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sun, 30 Sep 2012 07:48:03 -0700 Subject: Revert "Added request.Proxy=null everywhere, as discussed in http://stackoverflow.com/questions/2519655/httpwebrequest-is-extremely-slow." But the patch is here, in case anyone wants to try it. This reverts commit 531edd51d82ecd6a842a2611c99e9919634491ef. --- .../CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs | 1 - .../CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs | 12 +++++------- .../CoreModules/Scripting/VectorRender/VectorRenderModule.cs | 1 - 3 files changed, 5 insertions(+), 9 deletions(-) (limited to 'OpenSim/Region/CoreModules/Scripting') diff --git a/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs b/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs index 2be91c0..d328eb3 100644 --- a/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs +++ b/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs @@ -384,7 +384,6 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest Request = (HttpWebRequest) WebRequest.Create(Url); Request.Method = HttpMethod; Request.ContentType = HttpMIMEType; - Request.Proxy = null; if(!HttpVerifyCert) { diff --git a/OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs b/OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs index 5af3326..45e6527 100644 --- a/OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs @@ -148,21 +148,19 @@ namespace OpenSim.Region.CoreModules.Scripting.LoadImageURL private void MakeHttpRequest(string url, UUID requestID) { WebRequest request = HttpWebRequest.Create(url); - - if (m_proxyurl != null && m_proxyurl.Length > 0) + + if (m_proxyurl != null && m_proxyurl.Length > 0) { - if (m_proxyexcepts != null && m_proxyexcepts.Length > 0) + if (m_proxyexcepts != null && m_proxyexcepts.Length > 0) { string[] elist = m_proxyexcepts.Split(';'); request.Proxy = new WebProxy(m_proxyurl, true, elist); - } - else + } + else { request.Proxy = new WebProxy(m_proxyurl, true); } } - else - request.Proxy = null; RequestState state = new RequestState((HttpWebRequest) request, requestID); // IAsyncResult result = request.BeginGetResponse(new AsyncCallback(HttpRequestReturn), state); diff --git a/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs b/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs index 9def6ee..b4e3d77 100644 --- a/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs @@ -826,7 +826,6 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender try { WebRequest request = HttpWebRequest.Create(url); - request.Proxy = null; //Ckrinke: Comment out for now as 'str' is unused. Bring it back into play later when it is used. //Ckrinke Stream str = null; HttpWebResponse response = (HttpWebResponse)(request).GetResponse(); -- cgit v1.1 From 0f70460a320da5606f3bdf316d5d25611fb0b3fb Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 19 Oct 2012 00:39:18 +0100 Subject: minor: comment out currently unused logger in DynamicTextureModule --- .../Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region/CoreModules/Scripting') diff --git a/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs b/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs index 1f340df..93a045e 100644 --- a/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs @@ -42,7 +42,7 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture { public class DynamicTextureModule : IRegionModule, IDynamicTextureManager { - private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); +// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private const int ALL_SIDES = -1; -- cgit v1.1 From 18b1ee6f379f4d34f72a9056bf6cdf185311fd05 Mon Sep 17 00:00:00 2001 From: SignpostMarv Date: Tue, 23 Oct 2012 15:29:40 +0100 Subject: Formatting and casing correction in WorldCommModule, trailing new line in OSSL to get git diff to not complain --- OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region/CoreModules/Scripting') diff --git a/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs b/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs index 8358bc0..c68ed6b 100644 --- a/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs @@ -472,8 +472,8 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm if (coll.Count > 0) { - // special case, called with same filter settings, return same handle - // (2008-05-02, tested on 1.21.1 server, still holds) + // special case, called with same filter settings, return same + // handle (2008-05-02, tested on 1.21.1 server, still holds) return coll[0].GetHandle(); } @@ -712,7 +712,7 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm } } - public class ListenerInfo: IWorldCommListenerInfo + public class ListenerInfo : IWorldCommListenerInfo { private bool m_active; // Listener is active or not private int m_handle; // Assigned handle of this listener -- cgit v1.1 From e977761071a2d614a9a621437fbf86479b414759 Mon Sep 17 00:00:00 2001 From: SignpostMarv Date: Tue, 23 Oct 2012 15:42:16 +0100 Subject: adding ability for listeners to be filtered by regular expressions and a general-purpose function to see if a given string matches a given regex --- .../Scripting/WorldComm/WorldCommModule.cs | 129 ++++++++++++++++++--- 1 file changed, 110 insertions(+), 19 deletions(-) (limited to 'OpenSim/Region/CoreModules/Scripting') diff --git a/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs b/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs index c68ed6b..cf0eb2a 100644 --- a/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs @@ -28,6 +28,7 @@ using System; using System.Collections; using System.Collections.Generic; +using System.Text.RegularExpressions; using Nini.Config; using OpenMetaverse; using OpenSim.Framework; @@ -170,12 +171,42 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm /// UUID of the SceneObjectPart /// channel to listen on /// name to filter on - /// key to filter on (user given, could be totally faked) + /// + /// key to filter on (user given, could be totally faked) + /// /// msg to filter on /// number of the scripts handle - public int Listen(uint localID, UUID itemID, UUID hostID, int channel, string name, UUID id, string msg) + public int Listen(uint localID, UUID itemID, UUID hostID, int channel, + string name, UUID id, string msg) { - return m_listenerManager.AddListener(localID, itemID, hostID, channel, name, id, msg); + return m_listenerManager.AddListener(localID, itemID, hostID, + channel, name, id, msg); + } + + /// + /// Create a listen event callback with the specified filters. + /// The parameters localID,itemID are needed to uniquely identify + /// the script during 'peek' time. Parameter hostID is needed to + /// determine the position of the script. + /// + /// localID of the script engine + /// UUID of the script engine + /// UUID of the SceneObjectPart + /// channel to listen on + /// name to filter on + /// + /// key to filter on (user given, could be totally faked) + /// + /// msg to filter on + /// + /// Bitfield indicating which strings should be processed as regex. + /// + /// number of the scripts handle + public int Listen(uint localID, UUID itemID, UUID hostID, int channel, + string name, UUID id, string msg, int regexBitfield) + { + return m_listenerManager.AddListener(localID, itemID, hostID, + channel, name, id, msg, regexBitfield); } /// @@ -465,10 +496,20 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm m_curlisteners = 0; } - public int AddListener(uint localID, UUID itemID, UUID hostID, int channel, string name, UUID id, string msg) + public int AddListener(uint localID, UUID itemID, UUID hostID, + int channel, string name, UUID id, string msg) + { + return AddListener(localID, itemID, hostID, channel, name, id, + msg, 0); + } + + public int AddListener(uint localID, UUID itemID, UUID hostID, + int channel, string name, UUID id, string msg, + int regexBitfield) { // do we already have a match on this particular filter event? - List coll = GetListeners(itemID, channel, name, id, msg); + List coll = GetListeners(itemID, channel, name, id, + msg); if (coll.Count > 0) { @@ -485,7 +526,9 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm if (newHandle > 0) { - ListenerInfo li = new ListenerInfo(newHandle, localID, itemID, hostID, channel, name, id, msg); + ListenerInfo li = new ListenerInfo(newHandle, localID, + itemID, hostID, channel, name, id, msg, + regexBitfield); List listeners; if (!m_listeners.TryGetValue(channel,out listeners)) @@ -626,6 +669,22 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm return -1; } + /// These are duplicated from ScriptBaseClass + /// http://opensimulator.org/mantis/view.php?id=6106#c21945 + #region Constants for the bitfield parameter of osListenRegex + + /// + /// process name parameter as regex + /// + public const int OS_LISTEN_REGEX_NAME = 0x1; + + /// + /// process message parameter as regex + /// + public const int OS_LISTEN_REGEX_MESSAGE = 0x2; + + #endregion + // Theres probably a more clever and efficient way to // do this, maybe with regex. // PM2008: Ha, one could even be smart and define a specialized Enumerator. @@ -651,7 +710,10 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm { continue; } - if (li.GetName().Length > 0 && !li.GetName().Equals(name)) + if (li.GetName().Length > 0 && ( + ((li.GetRegexBitfield() & OS_LISTEN_REGEX_NAME) != OS_LISTEN_REGEX_NAME && !li.GetName().Equals(name)) || + ((li.GetRegexBitfield() & OS_LISTEN_REGEX_NAME) == OS_LISTEN_REGEX_NAME && !Regex.IsMatch(name, li.GetName())) + )) { continue; } @@ -659,7 +721,10 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm { continue; } - if (li.GetMessage().Length > 0 && !li.GetMessage().Equals(msg)) + if (li.GetMessage().Length > 0 && ( + ((li.GetRegexBitfield() & OS_LISTEN_REGEX_MESSAGE) != OS_LISTEN_REGEX_MESSAGE && !li.GetMessage().Equals(msg)) || + ((li.GetRegexBitfield() & OS_LISTEN_REGEX_MESSAGE) == OS_LISTEN_REGEX_MESSAGE && !Regex.IsMatch(msg, li.GetMessage())) + )) { continue; } @@ -692,10 +757,13 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm { int idx = 0; Object[] item = new Object[6]; + int dataItemLength = 6; while (idx < data.Length) { - Array.Copy(data, idx, item, 0, 6); + dataItemLength = (idx + 7 == data.Length || (idx + 7 < data.Length && data[idx + 7] is bool)) ? 7 : 6; + item = new Object[dataItemLength]; + Array.Copy(data, idx, item, 0, dataItemLength); ListenerInfo info = ListenerInfo.FromData(localID, itemID, hostID, item); @@ -707,7 +775,7 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm m_listeners[(int)item[2]].Add(info); } - idx+=6; + idx+=dataItemLength; } } } @@ -723,19 +791,33 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm private UUID m_id; // ID to filter messages from private string m_name; // Object name to filter messages from private string m_message; // The message + private int m_regexBitfield; // The regex bitfield public ListenerInfo(int handle, uint localID, UUID ItemID, UUID hostID, int channel, string name, UUID id, string message) { - Initialise(handle, localID, ItemID, hostID, channel, name, id, message); + Initialise(handle, localID, ItemID, hostID, channel, name, id, + message, 0); + } + + public ListenerInfo(int handle, uint localID, UUID ItemID, + UUID hostID, int channel, string name, UUID id, + string message, int regexBitfield) + { + Initialise(handle, localID, ItemID, hostID, channel, name, id, + message, regexBitfield); } public ListenerInfo(ListenerInfo li, string name, UUID id, string message) { - Initialise(li.m_handle, li.m_localID, li.m_itemID, li.m_hostID, li.m_channel, name, id, message); + Initialise(li.m_handle, li.m_localID, li.m_itemID, li.m_hostID, li.m_channel, name, id, message, 0); + } + + public ListenerInfo(ListenerInfo li, string name, UUID id, string message, int regexBitfield) + { + Initialise(li.m_handle, li.m_localID, li.m_itemID, li.m_hostID, li.m_channel, name, id, message, regexBitfield); } - private void Initialise(int handle, uint localID, UUID ItemID, UUID hostID, int channel, string name, - UUID id, string message) + private void Initialise(int handle, uint localID, UUID ItemID, UUID hostID, int channel, string name, UUID id, string message, int regexBitfield) { m_active = true; m_handle = handle; @@ -746,11 +828,12 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm m_name = name; m_id = id; m_message = message; + m_regexBitfield = regexBitfield; } public Object[] GetSerializationData() { - Object[] data = new Object[6]; + Object[] data = new Object[7]; data[0] = m_active; data[1] = m_handle; @@ -758,16 +841,19 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm data[3] = m_name; data[4] = m_id; data[5] = m_message; + data[6] = m_regexBitfield; return data; } public static ListenerInfo FromData(uint localID, UUID ItemID, UUID hostID, Object[] data) { - ListenerInfo linfo = new ListenerInfo((int)data[1], localID, - ItemID, hostID, (int)data[2], (string)data[3], - (UUID)data[4], (string)data[5]); - linfo.m_active=(bool)data[0]; + ListenerInfo linfo = new ListenerInfo((int)data[1], localID, ItemID, hostID, (int)data[2], (string)data[3], (UUID)data[4], (string)data[5]); + linfo.m_active = (bool)data[0]; + if (data.Length >= 7) + { + linfo.m_regexBitfield = (int)data[6]; + } return linfo; } @@ -826,5 +912,10 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm { return m_id; } + + public int GetRegexBitfield() + { + return m_regexBitfield; + } } } -- cgit v1.1 From 80dcc13af2b33a5621bac49f15cbf6a97d2d8e16 Mon Sep 17 00:00:00 2001 From: SignpostMarv Date: Tue, 23 Oct 2012 16:02:31 +0100 Subject: refactoring IWorldCommListenerInfo.GetRegexBitfield() method to be a field with a private setter --- .../Scripting/WorldComm/WorldCommModule.cs | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) (limited to 'OpenSim/Region/CoreModules/Scripting') diff --git a/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs b/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs index cf0eb2a..401ff6c 100644 --- a/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs @@ -711,8 +711,8 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm continue; } if (li.GetName().Length > 0 && ( - ((li.GetRegexBitfield() & OS_LISTEN_REGEX_NAME) != OS_LISTEN_REGEX_NAME && !li.GetName().Equals(name)) || - ((li.GetRegexBitfield() & OS_LISTEN_REGEX_NAME) == OS_LISTEN_REGEX_NAME && !Regex.IsMatch(name, li.GetName())) + ((li.RegexBitfield & OS_LISTEN_REGEX_NAME) != OS_LISTEN_REGEX_NAME && !li.GetName().Equals(name)) || + ((li.RegexBitfield & OS_LISTEN_REGEX_NAME) == OS_LISTEN_REGEX_NAME && !Regex.IsMatch(name, li.GetName())) )) { continue; @@ -722,8 +722,8 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm continue; } if (li.GetMessage().Length > 0 && ( - ((li.GetRegexBitfield() & OS_LISTEN_REGEX_MESSAGE) != OS_LISTEN_REGEX_MESSAGE && !li.GetMessage().Equals(msg)) || - ((li.GetRegexBitfield() & OS_LISTEN_REGEX_MESSAGE) == OS_LISTEN_REGEX_MESSAGE && !Regex.IsMatch(msg, li.GetMessage())) + ((li.RegexBitfield & OS_LISTEN_REGEX_MESSAGE) != OS_LISTEN_REGEX_MESSAGE && !li.GetMessage().Equals(msg)) || + ((li.RegexBitfield & OS_LISTEN_REGEX_MESSAGE) == OS_LISTEN_REGEX_MESSAGE && !Regex.IsMatch(msg, li.GetMessage())) )) { continue; @@ -791,7 +791,6 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm private UUID m_id; // ID to filter messages from private string m_name; // Object name to filter messages from private string m_message; // The message - private int m_regexBitfield; // The regex bitfield public ListenerInfo(int handle, uint localID, UUID ItemID, UUID hostID, int channel, string name, UUID id, string message) { @@ -828,7 +827,7 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm m_name = name; m_id = id; m_message = message; - m_regexBitfield = regexBitfield; + RegexBitfield = regexBitfield; } public Object[] GetSerializationData() @@ -841,7 +840,7 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm data[3] = m_name; data[4] = m_id; data[5] = m_message; - data[6] = m_regexBitfield; + data[6] = RegexBitfield; return data; } @@ -852,7 +851,7 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm linfo.m_active = (bool)data[0]; if (data.Length >= 7) { - linfo.m_regexBitfield = (int)data[6]; + linfo.RegexBitfield = (int)data[6]; } return linfo; @@ -913,9 +912,6 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm return m_id; } - public int GetRegexBitfield() - { - return m_regexBitfield; - } + public int RegexBitfield { get; private set; } } } -- cgit v1.1 From f391d028de3aff0cc49d024d855555253eb8c02c Mon Sep 17 00:00:00 2001 From: Melanie Date: Sun, 4 Nov 2012 22:01:34 +0100 Subject: Add a method to query all registered script constants to allow non-XEngine script engines to use them. --- .../ScriptModuleComms/ScriptModuleCommsModule.cs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'OpenSim/Region/CoreModules/Scripting') diff --git a/OpenSim/Region/CoreModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs b/OpenSim/Region/CoreModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs index 98396ff..dc54c3f 100644 --- a/OpenSim/Region/CoreModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs @@ -361,6 +361,22 @@ namespace OpenSim.Region.OptionalModules.Scripting.ScriptModuleComms return null; } + /// + /// Get all registered constants + /// + public Dictionary GetConstants() + { + Dictionary ret = new Dictionary(); + + lock (m_constants) + { + foreach (KeyValuePair kvp in m_constants) + ret[kvp.Key] = kvp.Value; + } + + return ret; + } + #endregion } -- cgit v1.1 From a87c4c7d8924138896ab93828cd8e7d8442fbaf7 Mon Sep 17 00:00:00 2001 From: SignpostMarv Date: Sun, 11 Nov 2012 00:21:10 +0000 Subject: Converting WorldCommModule to INonSharedRegionModule Signed-off-by: Diva Canto --- .../Scripting/WorldComm/WorldCommModule.cs | 36 +++++++++++++++------- 1 file changed, 25 insertions(+), 11 deletions(-) (limited to 'OpenSim/Region/CoreModules/Scripting') diff --git a/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs b/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs index 401ff6c..2c26e63 100644 --- a/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs @@ -30,6 +30,7 @@ using System.Collections; using System.Collections.Generic; using System.Text.RegularExpressions; using Nini.Config; +using Mono.Addins; using OpenMetaverse; using OpenSim.Framework; using OpenSim.Region.Framework.Interfaces; @@ -86,7 +87,8 @@ using OpenSim.Region.Framework.Scenes; namespace OpenSim.Region.CoreModules.Scripting.WorldComm { - public class WorldCommModule : IRegionModule, IWorldComm + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] + public class WorldCommModule : IWorldComm, INonSharedRegionModule { // private static readonly ILog m_log = // LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -99,9 +101,9 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm private int m_saydistance = 20; private int m_shoutdistance = 100; - #region IRegionModule Members + #region INonSharedRegionModule Members - public void Initialise(Scene scene, IConfigSource config) + public void Initialise(IConfigSource config) { // wrap this in a try block so that defaults will work if // the config file doesn't specify otherwise. @@ -120,18 +122,33 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm } if (maxlisteners < 1) maxlisteners = int.MaxValue; if (maxhandles < 1) maxhandles = int.MaxValue; + m_listenerManager = new ListenerManager(maxlisteners, maxhandles); + m_pendingQ = new Queue(); + m_pending = Queue.Synchronized(m_pendingQ); + } + public void PostInitialise() + { + } + + public void AddRegion(Scene scene) + { m_scene = scene; m_scene.RegisterModuleInterface(this); - m_listenerManager = new ListenerManager(maxlisteners, maxhandles); m_scene.EventManager.OnChatFromClient += DeliverClientMessage; m_scene.EventManager.OnChatBroadcast += DeliverClientMessage; - m_pendingQ = new Queue(); - m_pending = Queue.Synchronized(m_pendingQ); } - public void PostInitialise() + public void RegionLoaded(Scene scene) { } + + public void RemoveRegion(Scene scene) { + if (scene != m_scene) + return; + + m_scene.UnregisterModuleInterface(this); + m_scene.EventManager.OnChatBroadcast -= DeliverClientMessage; + m_scene.EventManager.OnChatBroadcast -= DeliverClientMessage; } public void Close() @@ -143,10 +160,7 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm get { return "WorldCommModule"; } } - public bool IsSharedModule - { - get { return false; } - } + public Type ReplaceableInterface { get { return null; } } #endregion -- cgit v1.1 From b3dddd7447c42a60f1e4a2452e6a6c6dbe9d5618 Mon Sep 17 00:00:00 2001 From: SignpostMarv Date: Sun, 11 Nov 2012 00:38:27 +0000 Subject: document & 80-character width terminal formatting Signed-off-by: Diva Canto --- .../Scripting/WorldComm/WorldCommModule.cs | 170 ++++++++++++++------- 1 file changed, 114 insertions(+), 56 deletions(-) (limited to 'OpenSim/Region/CoreModules/Scripting') diff --git a/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs b/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs index 2c26e63..c88be82 100644 --- a/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs @@ -29,9 +29,12 @@ using System; using System.Collections; using System.Collections.Generic; using System.Text.RegularExpressions; + using Nini.Config; using Mono.Addins; + using OpenMetaverse; + using OpenSim.Framework; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; @@ -111,11 +114,16 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm int maxhandles = 64; try { - m_whisperdistance = config.Configs["Chat"].GetInt("whisper_distance", m_whisperdistance); - m_saydistance = config.Configs["Chat"].GetInt("say_distance", m_saydistance); - m_shoutdistance = config.Configs["Chat"].GetInt("shout_distance", m_shoutdistance); - maxlisteners = config.Configs["LL-Functions"].GetInt("max_listens_per_region", maxlisteners); - maxhandles = config.Configs["LL-Functions"].GetInt("max_listens_per_script", maxhandles); + m_whisperdistance = config.Configs["Chat"].GetInt( + "whisper_distance", m_whisperdistance); + m_saydistance = config.Configs["Chat"].GetInt( + "say_distance", m_saydistance); + m_shoutdistance = config.Configs["Chat"].GetInt( + "shout_distance", m_shoutdistance); + maxlisteners = config.Configs["LL-Functions"].GetInt( + "max_listens_per_region", maxlisteners); + maxhandles = config.Configs["LL-Functions"].GetInt( + "max_listens_per_script", maxhandles); } catch (Exception) { @@ -269,7 +277,7 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm if ((source = m_scene.GetSceneObjectPart(id)) != null) position = source.AbsolutePosition; - else if ((avatar = m_scene.GetScenePresence(id)) != null) + else if ((avatar = m_scene.GetScenePresence(id)) != null) position = avatar.AbsolutePosition; else if (ChatTypeEnum.Region == type) position = CenterOfRegion; @@ -292,7 +300,8 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm /// name of sender (object or avatar) /// key of sender (object or avatar) /// msg to sent - public void DeliverMessage(ChatTypeEnum type, int channel, string name, UUID id, string msg, Vector3 position) + public void DeliverMessage(ChatTypeEnum type, int channel, + string name, UUID id, string msg, Vector3 position) { // m_log.DebugFormat("[WorldComm] got[2] type {0}, channel {1}, name {2}, id {3}, msg {4}", // type, channel, name, id, msg); @@ -300,17 +309,21 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm // Determine which listen event filters match the given set of arguments, this results // in a limited set of listeners, each belonging a host. If the host is in range, add them // to the pending queue. - foreach (ListenerInfo li in m_listenerManager.GetListeners(UUID.Zero, channel, name, id, msg)) + foreach (ListenerInfo li + in m_listenerManager.GetListeners(UUID.Zero, channel, + name, id, msg)) { // Dont process if this message is from yourself! if (li.GetHostID().Equals(id)) continue; - SceneObjectPart sPart = m_scene.GetSceneObjectPart(li.GetHostID()); + SceneObjectPart sPart = m_scene.GetSceneObjectPart( + li.GetHostID()); if (sPart == null) continue; - double dis = Util.GetDistanceTo(sPart.AbsolutePosition, position); + double dis = Util.GetDistanceTo(sPart.AbsolutePosition, + position); switch (type) { case ChatTypeEnum.Whisper: @@ -353,14 +366,16 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm /// /// Message. /// - public void DeliverMessageTo(UUID target, int channel, Vector3 pos, string name, UUID id, string msg) + public void DeliverMessageTo(UUID target, int channel, Vector3 pos, + string name, UUID id, string msg) { // Is id an avatar? ScenePresence sp = m_scene.GetScenePresence(target); if (sp != null) { - // ignore if a child agent this is restricted to inside one region + // ignore if a child agent this is restricted to inside one + // region if (sp.IsChildAgent) return; @@ -369,8 +384,9 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm // non zero channel messages only go to the attachments if (channel == 0) { - m_scene.SimChatToAgent(target, Utils.StringToBytes(msg), pos, name, id, false); - } + m_scene.SimChatToAgent(target, Utils.StringToBytes(msg), + pos, name, id, false); + } else { List attachments = sp.GetAttachments(); @@ -386,13 +402,18 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm } // Need to check each attachment - foreach (ListenerInfo li in m_listenerManager.GetListeners(UUID.Zero, channel, name, id, msg)) + foreach (ListenerInfo li + in m_listenerManager.GetListeners(UUID.Zero, + channel, name, id, msg)) { if (li.GetHostID().Equals(id)) continue; - if (m_scene.GetSceneObjectPart(li.GetHostID()) == null) + if (m_scene.GetSceneObjectPart( + li.GetHostID()) == null) + { continue; + } if (targets.Contains(li.GetHostID())) QueueMessage(new ListenerInfo(li, name, id, msg)); @@ -403,17 +424,20 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm } // No avatar found so look for an object - foreach (ListenerInfo li in m_listenerManager.GetListeners(UUID.Zero, channel, name, id, msg)) + foreach (ListenerInfo li + in m_listenerManager.GetListeners(UUID.Zero, channel, + name, id, msg)) { // Dont process if this message is from yourself! if (li.GetHostID().Equals(id)) continue; - SceneObjectPart sPart = m_scene.GetSceneObjectPart(li.GetHostID()); + SceneObjectPart sPart = m_scene.GetSceneObjectPart( + li.GetHostID()); if (sPart == null) continue; - if ( li.GetHostID().Equals(target)) + if (li.GetHostID().Equals(target)) { QueueMessage(new ListenerInfo(li, name, id, msg)); break; @@ -467,9 +491,15 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm private void DeliverClientMessage(Object sender, OSChatMessage e) { if (null != e.Sender) - DeliverMessage(e.Type, e.Channel, e.Sender.Name, e.Sender.AgentId, e.Message, e.Position); + { + DeliverMessage(e.Type, e.Channel, e.Sender.Name, + e.Sender.AgentId, e.Message, e.Position); + } else - DeliverMessage(e.Type, e.Channel, e.From, UUID.Zero, e.Message, e.Position); + { + DeliverMessage(e.Type, e.Channel, e.From, UUID.Zero, + e.Message, e.Position); + } } public Object[] GetSerializationData(UUID itemID) @@ -486,7 +516,8 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm public class ListenerManager { - private Dictionary> m_listeners = new Dictionary>(); + private Dictionary> m_listeners = + new Dictionary>(); private int m_maxlisteners; private int m_maxhandles; private int m_curlisteners; @@ -544,14 +575,15 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm itemID, hostID, channel, name, id, msg, regexBitfield); - List listeners; - if (!m_listeners.TryGetValue(channel,out listeners)) - { - listeners = new List(); - m_listeners.Add(channel, listeners); - } - listeners.Add(li); - m_curlisteners++; + List listeners; + if (!m_listeners.TryGetValue( + channel, out listeners)) + { + listeners = new List(); + m_listeners.Add(channel, listeners); + } + listeners.Add(li); + m_curlisteners++; return newHandle; } @@ -564,11 +596,13 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm { lock (m_listeners) { - foreach (KeyValuePair> lis in m_listeners) + foreach (KeyValuePair> lis + in m_listeners) { foreach (ListenerInfo li in lis.Value) { - if (li.GetItemID().Equals(itemID) && li.GetHandle().Equals(handle)) + if (li.GetItemID().Equals(itemID) && + li.GetHandle().Equals(handle)) { lis.Value.Remove(li); if (lis.Value.Count == 0) @@ -591,13 +625,15 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm lock (m_listeners) { - foreach (KeyValuePair> lis in m_listeners) + foreach (KeyValuePair> lis + in m_listeners) { foreach (ListenerInfo li in lis.Value) { if (li.GetItemID().Equals(itemID)) { - // store them first, else the enumerated bails on us + // store them first, else the enumerated bails on + // us removedListeners.Add(li); } } @@ -624,11 +660,13 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm { lock (m_listeners) { - foreach (KeyValuePair> lis in m_listeners) + foreach (KeyValuePair> lis + in m_listeners) { foreach (ListenerInfo li in lis.Value) { - if (li.GetItemID().Equals(itemID) && li.GetHandle() == handle) + if (li.GetItemID().Equals(itemID) && + li.GetHandle() == handle) { li.Activate(); // only one, bail out @@ -643,11 +681,13 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm { lock (m_listeners) { - foreach (KeyValuePair> lis in m_listeners) + foreach (KeyValuePair> lis + in m_listeners) { foreach (ListenerInfo li in lis.Value) { - if (li.GetItemID().Equals(itemID) && li.GetHandle() == handle) + if (li.GetItemID().Equals(itemID) && + li.GetHandle() == handle) { li.Deactivate(); // only one, bail out @@ -658,19 +698,24 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm } } - // non-locked access, since its always called in the context of the lock + /// + /// non-locked access, since its always called in the context of the + /// lock + /// + /// + /// private int GetNewHandle(UUID itemID) { List handles = new List(); // build a list of used keys for this specific itemID... - foreach (KeyValuePair> lis in m_listeners) + foreach (KeyValuePair> lis in m_listeners) { - foreach (ListenerInfo li in lis.Value) - { - if (li.GetItemID().Equals(itemID)) - handles.Add(li.GetHandle()); - } + foreach (ListenerInfo li in lis.Value) + { + if (li.GetItemID().Equals(itemID)) + handles.Add(li.GetHandle()); + } } // Note: 0 is NOT a valid handle for llListen() to return @@ -709,7 +754,7 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm lock (m_listeners) { List listeners; - if (!m_listeners.TryGetValue(channel,out listeners)) + if (!m_listeners.TryGetValue(channel, out listeners)) { return collection; } @@ -720,7 +765,8 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm { continue; } - if (!itemID.Equals(UUID.Zero) && !li.GetItemID().Equals(itemID)) + if (!itemID.Equals(UUID.Zero) && + !li.GetItemID().Equals(itemID)) { continue; } @@ -785,11 +831,14 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm lock (m_listeners) { if (!m_listeners.ContainsKey((int)item[2])) - m_listeners.Add((int)item[2], new List()); + { + m_listeners.Add((int)item[2], + new List()); + } m_listeners[(int)item[2]].Add(info); } - idx+=dataItemLength; + idx += dataItemLength; } } } @@ -820,17 +869,23 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm message, regexBitfield); } - public ListenerInfo(ListenerInfo li, string name, UUID id, string message) + public ListenerInfo(ListenerInfo li, string name, UUID id, + string message) { - Initialise(li.m_handle, li.m_localID, li.m_itemID, li.m_hostID, li.m_channel, name, id, message, 0); + Initialise(li.m_handle, li.m_localID, li.m_itemID, li.m_hostID, + li.m_channel, name, id, message, 0); } - public ListenerInfo(ListenerInfo li, string name, UUID id, string message, int regexBitfield) + public ListenerInfo(ListenerInfo li, string name, UUID id, + string message, int regexBitfield) { - Initialise(li.m_handle, li.m_localID, li.m_itemID, li.m_hostID, li.m_channel, name, id, message, regexBitfield); + Initialise(li.m_handle, li.m_localID, li.m_itemID, li.m_hostID, + li.m_channel, name, id, message, regexBitfield); } - private void Initialise(int handle, uint localID, UUID ItemID, UUID hostID, int channel, string name, UUID id, string message, int regexBitfield) + private void Initialise(int handle, uint localID, UUID ItemID, + UUID hostID, int channel, string name, UUID id, + string message, int regexBitfield) { m_active = true; m_handle = handle; @@ -859,9 +914,12 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm return data; } - public static ListenerInfo FromData(uint localID, UUID ItemID, UUID hostID, Object[] data) + public static ListenerInfo FromData(uint localID, UUID ItemID, + UUID hostID, Object[] data) { - ListenerInfo linfo = new ListenerInfo((int)data[1], localID, ItemID, hostID, (int)data[2], (string)data[3], (UUID)data[4], (string)data[5]); + ListenerInfo linfo = new ListenerInfo((int)data[1], localID, + ItemID, hostID, (int)data[2], (string)data[3], + (UUID)data[4], (string)data[5]); linfo.m_active = (bool)data[0]; if (data.Length >= 7) { -- cgit v1.1 From d5f9f5c9c347f6d858bf91de87a5ba71ba06082a Mon Sep 17 00:00:00 2001 From: SignpostMarv Date: Sun, 11 Nov 2012 00:39:10 +0000 Subject: document, 80-character width terminal formatting converting comments to documentation for IDE & doxygen goodness Signed-off-by: Diva Canto --- .../Scripting/WorldComm/WorldCommModule.cs | 80 ++++++++++++++++++---- 1 file changed, 65 insertions(+), 15 deletions(-) (limited to 'OpenSim/Region/CoreModules/Scripting') diff --git a/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs b/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs index c88be82..2d2ea2f 100644 --- a/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs @@ -744,10 +744,23 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm #endregion - // Theres probably a more clever and efficient way to - // do this, maybe with regex. - // PM2008: Ha, one could even be smart and define a specialized Enumerator. - public List GetListeners(UUID itemID, int channel, string name, UUID id, string msg) + /// + /// Get listeners matching the input parameters. + /// + /// + /// Theres probably a more clever and efficient way to do this, maybe + /// with regex. + /// PM2008: Ha, one could even be smart and define a specialized + /// Enumerator. + /// + /// + /// + /// + /// + /// + /// + public List GetListeners(UUID itemID, int channel, + string name, UUID id, string msg) { List collection = new List(); @@ -845,17 +858,54 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm public class ListenerInfo : IWorldCommListenerInfo { - private bool m_active; // Listener is active or not - private int m_handle; // Assigned handle of this listener - private uint m_localID; // Local ID from script engine - private UUID m_itemID; // ID of the host script engine - private UUID m_hostID; // ID of the host/scene part - private int m_channel; // Channel - private UUID m_id; // ID to filter messages from - private string m_name; // Object name to filter messages from - private string m_message; // The message - - public ListenerInfo(int handle, uint localID, UUID ItemID, UUID hostID, int channel, string name, UUID id, string message) + /// + /// Listener is active or not + /// + private bool m_active; + + /// + /// Assigned handle of this listener + /// + private int m_handle; + + /// + /// Local ID from script engine + /// + private uint m_localID; + + /// + /// ID of the host script engine + /// + private UUID m_itemID; + + /// + /// ID of the host/scene part + /// + private UUID m_hostID; + + /// + /// Channel + /// + private int m_channel; + + /// + /// ID to filter messages from + /// + private UUID m_id; + + /// + /// Object name to filter messages from + /// + private string m_name; + + /// + /// The message + /// + private string m_message; + + public ListenerInfo(int handle, uint localID, UUID ItemID, + UUID hostID, int channel, string name, UUID id, + string message) { Initialise(handle, localID, ItemID, hostID, channel, name, id, message, 0); -- cgit v1.1 From 84be90e5f83835800443dde3473545ad73c62a9b Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sun, 11 Nov 2012 14:00:58 -0800 Subject: One more module converted: EmailModule. --- .../Scripting/EMailModules/EmailModule.cs | 110 ++++++++++++--------- 1 file changed, 64 insertions(+), 46 deletions(-) (limited to 'OpenSim/Region/CoreModules/Scripting') diff --git a/OpenSim/Region/CoreModules/Scripting/EMailModules/EmailModule.cs b/OpenSim/Region/CoreModules/Scripting/EMailModules/EmailModule.cs index e91e8b9..d943b20 100644 --- a/OpenSim/Region/CoreModules/Scripting/EMailModules/EmailModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/EMailModules/EmailModule.cs @@ -37,10 +37,12 @@ using OpenMetaverse; using OpenSim.Framework; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; +using Mono.Addins; namespace OpenSim.Region.CoreModules.Scripting.EmailModules { - public class EmailModule : IRegionModule, IEmailModule + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "EmailModule")] + public class EmailModule : ISharedRegionModule, IEmailModule { // // Log @@ -72,31 +74,9 @@ namespace OpenSim.Region.CoreModules.Scripting.EmailModules private bool m_Enabled = false; - public void InsertEmail(UUID to, Email email) - { - // It's tempting to create the queue here. Don't; objects which have - // not yet called GetNextEmail should have no queue, and emails to them - // should be silently dropped. - - lock (m_MailQueues) - { - if (m_MailQueues.ContainsKey(to)) - { - if (m_MailQueues[to].Count >= m_MaxQueueSize) - { - // fail silently - return; - } - - lock (m_MailQueues[to]) - { - m_MailQueues[to].Add(email); - } - } - } - } + #region ISharedRegionModule - public void Initialise(Scene scene, IConfigSource config) + public void Initialise(IConfigSource config) { m_Config = config; IConfig SMTPConfig; @@ -129,36 +109,44 @@ namespace OpenSim.Region.CoreModules.Scripting.EmailModules SMTP_SERVER_PORT = SMTPConfig.GetInt("SMTP_SERVER_PORT", SMTP_SERVER_PORT); SMTP_SERVER_LOGIN = SMTPConfig.GetString("SMTP_SERVER_LOGIN", SMTP_SERVER_LOGIN); SMTP_SERVER_PASSWORD = SMTPConfig.GetString("SMTP_SERVER_PASSWORD", SMTP_SERVER_PASSWORD); - m_MaxEmailSize = SMTPConfig.GetInt("email_max_size", m_MaxEmailSize); + m_MaxEmailSize = SMTPConfig.GetInt("email_max_size", m_MaxEmailSize); } catch (Exception e) { - m_log.Error("[EMAIL] DefaultEmailModule not configured: "+ e.Message); + m_log.Error("[EMAIL] DefaultEmailModule not configured: " + e.Message); m_Enabled = false; return; } - // It's a go! - if (m_Enabled) + } + + public void AddRegion(Scene scene) + { + if (!m_Enabled) + return; + + // It's a go! + lock (m_Scenes) { - lock (m_Scenes) - { - // Claim the interface slot - scene.RegisterModuleInterface(this); + // Claim the interface slot + scene.RegisterModuleInterface(this); - // Add to scene list - if (m_Scenes.ContainsKey(scene.RegionInfo.RegionHandle)) - { - m_Scenes[scene.RegionInfo.RegionHandle] = scene; - } - else - { - m_Scenes.Add(scene.RegionInfo.RegionHandle, scene); - } + // Add to scene list + if (m_Scenes.ContainsKey(scene.RegionInfo.RegionHandle)) + { + m_Scenes[scene.RegionInfo.RegionHandle] = scene; + } + else + { + m_Scenes.Add(scene.RegionInfo.RegionHandle, scene); } - - m_log.Info("[EMAIL] Activated DefaultEmailModule"); } + + m_log.Info("[EMAIL] Activated DefaultEmailModule"); + } + + public void RemoveRegion(Scene scene) + { } public void PostInitialise() @@ -174,9 +162,39 @@ namespace OpenSim.Region.CoreModules.Scripting.EmailModules get { return "DefaultEmailModule"; } } - public bool IsSharedModule + public Type ReplaceableInterface + { + get { return null; } + } + + public void RegionLoaded(Scene scene) { - get { return true; } + } + + #endregion + + public void InsertEmail(UUID to, Email email) + { + // It's tempting to create the queue here. Don't; objects which have + // not yet called GetNextEmail should have no queue, and emails to them + // should be silently dropped. + + lock (m_MailQueues) + { + if (m_MailQueues.ContainsKey(to)) + { + if (m_MailQueues[to].Count >= m_MaxQueueSize) + { + // fail silently + return; + } + + lock (m_MailQueues[to]) + { + m_MailQueues[to].Add(email); + } + } + } } private bool IsLocal(UUID objectID) -- cgit v1.1 From 963b1e861c710337b23276680ddfb68ec2ceaadf Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sun, 11 Nov 2012 14:22:06 -0800 Subject: One more module converted: ScriptsHttpRequests. --- .../Scripting/HttpRequest/ScriptsHttpRequests.cs | 34 ++++++++++++++++------ 1 file changed, 25 insertions(+), 9 deletions(-) (limited to 'OpenSim/Region/CoreModules/Scripting') diff --git a/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs b/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs index d328eb3..a676971 100644 --- a/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs +++ b/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs @@ -41,6 +41,7 @@ using OpenSim.Framework.Servers; using OpenSim.Framework.Servers.HttpServer; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; +using Mono.Addins; /***************************************************** * @@ -87,7 +88,8 @@ using OpenSim.Region.Framework.Scenes; namespace OpenSim.Region.CoreModules.Scripting.HttpRequest { - public class HttpRequestModule : IRegionModule, IHttpRequestModule + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "HttpRequestModule")] + public class HttpRequestModule : ISharedRegionModule, IHttpRequestModule { private object HttpListLock = new object(); private int httpTimeout = 30000; @@ -270,24 +272,38 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest #endregion - #region IRegionModule Members + #region ISharedRegionModule Members - public void Initialise(Scene scene, IConfigSource config) + public void Initialise(IConfigSource config) { - m_scene = scene; - - m_scene.RegisterModuleInterface(this); - m_proxyurl = config.Configs["Startup"].GetString("HttpProxy"); m_proxyexcepts = config.Configs["Startup"].GetString("HttpProxyExceptions"); m_pendingRequests = new Dictionary(); } + public void AddRegion(Scene scene) + { + m_scene = scene; + + m_scene.RegisterModuleInterface(this); + } + + public void RemoveRegion(Scene scene) + { + scene.UnregisterModuleInterface(this); + if (scene == m_scene) + m_scene = null; + } + public void PostInitialise() { } + public void RegionLoaded(Scene scene) + { + } + public void Close() { } @@ -297,9 +313,9 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest get { return m_name; } } - public bool IsSharedModule + public Type ReplaceableInterface { - get { return true; } + get { return null; } } #endregion -- cgit v1.1 From 6759ed1013b78371b28c2d802c5d793e7b32c723 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sun, 11 Nov 2012 14:46:22 -0800 Subject: One more module converted: LoadImageURLModule. Also removed it from its hard-coded instantiation (I think I understood what the problem was, and that I've done it right). --- .../Scripting/LoadImageURL/LoadImageURLModule.cs | 57 ++++++++++++++-------- 1 file changed, 38 insertions(+), 19 deletions(-) (limited to 'OpenSim/Region/CoreModules/Scripting') diff --git a/OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs b/OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs index 45e6527..a08a183 100644 --- a/OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs @@ -37,16 +37,33 @@ using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; using log4net; using System.Reflection; +using Mono.Addins; namespace OpenSim.Region.CoreModules.Scripting.LoadImageURL { - public class LoadImageURLModule : IRegionModule, IDynamicTextureRender + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "LoadImageURLModule")] + public class LoadImageURLModule : ISharedRegionModule, IDynamicTextureRender { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private string m_name = "LoadImageURL"; private Scene m_scene; private IDynamicTextureManager m_textureManager; + private IDynamicTextureManager TextureManager + { + get + { + if (m_textureManager == null && m_scene != null) + { + m_textureManager = m_scene.RequestModuleInterface(); + if (m_textureManager != null) + { + m_textureManager.RegisterRender(GetContentType(), this); + } + } + return m_textureManager; + } + } private string m_proxyurl = ""; private string m_proxyexcepts = ""; @@ -104,29 +121,31 @@ namespace OpenSim.Region.CoreModules.Scripting.LoadImageURL #endregion - #region IRegionModule Members + #region ISharedRegionModule Members - public void Initialise(Scene scene, IConfigSource config) + public void Initialise(IConfigSource config) { - if (m_scene == null) - { - m_scene = scene; - } - m_proxyurl = config.Configs["Startup"].GetString("HttpProxy"); m_proxyexcepts = config.Configs["Startup"].GetString("HttpProxyExceptions"); } public void PostInitialise() { - if (m_scene != null) - { - m_textureManager = m_scene.RequestModuleInterface(); - if (m_textureManager != null) - { - m_textureManager.RegisterRender(GetContentType(), this); - } - } + } + + public void AddRegion(Scene scene) + { + if (m_scene == null) + m_scene = scene; + + } + + public void RemoveRegion(Scene scene) + { + } + + public void RegionLoaded(Scene scene) + { } public void Close() @@ -138,9 +157,9 @@ namespace OpenSim.Region.CoreModules.Scripting.LoadImageURL get { return m_name; } } - public bool IsSharedModule + public Type ReplaceableInterface { - get { return true; } + get { return null; } } #endregion @@ -252,7 +271,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LoadImageURL m_log.DebugFormat("[LOADIMAGEURLMODULE]: Returning {0} bytes of image data for request {1}", imageJ2000.Length, state.RequestID); - m_textureManager.ReturnData( + TextureManager.ReturnData( state.RequestID, new OpenSim.Region.CoreModules.Scripting.DynamicTexture.DynamicTexture( request.RequestUri, null, imageJ2000, newSize, false)); -- cgit v1.1 From 9f45198516ef7c7bfc92d638ae142d821852a4d9 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sun, 11 Nov 2012 14:54:40 -0800 Subject: One more module: DynamicTextureModule. Removed it from the special load in the beginning. --- .../DynamicTexture/DynamicTextureModule.cs | 38 +++++++++++++++------- 1 file changed, 27 insertions(+), 11 deletions(-) (limited to 'OpenSim/Region/CoreModules/Scripting') diff --git a/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs b/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs index 93a045e..9d90517 100644 --- a/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs @@ -37,10 +37,12 @@ using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; using log4net; using System.Reflection; +using Mono.Addins; namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture { - public class DynamicTextureModule : IRegionModule, IDynamicTextureManager + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "DynamicTextureModule")] + public class DynamicTextureModule : ISharedRegionModule, IDynamicTextureManager { // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -323,17 +325,30 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture #endregion - #region IRegionModule Members + #region ISharedRegionModule Members - public void Initialise(Scene scene, IConfigSource config) + public void Initialise(IConfigSource config) { IConfig texturesConfig = config.Configs["Textures"]; if (texturesConfig != null) { ReuseTextures = texturesConfig.GetBoolean("ReuseDynamicTextures", false); ReuseLowDataTextures = texturesConfig.GetBoolean("ReuseDynamicLowDataTextures", false); + + if (ReuseTextures) + { + m_reuseableDynamicTextures = new Cache(CacheMedium.Memory, CacheStrategy.Conservative); + m_reuseableDynamicTextures.DefaultTTL = new TimeSpan(24, 0, 0); + } } + } + + public void PostInitialise() + { + } + public void AddRegion(Scene scene) + { if (!RegisteredScenes.ContainsKey(scene.RegionInfo.RegionID)) { RegisteredScenes.Add(scene.RegionInfo.RegionID, scene); @@ -341,13 +356,14 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture } } - public void PostInitialise() + public void RegionLoaded(Scene scene) { - if (ReuseTextures) - { - m_reuseableDynamicTextures = new Cache(CacheMedium.Memory, CacheStrategy.Conservative); - m_reuseableDynamicTextures.DefaultTTL = new TimeSpan(24, 0, 0); - } + } + + public void RemoveRegion(Scene scene) + { + if (RegisteredScenes.ContainsKey(scene.RegionInfo.RegionID)) + RegisteredScenes.Remove(scene.RegionInfo.RegionID); } public void Close() @@ -359,9 +375,9 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture get { return "DynamicTextureModule"; } } - public bool IsSharedModule + public Type ReplaceableInterface { - get { return true; } + get { return null; } } #endregion -- cgit v1.1 From 4de8915dddf7fdf6456b471c303b4d214ad1bb8e Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sun, 11 Nov 2012 15:04:02 -0800 Subject: One more module converted: VectorRenderModule. --- .../Scripting/VectorRender/VectorRenderModule.cs | 68 +++++++++++++--------- 1 file changed, 41 insertions(+), 27 deletions(-) (limited to 'OpenSim/Region/CoreModules/Scripting') diff --git a/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs b/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs index b4e3d77..efa99e9 100644 --- a/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs @@ -40,12 +40,14 @@ using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; using log4net; using System.Reflection; +using Mono.Addins; //using Cairo; namespace OpenSim.Region.CoreModules.Scripting.VectorRender { - public class VectorRenderModule : IRegionModule, IDynamicTextureRender + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "VectorRenderModule")] + public class VectorRenderModule : ISharedRegionModule, IDynamicTextureRender { // These fields exist for testing purposes, please do not remove. // private static bool s_flipper; @@ -56,6 +58,22 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender private Scene m_scene; private IDynamicTextureManager m_textureManager; + private IDynamicTextureManager TextureManager + { + get + { + if (m_textureManager == null && m_scene != null) + { + m_textureManager = m_scene.RequestModuleInterface(); + if (m_textureManager != null) + { + m_textureManager.RegisterRender(GetContentType(), this); + } + } + return m_textureManager; + } + } + private Graphics m_graph; private string m_fontName = "Arial"; @@ -104,7 +122,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender public bool AsyncConvertData(UUID id, string bodyData, string extraParams) { // XXX: This isn't actually being done asynchronously! - m_textureManager.ReturnData(id, ConvertData(bodyData, extraParams)); + TextureManager.ReturnData(id, ConvertData(bodyData, extraParams)); return true; } @@ -131,45 +149,41 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender #endregion - #region IRegionModule Members + #region ISharedRegionModule Members - public void Initialise(Scene scene, IConfigSource config) + public void Initialise(IConfigSource config) { - if (m_scene == null) - { - m_scene = scene; - } - - if (m_graph == null) - { - // We won't dispose of these explicitly since this module is only removed when the entire simulator - // is shut down. - Bitmap bitmap = new Bitmap(1024, 1024, PixelFormat.Format32bppArgb); - m_graph = Graphics.FromImage(bitmap); - } - IConfig cfg = config.Configs["VectorRender"]; if (null != cfg) { m_fontName = cfg.GetString("font_name", m_fontName); } m_log.DebugFormat("[VECTORRENDERMODULE]: using font \"{0}\" for text rendering.", m_fontName); + + // We won't dispose of these explicitly since this module is only removed when the entire simulator + // is shut down. + Bitmap bitmap = new Bitmap(1024, 1024, PixelFormat.Format32bppArgb); + m_graph = Graphics.FromImage(bitmap); } public void PostInitialise() { - m_textureManager = m_scene.RequestModuleInterface(); - if (m_textureManager != null) + } + + public void AddRegion(Scene scene) + { + if (m_scene == null) { - m_textureManager.RegisterRender(GetContentType(), this); + m_scene = scene; } + } - // This code exists for testing purposes, please do not remove. -// s_asset1Data = m_scene.AssetService.Get("00000000-0000-1111-9999-000000000001").Data; -// s_asset1Data = m_scene.AssetService.Get("9f4acf0d-1841-4e15-bdb8-3a12efc9dd8f").Data; + public void RegionLoaded(Scene scene) + { + } - // Terrain dirt - smallest bin/assets file (6004 bytes) -// s_asset2Data = m_scene.AssetService.Get("b8d3965a-ad78-bf43-699b-bff8eca6c975").Data; + public void RemoveRegion(Scene scene) + { } public void Close() @@ -181,9 +195,9 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender get { return "VectorRenderModule"; } } - public bool IsSharedModule + public Type ReplaceableInterface { - get { return true; } + get { return null; } } #endregion -- cgit v1.1 From 571f6a030002e754e9c711218396fa649ac28de6 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sun, 11 Nov 2012 15:29:25 -0800 Subject: One more module converted: XMLRPCModule. Removed it from the special loading at start. --- .../CoreModules/Scripting/XMLRPC/XMLRPCModule.cs | 82 ++++++++++++++-------- 1 file changed, 51 insertions(+), 31 deletions(-) (limited to 'OpenSim/Region/CoreModules/Scripting') diff --git a/OpenSim/Region/CoreModules/Scripting/XMLRPC/XMLRPCModule.cs b/OpenSim/Region/CoreModules/Scripting/XMLRPC/XMLRPCModule.cs index 0003af2..385f5ad 100644 --- a/OpenSim/Region/CoreModules/Scripting/XMLRPC/XMLRPCModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/XMLRPC/XMLRPCModule.cs @@ -40,6 +40,7 @@ using OpenSim.Framework.Servers; using OpenSim.Framework.Servers.HttpServer; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; +using Mono.Addins; /***************************************************** * @@ -76,7 +77,8 @@ using OpenSim.Region.Framework.Scenes; namespace OpenSim.Region.CoreModules.Scripting.XMLRPC { - public class XMLRPCModule : IRegionModule, IXMLRPC + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "XMLRPCModule")] + public class XMLRPCModule : ISharedRegionModule, IXMLRPC { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -86,6 +88,10 @@ namespace OpenSim.Region.CoreModules.Scripting.XMLRPC private Dictionary m_openChannels; private Dictionary m_pendingSRDResponses; private int m_remoteDataPort = 0; + public int Port + { + get { return m_remoteDataPort; } + } private Dictionary m_rpcPending; private Dictionary m_rpcPendingResponses; @@ -94,34 +100,24 @@ namespace OpenSim.Region.CoreModules.Scripting.XMLRPC private int RemoteReplyScriptWait = 300; private object XMLRPCListLock = new object(); - #region IRegionModule Members + #region ISharedRegionModule Members - public void Initialise(Scene scene, IConfigSource config) + public void Initialise(IConfigSource config) { // We need to create these early because the scripts might be calling // But since this gets called for every region, we need to make sure they // get called only one time (or we lose any open channels) - if (null == m_openChannels) - { - m_openChannels = new Dictionary(); - m_rpcPending = new Dictionary(); - m_rpcPendingResponses = new Dictionary(); - m_pendingSRDResponses = new Dictionary(); + m_openChannels = new Dictionary(); + m_rpcPending = new Dictionary(); + m_rpcPendingResponses = new Dictionary(); + m_pendingSRDResponses = new Dictionary(); - try - { - m_remoteDataPort = config.Configs["XMLRPC"].GetInt("XmlRpcPort", m_remoteDataPort); - } - catch (Exception) - { - } + try + { + m_remoteDataPort = config.Configs["XMLRPC"].GetInt("XmlRpcPort", m_remoteDataPort); } - - if (!m_scenes.Contains(scene)) + catch (Exception) { - m_scenes.Add(scene); - - scene.RegisterModuleInterface(this); } } @@ -131,32 +127,56 @@ namespace OpenSim.Region.CoreModules.Scripting.XMLRPC { // Start http server // Attach xmlrpc handlers -// m_log.InfoFormat( -// "[XML RPC MODULE]: Starting up XMLRPC Server on port {0} for llRemoteData commands.", -// m_remoteDataPort); + // m_log.InfoFormat( + // "[XML RPC MODULE]: Starting up XMLRPC Server on port {0} for llRemoteData commands.", + // m_remoteDataPort); IHttpServer httpServer = MainServer.GetHttpServer((uint)m_remoteDataPort); httpServer.AddXmlRPCHandler("llRemoteData", XmlRpcRemoteData); } } - public void Close() + public void AddRegion(Scene scene) + { + if (!IsEnabled()) + return; + + if (!m_scenes.Contains(scene)) + { + m_scenes.Add(scene); + + scene.RegisterModuleInterface(this); + } + } + + public void RegionLoaded(Scene scene) { } - public string Name + public void RemoveRegion(Scene scene) { - get { return m_name; } + if (!IsEnabled()) + return; + + if (m_scenes.Contains(scene)) + { + scene.UnregisterModuleInterface(this); + m_scenes.Remove(scene); + } } - public bool IsSharedModule + public void Close() { - get { return true; } } - public int Port + public string Name { - get { return m_remoteDataPort; } + get { return m_name; } + } + + public Type ReplaceableInterface + { + get { return null; } } #endregion -- cgit v1.1 From db418bff2bb6b2676c996e77b260b0977e886f5d Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sun, 11 Nov 2012 19:39:21 -0800 Subject: Fix issues with the DynamicTextureModule and corresponding unit tests. --- .../DynamicTexture/DynamicTextureModule.cs | 10 +++++++ .../Scripting/LoadImageURL/LoadImageURLModule.cs | 31 +++++++++++----------- .../Scripting/VectorRender/VectorRenderModule.cs | 30 ++++++++++----------- 3 files changed, 39 insertions(+), 32 deletions(-) (limited to 'OpenSim/Region/CoreModules/Scripting') diff --git a/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs b/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs index 9d90517..9d77b19 100644 --- a/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs @@ -83,6 +83,16 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture /// private Cache m_reuseableDynamicTextures; + /// + /// This constructor is only here because of the Unit Tests... + /// Don't use it. + /// + public DynamicTextureModule() + { + m_reuseableDynamicTextures = new Cache(CacheMedium.Memory, CacheStrategy.Conservative); + m_reuseableDynamicTextures.DefaultTTL = new TimeSpan(24, 0, 0); + } + #region IDynamicTextureManager Members public void RegisterRender(string handleType, IDynamicTextureRender render) diff --git a/OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs b/OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs index a08a183..65737fa 100644 --- a/OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs @@ -49,21 +49,6 @@ namespace OpenSim.Region.CoreModules.Scripting.LoadImageURL private string m_name = "LoadImageURL"; private Scene m_scene; private IDynamicTextureManager m_textureManager; - private IDynamicTextureManager TextureManager - { - get - { - if (m_textureManager == null && m_scene != null) - { - m_textureManager = m_scene.RequestModuleInterface(); - if (m_textureManager != null) - { - m_textureManager.RegisterRender(GetContentType(), this); - } - } - return m_textureManager; - } - } private string m_proxyurl = ""; private string m_proxyexcepts = ""; @@ -146,6 +131,14 @@ namespace OpenSim.Region.CoreModules.Scripting.LoadImageURL public void RegionLoaded(Scene scene) { + if (m_textureManager == null && m_scene == scene) + { + m_textureManager = m_scene.RequestModuleInterface(); + if (m_textureManager != null) + { + m_textureManager.RegisterRender(GetContentType(), this); + } + } } public void Close() @@ -191,6 +184,12 @@ namespace OpenSim.Region.CoreModules.Scripting.LoadImageURL private void HttpRequestReturn(IAsyncResult result) { + if (m_textureManager == null) + { + m_log.WarnFormat("[LOADIMAGEURLMODULE]: No texture manager. Can't function."); + return; + } + RequestState state = (RequestState) result.AsyncState; WebRequest request = (WebRequest) state.Request; Stream stream = null; @@ -271,7 +270,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LoadImageURL m_log.DebugFormat("[LOADIMAGEURLMODULE]: Returning {0} bytes of image data for request {1}", imageJ2000.Length, state.RequestID); - TextureManager.ReturnData( + m_textureManager.ReturnData( state.RequestID, new OpenSim.Region.CoreModules.Scripting.DynamicTexture.DynamicTexture( request.RequestUri, null, imageJ2000, newSize, false)); diff --git a/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs b/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs index efa99e9..689e8a7 100644 --- a/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs @@ -58,21 +58,6 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender private Scene m_scene; private IDynamicTextureManager m_textureManager; - private IDynamicTextureManager TextureManager - { - get - { - if (m_textureManager == null && m_scene != null) - { - m_textureManager = m_scene.RequestModuleInterface(); - if (m_textureManager != null) - { - m_textureManager.RegisterRender(GetContentType(), this); - } - } - return m_textureManager; - } - } private Graphics m_graph; private string m_fontName = "Arial"; @@ -121,8 +106,13 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender public bool AsyncConvertData(UUID id, string bodyData, string extraParams) { + if (m_textureManager == null) + { + m_log.Warn("[VECTORRENDERMODULE]: No texture manager. Can't function"); + return false; + } // XXX: This isn't actually being done asynchronously! - TextureManager.ReturnData(id, ConvertData(bodyData, extraParams)); + m_textureManager.ReturnData(id, ConvertData(bodyData, extraParams)); return true; } @@ -180,6 +170,14 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender public void RegionLoaded(Scene scene) { + if (m_textureManager == null && m_scene == scene) + { + m_textureManager = m_scene.RequestModuleInterface(); + if (m_textureManager != null) + { + m_textureManager.RegisterRender(GetContentType(), this); + } + } } public void RemoveRegion(Scene scene) -- cgit v1.1 From 40d5148bbcc05d2cfd9ab14e06aee768b49819a0 Mon Sep 17 00:00:00 2001 From: Melanie Date: Tue, 13 Nov 2012 01:56:32 +0000 Subject: Update ScriptModuleComms name space to CoreModules --- .../CoreModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region/CoreModules/Scripting') diff --git a/OpenSim/Region/CoreModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs b/OpenSim/Region/CoreModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs index dc54c3f..f6e1d39 100644 --- a/OpenSim/Region/CoreModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs @@ -38,7 +38,7 @@ using OpenMetaverse; using System.Linq; using System.Linq.Expressions; -namespace OpenSim.Region.OptionalModules.Scripting.ScriptModuleComms +namespace OpenSim.Region.CoreModules.Scripting.ScriptModuleComms { [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "ScriptModuleCommsModule")] class ScriptModuleCommsModule : INonSharedRegionModule, IScriptModuleComms -- cgit v1.1 From 86903f23dd9c0e671fcc9854c031bcc0c6d6cc7f Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Mon, 12 Nov 2012 18:08:02 -0800 Subject: Cleanup on region modules: gave short node id's to all of them. --- OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region/CoreModules/Scripting') diff --git a/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs b/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs index 2d2ea2f..2c2c99c 100644 --- a/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs @@ -90,7 +90,7 @@ using OpenSim.Region.Framework.Scenes; namespace OpenSim.Region.CoreModules.Scripting.WorldComm { - [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "WorldCommModule")] public class WorldCommModule : IWorldComm, INonSharedRegionModule { // private static readonly ILog m_log = -- cgit v1.1 From 608444c9f712cf76fd5560d012b0f90fe2a3986e Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Tue, 13 Nov 2012 08:27:51 -0800 Subject: Another 21 modules' directives moved out of .addin.xml --- OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs | 2 ++ 1 file changed, 2 insertions(+) (limited to 'OpenSim/Region/CoreModules/Scripting') diff --git a/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs b/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs index 53a9679..a654477 100644 --- a/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs @@ -31,6 +31,7 @@ using System.Collections.Generic; using System.Collections; using System.Reflection; using log4net; +using Mono.Addins; using Nini.Config; using OpenMetaverse; using OpenSim.Framework; @@ -94,6 +95,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp /// /// This module provides external URLs for in-world scripts. /// + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "UrlModule")] public class UrlModule : ISharedRegionModule, IUrlModule { private static readonly ILog m_log = -- cgit v1.1