25 using System.Collections.Generic;
26 using System.Collections.Specialized;
27 using SiliconStudio.Core.Collections;
28 using SiliconStudio.Core.Diagnostics;
30 namespace SiliconStudio.
Paradox.Games
35 private readonly List<IGameSystemBase> pendingGameSystems;
36 private readonly List<KeyValuePair<IDrawable, ProfilingKey>> drawableGameSystems;
37 private readonly List<KeyValuePair<IUpdateable, ProfilingKey>> updateableGameSystems;
38 private readonly List<IContentable> contentableGameSystems;
39 private readonly List<IContentable> currentlyContentGameSystems;
40 private readonly List<KeyValuePair<IDrawable, ProfilingKey>> currentlyDrawingGameSystems;
41 private readonly List<KeyValuePair<IUpdateable, ProfilingKey>> currentlyUpdatingGameSystems;
42 private bool isFirstUpdateDone =
false;
46 drawableGameSystems =
new List<KeyValuePair<IDrawable, ProfilingKey>>();
47 currentlyContentGameSystems =
new List<IContentable>();
48 currentlyDrawingGameSystems =
new List<KeyValuePair<IDrawable, ProfilingKey>>();
49 pendingGameSystems =
new List<IGameSystemBase>();
50 updateableGameSystems =
new List<KeyValuePair<IUpdateable, ProfilingKey>>();
51 currentlyUpdatingGameSystems =
new List<KeyValuePair<IUpdateable, ProfilingKey>>();
52 contentableGameSystems =
new List<IContentable>();
55 CollectionChanged += GameSystems_CollectionChanged;
72 public bool IsFirstUpdateDone {
get {
return isFirstUpdateDone; } }
83 lock (updateableGameSystems)
85 foreach (var updateable
in updateableGameSystems)
87 currentlyUpdatingGameSystems.Add(updateable);
91 foreach (var updateable
in currentlyUpdatingGameSystems)
93 if (updateable.Key.Enabled)
95 using (Profiler.Begin(updateable.Value))
97 updateable.Key.Update(gameTime);
102 currentlyUpdatingGameSystems.Clear();
103 isFirstUpdateDone =
true;
115 lock (drawableGameSystems)
117 for (
int i = 0; i < drawableGameSystems.Count; i++)
119 currentlyDrawingGameSystems.Add(drawableGameSystems[i]);
123 for (
int i = 0; i < currentlyDrawingGameSystems.Count; i++)
125 var drawable = currentlyDrawingGameSystems[i];
126 if (drawable.Key.Visible)
128 using (Profiler.Begin(drawable.Value))
130 if (drawable.Key.BeginDraw())
132 drawable.Key.Draw(gameTime);
133 drawable.Key.EndDraw();
139 currentlyDrawingGameSystems.Clear();
149 throw new InvalidOperationException(
"Not initialized.");
152 State = GameSystemState.ContentLoaded;
154 lock (contentableGameSystems)
156 foreach (var contentable
in contentableGameSystems)
158 currentlyContentGameSystems.Add(contentable);
162 foreach (var contentable
in currentlyContentGameSystems)
164 using (var profile = Profiler.Begin(GameProfilingKeys.GameSystemLoadContent, GetGameSystemName(contentable)))
165 contentable.LoadContent();
168 currentlyContentGameSystems.Clear();
178 throw new InvalidOperationException(
"Not running.");
181 State = GameSystemState.Initialized;
183 lock (contentableGameSystems)
185 foreach (var contentable
in contentableGameSystems)
187 currentlyContentGameSystems.Add(contentable);
191 foreach (var contentable
in currentlyContentGameSystems)
193 contentable.UnloadContent();
196 currentlyContentGameSystems.Clear();
203 throw new InvalidOperationException(
"Already initialized.");
206 State = GameSystemState.Initialized;
208 InitializePendingGameSystems();
211 private void InitializePendingGameSystems()
214 while (pendingGameSystems.Count != 0)
216 var gameSystemName = GetGameSystemName(pendingGameSystems[0]);
217 using (var profile = Profiler.Begin(GameProfilingKeys.GameSystemInitialize, gameSystemName))
218 pendingGameSystems[0].Initialize();
221 var contentable = (IContentable)pendingGameSystems[0];
222 using (var profile = Profiler.Begin(GameProfilingKeys.GameSystemLoadContent, gameSystemName))
223 contentable.LoadContent();
226 pendingGameSystems.RemoveAt(0);
233 if (e.
Action == NotifyCollectionChangedAction.Add)
235 GameSystems_ItemAdded(sender, e);
237 else if (e.
Action == NotifyCollectionChangedAction.Remove)
239 GameSystems_ItemRemoved(sender, e);
245 var gameSystem = (IGameSystemBase)e.
Item;
250 gameSystem.Initialize();
255 pendingGameSystems.Add(gameSystem);
259 var contentableSystem = gameSystem as IContentable;
260 if (contentableSystem != null)
262 lock (contentableGameSystems)
264 if (!contentableGameSystems.Contains(contentableSystem))
266 contentableGameSystems.Add(contentableSystem);
272 contentableSystem.LoadContent();
277 var updateableGameSystem = gameSystem as IUpdateable;
278 if (updateableGameSystem != null && AddGameSystem(updateableGameSystem, updateableGameSystems, UpdateableComparer.Default, GameProfilingKeys.GameUpdate))
280 updateableGameSystem.UpdateOrderChanged += updateableGameSystem_UpdateOrderChanged;
284 var drawableGameSystem = gameSystem as IDrawable;
285 if (drawableGameSystem != null && AddGameSystem(drawableGameSystem, drawableGameSystems, DrawableComparer.Default, GameProfilingKeys.GameDraw))
287 drawableGameSystem.DrawOrderChanged += drawableGameSystem_DrawOrderChanged;
293 var gameSystem = (IGameSystemBase)e.
Item;
297 pendingGameSystems.Remove(gameSystem);
300 var contentableSystem = gameSystem as IContentable;
301 if (contentableSystem != null)
303 lock (contentableGameSystems)
305 contentableGameSystems.Remove(contentableSystem);
311 contentableSystem.UnloadContent();
315 var updateableSystem = gameSystem as IUpdateable;
316 if (updateableSystem != null)
318 lock (updateableGameSystems)
320 var key =
new KeyValuePair<IUpdateable, ProfilingKey>(updateableSystem, null);
321 updateableGameSystems.Remove(key);
324 updateableSystem.UpdateOrderChanged -= updateableGameSystem_UpdateOrderChanged;
327 var drawableSystem = gameSystem as IDrawable;
328 if (drawableSystem != null)
330 lock (drawableGameSystems)
332 var key =
new KeyValuePair<IDrawable, ProfilingKey>(drawableSystem, null);
333 drawableGameSystems.Remove(key);
336 drawableSystem.DrawOrderChanged -= drawableGameSystem_DrawOrderChanged;
340 private void updateableGameSystem_UpdateOrderChanged(
object sender,
EventArgs e)
342 AddGameSystem((IUpdateable)sender, updateableGameSystems, UpdateableComparer.Default, GameProfilingKeys.GameUpdate,
true);
345 private void drawableGameSystem_DrawOrderChanged(
object sender,
EventArgs e)
347 AddGameSystem((IDrawable)sender, drawableGameSystems, DrawableComparer.Default, GameProfilingKeys.GameDraw,
true);
355 var gameSystemKey =
new KeyValuePair<T, ProfilingKey>(gameSystem, null);
359 for (
int i = 0; i < gameSystems.Count; ++i)
361 if (gameSystem == gameSystems[i].Key)
370 if (removePreviousSystem)
372 gameSystemKey = gameSystems[index];
373 gameSystems.RemoveAt(index);
379 gameSystemKey =
new KeyValuePair<T, ProfilingKey>(gameSystemKey.Key,
new ProfilingKey(parentProfilingKey, gameSystem.GetType().Name));
385 index = gameSystems.UpperBound(gameSystemKey, comparer, 0, gameSystems.Count);
387 gameSystems.Insert(index, gameSystemKey);
398 private static string GetGameSystemName(
object gameSystem)
400 return gameSystem is IGameSystemBase ? ((IGameSystemBase)gameSystem).Name : gameSystem != null ? gameSystem.GetType().Name :
"null";
406 internal struct DrawableComparer :
IComparer<KeyValuePair<IDrawable, ProfilingKey>>
408 public static readonly DrawableComparer
Default =
new DrawableComparer();
410 public int Compare(KeyValuePair<IDrawable, ProfilingKey> leftValue, KeyValuePair<IDrawable, ProfilingKey> rightValue)
412 var left = leftValue.Key;
413 var right = rightValue.Key;
415 return left.DrawOrder.CompareTo(right.DrawOrder);
422 internal struct UpdateableComparer :
IComparer<KeyValuePair<IUpdateable, ProfilingKey>>
424 public static readonly UpdateableComparer
Default =
new UpdateableComparer();
426 public int Compare(KeyValuePair<IUpdateable, ProfilingKey> leftValue, KeyValuePair<IUpdateable, ProfilingKey> rightValue)
428 var left = leftValue.Key;
429 var right = rightValue.Key;
431 return left.UpdateOrder.CompareTo(right.UpdateOrder);
virtual void Update(GameTime gameTime)
Reference page contains links to related conceptual articles.
virtual void Draw(GameTime gameTime)
Reference page contains code sample.
virtual void UnloadContent()
Called when graphics resources need to be unloaded. Override this method to unload any game-specific ...
A key to identify a specific profile.
An interface to load and unload asset.
Use the default mode depending on the type of the field/property.
virtual void LoadContent()
Loads the content.
Current timing used for variable-step (real time) or fixed-step (game time) games.
object Item
Gets the added or removed item (if dictionary, value only).
NotifyCollectionChangedAction Action
Gets the type of action performed. Allowed values are NotifyCollectionChangedAction.Add and NotifyCollectionChangedAction.Remove.
A collection of game components.
GameSystemState
Describes state of the GameSystemCollection.