1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
|
using System;
using System.Collections.Generic;
using libsecondlife;
using OpenSim.Framework;
using OpenSim.Framework.Console;
using OpenSim.Region.Environment.Scenes;
namespace OpenSim.Region.Environment.Modules
{
public class UserTextureDownloadService
{
private readonly Dictionary<LLUUID, TextureSender> m_textureSenders = new Dictionary<LLUUID, TextureSender>();
private readonly BlockingQueue<TextureSender> m_sharedSendersQueue;
private readonly Scene m_scene;
public UserTextureDownloadService(Scene scene, BlockingQueue<TextureSender> sharedQueue)
{
m_scene = scene;
m_sharedSendersQueue = sharedQueue;
}
public void HandleTextureRequest(IClientAPI client, TextureRequestArgs e)
{
TextureSender textureSender;
//TODO: should be working out the data size/ number of packets to be sent for each discard level
if ((e.DiscardLevel >= 0) || (e.Priority != 0))
{
lock (m_textureSenders)
{
if (m_textureSenders.TryGetValue(e.RequestedAssetID, out textureSender))
{
textureSender.UpdateRequest(e.DiscardLevel, e.PacketNumber);
if ((textureSender.ImageLoaded) &&
(textureSender.Sending == false))
{
EnqueueTextureSender(textureSender);
}
}
else
{
TextureSender requestHandler =
new TextureSender(client, e.RequestedAssetID, e.DiscardLevel, e.PacketNumber);
m_textureSenders.Add(e.RequestedAssetID, requestHandler);
m_scene.AssetCache.GetAsset(e.RequestedAssetID, TextureCallback);
}
}
}
else
{
lock (m_textureSenders)
{
if (m_textureSenders.TryGetValue(e.RequestedAssetID, out textureSender))
{
textureSender.Cancel = true;
}
}
}
}
public void TextureCallback(LLUUID textureID, AssetBase asset)
{
lock (m_textureSenders)
{
TextureSender textureSender;
if (m_textureSenders.TryGetValue(textureID, out textureSender))
{
if (!textureSender.ImageLoaded)
{
textureSender.TextureReceived(asset);
EnqueueTextureSender(textureSender);
}
}
else
{
throw new Exception("Got a texture with no sender object to handle it, this shouldn't happen");
}
}
}
private void EnqueueTextureSender(TextureSender textureSender)
{
textureSender.Cancel = false;
textureSender.Sending = true;
textureSender.counter = 0;
if (!m_sharedSendersQueue.Contains(textureSender))
{
m_sharedSendersQueue.Enqueue(textureSender);
}
}
internal void Close()
{
lock (m_textureSenders)
{
foreach( TextureSender textureSender in m_textureSenders.Values )
{
textureSender.Cancel = true;
}
m_textureSenders.Clear();
}
}
}
}
|