Created
July 7, 2017 18:04
-
-
Save mikeseese/68ea5986be69c61c6a99baa9e55a7c99 to your computer and use it in GitHub Desktop.
Grim Reaper Helps Destroy Objects
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Threading; | |
using System.Collections.Generic; | |
using System.Linq; | |
using Assets.Game.Scripts.Network; | |
namespace Assets.Game.Scripts | |
{ | |
public class GrimReaper | |
{ | |
private static GrimReaper _instance; | |
#region SingletonConstructor | |
public static GrimReaper Instance | |
{ | |
get | |
{ | |
return _instance ?? (_instance = new GrimReaper()); | |
} | |
} | |
#endregion | |
private List<BuildableMapObject> _deathRow; | |
private List<BuildableMapObject> _executionLine; | |
private DateTime _executionTime; | |
private TimeSpan _executionGracePeriod; | |
private Mutex _deathRowLock; | |
private Mutex _summonLock; | |
private bool _isSummoned; | |
public GrimReaper() | |
{ | |
_deathRowLock = new Mutex(); | |
_summonLock = new Mutex(); | |
_isSummoned = false; | |
_executionGracePeriod = new TimeSpan(0, 0, GracePeriodSeconds); | |
_deathRow = new List<BuildableMapObject>(); | |
_executionLine = new List<BuildableMapObject>(); | |
} | |
public void QueueDeath(BuildableMapObject o, DateTime timeOfDeath) | |
{ | |
// Make sure we get the lock. We need to give the object its | |
// grace period fairly | |
_deathRowLock.WaitOne(); | |
_deathRow.Add(o); | |
_executionTime = timeOfDeath + _executionGracePeriod; | |
_deathRowLock.ReleaseMutex(); | |
} | |
public bool IsSummoned() | |
{ | |
return _isSummoned; | |
} | |
public void Summon() | |
{ | |
if(IsSummoned()) | |
{ | |
return; | |
} | |
// the grim reaper has got a job like everybody else! | |
// give him a break; he can't be in more than one | |
// place at at time | |
_isSummoned = true; | |
_summonLock.WaitOne(); | |
ThreadPool.QueueUserWorkItem(AnswerSummon); | |
} | |
private void AnswerSummon(Object stateInfo) | |
{ | |
if(_deathRow.Count > 0) | |
{ | |
while(Helpers.ServerUtcNow < _executionTime) | |
{ | |
TakeBreakUntil(_executionTime); | |
} | |
// Only those that have been fairly given a grace period can be killed | |
_deathRowLock.WaitOne(); | |
_executionLine = new List<BuildableMapObject>(_deathRow); | |
_deathRow.Clear(); | |
_deathRowLock.ReleaseMutex(); | |
Execute(_executionLine); | |
} | |
_summonLock.ReleaseMutex(); | |
_isSummoned = false; | |
} | |
private void TakeBreakUntil(DateTime clockInTime) | |
{ | |
Thread.Sleep(Convert.ToInt32((clockInTime - Helpers.ServerUtcNow).TotalMilliseconds)); | |
} | |
public void Execute(List<BuildableMapObject> executionLine) | |
{ | |
var message = executionLine.Select(t => t.Id).ToArray(); | |
// execute post-killing code | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment