libraries / Mitov / OpenWire.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 _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