1 #ifndef STATEDISTRIBUTIONDOMAIN_H
2 #define STATEDISTRIBUTIONDOMAIN_H
13 #include "al/app/al_SimulationDomain.hpp"
14 #include "al/protocol/al_OSC.hpp"
15 #include "al/spatial/al_Pose.hpp"
36 template <
class TSharedState = DefaultState>
39 std::shared_ptr<StateSendDomain<TSharedState>>
40 addStateSender(std::string
id =
"",
41 std::shared_ptr<TSharedState> statePtr =
nullptr);
43 std::shared_ptr<StateReceiveDomain<TSharedState>>
44 addStateReceiver(std::string
id =
"",
45 std::shared_ptr<TSharedState> statePtr =
nullptr);
47 bool isSender() {
return mIsSender; }
50 for (
auto sendrecv : mSendRecvDomains) {
56 bool mIsSender{
false};
58 std::vector<std::shared_ptr<SynchronousDomain>> mSendRecvDomains;
63 template <
class TSharedState = DefaultState>
73 if (newMessages > 0) {
74 mQueuedStates = newMessages;
75 std::memcpy(mState.get(), buf.get(),
sizeof(TSharedState));
93 void configure(uint16_t port = 10100, std::string
id =
"state",
94 std::string address =
"0.0.0.0", uint16_t packetSize = 1400) {
98 mPacketSize = packetSize;
101 std::shared_ptr<TSharedState> state() {
return mState; }
103 void setStatePointer(std::shared_ptr<TSharedState> ptr) { mState = ptr; }
105 void lockState() { mRecvLock.lock(); }
106 void unlockState() { mRecvLock.unlock(); }
107 int newStates() {
return mQueuedStates; }
109 std::string id()
const {
return mId; }
111 void setId(
const std::string &
id) { mId = id; }
114 std::shared_ptr<TSharedState> mState;
115 int mQueuedStates{1};
116 std::string mAddress{
"localhost"};
117 uint16_t mPort = 10100;
118 uint16_t mPacketSize = 1400;
123 class Handler :
public osc::PacketHandler {
125 StateReceiveDomain *mOscDomain;
126 void onMessage(osc::Message &m)
override {
128 if (m.addressPattern() ==
"/_state" && m.typeTags() ==
"sb") {
131 if (
id == mOscDomain->mId) {
134 if (
sizeof(TSharedState) == inBlob.size) {
135 mOscDomain->mRecvLock.lock();
136 memcpy(mOscDomain->buf.get(), inBlob.data,
sizeof(TSharedState));
137 mOscDomain->newMessages++;
138 mOscDomain->mRecvLock.unlock();
140 std::cerr <<
"ERROR: received state size mismatch" << std::endl;
147 std::unique_ptr<unsigned char[]> buf;
149 uint16_t newMessages = 0;
150 std::mutex mRecvLock;
151 std::unique_ptr<osc::Recv> mRecv;
154 template <
class TSharedState>
156 initializeSubdomains(
true);
157 assert(parent !=
nullptr);
159 buf = std::make_unique<unsigned char[]>(
sizeof(TSharedState));
160 mRecv = std::make_unique<osc::Recv>();
161 if (!mRecv || !mRecv->open(mPort, mAddress.c_str())) {
162 std::cerr <<
"Error opening server" << std::endl;
165 mHandler.mOscDomain =
this;
166 mRecv->handler(mHandler);
167 if (!mRecv->start()) {
168 std::cerr <<
"Failed to start receiver. " << std::endl;
172 std::cout <<
"Opened " << mAddress <<
":" << mPort << std::endl;
173 initializeSubdomains(
false);
177 template <
class TSharedState = DefaultState>
197 osc::Blob b(mState.get(),
sizeof(TSharedState));
200 s.
send(
"/_state", mId, b);
216 void configure(uint16_t port, std::string
id =
"state",
217 std::string address =
"localhost",
218 uint16_t packetSize = 1400) {
222 mPacketSize = packetSize;
225 std::shared_ptr<TSharedState> state() {
return mState; }
230 void setStatePointer(std::shared_ptr<TSharedState> ptr) {
236 int newStates() {
return mQueuedStates; }
238 std::string id()
const {
return mId; }
240 void setId(
const std::string &
id) { mId = id; }
242 void setAddress(std::string address) { mAddress = address; };
245 std::shared_ptr<TSharedState> mState;
246 std::mutex mStateLock;
247 int mQueuedStates{0};
248 uint16_t mPort = 10100;
249 std::string mAddress{
"localhost"};
250 uint16_t mPacketSize = 1400;
253 std::unique_ptr<osc::Send> mSend;
255 std::string mId =
"";
258 template <
class TSharedState>
259 std::shared_ptr<StateSendDomain<TSharedState>>
260 StateDistributionDomain<TSharedState>::addStateSender(
261 std::string
id, std::shared_ptr<TSharedState> statePtr) {
263 this->
template newSubDomain<StateSendDomain<TSharedState>>(
false);
264 newDomain->setId(
id);
265 newDomain->setStatePointer(statePtr);
266 mSendRecvDomains.push_back(newDomain);
270 template <
class TSharedState>
271 std::shared_ptr<StateReceiveDomain<TSharedState>>
272 StateDistributionDomain<TSharedState>::addStateReceiver(
273 std::string
id, std::shared_ptr<TSharedState> statePtr) {
275 this->
template newSubDomain<StateReceiveDomain<TSharedState>>(
true);
276 newDomain->setId(
id);
277 newDomain->setStatePointer(statePtr);
278 mSendRecvDomains.push_back(newDomain);
bool cleanupSubdomains(bool pre=false)
cleanup subdomains
bool initializeSubdomains(bool pre=false)
initializeSubdomains should be called within the domain's initialization function
void removeSubDomain(std::shared_ptr< SynchronousDomain > subDomain)
Remove a subdomain.
bool tickSubdomains(bool pre=false)
execute subdomains
A local coordinate frame.
Domain for distributing state for a simulation domain.
bool cleanup(ComputationDomain *parent=nullptr) override
cleanup
bool tick() override
Execute a pass of the domain.
bool init(ComputationDomain *parent=nullptr) override
initialize
bool init(ComputationDomain *parent=nullptr) override
initialize
bool tick() override
Execute a pass of the domain.
bool cleanup(ComputationDomain *parent=nullptr) override
cleanup
size_t send()
Send and clear current packet contents.