1 module eventmanager.abstractevent;
2 
3 import std.datetime;
4 import std.variant;
5 import std.exception;
6 import std.stdio;
7 
8 import eventmanager.eventinterface;
9 
10 struct EventLifecycle
11 {
12     long eventCreated;
13     long eventReceived;
14     long eventDispatched;
15     long eventProcessingTime;   // How long the event took to be fully processed.
16 }
17 
18 abstract class AbstractEvent(T) : EventInterface
19 {
20     protected EventLifecycle lifecycle;
21     protected T metadata;
22 
23     this(T metadata) @safe {
24         //this.timestamp = Clock.currTime().toUnixTime();
25         this.lifecycle.eventCreated = Clock.currStdTime();
26         this.metadata = metadata;
27     }
28 
29     public EventLifecycle getLifecycle() @safe
30     {
31         return this.lifecycle;
32     }
33 
34     public Variant getMetadata()
35     {
36         return cast(Variant)this.metadata;
37     }
38 
39     public void setEventReceived() @safe
40     {
41         this.lifecycle.eventReceived = Clock.currStdTime();
42     }
43 
44     public void setEventDispatched() @safe in {
45         enforce(this.lifecycle.eventReceived > 0, "Event must be flagged as being received BEFORE being dispatched");
46     } body {
47         this.lifecycle.eventDispatched = Clock.currStdTime();
48         this.lifecycle.eventProcessingTime = this.lifecycle.eventDispatched - this.lifecycle.eventCreated;
49     }
50 }
51 
52 unittest {
53     struct EventTestMetadata
54     {
55         int id;
56         string name;
57     }
58         
59     class TestEvent : AbstractEvent!EventTestMetadata
60     {
61         this(EventTestMetadata metadata)
62         {
63             super(metadata);
64         }
65     }
66 
67     EventTestMetadata metadata;
68     metadata.id = 1;
69     metadata.name = "Jane Doe";
70     
71     // Test instantiating an event
72     auto testEvent = new TestEvent(metadata);
73 
74     // Ensure the lifecycle created time has been set
75     auto lifeCycle = testEvent.getLifecycle();
76     assert(lifeCycle.eventCreated > 0);
77 
78     // Ensure we can get the event metadata back correctly
79     auto meta = testEvent.getMetadata();
80     assert(meta.type == typeid(EventTestMetadata));
81     EventTestMetadata metaEventTest = *meta.peek!(EventTestMetadata);
82     assert(metaEventTest.id == 1);
83     assert(metaEventTest.name == "Jane Doe");
84 }