1////////////////////////////////////////////////////////////////////////////////
2// //
3// This software is supplied under the terms of a license agreement or //
4// nondisclosure agreement with Mitov Software and may not be copied //
5// or disclosed except in accordance with the terms of that agreement. //
6// Copyright(c) 2002-2016 Mitov Software. All Rights Reserved. //
7// //
8////////////////////////////////////////////////////////////////////////////////
9
10#ifndef _OPENWIRE_h
11#define _OPENWIRE_h
12
13#include <Mitov_SimpleList.h>
14
15namespace OpenWire
16{
17 class Object
18 {
19 };
20//---------------------------------------------------------------------------
21 class VirtualObject : public Object
22 {
23 public:
24 virtual ~VirtualObject() {}
25 };
26//---------------------------------------------------------------------------
27 class Component : public VirtualObject
28 {
29 public:
30 static void _SystemInit();
31 static void _SystemLoop();
32
33 protected:
34 virtual void CalculateFields() {}
35 virtual void SystemInit()
36 {
37 CalculateFields();
38 }
39
40 virtual void SystemStart() {}
41 virtual void SystemLoopBegin( unsigned long currentMicros ) {}
42 virtual void SystemLoopEnd() {}
43 virtual void SystemLoopUpdateHardware() {}
44
45 public:
46 Component();
47 virtual ~Component();
48
49 };
50//---------------------------------------------------------------------------
51 typedef void (Object::*TOnPinReceive) ( void *_Data );
52//---------------------------------------------------------------------------
53 typedef void (Object::*TOnPinIndexedReceive) ( int AIndex, void *_Data );
54//---------------------------------------------------------------------------
55 class Pin : public Object
56 {
57 public:
58 virtual void InternalConnect( Pin &_other ) {}
59
60 public:
61 virtual void Connect( Pin &_other )
62 {
63 InternalConnect( _other );
64 _other.InternalConnect( *this );
65 }
66
67 virtual void Receive( void *_Data ) {}
68 };
69//---------------------------------------------------------------------------
70 class CallbackPin : public Pin
71 {
72 protected:
73 Object *OnReceiveObject = nullptr;
74 TOnPinReceive OnReceive = nullptr;
75
76 public:
77 void SetCallback( Object *AOnReceiveObject, TOnPinReceive AOnReceive )
78 {
79 OnReceiveObject = AOnReceiveObject;
80 OnReceive = AOnReceive;
81 }
82
83 public:
84 virtual void InternalConnect( Pin &_other ) {}
85
86 public:
87 virtual void Receive( void *_Data ) override
88 {
89 if( OnReceive )
90 ( OnReceiveObject->*OnReceive )( _Data );
91
92 }
93
94 };
95//---------------------------------------------------------------------------
96 class StreamPin : public Pin
97 {
98 public:
99 Mitov::SimpleList<OpenWire::Pin*> Pins;
100
101 public:
102 template<typename T> void SendValue( T AValue )
103 {
104 Notify( &AValue );
105 }
106
107 void SendValue( String AValue )
108 {
109 Notify( (char *)AValue.c_str() );
110 }
111
112 public:
113 virtual void InternalConnect( Pin &_other ) override
114 {
115 Pins.push_back( &_other );
116 }
117
118 public:
119 virtual bool IsConnected()
120 {
121 return ( Pins.size() > 0 );
122 }
123
124 public:
125 virtual void Notify( void *_data )
126 {
127 for( Mitov::SimpleList<OpenWire::Pin*>::iterator Iter = Pins.begin(); Iter != Pins.end(); ++Iter )
128 ( *Iter )->Receive( _data );
129
130 }
131 };
132//---------------------------------------------------------------------------
133 class SourcePin : public StreamPin
134 {
135 };
136//---------------------------------------------------------------------------
137 class SinkPin : public CallbackPin
138 {
139 };
140//---------------------------------------------------------------------------
141 class ConnectSinkPin : public CallbackPin
142 {
143 typedef CallbackPin inherited;
144
145 protected:
146 bool FIsConnected = false;
147
148 public:
149 virtual void InternalConnect( Pin &_other )
150 {
151 inherited::InternalConnect( _other );
152 FIsConnected = true;
153 }
154
155 virtual bool IsConnected()
156 {
157 return FIsConnected;
158 }
159
160 };
161//---------------------------------------------------------------------------
162 template<typename T> class TypedSourcePin : public SourcePin
163 {
164 typedef SourcePin inherited;
165
166 protected:
167 T FValue;
168
169 public:
170 void SetValue( T AValue, bool AChangeOnly )
171 {
172 if( AChangeOnly )
173 if( AValue == FValue )
174 return;
175
176 FValue = AValue;
177 Notify( &FValue );
178 }
179
180 };
181//---------------------------------------------------------------------------
182 template<typename T> class VlaueSinkPin : public SinkPin
183 {
184 typedef SinkPin inherited;
185
186 public:
187 T Value = T( 0 );
188
189 public:
190 virtual void Receive( void *_Data ) override
191 {
192 Value = *(T*)_Data;
193 inherited::Receive( _Data );
194 }
195 };
196//---------------------------------------------------------------------------
197 template<> class VlaueSinkPin<String> : public SinkPin
198 {
199 typedef SinkPin inherited;
200
201 public:
202 String Value;
203
204 public:
205 virtual void Receive( void *_Data ) override
206 {
207 Value = (char *)_Data;
208 inherited::Receive( _Data );
209 }
210 };
211//---------------------------------------------------------------------------
212 template<> class VlaueSinkPin<char *> : public SinkPin
213 {
214 typedef SinkPin inherited;
215
216 public:
217 String Value;
218
219 public:
220 virtual void Receive( void *_Data ) override
221 {
222 Value = (char*)_Data;
223 inherited::Receive( _Data );
224 }
225
226 };
227//---------------------------------------------------------------------------
228 template<typename T> class VlaueChangeSinkPin : public SinkPin
229 {
230 typedef SinkPin inherited;
231
232 public:
233 T Value = 0;
234 T OldValue = 0;
235
236 public:
237 virtual void Receive( void *_Data ) override
238 {
239 Value = *(T*)_Data;
240 inherited::Receive( _Data );
241 }
242
243 };
244//---------------------------------------------------------------------------
245 template<> class VlaueChangeSinkPin<char *> : public SinkPin
246 {
247 typedef SinkPin inherited;
248
249 public:
250 String Value;
251 String OldValue;
252
253 public:
254 virtual void Receive( void *_Data ) override
255 {
256 Value = (char *)_Data;
257 inherited::Receive( _Data );
258 }
259
260 };
261//---------------------------------------------------------------------------
262 template<> class VlaueChangeSinkPin<String> : public SinkPin
263 {
264 typedef SinkPin inherited;
265
266 public:
267 String Value;
268 String OldValue;
269
270 public:
271 virtual void Receive( void *_Data ) override
272 {
273 Value = (char *)_Data;
274 inherited::Receive( _Data );
275 }
276
277 };
278//---------------------------------------------------------------------------
279 class IndexedSinkPin : public SinkPin
280 {
281 typedef SinkPin inherited;
282
283 public:
284 int Index = 0;
285
286 public:
287 TOnPinIndexedReceive OnIndexedReceive = nullptr;
288
289 protected:
290 virtual void Receive( void *_Data ) override
291 {
292 if( OnIndexedReceive )
293 ( OnReceiveObject->*OnIndexedReceive )( Index, _Data );
294
295 inherited::Receive( _Data );
296 }
297
298 };
299//---------------------------------------------------------------------------
300 template<typename T> class LiveBindingSink : public OpenWire::Pin
301 {
302 protected:
303 void (*FFunc)( T AData );
304
305 protected:
306 virtual void Receive( void *_Data ) override
307 {
308 FFunc(*(T*)_Data );
309 }
310
311 public:
312 LiveBindingSink( void (*AFunc)( T AData ) ) :
313 FFunc( AFunc )
314 {
315 }
316 };
317//---------------------------------------------------------------------------
318 static Mitov::SimpleList<OpenWire::Component*> _Components;
319//---------------------------------------------------------------------------
320 Component::Component()
321 {
322 _Components.push_back(this);
323 }
324//---------------------------------------------------------------------------
325 Component::~Component()
326 {
327 for( Mitov::SimpleList<OpenWire::Component *>::iterator Iter = OpenWire::_Components.begin(); Iter != OpenWire::_Components.end(); ++Iter )
328 if( *Iter == this )
329 {
330 _Components.erase(Iter);
331 break;
332 }
333
334 }
335//---------------------------------------------------------------------------
336 void Component::_SystemInit()
337 {
338 for( Mitov::SimpleList<OpenWire::Component *>::iterator Iter = OpenWire::_Components.begin(); Iter != OpenWire::_Components.end(); ++Iter )
339 ( *Iter )->SystemInit();
340
341 for( Mitov::SimpleList<OpenWire::Component *>::iterator Iter = OpenWire::_Components.begin(); Iter != OpenWire::_Components.end(); ++Iter )
342 ( *Iter )->SystemStart();
343
344 }
345//---------------------------------------------------------------------------
346 void Component::_SystemLoop()
347 {
348 unsigned long currentMicros = micros();
349 for( Mitov::SimpleList<OpenWire::Component *>::iterator Iter = OpenWire::_Components.begin(); Iter != OpenWire::_Components.end(); ++Iter )
350 ( *Iter )->SystemLoopBegin( currentMicros );
351
352 for( Mitov::SimpleList<OpenWire::Component *>::iterator Iter = OpenWire::_Components.begin(); Iter != OpenWire::_Components.end(); ++Iter )
353 ( *Iter )->SystemLoopEnd();
354
355 for( Mitov::SimpleList<OpenWire::Component *>::iterator Iter = OpenWire::_Components.begin(); Iter != OpenWire::_Components.end(); ++Iter )
356 ( *Iter )->SystemLoopUpdateHardware();
357
358 }
359//---------------------------------------------------------------------------
360}
361
362#endif