Skip to content

Instantly share code, notes, and snippets.

@mikeseese
Created July 7, 2017 18:04
Show Gist options
  • Save mikeseese/68ea5986be69c61c6a99baa9e55a7c99 to your computer and use it in GitHub Desktop.
Save mikeseese/68ea5986be69c61c6a99baa9e55a7c99 to your computer and use it in GitHub Desktop.
Grim Reaper Helps Destroy Objects
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