aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules/Asset/CenomeAssetCache.cs
diff options
context:
space:
mode:
authorJeff Ames2009-06-04 00:51:02 +0000
committerJeff Ames2009-06-04 00:51:02 +0000
commit007016ecd2fabf0bbe789ac6fc0ab6f827ff90b7 (patch)
treead04e7e72d19259e7b726c1d8eb55d8b339d80aa /OpenSim/Region/CoreModules/Asset/CenomeAssetCache.cs
parentCommitting the skeleton of the authentication service (diff)
downloadopensim-SC_OLD-007016ecd2fabf0bbe789ac6fc0ab6f827ff90b7.zip
opensim-SC_OLD-007016ecd2fabf0bbe789ac6fc0ab6f827ff90b7.tar.gz
opensim-SC_OLD-007016ecd2fabf0bbe789ac6fc0ab6f827ff90b7.tar.bz2
opensim-SC_OLD-007016ecd2fabf0bbe789ac6fc0ab6f827ff90b7.tar.xz
Update svn properties.
Diffstat (limited to 'OpenSim/Region/CoreModules/Asset/CenomeAssetCache.cs')
-rw-r--r--OpenSim/Region/CoreModules/Asset/CenomeAssetCache.cs764
1 files changed, 382 insertions, 382 deletions
diff --git a/OpenSim/Region/CoreModules/Asset/CenomeAssetCache.cs b/OpenSim/Region/CoreModules/Asset/CenomeAssetCache.cs
index 00a8143..bbc9c9b 100644
--- a/OpenSim/Region/CoreModules/Asset/CenomeAssetCache.cs
+++ b/OpenSim/Region/CoreModules/Asset/CenomeAssetCache.cs
@@ -1,382 +1,382 @@
1// -------------------------------------------------------------------------------------------------------------------- 1// --------------------------------------------------------------------------------------------------------------------
2// <copyright company="" file="CenomeAssetCache.cs"> 2// <copyright company="" file="CenomeAssetCache.cs">
3// 3//
4// </copyright> 4// </copyright>
5// <summary> 5// <summary>
6// 6//
7// </summary> 7// </summary>
8// 8//
9// -------------------------------------------------------------------------------------------------------------------- 9// --------------------------------------------------------------------------------------------------------------------
10using System; 10using System;
11using System.Reflection; 11using System.Reflection;
12using log4net; 12using log4net;
13using Nini.Config; 13using Nini.Config;
14using OpenSim.Framework; 14using OpenSim.Framework;
15using OpenSim.Region.Framework.Interfaces; 15using OpenSim.Region.Framework.Interfaces;
16using OpenSim.Region.Framework.Scenes; 16using OpenSim.Region.Framework.Scenes;
17 17
18namespace OpenSim.Region.CoreModules.Asset 18namespace OpenSim.Region.CoreModules.Asset
19{ 19{
20 /// <summary> 20 /// <summary>
21 /// Cenome memory asset cache. 21 /// Cenome memory asset cache.
22 /// </summary> 22 /// </summary>
23 /// <remarks> 23 /// <remarks>
24 /// <para> 24 /// <para>
25 /// Cache is enabled by setting "AssetCaching" configuration to value "CenomeMemoryAssetCache". 25 /// Cache is enabled by setting "AssetCaching" configuration to value "CenomeMemoryAssetCache".
26 /// When cache is successfully enable log should have message 26 /// When cache is successfully enable log should have message
27 /// "[ASSET CACHE]: Cenome asset cache enabled (MaxSize = XXX bytes, MaxCount = XXX, ExpirationTime = XXX)". 27 /// "[ASSET CACHE]: Cenome asset cache enabled (MaxSize = XXX bytes, MaxCount = XXX, ExpirationTime = XXX)".
28 /// </para> 28 /// </para>
29 /// <para> 29 /// <para>
30 /// Cache's size is limited by two parameters: 30 /// Cache's size is limited by two parameters:
31 /// maximal allowed size in bytes and maximal allowed asset count. When new asset 31 /// maximal allowed size in bytes and maximal allowed asset count. When new asset
32 /// is added to cache that have achieved either size or count limitation, cache 32 /// is added to cache that have achieved either size or count limitation, cache
33 /// will automatically remove less recently used assets from cache. Additionally 33 /// will automatically remove less recently used assets from cache. Additionally
34 /// asset's lifetime is controlled by expiration time. 34 /// asset's lifetime is controlled by expiration time.
35 /// </para> 35 /// </para>
36 /// <para> 36 /// <para>
37 /// <list type="table"> 37 /// <list type="table">
38 /// <listheader> 38 /// <listheader>
39 /// <term>Configuration</term> 39 /// <term>Configuration</term>
40 /// <description>Description</description> 40 /// <description>Description</description>
41 /// </listheader> 41 /// </listheader>
42 /// <item> 42 /// <item>
43 /// <term>MaxSize</term> 43 /// <term>MaxSize</term>
44 /// <description>Maximal size of the cache in bytes. Default value: 128MB (134 217 728 bytes).</description> 44 /// <description>Maximal size of the cache in bytes. Default value: 128MB (134 217 728 bytes).</description>
45 /// </item> 45 /// </item>
46 /// <item> 46 /// <item>
47 /// <term>MaxCount</term> 47 /// <term>MaxCount</term>
48 /// <description>Maximal count of assets stored to cache. Default value: 4096 assets.</description> 48 /// <description>Maximal count of assets stored to cache. Default value: 4096 assets.</description>
49 /// </item> 49 /// </item>
50 /// <item> 50 /// <item>
51 /// <term>ExpirationTime</term> 51 /// <term>ExpirationTime</term>
52 /// <description>Asset's expiration time in minutes. Default value: 30 minutes.</description> 52 /// <description>Asset's expiration time in minutes. Default value: 30 minutes.</description>
53 /// </item> 53 /// </item>
54 /// </list> 54 /// </list>
55 /// </para> 55 /// </para>
56 /// </remarks> 56 /// </remarks>
57 /// <example> 57 /// <example>
58 /// Enabling Cenome Asset Cache: 58 /// Enabling Cenome Asset Cache:
59 /// <code> 59 /// <code>
60 /// [Modules] 60 /// [Modules]
61 /// AssetCaching = "CenomeMemoryAssetCache" 61 /// AssetCaching = "CenomeMemoryAssetCache"
62 /// </code> 62 /// </code>
63 /// Setting size and expiration time limitations: 63 /// Setting size and expiration time limitations:
64 /// <code> 64 /// <code>
65 /// [AssetService] 65 /// [AssetService]
66 /// ; 256 MB (default: 134217728) 66 /// ; 256 MB (default: 134217728)
67 /// MaxSize = 268435456 67 /// MaxSize = 268435456
68 /// ; How many assets it is possible to store cache (default: 4096) 68 /// ; How many assets it is possible to store cache (default: 4096)
69 /// MaxCount = 16384 69 /// MaxCount = 16384
70 /// ; Expiration time - 1 hour (default: 30 minutes) 70 /// ; Expiration time - 1 hour (default: 30 minutes)
71 /// ExpirationTime = 60 71 /// ExpirationTime = 60
72 /// </code> 72 /// </code>
73 /// </example> 73 /// </example>
74 public class CenomeMemoryAssetCache : IImprovedAssetCache, ISharedRegionModule 74 public class CenomeMemoryAssetCache : IImprovedAssetCache, ISharedRegionModule
75 { 75 {
76 /// <summary> 76 /// <summary>
77 /// Cache's default maximal asset count. 77 /// Cache's default maximal asset count.
78 /// </summary> 78 /// </summary>
79 /// <remarks> 79 /// <remarks>
80 /// <para> 80 /// <para>
81 /// Assuming that average asset size is about 32768 bytes. 81 /// Assuming that average asset size is about 32768 bytes.
82 /// </para> 82 /// </para>
83 /// </remarks> 83 /// </remarks>
84 public const int DefaultMaxCount = 4096; 84 public const int DefaultMaxCount = 4096;
85 85
86 /// <summary> 86 /// <summary>
87 /// Default maximal size of the cache in bytes 87 /// Default maximal size of the cache in bytes
88 /// </summary> 88 /// </summary>
89 /// <remarks> 89 /// <remarks>
90 /// <para> 90 /// <para>
91 /// 128MB = 128 * 1024^2 = 134 217 728 bytes. 91 /// 128MB = 128 * 1024^2 = 134 217 728 bytes.
92 /// </para> 92 /// </para>
93 /// </remarks> 93 /// </remarks>
94 public const long DefaultMaxSize = 134217728; 94 public const long DefaultMaxSize = 134217728;
95 95
96 /// <summary> 96 /// <summary>
97 /// Asset's default expiration time in the cache. 97 /// Asset's default expiration time in the cache.
98 /// </summary> 98 /// </summary>
99 public static readonly TimeSpan DefaultExpirationTime = TimeSpan.FromMinutes( 30.0 ); 99 public static readonly TimeSpan DefaultExpirationTime = TimeSpan.FromMinutes( 30.0 );
100 100
101 /// <summary> 101 /// <summary>
102 /// Log manager instance. 102 /// Log manager instance.
103 /// </summary> 103 /// </summary>
104 private static readonly ILog Log = LogManager.GetLogger( MethodBase.GetCurrentMethod().DeclaringType ); 104 private static readonly ILog Log = LogManager.GetLogger( MethodBase.GetCurrentMethod().DeclaringType );
105 105
106 /// <summary> 106 /// <summary>
107 /// Cache object. 107 /// Cache object.
108 /// </summary> 108 /// </summary>
109 private ICnmCache<string, AssetBase> m_cache; 109 private ICnmCache<string, AssetBase> m_cache;
110 110
111 /// <summary> 111 /// <summary>
112 /// Count of cache commands 112 /// Count of cache commands
113 /// </summary> 113 /// </summary>
114 private int m_cachedCount; 114 private int m_cachedCount;
115 115
116 /// <summary> 116 /// <summary>
117 /// How many gets before dumping statistics 117 /// How many gets before dumping statistics
118 /// </summary> 118 /// </summary>
119 /// <remarks> 119 /// <remarks>
120 /// If 0 or less, then disabled. 120 /// If 0 or less, then disabled.
121 /// </remarks> 121 /// </remarks>
122 private int m_debugEpoch; 122 private int m_debugEpoch;
123 123
124 /// <summary> 124 /// <summary>
125 /// Is Cenome asset cache enabled. 125 /// Is Cenome asset cache enabled.
126 /// </summary> 126 /// </summary>
127 private bool m_enabled; 127 private bool m_enabled;
128 128
129 /// <summary> 129 /// <summary>
130 /// Count of get requests 130 /// Count of get requests
131 /// </summary> 131 /// </summary>
132 private int m_getCount; 132 private int m_getCount;
133 133
134 /// <summary> 134 /// <summary>
135 /// How many hits 135 /// How many hits
136 /// </summary> 136 /// </summary>
137 private int m_hitCount; 137 private int m_hitCount;
138 138
139 /// <summary> 139 /// <summary>
140 /// Initialize asset cache module with default parameters. 140 /// Initialize asset cache module with default parameters.
141 /// </summary> 141 /// </summary>
142 public void Initialize() 142 public void Initialize()
143 { 143 {
144 Initialize( DefaultMaxSize, DefaultMaxCount, DefaultExpirationTime ); 144 Initialize( DefaultMaxSize, DefaultMaxCount, DefaultExpirationTime );
145 } 145 }
146 146
147 /// <summary> 147 /// <summary>
148 /// Initialize asset cache module, with custom parameters. 148 /// Initialize asset cache module, with custom parameters.
149 /// </summary> 149 /// </summary>
150 /// <param name="maximalSize"> 150 /// <param name="maximalSize">
151 /// Cache's maximal size in bytes. 151 /// Cache's maximal size in bytes.
152 /// </param> 152 /// </param>
153 /// <param name="maximalCount"> 153 /// <param name="maximalCount">
154 /// Cache's maximal count of assets. 154 /// Cache's maximal count of assets.
155 /// </param> 155 /// </param>
156 /// <param name="expirationTime"> 156 /// <param name="expirationTime">
157 /// Asset's expiration time. 157 /// Asset's expiration time.
158 /// </param> 158 /// </param>
159 public void Initialize( long maximalSize, int maximalCount, TimeSpan expirationTime ) 159 public void Initialize( long maximalSize, int maximalCount, TimeSpan expirationTime )
160 { 160 {
161 if( maximalSize <= 0 || maximalCount <= 0 ) 161 if( maximalSize <= 0 || maximalCount <= 0 )
162 { 162 {
163 Log.Info( "[ASSET CACHE]: Cenome asset cache is not enabled." ); 163 Log.Info( "[ASSET CACHE]: Cenome asset cache is not enabled." );
164 m_enabled = false; 164 m_enabled = false;
165 return; 165 return;
166 } 166 }
167 167
168 if( expirationTime <= TimeSpan.Zero ) 168 if( expirationTime <= TimeSpan.Zero )
169 { 169 {
170 // Disable expiration time 170 // Disable expiration time
171 expirationTime = TimeSpan.MaxValue; 171 expirationTime = TimeSpan.MaxValue;
172 } 172 }
173 173
174 // Create cache and add synchronization wrapper over it 174 // Create cache and add synchronization wrapper over it
175 m_cache = 175 m_cache =
176 CnmSynchronizedCache<string, AssetBase>.Synchronized( new CnmMemoryCache<string, AssetBase>( 176 CnmSynchronizedCache<string, AssetBase>.Synchronized( new CnmMemoryCache<string, AssetBase>(
177 maximalSize, maximalCount, expirationTime ) ); 177 maximalSize, maximalCount, expirationTime ) );
178 m_enabled = true; 178 m_enabled = true;
179 Log.InfoFormat( 179 Log.InfoFormat(
180 "[ASSET CACHE]: Cenome asset cache enabled (MaxSize = {0} bytes, MaxCount = {1}, ExpirationTime = {2})", 180 "[ASSET CACHE]: Cenome asset cache enabled (MaxSize = {0} bytes, MaxCount = {1}, ExpirationTime = {2})",
181 maximalSize, 181 maximalSize,
182 maximalCount, 182 maximalCount,
183 expirationTime ); 183 expirationTime );
184 } 184 }
185 185
186 #region IImprovedAssetCache Members 186 #region IImprovedAssetCache Members
187 187
188 /// <summary> 188 /// <summary>
189 /// Cache asset. 189 /// Cache asset.
190 /// </summary> 190 /// </summary>
191 /// <param name="asset"> 191 /// <param name="asset">
192 /// The asset that is being cached. 192 /// The asset that is being cached.
193 /// </param> 193 /// </param>
194 public void Cache( AssetBase asset ) 194 public void Cache( AssetBase asset )
195 { 195 {
196 long size = asset.Data != null ? asset.Data.Length : 1; 196 long size = asset.Data != null ? asset.Data.Length : 1;
197 m_cache.Set( asset.ID, asset, size ); 197 m_cache.Set( asset.ID, asset, size );
198 m_cachedCount++; 198 m_cachedCount++;
199 } 199 }
200 200
201 /// <summary> 201 /// <summary>
202 /// Clear asset cache. 202 /// Clear asset cache.
203 /// </summary> 203 /// </summary>
204 public void Clear() 204 public void Clear()
205 { 205 {
206 m_cache.Clear(); 206 m_cache.Clear();
207 } 207 }
208 208
209 /// <summary> 209 /// <summary>
210 /// Expire (remove) asset stored to cache. 210 /// Expire (remove) asset stored to cache.
211 /// </summary> 211 /// </summary>
212 /// <param name="id"> 212 /// <param name="id">
213 /// The expired asset's id. 213 /// The expired asset's id.
214 /// </param> 214 /// </param>
215 public void Expire( string id ) 215 public void Expire( string id )
216 { 216 {
217 m_cache.Remove( id ); 217 m_cache.Remove( id );
218 } 218 }
219 219
220 /// <summary> 220 /// <summary>
221 /// Get asset stored 221 /// Get asset stored
222 /// </summary> 222 /// </summary>
223 /// <param name="id"> 223 /// <param name="id">
224 /// The asset's id. 224 /// The asset's id.
225 /// </param> 225 /// </param>
226 /// <returns> 226 /// <returns>
227 /// Asset if it is found from cache; otherwise <see langword="null"/>. 227 /// Asset if it is found from cache; otherwise <see langword="null"/>.
228 /// </returns> 228 /// </returns>
229 /// <remarks> 229 /// <remarks>
230 /// <para> 230 /// <para>
231 /// Caller should always check that is return value <see langword="null"/>. 231 /// Caller should always check that is return value <see langword="null"/>.
232 /// Cache doesn't guarantee in any situation that asset is stored to it. 232 /// Cache doesn't guarantee in any situation that asset is stored to it.
233 /// </para> 233 /// </para>
234 /// </remarks> 234 /// </remarks>
235 public AssetBase Get( string id ) 235 public AssetBase Get( string id )
236 { 236 {
237 m_getCount++; 237 m_getCount++;
238 AssetBase assetBase; 238 AssetBase assetBase;
239 if( m_cache.TryGetValue( id, out assetBase ) ) 239 if( m_cache.TryGetValue( id, out assetBase ) )
240 m_hitCount++; 240 m_hitCount++;
241 241
242 if( m_getCount == m_debugEpoch ) 242 if( m_getCount == m_debugEpoch )
243 { 243 {
244 Log.InfoFormat( 244 Log.InfoFormat(
245 "[ASSET CACHE]: Cached = {0}, Get = {1}, Hits = {2}%, Size = {3} bytes, Avg. A. Size = {4} bytes", 245 "[ASSET CACHE]: Cached = {0}, Get = {1}, Hits = {2}%, Size = {3} bytes, Avg. A. Size = {4} bytes",
246 m_cachedCount, 246 m_cachedCount,
247 m_getCount, 247 m_getCount,
248 ((double) m_hitCount / m_getCount) * 100.0, 248 ((double) m_hitCount / m_getCount) * 100.0,
249 m_cache.Size, 249 m_cache.Size,
250 m_cache.Size / m_cache.Count ); 250 m_cache.Size / m_cache.Count );
251 m_getCount = 0; 251 m_getCount = 0;
252 m_hitCount = 0; 252 m_hitCount = 0;
253 m_cachedCount = 0; 253 m_cachedCount = 0;
254 } 254 }
255 255
256 return assetBase; 256 return assetBase;
257 } 257 }
258 258
259 #endregion 259 #endregion
260 260
261 #region ISharedRegionModule Members 261 #region ISharedRegionModule Members
262 262
263 /// <summary> 263 /// <summary>
264 /// Gets region module's name. 264 /// Gets region module's name.
265 /// </summary> 265 /// </summary>
266 public string Name 266 public string Name
267 { 267 {
268 get { return "CenomeMemoryAssetCache"; } 268 get { return "CenomeMemoryAssetCache"; }
269 } 269 }
270 270
271 /// <summary> 271 /// <summary>
272 /// New region is being added to server. 272 /// New region is being added to server.
273 /// </summary> 273 /// </summary>
274 /// <param name="scene"> 274 /// <param name="scene">
275 /// Region's scene. 275 /// Region's scene.
276 /// </param> 276 /// </param>
277 public void AddRegion( Scene scene ) 277 public void AddRegion( Scene scene )
278 { 278 {
279 if( m_enabled ) 279 if( m_enabled )
280 scene.RegisterModuleInterface<IImprovedAssetCache>( this ); 280 scene.RegisterModuleInterface<IImprovedAssetCache>( this );
281 } 281 }
282 282
283 /// <summary> 283 /// <summary>
284 /// Close region module. 284 /// Close region module.
285 /// </summary> 285 /// </summary>
286 public void Close() 286 public void Close()
287 { 287 {
288 m_enabled = false; 288 m_enabled = false;
289 m_cache.Clear(); 289 m_cache.Clear();
290 m_cache = null; 290 m_cache = null;
291 } 291 }
292 292
293 /// <summary> 293 /// <summary>
294 /// Initialize region module. 294 /// Initialize region module.
295 /// </summary> 295 /// </summary>
296 /// <param name="source"> 296 /// <param name="source">
297 /// Configuration source. 297 /// Configuration source.
298 /// </param> 298 /// </param>
299 public void Initialise( IConfigSource source ) 299 public void Initialise( IConfigSource source )
300 { 300 {
301 m_cache = null; 301 m_cache = null;
302 m_enabled = false; 302 m_enabled = false;
303 303
304 IConfig moduleConfig = source.Configs[ "Modules" ]; 304 IConfig moduleConfig = source.Configs[ "Modules" ];
305 if( moduleConfig == null ) 305 if( moduleConfig == null )
306 return; 306 return;
307 307
308 string name = moduleConfig.GetString( "AssetCaching" ); 308 string name = moduleConfig.GetString( "AssetCaching" );
309 Log.DebugFormat( "[XXX] name = {0} (this module's name: {1}", name, Name ); 309 Log.DebugFormat( "[XXX] name = {0} (this module's name: {1}", name, Name );
310 310
311 if( name != Name ) 311 if( name != Name )
312 return; 312 return;
313 313
314 // This module is used 314 // This module is used
315 long maxSize = DefaultMaxSize; 315 long maxSize = DefaultMaxSize;
316 int maxCount = DefaultMaxCount; 316 int maxCount = DefaultMaxCount;
317 TimeSpan expirationTime = DefaultExpirationTime; 317 TimeSpan expirationTime = DefaultExpirationTime;
318 318
319 IConfig assetConfig = source.Configs[ "AssetCache" ]; 319 IConfig assetConfig = source.Configs[ "AssetCache" ];
320 if( assetConfig != null ) 320 if( assetConfig != null )
321 { 321 {
322 // Get optional configurations 322 // Get optional configurations
323 maxSize = assetConfig.GetLong( "MaxSize", DefaultMaxSize ); 323 maxSize = assetConfig.GetLong( "MaxSize", DefaultMaxSize );
324 maxCount = assetConfig.GetInt( "MaxCount", DefaultMaxCount ); 324 maxCount = assetConfig.GetInt( "MaxCount", DefaultMaxCount );
325 expirationTime = 325 expirationTime =
326 TimeSpan.FromMinutes( assetConfig.GetInt( "ExpirationTime", (int) DefaultExpirationTime.TotalMinutes ) ); 326 TimeSpan.FromMinutes( assetConfig.GetInt( "ExpirationTime", (int) DefaultExpirationTime.TotalMinutes ) );
327 327
328 // Debugging purposes only 328 // Debugging purposes only
329 m_debugEpoch = assetConfig.GetInt( "DebugEpoch", 0 ); 329 m_debugEpoch = assetConfig.GetInt( "DebugEpoch", 0 );
330 } 330 }
331 331
332 Initialize( maxSize, maxCount, expirationTime ); 332 Initialize( maxSize, maxCount, expirationTime );
333 } 333 }
334 334
335 /// <summary> 335 /// <summary>
336 /// Initialization post handling. 336 /// Initialization post handling.
337 /// </summary> 337 /// </summary>
338 /// <remarks> 338 /// <remarks>
339 /// <para> 339 /// <para>
340 /// Modules can use this to initialize connection with other modules. 340 /// Modules can use this to initialize connection with other modules.
341 /// </para> 341 /// </para>
342 /// </remarks> 342 /// </remarks>
343 public void PostInitialise() 343 public void PostInitialise()
344 { 344 {
345 } 345 }
346 346
347 /// <summary> 347 /// <summary>
348 /// Region has been loaded. 348 /// Region has been loaded.
349 /// </summary> 349 /// </summary>
350 /// <param name="scene"> 350 /// <param name="scene">
351 /// Region's scene. 351 /// Region's scene.
352 /// </param> 352 /// </param>
353 /// <remarks> 353 /// <remarks>
354 /// <para> 354 /// <para>
355 /// This is needed for all module types. Modules will register 355 /// This is needed for all module types. Modules will register
356 /// Interfaces with scene in AddScene, and will also need a means 356 /// Interfaces with scene in AddScene, and will also need a means
357 /// to access interfaces registered by other modules. Without 357 /// to access interfaces registered by other modules. Without
358 /// this extra method, a module attempting to use another modules' 358 /// this extra method, a module attempting to use another modules'
359 /// interface would be successful only depending on load order, 359 /// interface would be successful only depending on load order,
360 /// which can't be depended upon, or modules would need to resort 360 /// which can't be depended upon, or modules would need to resort
361 /// to ugly kludges to attempt to request interfaces when needed 361 /// to ugly kludges to attempt to request interfaces when needed
362 /// and unnecessary caching logic repeated in all modules. 362 /// and unnecessary caching logic repeated in all modules.
363 /// The extra function stub is just that much cleaner. 363 /// The extra function stub is just that much cleaner.
364 /// </para> 364 /// </para>
365 /// </remarks> 365 /// </remarks>
366 public void RegionLoaded( Scene scene ) 366 public void RegionLoaded( Scene scene )
367 { 367 {
368 } 368 }
369 369
370 /// <summary> 370 /// <summary>
371 /// Region is being removed. 371 /// Region is being removed.
372 /// </summary> 372 /// </summary>
373 /// <param name="scene"> 373 /// <param name="scene">
374 /// Region scene that is being removed. 374 /// Region scene that is being removed.
375 /// </param> 375 /// </param>
376 public void RemoveRegion( Scene scene ) 376 public void RemoveRegion( Scene scene )
377 { 377 {
378 } 378 }
379 379
380 #endregion 380 #endregion
381 } 381 }
382} 382}