Comments (2)
As I see it in your code, the important part from lua seems to be that you need to only be able to bind arbitrary lua function to a signal regardless of what that signal is as long as the signal is exposed to lua.
A problem is that you cannot access templated classes without knowing the template parameters, which are the types that you cannot get from lua. You are basically required to do any binding for templated classes beforehand or you must know/have a predetermined logic to come up with the template signature in the function you bind. There are different kinds of things you can do depending on what you need. There might be some way to get around to what you need using templates, but off the top of my head I didnt come up with any that did not seem impractical (for example make a map of template instanciations that are then available to lua through a map of sorts).
Instead, here is one simple example that utilizes a inheritance to implement a non-templated base class for lua while maintaining the typed C++ counterpart in the templated subclass. It allows you to bind the functionality required by lua through the base class only once, enabling you to connect functions to any signal exposed into lua regardless of its types. Maybe its what you need, or maybe it gives you inspiration for something cooler :)
#include <limits>
#include <functional>
#define SOL_ALL_SAFETIES_ON 1
#include <sol/sol.hpp>
#include <iostream>
class SignalBase {
public:
void connectLua(sol::protected_function fn) {
luaHandlers.push_back(fn);
}
protected:
std::vector<sol::protected_function> luaHandlers;
};
template<class... TArgs>
class Signal : public SignalBase {
using Handler = std::function<void(TArgs &...)>;
public:
void connect(Handler &&handler) {
handlers.push_back(handler);
}
void notify(TArgs... args) {
for (auto handler: handlers) {
handler(args...);
}
for (auto handler: luaHandlers) {
handler(args...);
}
}
private:
std::vector<Handler> handlers;
};
int main() {
sol::state state;
state.open_libraries();
auto usertype = state.new_usertype<SignalBase>("Signal", sol::no_constructor);
usertype["connect"] = &SignalBase::connectLua;
Signal<float, uint32_t> signal;
state["mySignal"] = std::reference_wrapper<SignalBase>(signal); // NOTE we have to cast or explicitly state here that we want SignalBase as otherwise sol will think its a different type because of the template class
signal.connect([](float a, uint32_t b) {
std::cout << "App: " << a << " " << b << "\n";
});
state.script(R"(
mySignal:connect(function(a, b)
print('Lua: ', a, b)
end)
)");
signal.notify(10.0f, 20);
return 0;
}
from sol2.
I ended up doing a a weird implementation with lambdas. One of the things that I wanted to also do was to make the lua signal "proxy" to consume the internal Signal (the example below is simplified but I pass more than just the original signal to the SolSignal class):
template<class... TArgs>
class Signal {
using Handler = std::function<void(TArgs &...)>;
public:
void connect(Handler &&handler) {
auto id = handlers.size();
handlers.push_back(handler);
}
void notify(TArgs... args) {
for (auto handler: handlers) {
handler(args...);
}
}
private:
std::vector<Handler> handlers;
};
class SolSignal {
public:
template<class... TArgs>
SolSignal(Signal<TArgs...> &signal) {
mConnector = [&signal](sol::protected_function fn) {
return signal.connect([fn](TArgs &...args) {
fn(args...);
});
};
}
SignalSlot connect(sol::protected_function fn) {
return mConnector(fn);
}
private:
std::function<SignalSlot(sol::protected_function)> mConnector;
};
int main() {
sol::state state;
state.open_libraries();
auto usertype = state.new_usertype<SolSignal>("Signal", sol::no_constructor);
usertype["connect"] = &SolSignal::connect;
Signal<float, uint32_t> signal;
state["mySignal"] = SolSignal(signal);
signal.connect([](float a, uint32_t b) {
std::cout << "App: " << a << " " << b << "\n";
});
state.script(R"(
mySignal:connect(function(a, b)
print('Lua: ', a, b)
end)
)");
signal.notify(10.0f, 20);
return 0;
}
But I might try inheritance as well. Maybe I can make it work with it since I have kind of made my own dynamic dispatch here and if I can, I would want to use the language feature itself :)
from sol2.
Related Issues (20)
- why is get_type return userdata?
- Build with emscripten? HOT 2
- Emscripten/Clang error on setting usertype member variable HOT 4
- Returned Derived Shared Pointer is Nil HOT 1
- AllocConsole and freopen mess up input/output operations HOT 1
- ADL Customization breaks with `std::vector` and usertype fields
- How to print Error Messages? I am not getting any. HOT 2
- How can I create my own print function in Sol3? HOT 1
- Error when lua require("interop")
- Missing documentation for using Sol to write Lua C libraries HOT 2
- Definition SOL_SAFE_USERTYPE is 0, sol compilation fails HOT 3
- Panic with multiple states HOT 1
- Segfault from protected_function args push HOT 2
- std::terminate called on attempting to index a nil value HOT 2
- Doesn't build with Clang 18.1.0 HOT 10
- Not able to build with CMake HOT 4
- How to pass Lua Closures into C++ Functions in Sol3 ? HOT 4
- Test failure on x86
- Custom module loaders not working? HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from sol2.