forked from themoos/python-moos
-
Notifications
You must be signed in to change notification settings - Fork 0
/
pyMOOS.cpp
162 lines (126 loc) · 4.87 KB
/
pyMOOS.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
#include "pyMOOS.hpp"
void MOOSExceptionTranslator(const pyMOOSException & e) {
// Use the Python 'C' API to set up an exception object
PyErr_SetString(PyExc_RuntimeError, e.what());
}
namespace MOOS {
/** this is a class which wraps MOOS::MOOSAsyncCommClient to provide
* and interface more suitable for python wrapping
*/
AsyncCommsWrapper::~AsyncCommsWrapper(){
Close(true);
}
bool AsyncCommsWrapper::Run(const std::string & sServer, int Port, const std::string & sMyName) {
return BASE::Run(sServer, Port, sMyName, 0);//Comms Tick not used in Async version
}
//we can support vectors of objects by not lists so
//here we have a funtion which copies a list to vector
MsgVector AsyncCommsWrapper::FetchMailAsVector() {
MsgVector v;
MOOSMSG_LIST M;
if (Fetch(M))
std::copy(M.begin(), M.end(), std::back_inserter(v));
return v;
}
/* python strings can be binary lets make this specific*/
bool AsyncCommsWrapper::NotifyBinary(const std::string& sKey, const std::string & sData,
double dfTime) {
CMOOSMsg M(MOOS_NOTIFY, sKey, sData.size(), (void *) sData.data(),
dfTime);
return BASE::Post(M);
}
bool AsyncCommsWrapper::on_connect_delegate(void * pParam) {
MOOS::AsyncCommsWrapper * pMe =
static_cast<MOOS::AsyncCommsWrapper*> (pParam);
return pMe->on_connect();
}
bool AsyncCommsWrapper::SetOnConnectCallback(bp::object func) {
BASE: SetOnConnectCallBack(on_connect_delegate, this);
on_connect_object_ = func;
return true;
}
bool AsyncCommsWrapper::Close(bool nice){
bool bResult = false;
Py_BEGIN_ALLOW_THREADS
//PyGILState_STATE gstate = PyGILState_Ensure();
closing_ = true;
bResult = BASE::Close(true);
//PyGILState_Release(gstate);
Py_END_ALLOW_THREADS
return bResult;
}
bool AsyncCommsWrapper::on_connect() {
bool bResult = false;
PyGILState_STATE gstate = PyGILState_Ensure();
try {
bp::object result = on_connect_object_();
bResult = bp::extract<bool>(result);
} catch (const bp::error_already_set&) {
PyErr_Print();
PyGILState_Release(gstate);
throw pyMOOSException("OnConnect:: caught an exception thrown in python callback");
}
PyGILState_Release(gstate);
return bResult;
}
bool AsyncCommsWrapper::SetOnMailCallback(bp::object func) {
BASE: SetOnMailCallBack(on_mail_delegate, this);
on_mail_object_ = func;
return true;
}
bool AsyncCommsWrapper::on_mail_delegate(void * pParam) {
MOOS::AsyncCommsWrapper * pMe =
static_cast<MOOS::AsyncCommsWrapper*> (pParam);
return pMe->on_mail();
}
bool AsyncCommsWrapper::on_mail() {
bool bResult = false;
PyGILState_STATE gstate = PyGILState_Ensure();
try {
if(!closing_){
bp::object result = on_mail_object_();
bResult = bp::extract<bool>(result);
}
} catch (const bp::error_already_set&) {
PyErr_Print();
PyGILState_Release(gstate);
throw pyMOOSException("OnMail:: caught an exception thrown in python callback");
}
PyGILState_Release(gstate);
return bResult;
}
bool AsyncCommsWrapper::active_queue_delegate(CMOOSMsg & M, void* pParam) {
MeAndQueue * maq = static_cast<MeAndQueue*> (pParam);
return maq->me_->OnQueue(M, maq->queue_name_);
}
bool AsyncCommsWrapper::OnQueue(CMOOSMsg & M, const std::string & sQueueName) {
std::map<std::string, MeAndQueue*>::iterator q;
{
MOOS::ScopedLock L(queue_api_lock_);
q = active_queue_details_.find(sQueueName);
if (q == active_queue_details_.end())
return false;
}
bool bResult = false;
PyGILState_STATE gstate = PyGILState_Ensure();
try {
bp::object result = q->second->func_(M);
bResult = bp::extract<bool>(result);
} catch (const bp::error_already_set& e) {
PyGILState_Release(gstate);
throw pyMOOSException("ActiveQueue:: caught an exception thrown in python callback");
}
PyGILState_Release(gstate);
return bResult;
}
bool AsyncCommsWrapper::AddActiveQueue(const std::string & sQueueName, bp::object func) {
MOOS::ScopedLock L(queue_api_lock_);
MeAndQueue* maq = new MeAndQueue;
maq->me_ = this;
maq->queue_name_ = sQueueName;
maq->func_ = func;
std::cerr << "adding active queue OK\n";
active_queue_details_[sQueueName] = maq;
return BASE::AddActiveQueue(sQueueName, active_queue_delegate, maq);
}
};