GM6000 Digital Heater Controller Build: 16 (Branch = develop)
SDX-1330
ModelPointCommon_.h
Go to the documentation of this file.
1#ifndef Cpl_Dm_ModelPointBase_h_
2#define Cpl_Dm_ModelPointBase_h_
3/*-----------------------------------------------------------------------------
4* This file is part of the Colony.Core Project. The Colony.Core Project is an
5* open source project with a BSD type of licensing agreement. See the license
6* agreement (license.txt) in the top/ directory or on the Internet at
7* http://integerfox.com/colony.core/license.txt
8*
9* Copyright (c) 2014-2025 John T. Taylor
10*
11* Redistributions of the source code must retain the above copyright notice.
12*----------------------------------------------------------------------------*/
13/** @file */
14
15
16#include "Cpl/Dm/ModelPoint.h"
18#include "Cpl/Dm/Subscriber.h"
19#include "Cpl/Container/DList.h"
20#include <stdint.h>
21#include <stdlib.h>
22
23///
24namespace Cpl {
25///
26namespace Dm {
27
28
29/** This concrete class provide common infrastructure for a Model Point.
30 */
32{
33protected:
34 /// Constructor
36 const char* symbolicName,
37 void* myDataPtr,
38 size_t dataSizeInBytes,
39 bool isValid = false );
40
41public:
42 /// See Cpl::Dm::ModelPoint
43 const char* getName() const noexcept;
44
45 /// See Cpl::Dm::ModelPoint. This method IS thread safe.
46 size_t getSize() const noexcept;
47
48 /// See Cpl::Dm::ModelPoint
49 uint16_t getSequenceNumber() const noexcept;
50
51 /// See Cpl::Dm::ModelPoint
52 uint16_t touch() noexcept;
53
54 /// See Cpl::Dm::ModelPoint
55 uint16_t setInvalid( LockRequest_T lockRequest = eNO_REQUEST ) noexcept;
56
57 /// See Cpl::Dm::ModelPoint
58 bool isNotValid( uint16_t* seqNumPtr=0 ) const noexcept;
59
60 /// See Cpl::Dm::ModelPoint
61 bool isLocked() const noexcept;
62
63 /// See Cpl::Dm::ModelPoint
64 uint16_t setLockState( LockRequest_T lockRequest ) noexcept;
65
66 /// See Cpl::Dm::ModelPoint
67 size_t getExternalSize( bool includeLockedState = false ) const noexcept;
68
69 /// See Cpl::Dm::ModelPoint. Note: The implementation does NOT account for Endianess, i.e. assumes the 'platform' is the same for export/import
70 size_t exportData( void* dstDataStream, size_t maxDstLength, uint16_t* retSequenceNumber = 0, bool includeLockedState = false ) const noexcept;
71
72 /// See Cpl::Dm::ModelPoint. Note: The implementation does NOT account for Endianess, i.e. assumes the 'platform' is the same for export/import
73 size_t importData( const void* srcDataStream, size_t srcLength, uint16_t* retSequenceNumber = 0, bool includeLockedState = false ) noexcept;
74
75 /// See Cpl::Dm::ModelPoint
76 void genericAttach( SubscriberApi& observer, uint16_t initialSeqNumber=SEQUENCE_NUMBER_UNKNOWN ) noexcept;
77
78 /// See Cpl::Dm::ModelPoint
79 void genericDetach( SubscriberApi& observer ) noexcept;
80
81 /// See Cpl::Dm::ModelPoint
82 bool toJSON( char* dst, size_t dstSize, bool& truncated, bool verbose=true, bool pretty=false ) noexcept;
83
84protected:
85 /** This method is used to read the MP contents and synchronize
86 the observer with the current MP contents. This method should ONLY be
87 used in the notification callback method and the 'observerToSync'
88 argument MUST be the argument provided by the callback method
89
90 Note: The observer will be subscribed for change notifications after
91 this call.
92 */
93 inline bool readAndSync( void* dstData, size_t dstSize, uint16_t& seqNum, SubscriberApi& observerToSync )
94 {
95 bool result = readData( dstData, dstSize , &seqNum );
96 attachSubscriber( observerToSync, seqNum );
97 return result;
98 }
99
100 public:
101 /** This method is used to test the validate state of the MP and synchronize
102 the observer with the current MP contents. This method should ONLY be
103 used in the notification callback method and the 'observerToSync'
104 argument MUST be the argument provided by the callback method
105
106 Note: The observer will be subscribed for change notifications after
107 this call
108 */
109 inline bool isNotValidAndSync( SubscriberApi& observerToSync )
110 {
111 uint16_t seqNum;
112 bool result = isNotValid( &seqNum );
113 attachSubscriber( observerToSync, seqNum );
114 return result;
115 }
116
117
118protected:
119 /// See Cpl::Dm::ModelPoint
120 bool readData( void* dstData, size_t dstSize, uint16_t* seqNumPtr=0 ) const noexcept;
121
122 /// See Cpl::Dm::ModelPoint
123 uint16_t writeData( const void* srcData, size_t srcSize, LockRequest_T lockRequest = eNO_REQUEST ) noexcept;
124
125 /// Updates the MP with the valid-state/data from 'src'. Note: the src.lock state is NOT copied
126 virtual uint16_t copyDataAndStateFrom( const ModelPointCommon_& src, LockRequest_T lockRequest ) noexcept;
127
128 /// See Cpl::Dm::ModelPoint
129 void attachSubscriber( SubscriberApi& observer, uint16_t initialSeqNumber=SEQUENCE_NUMBER_UNKNOWN ) noexcept;
130
131 /// See Cpl::Dm::ModelPoint
132 void detachSubscriber( SubscriberApi& observer ) noexcept;
133
134 /// See Cpl::Dm::ModelPoint
135 void copyDataTo_( void* dstData, size_t dstSize ) const noexcept;
136
137 /// See Cpl::Dm::ModelPoint
138 void copyDataFrom_( const void* srcData, size_t srcSize ) noexcept;
139
140
141 /// See Cpl::Dm::ModelPoint. Note: This implementation does NOT work if the any of the data content are floats/double data types
142 bool isDataEqual_( const void* otherData ) const noexcept;
143
144 /// See Cpl::Dm::ModelPoint.
145 const void* getImportExportDataPointer_() const noexcept;
146
147 /// See Cpl::Dm::ModelPoint.
148 size_t getInternalDataSize_() const noexcept;
149
150public:
151 /// See Cpl::Dm::ModelPoint
152 void processSubscriptionEvent_( SubscriberApi& subscriber, Event_T event ) noexcept;
153
154
155protected:
156 /** Internal helper method that completes the data update process as well
157 as ensuring any change notifications get generated. Note: This method
158 ALWAYS sets the MP's state to 'valid'
159
160 This method is NOT thread safe.
161 */
162 virtual void processDataUpdated() noexcept;
163
164 /** Internal helper method that handles generating change notifications
165 when the Model Point's data/state has changed.
166
167 This method is NOT thread safe.
168 */
169 virtual void processChangeNotifications() noexcept;
170
171 /** Internal helper method that advances/updates the Model Point's
172 sequence number.
173
174 This method is NOT thread safe.
175 */
176 virtual void advanceSequenceNumber() noexcept;
177
178 /** Internal helper method that manages testing and updating the locked
179 state.
180
181 Rules:
182 1) If 'lockRequest' is eNO_REQUEST, the method only returns true if
183 the MP is in the unlocked state
184 2) If 'lockRequest' is eLOCK, the method only returns if the MP is in
185 the unlocked state. In addition, when true is returned the MP is
186 put into the locked state.
187 3) If 'lockRequest' is eUNLOCK, the method always returns true and
188 the MP is left in the unlocked state.
189
190 This method is NOT thread safe.
191 */
192 virtual bool testAndUpdateLock( LockRequest_T lockRequest ) noexcept;
193
194
195protected:
196 /// Helper FSM method
197 virtual void transitionToNotifyPending( SubscriberApi& subscriber ) noexcept;
198
199 /// Helper FSM method
200 virtual void transitionToSubscribed( SubscriberApi& subscriber ) noexcept;
201
202 /// Helper method when converting MP to a JSON string
203 virtual JsonDocument& beginJSON( bool isValid, bool locked, uint16_t seqnum, bool verbose=true ) noexcept;
204
205 /// Helper method when converting MP to a JSON string
206 virtual void endJSON( char* dst, size_t dstSize, bool& truncated, bool verbose=true, bool pretty=false ) noexcept;
207
208 /** Helper method that a child a class can override to change behavior when
209 an MP is set to the invalid state. The default behavior is to zero out
210 the data (i.e. perform a memset(m_dataPtr,0, m_dataSize) call on the data)
211 */
212 virtual void hookSetInvalid() noexcept;
213
214
215protected:
216 /// List of Active Subscribers
217 Cpl::Container::DList<SubscriberApi> m_subscribers;
218
219 /// The model point's symbolic name
220 const char* m_name;
221
222 /// Reference to the containing Model Base
224
225 /// Reference to my Data
227
228 /// Size of my data
230
231 /// Sequence number used for tracking changes in the Point data
232 uint16_t m_seqNum;
233
234 /// Locked state
236
237 /// valid/invalid state
239};
240
241}; // end namespaces
242};
243#endif // end header latch
This concrete class implements a simple Model Database.
Definition ModelDatabase.h:56
This concrete class provide common infrastructure for a Model Point.
Definition ModelPointCommon_.h:32
ModelPointCommon_(ModelDatabase &myModelBase, const char *symbolicName, void *myDataPtr, size_t dataSizeInBytes, bool isValid=false)
Constructor.
void attachSubscriber(SubscriberApi &observer, uint16_t initialSeqNumber=SEQUENCE_NUMBER_UNKNOWN) noexcept
See Cpl::Dm::ModelPoint.
void copyDataTo_(void *dstData, size_t dstSize) const noexcept
See Cpl::Dm::ModelPoint.
bool m_valid
valid/invalid state
Definition ModelPointCommon_.h:238
bool readAndSync(void *dstData, size_t dstSize, uint16_t &seqNum, SubscriberApi &observerToSync)
This method is used to read the MP contents and synchronize the observer with the current MP contents...
Definition ModelPointCommon_.h:93
size_t getExternalSize(bool includeLockedState=false) const noexcept
See Cpl::Dm::ModelPoint.
uint16_t setInvalid(LockRequest_T lockRequest=eNO_REQUEST) noexcept
See Cpl::Dm::ModelPoint.
Cpl::Container::DList< SubscriberApi > m_subscribers
List of Active Subscribers.
Definition ModelPointCommon_.h:217
virtual JsonDocument & beginJSON(bool isValid, bool locked, uint16_t seqnum, bool verbose=true) noexcept
Helper method when converting MP to a JSON string.
virtual void endJSON(char *dst, size_t dstSize, bool &truncated, bool verbose=true, bool pretty=false) noexcept
Helper method when converting MP to a JSON string.
virtual void transitionToNotifyPending(SubscriberApi &subscriber) noexcept
Helper FSM method.
void genericAttach(SubscriberApi &observer, uint16_t initialSeqNumber=SEQUENCE_NUMBER_UNKNOWN) noexcept
See Cpl::Dm::ModelPoint.
void detachSubscriber(SubscriberApi &observer) noexcept
See Cpl::Dm::ModelPoint.
const char * m_name
The model point's symbolic name.
Definition ModelPointCommon_.h:220
virtual bool testAndUpdateLock(LockRequest_T lockRequest) noexcept
Internal helper method that manages testing and updating the locked state.
bool isLocked() const noexcept
See Cpl::Dm::ModelPoint.
ModelDatabase & m_modelDatabase
Reference to the containing Model Base.
Definition ModelPointCommon_.h:223
bool isNotValid(uint16_t *seqNumPtr=0) const noexcept
See Cpl::Dm::ModelPoint.
void copyDataFrom_(const void *srcData, size_t srcSize) noexcept
See Cpl::Dm::ModelPoint.
virtual void advanceSequenceNumber() noexcept
Internal helper method that advances/updates the Model Point's sequence number.
bool isNotValidAndSync(SubscriberApi &observerToSync)
This method is used to test the validate state of the MP and synchronize the observer with the curren...
Definition ModelPointCommon_.h:109
uint16_t getSequenceNumber() const noexcept
See Cpl::Dm::ModelPoint.
void genericDetach(SubscriberApi &observer) noexcept
See Cpl::Dm::ModelPoint.
virtual void processChangeNotifications() noexcept
Internal helper method that handles generating change notifications when the Model Point's data/state...
virtual uint16_t copyDataAndStateFrom(const ModelPointCommon_ &src, LockRequest_T lockRequest) noexcept
Updates the MP with the valid-state/data from 'src'. Note: the src.lock state is NOT copied.
uint16_t m_seqNum
Sequence number used for tracking changes in the Point data.
Definition ModelPointCommon_.h:232
uint16_t touch() noexcept
See Cpl::Dm::ModelPoint.
const char * getName() const noexcept
See Cpl::Dm::ModelPoint.
virtual void transitionToSubscribed(SubscriberApi &subscriber) noexcept
Helper FSM method.
uint16_t setLockState(LockRequest_T lockRequest) noexcept
See Cpl::Dm::ModelPoint.
size_t m_dataSize
Size of my data.
Definition ModelPointCommon_.h:229
const void * getImportExportDataPointer_() const noexcept
See Cpl::Dm::ModelPoint.
size_t getInternalDataSize_() const noexcept
See Cpl::Dm::ModelPoint.
size_t getSize() const noexcept
See Cpl::Dm::ModelPoint. This method IS thread safe.
virtual void hookSetInvalid() noexcept
Helper method that a child a class can override to change behavior when an MP is set to the invalid s...
bool toJSON(char *dst, size_t dstSize, bool &truncated, bool verbose=true, bool pretty=false) noexcept
See Cpl::Dm::ModelPoint.
void processSubscriptionEvent_(SubscriberApi &subscriber, Event_T event) noexcept
See Cpl::Dm::ModelPoint.
bool isDataEqual_(const void *otherData) const noexcept
See Cpl::Dm::ModelPoint. Note: This implementation does NOT work if the any of the data content are f...
bool readData(void *dstData, size_t dstSize, uint16_t *seqNumPtr=0) const noexcept
See Cpl::Dm::ModelPoint.
size_t exportData(void *dstDataStream, size_t maxDstLength, uint16_t *retSequenceNumber=0, bool includeLockedState=false) const noexcept
See Cpl::Dm::ModelPoint. Note: The implementation does NOT account for Endianess, i....
bool m_locked
Locked state.
Definition ModelPointCommon_.h:235
uint16_t writeData(const void *srcData, size_t srcSize, LockRequest_T lockRequest=eNO_REQUEST) noexcept
See Cpl::Dm::ModelPoint.
void * m_dataPtr
Reference to my Data.
Definition ModelPointCommon_.h:226
size_t importData(const void *srcDataStream, size_t srcLength, uint16_t *retSequenceNumber=0, bool includeLockedState=false) noexcept
See Cpl::Dm::ModelPoint. Note: The implementation does NOT account for Endianess, i....
virtual void processDataUpdated() noexcept
Internal helper method that completes the data update process as well as ensuring any change notifica...
This mostly abstract class defines the interface for a Model Point.
Definition ModelPoint.h:46
LockRequest_T
Options related to the Model Point's locked state.
Definition ModelPoint.h:50
@ eNO_REQUEST
No change in the MP's lock state is requested.
Definition ModelPoint.h:51
static const uint16_t SEQUENCE_NUMBER_UNKNOWN
Magic value to use when registering for a change notification and application does not 'know' the cur...
Definition ModelPoint.h:62
Event_T
Subscriber events.
Definition ModelPoint.h:365
This abstract class defines the Subscriber interface - for change notifications - to a Model Points d...
Definition SubscriberApi.h:34
The 'Cpl' namespace is the root name space for the Colony.
Definition Api16.h:20