Merge pull request #174 from Mitch528/events

Expanded upon EventScheduler
This commit is contained in:
Drew DeVault 2015-06-26 12:41:45 -06:00
commit 43d2840171
5 changed files with 102 additions and 15 deletions

View File

@ -5,6 +5,7 @@ namespace TrueCraft.API.Server
public interface IEventScheduler
{
void ScheduleEvent(DateTime when, Action<IMultiplayerServer> action);
void Update();
void Start();
void Stop();
}
}

View File

@ -1,17 +1,23 @@
using System;
using TrueCraft.API.Server;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using TrueCraft.API.Logging;
namespace TrueCraft
{
public class EventScheduler : IEventScheduler
{
// TODO: This could be done more efficiently if the list were kept sorted
private IList<ScheduledEvent> Events { get; set; }
private List<ScheduledEvent> Events { get; set; }
private object EventLock = new object();
private IMultiplayerServer Server { get; set; }
private SemaphoreSlim Sem = new SemaphoreSlim(0, 1);
private CancellationTokenSource Cancel;
public EventScheduler(IMultiplayerServer server)
{
Events = new List<ScheduledEvent>();
@ -24,30 +30,99 @@ namespace TrueCraft
{
Events.Add(new ScheduledEvent { When = when, Action = action });
}
if (Sem.CurrentCount == 0)
Sem.Release();
}
public void Update()
public void Start()
{
lock (EventLock)
Cancel = new CancellationTokenSource();
Thread scheduleThread = new Thread(Update);
scheduleThread.IsBackground = true;
scheduleThread.Start();
}
public void Stop()
{
Cancel.Cancel();
}
private void Update()
{
while (true)
{
var start = DateTime.Now;
for (int i = 0; i < Events.Count; i++)
if (Cancel.IsCancellationRequested)
break;
try
{
var e = Events[i];
if (e.When <= start)
ScheduledEvent? nextEvent = null;
lock (EventLock)
{
e.Action(Server);
Events.RemoveAt(i);
i--;
var evts = Events.ToList();
evts.Sort();
DateTime now = DateTime.Now;
for (int i = 0; i < evts.Count; i++)
{
ScheduledEvent evt = evts[i];
if (evt.When < now)
break;
evts.RemoveAt(i);
i--;
evt.Action(Server);
}
if (evts.Count > 0)
nextEvent = evts.First();
Events = evts;
}
var tasks = new List<Task> { Sem.WaitAsync(Cancel.Token) };
if (nextEvent != null)
{
TimeSpan ts = nextEvent.Value.When - DateTime.Now;
if (ts < TimeSpan.Zero)
continue;
tasks.Add(Task.Delay(ts, Cancel.Token));
}
Task.WhenAny(tasks).Wait();
}
catch (OperationCanceledException)
{
return;
}
catch (Exception ex)
{
Server.Log(LogCategory.Error, "Scheduler Error", ex.ToString());
}
}
}
private struct ScheduledEvent
private struct ScheduledEvent : IComparable<ScheduledEvent>
{
public DateTime When;
public Action<IMultiplayerServer> Action;
public int CompareTo(ScheduledEvent other)
{
if (When > other.When)
return 1;
if (When == other.When)
return 0;
return -1;
}
}
}
}

View File

@ -113,6 +113,8 @@ namespace TrueCraft
Listener.Start();
EndPoint = (IPEndPoint)Listener.LocalEndpoint;
Scheduler.Start();
SocketAsyncEventArgs args = new SocketAsyncEventArgs();
args.Completed += AcceptClient;
@ -135,6 +137,8 @@ namespace TrueCraft
w.Save();
foreach (var c in Clients)
DisconnectClient(c);
Scheduler.Stop();
}
public void AddWorld(IWorld world)
@ -294,7 +298,6 @@ namespace TrueCraft
{
if (ShuttingDown)
return;
Scheduler.Update();
foreach (var manager in EntityManagers)
{
manager.Update();

View File

@ -9,6 +9,8 @@
<AssemblyName>TrueCraft</AssemblyName>
<ProductVersion>8.0.30703</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<Optimize>false</Optimize>
@ -16,11 +18,13 @@
<WarningLevel>4</WarningLevel>
<DebugSymbols>true</DebugSymbols>
<ConsolePause>false</ConsolePause>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<Optimize>false</Optimize>
<OutputPath>bin\Release</OutputPath>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
@ -75,6 +79,7 @@
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="app.config" />
<None Include="packages.config" />
</ItemGroup>
</Project>

3
TrueCraft/app.config Normal file
View File

@ -0,0 +1,3 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/></startup></configuration>