1 module des.flow.element;
2 
3 import des.util.arch.emm;
4 import des.util.logsys;
5 
6 import des.flow.event;
7 import des.flow.signal;
8 
9 /++
10 Inner interpret of thread
11 
12 action must be in:
13   * preparation               -> ctor
14   * last actions before start -> process special input event
15   * actions on pause          -> process special input event
16   * processing                -> process
17   * terminate all             -> selfDestroy( external memory manager )
18 +/
19 abstract class WorkElement : EventBus, SignalBus, ExternalMemoryManager
20 {
21     mixin EMM;
22     mixin ClassLogger;
23 
24 private:
25 
26     ///
27     SignalProcessor signal_processor;
28 
29     ///
30     EventProcessor event_listener;
31 
32 public:
33 
34     /// main work function
35     abstract void process();
36 
37     /// 
38     EventProcessor[] getEventProcessors() { return []; }
39 
40     ///
41     final void setEventListener( EventProcessor ep )
42     {
43         event_listener = ep;
44         logger.Debug( "set event listener [%s]", ep );
45     }
46 
47     /// push event to event listener if it exists
48     final void pushEvent( in Event ev )
49     {
50         logger.trace( "push event with code [%d] timestamp [%d] to listener [%s]", ev.code, ev.timestamp, event_listener );
51         if( event_listener !is null )
52             event_listener.processEvent( ev );
53     }
54 
55     ///
56     final void setSignalProcessor( SignalProcessor sp )
57     in { assert( sp !is null ); } body
58     {
59         signal_processor = sp;
60         logger.Debug( "set signal processor [%s]", sp );
61     }
62 
63     /// send signal to signal processor if it exists
64     final void sendSignal( in Signal sg )
65     {
66         logger.trace( "send signal [%s] to processor [%s]", sg, signal_processor );
67         if( signal_processor !is null )
68             signal_processor.processSignal( sg );
69     }
70 }
71 
72 ///
73 unittest
74 {
75     struct TestStruct { double x, y; string info; immutable(int)[] data; }
76     auto ts = TestStruct( 3.14, 2.7, "hello", [ 2, 3, 4 ] );
77 
78     class TestElement: WorkElement
79     {
80         override void process(){}
81     }
82 
83     class TestSignalProcessor : SignalProcessor 
84     { void processSignal( in Signal s ) { assert( s.code == 0 ); } }
85 
86     auto elem = new TestElement;
87     elem.setSignalProcessor( new TestSignalProcessor );
88 
89     elem.sendSignal( Signal(0) );
90 
91     size_t cnt = 0;
92     elem.setEventListener( new class EventProcessor {
93         void processEvent( in Event ev )
94         { cnt++; assert( ev.as!TestStruct == ts ); }
95         });
96 
97     auto ev = Event( 8, ts );
98     elem.pushEvent( ev );
99     elem.pushEvent( const Event( ev ) );
100     elem.pushEvent( shared Event( ev ) );
101     elem.pushEvent( immutable Event( ev ) );
102     elem.pushEvent( const shared Event( ev ) );
103     elem.pushEvent( shared const Event( ev ) );
104     elem.pushEvent( immutable shared Event( ev ) );
105     elem.pushEvent( shared immutable Event( ev ) );
106     assert( cnt == 8 );
107 }