@@ -2,9 +2,9 @@ using System.Collections.Generic; | |||
namespace Svelto.ECS | |||
{ | |||
public class DispatcherOnChange<T> : DispatcherOnSet<T> | |||
public class DispatchOnChange<T> : DispatchOnSet<T> | |||
{ | |||
public DispatcherOnChange(int senderID) : base(senderID) | |||
public DispatchOnChange(int senderID) : base(senderID) | |||
{ } | |||
public new T value | |||
@@ -1,11 +1,13 @@ | |||
using BetterWeakEvents; | |||
namespace Svelto.ECS | |||
{ | |||
public class DispatcherOnSet<T> | |||
public class DispatchOnSet<T> | |||
{ | |||
public DispatcherOnSet(int senderID) | |||
public DispatchOnSet(int senderID) | |||
{ | |||
_senderID = senderID; | |||
_subscribers = new System.Collections.Generic.HashSet<WeakAction<int, T>>(); | |||
_subscribers = new WeakEvent<int, T>(); | |||
} | |||
public T value | |||
@@ -14,14 +16,7 @@ namespace Svelto.ECS | |||
{ | |||
_value = value; | |||
if (_subscribers != null) | |||
{ | |||
using (var enumerator = _subscribers.GetEnumerator()) | |||
{ | |||
while (enumerator.MoveNext() == true) | |||
enumerator.Current.Invoke(_senderID, _value); | |||
} | |||
} | |||
_subscribers.Invoke(_senderID, value); | |||
} | |||
get | |||
@@ -30,19 +25,19 @@ namespace Svelto.ECS | |||
} | |||
} | |||
public void NotifyOnDataChange(System.Action<int, T> action) | |||
public void NotifyOnValueSet(System.Action<int, T> action) | |||
{ | |||
_subscribers.Add(new WeakAction<int, T>(action)); | |||
_subscribers += action; | |||
} | |||
public void StopNotifyOnDataChange(System.Action<int, T> action) | |||
public void StopNotify(System.Action<int, T> action) | |||
{ | |||
_subscribers.Remove(new WeakAction<int, T>(action)); | |||
_subscribers -= action; | |||
} | |||
protected T _value; | |||
protected int _senderID; | |||
protected System.Collections.Generic.HashSet<WeakAction<int, T>> _subscribers; | |||
protected WeakEvent<int, T> _subscribers; | |||
} | |||
} |
@@ -0,0 +1,127 @@ | |||
namespace Svelto.ECS | |||
{ | |||
class GenericEntityDescriptor<T> : EntityDescriptor | |||
where T : NodeWithID, new() | |||
{ | |||
static GenericEntityDescriptor() | |||
{ | |||
_nodesToBuild = new INodeBuilder[] | |||
{ | |||
new NodeBuilder<T>() | |||
}; | |||
} | |||
public GenericEntityDescriptor(params object[] componentsImplementor) : base(_nodesToBuild, componentsImplementor) | |||
{ | |||
} | |||
static INodeBuilder[] _nodesToBuild; | |||
} | |||
class GenericEntityDescriptor<T, U> : EntityDescriptor | |||
where T : NodeWithID, new() | |||
where U : NodeWithID, new() | |||
{ | |||
static GenericEntityDescriptor() | |||
{ | |||
_nodesToBuild = new INodeBuilder[] | |||
{ | |||
new NodeBuilder<T>(), | |||
new NodeBuilder<U>() | |||
}; | |||
} | |||
public GenericEntityDescriptor(params object[] componentsImplementor) : base(_nodesToBuild, componentsImplementor) | |||
{ | |||
} | |||
static INodeBuilder[] _nodesToBuild; | |||
} | |||
class GenericEntityDescriptor<T, U, V> : EntityDescriptor | |||
where T : NodeWithID, new() | |||
where U : NodeWithID, new() | |||
where V : NodeWithID, new() | |||
{ | |||
static GenericEntityDescriptor() | |||
{ | |||
_nodesToBuild = new INodeBuilder[] | |||
{ | |||
new NodeBuilder<T>(), | |||
new NodeBuilder<U>(), | |||
new NodeBuilder<V>() | |||
}; | |||
} | |||
public GenericEntityDescriptor(params object[] componentsImplementor) : base(_nodesToBuild, componentsImplementor) | |||
{ | |||
} | |||
static INodeBuilder[] _nodesToBuild; | |||
} | |||
class GenericEntityDescriptor<T, U, V, W> : EntityDescriptor | |||
where T : NodeWithID, new() | |||
where U : NodeWithID, new() | |||
where V : NodeWithID, new() | |||
where W : NodeWithID, new() | |||
{ | |||
static GenericEntityDescriptor() | |||
{ | |||
_nodesToBuild = new INodeBuilder[] | |||
{ | |||
new NodeBuilder<T>(), | |||
new NodeBuilder<U>(), | |||
new NodeBuilder<V>(), | |||
new NodeBuilder<W>() | |||
}; | |||
} | |||
public GenericEntityDescriptor(params object[] componentsImplementor) : base(_nodesToBuild, componentsImplementor) | |||
{ | |||
} | |||
static INodeBuilder[] _nodesToBuild; | |||
} | |||
class GenericEntityDescriptor<T, U, V, W, X> : EntityDescriptor | |||
where T : NodeWithID, new() | |||
where U : NodeWithID, new() | |||
where V : NodeWithID, new() | |||
where W : NodeWithID, new() | |||
where X : NodeWithID, new() | |||
{ | |||
static GenericEntityDescriptor() | |||
{ | |||
_nodesToBuild = new INodeBuilder[] | |||
{ | |||
new NodeBuilder<T>(), | |||
new NodeBuilder<U>(), | |||
new NodeBuilder<V>(), | |||
new NodeBuilder<W>(), | |||
new NodeBuilder<X>() | |||
}; | |||
} | |||
public GenericEntityDescriptor(params object[] componentsImplementor) : base(_nodesToBuild, componentsImplementor) | |||
{ | |||
} | |||
static INodeBuilder[] _nodesToBuild; | |||
} | |||
class GenericEntityDescriptor<T, U, V, W, X, Y> : EntityDescriptor | |||
where T : NodeWithID, new() | |||
where U : NodeWithID, new() | |||
where V : NodeWithID, new() | |||
where W : NodeWithID, new() | |||
where X : NodeWithID, new() | |||
where Y : NodeWithID, new() | |||
{ | |||
static GenericEntityDescriptor() | |||
{ | |||
_nodesToBuild = new INodeBuilder[] | |||
{ | |||
new NodeBuilder<T>(), | |||
new NodeBuilder<U>(), | |||
new NodeBuilder<V>(), | |||
new NodeBuilder<W>(), | |||
new NodeBuilder<X>(), | |||
new NodeBuilder<Y>() | |||
}; | |||
} | |||
public GenericEntityDescriptor(params object[] componentsImplementor) : base(_nodesToBuild, componentsImplementor) | |||
{ | |||
} | |||
static INodeBuilder[] _nodesToBuild; | |||
} | |||
} |
@@ -1,6 +1,6 @@ | |||
fileFormatVersion: 2 | |||
guid: eaffccbdbcacfa449b997dc1f7181bb4 | |||
timeCreated: 1461942385 | |||
guid: fd70d1b3107162f4790b1b71a129818f | |||
timeCreated: 1484485852 | |||
licenseType: Pro | |||
MonoImporter: | |||
serializedVersion: 2 |
@@ -0,0 +1,52 @@ | |||
using System; | |||
using Steps = System.Collections.Generic.Dictionary<Svelto.ECS.IEngine, System.Collections.Generic.Dictionary<System.Enum, Svelto.ECS.IStep[]>>; | |||
namespace Svelto.ECS | |||
{ | |||
public interface IStep | |||
{ } | |||
public interface IStep<T>:IStep | |||
{ | |||
void Step(ref T token, Enum condition); | |||
} | |||
public class Sequencer | |||
{ | |||
public Sequencer() | |||
{} | |||
public void SetSequence(Steps steps) | |||
{ | |||
_steps = steps; | |||
} | |||
public void Next<T>(IEngine engine, ref T param) | |||
{ | |||
Next(engine, ref param, Condition.always); | |||
} | |||
public void Next<T>(IEngine engine, ref T param, Enum condition) | |||
{ | |||
var tos = _steps[engine]; | |||
var steps = tos[condition]; | |||
if (steps != null) | |||
for (int i = 0; i < steps.Length; i++) | |||
((IStep<T>)steps[i]).Step(ref param, condition); | |||
} | |||
Steps _steps; | |||
} | |||
public enum Condition | |||
{ | |||
always | |||
} | |||
public enum DamageCondition | |||
{ | |||
damage, | |||
dead | |||
} | |||
} |
@@ -0,0 +1,12 @@ | |||
fileFormatVersion: 2 | |||
guid: 4e1f40937ca5027428ed7193729be1a5 | |||
timeCreated: 1484487023 | |||
licenseType: Pro | |||
MonoImporter: | |||
serializedVersion: 2 | |||
defaultReferences: [] | |||
executionOrder: 0 | |||
icon: {instanceID: 0} | |||
userData: | |||
assetBundleName: | |||
assetBundleVariant: |
@@ -12,7 +12,9 @@ | |||
Remove(obj as TNodeType); | |||
} | |||
protected abstract void Add(TNodeType node); | |||
protected abstract void Remove(TNodeType node); | |||
protected virtual void Add(TNodeType node) | |||
{} | |||
protected virtual void Remove(TNodeType node) | |||
{} | |||
} | |||
} |
@@ -1,99 +0,0 @@ | |||
using System; | |||
using System.Reflection; | |||
using System.Runtime.CompilerServices; | |||
using System.Runtime.InteropServices; | |||
public struct WeakAction<T1, T2>:IEquatable<WeakAction<T1, T2>> | |||
{ | |||
public WeakAction(Action<T1, T2> listener) | |||
{ | |||
ObjectRef = GCHandle.Alloc(listener.Target, GCHandleType.Weak); | |||
Method = listener.Method; | |||
if (Method.DeclaringType.GetCustomAttributes(typeof(CompilerGeneratedAttribute), false).Length != 0) | |||
throw new ArgumentException("Cannot create weak event to anonymous method with closure."); | |||
} | |||
public bool Invoke(T1 data1, T2 data2) | |||
{ | |||
if (ObjectRef.IsAllocated && ObjectRef.Target != null) | |||
{ | |||
Method.Invoke(ObjectRef.Target, new object[] { data1, data2 }); | |||
return true; | |||
} | |||
return false; | |||
} | |||
public bool Equals(WeakAction<T1, T2> other) | |||
{ | |||
return (Method.Equals(other.Method)); | |||
} | |||
readonly GCHandle ObjectRef; | |||
readonly MethodInfo Method; | |||
} | |||
public struct WeakAction<T>:IEquatable<WeakAction<T>> | |||
{ | |||
public WeakAction(Action<T> listener) | |||
{ | |||
ObjectRef = GCHandle.Alloc(listener.Target, GCHandleType.Weak); | |||
Method = listener.Method; | |||
if (Method.DeclaringType.GetCustomAttributes(typeof(CompilerGeneratedAttribute), false).Length != 0) | |||
throw new ArgumentException("Cannot create weak event to anonymous method with closure."); | |||
} | |||
public bool Invoke(T data) | |||
{ | |||
if (ObjectRef.IsAllocated && ObjectRef.Target != null) | |||
{ | |||
Method.Invoke(ObjectRef.Target, new object[] { data }); | |||
return true; | |||
} | |||
return false; | |||
} | |||
public bool Equals(WeakAction<T> other) | |||
{ | |||
return (Method.Equals(other.Method)); | |||
} | |||
readonly GCHandle ObjectRef; | |||
readonly MethodInfo Method; | |||
} | |||
public struct WeakAction:IEquatable<WeakAction> | |||
{ | |||
public WeakAction(Action listener) | |||
{ | |||
ObjectRef = GCHandle.Alloc(listener.Target, GCHandleType.Weak); | |||
Method = listener.Method; | |||
if (Method.DeclaringType.GetCustomAttributes(typeof(CompilerGeneratedAttribute), false).Length != 0) | |||
throw new ArgumentException("Cannot create weak event to anonymous method with closure."); | |||
} | |||
public bool Invoke() | |||
{ | |||
if (ObjectRef.IsAllocated && ObjectRef.Target != null) | |||
{ | |||
Method.Invoke(ObjectRef.Target, null); | |||
return true; | |||
} | |||
return false; | |||
} | |||
public bool Equals(WeakAction other) | |||
{ | |||
return (Method.Equals(other.Method)); | |||
} | |||
readonly GCHandle ObjectRef; | |||
readonly MethodInfo Method; | |||
} | |||
@@ -0,0 +1,122 @@ | |||
using System; | |||
using System.Reflection; | |||
using System.Runtime.CompilerServices; | |||
using System.Runtime.InteropServices; | |||
//careful, you must handle the destruction of the GCHandles! | |||
namespace BetterWeakEvents | |||
{ | |||
public struct WeakAction<T1, T2> : IEquatable<WeakAction<T1, T2>> | |||
{ | |||
public WeakAction(Action<T1, T2> listener) | |||
{ | |||
ObjectRef = GCHandle.Alloc(listener.Target, GCHandleType.Weak); | |||
Method = listener.Method; | |||
if (Method.DeclaringType.GetCustomAttributes(typeof(CompilerGeneratedAttribute), false).Length != 0) | |||
throw new ArgumentException("Cannot create weak event to anonymous method with closure."); | |||
} | |||
public bool Invoke(T1 data1, T2 data2) | |||
{ | |||
if (ObjectRef.IsAllocated && ObjectRef.Target != null) | |||
{ | |||
Method.Invoke(ObjectRef.Target, new object[] { data1, data2 }); | |||
return true; | |||
} | |||
Release(); | |||
return false; | |||
} | |||
public bool Equals(WeakAction<T1, T2> other) | |||
{ | |||
return (Method.Equals(other.Method)); | |||
} | |||
public void Release() | |||
{ | |||
ObjectRef.Free(); | |||
} | |||
readonly GCHandle ObjectRef; | |||
readonly MethodInfo Method; | |||
} | |||
public struct WeakAction<T> : IEquatable<WeakAction<T>> | |||
{ | |||
public WeakAction(Action<T> listener) | |||
{ | |||
ObjectRef = GCHandle.Alloc(listener.Target, GCHandleType.Weak); | |||
Method = listener.Method; | |||
if (Method.DeclaringType.GetCustomAttributes(typeof(CompilerGeneratedAttribute), false).Length != 0) | |||
throw new ArgumentException("Cannot create weak event to anonymous method with closure."); | |||
} | |||
public bool Invoke(T data) | |||
{ | |||
if (ObjectRef.IsAllocated && ObjectRef.Target != null) | |||
{ | |||
Method.Invoke(ObjectRef.Target, new object[] { data }); | |||
return true; | |||
} | |||
Release(); | |||
return false; | |||
} | |||
public bool Equals(WeakAction<T> other) | |||
{ | |||
return (Method.Equals(other.Method)); | |||
} | |||
public void Release() | |||
{ | |||
ObjectRef.Free(); | |||
} | |||
readonly GCHandle ObjectRef; | |||
readonly MethodInfo Method; | |||
} | |||
public struct WeakAction : IEquatable<WeakAction> | |||
{ | |||
public WeakAction(Action listener) | |||
{ | |||
ObjectRef = GCHandle.Alloc(listener.Target, GCHandleType.Weak); | |||
Method = listener.Method; | |||
if (Method.DeclaringType.GetCustomAttributes(typeof(CompilerGeneratedAttribute), false).Length != 0) | |||
throw new ArgumentException("Cannot create weak event to anonymous method with closure."); | |||
} | |||
public bool Invoke() | |||
{ | |||
if (ObjectRef.IsAllocated && ObjectRef.Target != null) | |||
{ | |||
Method.Invoke(ObjectRef.Target, null); | |||
return true; | |||
} | |||
Release(); | |||
return false; | |||
} | |||
public bool Equals(WeakAction other) | |||
{ | |||
return (Method.Equals(other.Method)); | |||
} | |||
public void Release() | |||
{ | |||
ObjectRef.Free(); | |||
} | |||
readonly GCHandle ObjectRef; | |||
readonly MethodInfo Method; | |||
} | |||
} |
@@ -0,0 +1,12 @@ | |||
fileFormatVersion: 2 | |||
guid: 1662357721652524593d7b0f731aef45 | |||
timeCreated: 1484483913 | |||
licenseType: Pro | |||
MonoImporter: | |||
serializedVersion: 2 | |||
defaultReferences: [] | |||
executionOrder: 0 | |||
icon: {instanceID: 0} | |||
userData: | |||
assetBundleName: | |||
assetBundleVariant: |
@@ -0,0 +1,35 @@ | |||
using Svelto.DataStructures; | |||
using System; | |||
namespace BetterWeakEvents | |||
{ | |||
public class WeakEvent<T1, T2> | |||
{ | |||
public static WeakEvent<T1, T2> operator+(WeakEvent<T1, T2> c1, Action<T1, T2> x) | |||
{ | |||
c1._subscribers.Add(new WeakAction<T1, T2>(x)); | |||
return c1; | |||
} | |||
public static WeakEvent<T1, T2> operator-(WeakEvent<T1, T2> c1, Action<T1, T2> x) | |||
{ | |||
c1._subscribers.UnorderredRemove(new WeakAction<T1, T2>(x)); | |||
return c1; | |||
} | |||
public void Invoke(T1 arg1, T2 arg2) | |||
{ | |||
for (int i = 0; i < _subscribers.Count; i++) | |||
if (_subscribers[i].Invoke(arg1, arg2) == false) | |||
_subscribers.UnorderredRemoveAt(i--); | |||
} | |||
~WeakEvent() | |||
{ | |||
for (int i = 0; i < _subscribers.Count; i++) | |||
_subscribers[i].Release(); | |||
} | |||
protected FasterList<WeakAction<T1, T2>> _subscribers = new FasterList<WeakAction<T1, T2>>(); | |||
} | |||
} |
@@ -0,0 +1,12 @@ | |||
fileFormatVersion: 2 | |||
guid: e2ee3763e7dffd4459c588eda6867ddd | |||
timeCreated: 1484480295 | |||
licenseType: Pro | |||
MonoImporter: | |||
serializedVersion: 2 | |||
defaultReferences: [] | |||
executionOrder: 0 | |||
icon: {instanceID: 0} | |||
userData: | |||
assetBundleName: | |||
assetBundleVariant: |