Skip to content

Commit

Permalink
Merge branch 'feat/monad-completion-source' into 'develop'
Browse files Browse the repository at this point in the history
Monad completion source

See merge request engine/mast!9
  • Loading branch information
alvinsay committed Apr 27, 2020
2 parents 6f76653 + cfb6542 commit 45927cd
Show file tree
Hide file tree
Showing 3 changed files with 127 additions and 0 deletions.
41 changes: 41 additions & 0 deletions Assets/Plugins/Rayark/Mast/Editor/Tests/TestMonad.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Collections;
using System.Threading;
using NUnit.Framework;

namespace Rayark.Mast
Expand Down Expand Up @@ -659,5 +660,45 @@ public void FuncMonadTest2()
Assert.IsNotNull(m.Error);
Assert.AreEqual("ex", m.Error.Message);
}

[Test]
public void MonadCompletionSourceTest()
{
var mcs = new MonadCompletionSource<int>();
var m = mcs.Monad;

_MonadCompletionSourceTestTask1(mcs);
_Wait(m);
Assert.AreEqual(3, m.Result);
}

void _MonadCompletionSourceTestTask1(IReturn<int> r)
{
ThreadPool.QueueUserWorkItem( state =>
{
Thread.Sleep(500);
r.Accept(3);
});
}

[Test]
public void MonadCompletionSourceErrorTest()
{
var mcs = new MonadCompletionSource<int>();
var m = mcs.Monad;

_MonadCompletionSourceTestTask2(mcs);
_Wait(m);
Assert.AreEqual(typeof(ArgumentException), m.Error.GetType());
}

void _MonadCompletionSourceTestTask2(IReturn<int> r)
{
ThreadPool.QueueUserWorkItem( state =>
{
Thread.Sleep(500);
r.Fail(new ArgumentException());
});
}
}
}
75 changes: 75 additions & 0 deletions Assets/Plugins/Rayark/Mast/MonadCompletionSource.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
using System;
using System.Collections;

namespace Rayark.Mast
{
/// <summary>
/// Represents the producer side of a <see cref="IMonad{T}"/> unbound to a coroutine,
/// providing access to the consumer side through the Monad property.
/// </summary>
/// <typeparam name="T">The type of the result value associated with this <see cref="MonadCompletionSource{T}"/></typeparam>
public class MonadCompletionSource<T> : IReturn<T>
{

#region private types
private class InternalMonad : IMonad<T>, IEnumerator
{
public bool IsDone = false;

public T Result
{
get;
set;
}

public Exception Error
{
get;
set;
}
public IEnumerator Do()
{
return this;
}

public bool MoveNext()
{
return !IsDone;
}

public void Reset()
{
}

public object Current
{
get { return null; }
}
}
#endregion


readonly InternalMonad _monad = new InternalMonad();

public IMonad<T> Monad
{
get { return _monad; }
}

public void Accept(T result)
{
if (_monad.IsDone)
throw new System.Exception("Already done");
_monad.Result = result;
_monad.IsDone = true;
}

public void Fail(Exception error)
{
if (_monad.IsDone)
throw new System.Exception("Already done");
_monad.Error = error;
_monad.IsDone = true;
}
}
}
11 changes: 11 additions & 0 deletions Assets/Plugins/Rayark/Mast/MonadCompletionSource.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 45927cd

Please sign in to comment.