diff options
41 files changed, 822 insertions, 2788 deletions
diff --git a/OpenSim/Client/MXP/ClientStack/MXPClientView.cs b/OpenSim/Client/MXP/ClientStack/MXPClientView.cs index 02eaf5d..e901ff6 100644 --- a/OpenSim/Client/MXP/ClientStack/MXPClientView.cs +++ b/OpenSim/Client/MXP/ClientStack/MXPClientView.cs | |||
@@ -826,12 +826,7 @@ namespace OpenSim.Client.MXP.ClientStack | |||
826 | OpenSim.Region.Framework.Scenes.Scene scene=(OpenSim.Region.Framework.Scenes.Scene)Scene; | 826 | OpenSim.Region.Framework.Scenes.Scene scene=(OpenSim.Region.Framework.Scenes.Scene)Scene; |
827 | AvatarAppearance appearance; | 827 | AvatarAppearance appearance; |
828 | scene.GetAvatarAppearance(this,out appearance); | 828 | scene.GetAvatarAppearance(this,out appearance); |
829 | List<byte> visualParams = new List<byte>(); | 829 | OnSetAppearance(appearance.Texture, (byte[])appearance.VisualParams.Clone()); |
830 | foreach (byte visualParam in appearance.VisualParams) | ||
831 | { | ||
832 | visualParams.Add(visualParam); | ||
833 | } | ||
834 | OnSetAppearance(appearance.Texture.GetBytes(), visualParams); | ||
835 | } | 830 | } |
836 | 831 | ||
837 | public void Stop() | 832 | public void Stop() |
@@ -1649,5 +1644,9 @@ namespace OpenSim.Client.MXP.ClientStack | |||
1649 | public void SendPickInfoReply(UUID pickID,UUID creatorID, bool topPick, UUID parcelID, string name, string desc, UUID snapshotID, string user, string originalName, string simName, Vector3 posGlobal, int sortOrder, bool enabled) | 1644 | public void SendPickInfoReply(UUID pickID,UUID creatorID, bool topPick, UUID parcelID, string name, string desc, UUID snapshotID, string user, string originalName, string simName, Vector3 posGlobal, int sortOrder, bool enabled) |
1650 | { | 1645 | { |
1651 | } | 1646 | } |
1647 | |||
1648 | public void SendRebakeAvatarTextures(UUID textureID) | ||
1649 | { | ||
1650 | } | ||
1652 | } | 1651 | } |
1653 | } | 1652 | } |
diff --git a/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs b/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs index bfca954..8c9eb5f 100644 --- a/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs +++ b/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs | |||
@@ -1145,5 +1145,9 @@ namespace OpenSim.Client.VWoHTTP.ClientStack | |||
1145 | } | 1145 | } |
1146 | 1146 | ||
1147 | #endregion | 1147 | #endregion |
1148 | |||
1149 | public void SendRebakeAvatarTextures(UUID textureID) | ||
1150 | { | ||
1151 | } | ||
1148 | } | 1152 | } |
1149 | } | 1153 | } |
diff --git a/OpenSim/Framework/AvatarAppearance.cs b/OpenSim/Framework/AvatarAppearance.cs index 940ae3b..3f4214e 100644 --- a/OpenSim/Framework/AvatarAppearance.cs +++ b/OpenSim/Framework/AvatarAppearance.cs | |||
@@ -380,13 +380,13 @@ namespace OpenSim.Framework | |||
380 | /// <summary> | 380 | /// <summary> |
381 | /// Set up appearance textures and avatar parameters, including a height calculation | 381 | /// Set up appearance textures and avatar parameters, including a height calculation |
382 | /// </summary> | 382 | /// </summary> |
383 | /// <param name="texture"></param> | 383 | public virtual void SetAppearance(Primitive.TextureEntry textureEntry, byte[] visualParams) |
384 | /// <param name="visualParam"></param> | ||
385 | public virtual void SetAppearance(byte[] texture, List<byte> visualParam) | ||
386 | { | 384 | { |
387 | Primitive.TextureEntry textureEnt = new Primitive.TextureEntry(texture, 0, texture.Length); | 385 | if (textureEntry != null) |
388 | m_texture = textureEnt; | 386 | m_texture = textureEntry; |
389 | m_visualparams = visualParam.ToArray(); | 387 | if (visualParams != null) |
388 | m_visualparams = visualParams; | ||
389 | |||
390 | m_avatarHeight = 1.23077f // Shortest possible avatar height | 390 | m_avatarHeight = 1.23077f // Shortest possible avatar height |
391 | + 0.516945f * (float)m_visualparams[(int)VPElement.SHAPE_HEIGHT] / 255.0f // Body height | 391 | + 0.516945f * (float)m_visualparams[(int)VPElement.SHAPE_HEIGHT] / 255.0f // Body height |
392 | + 0.072514f * (float)m_visualparams[(int)VPElement.SHAPE_HEAD_SIZE] / 255.0f // Head size | 392 | + 0.072514f * (float)m_visualparams[(int)VPElement.SHAPE_HEAD_SIZE] / 255.0f // Head size |
diff --git a/OpenSim/Framework/BlockingQueue.cs b/OpenSim/Framework/BlockingQueue.cs index e03229b..857930a 100644 --- a/OpenSim/Framework/BlockingQueue.cs +++ b/OpenSim/Framework/BlockingQueue.cs | |||
@@ -66,7 +66,9 @@ namespace OpenSim.Framework | |||
66 | if (m_pqueue.Count > 0) | 66 | if (m_pqueue.Count > 0) |
67 | return m_pqueue.Dequeue(); | 67 | return m_pqueue.Dequeue(); |
68 | 68 | ||
69 | return m_queue.Dequeue(); | 69 | if (m_queue.Count > 0) |
70 | return m_queue.Dequeue(); | ||
71 | return default(T); | ||
70 | } | 72 | } |
71 | } | 73 | } |
72 | 74 | ||
@@ -119,6 +121,7 @@ namespace OpenSim.Framework | |||
119 | { | 121 | { |
120 | m_pqueue.Clear(); | 122 | m_pqueue.Clear(); |
121 | m_queue.Clear(); | 123 | m_queue.Clear(); |
124 | Monitor.Pulse(m_queueSync); | ||
122 | } | 125 | } |
123 | } | 126 | } |
124 | } | 127 | } |
diff --git a/OpenSim/Framework/IClientAPI.cs b/OpenSim/Framework/IClientAPI.cs index 4bc35e6..d3bd9e7 100644 --- a/OpenSim/Framework/IClientAPI.cs +++ b/OpenSim/Framework/IClientAPI.cs | |||
@@ -65,7 +65,7 @@ namespace OpenSim.Framework | |||
65 | 65 | ||
66 | public delegate void NetworkStats(int inPackets, int outPackets, int unAckedBytes); | 66 | public delegate void NetworkStats(int inPackets, int outPackets, int unAckedBytes); |
67 | 67 | ||
68 | public delegate void SetAppearance(byte[] texture, List<byte> visualParamList); | 68 | public delegate void SetAppearance(Primitive.TextureEntry textureEntry, byte[] visualParams); |
69 | 69 | ||
70 | public delegate void StartAnim(IClientAPI remoteClient, UUID animID); | 70 | public delegate void StartAnim(IClientAPI remoteClient, UUID animID); |
71 | 71 | ||
@@ -1127,7 +1127,6 @@ namespace OpenSim.Framework | |||
1127 | 1127 | ||
1128 | void SetClientOption(string option, string value); | 1128 | void SetClientOption(string option, string value); |
1129 | string GetClientOption(string option); | 1129 | string GetClientOption(string option); |
1130 | void Terminate(); | ||
1131 | 1130 | ||
1132 | void SendSetFollowCamProperties(UUID objectID, SortedDictionary<int, float> parameters); | 1131 | void SendSetFollowCamProperties(UUID objectID, SortedDictionary<int, float> parameters); |
1133 | void SendClearFollowCamProperties(UUID objectID); | 1132 | void SendClearFollowCamProperties(UUID objectID); |
@@ -1175,5 +1174,7 @@ namespace OpenSim.Framework | |||
1175 | void KillEndDone(); | 1174 | void KillEndDone(); |
1176 | 1175 | ||
1177 | bool AddGenericPacketHandler(string MethodName, GenericMessage handler); | 1176 | bool AddGenericPacketHandler(string MethodName, GenericMessage handler); |
1177 | |||
1178 | void SendRebakeAvatarTextures(UUID textureID); | ||
1178 | } | 1179 | } |
1179 | } | 1180 | } |
diff --git a/OpenSim/Framework/PacketPool.cs b/OpenSim/Framework/PacketPool.cs index 8075ce6..7e2860e 100644 --- a/OpenSim/Framework/PacketPool.cs +++ b/OpenSim/Framework/PacketPool.cs | |||
@@ -234,7 +234,8 @@ namespace OpenSim.Framework | |||
234 | 234 | ||
235 | lock (DataBlocks) | 235 | lock (DataBlocks) |
236 | { | 236 | { |
237 | DataBlocks[typeof(T)].Push(block); | 237 | if (DataBlocks[typeof(T)].Count < 50) |
238 | DataBlocks[typeof(T)].Push(block); | ||
238 | } | 239 | } |
239 | } | 240 | } |
240 | } | 241 | } |
diff --git a/OpenSim/Framework/Servers/HttpServer/Tests/BaseRequestHandlerTests.cs b/OpenSim/Framework/Servers/HttpServer/Tests/BaseRequestHandlerTests.cs deleted file mode 100644 index 2fa118d..0000000 --- a/OpenSim/Framework/Servers/HttpServer/Tests/BaseRequestHandlerTests.cs +++ /dev/null | |||
@@ -1,70 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | using System; | ||
29 | using System.Collections.Generic; | ||
30 | using System.Text; | ||
31 | using NUnit.Framework; | ||
32 | using OpenSim.Tests.Common.Setup; | ||
33 | |||
34 | namespace OpenSim.Framework.Servers.HttpServer.Tests | ||
35 | { | ||
36 | [TestFixture] | ||
37 | public class BaseRequestHandlerTests | ||
38 | { | ||
39 | private const string BASE_PATH = "/testpath"; | ||
40 | |||
41 | private class BaseRequestHandlerImpl : BaseRequestHandler | ||
42 | { | ||
43 | public BaseRequestHandlerImpl(string httpMethod, string path) : base(httpMethod, path) | ||
44 | { | ||
45 | } | ||
46 | } | ||
47 | |||
48 | [Test] | ||
49 | public void TestConstructor() | ||
50 | { | ||
51 | new BaseRequestHandlerImpl(null, null); | ||
52 | } | ||
53 | |||
54 | [Test] | ||
55 | public void TestGetParams() | ||
56 | { | ||
57 | BaseRequestHandlerImpl handler = new BaseRequestHandlerImpl(null, BASE_PATH); | ||
58 | |||
59 | BaseRequestHandlerTestHelper.BaseTestGetParams(handler, BASE_PATH); | ||
60 | } | ||
61 | |||
62 | [Test] | ||
63 | public void TestSplitParams() | ||
64 | { | ||
65 | BaseRequestHandlerImpl handler = new BaseRequestHandlerImpl(null, BASE_PATH); | ||
66 | |||
67 | BaseRequestHandlerTestHelper.BaseTestSplitParams(handler, BASE_PATH); | ||
68 | } | ||
69 | } | ||
70 | } | ||
diff --git a/OpenSim/Framework/Tests/AgentCircuitDataTest.cs b/OpenSim/Framework/Tests/AgentCircuitDataTest.cs index ecd35c0..2fda6f3 100644 --- a/OpenSim/Framework/Tests/AgentCircuitDataTest.cs +++ b/OpenSim/Framework/Tests/AgentCircuitDataTest.cs | |||
@@ -227,8 +227,7 @@ namespace OpenSim.Framework.Tests | |||
227 | wearbyte.Add(VisualParams[i]); | 227 | wearbyte.Add(VisualParams[i]); |
228 | } | 228 | } |
229 | 229 | ||
230 | 230 | AvAppearance.SetAppearance(AvAppearance.Texture, (byte[])VisualParams.Clone()); | |
231 | AvAppearance.SetAppearance(AvAppearance.Texture.GetBytes(), wearbyte); | ||
232 | } | 231 | } |
233 | 232 | ||
234 | /// <summary> | 233 | /// <summary> |
diff --git a/OpenSim/Region/Application/OpenSim.cs b/OpenSim/Region/Application/OpenSim.cs index f070812..4d8409bb 100644 --- a/OpenSim/Region/Application/OpenSim.cs +++ b/OpenSim/Region/Application/OpenSim.cs | |||
@@ -306,10 +306,6 @@ namespace OpenSim | |||
306 | "delete-region <name>", | 306 | "delete-region <name>", |
307 | "Delete a region from disk", RunCommand); | 307 | "Delete a region from disk", RunCommand); |
308 | 308 | ||
309 | m_console.Commands.AddCommand("region", false, "predecode-j2k", | ||
310 | "predecode-j2k [<num threads>]>", | ||
311 | "Precache assets,decode j2k layerdata", RunCommand); | ||
312 | |||
313 | m_console.Commands.AddCommand("region", false, "modules list", | 309 | m_console.Commands.AddCommand("region", false, "modules list", |
314 | "modules list", | 310 | "modules list", |
315 | "List modules", HandleModules); | 311 | "List modules", HandleModules); |
@@ -744,17 +740,6 @@ namespace OpenSim | |||
744 | } | 740 | } |
745 | break; | 741 | break; |
746 | 742 | ||
747 | case "predecode-j2k": | ||
748 | if (cmdparams.Length > 0) | ||
749 | { | ||
750 | m_sceneManager.CacheJ2kDecode(Convert.ToInt32(cmdparams[0])); | ||
751 | } | ||
752 | else | ||
753 | { | ||
754 | m_sceneManager.CacheJ2kDecode(1); | ||
755 | } | ||
756 | break; | ||
757 | |||
758 | } | 743 | } |
759 | } | 744 | } |
760 | 745 | ||
diff --git a/OpenSim/Region/ClientStack/LindenUDP/ILLPacketHandler.cs b/OpenSim/Region/ClientStack/LindenUDP/ILLPacketHandler.cs index 32a4ad4..31f9580 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/ILLPacketHandler.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/ILLPacketHandler.cs | |||
@@ -34,16 +34,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
34 | { | 34 | { |
35 | public delegate void PacketStats(int inPackets, int outPackets, int unAckedBytes); | 35 | public delegate void PacketStats(int inPackets, int outPackets, int unAckedBytes); |
36 | public delegate void PacketDrop(Packet pack, Object id); | 36 | public delegate void PacketDrop(Packet pack, Object id); |
37 | public delegate void QueueEmpty(ThrottleOutPacketType queue); | ||
37 | public delegate bool SynchronizeClientHandler(IScene scene, Packet packet, UUID agentID, ThrottleOutPacketType throttlePacketType); | 38 | public delegate bool SynchronizeClientHandler(IScene scene, Packet packet, UUID agentID, ThrottleOutPacketType throttlePacketType); |
38 | 39 | ||
39 | /// <summary> | 40 | /// <summary> |
40 | /// Interface to a class that handles all the activity involved with maintaining the client circuit (handling acks, | 41 | /// Interface to a class that handles all the activity involved with maintaining the client circuit (handling acks, |
41 | /// resends, pings, etc.) | 42 | /// resends, pings, etc.) |
42 | /// </summary> | 43 | /// </summary> |
43 | public interface ILLPacketHandler | 44 | public interface ILLPacketHandler : IDisposable |
44 | { | 45 | { |
45 | event PacketStats OnPacketStats; | 46 | event PacketStats OnPacketStats; |
46 | event PacketDrop OnPacketDrop; | 47 | event PacketDrop OnPacketDrop; |
48 | event QueueEmpty OnQueueEmpty; | ||
47 | SynchronizeClientHandler SynchronizeClient { set; } | 49 | SynchronizeClientHandler SynchronizeClient { set; } |
48 | 50 | ||
49 | int PacketsReceived { get; } | 51 | int PacketsReceived { get; } |
@@ -70,12 +72,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
70 | void OutPacket(Packet NewPack, | 72 | void OutPacket(Packet NewPack, |
71 | ThrottleOutPacketType throttlePacketType, Object id); | 73 | ThrottleOutPacketType throttlePacketType, Object id); |
72 | LLPacketQueue PacketQueue { get; } | 74 | LLPacketQueue PacketQueue { get; } |
73 | void Stop(); | ||
74 | void Flush(); | 75 | void Flush(); |
75 | void Clear(); | 76 | void Clear(); |
76 | ClientInfo GetClientInfo(); | 77 | ClientInfo GetClientInfo(); |
77 | void SetClientInfo(ClientInfo info); | 78 | void SetClientInfo(ClientInfo info); |
78 | void AddImportantPacket(PacketType type); | 79 | void AddImportantPacket(PacketType type); |
79 | void RemoveImportantPacket(PacketType type); | 80 | void RemoveImportantPacket(PacketType type); |
81 | int GetQueueCount(ThrottleOutPacketType queue); | ||
80 | } | 82 | } |
81 | } | 83 | } |
diff --git a/OpenSim/Region/ClientStack/LindenUDP/J2KImage.cs b/OpenSim/Region/ClientStack/LindenUDP/J2KImage.cs index 638c765..5f549b5 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/J2KImage.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/J2KImage.cs | |||
@@ -38,40 +38,37 @@ using System.Reflection; | |||
38 | namespace OpenSim.Region.ClientStack.LindenUDP | 38 | namespace OpenSim.Region.ClientStack.LindenUDP |
39 | { | 39 | { |
40 | /// <summary> | 40 | /// <summary> |
41 | /// We use this class to store image data and associated request data and attributes | 41 | /// Stores information about a current texture download and a reference to the texture asset |
42 | /// </summary> | 42 | /// </summary> |
43 | public class J2KImage | 43 | public class J2KImage |
44 | { | 44 | { |
45 | private const int IMAGE_PACKET_SIZE = 1000; | ||
46 | private const int FIRST_PACKET_SIZE = 600; | ||
47 | |||
45 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 48 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
46 | 49 | ||
47 | public double m_designatedPriorityKey; | 50 | public uint m_lastSequence; |
48 | public double m_requestedPriority = 0.0d; | 51 | public float m_requestedPriority; |
49 | public uint m_lastSequence = 0; | ||
50 | public uint m_requestedPacketNumber; | 52 | public uint m_requestedPacketNumber; |
51 | public sbyte m_requestedDiscardLevel; | 53 | public sbyte m_requestedDiscardLevel; |
52 | public UUID m_requestedUUID; | 54 | public UUID m_requestedUUID; |
53 | public IJ2KDecoder m_j2kDecodeModule; | 55 | public IJ2KDecoder m_j2kDecodeModule; |
54 | public IAssetService m_assetCache; | 56 | public IAssetService m_assetCache; |
55 | public OpenJPEG.J2KLayerInfo[] Layers = new OpenJPEG.J2KLayerInfo[0]; | 57 | public OpenJPEG.J2KLayerInfo[] m_layers; |
56 | public AssetBase m_MissingSubstitute = null; | 58 | public bool m_decoded; |
57 | public bool m_decoded = false; | 59 | public bool m_hasasset; |
58 | public bool m_completedSendAtCurrentDiscardLevel; | 60 | public C5.IPriorityQueueHandle<J2KImage> m_priorityQueueHandle; |
59 | 61 | ||
60 | private sbyte m_discardLevel=-1; | ||
61 | private uint m_packetNumber; | 62 | private uint m_packetNumber; |
62 | private bool m_decoderequested = false; | 63 | private bool m_decoderequested; |
63 | private bool m_hasasset = false; | 64 | private bool m_asset_requested; |
64 | private bool m_asset_requested = false; | 65 | private bool m_sentinfo; |
65 | private bool m_sentinfo = false; | 66 | private uint m_stopPacket; |
66 | private uint m_stopPacket = 0; | 67 | private AssetBase m_asset; |
67 | private const int cImagePacketSize = 1000; | 68 | private int m_assetDataLength; |
68 | private const int cFirstPacketSize = 600; | 69 | private LLImageManager m_imageManager; |
69 | private AssetBase m_asset = null; | 70 | |
70 | private LLImageManager m_image; | 71 | #region Properties |
71 | public J2KImage(LLImageManager image) | ||
72 | { | ||
73 | m_image = image; | ||
74 | } | ||
75 | 72 | ||
76 | public uint m_pPacketNumber | 73 | public uint m_pPacketNumber |
77 | { | 74 | { |
@@ -84,10 +81,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
84 | 81 | ||
85 | public byte[] Data | 82 | public byte[] Data |
86 | { | 83 | { |
87 | get | 84 | get |
88 | { | 85 | { |
89 | if (m_asset != null) | 86 | if (m_asset != null) |
90 | return m_asset.Data; | 87 | return m_asset.Data; |
91 | else | 88 | else |
92 | return null; | 89 | return null; |
93 | } | 90 | } |
@@ -97,9 +94,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
97 | { | 94 | { |
98 | if (!m_decoded) | 95 | if (!m_decoded) |
99 | return 0; | 96 | return 0; |
97 | |||
100 | try | 98 | try |
101 | { | 99 | { |
102 | return (ushort)(((m_asset.Data.Length - cFirstPacketSize + cImagePacketSize - 1) / cImagePacketSize) + 1); | 100 | return (ushort)(((m_assetDataLength - FIRST_PACKET_SIZE + IMAGE_PACKET_SIZE - 1) / IMAGE_PACKET_SIZE) + 1); |
103 | } | 101 | } |
104 | catch (Exception) | 102 | catch (Exception) |
105 | { | 103 | { |
@@ -110,119 +108,154 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
110 | } | 108 | } |
111 | } | 109 | } |
112 | 110 | ||
113 | public void J2KDecodedCallback(UUID AssetId, OpenJPEG.J2KLayerInfo[] layers) | 111 | #endregion Properties |
114 | { | ||
115 | m_image.m_outstandingtextures++; | ||
116 | Layers = layers; | ||
117 | m_decoded = true; | ||
118 | RunUpdate(); | ||
119 | } | ||
120 | 112 | ||
121 | public void AssetDataCallback(UUID AssetID, AssetBase asset) | 113 | public J2KImage(LLImageManager imageManager) |
122 | { | 114 | { |
123 | m_hasasset = true; | 115 | m_imageManager = imageManager; |
124 | if (asset == null || asset.Data == null) | ||
125 | { | ||
126 | m_asset = m_MissingSubstitute; | ||
127 | } | ||
128 | else | ||
129 | { | ||
130 | m_asset = asset; | ||
131 | } | ||
132 | RunUpdate(); | ||
133 | } | 116 | } |
134 | 117 | ||
135 | protected void AssetReceived(string id, Object sender, AssetBase asset) | 118 | public bool SendPackets(LLClientView client, int maxpack) |
136 | { | 119 | { |
137 | UUID assetID = UUID.Zero; | 120 | if (m_packetNumber <= m_stopPacket) |
138 | if (asset != null) | 121 | { |
139 | assetID = asset.FullID; | 122 | bool SendMore = true; |
140 | 123 | if (!m_sentinfo || (m_packetNumber == 0)) | |
141 | AssetDataCallback(assetID, asset); | 124 | { |
142 | 125 | if (SendFirstPacket(client)) | |
143 | } | 126 | { |
127 | SendMore = false; | ||
128 | } | ||
129 | m_sentinfo = true; | ||
130 | m_packetNumber++; | ||
131 | } | ||
132 | // bool ignoreStop = false; | ||
133 | if (m_packetNumber < 2) | ||
134 | { | ||
135 | m_packetNumber = 2; | ||
136 | } | ||
144 | 137 | ||
145 | private int GetPacketForBytePosition(int bytePosition) | 138 | int count = 0; |
146 | { | 139 | while (SendMore && count < maxpack && m_packetNumber <= m_stopPacket) |
147 | return ((bytePosition - cFirstPacketSize + cImagePacketSize - 1) / cImagePacketSize) + 1; | 140 | { |
148 | } | 141 | count++; |
142 | SendMore = SendPacket(client); | ||
143 | m_packetNumber++; | ||
144 | } | ||
149 | 145 | ||
150 | public int LastPacketSize() | 146 | if (m_packetNumber > m_stopPacket) |
151 | { | 147 | return true; |
152 | if (m_packetNumber == 1) | ||
153 | return m_asset.Data.Length; | ||
154 | int lastsize = (m_asset.Data.Length - cFirstPacketSize) % cImagePacketSize; | ||
155 | //If the last packet size is zero, it's really cImagePacketSize, it sits on the boundary | ||
156 | if (lastsize == 0) | ||
157 | { | ||
158 | lastsize = cImagePacketSize; | ||
159 | } | 148 | } |
160 | return lastsize; | ||
161 | } | ||
162 | |||
163 | public int CurrentBytePosition() | ||
164 | { | ||
165 | if (m_packetNumber == 0) | ||
166 | return 0; | ||
167 | if (m_packetNumber == 1) | ||
168 | return cFirstPacketSize; | ||
169 | 149 | ||
170 | int result = cFirstPacketSize + ((int)m_packetNumber - 2) * cImagePacketSize; | 150 | return false; |
171 | if (result < 0) | ||
172 | { | ||
173 | result = cFirstPacketSize; | ||
174 | } | ||
175 | return result; | ||
176 | } | 151 | } |
177 | 152 | ||
178 | public bool SendFirstPacket(LLClientView client) | 153 | public void RunUpdate() |
179 | { | 154 | { |
180 | // this means we don't have | 155 | //This is where we decide what we need to update |
181 | if (Data == null) | 156 | //and assign the real discardLevel and packetNumber |
182 | { | 157 | //assuming of course that the connected client might be bonkers |
183 | client.SendImageNotFound(m_requestedUUID); | 158 | |
184 | m_log.WarnFormat("[TEXTURE]: Got null Data element on a asset {0}.. and the missing image Data property is al", m_requestedUUID); | 159 | if (!m_hasasset) |
185 | return true; | ||
186 | } | ||
187 | // Do we have less then 1 packet's worth of data? | ||
188 | else if (m_asset.Data.Length <= cFirstPacketSize) | ||
189 | { | 160 | { |
190 | // Send only 1 packet | 161 | if (!m_asset_requested) |
191 | client.SendImageFirstPart(1, m_requestedUUID, (uint)m_asset.Data.Length, m_asset.Data, 2); | 162 | { |
192 | m_stopPacket = 0; | 163 | m_asset_requested = true; |
193 | return true; | 164 | m_assetCache.Get(m_requestedUUID.ToString(), this, AssetReceived); |
165 | } | ||
194 | } | 166 | } |
195 | else | 167 | else |
196 | { | 168 | { |
197 | byte[] firstImageData = new byte[cFirstPacketSize]; | 169 | if (!m_decoded) |
198 | try | 170 | { |
199 | { | 171 | //We need to decode the requested image first |
200 | Buffer.BlockCopy(m_asset.Data, 0, firstImageData, 0, (int)cFirstPacketSize); | 172 | if (!m_decoderequested) |
201 | client.SendImageFirstPart(TexturePacketCount(), m_requestedUUID, (uint)m_asset.Data.Length, firstImageData, 2); | 173 | { |
174 | //Request decode | ||
175 | m_decoderequested = true; | ||
176 | // Do we have a jpeg decoder? | ||
177 | if (m_j2kDecodeModule != null) | ||
178 | { | ||
179 | if (Data == null) | ||
180 | { | ||
181 | J2KDecodedCallback(m_requestedUUID, new OpenJPEG.J2KLayerInfo[0]); | ||
182 | } | ||
183 | else | ||
184 | { | ||
185 | // Send it off to the jpeg decoder | ||
186 | m_j2kDecodeModule.BeginDecode(m_requestedUUID, Data, J2KDecodedCallback); | ||
187 | } | ||
188 | |||
189 | } | ||
190 | else | ||
191 | { | ||
192 | J2KDecodedCallback(m_requestedUUID, new OpenJPEG.J2KLayerInfo[0]); | ||
193 | } | ||
194 | } | ||
202 | } | 195 | } |
203 | catch (Exception) | 196 | else |
204 | { | 197 | { |
205 | m_log.Error("Texture block copy failed. Possibly out of memory?"); | 198 | // Check for missing image asset data |
206 | return true; | 199 | if (m_asset == null || m_asset.Data == null) |
200 | { | ||
201 | // FIXME: | ||
202 | m_packetNumber = m_stopPacket; | ||
203 | return; | ||
204 | } | ||
205 | |||
206 | if (m_requestedDiscardLevel >= 0 || m_stopPacket == 0) | ||
207 | { | ||
208 | int maxDiscardLevel = Math.Max(0, m_layers.Length - 1); | ||
209 | |||
210 | // Treat initial texture downloads with a DiscardLevel of -1 a request for the highest DiscardLevel | ||
211 | if (m_requestedDiscardLevel < 0 && m_stopPacket == 0) | ||
212 | m_requestedDiscardLevel = (sbyte)maxDiscardLevel; | ||
213 | |||
214 | // Clamp at the highest discard level | ||
215 | m_requestedDiscardLevel = (sbyte)Math.Min(m_requestedDiscardLevel, maxDiscardLevel); | ||
216 | |||
217 | //Calculate the m_stopPacket | ||
218 | if (m_layers.Length > 0) | ||
219 | { | ||
220 | m_stopPacket = (uint)GetPacketForBytePosition(m_layers[(m_layers.Length - 1) - m_requestedDiscardLevel].End); | ||
221 | //I don't know why, but the viewer seems to expect the final packet if the file | ||
222 | //is just one packet bigger. | ||
223 | if (TexturePacketCount() == m_stopPacket + 1) | ||
224 | { | ||
225 | m_stopPacket = TexturePacketCount(); | ||
226 | } | ||
227 | } | ||
228 | else | ||
229 | { | ||
230 | m_stopPacket = TexturePacketCount(); | ||
231 | } | ||
232 | |||
233 | m_packetNumber = m_requestedPacketNumber; | ||
234 | } | ||
235 | |||
236 | if (m_imageManager.Client.PacketHandler.GetQueueCount(ThrottleOutPacketType.Texture) == 0) | ||
237 | { | ||
238 | //m_log.Debug("No textures queued, sending one packet to kickstart it"); | ||
239 | SendPacket(m_imageManager.Client); | ||
240 | } | ||
207 | } | 241 | } |
208 | } | 242 | } |
209 | return false; | ||
210 | } | 243 | } |
211 | 244 | ||
212 | private bool SendPacket(LLClientView client) | 245 | private bool SendPacket(LLClientView client) |
213 | { | 246 | { |
214 | bool complete = false; | 247 | bool complete = false; |
215 | int imagePacketSize = ((int)m_packetNumber == (TexturePacketCount())) ? LastPacketSize() : cImagePacketSize; | 248 | int imagePacketSize = ((int)m_packetNumber == (TexturePacketCount())) ? LastPacketSize() : IMAGE_PACKET_SIZE; |
216 | 249 | ||
217 | try | 250 | try |
218 | { | 251 | { |
219 | if ((CurrentBytePosition() + cImagePacketSize) > m_asset.Data.Length) | 252 | if ((CurrentBytePosition() + IMAGE_PACKET_SIZE) > m_assetDataLength) |
220 | { | 253 | { |
221 | imagePacketSize = LastPacketSize(); | 254 | imagePacketSize = LastPacketSize(); |
222 | complete=true; | 255 | complete = true; |
223 | if ((CurrentBytePosition() + imagePacketSize) > m_asset.Data.Length) | 256 | if ((CurrentBytePosition() + imagePacketSize) > m_assetDataLength) |
224 | { | 257 | { |
225 | imagePacketSize = m_asset.Data.Length - CurrentBytePosition(); | 258 | imagePacketSize = m_assetDataLength - CurrentBytePosition(); |
226 | complete = true; | 259 | complete = true; |
227 | } | 260 | } |
228 | } | 261 | } |
@@ -244,7 +277,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
244 | } | 277 | } |
245 | 278 | ||
246 | //Send the packet | 279 | //Send the packet |
247 | client.SendImageNextPart((ushort)(m_packetNumber-1), m_requestedUUID, imageData); | 280 | client.SendImageNextPart((ushort)(m_packetNumber - 1), m_requestedUUID, imageData); |
248 | } | 281 | } |
249 | if (complete) | 282 | if (complete) |
250 | { | 283 | { |
@@ -260,143 +293,115 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
260 | return false; | 293 | return false; |
261 | } | 294 | } |
262 | } | 295 | } |
263 | public bool SendPackets(LLClientView client, int maxpack) | 296 | |
297 | private int GetPacketForBytePosition(int bytePosition) | ||
264 | { | 298 | { |
299 | return ((bytePosition - FIRST_PACKET_SIZE + IMAGE_PACKET_SIZE - 1) / IMAGE_PACKET_SIZE) + 1; | ||
300 | } | ||
265 | 301 | ||
266 | if (!m_completedSendAtCurrentDiscardLevel) | 302 | private int LastPacketSize() |
303 | { | ||
304 | if (m_packetNumber == 1) | ||
305 | return m_assetDataLength; | ||
306 | int lastsize = (m_assetDataLength - FIRST_PACKET_SIZE) % IMAGE_PACKET_SIZE; | ||
307 | //If the last packet size is zero, it's really cImagePacketSize, it sits on the boundary | ||
308 | if (lastsize == 0) | ||
267 | { | 309 | { |
268 | if (m_packetNumber <= m_stopPacket) | 310 | lastsize = IMAGE_PACKET_SIZE; |
269 | { | 311 | } |
270 | bool SendMore = true; | 312 | return lastsize; |
271 | if (!m_sentinfo || (m_packetNumber == 0)) | 313 | } |
272 | { | ||
273 | if (SendFirstPacket(client)) | ||
274 | { | ||
275 | SendMore = false; | ||
276 | } | ||
277 | m_sentinfo = true; | ||
278 | m_packetNumber++; | ||
279 | } | ||
280 | // bool ignoreStop = false; | ||
281 | if (m_packetNumber < 2) | ||
282 | { | ||
283 | m_packetNumber = 2; | ||
284 | } | ||
285 | 314 | ||
286 | int count = 0; | 315 | private int CurrentBytePosition() |
287 | while (SendMore && count < maxpack && m_packetNumber <= m_stopPacket) | 316 | { |
288 | { | 317 | if (m_packetNumber == 0) |
289 | count++; | 318 | return 0; |
290 | SendMore = SendPacket(client); | 319 | if (m_packetNumber == 1) |
291 | m_packetNumber++; | 320 | return FIRST_PACKET_SIZE; |
292 | } | ||
293 | 321 | ||
294 | if (m_packetNumber > m_stopPacket) | 322 | int result = FIRST_PACKET_SIZE + ((int)m_packetNumber - 2) * IMAGE_PACKET_SIZE; |
295 | { | 323 | if (result < 0) |
296 | return true; | 324 | { |
297 | } | 325 | result = FIRST_PACKET_SIZE; |
326 | } | ||
327 | return result; | ||
328 | } | ||
329 | |||
330 | private bool SendFirstPacket(LLClientView client) | ||
331 | { | ||
332 | // this means we don't have | ||
333 | if (Data == null) | ||
334 | { | ||
335 | client.SendImageNotFound(m_requestedUUID); | ||
336 | m_log.WarnFormat("[TEXTURE]: Got null Data element on a asset {0}.. and the missing image Data property is also null", m_requestedUUID); | ||
337 | return true; | ||
338 | } | ||
339 | // Do we have less then 1 packet's worth of data? | ||
340 | else if (m_assetDataLength <= FIRST_PACKET_SIZE) | ||
341 | { | ||
342 | // Send only 1 packet | ||
343 | client.SendImageFirstPart(1, m_requestedUUID, (uint)m_assetDataLength, m_asset.Data, 2); | ||
344 | m_stopPacket = 0; | ||
345 | return true; | ||
346 | } | ||
347 | else | ||
348 | { | ||
349 | byte[] firstImageData = new byte[FIRST_PACKET_SIZE]; | ||
350 | try | ||
351 | { | ||
352 | Buffer.BlockCopy(m_asset.Data, 0, firstImageData, 0, (int)FIRST_PACKET_SIZE); | ||
353 | client.SendImageFirstPart(TexturePacketCount(), m_requestedUUID, (uint)m_assetDataLength, firstImageData, 2); | ||
354 | } | ||
355 | catch (Exception) | ||
356 | { | ||
357 | m_log.Error("Texture block copy failed. Possibly out of memory?"); | ||
358 | return true; | ||
298 | } | 359 | } |
299 | } | 360 | } |
300 | return false; | 361 | return false; |
301 | } | 362 | } |
302 | 363 | ||
303 | public void RunUpdate() | 364 | private void J2KDecodedCallback(UUID AssetId, OpenJPEG.J2KLayerInfo[] layers) |
304 | { | 365 | { |
305 | //This is where we decide what we need to update | 366 | m_layers = layers; |
306 | //and assign the real discardLevel and packetNumber | 367 | m_decoded = true; |
307 | //assuming of course that the connected client might be bonkers | 368 | RunUpdate(); |
369 | } | ||
308 | 370 | ||
309 | if (!m_hasasset) | 371 | private void AssetDataCallback(UUID AssetID, AssetBase asset) |
310 | { | 372 | { |
373 | m_hasasset = true; | ||
311 | 374 | ||
312 | if (!m_asset_requested) | 375 | if (asset == null || asset.Data == null) |
376 | { | ||
377 | if (m_imageManager.MissingImage != null) | ||
313 | { | 378 | { |
314 | m_asset_requested = true; | 379 | m_asset = m_imageManager.MissingImage; |
315 | m_assetCache.Get(m_requestedUUID.ToString(), this, AssetReceived); | 380 | m_assetDataLength = m_asset.Data.Length; |
316 | 381 | } | |
382 | else | ||
383 | { | ||
384 | m_asset = null; | ||
385 | m_decoded = true; | ||
317 | } | 386 | } |
318 | |||
319 | } | 387 | } |
320 | else | 388 | else |
321 | { | 389 | { |
390 | m_asset = asset; | ||
391 | m_assetDataLength = m_asset.Data.Length; | ||
392 | } | ||
322 | 393 | ||
394 | RunUpdate(); | ||
395 | } | ||
323 | 396 | ||
324 | if (!m_decoded) | 397 | private void AssetReceived(string id, Object sender, AssetBase asset) |
325 | { | 398 | { |
326 | //We need to decode the requested image first | 399 | UUID assetID = UUID.Zero; |
327 | if (!m_decoderequested) | 400 | if (asset != null) |
328 | { | 401 | assetID = asset.FullID; |
329 | //Request decode | ||
330 | m_decoderequested = true; | ||
331 | // Do we have a jpeg decoder? | ||
332 | if (m_j2kDecodeModule != null) | ||
333 | { | ||
334 | if (Data == null) | ||
335 | { | ||
336 | J2KDecodedCallback(m_requestedUUID, new OpenJPEG.J2KLayerInfo[0]); | ||
337 | } | ||
338 | // Send it off to the jpeg decoder | ||
339 | m_j2kDecodeModule.decode(m_requestedUUID, Data, J2KDecodedCallback); | ||
340 | |||
341 | } | ||
342 | else | ||
343 | { | ||
344 | J2KDecodedCallback(m_requestedUUID, new OpenJPEG.J2KLayerInfo[0]); | ||
345 | } | ||
346 | } | ||
347 | |||
348 | } | ||
349 | else | ||
350 | { | ||
351 | //discardLevel of -1 means just update the priority | ||
352 | if (m_requestedDiscardLevel != -1) | ||
353 | { | ||
354 | //Evaluate the discard level | ||
355 | //First, is it positive? | ||
356 | if (m_requestedDiscardLevel >= 0) | ||
357 | { | ||
358 | if (m_requestedDiscardLevel > Layers.Length - 1) | ||
359 | { | ||
360 | m_discardLevel = (sbyte)(Layers.Length - 1); | ||
361 | } | ||
362 | else | ||
363 | { | ||
364 | m_discardLevel = m_requestedDiscardLevel; | ||
365 | } | ||
366 | 402 | ||
367 | //Calculate the m_stopPacket | 403 | AssetDataCallback(assetID, asset); |
368 | if (Layers.Length > 0) | ||
369 | { | ||
370 | m_stopPacket = (uint)GetPacketForBytePosition(Layers[(Layers.Length - 1) - m_discardLevel].End); | ||
371 | //I don't know why, but the viewer seems to expect the final packet if the file | ||
372 | //is just one packet bigger. | ||
373 | if (TexturePacketCount() == m_stopPacket + 1) | ||
374 | { | ||
375 | m_stopPacket = TexturePacketCount(); | ||
376 | } | ||
377 | } | ||
378 | else | ||
379 | { | ||
380 | m_stopPacket = TexturePacketCount(); | ||
381 | } | ||
382 | //Don't reset packet number unless we're waiting or it's ahead of us | ||
383 | if (m_completedSendAtCurrentDiscardLevel || m_requestedPacketNumber>m_packetNumber) | ||
384 | { | ||
385 | m_packetNumber = m_requestedPacketNumber; | ||
386 | } | ||
387 | 404 | ||
388 | if (m_packetNumber <= m_stopPacket) | ||
389 | { | ||
390 | m_completedSendAtCurrentDiscardLevel = false; | ||
391 | } | ||
392 | } | ||
393 | } | ||
394 | else | ||
395 | { | ||
396 | m_packetNumber = m_stopPacket; | ||
397 | } | ||
398 | } | ||
399 | } | ||
400 | } | 405 | } |
401 | } | 406 | } |
402 | } | 407 | } |
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index 88ace6a..3b43771 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs | |||
@@ -81,8 +81,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
81 | private List<ObjectUpdatePacket.ObjectDataBlock> m_primFullUpdates = | 81 | private List<ObjectUpdatePacket.ObjectDataBlock> m_primFullUpdates = |
82 | new List<ObjectUpdatePacket.ObjectDataBlock>(); | 82 | new List<ObjectUpdatePacket.ObjectDataBlock>(); |
83 | 83 | ||
84 | private Timer m_textureRequestTimer; | ||
85 | |||
86 | private bool m_clientBlocked; | 84 | private bool m_clientBlocked; |
87 | 85 | ||
88 | private int m_probesWithNoIngressPackets; | 86 | private int m_probesWithNoIngressPackets; |
@@ -143,9 +141,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
143 | protected int m_primTerseUpdateRate = 10; | 141 | protected int m_primTerseUpdateRate = 10; |
144 | protected int m_primFullUpdateRate = 14; | 142 | protected int m_primFullUpdateRate = 14; |
145 | 143 | ||
146 | protected int m_textureRequestRate = 100; | 144 | protected int m_textureSendLimit = 20; |
147 | protected int m_textureSendLimit = 10; | 145 | protected int m_textureDataLimit = 10; |
148 | protected int m_textureDataLimit = 5; | ||
149 | 146 | ||
150 | protected int m_packetMTU = 1400; | 147 | protected int m_packetMTU = 1400; |
151 | 148 | ||
@@ -534,6 +531,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
534 | m_PacketHandler = new LLPacketHandler(this, m_networkServer, userSettings); | 531 | m_PacketHandler = new LLPacketHandler(this, m_networkServer, userSettings); |
535 | m_PacketHandler.SynchronizeClient = SynchronizeClient; | 532 | m_PacketHandler.SynchronizeClient = SynchronizeClient; |
536 | m_PacketHandler.OnPacketStats += PopulateStats; | 533 | m_PacketHandler.OnPacketStats += PopulateStats; |
534 | m_PacketHandler.OnQueueEmpty += HandleQueueEmpty; | ||
537 | 535 | ||
538 | if (scene.Config != null) | 536 | if (scene.Config != null) |
539 | { | 537 | { |
@@ -555,9 +553,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
555 | m_primFullUpdateRate = clientConfig.GetInt("FullUpdateRate", | 553 | m_primFullUpdateRate = clientConfig.GetInt("FullUpdateRate", |
556 | m_primFullUpdateRate); | 554 | m_primFullUpdateRate); |
557 | 555 | ||
558 | m_textureRequestRate = clientConfig.GetInt("TextureRequestRate", | ||
559 | m_textureRequestRate); | ||
560 | |||
561 | m_textureSendLimit = clientConfig.GetInt("TextureSendLimit", | 556 | m_textureSendLimit = clientConfig.GetInt("TextureSendLimit", |
562 | m_textureSendLimit); | 557 | m_textureSendLimit); |
563 | 558 | ||
@@ -607,9 +602,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
607 | if (m_primFullUpdateTimer.Enabled) | 602 | if (m_primFullUpdateTimer.Enabled) |
608 | lock (m_primFullUpdateTimer) | 603 | lock (m_primFullUpdateTimer) |
609 | m_primFullUpdateTimer.Stop(); | 604 | m_primFullUpdateTimer.Stop(); |
610 | if (m_textureRequestTimer.Enabled) | ||
611 | lock (m_textureRequestTimer) | ||
612 | m_textureRequestTimer.Stop(); | ||
613 | 605 | ||
614 | // This is just to give the client a reasonable chance of | 606 | // This is just to give the client a reasonable chance of |
615 | // flushing out all it's packets. There should probably | 607 | // flushing out all it's packets. There should probably |
@@ -633,6 +625,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
633 | // of the client thread regardless of where Close() is called. | 625 | // of the client thread regardless of where Close() is called. |
634 | KillEndDone(); | 626 | KillEndDone(); |
635 | } | 627 | } |
628 | |||
629 | Terminate(); | ||
636 | } | 630 | } |
637 | 631 | ||
638 | /// <summary> | 632 | /// <summary> |
@@ -704,10 +698,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
704 | if (m_primFullUpdateTimer.Enabled) | 698 | if (m_primFullUpdateTimer.Enabled) |
705 | lock (m_primFullUpdateTimer) | 699 | lock (m_primFullUpdateTimer) |
706 | m_primFullUpdateTimer.Stop(); | 700 | m_primFullUpdateTimer.Stop(); |
707 | |||
708 | if (m_textureRequestTimer.Enabled) | ||
709 | lock (m_textureRequestTimer) | ||
710 | m_textureRequestTimer.Stop(); | ||
711 | } | 701 | } |
712 | 702 | ||
713 | public void Restart() | 703 | public void Restart() |
@@ -730,23 +720,25 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
730 | m_primFullUpdateTimer = new Timer(m_primFullUpdateRate); | 720 | m_primFullUpdateTimer = new Timer(m_primFullUpdateRate); |
731 | m_primFullUpdateTimer.Elapsed += new ElapsedEventHandler(ProcessPrimFullUpdates); | 721 | m_primFullUpdateTimer.Elapsed += new ElapsedEventHandler(ProcessPrimFullUpdates); |
732 | m_primFullUpdateTimer.AutoReset = false; | 722 | m_primFullUpdateTimer.AutoReset = false; |
733 | |||
734 | m_textureRequestTimer = new Timer(m_textureRequestRate); | ||
735 | m_textureRequestTimer.Elapsed += new ElapsedEventHandler(ProcessTextureRequests); | ||
736 | m_textureRequestTimer.AutoReset = false; | ||
737 | |||
738 | } | 723 | } |
739 | 724 | ||
740 | public void Terminate() | 725 | private void Terminate() |
741 | { | 726 | { |
727 | IsActive = false; | ||
728 | |||
729 | m_clientPingTimer.Close(); | ||
730 | m_avatarTerseUpdateTimer.Close(); | ||
731 | m_primTerseUpdateTimer.Close(); | ||
732 | m_primFullUpdateTimer.Close(); | ||
733 | |||
742 | m_PacketHandler.OnPacketStats -= PopulateStats; | 734 | m_PacketHandler.OnPacketStats -= PopulateStats; |
743 | m_PacketHandler.Stop(); | 735 | m_PacketHandler.Dispose(); |
744 | 736 | ||
745 | // wait for thread stoped | 737 | // wait for thread stoped |
746 | m_clientThread.Join(); | 738 | // m_clientThread.Join(); |
747 | 739 | ||
748 | // delete circuit code | 740 | // delete circuit code |
749 | m_networkServer.CloseClient(this); | 741 | //m_networkServer.CloseClient(this); |
750 | } | 742 | } |
751 | 743 | ||
752 | #endregion | 744 | #endregion |
@@ -876,6 +868,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
876 | while (IsActive) | 868 | while (IsActive) |
877 | { | 869 | { |
878 | LLQueItem nextPacket = m_PacketHandler.PacketQueue.Dequeue(); | 870 | LLQueItem nextPacket = m_PacketHandler.PacketQueue.Dequeue(); |
871 | |||
872 | if (nextPacket == null) { | ||
873 | m_log.DebugFormat("[CLIENT]: PacketQueue return null LLQueItem"); | ||
874 | continue; | ||
875 | } | ||
879 | 876 | ||
880 | if (nextPacket.Incoming) | 877 | if (nextPacket.Incoming) |
881 | { | 878 | { |
@@ -967,10 +964,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
967 | m_primFullUpdateTimer.Elapsed += new ElapsedEventHandler(ProcessPrimFullUpdates); | 964 | m_primFullUpdateTimer.Elapsed += new ElapsedEventHandler(ProcessPrimFullUpdates); |
968 | m_primFullUpdateTimer.AutoReset = false; | 965 | m_primFullUpdateTimer.AutoReset = false; |
969 | 966 | ||
970 | m_textureRequestTimer = new Timer(m_textureRequestRate); | ||
971 | m_textureRequestTimer.Elapsed += new ElapsedEventHandler(ProcessTextureRequests); | ||
972 | m_textureRequestTimer.AutoReset = false; | ||
973 | |||
974 | m_scene.AddNewClient(this); | 967 | m_scene.AddNewClient(this); |
975 | 968 | ||
976 | RefreshGroupMembership(); | 969 | RefreshGroupMembership(); |
@@ -1042,26 +1035,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1042 | } | 1035 | } |
1043 | } | 1036 | } |
1044 | 1037 | ||
1045 | protected virtual void TextureRequestHandler() | ||
1046 | { | ||
1047 | m_log.DebugFormat("[TRH] Thread started"); | ||
1048 | while (m_imageManager != null) | ||
1049 | { | ||
1050 | try | ||
1051 | { | ||
1052 | while (m_imageManager != null) | ||
1053 | { | ||
1054 | } | ||
1055 | } | ||
1056 | catch (Exception e) | ||
1057 | { | ||
1058 | m_log.WarnFormat("[TRH] Exception in handler loop: {0}", e.Message); | ||
1059 | m_log.Debug(e); | ||
1060 | } | ||
1061 | } | ||
1062 | m_log.DebugFormat("[TRH] Thread terminated"); | ||
1063 | } | ||
1064 | |||
1065 | # endregion | 1038 | # endregion |
1066 | 1039 | ||
1067 | // Previously ClientView.API partial class | 1040 | // Previously ClientView.API partial class |
@@ -3161,22 +3134,22 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3161 | } | 3134 | } |
3162 | } | 3135 | } |
3163 | 3136 | ||
3164 | // Unlike the other timers, this one is only started after | 3137 | void HandleQueueEmpty(ThrottleOutPacketType queue) |
3165 | // the first request is seen. | ||
3166 | |||
3167 | void ProcessTextureRequests(object sender, ElapsedEventArgs e) | ||
3168 | { | 3138 | { |
3169 | if (m_imageManager != null) | 3139 | switch (queue) |
3170 | { | 3140 | { |
3171 | if (m_imageManager.ProcessImageQueue(m_textureSendLimit, | 3141 | case ThrottleOutPacketType.Texture: |
3172 | m_textureDataLimit)) | 3142 | ProcessTextureRequests(); |
3173 | { | 3143 | break; |
3174 | lock (m_textureRequestTimer) | ||
3175 | m_textureRequestTimer.Start(); | ||
3176 | } | ||
3177 | } | 3144 | } |
3178 | } | 3145 | } |
3179 | 3146 | ||
3147 | void ProcessTextureRequests() | ||
3148 | { | ||
3149 | if (m_imageManager != null) | ||
3150 | m_imageManager.ProcessImageQueue(m_textureSendLimit, m_textureDataLimit); | ||
3151 | } | ||
3152 | |||
3180 | void ProcessPrimFullUpdates(object sender, ElapsedEventArgs e) | 3153 | void ProcessPrimFullUpdates(object sender, ElapsedEventArgs e) |
3181 | { | 3154 | { |
3182 | lock (m_primFullUpdates) | 3155 | lock (m_primFullUpdates) |
@@ -5275,13 +5248,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
5275 | // for the client session anyway, in order to protect ourselves against bad code in plugins | 5248 | // for the client session anyway, in order to protect ourselves against bad code in plugins |
5276 | try | 5249 | try |
5277 | { | 5250 | { |
5278 | List<byte> visualparams = new List<byte>(); | 5251 | byte[] visualparams = new byte[appear.VisualParam.Length]; |
5279 | foreach (AgentSetAppearancePacket.VisualParamBlock x in appear.VisualParam) | 5252 | for (int i = 0; i < appear.VisualParam.Length; i++) |
5280 | { | 5253 | visualparams[i] = appear.VisualParam[i].ParamValue; |
5281 | visualparams.Add(x.ParamValue); | ||
5282 | } | ||
5283 | 5254 | ||
5284 | handlerSetAppearance(appear.ObjectData.TextureEntry, visualparams); | 5255 | Primitive.TextureEntry te = null; |
5256 | if (appear.ObjectData.TextureEntry.Length > 1) | ||
5257 | te = new Primitive.TextureEntry(appear.ObjectData.TextureEntry, 0, appear.ObjectData.TextureEntry.Length); | ||
5258 | |||
5259 | handlerSetAppearance(te, visualparams); | ||
5285 | } | 5260 | } |
5286 | catch (Exception e) | 5261 | catch (Exception e) |
5287 | { | 5262 | { |
@@ -6624,8 +6599,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
6624 | if (m_imageManager != null) | 6599 | if (m_imageManager != null) |
6625 | { | 6600 | { |
6626 | m_imageManager.EnqueueReq(args); | 6601 | m_imageManager.EnqueueReq(args); |
6627 | lock (m_textureRequestTimer) | ||
6628 | m_textureRequestTimer.Start(); | ||
6629 | } | 6602 | } |
6630 | } | 6603 | } |
6631 | } | 6604 | } |
@@ -11026,5 +10999,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
11026 | } | 10999 | } |
11027 | 11000 | ||
11028 | #endregion | 11001 | #endregion |
11002 | |||
11003 | public void SendRebakeAvatarTextures(UUID textureID) | ||
11004 | { | ||
11005 | RebakeAvatarTexturesPacket pack = | ||
11006 | (RebakeAvatarTexturesPacket)PacketPool.Instance.GetPacket(PacketType.RebakeAvatarTextures); | ||
11007 | |||
11008 | pack.TextureData = new RebakeAvatarTexturesPacket.TextureDataBlock(); | ||
11009 | pack.TextureData.TextureID = textureID; | ||
11010 | OutPacket(pack, ThrottleOutPacketType.Task); | ||
11011 | } | ||
11029 | } | 11012 | } |
11030 | } | 11013 | } |
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLImageManager.cs b/OpenSim/Region/ClientStack/LindenUDP/LLImageManager.cs index 295a5e6..a484fdf 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLImageManager.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLImageManager.cs | |||
@@ -27,58 +27,60 @@ | |||
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using System.Threading; | 29 | using System.Threading; |
30 | using System.Collections; | ||
30 | using System.Collections.Generic; | 31 | using System.Collections.Generic; |
32 | using System.Reflection; | ||
31 | using OpenMetaverse; | 33 | using OpenMetaverse; |
32 | using OpenMetaverse.Imaging; | 34 | using OpenMetaverse.Imaging; |
33 | using OpenSim.Framework; | 35 | using OpenSim.Framework; |
34 | using OpenSim.Region.Framework.Interfaces; | 36 | using OpenSim.Region.Framework.Interfaces; |
35 | using OpenSim.Services.Interfaces; | 37 | using OpenSim.Services.Interfaces; |
36 | using log4net; | 38 | using log4net; |
37 | using System.Reflection; | ||
38 | 39 | ||
39 | namespace OpenSim.Region.ClientStack.LindenUDP | 40 | namespace OpenSim.Region.ClientStack.LindenUDP |
40 | { | 41 | { |
41 | |||
42 | public class LLImageManager | 42 | public class LLImageManager |
43 | { | 43 | { |
44 | 44 | private sealed class J2KImageComparer : IComparer<J2KImage> | |
45 | //Public interfaces: | 45 | { |
46 | //Constructor - (LLClientView, IAssetCache, IJ2KDecoder); | 46 | public int Compare(J2KImage x, J2KImage y) |
47 | //void EnqueueReq - (TextureRequestArgs) | 47 | { |
48 | //ProcessImageQueue | 48 | return x.m_requestedPriority.CompareTo(y.m_requestedPriority); |
49 | //Close | 49 | } |
50 | } | ||
51 | |||
50 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 52 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
51 | private bool m_shuttingdown = false; | 53 | private bool m_shuttingdown = false; |
52 | private long m_lastloopprocessed = 0; | 54 | private long m_lastloopprocessed = 0; |
55 | private AssetBase m_missingImage = null; | ||
53 | 56 | ||
54 | private LLClientView m_client; //Client we're assigned to | 57 | private LLClientView m_client; //Client we're assigned to |
55 | private IAssetService m_assetCache; //Asset Cache | 58 | private IAssetService m_assetCache; //Asset Cache |
56 | private IJ2KDecoder m_j2kDecodeModule; //Our J2K module | 59 | private IJ2KDecoder m_j2kDecodeModule; //Our J2K module |
60 | private C5.IntervalHeap<J2KImage> m_priorityQueue = new C5.IntervalHeap<J2KImage>(10, new J2KImageComparer()); | ||
57 | 61 | ||
58 | private readonly AssetBase m_missingsubstitute; //Sustitute for bad decodes | ||
59 | private Dictionary<UUID,J2KImage> m_imagestore; // Our main image storage dictionary | ||
60 | private SortedList<double,UUID> m_priorities; // For fast image lookup based on priority | ||
61 | private Dictionary<int, int> m_priorityresolver; //Enabling super fast assignment of images with the same priorities | ||
62 | |||
63 | private const double doubleMinimum = .0000001; | ||
64 | |||
65 | public int m_outstandingtextures = 0; | ||
66 | //Constructor | ||
67 | public LLImageManager(LLClientView client, IAssetService pAssetCache, IJ2KDecoder pJ2kDecodeModule) | 62 | public LLImageManager(LLClientView client, IAssetService pAssetCache, IJ2KDecoder pJ2kDecodeModule) |
68 | { | 63 | { |
69 | |||
70 | m_imagestore = new Dictionary<UUID,J2KImage>(); | ||
71 | m_priorities = new SortedList<double,UUID>(); | ||
72 | m_priorityresolver = new Dictionary<int, int>(); | ||
73 | m_client = client; | 64 | m_client = client; |
74 | m_assetCache = pAssetCache; | 65 | m_assetCache = pAssetCache; |
75 | if (pAssetCache != null) | 66 | if (pAssetCache != null) |
76 | m_missingsubstitute = pAssetCache.Get("5748decc-f629-461c-9a36-a35a221fe21f"); | 67 | m_missingImage = pAssetCache.Get("5748decc-f629-461c-9a36-a35a221fe21f"); |
77 | else | 68 | else |
78 | m_log.Error("[ClientView] - couldn't set missing image, all manner of things will probably break"); | 69 | m_log.Error("[ClientView] - couldn't set missing image asset, falling back to missing image packet. This is known to crash the client"); |
70 | |||
79 | m_j2kDecodeModule = pJ2kDecodeModule; | 71 | m_j2kDecodeModule = pJ2kDecodeModule; |
80 | } | 72 | } |
81 | 73 | ||
74 | public LLClientView Client | ||
75 | { | ||
76 | get { return m_client; } | ||
77 | } | ||
78 | |||
79 | public AssetBase MissingImage | ||
80 | { | ||
81 | get { return m_missingImage; } | ||
82 | } | ||
83 | |||
82 | public void EnqueueReq(TextureRequestArgs newRequest) | 84 | public void EnqueueReq(TextureRequestArgs newRequest) |
83 | { | 85 | { |
84 | //newRequest is the properties of our new texture fetch request. | 86 | //newRequest is the properties of our new texture fetch request. |
@@ -88,234 +90,203 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
88 | //Make sure we're not shutting down.. | 90 | //Make sure we're not shutting down.. |
89 | if (!m_shuttingdown) | 91 | if (!m_shuttingdown) |
90 | { | 92 | { |
93 | J2KImage imgrequest; | ||
91 | 94 | ||
92 | //Do we already know about this UUID? | 95 | // Do a linear search for this texture download |
93 | if (m_imagestore.ContainsKey(newRequest.RequestedAssetID)) | 96 | lock (m_priorityQueue) |
94 | { | 97 | m_priorityQueue.Find(delegate(J2KImage img) { return img.m_requestedUUID == newRequest.RequestedAssetID; }, out imgrequest); |
95 | //Check the packet sequence to make sure this isn't older than | ||
96 | //one we've already received | ||
97 | |||
98 | J2KImage imgrequest = m_imagestore[newRequest.RequestedAssetID]; | ||
99 | |||
100 | // This is the inbound request sequence number. We can ignore | ||
101 | // "old" ones. | ||
102 | 98 | ||
103 | if (newRequest.requestSequence > imgrequest.m_lastSequence) | 99 | if (imgrequest != null) |
100 | { | ||
101 | if (newRequest.DiscardLevel == -1 && newRequest.Priority == 0f) | ||
104 | { | 102 | { |
103 | //m_log.Debug("[TEX]: (CAN) ID=" + newRequest.RequestedAssetID); | ||
105 | 104 | ||
106 | imgrequest.m_lastSequence = newRequest.requestSequence; | 105 | try |
107 | |||
108 | //Check the priority | ||
109 | |||
110 | double priority = imgrequest.m_requestedPriority; | ||
111 | if (priority != newRequest.Priority) | ||
112 | { | 106 | { |
113 | //Remove the old priority | 107 | lock (m_priorityQueue) |
114 | m_priorities.Remove(imgrequest.m_designatedPriorityKey); | 108 | m_priorityQueue.Delete(imgrequest.m_priorityQueueHandle); |
115 | //Assign a new unique priority | ||
116 | imgrequest.m_requestedPriority = newRequest.Priority; | ||
117 | imgrequest.m_designatedPriorityKey = AssignPriority(newRequest.RequestedAssetID, newRequest.Priority); | ||
118 | } | 109 | } |
110 | catch (Exception) { } | ||
111 | } | ||
112 | else | ||
113 | { | ||
114 | //m_log.DebugFormat("[TEX]: (UPD) ID={0}: D={1}, S={2}, P={3}", | ||
115 | // newRequest.RequestedAssetID, newRequest.DiscardLevel, newRequest.PacketNumber, newRequest.Priority); | ||
119 | 116 | ||
120 | //Update the requested discard level | 117 | //Check the packet sequence to make sure this isn't older than |
121 | imgrequest.m_requestedDiscardLevel = newRequest.DiscardLevel; | 118 | //one we've already received |
119 | if (newRequest.requestSequence > imgrequest.m_lastSequence) | ||
120 | { | ||
121 | //Update the sequence number of the last RequestImage packet | ||
122 | imgrequest.m_lastSequence = newRequest.requestSequence; | ||
122 | 123 | ||
123 | //Update the requested packet number | 124 | //Update the requested discard level |
124 | imgrequest.m_requestedPacketNumber = newRequest.PacketNumber; | 125 | imgrequest.m_requestedDiscardLevel = newRequest.DiscardLevel; |
125 | 126 | ||
126 | //Check if this will create an outstanding texture request | 127 | //Update the requested packet number |
127 | bool activated = imgrequest.m_completedSendAtCurrentDiscardLevel; | 128 | imgrequest.m_requestedPacketNumber = newRequest.PacketNumber; |
128 | //Run an update | ||
129 | 129 | ||
130 | imgrequest.RunUpdate(); | 130 | //Update the requested priority |
131 | imgrequest.m_requestedPriority = newRequest.Priority; | ||
132 | try | ||
133 | { | ||
134 | lock (m_priorityQueue) | ||
135 | m_priorityQueue.Replace(imgrequest.m_priorityQueueHandle, imgrequest); | ||
136 | } | ||
137 | catch (Exception) | ||
138 | { | ||
139 | imgrequest.m_priorityQueueHandle = null; | ||
140 | lock (m_priorityQueue) | ||
141 | m_priorityQueue.Add(ref imgrequest.m_priorityQueueHandle, imgrequest); | ||
142 | } | ||
131 | 143 | ||
132 | if (activated && !imgrequest.m_completedSendAtCurrentDiscardLevel && imgrequest.m_decoded) | 144 | //Run an update |
133 | { | 145 | imgrequest.RunUpdate(); |
134 | Interlocked.Increment(ref m_outstandingtextures); | ||
135 | } | 146 | } |
136 | } | 147 | } |
137 | } | 148 | } |
138 | else | 149 | else |
139 | { | 150 | { |
140 | J2KImage imgrequest = new J2KImage(this); | 151 | if (newRequest.DiscardLevel == -1 && newRequest.Priority == 0f) |
141 | 152 | { | |
142 | //Assign our missing substitute | 153 | //m_log.DebugFormat("[TEX]: (IGN) ID={0}: D={1}, S={2}, P={3}", |
143 | imgrequest.m_MissingSubstitute = m_missingsubstitute; | 154 | // newRequest.RequestedAssetID, newRequest.DiscardLevel, newRequest.PacketNumber, newRequest.Priority); |
155 | } | ||
156 | else | ||
157 | { | ||
158 | //m_log.DebugFormat("[TEX]: (NEW) ID={0}: D={1}, S={2}, P={3}", | ||
159 | // newRequest.RequestedAssetID, newRequest.DiscardLevel, newRequest.PacketNumber, newRequest.Priority); | ||
144 | 160 | ||
145 | //Assign our decoder module | 161 | imgrequest = new J2KImage(this); |
146 | imgrequest.m_j2kDecodeModule = m_j2kDecodeModule; | ||
147 | 162 | ||
148 | //Assign our asset cache module | 163 | //Assign our decoder module |
149 | imgrequest.m_assetCache = m_assetCache; | 164 | imgrequest.m_j2kDecodeModule = m_j2kDecodeModule; |
150 | 165 | ||
151 | //Assign a priority based on our request | 166 | //Assign our asset cache module |
152 | imgrequest.m_designatedPriorityKey = AssignPriority(newRequest.RequestedAssetID, newRequest.Priority); | 167 | imgrequest.m_assetCache = m_assetCache; |
153 | 168 | ||
154 | //Assign the requested discard level | 169 | //Assign the requested discard level |
155 | imgrequest.m_requestedDiscardLevel = newRequest.DiscardLevel; | 170 | imgrequest.m_requestedDiscardLevel = newRequest.DiscardLevel; |
156 | 171 | ||
157 | //Assign the requested packet number | 172 | //Assign the requested packet number |
158 | imgrequest.m_requestedPacketNumber = newRequest.PacketNumber; | 173 | imgrequest.m_requestedPacketNumber = newRequest.PacketNumber; |
159 | 174 | ||
160 | //Assign the requested priority | 175 | //Assign the requested priority |
161 | imgrequest.m_requestedPriority = newRequest.Priority; | 176 | imgrequest.m_requestedPriority = newRequest.Priority; |
162 | 177 | ||
163 | //Assign the asset uuid | 178 | //Assign the asset uuid |
164 | imgrequest.m_requestedUUID = newRequest.RequestedAssetID; | 179 | imgrequest.m_requestedUUID = newRequest.RequestedAssetID; |
165 | 180 | ||
166 | m_imagestore.Add(imgrequest.m_requestedUUID, imgrequest); | 181 | //Assign the requested priority |
182 | imgrequest.m_requestedPriority = newRequest.Priority; | ||
167 | 183 | ||
168 | //Run an update | 184 | //Add this download to the priority queue |
169 | imgrequest.RunUpdate(); | 185 | lock (m_priorityQueue) |
186 | m_priorityQueue.Add(ref imgrequest.m_priorityQueueHandle, imgrequest); | ||
170 | 187 | ||
188 | //Run an update | ||
189 | imgrequest.RunUpdate(); | ||
190 | } | ||
171 | } | 191 | } |
172 | } | 192 | } |
173 | } | 193 | } |
174 | 194 | ||
175 | private double AssignPriority(UUID pAssetID, double pPriority) | 195 | public bool ProcessImageQueue(int count, int maxpack) |
176 | { | 196 | { |
177 | 197 | lock (this) | |
178 | //First, find out if we can just assign directly | ||
179 | if (m_priorityresolver.ContainsKey((int)pPriority) == false) | ||
180 | { | 198 | { |
181 | m_priorities.Add((double)((int)pPriority), pAssetID); | 199 | //count is the number of textures we want to process in one go. |
182 | m_priorityresolver.Add((int)pPriority, 0); | 200 | //As part of this class re-write, that number will probably rise |
183 | return (double)((int)pPriority); | 201 | //since we're processing in a more efficient manner. |
184 | } | ||
185 | else | ||
186 | { | ||
187 | //Use the hash lookup goodness of a secondary dictionary to find a free slot | ||
188 | double mFreePriority = ((int)pPriority) + (doubleMinimum * (m_priorityresolver[(int)pPriority] + 1)); | ||
189 | m_priorities[mFreePriority] = pAssetID; | ||
190 | m_priorityresolver[(int)pPriority]++; | ||
191 | return mFreePriority; | ||
192 | } | ||
193 | 202 | ||
203 | // this can happen during Close() | ||
204 | if (m_client == null) | ||
205 | return false; | ||
194 | 206 | ||
207 | int numCollected = 0; | ||
195 | 208 | ||
196 | } | 209 | //Calculate our threshold |
210 | int threshold; | ||
211 | if (m_lastloopprocessed == 0) | ||
212 | { | ||
213 | if (m_client.PacketHandler == null || m_client.PacketHandler.PacketQueue == null || m_client.PacketHandler.PacketQueue.TextureThrottle == null) | ||
214 | return false; | ||
215 | //This is decent for a semi fast machine, but we'll calculate it more accurately based on time below | ||
216 | threshold = m_client.PacketHandler.PacketQueue.TextureThrottle.Current / 6300; | ||
217 | m_lastloopprocessed = DateTime.Now.Ticks; | ||
218 | } | ||
219 | else | ||
220 | { | ||
221 | double throttleseconds = ((double)DateTime.Now.Ticks - (double)m_lastloopprocessed) / (double)TimeSpan.TicksPerSecond; | ||
222 | throttleseconds = throttleseconds * m_client.PacketHandler.PacketQueue.TextureThrottle.Current; | ||
197 | 223 | ||
198 | public bool ProcessImageQueue(int count, int maxpack) | 224 | //Average of 1000 bytes per packet |
199 | { | 225 | throttleseconds = throttleseconds / 1000; |
226 | |||
227 | //Safe-zone multiplier of 2.0 | ||
228 | threshold = (int)(throttleseconds * 2.0); | ||
229 | m_lastloopprocessed = DateTime.Now.Ticks; | ||
230 | |||
231 | } | ||
232 | |||
233 | if (m_client.PacketHandler == null) | ||
234 | return false; | ||
200 | 235 | ||
201 | // this can happen during Close() | 236 | if (m_client.PacketHandler.PacketQueue == null) |
202 | if (m_client == null) | 237 | return false; |
203 | return false; | 238 | |
204 | 239 | if (threshold < 10) | |
205 | //Count is the number of textures we want to process in one go. | 240 | threshold = 10; |
206 | //As part of this class re-write, that number will probably rise | 241 | |
207 | //since we're processing in a more efficient manner. | 242 | //Uncomment this to see what the texture stack is doing |
208 | 243 | //m_log.Debug("Queue: " + m_client.PacketHandler.PacketQueue.getQueueCount(ThrottleOutPacketType.Texture).ToString() + " Threshold: " + threshold.ToString() + " outstanding: " + m_outstandingtextures.ToString()); | |
209 | int numCollected = 0; | 244 | if (true) //m_client.PacketHandler.PacketQueue.GetQueueCount(ThrottleOutPacketType.Texture) < threshold) |
210 | |||
211 | //Calculate our threshold | ||
212 | int threshold; | ||
213 | if (m_lastloopprocessed == 0) | ||
214 | { | ||
215 | if (m_client.PacketHandler == null || m_client.PacketHandler.PacketQueue == null || m_client.PacketHandler.PacketQueue.TextureThrottle == null) | ||
216 | return false; | ||
217 | //This is decent for a semi fast machine, but we'll calculate it more accurately based on time below | ||
218 | threshold = m_client.PacketHandler.PacketQueue.TextureThrottle.Current / 6300; | ||
219 | m_lastloopprocessed = DateTime.Now.Ticks; | ||
220 | } | ||
221 | else | ||
222 | { | ||
223 | double throttleseconds = ((double)DateTime.Now.Ticks - (double)m_lastloopprocessed) / (double)TimeSpan.TicksPerSecond; | ||
224 | throttleseconds = throttleseconds * m_client.PacketHandler.PacketQueue.TextureThrottle.Current; | ||
225 | |||
226 | //Average of 1000 bytes per packet | ||
227 | throttleseconds = throttleseconds / 1000; | ||
228 | |||
229 | //Safe-zone multiplier of 2.0 | ||
230 | threshold = (int)(throttleseconds * 2.0); | ||
231 | m_lastloopprocessed = DateTime.Now.Ticks; | ||
232 | |||
233 | } | ||
234 | |||
235 | if (threshold < 10) | ||
236 | { | ||
237 | threshold = 10; | ||
238 | } | ||
239 | |||
240 | if (m_client.PacketHandler == null) | ||
241 | return false; | ||
242 | |||
243 | if (m_client.PacketHandler.PacketQueue == null) | ||
244 | return false; | ||
245 | |||
246 | //First of all make sure our packet queue isn't above our threshold | ||
247 | |||
248 | //Uncomment this to see what the texture stack is doing | ||
249 | //m_log.Debug("Queue: " + m_client.PacketHandler.PacketQueue.TextureOutgoingPacketQueueCount.ToString() + " Threshold: " + threshold.ToString() + " outstanding: " + m_outstandingtextures.ToString()); | ||
250 | if (m_client.PacketHandler.PacketQueue.TextureOutgoingPacketQueueCount < threshold && m_outstandingtextures > 0) | ||
251 | { | ||
252 | bool justreset = false; | ||
253 | |||
254 | for (int x = m_priorities.Count - 1; x > -1; x--) | ||
255 | { | 245 | { |
256 | 246 | while (m_priorityQueue.Count > 0) | |
257 | J2KImage imagereq = m_imagestore[m_priorities.Values[x]]; | ||
258 | if (imagereq.m_decoded == true && !imagereq.m_completedSendAtCurrentDiscardLevel) | ||
259 | { | 247 | { |
260 | numCollected++; | 248 | J2KImage imagereq = null; |
261 | //SendPackets will send up to ten packets per cycle | 249 | lock (m_priorityQueue) |
262 | if (imagereq.SendPackets(m_client, maxpack)) | 250 | imagereq = m_priorityQueue.FindMax(); |
251 | |||
252 | if (imagereq.m_decoded == true) | ||
263 | { | 253 | { |
264 | //Send complete | 254 | // we need to test this here now that we are dropping assets |
265 | if (!imagereq.m_completedSendAtCurrentDiscardLevel) | 255 | if (!imagereq.m_hasasset) |
266 | { | 256 | { |
267 | imagereq.m_completedSendAtCurrentDiscardLevel = true; | 257 | m_log.WarnFormat("[LLIMAGE MANAGER]: Re-requesting the image asset {0}", imagereq.m_requestedUUID); |
268 | Interlocked.Decrement(ref m_outstandingtextures); | 258 | imagereq.RunUpdate(); |
269 | //Re-assign priority to bottom | 259 | continue; |
270 | //Remove the old priority | 260 | } |
271 | m_priorities.Remove(imagereq.m_designatedPriorityKey); | 261 | |
272 | int lowest; | 262 | ++numCollected; |
273 | if (m_priorities.Count > 0) | 263 | |
274 | { | 264 | //SendPackets will send up to ten packets per cycle |
275 | lowest = (int)m_priorities.Keys[0]; | 265 | if (imagereq.SendPackets(m_client, maxpack)) |
276 | lowest--; | 266 | { |
277 | } | 267 | // Send complete. Destroy any knowledge of this transfer |
278 | else | 268 | try |
279 | { | 269 | { |
280 | lowest = -10000; | 270 | lock (m_priorityQueue) |
281 | } | 271 | m_priorityQueue.Delete(imagereq.m_priorityQueueHandle); |
282 | m_priorities.Add((double)lowest, imagereq.m_requestedUUID); | ||
283 | imagereq.m_designatedPriorityKey = (double)lowest; | ||
284 | if (m_priorityresolver.ContainsKey((int)lowest)) | ||
285 | { | ||
286 | m_priorityresolver[(int)lowest]++; | ||
287 | } | ||
288 | else | ||
289 | { | ||
290 | m_priorityresolver.Add((int)lowest, 0); | ||
291 | } | 272 | } |
273 | catch (Exception) { } | ||
292 | } | 274 | } |
293 | } | 275 | } |
276 | |||
294 | if (numCollected == count) | 277 | if (numCollected == count) |
295 | { | ||
296 | break; | 278 | break; |
297 | } | ||
298 | } | ||
299 | if (numCollected == count || m_outstandingtextures == 0) | ||
300 | break; | ||
301 | if (numCollected % m_outstandingtextures == 0 && !justreset) | ||
302 | { | ||
303 | //We've gotten as much as we can from the stack, | ||
304 | //reset to the top so that we can send MOAR DATA (nomnomnom)! | ||
305 | x = m_priorities.Count - 1; | ||
306 | |||
307 | justreset = true; //prevents us from getting stuck in a loop | ||
308 | } | 279 | } |
309 | } | 280 | } |
310 | } | ||
311 | 281 | ||
312 | return m_outstandingtextures != 0; | 282 | return m_priorityQueue.Count > 0; |
283 | } | ||
313 | } | 284 | } |
314 | 285 | ||
315 | //Faux destructor | 286 | //Faux destructor |
316 | public void Close() | 287 | public void Close() |
317 | { | 288 | { |
318 | 289 | ||
319 | m_shuttingdown = true; | 290 | m_shuttingdown = true; |
320 | m_j2kDecodeModule = null; | 291 | m_j2kDecodeModule = null; |
321 | m_assetCache = null; | 292 | m_assetCache = null; |
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLPacketHandler.cs b/OpenSim/Region/ClientStack/LindenUDP/LLPacketHandler.cs index eaf8f60..e98a360 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLPacketHandler.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLPacketHandler.cs | |||
@@ -129,6 +129,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
129 | // | 129 | // |
130 | public event PacketStats OnPacketStats; | 130 | public event PacketStats OnPacketStats; |
131 | public event PacketDrop OnPacketDrop; | 131 | public event PacketDrop OnPacketDrop; |
132 | public event QueueEmpty OnQueueEmpty; | ||
132 | 133 | ||
133 | 134 | ||
134 | //private SynchronizeClientHandler m_SynchronizeClient = null; | 135 | //private SynchronizeClientHandler m_SynchronizeClient = null; |
@@ -172,13 +173,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
172 | 173 | ||
173 | m_PacketQueue = new LLPacketQueue(client.AgentId, userSettings); | 174 | m_PacketQueue = new LLPacketQueue(client.AgentId, userSettings); |
174 | 175 | ||
176 | m_PacketQueue.OnQueueEmpty += TriggerOnQueueEmpty; | ||
177 | |||
175 | m_AckTimer.Elapsed += AckTimerElapsed; | 178 | m_AckTimer.Elapsed += AckTimerElapsed; |
176 | m_AckTimer.Start(); | 179 | m_AckTimer.Start(); |
177 | } | 180 | } |
178 | 181 | ||
179 | public void Stop() | 182 | public void Dispose() |
180 | { | 183 | { |
181 | m_AckTimer.Stop(); | 184 | m_AckTimer.Stop(); |
185 | m_AckTimer.Close(); | ||
182 | 186 | ||
183 | m_PacketQueue.Enqueue(null); | 187 | m_PacketQueue.Enqueue(null); |
184 | m_PacketQueue.Close(); | 188 | m_PacketQueue.Close(); |
@@ -768,6 +772,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
768 | handlerPacketDrop(packet, id); | 772 | handlerPacketDrop(packet, id); |
769 | } | 773 | } |
770 | 774 | ||
775 | private void TriggerOnQueueEmpty(ThrottleOutPacketType queue) | ||
776 | { | ||
777 | QueueEmpty handlerQueueEmpty = OnQueueEmpty; | ||
778 | |||
779 | if (handlerQueueEmpty != null) | ||
780 | handlerQueueEmpty(queue); | ||
781 | } | ||
782 | |||
771 | // Convert the packet to bytes and stuff it onto the send queue | 783 | // Convert the packet to bytes and stuff it onto the send queue |
772 | // | 784 | // |
773 | public void ProcessOutPacket(LLQueItem item) | 785 | public void ProcessOutPacket(LLQueItem item) |
@@ -849,5 +861,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
849 | m_PacketQueue.Close(); | 861 | m_PacketQueue.Close(); |
850 | Thread.CurrentThread.Abort(); | 862 | Thread.CurrentThread.Abort(); |
851 | } | 863 | } |
864 | |||
865 | public int GetQueueCount(ThrottleOutPacketType queue) | ||
866 | { | ||
867 | return m_PacketQueue.GetQueueCount(queue); | ||
868 | } | ||
852 | } | 869 | } |
853 | } | 870 | } |
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLPacketQueue.cs b/OpenSim/Region/ClientStack/LindenUDP/LLPacketQueue.cs index c427870..3eed2e0 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLPacketQueue.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLPacketQueue.cs | |||
@@ -39,7 +39,7 @@ using Timer=System.Timers.Timer; | |||
39 | 39 | ||
40 | namespace OpenSim.Region.ClientStack.LindenUDP | 40 | namespace OpenSim.Region.ClientStack.LindenUDP |
41 | { | 41 | { |
42 | public class LLPacketQueue : IPullStatsProvider | 42 | public class LLPacketQueue : IPullStatsProvider, IDisposable |
43 | { | 43 | { |
44 | private static readonly ILog m_log | 44 | private static readonly ILog m_log |
45 | = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 45 | = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
@@ -62,6 +62,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
62 | private Queue<LLQueItem> TextureOutgoingPacketQueue; | 62 | private Queue<LLQueItem> TextureOutgoingPacketQueue; |
63 | private Queue<LLQueItem> AssetOutgoingPacketQueue; | 63 | private Queue<LLQueItem> AssetOutgoingPacketQueue; |
64 | 64 | ||
65 | private List<ThrottleOutPacketType> Empty = new List<ThrottleOutPacketType>(); | ||
66 | // m_log.Info("[THROTTLE]: Entering Throttle"); | ||
65 | // private Dictionary<uint, uint> PendingAcks = new Dictionary<uint, uint>(); | 67 | // private Dictionary<uint, uint> PendingAcks = new Dictionary<uint, uint>(); |
66 | // private Dictionary<uint, Packet> NeedAck = new Dictionary<uint, Packet>(); | 68 | // private Dictionary<uint, Packet> NeedAck = new Dictionary<uint, Packet>(); |
67 | 69 | ||
@@ -85,26 +87,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
85 | 87 | ||
86 | private Dictionary<uint,int> contents = new Dictionary<uint, int>(); | 88 | private Dictionary<uint,int> contents = new Dictionary<uint, int>(); |
87 | 89 | ||
88 | /// <summary> | ||
89 | /// The number of packets in the OutgoingPacketQueue | ||
90 | /// | ||
91 | /// </summary> | ||
92 | internal int TextureOutgoingPacketQueueCount | ||
93 | { | ||
94 | get | ||
95 | { | ||
96 | if (TextureOutgoingPacketQueue == null) | ||
97 | return 0; | ||
98 | return TextureOutgoingPacketQueue.Count; | ||
99 | } | ||
100 | } | ||
101 | |||
102 | // private long LastThrottle; | 90 | // private long LastThrottle; |
103 | // private long ThrottleInterval; | 91 | // private long ThrottleInterval; |
104 | private Timer throttleTimer; | 92 | private Timer throttleTimer; |
105 | 93 | ||
106 | private UUID m_agentId; | 94 | private UUID m_agentId; |
107 | 95 | ||
96 | public event QueueEmpty OnQueueEmpty; | ||
97 | |||
108 | public LLPacketQueue(UUID agentId, ClientStackUserSettings userSettings) | 98 | public LLPacketQueue(UUID agentId, ClientStackUserSettings userSettings) |
109 | { | 99 | { |
110 | // While working on this, the BlockingQueue had me fooled for a bit. | 100 | // While working on this, the BlockingQueue had me fooled for a bit. |
@@ -210,28 +200,28 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
210 | switch (item.throttleType & ThrottleOutPacketType.TypeMask) | 200 | switch (item.throttleType & ThrottleOutPacketType.TypeMask) |
211 | { | 201 | { |
212 | case ThrottleOutPacketType.Resend: | 202 | case ThrottleOutPacketType.Resend: |
213 | ThrottleCheck(ref ResendThrottle, ref ResendOutgoingPacketQueue, item); | 203 | ThrottleCheck(ref ResendThrottle, ref ResendOutgoingPacketQueue, item, ThrottleOutPacketType.Resend); |
214 | break; | 204 | break; |
215 | case ThrottleOutPacketType.Texture: | 205 | case ThrottleOutPacketType.Texture: |
216 | ThrottleCheck(ref TextureThrottle, ref TextureOutgoingPacketQueue, item); | 206 | ThrottleCheck(ref TextureThrottle, ref TextureOutgoingPacketQueue, item, ThrottleOutPacketType.Texture); |
217 | break; | 207 | break; |
218 | case ThrottleOutPacketType.Task: | 208 | case ThrottleOutPacketType.Task: |
219 | if ((item.throttleType & ThrottleOutPacketType.LowPriority) != 0) | 209 | if ((item.throttleType & ThrottleOutPacketType.LowPriority) != 0) |
220 | ThrottleCheck(ref TaskThrottle, ref TaskLowpriorityPacketQueue, item); | 210 | ThrottleCheck(ref TaskThrottle, ref TaskLowpriorityPacketQueue, item, ThrottleOutPacketType.Task); |
221 | else | 211 | else |
222 | ThrottleCheck(ref TaskThrottle, ref TaskOutgoingPacketQueue, item); | 212 | ThrottleCheck(ref TaskThrottle, ref TaskOutgoingPacketQueue, item, ThrottleOutPacketType.Task); |
223 | break; | 213 | break; |
224 | case ThrottleOutPacketType.Land: | 214 | case ThrottleOutPacketType.Land: |
225 | ThrottleCheck(ref LandThrottle, ref LandOutgoingPacketQueue, item); | 215 | ThrottleCheck(ref LandThrottle, ref LandOutgoingPacketQueue, item, ThrottleOutPacketType.Land); |
226 | break; | 216 | break; |
227 | case ThrottleOutPacketType.Asset: | 217 | case ThrottleOutPacketType.Asset: |
228 | ThrottleCheck(ref AssetThrottle, ref AssetOutgoingPacketQueue, item); | 218 | ThrottleCheck(ref AssetThrottle, ref AssetOutgoingPacketQueue, item, ThrottleOutPacketType.Asset); |
229 | break; | 219 | break; |
230 | case ThrottleOutPacketType.Cloud: | 220 | case ThrottleOutPacketType.Cloud: |
231 | ThrottleCheck(ref CloudThrottle, ref CloudOutgoingPacketQueue, item); | 221 | ThrottleCheck(ref CloudThrottle, ref CloudOutgoingPacketQueue, item, ThrottleOutPacketType.Cloud); |
232 | break; | 222 | break; |
233 | case ThrottleOutPacketType.Wind: | 223 | case ThrottleOutPacketType.Wind: |
234 | ThrottleCheck(ref WindThrottle, ref WindOutgoingPacketQueue, item); | 224 | ThrottleCheck(ref WindThrottle, ref WindOutgoingPacketQueue, item, ThrottleOutPacketType.Wind); |
235 | break; | 225 | break; |
236 | 226 | ||
237 | default: | 227 | default: |
@@ -283,43 +273,25 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
283 | { | 273 | { |
284 | lock (this) | 274 | lock (this) |
285 | { | 275 | { |
286 | while (PacketsWaiting()) | 276 | // These categories do not contain transactional packets so we can safely drop any pending data in them |
277 | LandOutgoingPacketQueue.Clear(); | ||
278 | WindOutgoingPacketQueue.Clear(); | ||
279 | CloudOutgoingPacketQueue.Clear(); | ||
280 | TextureOutgoingPacketQueue.Clear(); | ||
281 | AssetOutgoingPacketQueue.Clear(); | ||
282 | |||
283 | // Now comes the fun part.. we dump all remaining resend and task packets into the send queue | ||
284 | while (ResendOutgoingPacketQueue.Count > 0 || TaskOutgoingPacketQueue.Count > 0 || TaskLowpriorityPacketQueue.Count > 0) | ||
287 | { | 285 | { |
288 | //Now comes the fun part.. we dump all our elements into m_packetQueue that we've saved up. | ||
289 | if (ResendOutgoingPacketQueue.Count > 0) | 286 | if (ResendOutgoingPacketQueue.Count > 0) |
290 | { | ||
291 | SendQueue.Enqueue(ResendOutgoingPacketQueue.Dequeue()); | 287 | SendQueue.Enqueue(ResendOutgoingPacketQueue.Dequeue()); |
292 | } | 288 | |
293 | if (LandOutgoingPacketQueue.Count > 0) | ||
294 | { | ||
295 | SendQueue.Enqueue(LandOutgoingPacketQueue.Dequeue()); | ||
296 | } | ||
297 | if (WindOutgoingPacketQueue.Count > 0) | ||
298 | { | ||
299 | SendQueue.Enqueue(WindOutgoingPacketQueue.Dequeue()); | ||
300 | } | ||
301 | if (CloudOutgoingPacketQueue.Count > 0) | ||
302 | { | ||
303 | SendQueue.Enqueue(CloudOutgoingPacketQueue.Dequeue()); | ||
304 | } | ||
305 | if (TaskOutgoingPacketQueue.Count > 0) | 289 | if (TaskOutgoingPacketQueue.Count > 0) |
306 | { | ||
307 | SendQueue.PriorityEnqueue(TaskOutgoingPacketQueue.Dequeue()); | 290 | SendQueue.PriorityEnqueue(TaskOutgoingPacketQueue.Dequeue()); |
308 | } | 291 | |
309 | if (TaskLowpriorityPacketQueue.Count > 0) | 292 | if (TaskLowpriorityPacketQueue.Count > 0) |
310 | { | ||
311 | SendQueue.Enqueue(TaskLowpriorityPacketQueue.Dequeue()); | 293 | SendQueue.Enqueue(TaskLowpriorityPacketQueue.Dequeue()); |
312 | } | ||
313 | if (TextureOutgoingPacketQueue.Count > 0) | ||
314 | { | ||
315 | SendQueue.Enqueue(TextureOutgoingPacketQueue.Dequeue()); | ||
316 | } | ||
317 | if (AssetOutgoingPacketQueue.Count > 0) | ||
318 | { | ||
319 | SendQueue.Enqueue(AssetOutgoingPacketQueue.Dequeue()); | ||
320 | } | ||
321 | } | 294 | } |
322 | // m_log.Info("[THROTTLE]: Processed " + throttleLoops + " packets"); | ||
323 | } | 295 | } |
324 | } | 296 | } |
325 | 297 | ||
@@ -342,11 +314,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
342 | 314 | ||
343 | public void Close() | 315 | public void Close() |
344 | { | 316 | { |
317 | Dispose(); | ||
318 | } | ||
319 | |||
320 | public void Dispose() | ||
321 | { | ||
345 | Flush(); | 322 | Flush(); |
346 | WipeClean(); // I'm sure there's a dirty joke in here somewhere. -AFrisby | 323 | WipeClean(); // I'm sure there's a dirty joke in here somewhere. -AFrisby |
347 | 324 | ||
348 | m_enabled = false; | 325 | m_enabled = false; |
349 | throttleTimer.Stop(); | 326 | throttleTimer.Stop(); |
327 | throttleTimer.Close(); | ||
350 | 328 | ||
351 | if (StatsManager.SimExtraStats != null) | 329 | if (StatsManager.SimExtraStats != null) |
352 | { | 330 | { |
@@ -388,6 +366,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
388 | 366 | ||
389 | int MaxThrottleLoops = 4550; // 50*7 packets can be dequeued at once. | 367 | int MaxThrottleLoops = 4550; // 50*7 packets can be dequeued at once. |
390 | int throttleLoops = 0; | 368 | int throttleLoops = 0; |
369 | List<ThrottleOutPacketType> e; | ||
391 | 370 | ||
392 | // We're going to dequeue all of the saved up packets until | 371 | // We're going to dequeue all of the saved up packets until |
393 | // we've hit the throttle limit or there's no more packets to send | 372 | // we've hit the throttle limit or there's no more packets to send |
@@ -399,7 +378,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
399 | bool qchanged = true; | 378 | bool qchanged = true; |
400 | 379 | ||
401 | ResetCounters(); | 380 | ResetCounters(); |
402 | // m_log.Info("[THROTTLE]: Entering Throttle"); | 381 | |
403 | while (TotalThrottle.UnderLimit() && qchanged && throttleLoops <= MaxThrottleLoops) | 382 | while (TotalThrottle.UnderLimit() && qchanged && throttleLoops <= MaxThrottleLoops) |
404 | { | 383 | { |
405 | qchanged = false; // We will break out of the loop if no work was accomplished | 384 | qchanged = false; // We will break out of the loop if no work was accomplished |
@@ -425,6 +404,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
425 | TotalThrottle.AddBytes(qpack.Length); | 404 | TotalThrottle.AddBytes(qpack.Length); |
426 | LandThrottle.AddBytes(qpack.Length); | 405 | LandThrottle.AddBytes(qpack.Length); |
427 | qchanged = true; | 406 | qchanged = true; |
407 | |||
408 | if (LandOutgoingPacketQueue.Count == 0 && !Empty.Contains(ThrottleOutPacketType.Land)) | ||
409 | Empty.Add(ThrottleOutPacketType.Land); | ||
428 | } | 410 | } |
429 | 411 | ||
430 | if ((WindOutgoingPacketQueue.Count > 0) && WindThrottle.UnderLimit()) | 412 | if ((WindOutgoingPacketQueue.Count > 0) && WindThrottle.UnderLimit()) |
@@ -435,6 +417,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
435 | TotalThrottle.AddBytes(qpack.Length); | 417 | TotalThrottle.AddBytes(qpack.Length); |
436 | WindThrottle.AddBytes(qpack.Length); | 418 | WindThrottle.AddBytes(qpack.Length); |
437 | qchanged = true; | 419 | qchanged = true; |
420 | |||
421 | if (WindOutgoingPacketQueue.Count == 0 && !Empty.Contains(ThrottleOutPacketType.Wind)) | ||
422 | Empty.Add(ThrottleOutPacketType.Wind); | ||
438 | } | 423 | } |
439 | 424 | ||
440 | if ((CloudOutgoingPacketQueue.Count > 0) && CloudThrottle.UnderLimit()) | 425 | if ((CloudOutgoingPacketQueue.Count > 0) && CloudThrottle.UnderLimit()) |
@@ -445,6 +430,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
445 | TotalThrottle.AddBytes(qpack.Length); | 430 | TotalThrottle.AddBytes(qpack.Length); |
446 | CloudThrottle.AddBytes(qpack.Length); | 431 | CloudThrottle.AddBytes(qpack.Length); |
447 | qchanged = true; | 432 | qchanged = true; |
433 | |||
434 | if (CloudOutgoingPacketQueue.Count == 0 && !Empty.Contains(ThrottleOutPacketType.Cloud)) | ||
435 | Empty.Add(ThrottleOutPacketType.Cloud); | ||
448 | } | 436 | } |
449 | 437 | ||
450 | if ((TaskOutgoingPacketQueue.Count > 0 || TaskLowpriorityPacketQueue.Count > 0) && TaskThrottle.UnderLimit()) | 438 | if ((TaskOutgoingPacketQueue.Count > 0 || TaskLowpriorityPacketQueue.Count > 0) && TaskThrottle.UnderLimit()) |
@@ -464,6 +452,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
464 | TotalThrottle.AddBytes(qpack.Length); | 452 | TotalThrottle.AddBytes(qpack.Length); |
465 | TaskThrottle.AddBytes(qpack.Length); | 453 | TaskThrottle.AddBytes(qpack.Length); |
466 | qchanged = true; | 454 | qchanged = true; |
455 | |||
456 | if (TaskOutgoingPacketQueue.Count == 0 && TaskLowpriorityPacketQueue.Count == 0 && !Empty.Contains(ThrottleOutPacketType.Task)) | ||
457 | Empty.Add(ThrottleOutPacketType.Task); | ||
467 | } | 458 | } |
468 | 459 | ||
469 | if ((TextureOutgoingPacketQueue.Count > 0) && TextureThrottle.UnderLimit()) | 460 | if ((TextureOutgoingPacketQueue.Count > 0) && TextureThrottle.UnderLimit()) |
@@ -474,6 +465,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
474 | TotalThrottle.AddBytes(qpack.Length); | 465 | TotalThrottle.AddBytes(qpack.Length); |
475 | TextureThrottle.AddBytes(qpack.Length); | 466 | TextureThrottle.AddBytes(qpack.Length); |
476 | qchanged = true; | 467 | qchanged = true; |
468 | |||
469 | if (TextureOutgoingPacketQueue.Count == 0 && !Empty.Contains(ThrottleOutPacketType.Texture)) | ||
470 | Empty.Add(ThrottleOutPacketType.Texture); | ||
477 | } | 471 | } |
478 | 472 | ||
479 | if ((AssetOutgoingPacketQueue.Count > 0) && AssetThrottle.UnderLimit()) | 473 | if ((AssetOutgoingPacketQueue.Count > 0) && AssetThrottle.UnderLimit()) |
@@ -484,10 +478,30 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
484 | TotalThrottle.AddBytes(qpack.Length); | 478 | TotalThrottle.AddBytes(qpack.Length); |
485 | AssetThrottle.AddBytes(qpack.Length); | 479 | AssetThrottle.AddBytes(qpack.Length); |
486 | qchanged = true; | 480 | qchanged = true; |
481 | |||
482 | if (AssetOutgoingPacketQueue.Count == 0 && !Empty.Contains(ThrottleOutPacketType.Asset)) | ||
483 | Empty.Add(ThrottleOutPacketType.Asset); | ||
487 | } | 484 | } |
488 | } | 485 | } |
489 | // m_log.Info("[THROTTLE]: Processed " + throttleLoops + " packets"); | 486 | // m_log.Info("[THROTTLE]: Processed " + throttleLoops + " packets"); |
487 | |||
488 | e = new List<ThrottleOutPacketType>(Empty); | ||
489 | Empty.Clear(); | ||
490 | } | 490 | } |
491 | |||
492 | foreach (ThrottleOutPacketType t in e) | ||
493 | { | ||
494 | if (GetQueueCount(t) == 0) | ||
495 | TriggerOnQueueEmpty(t); | ||
496 | } | ||
497 | } | ||
498 | |||
499 | private void TriggerOnQueueEmpty(ThrottleOutPacketType queue) | ||
500 | { | ||
501 | QueueEmpty handlerQueueEmpty = OnQueueEmpty; | ||
502 | |||
503 | if (handlerQueueEmpty != null) | ||
504 | handlerQueueEmpty(queue); | ||
491 | } | 505 | } |
492 | 506 | ||
493 | private void ThrottleTimerElapsed(object sender, ElapsedEventArgs e) | 507 | private void ThrottleTimerElapsed(object sender, ElapsedEventArgs e) |
@@ -497,7 +511,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
497 | ProcessThrottle(); | 511 | ProcessThrottle(); |
498 | } | 512 | } |
499 | 513 | ||
500 | private void ThrottleCheck(ref LLPacketThrottle throttle, ref Queue<LLQueItem> q, LLQueItem item) | 514 | private void ThrottleCheck(ref LLPacketThrottle throttle, ref Queue<LLQueItem> q, LLQueItem item, ThrottleOutPacketType itemType) |
501 | { | 515 | { |
502 | // The idea.. is if the packet throttle queues are empty | 516 | // The idea.. is if the packet throttle queues are empty |
503 | // and the client is under throttle for the type. Queue | 517 | // and the client is under throttle for the type. Queue |
@@ -513,6 +527,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
513 | throttle.AddBytes(item.Length); | 527 | throttle.AddBytes(item.Length); |
514 | TotalThrottle.AddBytes(item.Length); | 528 | TotalThrottle.AddBytes(item.Length); |
515 | SendQueue.Enqueue(item); | 529 | SendQueue.Enqueue(item); |
530 | lock (this) | ||
531 | { | ||
532 | if (!Empty.Contains(itemType)) | ||
533 | Empty.Add(itemType); | ||
534 | } | ||
516 | } | 535 | } |
517 | catch (Exception e) | 536 | catch (Exception e) |
518 | { | 537 | { |
@@ -698,5 +717,26 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
698 | { | 717 | { |
699 | get { return throttleMultiplier; } | 718 | get { return throttleMultiplier; } |
700 | } | 719 | } |
720 | |||
721 | public int GetQueueCount(ThrottleOutPacketType queue) | ||
722 | { | ||
723 | switch (queue) | ||
724 | { | ||
725 | case ThrottleOutPacketType.Land: | ||
726 | return LandOutgoingPacketQueue.Count; | ||
727 | case ThrottleOutPacketType.Wind: | ||
728 | return WindOutgoingPacketQueue.Count; | ||
729 | case ThrottleOutPacketType.Cloud: | ||
730 | return CloudOutgoingPacketQueue.Count; | ||
731 | case ThrottleOutPacketType.Task: | ||
732 | return TaskOutgoingPacketQueue.Count; | ||
733 | case ThrottleOutPacketType.Texture: | ||
734 | return TextureOutgoingPacketQueue.Count; | ||
735 | case ThrottleOutPacketType.Asset: | ||
736 | return AssetOutgoingPacketQueue.Count; | ||
737 | } | ||
738 | |||
739 | return 0; | ||
740 | } | ||
701 | } | 741 | } |
702 | } | 742 | } |
diff --git a/OpenSim/Region/CoreModules/Agent/TextureSender/J2KDecoderModule.cs b/OpenSim/Region/CoreModules/Agent/TextureSender/J2KDecoderModule.cs index 1fdb003..a0f359b 100644 --- a/OpenSim/Region/CoreModules/Agent/TextureSender/J2KDecoderModule.cs +++ b/OpenSim/Region/CoreModules/Agent/TextureSender/J2KDecoderModule.cs | |||
@@ -34,8 +34,8 @@ using System.Threading; | |||
34 | using log4net; | 34 | using log4net; |
35 | using Nini.Config; | 35 | using Nini.Config; |
36 | using OpenMetaverse; | 36 | using OpenMetaverse; |
37 | using OpenMetaverse.Assets; | ||
38 | using OpenMetaverse.Imaging; | 37 | using OpenMetaverse.Imaging; |
38 | using CSJ2K; | ||
39 | using OpenSim.Framework; | 39 | using OpenSim.Framework; |
40 | using OpenSim.Region.Framework.Interfaces; | 40 | using OpenSim.Region.Framework.Interfaces; |
41 | using OpenSim.Region.Framework.Scenes; | 41 | using OpenSim.Region.Framework.Scenes; |
@@ -43,31 +43,25 @@ using OpenSim.Services.Interfaces; | |||
43 | 43 | ||
44 | namespace OpenSim.Region.CoreModules.Agent.TextureSender | 44 | namespace OpenSim.Region.CoreModules.Agent.TextureSender |
45 | { | 45 | { |
46 | public delegate void J2KDecodeDelegate(UUID AssetId); | 46 | public delegate void J2KDecodeDelegate(UUID assetID); |
47 | 47 | ||
48 | public class J2KDecoderModule : IRegionModule, IJ2KDecoder | 48 | public class J2KDecoderModule : IRegionModule, IJ2KDecoder |
49 | { | 49 | { |
50 | #region IRegionModule Members | 50 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
51 | 51 | ||
52 | private static readonly ILog m_log | 52 | /// <summary>Temporarily holds deserialized layer data information in memory</summary> |
53 | = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 53 | private readonly ExpiringCache<UUID, OpenJPEG.J2KLayerInfo[]> m_decodedCache = new ExpiringCache<UUID,OpenJPEG.J2KLayerInfo[]>(); |
54 | /// <summary>List of client methods to notify of results of decode</summary> | ||
55 | private readonly Dictionary<UUID, List<DecodedCallback>> m_notifyList = new Dictionary<UUID, List<DecodedCallback>>(); | ||
56 | /// <summary>Cache that will store decoded JPEG2000 layer boundary data</summary> | ||
57 | private IImprovedAssetCache m_cache; | ||
58 | /// <summary>Reference to a scene (doesn't matter which one as long as it can load the cache module)</summary> | ||
59 | private Scene m_scene; | ||
54 | 60 | ||
55 | /// <summary> | 61 | #region IRegionModule |
56 | /// Cached Decoded Layers | ||
57 | /// </summary> | ||
58 | private readonly Dictionary<UUID, OpenJPEG.J2KLayerInfo[]> m_cacheddecode = new Dictionary<UUID, OpenJPEG.J2KLayerInfo[]>(); | ||
59 | private bool OpenJpegFail = false; | ||
60 | private string CacheFolder = Util.dataDir() + "/j2kDecodeCache"; | ||
61 | private int CacheTimeout = 720; | ||
62 | private J2KDecodeFileCache fCache = null; | ||
63 | private Thread CleanerThread = null; | ||
64 | private IAssetService AssetService = null; | ||
65 | private Scene m_Scene = null; | ||
66 | 62 | ||
67 | /// <summary> | 63 | public string Name { get { return "J2KDecoderModule"; } } |
68 | /// List of client methods to notify of results of decode | 64 | public bool IsSharedModule { get { return true; } } |
69 | /// </summary> | ||
70 | private readonly Dictionary<UUID, List<DecodedCallback>> m_notifyList = new Dictionary<UUID, List<DecodedCallback>>(); | ||
71 | 65 | ||
72 | public J2KDecoderModule() | 66 | public J2KDecoderModule() |
73 | { | 67 | { |
@@ -75,630 +69,267 @@ namespace OpenSim.Region.CoreModules.Agent.TextureSender | |||
75 | 69 | ||
76 | public void Initialise(Scene scene, IConfigSource source) | 70 | public void Initialise(Scene scene, IConfigSource source) |
77 | { | 71 | { |
78 | if (m_Scene == null) | 72 | if (m_scene == null) |
79 | m_Scene = scene; | 73 | m_scene = scene; |
80 | |||
81 | IConfig j2kConfig = source.Configs["J2KDecoder"]; | ||
82 | if (j2kConfig != null) | ||
83 | { | ||
84 | CacheFolder = j2kConfig.GetString("CacheDir", CacheFolder); | ||
85 | CacheTimeout = j2kConfig.GetInt("CacheTimeout", CacheTimeout); | ||
86 | } | ||
87 | |||
88 | if (fCache == null) | ||
89 | fCache = new J2KDecodeFileCache(CacheFolder, CacheTimeout); | ||
90 | 74 | ||
91 | scene.RegisterModuleInterface<IJ2KDecoder>(this); | 75 | scene.RegisterModuleInterface<IJ2KDecoder>(this); |
92 | |||
93 | if (CleanerThread == null && CacheTimeout != 0) | ||
94 | { | ||
95 | CleanerThread = new Thread(CleanCache); | ||
96 | CleanerThread.Name = "J2KCleanerThread"; | ||
97 | CleanerThread.IsBackground = true; | ||
98 | CleanerThread.Start(); | ||
99 | } | ||
100 | } | 76 | } |
101 | 77 | ||
102 | public void PostInitialise() | 78 | public void PostInitialise() |
103 | { | 79 | { |
104 | AssetService = m_Scene.AssetService; | 80 | m_cache = m_scene.RequestModuleInterface<IImprovedAssetCache>(); |
105 | } | 81 | } |
106 | 82 | ||
107 | public void Close() | 83 | public void Close() |
108 | { | 84 | { |
109 | |||
110 | } | ||
111 | |||
112 | public string Name | ||
113 | { | ||
114 | get { return "J2KDecoderModule"; } | ||
115 | } | ||
116 | |||
117 | public bool IsSharedModule | ||
118 | { | ||
119 | get { return true; } | ||
120 | } | 85 | } |
121 | 86 | ||
122 | #endregion | 87 | #endregion IRegionModule |
123 | |||
124 | #region IJ2KDecoder Members | ||
125 | 88 | ||
89 | #region IJ2KDecoder | ||
126 | 90 | ||
127 | public void decode(UUID AssetId, byte[] assetData, DecodedCallback decodedReturn) | 91 | public void BeginDecode(UUID assetID, byte[] j2kData, DecodedCallback callback) |
128 | { | 92 | { |
129 | // Dummy for if decoding fails. | 93 | OpenJPEG.J2KLayerInfo[] result; |
130 | OpenJPEG.J2KLayerInfo[] result = new OpenJPEG.J2KLayerInfo[0]; | ||
131 | |||
132 | // Check if it's cached | ||
133 | bool cached = false; | ||
134 | lock (m_cacheddecode) | ||
135 | { | ||
136 | if (m_cacheddecode.ContainsKey(AssetId)) | ||
137 | { | ||
138 | cached = true; | ||
139 | result = m_cacheddecode[AssetId]; | ||
140 | } | ||
141 | } | ||
142 | 94 | ||
143 | // If it's cached, return the cached results | 95 | // If it's cached, return the cached results |
144 | if (cached) | 96 | if (m_decodedCache.TryGetValue(assetID, out result)) |
145 | { | 97 | { |
146 | decodedReturn(AssetId, result); | 98 | callback(assetID, result); |
147 | } | 99 | } |
148 | else | 100 | else |
149 | { | 101 | { |
150 | // not cached, so we need to decode it | 102 | // Not cached, we need to decode it. |
151 | // Add to notify list and start decoding. | 103 | // Add to notify list and start decoding. |
152 | // Next request for this asset while it's decoding will only be added to the notify list | 104 | // Next request for this asset while it's decoding will only be added to the notify list |
153 | // once this is decoded, requests will be served from the cache and all clients in the notifylist will be updated | 105 | // once this is decoded, requests will be served from the cache and all clients in the notifylist will be updated |
154 | bool decode = false; | 106 | bool decode = false; |
155 | lock (m_notifyList) | 107 | lock (m_notifyList) |
156 | { | 108 | { |
157 | if (m_notifyList.ContainsKey(AssetId)) | 109 | if (m_notifyList.ContainsKey(assetID)) |
158 | { | 110 | { |
159 | m_notifyList[AssetId].Add(decodedReturn); | 111 | m_notifyList[assetID].Add(callback); |
160 | } | 112 | } |
161 | else | 113 | else |
162 | { | 114 | { |
163 | List<DecodedCallback> notifylist = new List<DecodedCallback>(); | 115 | List<DecodedCallback> notifylist = new List<DecodedCallback>(); |
164 | notifylist.Add(decodedReturn); | 116 | notifylist.Add(callback); |
165 | m_notifyList.Add(AssetId, notifylist); | 117 | m_notifyList.Add(assetID, notifylist); |
166 | decode = true; | 118 | decode = true; |
167 | } | 119 | } |
168 | } | 120 | } |
121 | |||
169 | // Do Decode! | 122 | // Do Decode! |
170 | if (decode) | 123 | if (decode) |
171 | { | 124 | DoJ2KDecode(assetID, j2kData); |
172 | doJ2kDecode(AssetId, assetData); | ||
173 | } | ||
174 | } | 125 | } |
175 | } | 126 | } |
176 | 127 | ||
177 | /// <summary> | 128 | /// <summary> |
178 | /// Provides a synchronous decode so that caller can be assured that this executes before the next line | 129 | /// Provides a synchronous decode so that caller can be assured that this executes before the next line |
179 | /// </summary> | 130 | /// </summary> |
180 | /// <param name="AssetId"></param> | 131 | /// <param name="assetID"></param> |
181 | /// <param name="j2kdata"></param> | 132 | /// <param name="j2kData"></param> |
182 | public void syncdecode(UUID AssetId, byte[] j2kdata) | 133 | public void Decode(UUID assetID, byte[] j2kData) |
183 | { | 134 | { |
184 | doJ2kDecode(AssetId, j2kdata); | 135 | DoJ2KDecode(assetID, j2kData); |
185 | } | 136 | } |
186 | 137 | ||
187 | #endregion | 138 | #endregion IJ2KDecoder |
188 | 139 | ||
189 | /// <summary> | 140 | /// <summary> |
190 | /// Decode Jpeg2000 Asset Data | 141 | /// Decode Jpeg2000 Asset Data |
191 | /// </summary> | 142 | /// </summary> |
192 | /// <param name="AssetId">UUID of Asset</param> | 143 | /// <param name="assetID">UUID of Asset</param> |
193 | /// <param name="j2kdata">Byte Array Asset Data </param> | 144 | /// <param name="j2kData">JPEG2000 data</param> |
194 | private void doJ2kDecode(UUID AssetId, byte[] j2kdata) | 145 | private void DoJ2KDecode(UUID assetID, byte[] j2kData) |
195 | { | 146 | { |
196 | int DecodeTime = 0; | 147 | int DecodeTime = 0; |
197 | DecodeTime = Environment.TickCount; | 148 | DecodeTime = Environment.TickCount; |
198 | OpenJPEG.J2KLayerInfo[] layers = new OpenJPEG.J2KLayerInfo[0]; // Dummy result for if it fails. Informs that there's only full quality | 149 | OpenJPEG.J2KLayerInfo[] layers; |
199 | 150 | ||
200 | if (!OpenJpegFail) | 151 | if (!TryLoadCacheForAsset(assetID, out layers)) |
201 | { | 152 | { |
202 | if (!fCache.TryLoadCacheForAsset(AssetId, out layers)) | 153 | try |
203 | { | 154 | { |
204 | try | 155 | List<int> layerStarts = CSJ2K.J2kImage.GetLayerBoundaries(new MemoryStream(j2kData)); |
156 | |||
157 | if (layerStarts != null && layerStarts.Count > 0) | ||
205 | { | 158 | { |
159 | layers = new OpenJPEG.J2KLayerInfo[layerStarts.Count]; | ||
206 | 160 | ||
207 | AssetTexture texture = new AssetTexture(AssetId, j2kdata); | 161 | for (int i = 0; i < layerStarts.Count; i++) |
208 | if (texture.DecodeLayerBoundaries()) | ||
209 | { | 162 | { |
210 | bool sane = true; | 163 | OpenJPEG.J2KLayerInfo layer = new OpenJPEG.J2KLayerInfo(); |
211 | 164 | ||
212 | // Sanity check all of the layers | 165 | if (i == 0) |
213 | for (int i = 0; i < texture.LayerInfo.Length; i++) | 166 | layer.Start = 0; |
214 | { | ||
215 | if (texture.LayerInfo[i].End > texture.AssetData.Length) | ||
216 | { | ||
217 | sane = false; | ||
218 | break; | ||
219 | } | ||
220 | } | ||
221 | |||
222 | if (sane) | ||
223 | { | ||
224 | layers = texture.LayerInfo; | ||
225 | fCache.SaveFileCacheForAsset(AssetId, layers); | ||
226 | |||
227 | |||
228 | // Write out decode time | ||
229 | m_log.InfoFormat("[J2KDecoderModule]: {0} Decode Time: {1}", Environment.TickCount - DecodeTime, | ||
230 | AssetId); | ||
231 | |||
232 | } | ||
233 | else | 167 | else |
234 | { | 168 | layer.Start = layerStarts[i]; |
235 | m_log.WarnFormat( | ||
236 | "[J2KDecoderModule]: JPEG2000 texture decoding succeeded, but sanity check failed for {0}", | ||
237 | AssetId); | ||
238 | } | ||
239 | } | ||
240 | |||
241 | else | ||
242 | { | ||
243 | /* | ||
244 | Random rnd = new Random(); | ||
245 | // scramble ends for test | ||
246 | for (int i = 0; i < texture.LayerInfo.Length; i++) | ||
247 | { | ||
248 | texture.LayerInfo[i].End = rnd.Next(999999); | ||
249 | } | ||
250 | */ | ||
251 | |||
252 | // Try to do some heuristics error correction! Yeah. | ||
253 | bool sane2Heuristics = true; | ||
254 | |||
255 | |||
256 | if (texture.Image == null) | ||
257 | sane2Heuristics = false; | ||
258 | |||
259 | if (texture.LayerInfo == null) | ||
260 | sane2Heuristics = false; | ||
261 | |||
262 | if (sane2Heuristics) | ||
263 | { | ||
264 | |||
265 | 169 | ||
266 | if (texture.LayerInfo.Length == 0) | 170 | if (i == layerStarts.Count - 1) |
267 | sane2Heuristics = false; | 171 | layer.End = j2kData.Length; |
268 | } | ||
269 | |||
270 | if (sane2Heuristics) | ||
271 | { | ||
272 | // Last layer start is less then the end of the file and last layer start is greater then 0 | ||
273 | if (texture.LayerInfo[texture.LayerInfo.Length - 1].Start < texture.AssetData.Length && texture.LayerInfo[texture.LayerInfo.Length - 1].Start > 0) | ||
274 | { | ||
275 | } | ||
276 | else | ||
277 | { | ||
278 | sane2Heuristics = false; | ||
279 | } | ||
280 | |||
281 | } | ||
282 | |||
283 | if (sane2Heuristics) | ||
284 | { | ||
285 | int start = 0; | ||
286 | |||
287 | // try to fix it by using consistant data in the start field | ||
288 | for (int i = 0; i < texture.LayerInfo.Length; i++) | ||
289 | { | ||
290 | if (i == 0) | ||
291 | start = 0; | ||
292 | |||
293 | if (i == texture.LayerInfo.Length - 1) | ||
294 | texture.LayerInfo[i].End = texture.AssetData.Length; | ||
295 | else | ||
296 | texture.LayerInfo[i].End = texture.LayerInfo[i + 1].Start - 1; | ||
297 | |||
298 | // in this case, the end of the next packet is less then the start of the last packet | ||
299 | // after we've attempted to fix it which means the start of the last packet is borked | ||
300 | // there's no recovery from this | ||
301 | if (texture.LayerInfo[i].End < start) | ||
302 | { | ||
303 | sane2Heuristics = false; | ||
304 | break; | ||
305 | } | ||
306 | |||
307 | if (texture.LayerInfo[i].End < 0 || texture.LayerInfo[i].End > texture.AssetData.Length) | ||
308 | { | ||
309 | sane2Heuristics = false; | ||
310 | break; | ||
311 | } | ||
312 | |||
313 | if (texture.LayerInfo[i].Start < 0 || texture.LayerInfo[i].Start > texture.AssetData.Length) | ||
314 | { | ||
315 | sane2Heuristics = false; | ||
316 | break; | ||
317 | } | ||
318 | |||
319 | start = texture.LayerInfo[i].Start; | ||
320 | } | ||
321 | } | ||
322 | |||
323 | if (sane2Heuristics) | ||
324 | { | ||
325 | layers = texture.LayerInfo; | ||
326 | fCache.SaveFileCacheForAsset(AssetId, layers); | ||
327 | |||
328 | |||
329 | // Write out decode time | ||
330 | m_log.InfoFormat("[J2KDecoderModule]: HEURISTICS SUCCEEDED {0} Decode Time: {1}", Environment.TickCount - DecodeTime, | ||
331 | AssetId); | ||
332 | |||
333 | } | ||
334 | else | 172 | else |
335 | { | 173 | layer.End = layerStarts[i + 1] - 1; |
336 | m_log.WarnFormat("[J2KDecoderModule]: JPEG2000 texture decoding failed for {0}. Is this a texture? is it J2K?", AssetId); | 174 | |
337 | } | 175 | layers[i] = layer; |
338 | } | 176 | } |
339 | texture = null; // dereference and dispose of ManagedImage | ||
340 | } | ||
341 | catch (DllNotFoundException) | ||
342 | { | ||
343 | m_log.Error( | ||
344 | "[J2KDecoderModule]: OpenJpeg is not installed properly. Decoding disabled! This will slow down texture performance! Often times this is because of an old version of GLIBC. You must have version 2.4 or above!"); | ||
345 | OpenJpegFail = true; | ||
346 | } | ||
347 | catch (Exception ex) | ||
348 | { | ||
349 | m_log.WarnFormat( | ||
350 | "[J2KDecoderModule]: JPEG2000 texture decoding threw an exception for {0}, {1}", | ||
351 | AssetId, ex); | ||
352 | } | 177 | } |
353 | } | 178 | } |
354 | 179 | catch (Exception ex) | |
355 | } | 180 | { |
181 | m_log.Warn("[J2KDecoderModule]: CSJ2K threw an exception decoding texture " + assetID + ": " + ex.Message); | ||
182 | } | ||
356 | 183 | ||
357 | // Cache Decoded layers | 184 | if (layers == null || layers.Length == 0) |
358 | lock (m_cacheddecode) | 185 | { |
359 | { | 186 | m_log.Warn("[J2KDecoderModule]: Failed to decode layer data for texture " + assetID + ", guessing sane defaults"); |
360 | if (m_cacheddecode.ContainsKey(AssetId)) | 187 | // Layer decoding completely failed. Guess at sane defaults for the layer boundaries |
361 | m_cacheddecode.Remove(AssetId); | 188 | layers = CreateDefaultLayers(j2kData.Length); |
362 | m_cacheddecode.Add(AssetId, layers); | 189 | } |
363 | 190 | ||
191 | // Cache Decoded layers | ||
192 | SaveFileCacheForAsset(assetID, layers); | ||
364 | } | 193 | } |
365 | 194 | ||
366 | // Notify Interested Parties | 195 | // Notify Interested Parties |
367 | lock (m_notifyList) | 196 | lock (m_notifyList) |
368 | { | 197 | { |
369 | if (m_notifyList.ContainsKey(AssetId)) | 198 | if (m_notifyList.ContainsKey(assetID)) |
370 | { | 199 | { |
371 | foreach (DecodedCallback d in m_notifyList[AssetId]) | 200 | foreach (DecodedCallback d in m_notifyList[assetID]) |
372 | { | 201 | { |
373 | if (d != null) | 202 | if (d != null) |
374 | d.DynamicInvoke(AssetId, layers); | 203 | d.DynamicInvoke(assetID, layers); |
375 | } | 204 | } |
376 | m_notifyList.Remove(AssetId); | 205 | m_notifyList.Remove(assetID); |
377 | } | 206 | } |
378 | } | 207 | } |
379 | } | 208 | } |
380 | |||
381 | private void CleanCache() | ||
382 | { | ||
383 | m_log.Info("[J2KDecoderModule]: Cleaner thread started"); | ||
384 | |||
385 | while (true) | ||
386 | { | ||
387 | if (AssetService != null) | ||
388 | fCache.ScanCacheFiles(RedecodeTexture); | ||
389 | 209 | ||
390 | System.Threading.Thread.Sleep(600000); | 210 | private OpenJPEG.J2KLayerInfo[] CreateDefaultLayers(int j2kLength) |
391 | } | ||
392 | } | ||
393 | |||
394 | private void RedecodeTexture(UUID assetID) | ||
395 | { | 211 | { |
396 | AssetBase texture = AssetService.Get(assetID.ToString()); | 212 | OpenJPEG.J2KLayerInfo[] layers = new OpenJPEG.J2KLayerInfo[5]; |
397 | if (texture == null) | 213 | |
398 | return; | 214 | for (int i = 0; i < layers.Length; i++) |
399 | 215 | layers[i] = new OpenJPEG.J2KLayerInfo(); | |
400 | doJ2kDecode(assetID, texture.Data); | 216 | |
217 | // These default layer sizes are based on a small sampling of real-world texture data | ||
218 | // with extra padding thrown in for good measure. This is a worst case fallback plan | ||
219 | // and may not gracefully handle all real world data | ||
220 | layers[0].Start = 0; | ||
221 | layers[1].Start = (int)((float)j2kLength * 0.02f); | ||
222 | layers[2].Start = (int)((float)j2kLength * 0.05f); | ||
223 | layers[3].Start = (int)((float)j2kLength * 0.20f); | ||
224 | layers[4].Start = (int)((float)j2kLength * 0.50f); | ||
225 | |||
226 | layers[0].End = layers[1].Start - 1; | ||
227 | layers[1].End = layers[2].Start - 1; | ||
228 | layers[2].End = layers[3].Start - 1; | ||
229 | layers[3].End = layers[4].Start - 1; | ||
230 | layers[4].End = j2kLength; | ||
231 | |||
232 | return layers; | ||
401 | } | 233 | } |
402 | } | ||
403 | 234 | ||
404 | public class J2KDecodeFileCache | 235 | private void SaveFileCacheForAsset(UUID AssetId, OpenJPEG.J2KLayerInfo[] Layers) |
405 | { | ||
406 | private readonly string m_cacheDecodeFolder; | ||
407 | private readonly int m_cacheTimeout; | ||
408 | private bool enabled = true; | ||
409 | |||
410 | private static readonly ILog m_log | ||
411 | = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
412 | |||
413 | /// <summary> | ||
414 | /// Creates a new instance of a file cache | ||
415 | /// </summary> | ||
416 | /// <param name="pFolder">base folder for the cache. Will be created if it doesn't exist</param> | ||
417 | public J2KDecodeFileCache(string pFolder, int timeout) | ||
418 | { | 236 | { |
419 | m_cacheDecodeFolder = pFolder; | 237 | m_decodedCache.AddOrUpdate(AssetId, Layers, TimeSpan.FromMinutes(10)); |
420 | m_cacheTimeout = timeout; | ||
421 | if (!Directory.Exists(pFolder)) | ||
422 | { | ||
423 | Createj2KCacheFolder(pFolder); | ||
424 | } | ||
425 | } | ||
426 | 238 | ||
427 | /// <summary> | 239 | if (m_cache != null) |
428 | /// Save Layers to Disk Cache | ||
429 | /// </summary> | ||
430 | /// <param name="AssetId">Asset to Save the layers. Used int he file name by default</param> | ||
431 | /// <param name="Layers">The Layer Data from OpenJpeg</param> | ||
432 | /// <returns></returns> | ||
433 | public bool SaveFileCacheForAsset(UUID AssetId, OpenJPEG.J2KLayerInfo[] Layers) | ||
434 | { | ||
435 | if (Layers.Length > 0 && enabled) | ||
436 | { | 240 | { |
437 | FileStream fsCache = | 241 | AssetBase layerDecodeAsset = new AssetBase(); |
438 | new FileStream(String.Format("{0}/{1}", m_cacheDecodeFolder, FileNameFromAssetId(AssetId)), | 242 | layerDecodeAsset.ID = "j2kCache_" + AssetId.ToString(); |
439 | FileMode.Create); | 243 | layerDecodeAsset.Local = true; |
440 | StreamWriter fsSWCache = new StreamWriter(fsCache); | 244 | layerDecodeAsset.Name = layerDecodeAsset.ID; |
245 | layerDecodeAsset.Temporary = true; | ||
246 | layerDecodeAsset.Type = (sbyte)AssetType.Notecard; | ||
247 | |||
248 | #region Serialize Layer Data | ||
249 | |||
441 | StringBuilder stringResult = new StringBuilder(); | 250 | StringBuilder stringResult = new StringBuilder(); |
442 | string strEnd = "\n"; | 251 | string strEnd = "\n"; |
443 | for (int i = 0; i < Layers.Length; i++) | 252 | for (int i = 0; i < Layers.Length; i++) |
444 | { | 253 | { |
445 | if (i == (Layers.Length - 1)) | 254 | if (i == Layers.Length - 1) |
446 | strEnd = ""; | 255 | strEnd = String.Empty; |
447 | 256 | ||
448 | stringResult.AppendFormat("{0}|{1}|{2}{3}", Layers[i].Start, Layers[i].End, Layers[i].End - Layers[i].Start, strEnd); | 257 | stringResult.AppendFormat("{0}|{1}|{2}{3}", Layers[i].Start, Layers[i].End, Layers[i].End - Layers[i].Start, strEnd); |
449 | } | 258 | } |
450 | fsSWCache.Write(stringResult.ToString()); | ||
451 | fsSWCache.Close(); | ||
452 | fsSWCache.Dispose(); | ||
453 | fsCache.Dispose(); | ||
454 | return true; | ||
455 | } | ||
456 | |||
457 | 259 | ||
458 | return false; | 260 | layerDecodeAsset.Data = Encoding.UTF8.GetBytes(stringResult.ToString()); |
459 | } | ||
460 | 261 | ||
461 | 262 | #endregion Serialize Layer Data | |
462 | /// <summary> | ||
463 | /// Loads the Layer data from the disk cache | ||
464 | /// Returns true if load succeeded | ||
465 | /// </summary> | ||
466 | /// <param name="AssetId">AssetId that we're checking the cache for</param> | ||
467 | /// <param name="Layers">out layers to save to</param> | ||
468 | /// <returns>true if load succeeded</returns> | ||
469 | public bool TryLoadCacheForAsset(UUID AssetId, out OpenJPEG.J2KLayerInfo[] Layers) | ||
470 | { | ||
471 | string filename = String.Format("{0}/{1}", m_cacheDecodeFolder, FileNameFromAssetId(AssetId)); | ||
472 | Layers = new OpenJPEG.J2KLayerInfo[0]; | ||
473 | 263 | ||
474 | if (!File.Exists(filename)) | 264 | m_cache.Cache(layerDecodeAsset); |
475 | return false; | ||
476 | |||
477 | if (!enabled) | ||
478 | { | ||
479 | return false; | ||
480 | } | 265 | } |
266 | } | ||
481 | 267 | ||
482 | string readResult = string.Empty; | 268 | bool TryLoadCacheForAsset(UUID AssetId, out OpenJPEG.J2KLayerInfo[] Layers) |
483 | 269 | { | |
484 | try | 270 | if (m_decodedCache.TryGetValue(AssetId, out Layers)) |
485 | { | 271 | { |
486 | FileStream fsCachefile = | 272 | return true; |
487 | new FileStream(filename, | ||
488 | FileMode.Open); | ||
489 | |||
490 | StreamReader sr = new StreamReader(fsCachefile); | ||
491 | readResult = sr.ReadToEnd(); | ||
492 | |||
493 | sr.Close(); | ||
494 | sr.Dispose(); | ||
495 | fsCachefile.Dispose(); | ||
496 | |||
497 | } | 273 | } |
498 | catch (IOException ioe) | 274 | else if (m_cache != null) |
499 | { | 275 | { |
500 | if (ioe is PathTooLongException) | 276 | string assetName = "j2kCache_" + AssetId.ToString(); |
501 | { | 277 | AssetBase layerDecodeAsset = m_cache.Get(assetName); |
502 | m_log.Error( | ||
503 | "[J2KDecodeCache]: Cache Read failed. Path is too long."); | ||
504 | } | ||
505 | else if (ioe is DirectoryNotFoundException) | ||
506 | { | ||
507 | m_log.Error( | ||
508 | "[J2KDecodeCache]: Cache Read failed. Cache Directory does not exist!"); | ||
509 | enabled = false; | ||
510 | } | ||
511 | else | ||
512 | { | ||
513 | m_log.Error( | ||
514 | "[J2KDecodeCache]: Cache Read failed. IO Exception."); | ||
515 | } | ||
516 | return false; | ||
517 | 278 | ||
518 | } | 279 | if (layerDecodeAsset != null) |
519 | catch (UnauthorizedAccessException) | ||
520 | { | ||
521 | m_log.Error( | ||
522 | "[J2KDecodeCache]: Cache Read failed. UnauthorizedAccessException Exception. Do you have the proper permissions on this file?"); | ||
523 | return false; | ||
524 | } | ||
525 | catch (ArgumentException ae) | ||
526 | { | ||
527 | if (ae is ArgumentNullException) | ||
528 | { | ||
529 | m_log.Error( | ||
530 | "[J2KDecodeCache]: Cache Read failed. No Filename provided"); | ||
531 | } | ||
532 | else | ||
533 | { | 280 | { |
534 | m_log.Error( | 281 | #region Deserialize Layer Data |
535 | "[J2KDecodeCache]: Cache Read failed. Filname was invalid"); | ||
536 | } | ||
537 | return false; | ||
538 | } | ||
539 | catch (NotSupportedException) | ||
540 | { | ||
541 | m_log.Error( | ||
542 | "[J2KDecodeCache]: Cache Read failed, not supported. Cache disabled!"); | ||
543 | enabled = false; | ||
544 | 282 | ||
545 | return false; | 283 | string readResult = Encoding.UTF8.GetString(layerDecodeAsset.Data); |
546 | } | 284 | string[] lines = readResult.Split(new char[] { '\n' }, StringSplitOptions.RemoveEmptyEntries); |
547 | catch (Exception e) | ||
548 | { | ||
549 | m_log.ErrorFormat( | ||
550 | "[J2KDecodeCache]: Cache Read failed, unknown exception. Error: {0}", | ||
551 | e.ToString()); | ||
552 | return false; | ||
553 | } | ||
554 | |||
555 | string[] lines = readResult.Split('\n'); | ||
556 | 285 | ||
557 | if (lines.Length <= 0) | 286 | if (lines.Length == 0) |
558 | return false; | ||
559 | |||
560 | Layers = new OpenJPEG.J2KLayerInfo[lines.Length]; | ||
561 | |||
562 | for (int i = 0; i < lines.Length; i++) | ||
563 | { | ||
564 | string[] elements = lines[i].Split('|'); | ||
565 | if (elements.Length == 3) | ||
566 | { | ||
567 | int element1, element2; | ||
568 | |||
569 | try | ||
570 | { | ||
571 | element1 = Convert.ToInt32(elements[0]); | ||
572 | element2 = Convert.ToInt32(elements[1]); | ||
573 | } | ||
574 | catch (FormatException) | ||
575 | { | 287 | { |
576 | m_log.WarnFormat("[J2KDecodeCache]: Cache Read failed with ErrorConvert for {0}", AssetId); | 288 | m_log.Warn("[J2KDecodeCache]: Expiring corrupted layer data (empty) " + assetName); |
577 | Layers = new OpenJPEG.J2KLayerInfo[0]; | 289 | m_cache.Expire(assetName); |
578 | return false; | 290 | return false; |
579 | } | 291 | } |
580 | 292 | ||
581 | Layers[i] = new OpenJPEG.J2KLayerInfo(); | 293 | Layers = new OpenJPEG.J2KLayerInfo[lines.Length]; |
582 | Layers[i].Start = element1; | ||
583 | Layers[i].End = element2; | ||
584 | |||
585 | } | ||
586 | else | ||
587 | { | ||
588 | // reading failed | ||
589 | m_log.WarnFormat("[J2KDecodeCache]: Cache Read failed for {0}", AssetId); | ||
590 | Layers = new OpenJPEG.J2KLayerInfo[0]; | ||
591 | return false; | ||
592 | } | ||
593 | } | ||
594 | |||
595 | |||
596 | |||
597 | |||
598 | return true; | ||
599 | } | ||
600 | 294 | ||
601 | /// <summary> | 295 | for (int i = 0; i < lines.Length; i++) |
602 | /// Routine which converts assetid to file name | 296 | { |
603 | /// </summary> | 297 | string[] elements = lines[i].Split('|'); |
604 | /// <param name="AssetId">asset id of the image</param> | 298 | if (elements.Length == 3) |
605 | /// <returns>string filename</returns> | 299 | { |
606 | public string FileNameFromAssetId(UUID AssetId) | 300 | int element1, element2; |
607 | { | ||
608 | return String.Format("j2kCache_{0}.cache", AssetId); | ||
609 | } | ||
610 | 301 | ||
611 | public UUID AssetIdFromFileName(string fileName) | 302 | try |
612 | { | 303 | { |
613 | string rawId = fileName.Replace("j2kCache_", "").Replace(".cache", ""); | 304 | element1 = Convert.ToInt32(elements[0]); |
614 | UUID asset; | 305 | element2 = Convert.ToInt32(elements[1]); |
615 | if (!UUID.TryParse(rawId, out asset)) | 306 | } |
616 | return UUID.Zero; | 307 | catch (FormatException) |
308 | { | ||
309 | m_log.Warn("[J2KDecodeCache]: Expiring corrupted layer data (format) " + assetName); | ||
310 | m_cache.Expire(assetName); | ||
311 | return false; | ||
312 | } | ||
617 | 313 | ||
618 | return asset; | 314 | Layers[i] = new OpenJPEG.J2KLayerInfo(); |
619 | } | 315 | Layers[i].Start = element1; |
316 | Layers[i].End = element2; | ||
317 | } | ||
318 | else | ||
319 | { | ||
320 | m_log.Warn("[J2KDecodeCache]: Expiring corrupted layer data (layout) " + assetName); | ||
321 | m_cache.Expire(assetName); | ||
322 | return false; | ||
323 | } | ||
324 | } | ||
620 | 325 | ||
621 | /// <summary> | 326 | #endregion Deserialize Layer Data |
622 | /// Creates the Cache Folder | ||
623 | /// </summary> | ||
624 | /// <param name="pFolder">Folder to Create</param> | ||
625 | public void Createj2KCacheFolder(string pFolder) | ||
626 | { | ||
627 | try | ||
628 | { | ||
629 | Directory.CreateDirectory(pFolder); | ||
630 | } | ||
631 | catch (IOException ioe) | ||
632 | { | ||
633 | if (ioe is PathTooLongException) | ||
634 | { | ||
635 | m_log.Error( | ||
636 | "[J2KDecodeCache]: Cache Directory does not exist and create failed because the path to the cache folder is too long. Cache disabled!"); | ||
637 | } | ||
638 | else if (ioe is DirectoryNotFoundException) | ||
639 | { | ||
640 | m_log.Error( | ||
641 | "[J2KDecodeCache]: Cache Directory does not exist and create failed because the supplied base of the directory folder does not exist. Cache disabled!"); | ||
642 | } | ||
643 | else | ||
644 | { | ||
645 | m_log.Error( | ||
646 | "[J2KDecodeCache]: Cache Directory does not exist and create failed because of an IO Exception. Cache disabled!"); | ||
647 | } | ||
648 | enabled = false; | ||
649 | 327 | ||
650 | } | 328 | return true; |
651 | catch (UnauthorizedAccessException) | ||
652 | { | ||
653 | m_log.Error( | ||
654 | "[J2KDecodeCache]: Cache Directory does not exist and create failed because of an UnauthorizedAccessException Exception. Cache disabled!"); | ||
655 | enabled = false; | ||
656 | } | ||
657 | catch (ArgumentException ae) | ||
658 | { | ||
659 | if (ae is ArgumentNullException) | ||
660 | { | ||
661 | m_log.Error( | ||
662 | "[J2KDecodeCache]: Cache Directory does not exist and create failed because the folder provided is invalid! Cache disabled!"); | ||
663 | } | 329 | } |
664 | else | ||
665 | { | ||
666 | m_log.Error( | ||
667 | "[J2KDecodeCache]: Cache Directory does not exist and create failed because no cache folder was provided! Cache disabled!"); | ||
668 | } | ||
669 | enabled = false; | ||
670 | } | 330 | } |
671 | catch (NotSupportedException) | ||
672 | { | ||
673 | m_log.Error( | ||
674 | "[J2KDecodeCache]: Cache Directory does not exist and create failed because it's not supported. Cache disabled!"); | ||
675 | enabled = false; | ||
676 | } | ||
677 | catch (Exception e) | ||
678 | { | ||
679 | m_log.ErrorFormat( | ||
680 | "[J2KDecodeCache]: Cache Directory does not exist and create failed because of an unknown exception. Cache disabled! Error: {0}", | ||
681 | e.ToString()); | ||
682 | enabled = false; | ||
683 | } | ||
684 | } | ||
685 | |||
686 | public void ScanCacheFiles(J2KDecodeDelegate decode) | ||
687 | { | ||
688 | DirectoryInfo dir = new DirectoryInfo(m_cacheDecodeFolder); | ||
689 | FileInfo[] files = dir.GetFiles("j2kCache_*.cache"); | ||
690 | 331 | ||
691 | foreach (FileInfo f in files) | 332 | return false; |
692 | { | ||
693 | TimeSpan fileAge = DateTime.Now - f.CreationTime; | ||
694 | |||
695 | if (m_cacheTimeout != 0 && fileAge >= TimeSpan.FromMinutes(m_cacheTimeout)) | ||
696 | { | ||
697 | File.Delete(f.Name); | ||
698 | decode(AssetIdFromFileName(f.Name)); | ||
699 | System.Threading.Thread.Sleep(5000); | ||
700 | } | ||
701 | } | ||
702 | } | 333 | } |
703 | } | 334 | } |
704 | } | 335 | } |
diff --git a/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs b/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs index 14eb9a2..9a6c49a 100644 --- a/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs | |||
@@ -325,7 +325,7 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture | |||
325 | IJ2KDecoder cacheLayerDecode = scene.RequestModuleInterface<IJ2KDecoder>(); | 325 | IJ2KDecoder cacheLayerDecode = scene.RequestModuleInterface<IJ2KDecoder>(); |
326 | if (cacheLayerDecode != null) | 326 | if (cacheLayerDecode != null) |
327 | { | 327 | { |
328 | cacheLayerDecode.syncdecode(asset.FullID, asset.Data); | 328 | cacheLayerDecode.Decode(asset.FullID, asset.Data); |
329 | cacheLayerDecode = null; | 329 | cacheLayerDecode = null; |
330 | LastAssetID = asset.FullID; | 330 | LastAssetID = asset.FullID; |
331 | } | 331 | } |
diff --git a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs index f4526ae..8ad4844 100644 --- a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs +++ b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs | |||
@@ -1102,5 +1102,9 @@ namespace OpenSim.Region.Examples.SimpleModule | |||
1102 | { | 1102 | { |
1103 | } | 1103 | } |
1104 | #endregion | 1104 | #endregion |
1105 | |||
1106 | public void SendRebakeAvatarTextures(UUID textureID) | ||
1107 | { | ||
1108 | } | ||
1105 | } | 1109 | } |
1106 | } | 1110 | } |
diff --git a/OpenSim/Region/Framework/Interfaces/IJ2KDecoder.cs b/OpenSim/Region/Framework/Interfaces/IJ2KDecoder.cs index b153997..856eb11 100644 --- a/OpenSim/Region/Framework/Interfaces/IJ2KDecoder.cs +++ b/OpenSim/Region/Framework/Interfaces/IJ2KDecoder.cs | |||
@@ -30,12 +30,11 @@ using OpenMetaverse.Imaging; | |||
30 | 30 | ||
31 | namespace OpenSim.Region.Framework.Interfaces | 31 | namespace OpenSim.Region.Framework.Interfaces |
32 | { | 32 | { |
33 | |||
34 | public delegate void DecodedCallback(UUID AssetId, OpenJPEG.J2KLayerInfo[] layers); | 33 | public delegate void DecodedCallback(UUID AssetId, OpenJPEG.J2KLayerInfo[] layers); |
35 | 34 | ||
36 | public interface IJ2KDecoder | 35 | public interface IJ2KDecoder |
37 | { | 36 | { |
38 | void decode(UUID AssetId, byte[] assetData, DecodedCallback decodedReturn); | 37 | void BeginDecode(UUID assetID, byte[] j2kData, DecodedCallback callback); |
39 | void syncdecode(UUID AssetId, byte[] j2kdata); | 38 | void Decode(UUID assetID, byte[] j2kData); |
40 | } | 39 | } |
41 | } | 40 | } |
diff --git a/OpenSim/Region/Framework/Scenes/SceneManager.cs b/OpenSim/Region/Framework/Scenes/SceneManager.cs index 1d4efd0..3097929 100644 --- a/OpenSim/Region/Framework/Scenes/SceneManager.cs +++ b/OpenSim/Region/Framework/Scenes/SceneManager.cs | |||
@@ -540,127 +540,5 @@ namespace OpenSim.Region.Framework.Scenes | |||
540 | { | 540 | { |
541 | m_localScenes.ForEach(action); | 541 | m_localScenes.ForEach(action); |
542 | } | 542 | } |
543 | |||
544 | public void CacheJ2kDecode(int threads) | ||
545 | { | ||
546 | if (threads < 1) threads = 1; | ||
547 | |||
548 | IJ2KDecoder m_decoder = m_localScenes[0].RequestModuleInterface<IJ2KDecoder>(); | ||
549 | |||
550 | List<UUID> assetRequestList = new List<UUID>(); | ||
551 | |||
552 | #region AssetGathering! | ||
553 | foreach (Scene scene in m_localScenes) | ||
554 | { | ||
555 | List<EntityBase> entitles = scene.GetEntities(); | ||
556 | foreach (EntityBase entity in entitles) | ||
557 | { | ||
558 | if (entity is SceneObjectGroup) | ||
559 | { | ||
560 | SceneObjectGroup sog = (SceneObjectGroup) entity; | ||
561 | foreach (SceneObjectPart part in sog.Children.Values) | ||
562 | { | ||
563 | if (part.Shape != null) | ||
564 | { | ||
565 | if (part.Shape.TextureEntry.Length > 0) | ||
566 | { | ||
567 | OpenMetaverse.Primitive.TextureEntry te = | ||
568 | new Primitive.TextureEntry(part.Shape.TextureEntry, 0, | ||
569 | part.Shape.TextureEntry.Length); | ||
570 | if (te.DefaultTexture != null) // this has been null for some reason... | ||
571 | { | ||
572 | if (te.DefaultTexture.TextureID != UUID.Zero) | ||
573 | assetRequestList.Add(te.DefaultTexture.TextureID); | ||
574 | } | ||
575 | for (int i=0; i<te.FaceTextures.Length; i++) | ||
576 | { | ||
577 | if (te.FaceTextures[i] != null) | ||
578 | { | ||
579 | if (te.FaceTextures[i].TextureID != UUID.Zero) | ||
580 | { | ||
581 | assetRequestList.Add(te.FaceTextures[i].TextureID); | ||
582 | } | ||
583 | } | ||
584 | } | ||
585 | } | ||
586 | if (part.Shape.SculptTexture != UUID.Zero) | ||
587 | { | ||
588 | assetRequestList.Add(part.Shape.SculptTexture); | ||
589 | } | ||
590 | |||
591 | } | ||
592 | } | ||
593 | } | ||
594 | } | ||
595 | } | ||
596 | #endregion | ||
597 | |||
598 | int entries_per_thread = (assetRequestList.Count / threads) + 1; | ||
599 | |||
600 | UUID[] arrAssetRequestList = assetRequestList.ToArray(); | ||
601 | |||
602 | List<UUID[]> arrvalus = new List<UUID[]>(); | ||
603 | |||
604 | //split into separate arrays | ||
605 | for (int j = 0; j < threads; j++) | ||
606 | { | ||
607 | List<UUID> val = new List<UUID>(); | ||
608 | |||
609 | for (int k = j * entries_per_thread; k < ((j + 1) * entries_per_thread); k++) | ||
610 | { | ||
611 | if (k < arrAssetRequestList.Length) | ||
612 | { | ||
613 | val.Add(arrAssetRequestList[k]); | ||
614 | } | ||
615 | |||
616 | } | ||
617 | arrvalus.Add(val.ToArray()); | ||
618 | } | ||
619 | |||
620 | for (int l = 0; l < arrvalus.Count; l++) | ||
621 | { | ||
622 | DecodeThreadContents threadworkItem = new DecodeThreadContents(); | ||
623 | threadworkItem.sn = m_localScenes[0]; | ||
624 | threadworkItem.j2kdecode = m_decoder; | ||
625 | threadworkItem.arrassets = arrvalus[l]; | ||
626 | |||
627 | System.Threading.Thread decodethread = | ||
628 | new System.Threading.Thread(new System.Threading.ParameterizedThreadStart(threadworkItem.run)); | ||
629 | |||
630 | threadworkItem.SetThread(decodethread); | ||
631 | |||
632 | decodethread.Priority = System.Threading.ThreadPriority.Lowest; | ||
633 | decodethread.Name = "J2kCacheDecodeThread_" + l + 1; | ||
634 | ThreadTracker.Add(decodethread); | ||
635 | decodethread.Start(); | ||
636 | |||
637 | } | ||
638 | } | ||
639 | } | ||
640 | |||
641 | public class DecodeThreadContents | ||
642 | { | ||
643 | public Scene sn; | ||
644 | public UUID[] arrassets; | ||
645 | public IJ2KDecoder j2kdecode; | ||
646 | private System.Threading.Thread thisthread; | ||
647 | |||
648 | public void run(object o) | ||
649 | { | ||
650 | for (int i=0;i<arrassets.Length;i++) | ||
651 | { | ||
652 | AssetBase ab = sn.AssetService.Get(arrassets[i].ToString()); | ||
653 | if (ab != null && ab.Data != null) | ||
654 | { | ||
655 | j2kdecode.syncdecode(arrassets[i], ab.Data); | ||
656 | } | ||
657 | } | ||
658 | ThreadTracker.Remove(thisthread); | ||
659 | } | ||
660 | |||
661 | public void SetThread(System.Threading.Thread thr) | ||
662 | { | ||
663 | thisthread = thr; | ||
664 | } | ||
665 | } | 543 | } |
666 | } | 544 | } |
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 66fefa3..3996cdc 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs | |||
@@ -74,6 +74,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
74 | 74 | ||
75 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 75 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
76 | 76 | ||
77 | private static readonly byte[] BAKE_INDICES = new byte[] { 8, 9, 10, 11, 19, 20 }; | ||
78 | |||
77 | public static byte[] DefaultTexture; | 79 | public static byte[] DefaultTexture; |
78 | 80 | ||
79 | public UUID currentParcelUUID = UUID.Zero; | 81 | public UUID currentParcelUUID = UUID.Zero; |
@@ -2686,7 +2688,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2686 | /// </summary> | 2688 | /// </summary> |
2687 | /// <param name="texture"></param> | 2689 | /// <param name="texture"></param> |
2688 | /// <param name="visualParam"></param> | 2690 | /// <param name="visualParam"></param> |
2689 | public void SetAppearance(byte[] texture, List<byte> visualParam) | 2691 | public void SetAppearance(Primitive.TextureEntry textureEntry, byte[] visualParams) |
2690 | { | 2692 | { |
2691 | if (m_physicsActor != null) | 2693 | if (m_physicsActor != null) |
2692 | { | 2694 | { |
@@ -2704,7 +2706,30 @@ namespace OpenSim.Region.Framework.Scenes | |||
2704 | AddToPhysicalScene(flyingTemp); | 2706 | AddToPhysicalScene(flyingTemp); |
2705 | } | 2707 | } |
2706 | } | 2708 | } |
2707 | m_appearance.SetAppearance(texture, visualParam); | 2709 | |
2710 | #region Bake Cache Check | ||
2711 | |||
2712 | if (textureEntry != null) | ||
2713 | { | ||
2714 | for (int i = 0; i < BAKE_INDICES.Length; i++) | ||
2715 | { | ||
2716 | int j = BAKE_INDICES[i]; | ||
2717 | Primitive.TextureEntryFace face = textureEntry.FaceTextures[j]; | ||
2718 | |||
2719 | if (face != null && face.TextureID != AppearanceManager.DEFAULT_AVATAR_TEXTURE) | ||
2720 | { | ||
2721 | if (m_scene.AssetService.Get(face.TextureID.ToString()) == null) | ||
2722 | { | ||
2723 | m_log.Warn("[APPEARANCE]: Missing baked texture " + face.TextureID + " (" + (AppearanceManager.TextureIndex)j + ") for avatar " + this.Name); | ||
2724 | this.ControllingClient.SendRebakeAvatarTextures(face.TextureID); | ||
2725 | } | ||
2726 | } | ||
2727 | } | ||
2728 | } | ||
2729 | |||
2730 | #endregion Bake Cache Check | ||
2731 | |||
2732 | m_appearance.SetAppearance(textureEntry, visualParams); | ||
2708 | if (m_appearance.AvatarHeight > 0) | 2733 | if (m_appearance.AvatarHeight > 0) |
2709 | SetHeight(m_appearance.AvatarHeight); | 2734 | SetHeight(m_appearance.AvatarHeight); |
2710 | m_scene.CommsManager.AvatarService.UpdateUserAppearance(m_controllingClient.AgentId, m_appearance); | 2735 | m_scene.CommsManager.AvatarService.UpdateUserAppearance(m_controllingClient.AgentId, m_appearance); |
@@ -3255,14 +3280,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
3255 | wears[i++] = new AvatarWearable(itemId, assetId); | 3280 | wears[i++] = new AvatarWearable(itemId, assetId); |
3256 | } | 3281 | } |
3257 | m_appearance.Wearables = wears; | 3282 | m_appearance.Wearables = wears; |
3258 | byte[] te = null; | 3283 | Primitive.TextureEntry te; |
3259 | if (cAgent.AgentTextures != null) | 3284 | if (cAgent.AgentTextures != null && cAgent.AgentTextures.Length > 1) |
3260 | te = cAgent.AgentTextures; | 3285 | te = new Primitive.TextureEntry(cAgent.AgentTextures, 0, cAgent.AgentTextures.Length); |
3261 | else | 3286 | else |
3262 | te = AvatarAppearance.GetDefaultTexture().GetBytes(); | 3287 | te = AvatarAppearance.GetDefaultTexture(); |
3263 | if ((cAgent.VisualParams == null) || (cAgent.VisualParams.Length < AvatarAppearance.VISUALPARAM_COUNT)) | 3288 | if ((cAgent.VisualParams == null) || (cAgent.VisualParams.Length < AvatarAppearance.VISUALPARAM_COUNT)) |
3264 | cAgent.VisualParams = AvatarAppearance.GetDefaultVisualParams(); | 3289 | cAgent.VisualParams = AvatarAppearance.GetDefaultVisualParams(); |
3265 | m_appearance.SetAppearance(te, new List<byte>(cAgent.VisualParams)); | 3290 | m_appearance.SetAppearance(te, (byte[])cAgent.VisualParams.Clone()); |
3266 | } | 3291 | } |
3267 | catch (Exception e) | 3292 | catch (Exception e) |
3268 | { | 3293 | { |
diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs index 605645b..ee2d2db 100644 --- a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs +++ b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs | |||
@@ -861,12 +861,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server | |||
861 | Scene scene = (Scene)Scene; | 861 | Scene scene = (Scene)Scene; |
862 | AvatarAppearance appearance; | 862 | AvatarAppearance appearance; |
863 | scene.GetAvatarAppearance(this, out appearance); | 863 | scene.GetAvatarAppearance(this, out appearance); |
864 | List<byte> visualParams = new List<byte>(); | 864 | OnSetAppearance(appearance.Texture, (byte[])appearance.VisualParams.Clone()); |
865 | foreach (byte visualParam in appearance.VisualParams) | ||
866 | { | ||
867 | visualParams.Add(visualParam); | ||
868 | } | ||
869 | OnSetAppearance(appearance.Texture.GetBytes(), visualParams); | ||
870 | } | 865 | } |
871 | 866 | ||
872 | public void SendRegionHandshake(RegionInfo regionInfo, RegionHandshakeArgs args) | 867 | public void SendRegionHandshake(RegionInfo regionInfo, RegionHandshakeArgs args) |
@@ -1609,5 +1604,9 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server | |||
1609 | } | 1604 | } |
1610 | 1605 | ||
1611 | #endregion | 1606 | #endregion |
1607 | |||
1608 | public void SendRebakeAvatarTextures(UUID textureID) | ||
1609 | { | ||
1610 | } | ||
1612 | } | 1611 | } |
1613 | } | 1612 | } |
diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs index f0bdf3b..ac8b98c 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs | |||
@@ -1101,5 +1101,9 @@ namespace OpenSim.Region.OptionalModules.World.NPC | |||
1101 | { | 1101 | { |
1102 | } | 1102 | } |
1103 | #endregion | 1103 | #endregion |
1104 | |||
1105 | public void SendRebakeAvatarTextures(UUID textureID) | ||
1106 | { | ||
1107 | } | ||
1104 | } | 1108 | } |
1105 | } | 1109 | } |
diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs index b3bfe07..30a2675 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs | |||
@@ -163,13 +163,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC | |||
163 | { | 163 | { |
164 | AvatarAppearance x = GetAppearance(p_cloneAppearanceFrom, p_scene); | 164 | AvatarAppearance x = GetAppearance(p_cloneAppearanceFrom, p_scene); |
165 | 165 | ||
166 | List<byte> wearbyte = new List<byte>(); | 166 | sp.SetAppearance(x.Texture, (byte[])x.VisualParams.Clone()); |
167 | for (int i = 0; i < x.VisualParams.Length; i++) | ||
168 | { | ||
169 | wearbyte.Add(x.VisualParams[i]); | ||
170 | } | ||
171 | |||
172 | sp.SetAppearance(x.Texture.GetBytes(), wearbyte); | ||
173 | } | 167 | } |
174 | 168 | ||
175 | m_avatars.Add(npcAvatar.AgentId, npcAvatar); | 169 | m_avatars.Add(npcAvatar.AgentId, npcAvatar); |
diff --git a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs index 56eb359..d56ddc8 100644 --- a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs +++ b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs | |||
@@ -78,6 +78,20 @@ namespace OpenSim.Region.Physics.Meshing | |||
78 | 78 | ||
79 | private Dictionary<ulong, Mesh> m_uniqueMeshes = new Dictionary<ulong, Mesh>(); | 79 | private Dictionary<ulong, Mesh> m_uniqueMeshes = new Dictionary<ulong, Mesh>(); |
80 | 80 | ||
81 | public Meshmerizer() | ||
82 | { | ||
83 | try | ||
84 | { | ||
85 | if (!Directory.Exists(decodedScultMapPath)) | ||
86 | Directory.CreateDirectory(decodedScultMapPath); | ||
87 | } | ||
88 | catch (Exception e) | ||
89 | { | ||
90 | m_log.WarnFormat("[SCULPT]: Unable to create {0} directory: ", decodedScultMapPath, e.Message); | ||
91 | } | ||
92 | |||
93 | } | ||
94 | |||
81 | /// <summary> | 95 | /// <summary> |
82 | /// creates a simple box mesh of the specified size. This mesh is of very low vertex count and may | 96 | /// creates a simple box mesh of the specified size. This mesh is of very low vertex count and may |
83 | /// be useful as a backup proxy when level of detail is not needed or when more complex meshes fail | 97 | /// be useful as a backup proxy when level of detail is not needed or when more complex meshes fail |
diff --git a/OpenSim/Server/Handlers/Tests/Asset/AssetServerGetHandlerTests.cs b/OpenSim/Server/Handlers/Tests/Asset/AssetServerGetHandlerTests.cs deleted file mode 100644 index 04a73e4..0000000 --- a/OpenSim/Server/Handlers/Tests/Asset/AssetServerGetHandlerTests.cs +++ /dev/null | |||
@@ -1,80 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | using NUnit.Framework; | ||
29 | using OpenSim.Framework; | ||
30 | using OpenSim.Framework.Servers.HttpServer; | ||
31 | using OpenSim.Server.Handlers.Asset; | ||
32 | using OpenSim.Services.Interfaces; | ||
33 | using OpenSim.Tests.Common; | ||
34 | using OpenSim.Tests.Common.Mock; | ||
35 | using OpenSim.Tests.Common.Setup; | ||
36 | |||
37 | namespace OpenSim.Server.Handlers.Tests.Asset | ||
38 | { | ||
39 | [TestFixture] | ||
40 | public class AssetServerGetHandlerTests | ||
41 | { | ||
42 | private const string ASSETS_PATH = "/assets"; | ||
43 | |||
44 | [Test] | ||
45 | public void TestConstructor() | ||
46 | { | ||
47 | TestHelper.InMethod(); | ||
48 | |||
49 | new AssetServerGetHandler(null); | ||
50 | } | ||
51 | |||
52 | [Test] | ||
53 | public void TestGetParams() | ||
54 | { | ||
55 | TestHelper.InMethod(); | ||
56 | |||
57 | AssetServerGetHandler handler = new AssetServerGetHandler(null); | ||
58 | BaseRequestHandlerTestHelper.BaseTestGetParams(handler, ASSETS_PATH); | ||
59 | } | ||
60 | |||
61 | [Test] | ||
62 | public void TestSplitParams() | ||
63 | { | ||
64 | TestHelper.InMethod(); | ||
65 | |||
66 | AssetServerGetHandler handler = new AssetServerGetHandler(null); | ||
67 | BaseRequestHandlerTestHelper.BaseTestSplitParams(handler, ASSETS_PATH); | ||
68 | } | ||
69 | |||
70 | // TODO: unused | ||
71 | // private static AssetBase CreateTestEnvironment(out AssetServerGetHandler handler, out OSHttpResponse response) | ||
72 | // { | ||
73 | // AssetBase asset = GetAssetStreamHandlerTestHelpers.CreateCommonTestResources(out response); | ||
74 | // IAssetService assetDataPlugin = new TestAssetService(); | ||
75 | // handler = new AssetServerGetHandler(assetDataPlugin); | ||
76 | // assetDataPlugin.Store(asset); | ||
77 | // return asset; | ||
78 | // } | ||
79 | } | ||
80 | } | ||
diff --git a/OpenSim/Tests/Common/Mock/TestClient.cs b/OpenSim/Tests/Common/Mock/TestClient.cs index fe31729..2b54890 100644 --- a/OpenSim/Tests/Common/Mock/TestClient.cs +++ b/OpenSim/Tests/Common/Mock/TestClient.cs | |||
@@ -1163,5 +1163,9 @@ namespace OpenSim.Tests.Common.Mock | |||
1163 | { | 1163 | { |
1164 | } | 1164 | } |
1165 | 1165 | ||
1166 | public void SendRebakeAvatarTextures(UUID textureID) | ||
1167 | { | ||
1168 | } | ||
1169 | |||
1166 | } | 1170 | } |
1167 | } | 1171 | } |
diff --git a/Prebuild/AUTHORS b/Prebuild/AUTHORS deleted file mode 100644 index 9e86ac0..0000000 --- a/Prebuild/AUTHORS +++ /dev/null | |||
@@ -1,10 +0,0 @@ | |||
1 | Dave Hudson (jendave@yahoo.com), | ||
2 | Matthew Holmes (matthew@wildfiregames.com) | ||
3 | Dan Moorehead (dan05a@gmail.com) | ||
4 | Rob Loach (http://www.robloach.net) | ||
5 | C.J. Adams-Collier (cjac@colliertech.org) | ||
6 | |||
7 | Patch Contributers | ||
8 | lbsa71 | ||
9 | chi11ken | ||
10 | sdague | ||
diff --git a/Prebuild/COPYING b/Prebuild/COPYING deleted file mode 100644 index c57c080..0000000 --- a/Prebuild/COPYING +++ /dev/null | |||
@@ -1,65 +0,0 @@ | |||
1 | BSD License | ||
2 | Copyright (c)2004-2008 | ||
3 | |||
4 | See AUTHORS file for list of copyright holders | ||
5 | |||
6 | Dave Hudson (jendave@yahoo.com), | ||
7 | Matthew Holmes (matthew@wildfiregames.com) | ||
8 | Dan Moorehead (dan05a@gmail.com) | ||
9 | Rob Loach (http://www.robloach.net) | ||
10 | C.J. Adams-Collier (cjac@colliertech.org) | ||
11 | |||
12 | http://dnpb.sourceforge.net | ||
13 | All rights reserved. | ||
14 | |||
15 | Redistribution and use in source and binary forms, with or without | ||
16 | modification, are permitted provided that the following conditions | ||
17 | are met: | ||
18 | |||
19 | 1. Redistributions of source code must retain the above copyright notice, | ||
20 | this list of conditions and the following disclaimer. | ||
21 | |||
22 | 2. Redistributions in binary form must reproduce the above copyright notice, | ||
23 | this list of conditions and the following disclaimer in the documentation | ||
24 | and/or other materials provided with the distribution. | ||
25 | |||
26 | 3. The names of the authors may not be used to endorse or promote | ||
27 | products derived from this software without specific prior written | ||
28 | permission. | ||
29 | |||
30 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
31 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
32 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS | ||
33 | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE | ||
34 | COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
35 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | ||
36 | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
37 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | ||
38 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
39 | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN | ||
40 | ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
41 | POSSIBILITY OF SUCH DAMAGE. | ||
42 | |||
43 | --- | ||
44 | |||
45 | Portions of src/Core/Targets/AutotoolsTarget.cs | ||
46 | // Copyright (C) 2006 Novell, Inc (http://www.novell.com) | ||
47 | // | ||
48 | // Permission is hereby granted, free of charge, to any person obtaining | ||
49 | // a copy of this software and associated documentation files (the | ||
50 | // "Software"), to deal in the Software without restriction, including | ||
51 | // without limitation the rights to use, copy, modify, merge, publish, | ||
52 | // distribute, sublicense, and/or sell copies of the Software, and to | ||
53 | // permit persons to whom the Software is furnished to do so, subject to | ||
54 | // the following conditions: | ||
55 | // | ||
56 | // The above copyright notice and this permission notice shall be | ||
57 | // included in all copies or substantial portions of the Software. | ||
58 | // | ||
59 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
60 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
61 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
62 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE | ||
63 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | ||
64 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | ||
65 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
diff --git a/Prebuild/ChangeLog b/Prebuild/ChangeLog deleted file mode 100644 index bb8e7b0..0000000 --- a/Prebuild/ChangeLog +++ /dev/null | |||
@@ -1,461 +0,0 @@ | |||
1 | 2008-12-09T02:15 D. Moonfire <d.moonfire@mfgames.com> | ||
2 | * src/Core/Kernel.cs | ||
3 | - Added a /ppi target to get the results of processing but before | ||
4 | processing the actual results. | ||
5 | * src/Core/Preprocessor.cs | ||
6 | - Applied the patch from kanato with formatting changes. | ||
7 | - Uses the <?include file="" ?> format. | ||
8 | * tests/ | ||
9 | - Added some lightweight tests to test the functionality of the | ||
10 | include patch. | ||
11 | |||
12 | 2008-06-19T09:37 John Anderson <sontek@gmail.com> | ||
13 | * src/Core/Kernel.cs | ||
14 | - Only Loop through targets that are not abstract. | ||
15 | * src/Core/Targets/VSGenericTarget.cs | ||
16 | - Marked abstract and removed the Target attribute. | ||
17 | |||
18 | 2008-06-16T17:37 John Anderson <sontek@gmail.com> | ||
19 | * src/Core/Nodes/ProjectNode.cs,data/prebuild-1.7.xsd | ||
20 | - Added the ability to hardcode guid's in the projects | ||
21 | |||
22 | 2008-05-21T0737 C.J. Adams-Collier <cjac@colliertech.org> | ||
23 | * src/Core/Targets/AutotoolsTarget.cs | ||
24 | - catch exception when unable to compile AssemblyInfo.cs | ||
25 | |||
26 | 2008-05-07T17:29 John Anderson <sontek@gmail.com> | ||
27 | * src/Core/Targets/VSGenericTarget.cs | ||
28 | - Generate asp.net output in bin\ folder (asp.net requires it there) | ||
29 | |||
30 | 2008-04-30T17:29 John Anderson <sontek@gmail.com> | ||
31 | * src/Core/Nodes/DatabaseReferenceNode.cs, | ||
32 | src/Core/Nodes/Datanode.cs, | ||
33 | src/Core/Nodes/FileNode.cs, | ||
34 | src/Core/Nodes/FileNodes.cs, | ||
35 | src/Core/Nodes/MatchNode.cs, | ||
36 | src/Core/Targets/VS2008Target.cs, | ||
37 | src/data/prebuild-1.7.xsd | ||
38 | - Refactored the project generation code to handle web projects and more | ||
39 | logically handle embedded resources and designer files. | ||
40 | |||
41 | 2008-04-30T17:29 Joseph Lombrozo <digitaljeebus@gmail.com> | ||
42 | * src/Core/Nodes/SolutionNode.cs | ||
43 | - Had solutions inherit Configurations in the same way that Projects do. | ||
44 | |||
45 | 2008-04-29T06:35 Joseph Lombrozo <digitaljeebus@gmail.com> | ||
46 | * src/Core/Targets/VS2008Target.cs, | ||
47 | src/Core/Nodes/DatabaseProjectNode.cs, | ||
48 | src/Core/Nodes/DatabaseReferenceNode.cs, | ||
49 | src/data/prebuild-1.7.xsd | ||
50 | - Added database references to database projects. | ||
51 | - Prevented nested solutions from being written to disk. | ||
52 | |||
53 | 2008-04-29T05:43 Joseph Lombrozo <digitaljeebus@gmail.com> | ||
54 | * src/Core/Targets/VS2008Target.cs | ||
55 | - Enabled embedded solutions to contain Files. | ||
56 | |||
57 | 2008-04-29T04:13 Joseph Lombrozo <digitaljeebus@gmail.com> | ||
58 | * src/Core/VSVersion.cs | ||
59 | - Fixed spelling mistake in enum comment. | ||
60 | * src/Core/Attributes/DataNodeAttribute.cs | ||
61 | - Allowed the DataNodeAttribute to be attached to a single class | ||
62 | more than once, allowing one class to be used to parse more than | ||
63 | one node at a time. | ||
64 | * src/Core/Kernel.cs | ||
65 | - Changed CacheNodeTypes() to allow for multiple DataNodeAttribute | ||
66 | instances in one class. Refactored ProcessFile(...) to return Solutions, | ||
67 | rather than adding them to the Kernel. | ||
68 | * src/Core/Nodes/SolutionNode.cs | ||
69 | - Added Guid (for embedded folders) | ||
70 | - Added DatabaseProjects, Solutions and Processes to the SolutionNode | ||
71 | when parsing. | ||
72 | * src/Core/Nodes/ProjectNode.cs | ||
73 | - Added FrameworkVersion property to allow for 2.0/3.0/3.5 differentiation. | ||
74 | * src/Core/Targets/VS2008Target.cs, src/data/prebuild-1.7.xsd | ||
75 | - Added ability to have embedded solutions, and externally referenced | ||
76 | prebuild scripts. | ||
77 | |||
78 | 2008-04-24T04:33 John M. Anderson <sontek@gmail.com> | ||
79 | * src/Core/Targets/VS2003Target.cs, src/Core/Targets/VSVersion.cs | ||
80 | - Moved the VSVersion enum into its own file. | ||
81 | * src/Core/Targets/VS2008Target.cs | ||
82 | - added support for VS2008 | ||
83 | * src/Core/Nodes/ProjectNode.cs | ||
84 | - Added initial support for ASP.NET projects | ||
85 | * src/Core/Nodes/DatabaseProjectNode.cs | ||
86 | - Added support for Visual Studio database projects | ||
87 | |||
88 | 2008-02-19T07:08 C.J. Adams-Collier <cjac@colliertech.org> | ||
89 | * TODO | ||
90 | - added some tasks from Sam Hocevar | ||
91 | * src/Core/Targets/AutotoolsTarget.cs | ||
92 | - added a missing end paren | ||
93 | * COPYING | ||
94 | - Removed Randy Ridge's name from the copyright. Looks to me like | ||
95 | his name was present only because the file was nabbed from Tao | ||
96 | |||
97 | 2008-02-09T20:29 C.J. Adams-Collier <cjac@colliertech.org> | ||
98 | * COPYING | ||
99 | - added MIT/X11 license due to inclusion of code from Monodevelop | ||
100 | * THANKS | ||
101 | - added Lluis Sanchez Gual and Todd Berman - I yoinked code from | ||
102 | their pkg-config .pc file parser to build AutotoolsTarget.cs. | ||
103 | Sorry it took me so long to remember to add mention of you guys! | ||
104 | * src/Core/Targets/AutotoolsTarget.cs | ||
105 | - added MIT/X11 license. see above. | ||
106 | |||
107 | 2008-02-07T08:27 C.J. Adams-Collier <cjac@colliertech.org> | ||
108 | * AUTHORS | ||
109 | - consolidated names and contact info found laying around the | ||
110 | source | ||
111 | * src/Core/Kernel.cs | ||
112 | - updated copyright date | ||
113 | - re-formatted license for 80-column editor | ||
114 | - updated log banner to indicate new date, new authors | ||
115 | * src/Core/Targets/AutotoolsTarget.cs | ||
116 | - clarified reasoning behind use of constants in | ||
117 | AutotoolsTarget.ParsePCFile | ||
118 | - reduced length of some long lines using newline/indent | ||
119 | - added log messages for parsing .pc files, emitting solutions, | ||
120 | projects | ||
121 | - robustified the inter-package dependency resolution target | ||
122 | - log warning when we can't find assembly for <Reference /> | ||
123 | - clarified code for case of inability to find embedded | ||
124 | autotools.xml | ||
125 | * src/data/autotools.xml | ||
126 | - adding system lookup of resgen2 to configure.ac | ||
127 | - fixed .resource -> .resources typo | ||
128 | - added a rule to create <foo>.response file containing all sources | ||
129 | - using @<foo>.response on $(CSC) command line instead of listing | ||
130 | all source files | ||
131 | * src/Properties/AssemblyInfo.cs | ||
132 | - re-formatted license for an 80-column editor | ||
133 | - added more authors to the AssemblyCopyright attribute | ||
134 | - bumped version to 2.0.3 | ||
135 | * prebuild.xml | ||
136 | - bumped version to 2.0.3 | ||
137 | * scripts/autotools.sh | ||
138 | - if 'mono' is in the path, run Prebuild.exe with it | ||
139 | - using dirname to capture correct path to prebuild.xml &c | ||
140 | |||
141 | 2008-02-06T17:18 C.J. Adams-Collier <cjac@colliertech.org> | ||
142 | * src/Core/Targets/NAntTarget.cs | ||
143 | - re-formatted the license for an 80-column editor | ||
144 | - added myself to the copyright | ||
145 | - added a fix submitted by Gryc Ueusp <gryc.ueusp@gmail.com> | ||
146 | * src/Core/Targets/AutotoolsTarget.cs | ||
147 | - updated copyright to include 2008 | ||
148 | * THANKS | ||
149 | - created file, added Gryc Ueusp <gryc.ueusp@gmail.com> | ||
150 | |||
151 | 2008-01-01T14:50 C.J. Adams-Collier <cjac@colliertech.org> | ||
152 | * src/data/autotools.xml | ||
153 | - fixed .resx -> .resource compilation | ||
154 | - fixed failing edge case where Project is an unsigned Library | ||
155 | - added $(RESOURCE_SRC) to list of extra dist files | ||
156 | * src/Core/Targets/AutotoolsTarget.cs | ||
157 | - removed embeddedResources from extraDistFiles list | ||
158 | |||
159 | 2007-04-18T07:49 C.J. Adams-Collier <cjac@colliertech.org> | ||
160 | * src/data/prebuild-1.7.xsd | ||
161 | - removed default version from references | ||
162 | |||
163 | 2007-04-06T12:42 C.J. Adams-Collier <cjac@colliertech.org> | ||
164 | * src/data/autotools.xml | ||
165 | - added support for /doc: output when XmlDocFile is not empty | ||
166 | - not printing \t \\n on lines that have no content | ||
167 | - gacutil now installs the root assembly instead of the one under | ||
168 | bin/Debug or whatever | ||
169 | |||
170 | 2007-04-04T22:12 C.J. Adams-Collier <cjac@colliertech.org> | ||
171 | * src/Core/Targets/AutotoolsTarget.cs | ||
172 | - removed debugging Console.WriteLine() | ||
173 | * src/data/autotools.xml | ||
174 | - ensuring that install-sh and missing get distributed | ||
175 | - explicitly stating that the sources, snk, resources and binary | ||
176 | references live under $(srcdir) | ||
177 | - corrected uninstall target | ||
178 | - verified distcheck completes successfully | ||
179 | |||
180 | 2007-04-03T21:56 C.J. Adams-Collier <cjac@colliertech.org> | ||
181 | * src/Core/Targets/AutotoolsTarget.cs | ||
182 | - added a using for System.Diagnostics | ||
183 | - added enum ClrVersion for use with the pkg-config parser | ||
184 | - added class SystemPackage for use with the pkg-config parser | ||
185 | - removed explicit "private" property of members since it is implied | ||
186 | - flushing the stream-writer before it's closed | ||
187 | - removed excess braces around an if statement | ||
188 | ! NormalizeAsmName(), AddAssembly(), GetAssembliesWithLibInfo(), | ||
189 | GetAssembliesWithoutLibInfo(), ProcessPiece(), | ||
190 | GetVariableFromPkgConfig(), ParsePCFile(), | ||
191 | RegisterSystemAssemblies(), RunInitialization() | ||
192 | - pulled the above from MonoDevelop to parse the system pkgconfig | ||
193 | files and determine /pkg: arguments. Original sources are here: | ||
194 | http://svn.myrealbox.com/source/trunk/monodevelop/Core/src/MonoDevelop.Core/MonoDevelop.Core/SystemAssemblyService.cs | ||
195 | http://svn.myrealbox.com/source/trunk/monodevelop/Core/src/MonoDevelop.Core/MonoDevelop.Core/ClrVersion.cs | ||
196 | ! WriteProject() | ||
197 | - now gathering project version from AssemblyInfo.cs if it is part | ||
198 | of the project | ||
199 | - changed the declaration of the ArrayList's in the method | ||
200 | - now copying assembly .config files to the project, distributing, | ||
201 | installing | ||
202 | - making sure all needed files live under the Project directory | ||
203 | - copying strongname keys to project directory | ||
204 | - parsing AssemblyInfo.cs to determine assembly version | ||
205 | - removing all references to ".." | ||
206 | - removed superfluous if(project.References.Count > 0) around | ||
207 | for(int refNum = 0; refNum < project.References.Count; refNum++) | ||
208 | - removed use of runtimeLibs | ||
209 | - adding hook to copy sibling project's generated assemblies to | ||
210 | this project during Make time | ||
211 | - added extra dist target to ensure all files required to build | ||
212 | get distributed during "make dist" | ||
213 | - added new xslt processing args: | ||
214 | -- assemblyName | ||
215 | -- extraDistFiles | ||
216 | -- pkgLibs (/pkg:foo) | ||
217 | -- localCopyTargets (to copy sibling assemblies at Make time) | ||
218 | -- projectVersion (if determined from AssemblyInfo.cs) | ||
219 | -- hasAssemblyConfig (if there's a assembly.exe.config present) | ||
220 | ! Write() | ||
221 | - calling RunInitialization() to gather pkg-config data | ||
222 | * src/data/autotools.xml | ||
223 | - accepting new args passed from AutotoolsTarget.cs | ||
224 | - modernized configure.ac a bit | ||
225 | - using a version of tar that allows >99-char filenames | ||
226 | - added ASSEMBLY_NAME variable | ||
227 | - using assembly name rather than project name for gac installation | ||
228 | - generated assembly is now assembly name and not project name | ||
229 | - accepting /pkg: flags gathered from AutotoolsTarget.cs | ||
230 | - adding Makefile targets to copy sibling project assemblies to . | ||
231 | - fixed Debug, Release targets | ||
232 | - adding support for strongname key signing | ||
233 | - adding /unsafe support | ||
234 | - adding a clean make target | ||
235 | - only running gacutil /u if the assembly being uninstalled is in gac | ||
236 | - added some templates to determine each Configuration's .snk | ||
237 | - added explanation as to why .exe assemblies live in $prefix/lib | ||
238 | * src/Properties/AssemblyInfo.cs | ||
239 | - bumped assembly version | ||
240 | * prebuild.xml | ||
241 | - bumped assembly version | ||
242 | |||
243 | 2007-03-29T18:03 C.J. Adams-Collier <cjac@colliertech.org> | ||
244 | * src/Core/Targets/AutotoolsTarget.cs | ||
245 | ! WriteProject() | ||
246 | - re-named incorrectly-named variable gacLibs to systemLibs | ||
247 | - added another reference list, runtimeLibs which contains the | ||
248 | libs we will need at runtime. we use this to build a MONO_PATH | ||
249 | - added monoPath to the xslt args list | ||
250 | * src/data/autotools.xml | ||
251 | ! <ProjectMakefileAm /> | ||
252 | - renamed gacLibs to systemLibs | ||
253 | - added the sources to the dist list | ||
254 | - added logic to install libs that aren't strongnamed | ||
255 | ! <ProjectWrapperScriptIn /> | ||
256 | - accepting a param to update the MONO_PATH | ||
257 | |||
258 | 2007-03-28T19:46 C.J. Adams-Collier <cjac@colliertech.org> | ||
259 | * src/Core/Targets/MonoDevelopTarget.cs | ||
260 | ! CleanProject() | ||
261 | - using Assembly.LoadWithPartialName to locate the assembly | ||
262 | * src/Core/Targets/AutotoolsTarget.cs | ||
263 | ! WriteCombine() | ||
264 | - no longer using $PWD to determine a project's source dir; this | ||
265 | doesn't work with <Process /> elements | ||
266 | - passing the solution name to all templates - fixes | ||
267 | multi-solution prebuild systems | ||
268 | ! WriteProject() | ||
269 | - no longer using $PWD to determine a project's source dir; this | ||
270 | doesn't work with <Process /> elements | ||
271 | - passing the solution name to all templates - fixes | ||
272 | multi-solution prebuild systems | ||
273 | - copying strongname key to the autotools directory | ||
274 | - using Assembly.LoadWithPartialName to locate assemblies | ||
275 | * src/data/autotools.xml | ||
276 | ! <ProjectConfigureAc /> | ||
277 | - fixed the .pc AC_CONFIG_FILES macro | ||
278 | ! <ProjectMakefileAm /> | ||
279 | - added solution name param | ||
280 | - wrapping if type=exe check around script install macro | ||
281 | - added type=lib check and .pc file install macro | ||
282 | - added support for Configuration-specific builds (Debug, Release, etc) | ||
283 | - added strongname keyfile code | ||
284 | - TODO: support non-strongnamed library installation | ||
285 | ! <ProjectWrapperScriptIn /> | ||
286 | - added space preservation attribute to stylesheet element | ||
287 | - added a lower-case project name variable | ||
288 | - added solution name param | ||
289 | - made for-each template more specific | ||
290 | ! <SolutionAutogenSh /> | ||
291 | - added solution name param | ||
292 | ! <SolutionConfigureAc /> | ||
293 | - added solution name param | ||
294 | ! <SolutionMakefileAm /> | ||
295 | - added solution name param | ||
296 | ! <ProjectPcIn /> | ||
297 | - added solution name param | ||
298 | |||
299 | 2007-03-27T09:33 C.J. Adams-Collier <cjac@colliertech.org> | ||
300 | * src/Core/Targets/AutotoolsTarget.cs | ||
301 | - now processing the wrapper script if type is "Exe" or "WinExe" | ||
302 | * src/data/autotools.xml | ||
303 | ! <ProjectConfigureAc /> | ||
304 | - being more exact about where text escaping is used | ||
305 | - using the correct variable name for the GACUTIL_FLAGS template | ||
306 | - using correct test="" for the AC_CONFIG_FILES macros | ||
307 | ! <ProjectMakefileAm /> | ||
308 | - uncommented the bin_SCRIPTS section now that the script is being | ||
309 | generated correctly | ||
310 | ! <ProjectWrapperScriptIn /> | ||
311 | - fixed whitespace at beginning of file, before #! | ||
312 | - using lower-case packageName to indicate installation location | ||
313 | |||
314 | 2007-03-27T09:33 C.J. Adams-Collier <cjac@colliertech.org> | ||
315 | * src/data/autotools.xml | ||
316 | ! <ProjectConfigureAc /> | ||
317 | * added a lcProjectName which is $projectName lower-cased | ||
318 | * moved autoconf template specifier near AC_OUTPUT | ||
319 | * AC_OUTPUT with args is deprecated. now using AC_CONFIG_FILES | ||
320 | * placed AC_CONFIG_FILES() calls for wrapper script or pkg-config | ||
321 | file in xslt project type checks | ||
322 | ! <ProjectMakefileAm /> | ||
323 | * commented out bin_SCRIPTS | ||
324 | * added a lcProjectName which is $projectName lower-cased | ||
325 | * using $lcProjectName instead of the longer version | ||
326 | |||
327 | 2007-03-27T08:39 C.J. Adams-Collier <cjac@colliertech.org> | ||
328 | * src/data/autotools.xml | ||
329 | ! <ProjectMakefileAm /> | ||
330 | - added whitespace-preservation | ||
331 | - added the missing projectName param | ||
332 | - replaced bin_SCRIPTS with something that worked | ||
333 | |||
334 | 2007-03-27T07:56 C.J. Adams-Collier <cjac@colliertech.org> | ||
335 | * src/data/autotools.xml | ||
336 | ! <ProjectConfigureAc /> | ||
337 | - cleaned up duplicate checks | ||
338 | - placed initialization macros above system check macros | ||
339 | - added some more messages about what's going on | ||
340 | - added GACUTIL_FLAGS variable including /package option | ||
341 | ! <ProjectMakefileAm /> | ||
342 | - added an incomplete bin_SCRIPTS | ||
343 | - RCS check says "building" instead of "compiling" | ||
344 | ! <SolutionConfigureAc /> | ||
345 | - removed macros that are useful only for projects | ||
346 | ! <ProjectWrapperScriptIn /> | ||
347 | - created this element on this revision | ||
348 | - this is a wrapper shell script that lives in the $PATH and runs | ||
349 | the CIL assembly | ||
350 | |||
351 | 2007-03-26T20:18 C.J. Adams-Collier <cjac@colliertech.org> | ||
352 | * src/Core/Targets/AutotoolsTarget.cs | ||
353 | - creating new template arguments to contain the list of libs to | ||
354 | reference: source, binary & GAC | ||
355 | - source libs are included as part of this solution (untested) | ||
356 | - binary libs are distributed with the source (untested) | ||
357 | - GAC libs are assumed to be in the GAC or other lib path (tested) | ||
358 | * src/data/autotools.xml | ||
359 | - created new params through which to accept reference info | ||
360 | - created a working $(CSC) line | ||
361 | - added a TODO item for ordering project dependency for | ||
362 | AC_CONFIG_SUBDIRS code | ||
363 | |||
364 | 2007-03-26T08:41 C.J. Adams-Collier <cjac@colliertech.org> | ||
365 | * src/Core/Targets/AutotoolsTarget.cs | ||
366 | - now creating list of source files in managed code and passing | ||
367 | them to the template via <xsl:param>s | ||
368 | * src/data/prebuild-1.7.xsd | ||
369 | - updated the header comment to 2007 | ||
370 | * src/data/autotools.xml | ||
371 | ! <ProjectConfigureAc> | ||
372 | - copied checks from Solution-level configure.ac | ||
373 | - copied solution-level config status | ||
374 | ! <ProjectMakefileAm> | ||
375 | - added <xsl:param> elements for file list to be passed through | ||
376 | - made a temporary target for the assembly we're building | ||
377 | - added this target to the deps of "all:" | ||
378 | ! <SolutionConfigureAc> | ||
379 | - changed status header/footer from "- - -" to "===" | ||
380 | |||
381 | 2007-03-23T08:33 C.J. Adams-Collier <cjac@colliertech.org> | ||
382 | Added version attribute handling code for Property element | ||
383 | Added description element handling code | ||
384 | * prebuild.xml | ||
385 | - added /Prebuild/Solution/Property/@version attribute | ||
386 | - added /Prebuild/Solution/Property/Description element | ||
387 | * src/Core/Nodes/ProjectNode.cs | ||
388 | - added some docs where they were missing and obvious | ||
389 | - added code to handle @version | ||
390 | * src/Core/Nodes/DescriptionNode.cs | ||
391 | - new file. Used to handle /Prebuild/Solution/Property/Description | ||
392 | * src/Core/Targets/AutotoolsTarget.cs | ||
393 | - added mkdirDashP(), a recursive directory creation method | ||
394 | - WriteProject() now copies the files to autotools/ | ||
395 | * src/data/prebuild-1.7.xsd | ||
396 | - added /Prebuild/Solution/Property/Description element | ||
397 | - added /Prebuild/Solution/Property/@version attribute | ||
398 | * src/data/autotools.xml | ||
399 | - removed excess <xsl:value-of select="$projectName"/> | ||
400 | - explicitly using dnpb: prefix | ||
401 | |||
402 | 2007-03-23T04:31 C.J. Adams-Collier <cjac@colliertech.org> | ||
403 | Merged code from my stripped-down test | ||
404 | Adding support for the /Prebuild/Solution/Project/Author element | ||
405 | * prebuild.xml | ||
406 | - added Author elements | ||
407 | - cleaned up the really long Project element | ||
408 | * src/Core/Nodes/ProjectNode.cs | ||
409 | - added Author tag processing code | ||
410 | * src/Core/Nodes/AuthorNode.cs | ||
411 | - Created to process Author elements | ||
412 | - based off of ReferencePathNode.cs | ||
413 | * src/Core/Targets/AutotoolsTarget.cs | ||
414 | - merged code from https://svn.colliertech.org/mono/dnpbAutotools/dnpbAutotools/test.cs | ||
415 | - renamed old WriteCombine to WriteCombineOld | ||
416 | - renamed old WriteProject to WriteProjectOld | ||
417 | * src/data/prebuild-1.7.xsd | ||
418 | - added Author element to Project | ||
419 | * src/data/autotools.xml | ||
420 | - lower-cased utf | ||
421 | |||
422 | |||
423 | 2007-03-22T13:58 C.J. Adams-Collier <cjac@colliertech.org> | ||
424 | Exposing an XmlDocument that represents the prebuild.xml file | ||
425 | passed to the program | ||
426 | |||
427 | * src/Core/Kernel.cs | ||
428 | - created an object member called XmlDocument m_CurrentDoc | ||
429 | - created a property to access its value | ||
430 | - using m_CurrentDoc to load up the prebuild.xml file rather than | ||
431 | a local variable called "doc" | ||
432 | |||
433 | 2007-03-22 C.J. Adams-Collier <cjac@colliertech.org> | ||
434 | * prebuild.xml | ||
435 | - added autotools.xml created at https://svn.colliertech.org/mono/dnpbAutotools/dnpbAutotools/autotools.xml | ||
436 | * src/data/autotools.xml | ||
437 | - the same | ||
438 | * src/Core/Targets/MonoDevelopTarget.cs | ||
439 | - fixed bug introduced in r206 | ||
440 | |||
441 | 2007-03-07 C.J. Adams-Collier <cjcollier@colliertech.org> | ||
442 | * src/data/prebuild-1.7.xsd | ||
443 | - added version attribute to Solution and Project elements | ||
444 | |||
445 | 2006-11-04T00:38 C.J. Adams-Collier <cjcollier@colliertech.org> | ||
446 | * placing AssemblyInfo.cs into Properties/ | ||
447 | * Fixed double-mention of the package name | ||
448 | |||
449 | 2006-11-03T15:23 C.J. Adams-Collier <cjcollier@colliertech.org> | ||
450 | * corrected a problem in the Include.am generation code | ||
451 | * created the new .exe | ||
452 | * copied it to the root of the build | ||
453 | |||
454 | 2006-11-03T14:57 C.J. Adams-Collier <cjcollier@colliertech.org> | ||
455 | * Updated the .exe file | ||
456 | |||
457 | 2006-11-03 C.J. Adams-Collier <cjcollier@colliertech.org> | ||
458 | * Added a TODO file | ||
459 | * Added a ChangeLog file | ||
460 | * applied some fixes for autotools gac and pkg-config installation | ||
461 | problems | ||
diff --git a/Prebuild/INSTALL b/Prebuild/INSTALL deleted file mode 100644 index 23e5f25..0000000 --- a/Prebuild/INSTALL +++ /dev/null | |||
@@ -1,236 +0,0 @@ | |||
1 | Installation Instructions | ||
2 | ************************* | ||
3 | |||
4 | Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005 Free | ||
5 | Software Foundation, Inc. | ||
6 | |||
7 | This file is free documentation; the Free Software Foundation gives | ||
8 | unlimited permission to copy, distribute and modify it. | ||
9 | |||
10 | Basic Installation | ||
11 | ================== | ||
12 | |||
13 | These are generic installation instructions. | ||
14 | |||
15 | The `configure' shell script attempts to guess correct values for | ||
16 | various system-dependent variables used during compilation. It uses | ||
17 | those values to create a `Makefile' in each directory of the package. | ||
18 | It may also create one or more `.h' files containing system-dependent | ||
19 | definitions. Finally, it creates a shell script `config.status' that | ||
20 | you can run in the future to recreate the current configuration, and a | ||
21 | file `config.log' containing compiler output (useful mainly for | ||
22 | debugging `configure'). | ||
23 | |||
24 | It can also use an optional file (typically called `config.cache' | ||
25 | and enabled with `--cache-file=config.cache' or simply `-C') that saves | ||
26 | the results of its tests to speed up reconfiguring. (Caching is | ||
27 | disabled by default to prevent problems with accidental use of stale | ||
28 | cache files.) | ||
29 | |||
30 | If you need to do unusual things to compile the package, please try | ||
31 | to figure out how `configure' could check whether to do them, and mail | ||
32 | diffs or instructions to the address given in the `README' so they can | ||
33 | be considered for the next release. If you are using the cache, and at | ||
34 | some point `config.cache' contains results you don't want to keep, you | ||
35 | may remove or edit it. | ||
36 | |||
37 | The file `configure.ac' (or `configure.in') is used to create | ||
38 | `configure' by a program called `autoconf'. You only need | ||
39 | `configure.ac' if you want to change it or regenerate `configure' using | ||
40 | a newer version of `autoconf'. | ||
41 | |||
42 | The simplest way to compile this package is: | ||
43 | |||
44 | 1. `cd' to the directory containing the package's source code and type | ||
45 | `./configure' to configure the package for your system. If you're | ||
46 | using `csh' on an old version of System V, you might need to type | ||
47 | `sh ./configure' instead to prevent `csh' from trying to execute | ||
48 | `configure' itself. | ||
49 | |||
50 | Running `configure' takes awhile. While running, it prints some | ||
51 | messages telling which features it is checking for. | ||
52 | |||
53 | 2. Type `make' to compile the package. | ||
54 | |||
55 | 3. Optionally, type `make check' to run any self-tests that come with | ||
56 | the package. | ||
57 | |||
58 | 4. Type `make install' to install the programs and any data files and | ||
59 | documentation. | ||
60 | |||
61 | 5. You can remove the program binaries and object files from the | ||
62 | source code directory by typing `make clean'. To also remove the | ||
63 | files that `configure' created (so you can compile the package for | ||
64 | a different kind of computer), type `make distclean'. There is | ||
65 | also a `make maintainer-clean' target, but that is intended mainly | ||
66 | for the package's developers. If you use it, you may have to get | ||
67 | all sorts of other programs in order to regenerate files that came | ||
68 | with the distribution. | ||
69 | |||
70 | Compilers and Options | ||
71 | ===================== | ||
72 | |||
73 | Some systems require unusual options for compilation or linking that the | ||
74 | `configure' script does not know about. Run `./configure --help' for | ||
75 | details on some of the pertinent environment variables. | ||
76 | |||
77 | You can give `configure' initial values for configuration parameters | ||
78 | by setting variables in the command line or in the environment. Here | ||
79 | is an example: | ||
80 | |||
81 | ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix | ||
82 | |||
83 | *Note Defining Variables::, for more details. | ||
84 | |||
85 | Compiling For Multiple Architectures | ||
86 | ==================================== | ||
87 | |||
88 | You can compile the package for more than one kind of computer at the | ||
89 | same time, by placing the object files for each architecture in their | ||
90 | own directory. To do this, you must use a version of `make' that | ||
91 | supports the `VPATH' variable, such as GNU `make'. `cd' to the | ||
92 | directory where you want the object files and executables to go and run | ||
93 | the `configure' script. `configure' automatically checks for the | ||
94 | source code in the directory that `configure' is in and in `..'. | ||
95 | |||
96 | If you have to use a `make' that does not support the `VPATH' | ||
97 | variable, you have to compile the package for one architecture at a | ||
98 | time in the source code directory. After you have installed the | ||
99 | package for one architecture, use `make distclean' before reconfiguring | ||
100 | for another architecture. | ||
101 | |||
102 | Installation Names | ||
103 | ================== | ||
104 | |||
105 | By default, `make install' installs the package's commands under | ||
106 | `/usr/local/bin', include files under `/usr/local/include', etc. You | ||
107 | can specify an installation prefix other than `/usr/local' by giving | ||
108 | `configure' the option `--prefix=PREFIX'. | ||
109 | |||
110 | You can specify separate installation prefixes for | ||
111 | architecture-specific files and architecture-independent files. If you | ||
112 | pass the option `--exec-prefix=PREFIX' to `configure', the package uses | ||
113 | PREFIX as the prefix for installing programs and libraries. | ||
114 | Documentation and other data files still use the regular prefix. | ||
115 | |||
116 | In addition, if you use an unusual directory layout you can give | ||
117 | options like `--bindir=DIR' to specify different values for particular | ||
118 | kinds of files. Run `configure --help' for a list of the directories | ||
119 | you can set and what kinds of files go in them. | ||
120 | |||
121 | If the package supports it, you can cause programs to be installed | ||
122 | with an extra prefix or suffix on their names by giving `configure' the | ||
123 | option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. | ||
124 | |||
125 | Optional Features | ||
126 | ================= | ||
127 | |||
128 | Some packages pay attention to `--enable-FEATURE' options to | ||
129 | `configure', where FEATURE indicates an optional part of the package. | ||
130 | They may also pay attention to `--with-PACKAGE' options, where PACKAGE | ||
131 | is something like `gnu-as' or `x' (for the X Window System). The | ||
132 | `README' should mention any `--enable-' and `--with-' options that the | ||
133 | package recognizes. | ||
134 | |||
135 | For packages that use the X Window System, `configure' can usually | ||
136 | find the X include and library files automatically, but if it doesn't, | ||
137 | you can use the `configure' options `--x-includes=DIR' and | ||
138 | `--x-libraries=DIR' to specify their locations. | ||
139 | |||
140 | Specifying the System Type | ||
141 | ========================== | ||
142 | |||
143 | There may be some features `configure' cannot figure out automatically, | ||
144 | but needs to determine by the type of machine the package will run on. | ||
145 | Usually, assuming the package is built to be run on the _same_ | ||
146 | architectures, `configure' can figure that out, but if it prints a | ||
147 | message saying it cannot guess the machine type, give it the | ||
148 | `--build=TYPE' option. TYPE can either be a short name for the system | ||
149 | type, such as `sun4', or a canonical name which has the form: | ||
150 | |||
151 | CPU-COMPANY-SYSTEM | ||
152 | |||
153 | where SYSTEM can have one of these forms: | ||
154 | |||
155 | OS KERNEL-OS | ||
156 | |||
157 | See the file `config.sub' for the possible values of each field. If | ||
158 | `config.sub' isn't included in this package, then this package doesn't | ||
159 | need to know the machine type. | ||
160 | |||
161 | If you are _building_ compiler tools for cross-compiling, you should | ||
162 | use the option `--target=TYPE' to select the type of system they will | ||
163 | produce code for. | ||
164 | |||
165 | If you want to _use_ a cross compiler, that generates code for a | ||
166 | platform different from the build platform, you should specify the | ||
167 | "host" platform (i.e., that on which the generated programs will | ||
168 | eventually be run) with `--host=TYPE'. | ||
169 | |||
170 | Sharing Defaults | ||
171 | ================ | ||
172 | |||
173 | If you want to set default values for `configure' scripts to share, you | ||
174 | can create a site shell script called `config.site' that gives default | ||
175 | values for variables like `CC', `cache_file', and `prefix'. | ||
176 | `configure' looks for `PREFIX/share/config.site' if it exists, then | ||
177 | `PREFIX/etc/config.site' if it exists. Or, you can set the | ||
178 | `CONFIG_SITE' environment variable to the location of the site script. | ||
179 | A warning: not all `configure' scripts look for a site script. | ||
180 | |||
181 | Defining Variables | ||
182 | ================== | ||
183 | |||
184 | Variables not defined in a site shell script can be set in the | ||
185 | environment passed to `configure'. However, some packages may run | ||
186 | configure again during the build, and the customized values of these | ||
187 | variables may be lost. In order to avoid this problem, you should set | ||
188 | them in the `configure' command line, using `VAR=value'. For example: | ||
189 | |||
190 | ./configure CC=/usr/local2/bin/gcc | ||
191 | |||
192 | causes the specified `gcc' to be used as the C compiler (unless it is | ||
193 | overridden in the site shell script). Here is a another example: | ||
194 | |||
195 | /bin/bash ./configure CONFIG_SHELL=/bin/bash | ||
196 | |||
197 | Here the `CONFIG_SHELL=/bin/bash' operand causes subsequent | ||
198 | configuration-related scripts to be executed by `/bin/bash'. | ||
199 | |||
200 | `configure' Invocation | ||
201 | ====================== | ||
202 | |||
203 | `configure' recognizes the following options to control how it operates. | ||
204 | |||
205 | `--help' | ||
206 | `-h' | ||
207 | Print a summary of the options to `configure', and exit. | ||
208 | |||
209 | `--version' | ||
210 | `-V' | ||
211 | Print the version of Autoconf used to generate the `configure' | ||
212 | script, and exit. | ||
213 | |||
214 | `--cache-file=FILE' | ||
215 | Enable the cache: use and save the results of the tests in FILE, | ||
216 | traditionally `config.cache'. FILE defaults to `/dev/null' to | ||
217 | disable caching. | ||
218 | |||
219 | `--config-cache' | ||
220 | `-C' | ||
221 | Alias for `--cache-file=config.cache'. | ||
222 | |||
223 | `--quiet' | ||
224 | `--silent' | ||
225 | `-q' | ||
226 | Do not print messages saying which checks are being made. To | ||
227 | suppress all normal output, redirect it to `/dev/null' (any error | ||
228 | messages will still be shown). | ||
229 | |||
230 | `--srcdir=DIR' | ||
231 | Look for the package's source code in directory DIR. Usually | ||
232 | `configure' can determine that directory automatically. | ||
233 | |||
234 | `configure' also accepts some other, not widely useful, options. Run | ||
235 | `configure --help' for more details. | ||
236 | |||
diff --git a/Prebuild/NEWS b/Prebuild/NEWS deleted file mode 100644 index 3ab3108..0000000 --- a/Prebuild/NEWS +++ /dev/null | |||
@@ -1,200 +0,0 @@ | |||
1 | Prebuild is an XML-driven pre-build tool allowing developers to easily generate project or make files for major IDE's and .NET development tools including: Visual Studio 2005, Visual Studio 2003, Visual Studio 2002, SharpDevelop, MonoDevelop, and NAnt. | ||
2 | |||
3 | Documentation and downloads are available at http://dnpb.sourceforge.net. | ||
4 | |||
5 | Prebuild is licensed under the BSD license. | ||
6 | |||
7 | [ XXXXXXX XX, XXX - 1.3.2 ] | ||
8 | + Added Keyfile signing to NAnt target and VS2005 target | ||
9 | + Updated XSD file to 1.7 | ||
10 | + Boo and VisualBasic Language support in VS2005 target | ||
11 | + Added basic Autotools target. It creates a non-recursive Autotools system. | ||
12 | ! Multiple files can be excluded from the Match node | ||
13 | ! VS2005 now handles .resx files correctly. | ||
14 | ! NAnt and Autotools now handle defines | ||
15 | ! NAnt and Autotools now handle resources | ||
16 | + Conditional XML variables can be passed through the command line. | ||
17 | + Added /install and /remove command line flags to install and remove assemblies from the GAC | ||
18 | + Many fixes to VS2005 target | ||
19 | |||
20 | [ July 21, 2006 - 1.3.1 ] | ||
21 | ! VS2005 fixes from Rob Loach | ||
22 | ! NAnt fixes from Rob Loach and David Hudson | ||
23 | ! XML doc fixes from Rob Loach | ||
24 | + Added SharpDevelop2 target (really just uses VS2005 target) | ||
25 | ! Fixed bug with BuildEvents in Monodevelop target | ||
26 | + Passing /yes will default to answering yes to any warnings | ||
27 | |||
28 | [ February 28, 2006 - 1.3 ] | ||
29 | + Added MonoDevelop target. | ||
30 | + Added NAnt target. | ||
31 | + Lots of fixes to all targets. | ||
32 | * Cleaned up the code using FXCop. | ||
33 | * Updated schema to 1.6 to fix a typo and add a new parameter. | ||
34 | * jendave is now the maintainer of the project. RobLoach has been added as a developer. | ||
35 | * Removed references to 'dnpb'. | ||
36 | + Added rudimentary support for pre- and post- build scripts | ||
37 | * Updated examples. | ||
38 | |||
39 | [ August 5, 2004 - 1.2 ] | ||
40 | + Added Visual Studio Express (vs2005express) target contributed by Borrillis and modified for use with different languages | ||
41 | + Added the allowedgroups command line option followed by a pipe-delimited list of project group filter flags (eg. Group1|Group2) allow optional filtering of all projects that dont have at least one of these flags | ||
42 | + Added the filterGroups XML attribute to the project node and updated the scheme to v1.5 for this addition, it is used to specified the delimited list of filter groups to which a project belongs | ||
43 | * Modified the removedir command line option to allow for a pipe-delimited list of directory names | ||
44 | ! Modified the resource loading code to search for resourced without the prepended namespace (as Visual Studio .NET does it) to allow for it to be compiled with SharpDevelop as well | ||
45 | + Added the GenerateXmlDocFile boolean option to the Options XML element | ||
46 | * Changed the behavior of the XmlDocFile option so that if not specified it uses the assemblyName (without file extension) + .xml for the file name instead of just not generating the file since the new GenerateXmlDocFile takes care of this | ||
47 | |||
48 | [ January 3, 2004 - 1.1 ] | ||
49 | ! Replaced regex use for more efficient manual parsing to allow use on non-windows platforms with Mono which has Regex problems | ||
50 | + Added the checkOsVars attribute to the root element for enabling interpolation for Enviroment variables in the form ${var}, otherwise no checking is performed for efficiency-sake | ||
51 | * Make the version attribute on the root element optional as it isn't used and not needed since the schema url contains the version | ||
52 | |||
53 | [ December 30, 2004 - 1.1 ] | ||
54 | ! Applied Leed's fix for SharpDevelop references | ||
55 | + Rewrote much of the processing for better validation and without the use of a temp file | ||
56 | + Added support for configurations at the project level which are named All. They now apply changes to all Solution level defined configs | ||
57 | * Changed all spaces into tabs | ||
58 | + Added support for the None build action | ||
59 | * Replaced all sequence's in the XML schema for all's because the order doesn't matter since the xml file is loaded into an XmlDocument | ||
60 | |||
61 | [ December 25, 2004 - 1.0 ] | ||
62 | + Added the /removedir option for cleaning directories like obj before file releases | ||
63 | + Changed WriteTempXml() and the new DeleteTempXml() methods to be compiled only in DEBUG builds | ||
64 | * Made path optional for Match elements (defaults to current directory) and updates schema for it | ||
65 | ! Fixed XML example in the readme.txt | ||
66 | + Added example xml files to docs directory | ||
67 | * Updated license.txt to add Dan Moorehead and update copyright years | ||
68 | + Updated prebuild.xml to take advantage of the default path attribute for match elements | ||
69 | + Updated Clean to delete the obj directories | ||
70 | |||
71 | [ December 25, 2004 - 0.13 ] | ||
72 | + Added dnpb.exe so that it can be used to generate the project files | ||
73 | + Added dnpb.ico | ||
74 | * Added parameterless Write statement to Log for writing a single line | ||
75 | * Changed scehema to version 1.3 for support of icon attribute | ||
76 | * Added support for All configuration name under a Project node signifying common settings for all configurations | ||
77 | ! Fixed the SupressWarnings by adding the corresponding field to OptionsNode | ||
78 | * Wrote documentation in docs/readme.txt | ||
79 | * Added Dan Moorehead to copyrights and extended date from 2004 to 2004-2005 | ||
80 | * Updated prebuild.xml | ||
81 | * Optimized Log class | ||
82 | * Updated OutputUsage() | ||
83 | * /clean targets all by default | ||
84 | * No log file is used by default, /log without value specified uses default file name | ||
85 | + Added support for the /pause which pauses the utility after execution to observe output | ||
86 | |||
87 | |||
88 | [ September 27, 2004 - 0.12.2a ] | ||
89 | ! Fixed a nasty bug when trying to delete our temp file for pre-processing. | ||
90 | |||
91 | [ September 15, 2004 - 0.12.2 ] | ||
92 | + Expanded platform identification, thanks to the NAnt guys for shedding some | ||
93 | light on how to properly check for UNIX platforms! Thanks guys! | ||
94 | * POSIX OS identifier changed to UNIX. Valid OS names are now "Win32", "UNIX", | ||
95 | and "Unknown". | ||
96 | ! Fixed SharpDevelop target to properly use the 'rootNamespace' attribute of | ||
97 | the Project tag. | ||
98 | + New command-line switch, /ppo, forces DNPB to pre-process the file and write | ||
99 | the pre-processed file. This allows you to test/debug your pre-processor | ||
100 | macros. No other processing will be done. You can specify a target file as | ||
101 | a paramter for the /ppo switch, or DNPB will write the file 'preprocessed.xml' | ||
102 | if you do not specify a file. | ||
103 | + The Match tag now has a 'buildAction' attribute which functions exactly like | ||
104 | the attribute of the same name for the File tag. | ||
105 | |||
106 | [ August 5, 2004 - 0.12.1 ] | ||
107 | + Added environment variable expansion for all values. Environment variables | ||
108 | should be listed in the form ${VAR}. | ||
109 | |||
110 | [ July 30, 2004 - 0.12.0 ] | ||
111 | + Added preprocessing via XML processing information tags. Available tags | ||
112 | are: <?if <exp> ?>, <?elseif <exp> ?>, <?else ?> and <?endif ?>. The | ||
113 | current expression parser is very basic, but will be replaced with a more | ||
114 | capable parser over time. Current operators available are: =, !=, <, >, | ||
115 | <=, >=. Current test variables available: OS, RuntimeVersion, RuntimeMajor, | ||
116 | RuntimeMinor, RuntimeRevision. | ||
117 | |||
118 | [ July 27, 2004 - 0.11.4 ] | ||
119 | + Added 'useRegex' attribute to the Match tag. Matches can now use regular | ||
120 | expressions to match filenames. | ||
121 | + Added the 'assemblyName' attribute to the Project tag. Projects can now | ||
122 | set their output assembly name. | ||
123 | ! Fixed several bugs in the way that Project tags inheirt their parent | ||
124 | Solutions configuration options. This operation should now work fully as | ||
125 | intended. | ||
126 | ! Due to some wierdness, Project Guid's are now stored as part of the Project | ||
127 | node and created at parse time. | ||
128 | |||
129 | [ May 11, 2004 - 0.11.3 ] | ||
130 | ! Fixed a bug where I was writing the wrong property name for a projects root | ||
131 | namespace. | ||
132 | ! Removed a DEBUG statement I had left in the code in 0.11.2. | ||
133 | ! Fixed a bug in the VS2002 writer which caused the version variables to not | ||
134 | be overriden correctly. | ||
135 | + Added the rootNamespace property to the <Project> element, allowing you to | ||
136 | specify the root namespace. | ||
137 | * /target and /clean are now mutually exclusive command line switches, and | ||
138 | they both now take the all option. In the case of /target all, all build | ||
139 | file for all targets will be created. In the case of /clean all, the user | ||
140 | will be prompted to make sure they want to do it, and if so, will clean | ||
141 | all build files for all targets. | ||
142 | |||
143 | [ April 22, 2004 - 0.11.2 ] | ||
144 | ! Fixed a bug with the /file command-line operator. Was using the unresolved | ||
145 | file path rather then the resolved one, was making the attempt to open the | ||
146 | dnpb file fail. | ||
147 | ! Fixed a bug in the schema that required at least 1 solution and 1 reference | ||
148 | path. We can do just fine with 0 of either of these. Some files may be all | ||
149 | <Process> statements and not have any <Solution> tags. | ||
150 | ! Fixed a bug that caused the project references not to be written with the | ||
151 | SharpDevelop target. | ||
152 | * Changed the schema to version 1.2, allowing for Configuration nodes to exist | ||
153 | under project nodes. The inheritance of values is hierarchical. Meaning, if | ||
154 | you define a configuration named Debug at the Soltion level, and one by the | ||
155 | same name at the Project level, the one at the Project level will first | ||
156 | inherit the options of the Solution level configuration, then set it's own | ||
157 | options. If you define a configuration at the Project level and it does not | ||
158 | exist at the Solution level, it will be created at the Solution level. | ||
159 | * Project references should now work correctly across the board. Note that due | ||
160 | to a restriction in Visual Studio, you can only reference projects in the same | ||
161 | solution. | ||
162 | |||
163 | [ April 21, 2004 - 0.11.1 ] | ||
164 | ! Fixed a problem with resolving paths in various targets. Was not properly | ||
165 | setting the CWD. | ||
166 | * Schema updated to 1.1, moving the ReferencePath element from the Options | ||
167 | element to the Project element. This makes more logical sense, given that | ||
168 | reference paths are resolved relative to the project path. Any prebuild.xml | ||
169 | file referecning verison 1.0 will fail! Please update to the 1.1 schema. | ||
170 | |||
171 | [ April 19, 2004 - 0.11.0 ] | ||
172 | * Added several attributes across the code to make FxCop happy | ||
173 | ! Fixed bugs in reference paths being written in the VS targets. | ||
174 | ! Fixed a bug in ProjectNode which was doing two CWDStack.Push() calls instead of | ||
175 | a Push/Pop pair. Was wreaking havoc with <Process> tags. | ||
176 | ! Fixed some bugs in the path tracking, both the Project and Solution nodes now | ||
177 | have a FullPath property, which is the full path to the file resolved at load | ||
178 | time. This should fix all path relativity problems. | ||
179 | + Added new /clean switch, allowing the target to clean up any files it generated. | ||
180 | in accordance, the ITarget interface has been updated to support a new Clean() | ||
181 | method. | ||
182 | + Completed addition of the <Process> tag, to allow the referencing of external | ||
183 | prebuild.xml files. | ||
184 | + Added the runtime attribute to the Project element. This allows the developer | ||
185 | to specify which runtime a project should target (Mono or Microsoft). This is | ||
186 | of course ignored in certain targets like the Visual Studio targets. | ||
187 | + Added the SharpDevelop target. | ||
188 | |||
189 | [ April 13, 2004 - 0.10.1a ] | ||
190 | + Added the buildAction attribute to the File node. This is needed for dnpb | ||
191 | to even be able to bootstrap itself (dnpb-1.0.xsd must be an embedded resource) | ||
192 | |||
193 | [ April 13, 2004 - 0.10.1 ] | ||
194 | * First Release | ||
195 | |||
196 | [ Key ] | ||
197 | * = Change or information | ||
198 | + = Addition | ||
199 | ! = Bug Fix | ||
200 | |||
diff --git a/Prebuild/README b/Prebuild/README deleted file mode 100644 index e8a2d69..0000000 --- a/Prebuild/README +++ /dev/null | |||
@@ -1,274 +0,0 @@ | |||
1 | Prebuild Instructions | ||
2 | |||
3 | Prebuild is an XML-driven pre-build tool allowing developers to easily generate project or make files for major IDE's and .NET development tools including: Visual Studio 2005, Visual Studio 2003, Visual Studio 2002, SharpDevelop, SharpDevelop2, MonoDevelop, and NAnt. | ||
4 | |||
5 | _______________________________________________________________________________ | ||
6 | Overview | ||
7 | |||
8 | Prebuild can be either be run from the command line to generate the | ||
9 | project and make files or you can execute the included batch (*.bat) | ||
10 | and Unix Shell script (*.sh) files. | ||
11 | |||
12 | _______________________________________________________________________________ | ||
13 | The currently supported developement tools and their associated batch | ||
14 | and shell script files. | ||
15 | |||
16 | Visual Studio .NET 2005 (VS2005.bat) | ||
17 | Visual Studio .NET 2003 (VS2003.bat) | ||
18 | Visual Studio .NET 2002 (VS2002.bat) | ||
19 | SharpDevelop (SharpDevelop.bat) - http://www.icsharpcode.net/OpenSource/SD/ | ||
20 | SharpDevelop2 (SharpDevelop.bat) - http://www.icsharpcode.net/OpenSource/SD/ | ||
21 | MonoDevelop (MonoDevelop.sh) - http://www.monodevelop.com/ | ||
22 | NAnt (nant.sh and nant.bat) - http://nant.sourceforge.net/ | ||
23 | Autotools (autotools.bat and autotools.sh) - http://en.wikipedia.org/wiki/GNU_build_system | ||
24 | |||
25 | Notes: | ||
26 | |||
27 | A Unix Shell script is provided for MonoDevelop, as it does not run on | ||
28 | Windows at this time. | ||
29 | |||
30 | Visual Studio .NET 2005 and the Visual Express IDE's can import | ||
31 | solutions from older versions of Visual Studio .NET. | ||
32 | |||
33 | Makefiles are not currently supported. | ||
34 | |||
35 | _______________________________________________________________________________ | ||
36 | Command Line Syntax: | ||
37 | |||
38 | Example: | ||
39 | > Prebuild /target vs2003 | ||
40 | |||
41 | This will generate the project files for Visual Studio.NET 2003 and | ||
42 | place the redirect the log to a file named PrebuildLog.txt in the | ||
43 | parent directory | ||
44 | |||
45 | |||
46 | The syntax structure is as below, where commandParameter is optional | ||
47 | depending on the command and you can provide several option-value | ||
48 | pairs. | ||
49 | |||
50 | Note: The '> ' signifies the command prompt, do not enter this literally | ||
51 | |||
52 | > Prebuild /<option> <commandParameter> | ||
53 | |||
54 | > Prebuild /target vs2003 /pause | ||
55 | |||
56 | > Prebuild /target vs2003 /log ../Log.txt /pause /ppo /file ProjectConfig.xml | ||
57 | |||
58 | > Prebuild /target sharpdev /log | ||
59 | |||
60 | > Prebuild /removedir obj|bin | ||
61 | |||
62 | > Prebuild /target vs2003 /allowedgroups Group1|Group2 | ||
63 | |||
64 | > Prebuild /clean | ||
65 | |||
66 | > Prebuild /clean /yes | ||
67 | |||
68 | > Prebuild /clean vs2003 | ||
69 | |||
70 | _______________________________________________________________________________ | ||
71 | Command Line Options: | ||
72 | |||
73 | /usage - Shows the help information on how to use Prebuild and what | ||
74 | the different options are and what they do | ||
75 | |||
76 | /clean - The project files generated for the target type specified as | ||
77 | a parameter for this option will be deleted. If no value is specified | ||
78 | or if 'all' is specified, then project files for all the target types | ||
79 | will be deleted. | ||
80 | |||
81 | /target - Specified the name of the development tool for which project | ||
82 | or make files will be generated. Possible parameter values include: | ||
83 | vs2003, vs2002, sharpdev | ||
84 | |||
85 | /file - Specifies the name of the XML which defines what files are to | ||
86 | be referenced by the generated project files as well as configures the | ||
87 | options for them. If not specified, prebuild.xml in the current | ||
88 | directory will be used as the default. | ||
89 | |||
90 | /log - Specified the log file that should be written to for build | ||
91 | errors. If this option is not specified, no log file is generated, | ||
92 | but if just no value is specified, then the defaul filename will be | ||
93 | used for the log (Prebuild.log). | ||
94 | |||
95 | /ppo - Preprocesses the xml file to test for syntax errors or problems | ||
96 | but doesn't generate the files | ||
97 | |||
98 | /pause - Shows the console until you press a key so that you can view | ||
99 | the messages written while performing the specified actions. | ||
100 | |||
101 | This allows you to check if an errors occurred and - if so - what it | ||
102 | was. | ||
103 | |||
104 | /showtargets - Shows a list of all the targets that can be specified | ||
105 | as values for the /clean and /target commands. | ||
106 | |||
107 | /allowedgroups - This is followed by a pipe-delimited list of project | ||
108 | group filter flags (eg. Group1|Group2) allow optional filtering of all | ||
109 | projects that dont have at least one of these flags | ||
110 | |||
111 | /removedir - This is followed by a pipe-delimited list of directory | ||
112 | names that will be deleted while recursivly searching the directory of | ||
113 | the prebuild application and its child directories (eg. use obj|bin to | ||
114 | delete all output and temporary directories before file releases) | ||
115 | |||
116 | /yes - Answer yes to any warnings (e.g. when cleaning all projects). | ||
117 | |||
118 | _______________________________________________________________________________ | ||
119 | Example Batch Files and Shell Scripts | ||
120 | |||
121 | NOTE: Common batch and shell script files are included with Prebuild source and file releases. | ||
122 | ______________________________ | ||
123 | MonoDevelop | ||
124 | |||
125 | #!/bin/sh | ||
126 | # Generates a solution (.mds) and a set of project files (.mdp) | ||
127 | |||
128 | # for MonoDevelop, a Mono port of SharpDevelop | ||
129 | # (http://icsharpcode.net/OpenSource/SD/Default.aspx) | ||
130 | |||
131 | ./Prebuild /target monodev /pause | ||
132 | |||
133 | ______________________________ | ||
134 | Visual Studio .NET 2003 | ||
135 | |||
136 | @rem Generates a solution (.sln) and a set of project files (.csproj) | ||
137 | @rem for Microsoft Visual Studio .NET 2002 | ||
138 | Prebuild /target vs2003 /pause | ||
139 | |||
140 | Notes: | ||
141 | Text after lines that start with @rem are comments and are not evaluated | ||
142 | You can also place pause on the last line instead of specifing the /pause command. | ||
143 | |||
144 | _______________________________________________________________________________ | ||
145 | Example XML Configuration File | ||
146 | |||
147 | Note: | ||
148 | |||
149 | XML Comments (<!-- Comment -->) are used to markup the prebuild.xml | ||
150 | file with notes | ||
151 | |||
152 | The below file may be out-of-date, however the RealmForge Prebuild | ||
153 | file serves as an up-to-date and extensive example. | ||
154 | |||
155 | It can be viewed using Tigris.org's WebSVN | ||
156 | (http://realmforge.tigris.org/source/browse/realmforge/trunk/src/prebuild.xml) | ||
157 | by just clicking on the "view file" link for the latest revision. | ||
158 | |||
159 | _________________________________ | ||
160 | |||
161 | <?xml version="1.0" encoding="utf-8"?> | ||
162 | <!--The version of the XML schema specified in the version and xmlns attributes should match the one for which the version of Prebuild.exe used was compiled for. In this example it is the version 1.3 schema, you can find the XSD schema file at the url specified in the xmlns attribute. --> | ||
163 | <Prebuild version="1.6" xmlns="http://dnpb.sourceforge.net/schemas/prebuild-1.6.xsd"> | ||
164 | <Solution name="RealmForge"> <!--The title and file name for the solution, combine, workspace, or project group (depending on what development tool you are using)--> | ||
165 | <!--Configurations found as children of Solution are used as templates for the configurations found in the project, this allows you to avoid writing the same options in each project (and maintaining each of these). You can provide defaults and then override them in the configurations defined for each project. All options are optional.--> | ||
166 | <Configuration name="Debug"> | ||
167 | <Options> | ||
168 | <!-- simple logically expressions can be evaluated, if, else, elseif, and endif are valid statements. Note that it is not neccisary to define POSIX or WIN32 --> | ||
169 | <?if OS = "Win32" ?> | ||
170 | <CompilerDefines>DEBUG;TRACE;WIN32</CompilerDefines> | ||
171 | <?else ?> | ||
172 | <CompilerDefines>DEBUG;TRACE;POSIX</CompilerDefines> | ||
173 | <?endif ?> | ||
174 | <OptimizeCode>false</OptimizeCode> | ||
175 | <CheckUnderflowOverflow>false</CheckUnderflowOverflow> | ||
176 | <AllowUnsafe>false</AllowUnsafe> | ||
177 | <WarningLevel>4</WarningLevel> | ||
178 | <!-The filter for the number of warnings or errors shown and the tolerance level as to what is an error. This is value from 0 to 4 where 4 is the most strict (least tolerent).--> | ||
179 | |||
180 | <WarningsAsErrors>false</WarningsAsErrors> | ||
181 | <SuppressWarnings>1591;219;1573;1572;168</SuppressWarnings> | ||
182 | <!-- A semicolon ';' delimited list of the warnings that are filtered and not shown in the output window during compiling a project. Only include the number portion of the warning codes that are shown in output during compilation (eg CS1591, should be entered as 1591)--> | ||
183 | |||
184 | <OutputPath>..\bin</OutputPath> | ||
185 | <DebugInformation>true</DebugInformation> | ||
186 | <RegisterComInterop>false</RegisterComInterop> | ||
187 | <IncrementalBuild>true</IncrementalBuild> | ||
188 | <BaseAddress>285212672</BaseAddress> | ||
189 | <FileAlignment>4096</FileAlignment> | ||
190 | <NoStdLib>false</NoStdLib> | ||
191 | <XmlDocFile>Docs.xml</XmlDocFile> | ||
192 | </Options> | ||
193 | </Configuration> | ||
194 | <Configuration name="Release"> <!-- You can define multple configurations that projects can have, but there is no way to define which one is selected by default as this is a part of the user preferences for a project, not the solution or project files --> | ||
195 | <Options> | ||
196 | <CompilerDefines>TRACE</CompilerDefines> | ||
197 | <OptimizeCode>true</OptimizeCode> | ||
198 | <CheckUnderflowOverflow>false</CheckUnderflowOverflow> | ||
199 | <AllowUnsafe>false</AllowUnsafe> | ||
200 | <WarningLevel>4</WarningLevel> | ||
201 | <WarningsAsErrors>false</WarningsAsErrors> | ||
202 | <SuppressWarnings>1591;219;1573;1572;168</SuppressWarnings> | ||
203 | <OutputPath>..\bin</OutputPath> | ||
204 | <DebugInformation>false</DebugInformation> | ||
205 | <RegisterComInterop>false</RegisterComInterop> | ||
206 | <IncrementalBuild>true</IncrementalBuild> | ||
207 | <BaseAddress>285212672</BaseAddress> | ||
208 | <FileAlignment>4096</FileAlignment> | ||
209 | <NoStdLib>false</NoStdLib> | ||
210 | <GenerateXmlDocFile>true</GenerateXmlDocFile> | ||
211 | <XmlDocFile>Docs.xml</XmlDocFile> | ||
212 | </Options> | ||
213 | </Configuration> | ||
214 | |||
215 | <!-- One of the projects that is included in the Solution --> | ||
216 | <Project name="RealmForge.Utility" Language="VisualBasic" path="Utility" type="Library" assemblyName="RealmForge.Utility" rootNamespace="RealmForge"> | ||
217 | <Configuration name="Debug"> | ||
218 | <Options> | ||
219 | <OutputPath>..\bin\lib\Utility</OutputPath> | ||
220 | <XmlDocFile>RealmForge.Utility.xml</XmlDocFile> | ||
221 | </Options> | ||
222 | </Configuration> | ||
223 | <Configuration name="Release"> | ||
224 | <Options> | ||
225 | <OutputPath>..\bin\lib\Utility</OutputPath> | ||
226 | <XmlDocFile>RealmForge.Utility.xml</XmlDocFile> | ||
227 | </Options> | ||
228 | </Configuration> | ||
229 | <ReferencePath>../bin</ReferencePath> | ||
230 | <Reference name="System"/> | ||
231 | <Reference name="System.Data"/> | ||
232 | <Reference name="System.Drawing"/> | ||
233 | <Reference name="System.Xml"/> | ||
234 | <Reference name="System.Runtime.Serialization.Formatters.Soap"/> | ||
235 | <Reference name="ICSharpCode.SharpZipLib"/> | ||
236 | <Files> | ||
237 | <Match path="." pattern="*.vb" recurse="true"/> | ||
238 | </Files> | ||
239 | </Project> | ||
240 | |||
241 | <!-- Another projects that is included in the Solution --> | ||
242 | <Project name="DemoGame" Language="C#" path="DemoGame" type="WinExe" icon="..\bin\RealmForge.ico" assemblyName="DemoGame" rootNamespace="RealmForge"> | ||
243 | <!-- icon is used to define the location of the .ico file that is embeeded in the assembly when the project is compiled. This is relative to the project path --> | ||
244 | <!--type defines the type of project, valid types are Library (.dll), WinExe (.exe), and Exe (.exe). WinExe is not windows specific, it just defines that it is a GUI application and that no Console or Command window will show when it is started--> | ||
245 | |||
246 | <Configuration name="Debug"> | ||
247 | <Options> | ||
248 | <OutputPath>..\bin</OutputPath> | ||
249 | <XmlDocFile>DemoGame.xml</XmlDocFile> | ||
250 | </Options> | ||
251 | </Configuration> | ||
252 | <Configuration name="Release"> | ||
253 | <Options> | ||
254 | <OutputPath>..\bin</OutputPath> | ||
255 | <XmlDocFile>DemoGame.xml</XmlDocFile> | ||
256 | </Options> | ||
257 | </Configuration> | ||
258 | <ReferencePath>../bin</ReferencePath> | ||
259 | <Reference name="System"/> <!-- Assemblies that are located in the GAC (installed, global) can be referenced--> | ||
260 | <Reference name="ode"/> <!-- Assemblies that are located in the output directory to which the file is built can be referenced --> | ||
261 | <Reference name="RealmForge.Utility"/> <!-- When you reference the name of another project, then that project (and it's output) will be referenced instead of looking for a pre-built assembly--> | ||
262 | <Files> | ||
263 | <Match path="." pattern="*.cs" recurse="true"/> | ||
264 | <Match path="." pattern="*.bmp" recurse="true" buildAction="EmbeddedResource"/> | ||
265 | <Match path="." pattern="[^a]*\.(png|jpg)" useRegex="true" buildAction="EmbeddedResource"/> | ||
266 | |||
267 | <!-- Uses a regex or regular expression to find all files that end with .png or .jpg but dont have the letter 'a' in their name and add them to the project as EmbeddedResource's. Because recurse enabled (default is false), only the values in the files in that are directly in the project directory (not child directories) are checked.--> | ||
268 | <!--EmbeddedResource, Content, and Compile are valid buildAction's--> | ||
269 | </Files> | ||
270 | </Project> | ||
271 | |||
272 | </Solution> | ||
273 | </Prebuild> | ||
274 | |||
diff --git a/Prebuild/THANKS b/Prebuild/THANKS deleted file mode 100644 index 576467c..0000000 --- a/Prebuild/THANKS +++ /dev/null | |||
@@ -1,18 +0,0 @@ | |||
1 | Gryc Ueusp <gryc.ueusp@gmail.com> | ||
2 | |||
3 | caught a problem with the NAnt target's .build output which caused | ||
4 | the Ubuntu build servers to choke on prebuild-generated packages | ||
5 | |||
6 | Todd Berman <tberman@sevenl.net> | ||
7 | Lluis Sanchez Gual <lluis@novell.com> | ||
8 | |||
9 | pkg-config .pc file parser used in AutotoolsTarget.cs was ripped off | ||
10 | from work contributed to MonoDevelop by Lluis and Todd. It came | ||
11 | from | ||
12 | |||
13 | src/core/MonoDevelop.Core/MonoDevelop.Core/SystemPackage.cs (Lluis) | ||
14 | |||
15 | and | ||
16 | |||
17 | src/core/MonoDevelop.Core/MonoDevelop.Core/SystemAssemblyService.cs | ||
18 | (Lluis && Todd) | ||
diff --git a/Prebuild/TODO b/Prebuild/TODO deleted file mode 100644 index 33b19a1..0000000 --- a/Prebuild/TODO +++ /dev/null | |||
@@ -1,43 +0,0 @@ | |||
1 | * monodev target should be able to detect whether the project is 1.x | ||
2 | or 2.x runtime | ||
3 | |||
4 | * remove target which links ../project/foo.dll to each project's build | ||
5 | root | ||
6 | |||
7 | * generate .config files | ||
8 | |||
9 | * Fix the autotools target so that | ||
10 | sub generate_project_files { ... } | ||
11 | sub generate_solution_files { ... } | ||
12 | sub generate_multi_solution_files { ... } | ||
13 | sub generate_project { | ||
14 | ... | ||
15 | generate_project_files(); | ||
16 | } | ||
17 | sub generate_solution { | ||
18 | foreach $project ( @projects ){ | ||
19 | mkdir "$project/"; | ||
20 | pushd "$project/"; | ||
21 | generate_project(); | ||
22 | popd; | ||
23 | } | ||
24 | generate_solution_files(); | ||
25 | } | ||
26 | sub generate_multi_solution { | ||
27 | foreach $solution ( @solutions ){ | ||
28 | mkdir "$solution/"; | ||
29 | pushd "$solution/"; | ||
30 | generate_solution(); | ||
31 | popd; | ||
32 | } | ||
33 | generate_multi_solution_files(); | ||
34 | } | ||
35 | |||
36 | if(numProjects == 1){ | ||
37 | generate_project(); | ||
38 | }elsif(numSolutions == 1){ | ||
39 | generate_solution(); | ||
40 | }else{ | ||
41 | generate_multi_solution(); | ||
42 | } | ||
43 | |||
diff --git a/Prebuild/prebuild b/Prebuild/prebuild deleted file mode 100644 index 0dc648d..0000000 --- a/Prebuild/prebuild +++ /dev/null | |||
@@ -1,2 +0,0 @@ | |||
1 | #!/bin/sh | ||
2 | exec mono [PREFIX]/prebuild.exe "$@" | ||
diff --git a/bin/CSJ2K.dll b/bin/CSJ2K.dll new file mode 100644 index 0000000..ff7e809 --- /dev/null +++ b/bin/CSJ2K.dll | |||
Binary files differ | |||
diff --git a/bin/OpenSim.ini.example b/bin/OpenSim.ini.example index 7fcabbc..fa8dc9d 100644 --- a/bin/OpenSim.ini.example +++ b/bin/OpenSim.ini.example | |||
@@ -1356,11 +1356,6 @@ | |||
1356 | 1356 | ||
1357 | ;PacketMTU = 1400 | 1357 | ;PacketMTU = 1400 |
1358 | 1358 | ||
1359 | ; TextureUpdateRate (mS) determines how many times per second | ||
1360 | ; texture send processing will occur. The default is 100mS. | ||
1361 | ; | ||
1362 | ;TextureRequestRate = 100 | ||
1363 | |||
1364 | ; TextureSendLimit determines how many different textures | 1359 | ; TextureSendLimit determines how many different textures |
1365 | ; will be considered on each cycle. Textures are selected | 1360 | ; will be considered on each cycle. Textures are selected |
1366 | ; by priority. The old mechanism specified a value of 10 for | 1361 | ; by priority. The old mechanism specified a value of 10 for |
@@ -1373,15 +1368,6 @@ | |||
1373 | ; | 1368 | ; |
1374 | ;TextureDataLimit = 5 | 1369 | ;TextureDataLimit = 5 |
1375 | 1370 | ||
1376 | ;; The JPEG2000 decode cache | ||
1377 | ;; Timeout is in minutes | ||
1378 | |||
1379 | [J2KDecoder] | ||
1380 | ;CacheDir = "./j2kDecodeCache" | ||
1381 | ; Time in minutes before cached decodes expire. Set to 0 for no expiration. Default is 720 minutes. | ||
1382 | |||
1383 | ;CacheTimeout = 720 | ||
1384 | |||
1385 | ;; | 1371 | ;; |
1386 | ;; These are defaults that are overwritten below in [Architecture]. | 1372 | ;; These are defaults that are overwritten below in [Architecture]. |
1387 | ;; These defaults allow OpenSim to work out of the box with | 1373 | ;; These defaults allow OpenSim to work out of the box with |
diff --git a/bin/assets/TexturesAssetSet/TexturesAssetSet.xml b/bin/assets/TexturesAssetSet/TexturesAssetSet.xml index 0352c99..773de44 100644 --- a/bin/assets/TexturesAssetSet/TexturesAssetSet.xml +++ b/bin/assets/TexturesAssetSet/TexturesAssetSet.xml | |||
@@ -401,4 +401,11 @@ | |||
401 | <Key Name="assetType" Value="0" /> | 401 | <Key Name="assetType" Value="0" /> |
402 | <Key Name="fileName" Value="default_clear.jp2" /> | 402 | <Key Name="fileName" Value="default_clear.jp2" /> |
403 | </Section> | 403 | </Section> |
404 | |||
405 | <Section Name="Default Avatar"> | ||
406 | <Key Name="assetID" Value="c228d1cf-4b5d-4ba8-84f4-899a0796aa97"/> | ||
407 | <Key Name="name" Value="Default Avatar"/> | ||
408 | <Key Name="assetType" Value="0" /> | ||
409 | <Key Name="fileName" Value="default_avatar.jp2" /> | ||
410 | </Section> | ||
404 | </Nini> | 411 | </Nini> |
diff --git a/bin/assets/TexturesAssetSet/default_avatar.jp2 b/bin/assets/TexturesAssetSet/default_avatar.jp2 new file mode 100644 index 0000000..116b860 --- /dev/null +++ b/bin/assets/TexturesAssetSet/default_avatar.jp2 | |||
Binary files differ | |||
diff --git a/prebuild.xml b/prebuild.xml index ce04f12..22ff3d7 100644 --- a/prebuild.xml +++ b/prebuild.xml | |||
@@ -1541,6 +1541,7 @@ | |||
1541 | <Reference name="OpenMetaverseTypes.dll"/> | 1541 | <Reference name="OpenMetaverseTypes.dll"/> |
1542 | <Reference name="OpenMetaverse.StructuredData.dll"/> | 1542 | <Reference name="OpenMetaverse.StructuredData.dll"/> |
1543 | <Reference name="OpenMetaverse.dll"/> | 1543 | <Reference name="OpenMetaverse.dll"/> |
1544 | <Reference name="CSJ2K.dll"/> | ||
1544 | <Reference name="OpenSim.Framework"/> | 1545 | <Reference name="OpenSim.Framework"/> |
1545 | <Reference name="OpenSim.Framework.Capabilities"/> | 1546 | <Reference name="OpenSim.Framework.Capabilities"/> |
1546 | <Reference name="OpenSim.Framework.Communications"/> | 1547 | <Reference name="OpenSim.Framework.Communications"/> |
@@ -3534,35 +3535,6 @@ | |||
3534 | </Files> | 3535 | </Files> |
3535 | </Project> | 3536 | </Project> |
3536 | 3537 | ||
3537 | <Project frameworkVersion="v3_5" name="OpenSim.Framework.Servers.HttpServer.Tests" path="OpenSim/Framework/Servers/HttpServer/Tests" type="Library"> | ||
3538 | <Configuration name="Debug"> | ||
3539 | <Options> | ||
3540 | <OutputPath>../../../../../bin/</OutputPath> | ||
3541 | </Options> | ||
3542 | </Configuration> | ||
3543 | <Configuration name="Release"> | ||
3544 | <Options> | ||
3545 | <OutputPath>../../../../../bin/</OutputPath> | ||
3546 | </Options> | ||
3547 | </Configuration> | ||
3548 | |||
3549 | <ReferencePath>../../../../../bin/</ReferencePath> | ||
3550 | <Reference name="System"/> | ||
3551 | <Reference name="OpenSim.Data"/> | ||
3552 | <Reference name="OpenSim.Tests.Common"/> | ||
3553 | <Reference name="OpenSim.Framework"/> | ||
3554 | <Reference name="OpenSim.Framework.Servers"/> | ||
3555 | <Reference name="OpenSim.Framework.Servers.HttpServer"/> | ||
3556 | <Reference name="log4net.dll"/> | ||
3557 | <Reference name="HttpServer_OpenSim.dll"/> | ||
3558 | <Reference name="nunit.framework.dll" /> | ||
3559 | |||
3560 | <Files> | ||
3561 | <Match pattern="*.cs" recurse="true"> | ||
3562 | </Match> | ||
3563 | </Files> | ||
3564 | </Project> | ||
3565 | |||
3566 | <Project frameworkVersion="v3_5" name="OpenSim.Framework.Communications.Tests" path="OpenSim/Framework/Communications/Tests" type="Library"> | 3538 | <Project frameworkVersion="v3_5" name="OpenSim.Framework.Communications.Tests" path="OpenSim/Framework/Communications/Tests" type="Library"> |
3567 | <Configuration name="Debug"> | 3539 | <Configuration name="Debug"> |
3568 | <Options> | 3540 | <Options> |
@@ -3829,40 +3801,6 @@ | |||
3829 | </Files> | 3801 | </Files> |
3830 | </Project> | 3802 | </Project> |
3831 | 3803 | ||
3832 | <Project frameworkVersion="v3_5" name="OpenSim.Server.Handlers.Tests" path="OpenSim/Server/Handlers/Tests" type="Library"> | ||
3833 | <Configuration name="Debug"> | ||
3834 | <Options> | ||
3835 | <OutputPath>../../../../bin/</OutputPath> | ||
3836 | </Options> | ||
3837 | </Configuration> | ||
3838 | <Configuration name="Release"> | ||
3839 | <Options> | ||
3840 | <OutputPath>../../../../bin/</OutputPath> | ||
3841 | </Options> | ||
3842 | </Configuration> | ||
3843 | |||
3844 | <ReferencePath>../../../../bin/</ReferencePath> | ||
3845 | <Reference name="System"/> | ||
3846 | <Reference name="System.Xml"/> | ||
3847 | <Reference name="OpenMetaverseTypes.dll"/> | ||
3848 | <Reference name="OpenMetaverse.dll"/> | ||
3849 | <Reference name="nunit.framework.dll" /> | ||
3850 | <Reference name="OpenSim.Framework"/> | ||
3851 | <Reference name="OpenSim.Framework.Console"/> | ||
3852 | <Reference name="OpenSim.Framework.Servers.HttpServer"/> | ||
3853 | <Reference name="OpenSim.Server.Handlers"/> | ||
3854 | <Reference name="OpenSim.Server.Base"/> | ||
3855 | <Reference name="OpenSim.Services.Base" /> | ||
3856 | <Reference name="OpenSim.Services.Interfaces"/> | ||
3857 | <Reference name="OpenSim.Tests.Common"/> | ||
3858 | <Reference name="Nini.dll" /> | ||
3859 | <Reference name="log4net.dll"/> | ||
3860 | |||
3861 | <Files> | ||
3862 | <Match pattern="*.cs" recurse="true"/> | ||
3863 | </Files> | ||
3864 | </Project> | ||
3865 | |||
3866 | <?include file="addon-modules/*/prebuild.xml" ?> | 3804 | <?include file="addon-modules/*/prebuild.xml" ?> |
3867 | 3805 | ||
3868 | </Solution> | 3806 | </Solution> |