stinger-ipc 0.0.1__py3-none-any.whl → 0.0.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. {stinger_ipc-0.0.1.dist-info → stinger_ipc-0.0.2.dist-info}/METADATA +3 -3
  2. stinger_ipc-0.0.2.dist-info/RECORD +48 -0
  3. stinger_ipc-0.0.2.dist-info/entry_points.txt +4 -0
  4. stingeripc/args.py +6 -5
  5. stingeripc/asyncapi.py +249 -167
  6. stingeripc/components.py +301 -136
  7. stingeripc/connection.py +2 -1
  8. stingeripc/exceptions.py +1 -2
  9. stingeripc/interface.py +8 -4
  10. stingeripc/lang_symb.py +68 -0
  11. stingeripc/templates/cpp/CMakeLists.txt.jinja2 +26 -0
  12. stingeripc/templates/cpp/examples/client_main.cpp.jinja2 +47 -0
  13. stingeripc/templates/cpp/examples/server_main.cpp.jinja2 +35 -0
  14. stingeripc/templates/cpp/include/broker.hpp.jinja2 +132 -0
  15. stingeripc/templates/cpp/include/client.hpp.jinja2 +53 -0
  16. stingeripc/templates/cpp/include/enums.hpp.jinja2 +17 -0
  17. stingeripc/templates/cpp/include/ibrokerconnection.hpp.jinja2 +42 -0
  18. stingeripc/templates/cpp/include/return_types.hpp.jinja2 +14 -0
  19. stingeripc/templates/cpp/include/server.hpp.jinja2 +44 -0
  20. stingeripc/templates/cpp/include/structs.hpp.jinja2 +13 -0
  21. stingeripc/templates/cpp/src/broker.cpp.jinja2 +243 -0
  22. stingeripc/templates/cpp/src/client.cpp.jinja2 +202 -0
  23. stingeripc/templates/cpp/src/server.cpp.jinja2 +170 -0
  24. stingeripc/templates/markdown/index.md.jinja2 +142 -0
  25. stingeripc/templates/python/__init__.py.jinja2 +1 -0
  26. stingeripc/templates/python/client.py.jinja2 +309 -0
  27. stingeripc/templates/python/connection.py.jinja2 +164 -0
  28. stingeripc/templates/python/interface_types.py.jinja2 +48 -0
  29. stingeripc/templates/python/method_codes.py.jinja2 +30 -0
  30. stingeripc/templates/python/pyproject.toml.jinja2 +9 -0
  31. stingeripc/templates/python/server.py.jinja2 +214 -0
  32. stingeripc/templates/rust/Cargo.toml.jinja2 +4 -0
  33. stingeripc/templates/rust/client/Cargo.toml.jinja2 +25 -0
  34. stingeripc/templates/rust/client/examples/client.rs.jinja2 +53 -0
  35. stingeripc/templates/rust/client/src/lib.rs.jinja2 +247 -0
  36. stingeripc/templates/rust/connection/Cargo.toml.jinja2 +21 -0
  37. stingeripc/templates/rust/connection/examples/pub_and_recv.rs.jinja2 +44 -0
  38. stingeripc/templates/rust/connection/src/handler.rs.jinja2 +0 -0
  39. stingeripc/templates/rust/connection/src/lib.rs.jinja2 +262 -0
  40. stingeripc/templates/rust/connection/src/payloads.rs.jinja2 +131 -0
  41. stingeripc/templates/rust/server/Cargo.toml.jinja2 +19 -0
  42. stingeripc/templates/rust/server/examples/server.rs.jinja2 +83 -0
  43. stingeripc/templates/rust/server/src/lib.rs.jinja2 +272 -0
  44. stingeripc/topic.py +11 -8
  45. stinger_ipc-0.0.1.dist-info/RECORD +0 -13
  46. {stinger_ipc-0.0.1.dist-info → stinger_ipc-0.0.2.dist-info}/WHEEL +0 -0
  47. {stinger_ipc-0.0.1.dist-info → stinger_ipc-0.0.2.dist-info}/licenses/LICENSE +0 -0
  48. {stinger_ipc-0.0.1.dist-info → stinger_ipc-0.0.2.dist-info}/top_level.txt +0 -0
stingeripc/connection.py CHANGED
@@ -1,7 +1,8 @@
1
1
  from abc import ABC, abstractmethod
2
2
 
3
+
3
4
  class AbstractConnection(ABC):
4
5
 
5
6
  @abstractmethod
6
- def publish(self, topic: str, payload: str, qos: int, retain:bool=False):
7
+ def publish(self, topic: str, payload: str, qos: int, retain: bool = False):
7
8
  pass
stingeripc/exceptions.py CHANGED
@@ -1,3 +1,2 @@
1
-
2
1
  class InvalidStingerStructure(Exception):
3
- pass
2
+ pass
stingeripc/interface.py CHANGED
@@ -5,17 +5,19 @@ import yamlloader
5
5
  from .components import StingerSpec, InvalidStingerStructure
6
6
  from .topic import InterfaceTopicCreator
7
7
 
8
- VERSION_SUPPORTED = "0.0.6"
8
+ VERSION_SUPPORTED = "0.0.7"
9
9
 
10
10
 
11
11
  class StingerInterface(StingerSpec):
12
12
 
13
13
  def __init__(self, stinger: Dict[str, Any], topic_prefix: Optional[str] = None):
14
14
  itc = self._create_topic_creator(stinger)
15
- super().__init__(itc, stinger['interface'])
15
+ super().__init__(itc, stinger["interface"])
16
16
 
17
17
  @staticmethod
18
- def _create_topic_creator(stinger_spec: Dict[str, Any], topic_prefix: Optional[str] = None) -> InterfaceTopicCreator:
18
+ def _create_topic_creator(
19
+ stinger_spec: Dict[str, Any], topic_prefix: Optional[str] = None
20
+ ) -> InterfaceTopicCreator:
19
21
  if (
20
22
  "stingeripc" not in stinger_spec
21
23
  or "version" not in stinger_spec["stingeripc"]
@@ -28,7 +30,9 @@ class StingerInterface(StingerSpec):
28
30
  raise InvalidStingerStructure(
29
31
  "Could not find interface name in Stinger Spec"
30
32
  )
31
- itc = InterfaceTopicCreator(stinger_spec["interface"]["name"], root=topic_prefix)
33
+ itc = InterfaceTopicCreator(
34
+ stinger_spec["interface"]["name"], root=topic_prefix
35
+ )
32
36
  return itc
33
37
 
34
38
  @classmethod
@@ -0,0 +1,68 @@
1
+
2
+ from jacobsjinjatoo import stringmanip
3
+
4
+ class PythonSymbols:
5
+ def __init__(self):
6
+ ...
7
+
8
+ @property
9
+ def type_definition_module(self) -> str:
10
+ return "stinger_types"
11
+
12
+ class PythonInterfaceSymbols(PythonSymbols):
13
+
14
+ def __init__(self, interface):
15
+ super().__init__()
16
+ self._iface = interface
17
+
18
+ @property
19
+ def client_class_name(self) -> str:
20
+ """ Name of the python class for the interface client."""
21
+ return f"{stringmanip.upper_camel_case(self._iface.name)}Client"
22
+
23
+ @property
24
+ def server_class_name(self) -> str:
25
+ """ Name of the python class for the interface server."""
26
+ return f"{stringmanip.upper_camel_case(self._iface.name)}Server"
27
+
28
+
29
+ class PythonStructSymbols(PythonSymbols):
30
+
31
+ def __init__(self, iface_struct):
32
+ super().__init__()
33
+ self._iface_struct = iface_struct
34
+
35
+
36
+ class PythonMethodSymbols(PythonSymbols):
37
+
38
+ def __init__(self, method):
39
+ super().__init__()
40
+ self._method = method
41
+
42
+ @property
43
+ def return_value_annotation(self) -> str:
44
+ return self._method.return_value_python_type
45
+
46
+ @property
47
+ def return_value_local_class(self) -> str:
48
+ return f"{stringmanip.upper_camel_case(self._method.name)}ReturnValue"
49
+
50
+ @property
51
+ def return_value_class(self):
52
+ return f"{self.type_definition_module}.{self.return_value_local_class}"
53
+
54
+ class RustInterfaceSymbols(PythonSymbols):
55
+
56
+ def __init__(self, interface):
57
+ super().__init__()
58
+ self._iface = interface
59
+
60
+ @property
61
+ def client_struct_name(self) -> str:
62
+ """ Name of the rust struct for the interface client."""
63
+ return f"{stringmanip.upper_camel_case(self._iface.name)}Client"
64
+
65
+ @property
66
+ def server_struct_name(self) -> str:
67
+ """ Name of the struct for the interface server."""
68
+ return f"{stringmanip.upper_camel_case(self._iface.name)}Server"
@@ -0,0 +1,26 @@
1
+ cmake_minimum_required(VERSION 3.16)
2
+
3
+ project ({{stinger.name}})
4
+ set(CMAKE_CXX_STANDARD 11)
5
+
6
+ include_directories(include)
7
+
8
+ set(SOURCE_FILES {%for src_file in source_files|sort%}{{src_file}} {%endfor%})
9
+
10
+ add_library(lib-{{stinger.name}} ${SOURCE_FILES})
11
+
12
+ set(THREADS_PREFER_PTHREAD_FLAG ON)
13
+ find_package(Threads REQUIRED)
14
+
15
+ add_executable(client-demo examples/client_main.cpp)
16
+ target_link_libraries(client-demo PUBLIC lib-{{stinger.name}})
17
+ target_link_libraries(client-demo PUBLIC mosquitto)
18
+ target_link_libraries(client-demo PUBLIC boost_thread)
19
+ target_link_libraries(client-demo PUBLIC boost_chrono)
20
+ target_link_libraries(client-demo PRIVATE Threads::Threads)
21
+
22
+ add_executable(server-demo examples/server_main.cpp)
23
+ target_link_libraries(server-demo PUBLIC lib-{{stinger.name}})
24
+ target_link_libraries(server-demo PUBLIC mosquitto)
25
+ target_link_libraries(server-demo PUBLIC boost_thread)
26
+ target_link_libraries(server-demo PRIVATE Threads::Threads)
@@ -0,0 +1,47 @@
1
+
2
+ #include <iostream>
3
+ #include <boost/chrono/chrono.hpp>
4
+ #include "broker.hpp"
5
+ #include "client.hpp"
6
+
7
+ int main(int argc, char** argv) {
8
+
9
+ {%set broker = stinger.get_example_broker()%}
10
+ auto conn = std::make_shared<{{broker.class_name}}>({%if broker.hostname is none%}"localhost", 1883, {%endif%}"{{stinger.name | UpperCamelCase}}Client-demo");
11
+ {{stinger.name | UpperCamelCase}}Client client(conn);
12
+
13
+ {%-for sig_name, sig in stinger.signals.items() %}
14
+ client.register{{sig_name | UpperCamelCase}}Callback([]({%for arg in sig.arg_list%}{{arg.cpp_type}} {{arg.name}}{%if not loop.last%}, {%endif%}{%endfor%}) {
15
+ std::cout << {%for arg in sig.arg_list%}"{{arg.name}}=" << {%-if arg.optional%} "None"{%else%}{%if arg.arg_type.name.lower() == 'enum'%}{{arg.enum.name | camelCase }}Strings[static_cast<int>({{arg.name}})]{%else%}{{arg.name}}{%endif%}{%endif%} << {%if not loop.last %}" | " << {%endif%}{%endfor%} std::endl;
16
+ });
17
+ {%-endfor%}
18
+
19
+ {%-for method_name, method in stinger.methods.items() %}
20
+ std::cout << "Calling {{method_name}}" << std::endl;
21
+ auto {{method_name|camelCase}}ResultFuture = client.{{method_name | camelCase}}({%for arg in method.arg_list%}{{arg.get_random_example_value('c++')}}{%if not loop.last%}, {%endif%}{%endfor%});
22
+ auto {{method_name|camelCase}}Status = {{method_name|camelCase}}ResultFuture.wait_for(boost::chrono::seconds(5));
23
+ if ({{method_name|camelCase}}Status == boost::future_status::timeout)
24
+ {
25
+ std::cout << "TIMEOUT after 5 seconds waiting for {{method_name}} response." << std::endl;
26
+ }
27
+ else
28
+ {
29
+ {%if method.return_value_type == 'primitive'-%}
30
+ std::cout << "Result: {{method.return_value.name | UpperCamelCase}}=" << {{method_name|camelCase}}ResultFuture.get() << std::endl;
31
+ {%elif method.return_value_type == 'enum'-%}
32
+ std::cout << "Result: {{method.return_value.name | UpperCamelCase}}=" << {{method.return_value.enum.name | camelCase }}Strings[{{method_name|camelCase}}ResultFuture.get()] << std::endl;
33
+ {%elif method.return_value_type == 'struct'-%}
34
+ {{method.return_value_cpp_class}} returnValue = {{method_name|camelCase}}ResultFuture.get();
35
+ std::cout << "Results:"{%for m in method.return_value%} << " {{m.name}}=" << {%if m.arg_type.name.lower() == 'enum'%}{{m.enum.name | camelCase }}Strings[static_cast<int>(returnValue.{{m.name}})]{%else%}returnValue.{{m.name}}{%endif%} {%endfor%} << std::endl;
36
+ {%endif%}
37
+ }
38
+ {%-endfor%}
39
+
40
+ std::cout << "Connected and waiting. Use Ctrl-C to exit." << std::endl;
41
+
42
+ while (true) {
43
+ sleep(10);
44
+ }
45
+
46
+ return 0;
47
+ }
@@ -0,0 +1,35 @@
1
+
2
+ #include <iostream>
3
+
4
+ #include "broker.hpp"
5
+ #include "server.hpp"
6
+ #include "enums.hpp"
7
+
8
+ int main(int argc, char** argv) {
9
+
10
+ {%set broker = stinger.get_example_broker()%}
11
+ auto conn = std::make_shared<{{broker.class_name}}>({%if broker.hostname is none%}"localhost", 1883, {%endif%}"{{stinger.name | UpperCamelCase}}Serve-demo");
12
+ {{stinger.name | UpperCamelCase}}Server server(conn);
13
+
14
+ {%-for sig_name, sig in stinger.signals.items() %}
15
+ auto {{sig_name}}Future = server.emit{{sig_name | UpperCamelCase}}Signal({%for arg in sig.arg_list%}{{arg.get_random_example_value(lang="c++")}}{%if not loop.last%}, {%endif%}{%endfor%});
16
+ {%-endfor%}
17
+ {%-for sig_name in stinger.signals.keys() %}
18
+ {{sig_name}}Future.wait();
19
+ {%-endfor%}
20
+
21
+ {%-for method_name, method in stinger.methods.items() %}
22
+ server.register{{method_name | UpperCamelCase}}Handler([]({%for arg in method.arg_list%}{{arg.cpp_type}} unused{{loop.index}}{%if not loop.last%}, {%endif%}{%endfor%}) -> {{method.return_value_cpp_class}}
23
+ {
24
+ std::cout << "Received call for {{method_name}}\n";
25
+ {%if method.return_value_type == 'struct'%}
26
+ return {{method.return_value_name | UpperCamelCase}}{ {{method.get_return_value_random_example_value('c++')}} };
27
+ {%else%}
28
+ return {{method.get_return_value_random_example_value('c++')}};
29
+ {%-endif%}
30
+ });
31
+ {%endfor%}
32
+ std::cout << "Press Enter to exit\n";
33
+ std::cin.ignore();
34
+ return 0;
35
+ }
@@ -0,0 +1,132 @@
1
+
2
+ #pragma once
3
+
4
+ #include <mosquitto.h>
5
+ #include <queue>
6
+ #include <string>
7
+ #include <map>
8
+ #include <utility>
9
+ #include <boost/interprocess/sync/scoped_lock.hpp>
10
+ #include <boost/thread/mutex.hpp>
11
+ #include <boost/core/noncopyable.hpp>
12
+
13
+ #define BOOST_THREAD_PROVIDES_FUTURE
14
+ #include <boost/thread/future.hpp>
15
+
16
+ #include "ibrokerconnection.hpp"
17
+
18
+ /*! This class presents a connection to a MQTT broker.
19
+ */
20
+ class MqttConnection : public IBrokerConnection
21
+ {
22
+ public:
23
+
24
+ /*! Constructor for a MqttConnection.
25
+ * \param hostname IP address or hostname of the MQTT broker server.
26
+ * \param port Port where the MQTT broker is running (often 1883).
27
+ */
28
+ MqttConnection(const std::string& host, int port, const std::string& clientId);
29
+
30
+ virtual ~MqttConnection();
31
+
32
+ /*! Publish a message to the MQTT broker.
33
+ * \param topic the topic of the message.
34
+ * \param payload is the payload body of the message.
35
+ * \param qos the MQTT quality of service value between 0 and 2 inclusive.
36
+ * \param retain an indicator that the MQTT broker should retain the message.
37
+ * \param optCorrelationId Optional correlation ID string that will be used to associate responses to requests.
38
+ * \param optResponseTopic Optional MQTT topic used for publishing responses to requests.
39
+ * \param optReturnValue Optional (predetermined) value for the result of a method call.
40
+ * \return A future which is resolved to true when the message has been published to the MQTT broker.
41
+ */
42
+ virtual boost::future<bool> Publish(
43
+ const std::string& topic,
44
+ const std::string& payload,
45
+ unsigned qos,
46
+ bool retain,
47
+ boost::optional<std::string> optCorrelationId,
48
+ boost::optional<std::string> optResponseTopic,
49
+ boost::optional<MethodResultCode> optResultCode);
50
+
51
+ /*! Subscribe to a topic.
52
+ * \param topic the subscription topic.
53
+ * \param qos an MQTT quality of service value between 0 and 2 inclusive.
54
+ */
55
+ virtual void Subscribe(const std::string& topic, int qos);
56
+
57
+ /*! Add a function that is called on the receipt of a message.
58
+ * Many callbacks can be added, and each will be called in the order in which the callbacks were added.
59
+ * \param cb the callback function.
60
+ */
61
+ virtual void AddMessageCallback(const std::function<void(const std::string&, const std::string&, const boost::optional<std::string>, const boost::optional<std::string>, const boost::optional<MethodResultCode>)>& cb);
62
+
63
+ /*! Determines if a topic string matches a subscription topic.
64
+ * \param topic a topic to match against a subscription.
65
+ * \param subscr the subscription topic string to match against.
66
+ * \return true if it is a match.
67
+ */
68
+ virtual bool TopicMatchesSubscription(const std::string& topic, const std::string& subscr) const;
69
+
70
+ virtual std::string GetClientId() const;
71
+ protected:
72
+ /*! Establishes the connection to the broker.
73
+ */
74
+ virtual void Connect();
75
+
76
+ private:
77
+ class MqttMessage : private boost::noncopyable
78
+ {
79
+ public:
80
+ MqttMessage(const std::string& topic, const std::string& payload, int qos, bool retain, boost::optional<std::string> optCorrelationId, boost::optional<std::string> optResponseTopic) : _topic(topic), _payload(payload), _qos(qos), _retain(retain), _optCorrelationId(optCorrelationId), _optResponseTopic(optResponseTopic) {}
81
+ MqttMessage(const MqttMessage& other) : _topic(other._topic), _payload(other._payload), _qos(other._qos), _retain(other._retain), _pSentPromise(other._pSentPromise) {}
82
+ virtual ~MqttMessage() = default;
83
+ boost::future<bool> getFuture() { return _pSentPromise->get_future(); };
84
+ std::string _topic;
85
+ std::string _payload;
86
+ int _qos;
87
+ bool _retain;
88
+ std::shared_ptr<boost::promise<bool>> _pSentPromise;
89
+ boost::optional<std::string> _optCorrelationId;
90
+ boost::optional<std::string> _optResponseTopic;
91
+ };
92
+
93
+ struct MqttSubscription
94
+ {
95
+ MqttSubscription(const std::string& topic, int qos) : _topic(topic), _qos(qos) {}
96
+ ~MqttSubscription() = default;
97
+ std::string _topic;
98
+ int _qos;
99
+ int subscription_id;
100
+ };
101
+
102
+ mosquitto *_mosq;
103
+ std::string _host;
104
+ int _port;
105
+ std::string _clientId;
106
+ std::queue<MqttSubscription> _subscriptions;
107
+ boost::mutex _mutex;
108
+ std::vector<std::function<void(const std::string&, const std::string&, const boost::optional<std::string>, const boost::optional<std::string>, const boost::optional<MethodResultCode>)>> _messageCallbacks;
109
+ std::queue<MqttMessage> _msgQueue;
110
+ std::map<int, std::shared_ptr<boost::promise<bool>>> _sendMessages;
111
+ };
112
+
113
+ {%for broker in stinger.brokers.values()%}
114
+ /*! This class presents a connection to a MQTT broker.
115
+ */
116
+ class {{broker.class_name}} : public MqttConnection
117
+ {
118
+ public:
119
+
120
+ /*! Constructor for a {{broker.class_name}}.
121
+ {%-if broker.hostname is none%}
122
+ * \param hostname IP address or hostname of the MQTT broker server.
123
+ {%-endif%}
124
+ {%-if broker.port is none%}
125
+ * \param port Port where the MQTT broker is running (often 1883).
126
+ {%-endif%}
127
+ */
128
+ {{broker.class_name}}({%if broker.hostname is none%}const std::string& host, int port, {%endif%}const std::string& clientId);
129
+
130
+ virtual ~{{broker.class_name}}() = default;
131
+ };
132
+ {%endfor%}
@@ -0,0 +1,53 @@
1
+
2
+ #pragma once
3
+
4
+ #include <cstdint>
5
+ #include <functional>
6
+ #include <map>
7
+ #include <memory>
8
+ #include <exception>
9
+ #include <mutex>
10
+ #include <rapidjson/document.h>
11
+ #include <boost/uuid/uuid.hpp>
12
+
13
+ #include "ibrokerconnection.hpp"
14
+ #include "enums.hpp"
15
+ #include "return_types.hpp"
16
+
17
+ class {{stinger.name | UpperCamelCase}}Client {
18
+
19
+ public:
20
+ // This is the name of the API.
21
+ static constexpr const char NAME[] = "{{stinger.name}}";
22
+ // This is the version of the API contract.
23
+ static constexpr const char INTERFACE_VERSION[] = "{{stinger.version}}";
24
+
25
+ // Constructor taking a connection object.
26
+ {{stinger.name | UpperCamelCase}}Client(std::shared_ptr<IBrokerConnection> broker);
27
+
28
+ virtual ~{{stinger.name | UpperCamelCase}}Client() = default;
29
+
30
+ {%for sig_name, sig in stinger.signals.items()%}
31
+ // Register a callback for the `{{sig_name}}` signal.
32
+ // The provided method will be called whenever a `{{sig_name}}` is received.
33
+ void register{{sig_name | UpperCamelCase}}Callback(const std::function<void({%for arg in sig.arg_list%}{{arg.cpp_type}}{%if not loop.last%}, {%endif%}{%endfor%})>& cb);
34
+ {%endfor%}
35
+
36
+ {%for method_name, method in stinger.methods.items()%}
37
+ // Calls the `{{method_name}}` method.
38
+ // Returns a future. When that future resolves, it will have the returned value.
39
+ boost::future<{{method.return_value_cpp_class}}> {{method_name | camelCase}}({%for arg in method.arg_list%}{{arg.cpp_type}} {{arg.name}}{%if not loop.last%}, {%endif%}{%endfor%});
40
+ {%endfor%}
41
+ private:
42
+ std::shared_ptr<IBrokerConnection> _broker;
43
+ void _receiveMessage(const std::string& topic, const std::string& payload, const boost::optional<std::string> optCorrelationId, const boost::optional<MethodResultCode> optResultCode);
44
+ {%-for method_name, method in stinger.methods.items()%}
45
+ std::map<boost::uuids::uuid, boost::promise<{{method.return_value_cpp_class}}>> _pending{{method_name|UpperCamelCase}}MethodCalls;
46
+ {%-endfor%}
47
+ {%for sig_name, sig in stinger.signals.items()%}
48
+ std::function<void({%for arg in sig.arg_list%}{{arg.cpp_type}}{%if not loop.last%}, {%endif%}{%endfor%})> _{{sig_name | camelCase}}Callback;
49
+ {%endfor%}
50
+ {%-for method_name, method in stinger.methods.items()%}
51
+ void _handle{{method_name|UpperCamelCase}}Response(const std::string& topic, const std::string& payload, const std::string& optCorrelationId);
52
+ {%-endfor%}
53
+ };
@@ -0,0 +1,17 @@
1
+ /*
2
+ DO NOT MODIFY THIS FILE. It is automatically generated and changes will be over-written
3
+ on the next generation.
4
+
5
+ It contains enumerations used by the {{stinger.name}} interface.
6
+ */
7
+
8
+ #pragma once
9
+
10
+ {%for ie_name, ie in stinger.enums.items() %}
11
+ enum class {{ie_name | UpperCamelCase }} {
12
+ {%-for value in ie.values %}
13
+ {{value | CONST_CASE}} = {{loop.index}}{%if not loop.last%},{%endif%}
14
+ {%-endfor%}
15
+ };
16
+ static const char *{{ie_name | camelCase }}Strings[] = {"{{ie_name | UpperCamelCase }}", {%for value in ie.values %}"{{value}}"{%if not loop.last%}, {%endif%}{%endfor%} };
17
+ {%endfor%}
@@ -0,0 +1,42 @@
1
+
2
+ #pragma once
3
+
4
+ #include <functional>
5
+ #include <string>
6
+
7
+ #define BOOST_THREAD_PROVIDES_FUTURE
8
+ #include <boost/thread/future.hpp>
9
+ #include <boost/optional.hpp> // Include the Boost.Optional header
10
+
11
+ enum class MethodResultCode
12
+ {
13
+ {%-for rc_i, rc_name in stinger.method_return_codes.items()%}
14
+ {{rc_name | CONST_CASE}} = {{rc_i}}{%if not loop.last%},{%endif%}
15
+ {%-endfor%}
16
+ };
17
+
18
+ class IBrokerConnection
19
+ {
20
+ public:
21
+ /*! Publish to a topic.
22
+ * Implementations should queue up messages when not connected.
23
+ */
24
+ virtual boost::future<bool> Publish(const std::string& topic, const std::string& payload, unsigned qos, bool retain, boost::optional<std::string> optCorrelationId, boost::optional<std::string> optResponseTopic, boost::optional<MethodResultCode> optResultCode) = 0;
25
+
26
+ /*! Subscribe to a topic.
27
+ * Implementation should queue up subscriptions when not connected.
28
+ */
29
+ virtual void Subscribe(const std::string& topic, int qos) = 0;
30
+
31
+ /*! Provide a callback to be called on an incoming message.
32
+ * Implementation should accept this at any time, even when not connected.
33
+ */
34
+ virtual void AddMessageCallback(const std::function<void(const std::string&, const std::string&, const boost::optional<std::string>, const boost::optional<std::string>, const boost::optional<MethodResultCode>)>& cb) = 0;
35
+
36
+ /*! Utility for matching topics.
37
+ * This probably should be a wrapper around `mosquitto_topic_matches_sub` or similar
38
+ */
39
+ virtual bool TopicMatchesSubscription(const std::string& topic, const std::string& subscr) const = 0;
40
+
41
+ virtual std::string GetClientId() const = 0;
42
+ };
@@ -0,0 +1,14 @@
1
+
2
+ #pragma once
3
+ #include <string>
4
+ #include "enums.hpp"
5
+
6
+ {%for method_name, method in stinger.methods.items()%}
7
+ {%-if method.return_value_type == 'struct'%}
8
+ struct {{method.return_value_name | UpperCamelCase}} {
9
+ {%-for rv in method.return_value %}
10
+ {{rv.cpp_temp_type}} {{rv.name}};
11
+ {%-endfor%}
12
+ };
13
+ {%endif%}
14
+ {%-endfor%}
@@ -0,0 +1,44 @@
1
+
2
+ #pragma once
3
+
4
+ #include <cstdint>
5
+ #include <functional>
6
+ #include <map>
7
+ #include <string>
8
+ #include <memory>
9
+ #include <exception>
10
+ #include <mutex>
11
+ #include <boost/optional.hpp>
12
+ #include <rapidjson/document.h>
13
+
14
+ #include "ibrokerconnection.hpp"
15
+ #include "enums.hpp"
16
+ #include "return_types.hpp"
17
+
18
+ class {{stinger.name | UpperCamelCase}}Server {
19
+
20
+ public:
21
+ static constexpr const char NAME[] = "{{stinger.name}}";
22
+ static constexpr const char INTERFACE_VERSION[] = "{{stinger.version}}";
23
+
24
+ {{stinger.name | UpperCamelCase}}Server(std::shared_ptr<IBrokerConnection> broker);
25
+
26
+ virtual ~{{stinger.name | UpperCamelCase}}Server() = default;
27
+
28
+ {%for sig_name, sig in stinger.signals.items()%}
29
+ boost::future<bool> emit{{sig_name | UpperCamelCase}}Signal({%for arg in sig.arg_list%}{{arg.cpp_type}}{%if not loop.last%}, {%endif%}{%endfor%});
30
+ {%endfor%}
31
+
32
+ {%for method_name, method in stinger.methods.items()%}
33
+ void register{{method_name | UpperCamelCase}}Handler(std::function<{{method.return_value_cpp_class}}({%for arg in method.arg_list%}{{arg.cpp_type}}{%if not loop.last%}, {%endif%}{%endfor%})> func);
34
+ {%endfor%}
35
+ private:
36
+ std::shared_ptr<IBrokerConnection> _broker;
37
+ void _receiveMessage(const std::string& topic, const std::string& payload, const boost::optional<std::string> optCorrelationId, const boost::optional<std::string> optResponseTopic);
38
+
39
+ {%for method_name, method in stinger.methods.items()%}
40
+ void _call{{method_name | UpperCamelCase}}Handler(const std::string& topic, const rapidjson::Document& doc, boost::optional<std::string> clientId, boost::optional<std::string> correlationId) const;
41
+ std::function<{{method.return_value_cpp_class}}({%for arg in method.arg_list%}{{arg.cpp_type}}{%if not loop.last%}, {%endif%}{%endfor%})> _{{method_name | camelCase}}Handler;
42
+ {%endfor%}
43
+
44
+ };
@@ -0,0 +1,13 @@
1
+
2
+ #pragma once
3
+ #include <string>
4
+ #include <boost/optional.hpp>
5
+ #include "enums.hpp"
6
+
7
+ {%for istruct_name, istruct in stinger.structs.items() %}
8
+ struct {{istruct_name | UpperCamelCase }} {
9
+ {%-for value in istruct.members %}
10
+ {{value.cpp_temp_type}} {{value.name}};
11
+ {%-endfor%}
12
+ };
13
+ {%endfor%}