diff options
author | MW | 2007-10-29 09:51:23 +0000 |
---|---|---|
committer | MW | 2007-10-29 09:51:23 +0000 |
commit | 27f003b68314ea5136632d6f9d14057c96ade1e1 (patch) | |
tree | 3bbdb9bb3fac97922768c2f6d0acd5dae3c4278f /OpenSim/Region/Environment/Modules/TextureDownloadModule.cs | |
parent | normalized line endings (diff) | |
download | opensim-SC-27f003b68314ea5136632d6f9d14057c96ade1e1.zip opensim-SC-27f003b68314ea5136632d6f9d14057c96ade1e1.tar.gz opensim-SC-27f003b68314ea5136632d6f9d14057c96ade1e1.tar.bz2 opensim-SC-27f003b68314ea5136632d6f9d14057c96ade1e1.tar.xz |
Started the process of cleaning up AssetCache and moving most of the code into modules. Have moved TextureRequest handling (from the client) to a module. But even though to start with I just did a little bit of cleaning up of the existing code, it doesn't seem to work as good as the old code so I need to spend more time on it. So for now am committing my changes but with them not in use. So for now all Texture and asset requests are still handled by the old code in AssetCache.
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Region/Environment/Modules/TextureDownloadModule.cs | 197 |
1 files changed, 192 insertions, 5 deletions
diff --git a/OpenSim/Region/Environment/Modules/TextureDownloadModule.cs b/OpenSim/Region/Environment/Modules/TextureDownloadModule.cs index d3297c8..56e20d1 100644 --- a/OpenSim/Region/Environment/Modules/TextureDownloadModule.cs +++ b/OpenSim/Region/Environment/Modules/TextureDownloadModule.cs | |||
@@ -25,9 +25,14 @@ | |||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | * | 26 | * |
27 | */ | 27 | */ |
28 | 28 | using System; | |
29 | using System.Collections.Generic; | ||
30 | using System.Threading; | ||
29 | using libsecondlife; | 31 | using libsecondlife; |
32 | using libsecondlife.Packets; | ||
30 | using OpenSim.Framework.Interfaces; | 33 | using OpenSim.Framework.Interfaces; |
34 | using OpenSim.Framework.Types; | ||
35 | using OpenSim.Framework.Utilities; | ||
31 | using OpenSim.Region.Environment.Interfaces; | 36 | using OpenSim.Region.Environment.Interfaces; |
32 | using OpenSim.Region.Environment.Scenes; | 37 | using OpenSim.Region.Environment.Scenes; |
33 | using Nini.Config; | 38 | using Nini.Config; |
@@ -37,15 +42,28 @@ namespace OpenSim.Region.Environment.Modules | |||
37 | public class TextureDownloadModule : IRegionModule | 42 | public class TextureDownloadModule : IRegionModule |
38 | { | 43 | { |
39 | private Scene m_scene; | 44 | private Scene m_scene; |
45 | private List<Scene> m_scenes = new List<Scene>(); | ||
46 | private Dictionary<LLUUID, Dictionary<LLUUID, AssetRequest>> ClientRequests = new Dictionary<LLUUID, Dictionary<LLUUID, AssetRequest>>(); | ||
47 | |||
48 | private BlockingQueue<TextureSender> QueueSenders = new BlockingQueue<TextureSender>(); | ||
49 | private Dictionary<LLUUID, List<LLUUID>> InProcess = new Dictionary<LLUUID, List<LLUUID>>(); | ||
50 | // private Thread m_thread; | ||
40 | 51 | ||
41 | public TextureDownloadModule() | 52 | public TextureDownloadModule() |
42 | { | 53 | { |
54 | // m_thread = new Thread(new ThreadStart(ProcessTextureSenders)); | ||
55 | // m_thread.IsBackground = true; | ||
56 | // m_thread.Start(); | ||
43 | } | 57 | } |
44 | 58 | ||
45 | public void Initialise(Scene scene, IConfigSource config) | 59 | public void Initialise(Scene scene, IConfigSource config) |
46 | { | 60 | { |
47 | m_scene = scene; | 61 | if (!m_scenes.Contains(scene)) |
48 | m_scene.EventManager.OnNewClient += NewClient; | 62 | { |
63 | m_scenes.Add(scene); | ||
64 | m_scene = scene; | ||
65 | m_scene.EventManager.OnNewClient += NewClient; | ||
66 | } | ||
49 | } | 67 | } |
50 | 68 | ||
51 | public void PostInitialise() | 69 | public void PostInitialise() |
@@ -63,15 +81,184 @@ namespace OpenSim.Region.Environment.Modules | |||
63 | 81 | ||
64 | public bool IsSharedModule | 82 | public bool IsSharedModule |
65 | { | 83 | { |
66 | get { return false; } | 84 | get { return true; } |
67 | } | 85 | } |
68 | 86 | ||
69 | public void NewClient(IClientAPI client) | 87 | public void NewClient(IClientAPI client) |
70 | { | 88 | { |
89 | /* lock (ClientRequests) | ||
90 | { | ||
91 | if (!ClientRequests.ContainsKey(client.AgentId)) | ||
92 | { | ||
93 | ClientRequests.Add(client.AgentId, new Dictionary<LLUUID, AssetRequest>()); | ||
94 | InProcess.Add(client.AgentId, new List<LLUUID>()); | ||
95 | } | ||
96 | } | ||
97 | client.OnRequestTexture += TextureRequest; | ||
98 | */ | ||
99 | } | ||
100 | |||
101 | public void TextureCallback(LLUUID textureID, AssetBase asset) | ||
102 | { | ||
103 | lock (ClientRequests) | ||
104 | { | ||
105 | foreach (Dictionary<LLUUID, AssetRequest> reqList in ClientRequests.Values) | ||
106 | { | ||
107 | if (reqList.ContainsKey(textureID)) | ||
108 | { | ||
109 | //check the texture isn't already in the process of being sent to the client. | ||
110 | if (!InProcess[reqList[textureID].RequestUser.AgentId].Contains(textureID)) | ||
111 | { | ||
112 | TextureSender sender = new TextureSender(reqList[textureID], asset); | ||
113 | QueueSenders.Enqueue(sender); | ||
114 | InProcess[reqList[textureID].RequestUser.AgentId].Add(textureID); | ||
115 | reqList.Remove(textureID); | ||
116 | } | ||
117 | } | ||
118 | } | ||
119 | } | ||
120 | } | ||
121 | |||
122 | public void TextureRequest(Object sender, TextureRequestArgs e) | ||
123 | { | ||
124 | IClientAPI client = (IClientAPI)sender; | ||
125 | if (!ClientRequests[client.AgentId].ContainsKey(e.RequestedAssetID)) | ||
126 | { | ||
127 | lock (ClientRequests) | ||
128 | { | ||
129 | AssetRequest request = new AssetRequest(client, e.RequestedAssetID, e.DiscardLevel, e.PacketNumber); | ||
130 | ClientRequests[client.AgentId].Add(e.RequestedAssetID, request); | ||
131 | } | ||
132 | m_scene.commsManager.AssetCache.GetAsset(e.RequestedAssetID, TextureCallback); | ||
133 | } | ||
134 | } | ||
135 | |||
136 | public void ProcessTextureSenders() | ||
137 | { | ||
138 | while (true) | ||
139 | { | ||
140 | TextureSender sender = this.QueueSenders.Dequeue(); | ||
141 | bool finished = sender.SendTexture(); | ||
142 | if (finished) | ||
143 | { | ||
144 | this.TextureSent(sender); | ||
145 | } | ||
146 | else | ||
147 | { | ||
148 | this.QueueSenders.Enqueue(sender); | ||
149 | } | ||
150 | } | ||
151 | } | ||
152 | |||
153 | private void TextureSent(TextureSender sender) | ||
154 | { | ||
155 | if (InProcess[sender.request.RequestUser.AgentId].Contains(sender.request.RequestAssetID)) | ||
156 | { | ||
157 | InProcess[sender.request.RequestUser.AgentId].Remove(sender.request.RequestAssetID); | ||
158 | } | ||
159 | } | ||
160 | |||
161 | public class TextureSender | ||
162 | { | ||
163 | public AssetRequest request; | ||
164 | private int counter = 0; | ||
165 | private AssetBase m_asset; | ||
166 | public long DataPointer = 0; | ||
167 | public int NumPackets = 0; | ||
168 | public int PacketCounter = 0; | ||
169 | |||
170 | public TextureSender(AssetRequest req, AssetBase asset) | ||
171 | { | ||
172 | request = req; | ||
173 | m_asset = asset; | ||
174 | |||
175 | if (asset.Data.LongLength > 600) | ||
176 | { | ||
177 | NumPackets = 2 + (int)(asset.Data.Length - 601) / 1000; | ||
178 | } | ||
179 | else | ||
180 | { | ||
181 | NumPackets = 1; | ||
182 | } | ||
183 | |||
184 | PacketCounter = (int) req.PacketNumber; | ||
185 | } | ||
186 | |||
187 | public bool SendTexture() | ||
188 | { | ||
189 | SendPacket(); | ||
190 | counter++; | ||
191 | if ((PacketCounter >= NumPackets) | counter > 100 | (NumPackets == 1) | (request.DiscardLevel == -1)) | ||
192 | { | ||
193 | return true; | ||
194 | } | ||
195 | return false; | ||
196 | } | ||
197 | |||
198 | public void SendPacket() | ||
199 | { | ||
200 | AssetRequest req = request; | ||
201 | if (PacketCounter == 0) | ||
202 | { | ||
203 | if (NumPackets == 1) | ||
204 | { | ||
205 | ImageDataPacket im = new ImageDataPacket(); | ||
206 | im.Header.Reliable = false; | ||
207 | im.ImageID.Packets = 1; | ||
208 | im.ImageID.ID = m_asset.FullID; | ||
209 | im.ImageID.Size = (uint)m_asset.Data.Length; | ||
210 | im.ImageData.Data = m_asset.Data; | ||
211 | im.ImageID.Codec = 2; | ||
212 | req.RequestUser.OutPacket(im); | ||
213 | PacketCounter++; | ||
214 | } | ||
215 | else | ||
216 | { | ||
217 | ImageDataPacket im = new ImageDataPacket(); | ||
218 | im.Header.Reliable = false; | ||
219 | im.ImageID.Packets = (ushort)(NumPackets); | ||
220 | im.ImageID.ID = m_asset.FullID; | ||
221 | im.ImageID.Size = (uint)m_asset.Data.Length; | ||
222 | im.ImageData.Data = new byte[600]; | ||
223 | Array.Copy(m_asset.Data, 0, im.ImageData.Data, 0, 600); | ||
224 | im.ImageID.Codec = 2; | ||
225 | req.RequestUser.OutPacket(im); | ||
226 | PacketCounter++; | ||
227 | } | ||
228 | } | ||
229 | else | ||
230 | { | ||
231 | ImagePacketPacket im = new ImagePacketPacket(); | ||
232 | im.Header.Reliable = false; | ||
233 | im.ImageID.Packet = (ushort)(PacketCounter); | ||
234 | im.ImageID.ID = m_asset.FullID; | ||
235 | int size = m_asset.Data.Length - 600 - (1000 * (PacketCounter - 1)); | ||
236 | if (size > 1000) size = 1000; | ||
237 | im.ImageData.Data = new byte[size]; | ||
238 | Array.Copy(m_asset.Data, 600 + (1000 * (PacketCounter - 1)), im.ImageData.Data, 0, size); | ||
239 | req.RequestUser.OutPacket(im); | ||
240 | PacketCounter++; | ||
241 | } | ||
242 | |||
243 | } | ||
244 | |||
71 | } | 245 | } |
72 | 246 | ||
73 | public void TextureAssetCallback(LLUUID texture, byte[] data) | 247 | public class AssetRequest |
74 | { | 248 | { |
249 | public IClientAPI RequestUser; | ||
250 | public LLUUID RequestAssetID; | ||
251 | public int DiscardLevel = -1; | ||
252 | public uint PacketNumber = 0; | ||
253 | |||
254 | public AssetRequest(IClientAPI client, LLUUID textureID, int discardLevel, uint packetNumber) | ||
255 | { | ||
256 | RequestUser = client; | ||
257 | RequestAssetID = textureID; | ||
258 | DiscardLevel = discardLevel; | ||
259 | PacketNumber = packetNumber; | ||
260 | } | ||
75 | } | 261 | } |
262 | |||
76 | } | 263 | } |
77 | } | 264 | } |