EventCore.cs 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Runtime.InteropServices;
  4. namespace AtomicEngine
  5. {
  6. public class VariantMap
  7. {
  8. public VariantMap(IntPtr native)
  9. {
  10. this.native = native;
  11. }
  12. public void Invalidate()
  13. {
  14. native = IntPtr.Zero;
  15. }
  16. void checkValid()
  17. {
  18. if (native == IntPtr.Zero)
  19. throw new System.AccessViolationException("Event data only valid during event");
  20. }
  21. public T Get<T>(string key) where T:RefCounted
  22. {
  23. checkValid ();
  24. // TODO: safe case
  25. IntPtr r = csb_Atomic_VariantMap_GetInstance (native, key);
  26. return r == IntPtr.Zero ? null : NativeCore.WrapNative<T> (r);
  27. }
  28. public int GetInt(string key)
  29. {
  30. checkValid ();
  31. return 0;
  32. }
  33. ~VariantMap()
  34. {
  35. }
  36. IntPtr native = default(IntPtr);
  37. [DllImport (Constants.LIBNAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
  38. private static extern IntPtr csb_Atomic_VariantMap_GetInstance(IntPtr native, string key);
  39. }
  40. public static class EventCore
  41. {
  42. class Subscription
  43. {
  44. public uint SenderRefID;
  45. public AtomicEventDelegate Handler;
  46. }
  47. // event type -> subscribers
  48. static Dictionary<uint, List<uint> > eventSubscribers = new Dictionary<uint, List<uint>>();
  49. static Dictionary<uint, Dictionary<uint, Subscription> > subscriptions = new Dictionary<uint, Dictionary<uint, Subscription> >();
  50. public static void SendEvent(AObject sender, string eventType)
  51. {
  52. csb_Atomic_AObject_SendEvent (sender.nativeInstance, eventType);
  53. }
  54. public static void SubscribeToEvent(AObject subscriber, AObject sender, string eventType, AtomicEventDelegate function)
  55. {
  56. var eventTypeID = Atomic.StringToStringHash (eventType);
  57. Dictionary<uint, Subscription> subs;
  58. if (!subscriptions.TryGetValue (subscriber.RefID, out subs)) {
  59. subs = new Dictionary<uint, Subscription> ();
  60. subscriptions [subscriber.RefID] = subs;
  61. }
  62. Subscription sub;
  63. if (!subs.TryGetValue (eventTypeID, out sub)) {
  64. sub = new Subscription ();
  65. subs [eventTypeID] = sub;
  66. }
  67. sub.SenderRefID = sender == null ? 0 : sender.RefID;
  68. sub.Handler = function;
  69. List<uint> subscribers;
  70. if (!eventSubscribers.TryGetValue (eventTypeID, out subscribers)) {
  71. subscribers = new List<uint> ();
  72. eventSubscribers [eventTypeID] = subscribers;
  73. }
  74. if (!subscribers.Contains (subscriber.RefID)) {
  75. subscribers.Add (subscriber.RefID);
  76. }
  77. }
  78. public static void BeginSendEvent(uint senderRefId, uint eventType, IntPtr eventData)
  79. {
  80. List<uint> subscribers;
  81. if (!eventSubscribers.TryGetValue (eventType, out subscribers)) {
  82. return;
  83. }
  84. if (subscribers.Count == 0) {
  85. return;
  86. }
  87. VariantMap vmap = new VariantMap (eventData);
  88. foreach (var id in subscribers) {
  89. Dictionary<uint, Subscription> subs;
  90. if (subscriptions.TryGetValue (id, out subs)) {
  91. Subscription sub;
  92. if (subs.TryGetValue (eventType, out sub)) {
  93. if (sub.SenderRefID == 0 || sub.SenderRefID == senderRefId) {
  94. sub.Handler (vmap);
  95. }
  96. }
  97. }
  98. }
  99. vmap.Invalidate ();
  100. }
  101. [DllImport (Constants.LIBNAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
  102. private static extern void csb_Atomic_AObject_SendEvent(IntPtr self, string eventType);
  103. }
  104. }