Inital commit. Meisten features sind implementiert und müssen getestet werden
This commit is contained in:
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
.vscode
|
||||||
|
CMakeFiles
|
||||||
|
build
|
||||||
18
CMakeLists.txt
Normal file
18
CMakeLists.txt
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.10)
|
||||||
|
project(thrawn)
|
||||||
|
|
||||||
|
set(CMAKE_CXX_STANDARD 17)
|
||||||
|
set(CMAKE_EXPORT_COMPILE_COMMANDS true)
|
||||||
|
|
||||||
|
include_directories("/usr/local/include")
|
||||||
|
include_directories("/usr/local/include/mqttpp-0.1")
|
||||||
|
link_directories("/usr/local/lib/mqttpp-0.1")
|
||||||
|
|
||||||
|
find_package(spdlog CONFIG REQUIRED)
|
||||||
|
include(FindLua)
|
||||||
|
find_package(lua REQUIRED)
|
||||||
|
|
||||||
|
add_executable(thrawn src/main.cpp src src/thrawn_api.cpp src/Service.cpp src/Cache.cpp src/LuaEngine.cpp)
|
||||||
|
target_link_libraries(thrawn ${LIBS} spdlog::spdlog ${LUA_LIBRARIES} mqttpp)
|
||||||
|
target_include_directories(thrawn PRIVATE ${LUA_INCLUDE_DIR})
|
||||||
|
install(TARGETS thrawn DESTINATION bin)
|
||||||
28
src/Cache.cpp
Normal file
28
src/Cache.cpp
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
#include "Cache.h"
|
||||||
|
#include <algorithm>
|
||||||
|
std::vector<TopicState> Cache::topic_states(std::vector<std::string>& topics) {
|
||||||
|
std::vector<TopicState> states;
|
||||||
|
|
||||||
|
for (const auto& topic : topics) {
|
||||||
|
auto hit = std::find_if(cache.begin(), cache.end(), [&](TopicState& cache_state) {
|
||||||
|
return cache_state.topic == topic;
|
||||||
|
});
|
||||||
|
if (hit != cache.end()) {
|
||||||
|
states.push_back(*hit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return states;
|
||||||
|
}
|
||||||
|
|
||||||
|
TopicState Cache::set_topic_value(const std::string& topic, const std::string& value) {
|
||||||
|
for (auto& state : cache) {
|
||||||
|
if (state.topic == topic) {
|
||||||
|
state.value = value;
|
||||||
|
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return cache.emplace_back(topic, value);
|
||||||
|
}
|
||||||
14
src/Cache.h
Normal file
14
src/Cache.h
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
#if !defined(CACHE_H)
|
||||||
|
#define CACHE_H
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include "Service.h"
|
||||||
|
class Cache {
|
||||||
|
private:
|
||||||
|
std::vector<TopicState> cache;
|
||||||
|
public:
|
||||||
|
std::vector<TopicState> topic_states(std::vector<std::string>& topics);
|
||||||
|
TopicState set_topic_value(const std::string& topic, const std::string& value);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // CACHE_H
|
||||||
32
src/LuaEngine.cpp
Normal file
32
src/LuaEngine.cpp
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
#include "LuaEngine.h"
|
||||||
|
|
||||||
|
LuaEngine::LuaEngine() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void LuaEngine::load_services() {
|
||||||
|
for (auto& service : services) {
|
||||||
|
service.load();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LuaEngine::start_services() {
|
||||||
|
for (auto& service : services) {
|
||||||
|
service.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LuaService* LuaEngine::create_service(std::string filename) {
|
||||||
|
services.emplace_back(filename);
|
||||||
|
|
||||||
|
return &services.back();
|
||||||
|
}
|
||||||
|
|
||||||
|
LuaService* LuaEngine::service_by_lua_state(lua_State* lua) {
|
||||||
|
for (auto& service : services) {
|
||||||
|
if (service.lua == lua) {
|
||||||
|
return &service;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
32
src/LuaEngine.h
Normal file
32
src/LuaEngine.h
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
#if !defined(LUA_ENGINE_H)
|
||||||
|
#define LUA_ENGINE_H
|
||||||
|
#include "Service.h"
|
||||||
|
#include "Cache.h"
|
||||||
|
#include <vector>
|
||||||
|
#include <functional>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
class LuaEngine {
|
||||||
|
private:
|
||||||
|
LuaEngine();
|
||||||
|
public:
|
||||||
|
std::function<void(const TopicState& state)> publish;
|
||||||
|
static LuaEngine& get_instance() {
|
||||||
|
static LuaEngine instance;
|
||||||
|
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
std::vector<LuaService> services;
|
||||||
|
|
||||||
|
Cache cache;
|
||||||
|
|
||||||
|
void load_services();
|
||||||
|
void start_services();
|
||||||
|
LuaService* create_service(std::string filename);
|
||||||
|
LuaService* service_by_lua_state(lua_State* lua);
|
||||||
|
|
||||||
|
LuaEngine(LuaEngine const&) = delete;
|
||||||
|
void operator=(LuaEngine const&) = delete;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // LUA_ENGINE_H
|
||||||
110
src/Service.cpp
Normal file
110
src/Service.cpp
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
#include "Service.h"
|
||||||
|
#include <iostream>
|
||||||
|
#include "thrawn_api.h"
|
||||||
|
#include "spdlog/spdlog.h"
|
||||||
|
|
||||||
|
std::string TopicState::to_string() {
|
||||||
|
std::string str = "[ Topic: '";
|
||||||
|
str += this->topic;
|
||||||
|
str += "', Value: '";
|
||||||
|
str += this->value;
|
||||||
|
str +="' ]";
|
||||||
|
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<TopicState> TopicState::create_from_lua(lua_State* lua, int lua_table_stack_index) {
|
||||||
|
if (! lua_istable(lua, lua_table_stack_index)) {
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
TopicState state;
|
||||||
|
|
||||||
|
lua_getfield(lua, lua_table_stack_index, "topic");
|
||||||
|
state.topic = lua_tostring(lua, -1);
|
||||||
|
lua_pop(lua, 1);
|
||||||
|
|
||||||
|
lua_getfield(lua, lua_table_stack_index, "value");
|
||||||
|
state.value = lua_tostring(lua, -1);
|
||||||
|
lua_pop(lua, 1);
|
||||||
|
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
LuaService::LuaService(std::string filename) {
|
||||||
|
lua = luaL_newstate();
|
||||||
|
name = "";
|
||||||
|
started = false;
|
||||||
|
loaded = false;
|
||||||
|
|
||||||
|
luaL_openlibs(lua);
|
||||||
|
|
||||||
|
lua_pushcfunction(lua, thrawn_log);
|
||||||
|
lua_setglobal(lua, "thrawn_log");
|
||||||
|
|
||||||
|
lua_pushcfunction(lua, thrawn_register_service);
|
||||||
|
lua_setglobal(lua, "thrawn_register_service");
|
||||||
|
|
||||||
|
lua_pushcfunction(lua, thrawn_subscribe);
|
||||||
|
lua_setglobal(lua, "thrawn_subscribe");
|
||||||
|
|
||||||
|
lua_pushcfunction(lua, thrawn_publish);
|
||||||
|
lua_setglobal(lua, "thrawn_publish");
|
||||||
|
|
||||||
|
lua_pushcfunction(lua, thrawn_create_topic_state);
|
||||||
|
lua_setglobal(lua, "thrawn_create_topic_state");
|
||||||
|
|
||||||
|
lua_pushcfunction(lua, thrawn_topic_state_str);
|
||||||
|
lua_setglobal(lua, "thrawn_topic_state_str");
|
||||||
|
|
||||||
|
lua_pushcfunction(lua, thrawn_topic_cache);
|
||||||
|
lua_setglobal(lua, "thrawn_topic_cache");
|
||||||
|
|
||||||
|
|
||||||
|
if (luaL_loadfile(lua, filename.c_str()) != 0) {
|
||||||
|
throw std::runtime_error("Error during loading of '" + filename + "' - [Lua error: '" + lua_tostring(lua,-1) + "'].");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LuaService::~LuaService() {
|
||||||
|
if (lua != nullptr) {
|
||||||
|
lua_close(lua);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LuaService::LuaService(LuaService&& service) noexcept {
|
||||||
|
lua = service.lua;
|
||||||
|
service.lua = nullptr;
|
||||||
|
name = std::move(service.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
LuaService& LuaService::operator=(LuaService&& service) noexcept {
|
||||||
|
lua = service.lua;
|
||||||
|
service.lua = nullptr;
|
||||||
|
name = std::move(service.name);
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LuaService::load() {
|
||||||
|
if (!loaded) {
|
||||||
|
loaded = true;
|
||||||
|
|
||||||
|
if (lua_pcall(lua, 0, 0 ,0) != 0) {
|
||||||
|
spdlog::error("[{}] Unable to call 'lua_pcall()' in load(). [Lua: '{}']", name, lua_tostring(lua,-1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LuaService::start() {
|
||||||
|
if (!started && loaded) {
|
||||||
|
started = true;
|
||||||
|
call_thrawn_on_start(*this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LuaService::on_update(const TopicState& state) {
|
||||||
|
if (started && loaded) {
|
||||||
|
call_thrawn_on_update(*this, state);
|
||||||
|
}
|
||||||
|
}
|
||||||
50
src/Service.h
Normal file
50
src/Service.h
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
#if !defined(SERVICE_H)
|
||||||
|
#define SERVICE_H
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#include <lua.h>
|
||||||
|
#include <lualib.h>
|
||||||
|
#include <lauxlib.h>
|
||||||
|
}
|
||||||
|
#include <string>
|
||||||
|
#include <memory>
|
||||||
|
#include <vector>
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
|
struct TopicState {
|
||||||
|
std::string topic;
|
||||||
|
std::string value;
|
||||||
|
|
||||||
|
TopicState() : topic(""), value(""){}
|
||||||
|
TopicState(const std::string& topic, const std::string& value) : topic(topic), value(value){}
|
||||||
|
|
||||||
|
static std::optional<TopicState> create_from_lua(lua_State* lua, int lua_table_stack_index);
|
||||||
|
|
||||||
|
std::string to_string();
|
||||||
|
};
|
||||||
|
|
||||||
|
struct LuaService {
|
||||||
|
public:
|
||||||
|
lua_State* lua;
|
||||||
|
std::string name;
|
||||||
|
std::vector<std::string> subscriptions;
|
||||||
|
|
||||||
|
LuaService(std::string filename);
|
||||||
|
~LuaService();
|
||||||
|
|
||||||
|
LuaService(const LuaService&) = delete;
|
||||||
|
LuaService& operator=(const LuaService&) = delete;
|
||||||
|
LuaService(LuaService&&) noexcept; //Noexcept is important because of std::vector
|
||||||
|
LuaService& operator=(LuaService&&) noexcept; //Noexcept is important because of std::vector
|
||||||
|
|
||||||
|
void load();
|
||||||
|
void start();
|
||||||
|
void on_update(const TopicState& topic_state);
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool loaded;
|
||||||
|
bool started;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // SERVICE_H
|
||||||
8
src/Version.h
Normal file
8
src/Version.h
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
#if !defined(VERSION_H)
|
||||||
|
#define VERSION_H
|
||||||
|
|
||||||
|
#define THRAWN_MAJOR_VERSION 1
|
||||||
|
#define THRAWN_MINOR_VERSION 0
|
||||||
|
#define THRAWN_PATCH_VERSION 0
|
||||||
|
|
||||||
|
#endif // VERSION_H
|
||||||
111
src/main.cpp
Normal file
111
src/main.cpp
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
#include <iostream>
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
#include "Service.h"
|
||||||
|
#include "thrawn_api.h"
|
||||||
|
#include "mqttpp.h"
|
||||||
|
#include "spdlog/spdlog.h"
|
||||||
|
#include "Cache.h"
|
||||||
|
#include "LuaEngine.h"
|
||||||
|
#include <filesystem>
|
||||||
|
#include "Version.h"
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
std::vector<std::string> lua_scripts_in_folder(const std::string& path_str) {
|
||||||
|
std::vector<std::string> scripts;
|
||||||
|
|
||||||
|
std::filesystem::path scripts_folder(path_str);
|
||||||
|
|
||||||
|
if (std::filesystem::exists(scripts_folder)) {
|
||||||
|
for (const auto& file: std::filesystem::directory_iterator(scripts_folder)) {
|
||||||
|
if (file.is_regular_file() && file.path().extension() == ".lua") {
|
||||||
|
scripts.push_back(file.path().string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
throw std::invalid_argument("Folder '" + path_str + "' does not exist.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return scripts;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char* argv[]) {
|
||||||
|
std::string services_path_str = "/etc/thrawn";
|
||||||
|
std::string mqttServerURI = "tcp://chimaera:1883";
|
||||||
|
mqttpp::LastWill last_will {mqttServerURI, "0"};
|
||||||
|
std::string lastWillConnected = "1";
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Parsing arguments
|
||||||
|
* Show version or load path
|
||||||
|
*/
|
||||||
|
if (argc > 1) {
|
||||||
|
if (strcmp(argv[1], "-v") == 0 || strcmp(argv[1], "--version") == 0) {
|
||||||
|
std::cout << "Version: " << THRAWN_MAJOR_VERSION << "." << THRAWN_MINOR_VERSION << "." << THRAWN_PATCH_VERSION << std::endl;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
services_path_str = argv[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MQTT
|
||||||
|
*/
|
||||||
|
spdlog::info("Starting MQTT connection to '{}' .", mqttServerURI);
|
||||||
|
|
||||||
|
mqttpp::Client mqtt(mqttServerURI, last_will);
|
||||||
|
|
||||||
|
if (! mqtt.connect()) {
|
||||||
|
spdlog::error("Failed to establishe mqtt connection to ‘{}'", mqttServerURI);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
mqtt.publish(last_will.topic, lastWillConnected);
|
||||||
|
mqtt.subscribe("#", [&] (const char* topic, const std::string& msg) {
|
||||||
|
LuaEngine::get_instance().cache.set_topic_value(topic, msg);
|
||||||
|
|
||||||
|
for (auto& service : LuaEngine::get_instance().services) {
|
||||||
|
for (const std::string& sub_topic : service.subscriptions) {
|
||||||
|
if (sub_topic == topic) {
|
||||||
|
service.on_update(TopicState(topic, msg));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
LuaEngine::get_instance().publish = [&](const TopicState& state) {
|
||||||
|
mqtt.publish(state.topic, state.value);
|
||||||
|
};
|
||||||
|
|
||||||
|
spdlog::info("Connection to MQTT server '{}' successfull.", mqttServerURI);
|
||||||
|
|
||||||
|
try {
|
||||||
|
for (const auto& script : lua_scripts_in_folder(services_path_str)) {
|
||||||
|
LuaEngine::get_instance().create_service(script);
|
||||||
|
}
|
||||||
|
}catch(const std::exception& e) {
|
||||||
|
spdlog::error(e.what());
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* LUA Engine
|
||||||
|
*/
|
||||||
|
spdlog::info("Starting Thrawn services on Chimaera.");
|
||||||
|
|
||||||
|
LuaEngine::get_instance().load_services();
|
||||||
|
|
||||||
|
spdlog::info("{} service(s) loaded.", LuaEngine::get_instance().services.size());
|
||||||
|
|
||||||
|
LuaEngine::get_instance().start_services();
|
||||||
|
|
||||||
|
spdlog::info("All services loaded.");
|
||||||
|
|
||||||
|
while (true) {}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
191
src/thrawn_api.cpp
Normal file
191
src/thrawn_api.cpp
Normal file
@@ -0,0 +1,191 @@
|
|||||||
|
#include "thrawn_api.h"
|
||||||
|
#include <iostream>
|
||||||
|
#include "Cache.h"
|
||||||
|
#include "LuaEngine.h"
|
||||||
|
#include "spdlog/spdlog.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
HELPER
|
||||||
|
*/
|
||||||
|
void push_topic_state_table(lua_State* lua, TopicState state) {
|
||||||
|
lua_newtable(lua);
|
||||||
|
lua_pushliteral(lua, "topic");
|
||||||
|
lua_pushstring(lua, state.topic.c_str());
|
||||||
|
lua_settable(lua, -3);
|
||||||
|
|
||||||
|
lua_pushliteral(lua, "value");
|
||||||
|
lua_pushstring(lua, state.value.c_str());
|
||||||
|
lua_settable(lua, -3);
|
||||||
|
}
|
||||||
|
|
||||||
|
void push_list_topic_state(lua_State* lua, std::vector<TopicState> states) {
|
||||||
|
lua_newtable(lua);
|
||||||
|
|
||||||
|
int i = 1;
|
||||||
|
for (auto& state : states) {
|
||||||
|
lua_pushinteger(lua, i);
|
||||||
|
push_topic_state_table(lua, state);
|
||||||
|
lua_settable(lua, -3);
|
||||||
|
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Ab hier ist ok
|
||||||
|
int thrawn_log(lua_State* lua)
|
||||||
|
{
|
||||||
|
int paramCount = lua_gettop(lua);
|
||||||
|
|
||||||
|
if(paramCount != 1)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!lua_isstring (lua, -1)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
spdlog::info("[{}] {}", LuaEngine::get_instance().service_by_lua_state(lua)->name, lua_tostring(lua, -1));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int thrawn_register_service(lua_State* lua) {
|
||||||
|
int paramCount = lua_gettop(lua);
|
||||||
|
|
||||||
|
if(paramCount != 1)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
LuaEngine::get_instance().service_by_lua_state(lua)->name = lua_tostring(lua, -1);
|
||||||
|
|
||||||
|
spdlog::info("Service '{}' registered", lua_tostring(lua, -1));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int thrawn_create_topic_state(lua_State* lua) {
|
||||||
|
int paramCount = lua_gettop(lua);
|
||||||
|
|
||||||
|
if(paramCount < 0 || paramCount > 3)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
TopicState state;
|
||||||
|
|
||||||
|
if (paramCount == 1) {
|
||||||
|
if (!lua_isstring (lua, -1)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
state.topic = lua_tostring(lua, -1);
|
||||||
|
}else if (paramCount == 2) {
|
||||||
|
if (!lua_isstring (lua, -2) && !lua_isstring (lua, -1)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
state.topic = lua_tostring(lua, -2);
|
||||||
|
state.value = lua_tostring(lua, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
push_topic_state_table(lua, state);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int thrawn_topic_state_str(lua_State* lua) {
|
||||||
|
int paramCount = lua_gettop(lua);
|
||||||
|
|
||||||
|
if(paramCount != 1)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<TopicState> state = TopicState::create_from_lua(lua, -1);
|
||||||
|
|
||||||
|
if (! state.has_value()) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_pushstring(lua, state.value().to_string().c_str());
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int thrawn_subscribe(lua_State* lua) {
|
||||||
|
int paramCount = lua_gettop(lua);
|
||||||
|
|
||||||
|
if(paramCount != 1){
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
LuaService* service = LuaEngine::get_instance().service_by_lua_state(lua);
|
||||||
|
|
||||||
|
if (service->name == "") {
|
||||||
|
spdlog::error("Not registered service tried to subscribe to '{}'", lua_tostring(lua, -1));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
service->subscriptions.push_back(lua_tostring(lua, -1));
|
||||||
|
|
||||||
|
spdlog::info("Service '{}' subscribed to '{}'", service->name, lua_tostring(lua, -1));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int thrawn_topic_cache(lua_State* lua) {
|
||||||
|
int paramCount = lua_gettop(lua);
|
||||||
|
|
||||||
|
if(paramCount != 0){
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
LuaEngine& lua_engine = LuaEngine::get_instance();
|
||||||
|
LuaService* service = lua_engine.service_by_lua_state(lua);
|
||||||
|
|
||||||
|
push_list_topic_state(lua, lua_engine.cache.topic_states(service->subscriptions));
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
// thrawn_publish(topic, value)
|
||||||
|
int thrawn_publish(lua_State* lua) {
|
||||||
|
int paramCount = lua_gettop(lua);
|
||||||
|
|
||||||
|
if (paramCount != 1) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<TopicState> state = TopicState::create_from_lua(lua, -1);
|
||||||
|
|
||||||
|
if (! state.has_value()) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
LuaEngine::get_instance().publish(state.value());
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void call_thrawn_on_start(LuaService& service) {
|
||||||
|
lua_getglobal(service.lua, "thrawn_on_start");
|
||||||
|
|
||||||
|
if (lua_pcall(service.lua,0, 0, 0) != 0) {
|
||||||
|
spdlog::error("[{}] Unable to call 'thrawn_on_start'. [Lua: '{}']", service.name, lua_tostring(service.lua,-1));
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void call_thrawn_on_update(LuaService& service, TopicState state) {
|
||||||
|
lua_getglobal(service.lua, "thrawn_on_update");
|
||||||
|
|
||||||
|
push_topic_state_table(service.lua, state);
|
||||||
|
|
||||||
|
if (lua_pcall(service.lua, 1, 0, 0) != 0) {
|
||||||
|
spdlog::error("[{}] Unable to call 'thrawn_on_update'. [Lua: '{}']", service.name, lua_tostring(service.lua,-1));
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
35
src/thrawn_api.h
Normal file
35
src/thrawn_api.h
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
#if !defined(THRAWN_API_H)
|
||||||
|
#define THRAWN_API_H
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#include <lua.h>
|
||||||
|
#include <lualib.h>
|
||||||
|
#include <lauxlib.h>
|
||||||
|
}
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
#include "Service.h"
|
||||||
|
|
||||||
|
//Functions for LUA
|
||||||
|
int thrawn_log(lua_State* lua);
|
||||||
|
|
||||||
|
int thrawn_register_service(lua_State* lua);
|
||||||
|
|
||||||
|
int thrawn_subscribe(lua_State* lua);
|
||||||
|
|
||||||
|
int thrawn_publish(lua_State* lua);
|
||||||
|
|
||||||
|
int thrawn_create_topic_state(lua_State* lua);
|
||||||
|
|
||||||
|
int thrawn_topic_state_str(lua_State* lua);
|
||||||
|
|
||||||
|
int thrawn_topic_cache(lua_State* lua);
|
||||||
|
|
||||||
|
// Function in LUA
|
||||||
|
void call_thrawn_on_start(LuaService& service);
|
||||||
|
|
||||||
|
void call_thrawn_on_update(LuaService& service, TopicState state);
|
||||||
|
|
||||||
|
#endif // THRAWN_API_H
|
||||||
Reference in New Issue
Block a user