libraries / Mitov / Mitov_Structure.hon commit Added link to project report (97a3ba0)
   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