Permalink
Browse files

Publish/subscribe design pattern

Added code for the publish/subscribe design pattern
  • Loading branch information...
1 parent d0e21b1 commit f5399e811d825c241882d4d309b8e5e674c21814 @ScottLilly committed Dec 30, 2016
View
@@ -93,6 +93,16 @@
<Compile Include="PrototypePattern\PatternVersion_Complex\LootTableEntry.cs" />
<Compile Include="PrototypePattern\PatternVersion_Complex\Monster.cs" />
<Compile Include="PrototypePattern\PatternVersion_Simple\Monster.cs" />
+ <Compile Include="PublishSubscribePattern\NonPatternVersion\Models\Location.cs" />
+ <Compile Include="PublishSubscribePattern\NonPatternVersion\Models\Player.cs" />
+ <Compile Include="PublishSubscribePattern\NonPatternVersion\ViewModels\GameSession.cs" />
+ <Compile Include="PublishSubscribePattern\PatternVersion\Models\Location.cs" />
+ <Compile Include="PublishSubscribePattern\PatternVersion\Models\Player.cs" />
+ <Compile Include="PublishSubscribePattern\PatternVersion\ViewModels\GameSession.cs" />
+ <Compile Include="PublishSubscribePattern\PatternVersion_CustomEventArgs\Common\PlayerKilledEventArgs.cs" />
+ <Compile Include="PublishSubscribePattern\PatternVersion_CustomEventArgs\Models\Location.cs" />
+ <Compile Include="PublishSubscribePattern\PatternVersion_CustomEventArgs\Models\Player.cs" />
+ <Compile Include="PublishSubscribePattern\PatternVersion_CustomEventArgs\ViewModels\GameSession.cs" />
<Compile Include="SingletonPattern\NonPatternVersion\Customer.cs" />
<Compile Include="SingletonPattern\NonPatternVersion\Logger.cs" />
<Compile Include="SingletonPattern\PatternVersion_DoubleLock\Logger.cs" />
@@ -119,6 +129,7 @@
<Content Include="LICENSE.txt" />
<Content Include="MementoPattern\READ_ME.txt" />
<Content Include="PrototypePattern\READ_ME.txt" />
+ <Content Include="PublishSubscribePattern\READ_ME.txt" />
<Content Include="READ_ME.txt" />
<Content Include="SingletonPattern\READ_ME.txt" />
<Content Include="StrategyPattern\READ_ME.txt" />
@@ -0,0 +1,13 @@
+namespace Engine.PublishSubscribePattern.NonPatternVersion.Models
+{
+ public class Location
+ {
+ public enum AtmosphereType
+ {
+ Normal,
+ Poisonous
+ }
+
+ public AtmosphereType Atmosphere { get; set; }
+ }
+}
@@ -0,0 +1,7 @@
+namespace Engine.PublishSubscribePattern.NonPatternVersion.Models
+{
+ public class Player
+ {
+ public int HitPoints { get; set; }
+ }
+}
@@ -0,0 +1,47 @@
+using System.Collections.Generic;
+using Engine.PublishSubscribePattern.NonPatternVersion.Models;
+
+namespace Engine.PublishSubscribePattern.NonPatternVersion.ViewModels
+{
+ public class GameSession
+ {
+ public List<string> Messages { get; set; }
+ public Player CurrentPlayer { get; set; }
+ public Location CurrentLocation { get; set; }
+
+ public GameSession()
+ {
+ Messages = new List<string>();
+
+ CurrentPlayer = new Player {HitPoints = 10};
+ CurrentLocation = new Location {Atmosphere = Location.AtmosphereType.Normal};
+ }
+
+ public void MonsterAttackPlayer(int amountOfDamage)
+ {
+ CurrentPlayer.HitPoints -= amountOfDamage;
+
+ CheckIfPlayerWasKilled();
+ }
+
+ public void MoveToLocation(Location location)
+ {
+ CurrentLocation = location;
+
+ if(CurrentLocation.Atmosphere == Location.AtmosphereType.Poisonous)
+ {
+ CurrentPlayer.HitPoints -= 1;
+
+ CheckIfPlayerWasKilled();
+ }
+ }
+
+ private void CheckIfPlayerWasKilled()
+ {
+ if(CurrentPlayer.HitPoints <= 0)
+ {
+ Messages.Add("You were killed");
+ }
+ }
+ }
+}
@@ -0,0 +1,13 @@
+namespace Engine.PublishSubscribePattern.PatternVersion.Models
+{
+ public class Location
+ {
+ public enum AtmosphereType
+ {
+ Normal,
+ Poisonous
+ }
+
+ public AtmosphereType Atmosphere { get; set; }
+ }
+}
@@ -0,0 +1,35 @@
+using System;
+
+namespace Engine.PublishSubscribePattern.PatternVersion.Models
+{
+ public class Player
+ {
+ private int _hitPoints;
+
+ public EventHandler PlayerKilled;
+
+ public int HitPoints
+ {
+ get { return _hitPoints; }
+ set
+ {
+ _hitPoints = value;
+
+ if(_hitPoints <= 0)
+ {
+ // When the player's HitPoint property is zero, or lower,
+ // the player object will raise a PlayerKilled notification to all subscribed objects.
+ OnPlayerKilled();
+ }
+ }
+ }
+
+ private void OnPlayerKilled()
+ {
+ // If there are no subscribed objects,
+ // the PlayerKilled EventHandler will be null,
+ // and nothing will be notified of this event.
+ PlayerKilled?.Invoke(this, EventArgs.Empty);
+ }
+ }
+}
@@ -0,0 +1,47 @@
+using System;
+using System.Collections.Generic;
+using Engine.PublishSubscribePattern.PatternVersion.Models;
+
+namespace Engine.PublishSubscribePattern.PatternVersion.ViewModels
+{
+ public class GameSession
+ {
+ public List<string> Messages { get; set; }
+ public Player CurrentPlayer { get; set; }
+ public Location CurrentLocation { get; set; }
+
+ public GameSession()
+ {
+ Messages = new List<string>();
+
+ CurrentPlayer = new Player {HitPoints = 10};
+ CurrentLocation = new Location {Atmosphere = Location.AtmosphereType.Normal};
+
+ // "Subscribe" to the PlayerKilled event.
+ //
+ // When the GameSession object receives this notification,
+ // it will run the HandlePlayerKilled function.
+ CurrentPlayer.PlayerKilled += HandlePlayerKilled;
+ }
+
+ public void MonsterAttackPlayer(int amountOfDamage)
+ {
+ CurrentPlayer.HitPoints -= amountOfDamage;
+ }
+
+ public void MoveToLocation(Location location)
+ {
+ CurrentLocation = location;
+
+ if(CurrentLocation.Atmosphere == Location.AtmosphereType.Poisonous)
+ {
+ CurrentPlayer.HitPoints -= 1;
+ }
+ }
+
+ private void HandlePlayerKilled(object sender, EventArgs eventArgs)
+ {
+ Messages.Add("You were killed");
+ }
+ }
+}
@@ -0,0 +1,14 @@
+using System;
+
+namespace Engine.PublishSubscribePattern.PatternVersion_CustomEventArgs.Common
+{
+ public class PlayerKilledEventArgs : EventArgs
+ {
+ public int NumberOfDeaths { get; private set; }
+
+ public PlayerKilledEventArgs(int numberOfDeaths)
+ {
+ NumberOfDeaths = numberOfDeaths;
+ }
+ }
+}
@@ -0,0 +1,13 @@
+namespace Engine.PublishSubscribePattern.PatternVersion_CustomEventArgs.Models
+{
+ public class Location
+ {
+ public enum AtmosphereType
+ {
+ Normal,
+ Poisonous
+ }
+
+ public AtmosphereType Atmosphere { get; set; }
+ }
+}
@@ -0,0 +1,37 @@
+using System;
+using Engine.PublishSubscribePattern.PatternVersion_CustomEventArgs.Common;
+
+namespace Engine.PublishSubscribePattern.PatternVersion_CustomEventArgs.Models
+{
+ public class Player
+ {
+ private int _hitPoints;
+ private int _numberOfDeaths;
+
+ public EventHandler<PlayerKilledEventArgs> PlayerKilled;
+
+ public int HitPoints
+ {
+ get { return _hitPoints; }
+ set
+ {
+ _hitPoints = value;
+
+ if(_hitPoints <= 0)
+ {
+ // Increase the "number of deaths" counter.
+ _numberOfDeaths++;
+
+ // When the player's HitPoint property is zero, or lower,
+ // the player object will raise a PlayerKilled notification to all subscribed objects.
+ OnPlayerKilled();
+ }
+ }
+ }
+
+ protected virtual void OnPlayerKilled()
+ {
+ PlayerKilled?.Invoke(this, new PlayerKilledEventArgs(_numberOfDeaths));
+ }
+ }
+}
@@ -0,0 +1,48 @@
+using System.Collections.Generic;
+using Engine.PublishSubscribePattern.PatternVersion_CustomEventArgs.Common;
+using Engine.PublishSubscribePattern.PatternVersion_CustomEventArgs.Models;
+
+namespace Engine.PublishSubscribePattern.PatternVersion_CustomEventArgs.ViewModels
+{
+ public class GameSession
+ {
+ public List<string> Messages { get; set; }
+ public Player CurrentPlayer { get; set; }
+ public Location CurrentLocation { get; set; }
+
+ public GameSession()
+ {
+ Messages = new List<string>();
+
+ CurrentPlayer = new Player {HitPoints = 10};
+ CurrentLocation = new Location {Atmosphere = Location.AtmosphereType.Normal};
+
+ // "Subscribe" to the PlayerKilled event.
+ //
+ // When the GameSession object receives this notification,
+ // it will run the HandlePlayerKilled function.
+ CurrentPlayer.PlayerKilled += HandlePlayerKilled;
+ }
+
+ public void MonsterAttackPlayer(int amountOfDamage)
+ {
+ CurrentPlayer.HitPoints -= amountOfDamage;
+ }
+
+ public void MoveToLocation(Location location)
+ {
+ CurrentLocation = location;
+
+ if(CurrentLocation.Atmosphere == Location.AtmosphereType.Poisonous)
+ {
+ CurrentPlayer.HitPoints -= 1;
+ }
+ }
+
+ private void HandlePlayerKilled(object sender, PlayerKilledEventArgs eventArgs)
+ {
+ Messages.Add("You were killed");
+ Messages.Add($"This was death number: {eventArgs.NumberOfDeaths}");
+ }
+ }
+}
@@ -0,0 +1,7 @@
+Publish/Subscribe Design Pattern
+
+Allows an object to notify any interested objects, when specific events happen to the object (e.g., values change)
+
+Website URL: http://scottlilly.com/c-design-pattern-publishsubscribe/
+
+YouTube video URL: https://www.youtube.com/watch?v=D83e-GM_EnI
@@ -81,6 +81,7 @@
</ItemGroup>
<ItemGroup>
<Folder Include="DataMapperPattern\" />
+ <Folder Include="PublishSubscribePattern\" />
</ItemGroup>
<Choose>
<When Condition="'$(VisualStudioVersion)' == '10.0' And '$(IsCodedUITest)' == 'True'">

0 comments on commit f5399e8

Please sign in to comment.