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 _MITOV_STRUCTURE_h
11#define _MITOV_STRUCTURE_h
12
13#include <Mitov.h>
14
15namespace Mitov
16{
17//---------------------------------------------------------------------------
18 class BasicMakeStructureElement : public OpenWire::Component
19 {
20 public:
21 virtual bool GetIsPopulated() { return true; }
22 virtual bool GetIsModified() { return false; }
23 virtual void ClearModified() {}
24 virtual void GetData( unsigned char *&AData, unsigned char &AOffset ) {}
25 };
26//---------------------------------------------------------------------------
27 class BasicSplitStructureElement : public OpenWire::Component
28 {
29 public:
30 virtual void Extract( unsigned char *&AData, unsigned char &AOffset ) {}
31
32 };
33//---------------------------------------------------------------------------
34 template<typename T> class BasicTypedStructureSinkElement : public BasicMakeStructureElement
35 {
36 public:
37 OpenWire::SinkPin InputPin;
38
39 protected:
40 T FValue = 0;
41 bool FPopulated : 1;
42 bool FModified : 1;
43
44/*
45 public:
46 T InitialValue;
47
48 virtual void SystemInit()
49 {
50 inherited::SystemInit();
51 FValue = InitialValue;
52 }
53*/
54 public:
55 virtual bool GetIsPopulated() override
56 {
57 return FPopulated;
58 }
59
60 virtual bool GetIsModified() override
61 {
62 return FModified;
63 }
64
65 virtual void ClearModified() override
66 {
67 FModified = false;
68 }
69
70 virtual void GetData( unsigned char *&AData, unsigned char &AOffset ) override
71 {
72 if( AOffset )
73 {
74// Serial.println( "TTT" );
75 ++AData;
76 AOffset = 0;
77 }
78
79#ifdef VISUINO_ESP8266
80 memcpy( AData, &FValue, sizeof( T ));
81#else
82 *(T*)AData = FValue;
83#endif
84// memcpy( AData, &FValue, sizeof( T ));
85 AData += sizeof( T );
86 FModified = false;
87 }
88
89 protected:
90 virtual void DoReceive( void *_Data )
91 {
92 T AValue = *(T*)_Data;
93 FPopulated = true;
94 if( AValue == FValue )
95 return;
96
97 FValue = AValue;
98 FModified = true;
99 }
100
101 public:
102 BasicTypedStructureSinkElement() :
103 FPopulated( false ),
104 FModified( false )
105 {
106 InputPin.SetCallback( this, (OpenWire::TOnPinReceive)&BasicTypedStructureSinkElement::DoReceive );
107 }
108
109 };
110//---------------------------------------------------------------------------
111 template<typename T> class BasicTypedStructureSourceElement : public BasicSplitStructureElement
112 {
113 public:
114 OpenWire::SourcePin OutputPin;
115
116 public:
117 virtual void Extract( unsigned char *&AData, unsigned char &AOffset ) override
118 {
119 if( AOffset )
120 {
121 ++ AData;
122 AOffset = 0;
123 }
124
125 T AValue;
126 AValue = *((T *)AData );
127 OutputPin.Notify( &AValue );
128
129 AData += sizeof( T );
130 }
131 };
132//---------------------------------------------------------------------------
133 class DigitalStructureSourceElement : public BasicTypedStructureSourceElement<bool>
134 {
135 public:
136/*
137 virtual int Start( bool &AAllign ) override
138 {
139 AAllign = false;
140 return 1;
141 }
142*/
143 virtual void Extract( unsigned char *&AData, unsigned char &AOffset ) override
144 {
145 unsigned char AValue = *AData;
146 bool ABoolValue = (( AValue & ( 1 << AOffset )) != 0 );
147 ++AOffset;
148
149 if( AOffset == 8 )
150 {
151 AOffset = 0;
152 ++AData;
153 }
154
155 OutputPin.Notify( &ABoolValue );
156 }
157 };
158//---------------------------------------------------------------------------
159 class DigitalStructureSinkElement : public BasicTypedStructureSinkElement<bool>
160 {
161 public:
162 virtual void GetData( unsigned char *&AData, unsigned char &AOffset ) override
163 {
164 *AData &= 0xFF >> ( 8 - AOffset ); // Zero the upper bits
165 if( FValue )
166 *AData |= 1 << AOffset; // Set the bit
167
168 ++AOffset;
169 if( AOffset == 8 )
170 {
171 AOffset = 0;
172 ++AData;
173 }
174 }
175 };
176//---------------------------------------------------------------------------
177 template<int T_BUFFER_SIZE> class MakeStructure : public Mitov::CommonSource, public Mitov::ClockingSupport
178 {
179 typedef Mitov::CommonSource inherited;
180
181 public:
182 Mitov::SimpleObjectList<BasicMakeStructureElement*> Elements;
183
184 bool OnlyModified = false;
185
186 protected:
187 byte FBuffer[ T_BUFFER_SIZE ];
188
189 protected:
190 virtual void DoClockReceive( void *_Data ) override
191 {
192// Serial.println( "++++++" );
193 int AElementCount = Elements.size();
194 if( OnlyModified )
195 {
196 bool AModified = false;
197 for( int i = 0; i < AElementCount; ++i )
198 if( Elements[ i ]->GetIsModified() )
199 {
200 AModified = true;
201 break;
202 }
203
204 if( !AModified )
205 return;
206 }
207
208 else
209 {
210 for( int i = 0; i < AElementCount; ++i )
211 if( ! Elements[ i ]->GetIsPopulated() )
212 return;
213
214 }
215
216 byte *ADataPtr = FBuffer;
217 unsigned char AOffset = 0;
218 for( int i = 0; i < AElementCount; ++i )
219 Elements[ i ]->GetData( ADataPtr, AOffset );
220
221// Serial.println( ASize );
222
223
224 OutputPin.SendValue( Mitov::TDataBlock( T_BUFFER_SIZE, FBuffer ));
225
226/*
227 ADataPtr = FBuffer;
228 int ASize = T_BUFFER_SIZE;
229
230 while( ASize-- )
231 OutputPin.Notify( ADataPtr++ );
232*/
233 }
234
235 protected:
236 virtual void SystemLoopBegin( unsigned long currentMicros ) override
237 {
238 if( !ClockInputPin.IsConnected() )
239 DoClockReceive( NULL );
240
241// delay( 1000 );
242 inherited::SystemLoopBegin( currentMicros );
243 }
244/*
245 virtual void SystemStart()
246 {
247 FBufferSize = 0;
248 FAllElements.push_back( &HeadMarker );
249 for( int i = 0; i < Elements.size(); ++i )
250 FAllElements.push_back( Elements[ i ] );
251
252 FAllElements.push_back( &Checksum );
253
254 for( int i = 0; i < FAllElements.size(); ++i )
255 {
256 bool AAlligned = false;
257 FBufferSize += FAllElements[ i ]->GetSize( AAlligned );
258// Serial.println( FBufferSize );
259 if( AAlligned )
260 {
261 FBufferSize = ( FBufferSize + 7 ) / 8;
262 FBufferSize *= 8;
263 }
264
265 }
266
267// Serial.println( FBufferSize );
268
269 FBufferSize = ( FBufferSize + 7 ) / 8;
270 FBuffers[ 0 ] = new unsigned char[ FBufferSize * 2 ];
271 FBuffers[ 1 ] = new unsigned char[ FBufferSize * 2 ];
272
273 inherited::SystemStart();
274 }
275*/
276 };
277//---------------------------------------------------------------------------
278 template<int T_BUFFER_SIZE> class SplitStructure : public Mitov::CommonSink
279 {
280 typedef Mitov::CommonSink inherited;
281
282 public:
283 Mitov::SimpleObjectList<BasicSplitStructureElement*> Elements;
284
285 protected:
286 byte FBuffer[ T_BUFFER_SIZE ];
287 byte *FDataPtr = FBuffer;
288
289 protected:
290 virtual void DoReceive( void *_Data )
291 {
292 Mitov::TDataBlock ABlock = *(Mitov::TDataBlock *)_Data;
293 while( ABlock.Size -- )
294 {
295 *FDataPtr ++ = *ABlock.Data ++;
296
297 if( ( FDataPtr - FBuffer ) >= T_BUFFER_SIZE )
298 {
299 unsigned char AOffset = 0;
300 byte *ADataPtr = FBuffer;
301 for( int i = 0; i < Elements.size(); ++i )
302 Elements[ i ]->Extract( ADataPtr, AOffset );
303
304 FDataPtr = FBuffer;
305 }
306 }
307 }
308
309/*
310 virtual void SystemStart() override
311 {
312 FDataPtr = FBuffer;
313 inherited::SystemStart();
314 }
315*/
316 };
317//---------------------------------------------------------------------------
318
319}
320
321#endif