Skip to content

Commit 10c7fb6

Browse files
committed
fix messaging subscription scoping
1 parent 9ef0539 commit 10c7fb6

File tree

3 files changed

+121
-34
lines changed

3 files changed

+121
-34
lines changed

src/architecture/_GeneralModuleFiles/swig_c_wrap.i

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
#include <architecture/utilities/bskLogging.h>
2424
#include <memory>
2525
#include <type_traits>
26+
#include <vector>
27+
#include <functional>
2628
%}
2729
%include <std_string.i>
2830

@@ -63,6 +65,22 @@ class CWrapper : public SysModel {
6365
std::unique_ptr<TConfig> config; //!< class variable
6466
};
6567

68+
class CModuleWrapper {
69+
private:
70+
std::vector<std::function<void()>> destructionCallbacks;
71+
72+
public:
73+
void addDestructionCallback(std::function<void()> callback) {
74+
destructionCallbacks.push_back(callback);
75+
}
76+
77+
~CModuleWrapper() {
78+
for (auto& callback : destructionCallbacks) {
79+
callback();
80+
}
81+
}
82+
};
83+
6684
%}
6785

6886
%define %c_wrap_3(moduleName, configName, functionSuffix)
@@ -83,7 +101,7 @@ class CWrapper : public SysModel {
83101
in overload resolution than methods using the explicit type.
84102
85103
This means that:
86-
104+
87105
Reset_hillPoint(hillPointConfig*, uint64_t, int64_t) { ... }
88106
89107
will always be chosen before:
@@ -103,7 +121,7 @@ class CWrapper : public SysModel {
103121
if (len(args)) > 0:
104122
args[0].thisown = False
105123
%}
106-
124+
107125
%include "moduleName.h"
108126

109127
%template(moduleName) CWrapper<configName,Update_ ## functionSuffix,SelfInit_ ## functionSuffix,Reset_ ## functionSuffix>;

src/architecture/messaging/messaging.h

Lines changed: 59 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
2323
#include "architecture/utilities/bskLogging.h"
2424
#include <typeinfo>
2525
#include <stdlib.h>
26+
#include <functional>
2627

2728
/*! forward-declare sim message for use by read functor */
2829
template<typename messageType>
@@ -38,6 +39,8 @@ class ReadFunctor{
3839
messageType* payloadPointer; //!< -- pointer to the incoming msg data
3940
MsgHeader *headerPointer; //!< -- pointer to the incoming msg header
4041
bool initialized; //!< -- flag indicating if the input message is connect to another message
42+
std::function<void()> refIncCallback;
43+
std::function<void()> refDecCallback;
4144

4245
public:
4346
//!< -- BSK Logging
@@ -46,10 +49,18 @@ class ReadFunctor{
4649

4750

4851
//! constructor
49-
ReadFunctor() : initialized(false) {};
52+
ReadFunctor() :
53+
initialized(false),
54+
refIncCallback([](){}),
55+
refDecCallback([](){}) {}
5056

5157
//! constructor
52-
ReadFunctor(messageType* payloadPtr, MsgHeader *headerPtr) : payloadPointer(payloadPtr), headerPointer(headerPtr), initialized(true){};
58+
ReadFunctor(messageType* payloadPtr, MsgHeader *headerPtr) :
59+
payloadPointer(payloadPtr),
60+
headerPointer(headerPtr),
61+
initialized(true),
62+
refIncCallback([](){}),
63+
refDecCallback([](){}) {}
5364

5465
//! constructor
5566
const messageType& operator()(){
@@ -174,6 +185,42 @@ class ReadFunctor{
174185

175186
//! Recorder method description
176187
Recorder<messageType> recorder(uint64_t timeDiff = 0){return Recorder<messageType>(this, timeDiff);}
188+
189+
/*! Set source reference and callback functions for reference counting
190+
* @param src Pointer to source object
191+
* @param incRef Function to increment reference count
192+
* @param decRef Function to decrement reference count
193+
*/
194+
void setSourceRef(std::function<void()> incRef, std::function<void()> decRef) {
195+
if (refDecCallback) {
196+
refDecCallback();
197+
}
198+
refIncCallback = incRef;
199+
refDecCallback = decRef;
200+
if (refIncCallback) {
201+
refIncCallback();
202+
}
203+
}
204+
205+
/*! Check if this reader is subscribed to a specific message source
206+
* @param source Pointer to message source to check
207+
* @return 1 if subscribed, 0 if not
208+
*/
209+
uint8_t isSubscribedTo(const Message<messageType>* source) const {
210+
if (!source) return 0;
211+
return (this->payloadPointer == source->getPayloadPtr() &&
212+
this->headerPointer == source->getHeaderPtr());
213+
}
214+
215+
/*! Check if this reader is subscribed to a void pointer source
216+
* @param source Void pointer to message source to check
217+
* @return 1 if subscribed, 0 if not
218+
*/
219+
uint8_t isSubscribedTo(const void* source) const {
220+
const Message<messageType>* msgSource =
221+
static_cast<const Message<messageType>*>(source);
222+
return isSubscribedTo(msgSource);
223+
}
177224
};
178225

179226
/*! Write Functor */
@@ -232,6 +279,16 @@ class Message{
232279

233280
//! Return the memory size of the payload, be careful about dynamically sized things
234281
uint64_t getPayloadSize() {return sizeof(messageType);};
282+
283+
/*! Get pointer to message payload
284+
* @return Const pointer to payload data
285+
*/
286+
const messageType* getPayloadPtr() const { return &payload; }
287+
288+
/*! Get pointer to message header
289+
* @return Const pointer to message header
290+
*/
291+
const MsgHeader* getHeaderPtr() const { return &header; }
235292
};
236293

237294

src/architecture/messaging/newMessaging.ih

Lines changed: 42 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -34,38 +34,50 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
3434

3535
%template(messageType ## Reader) ReadFunctor<messageTypePayload>;
3636
%extend ReadFunctor<messageTypePayload> {
37-
%pythoncode %{
38-
def subscribeTo(self, source):
39-
if type(source) == messageType:
40-
self.__subscribe_to(source)
37+
void setPySourceRef(PyObject* source) {
38+
if (source) {
39+
self->setSourceRef(
40+
[source]() { Py_INCREF(source); },
41+
[source]() { Py_DECREF(source); }
42+
);
43+
}
44+
}
45+
46+
%pythoncode %{
47+
def subscribeTo(self, source):
48+
if type(source) == messageType:
49+
self.__subscribe_to(source)
50+
self.setPySourceRef(source)
51+
return
52+
53+
try:
54+
from Basilisk.architecture.messaging.messageType ## Payload import messageType ## _C
55+
if type(source) == messageType ## _C:
56+
self.__subscribe_to_C(source)
57+
self.setPySourceRef(source)
4158
return
42-
43-
try:
44-
from Basilisk.architecture.messaging.messageType ## Payload import messageType ## _C
45-
if type(source) == messageType ## _C:
46-
self.__subscribe_to_C(source)
47-
return
48-
except ImportError:
49-
pass
50-
51-
raise Exception('tried to subscribe ReadFunctor<messageTypePayload> to output message type'
52-
+ str(type(source)))
53-
54-
55-
def isSubscribedTo(self, source):
56-
if type(source) == messageType:
57-
return self.__is_subscribed_to(source)
58-
59-
try:
60-
from Basilisk.architecture.messaging.messageType ## Payload import messageType ## _C
61-
except ImportError:
62-
return 0
63-
59+
except ImportError:
60+
pass
61+
62+
raise Exception('tried to subscribe ReadFunctor<messageTypePayload> to output message type'
63+
+ str(type(source)))
64+
%}
65+
66+
%pythoncode %{
67+
def isSubscribedTo(self, source):
68+
"""Check if this reader is subscribed to the given source"""
69+
if type(source) == messageType:
70+
return self.__is_subscribed_to(source)
71+
72+
try:
73+
from Basilisk.architecture.messaging.messageType ## Payload import messageType ## _C
6474
if type(source) == messageType ## _C:
6575
return self.__is_subscribed_to_C(source)
66-
else:
67-
return 0
68-
%}
76+
except ImportError:
77+
pass
78+
79+
return 0
80+
%}
6981
};
7082

7183
%template(messageType ## Writer) WriteFunctor<messageTypePayload>;
@@ -110,7 +122,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
110122
for el, k in zip(attr, range(len(attr))):
111123
self.explore_and_find_subattr(el, attr_name + "[" + str(k) + "]", content)
112124
else:
113-
# The attribute is a list of common types
125+
# The attribute is a list of common types
114126
content[attr_name] = attr
115127
elif "Basilisk" in str(type(attr)):
116128
# The attribute is a swigged BSK object

0 commit comments

Comments
 (0)