Scott.McNab Posted April 4, 2018 Posted April 4, 2018 Currently it is possible to export a generic C++ function to UnigineScript with code similar to: auto SomeFunction(Unigine::Variable someParam) { // some logic return Unigine::Variable(); } ... Unigine::Interpreter::addExternFunction("SomeFunction", Unigine::MakeExternFunction(&SomeFunction)); It would be much more convenient if we could bind to C++ lambda functions instead, especially since then it would be possible to capture some variables from the surrounding scope: int someValue; ... Unigine::Interpreter::addExternFunction("SomeFunction", Unigine::MakeExternFunction([=](Unigine::Variable someParam) { // some logic that uses captured someValue return Unigine::Variable(...); })); However I can't seem to get this syntax to work. Do you have an example of how to export a lambda function to UnigineScript? Thanks! 1
unclebob Posted April 5, 2018 Posted April 5, 2018 Hi Scott! Try to specify lambda return type and function argument types as template parameters: using namespace Unigine; static int global_variable = 21; Interpreter::addExternFunction("SomeFunction", MakeExternFunction<Variable, const Variable &>([=](const Variable &v) -> Variable { return Variable(...); }));
Scott.McNab Posted April 5, 2018 Author Posted April 5, 2018 Hi unclebob I've just tried compiling your example code: Unigine::Interpreter::addExternFunction("SomeFunction", Unigine::MakeExternFunction<Unigine::Variable, const Unigine::Variable &>([=](const Unigine::Variable &v) -> Unigine::Variable { return Unigine::Variable(); })); However I get the following compiler error: Quote 1>source.cpp(264): error C2664: 'Unigine::ExternFunctionBase *Unigine::MakeExternFunction<Unigine::Variable,const Unigine::Variable&>(Ret (__cdecl *)(A0),const char *)': cannot convert argument 1 from 'rtvis::client::fe::plugin::ui::PluginMenuBar::ExposeScriptAPI::<lambda_565db0245ae61f563ff538f489911fe9>' to 'Unigine::Variable (__cdecl *)(const Unigine::Variable &)' 1> with 1> [ 1> Ret=Unigine::Variable, 1> A0=const Unigine::Variable & 1> ] 1>source.cpp(266): note: No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called 1>source.cpp(264): error C2660: 'Unigine::Interpreter::addExternFunction': function does not take 1 arguments Any idea how to fix this? FYI I'm using Visual Studio Professional 2017 15.5.7 with C++ Language Standard flag set to /std:c++17 Thanks
Scott.McNab Posted April 6, 2018 Author Posted April 6, 2018 FWIW I'm also seeing a similar error using Unigine::MakeCallback: int some_local_variable; button->setCallback0(Unigine::Gui::CLICKED, Unigine::MakeCallback<void>([=]() { ... // code that attempts to use captured some_local_variable })); This gives error: Quote 1>source.cpp(33): error C2664: 'Unigine::CallbackBase *Unigine::MakeCallback<void>(Ret (__cdecl *)(void))': cannot convert argument 1 from 'rtvis::client::fe::analysis::ui::AnalysisPluginView::RegisterGuiCallbacks::<lambda_939dbbdc65a76e8665aa9bbe2f4fe34d>' to 'void (__cdecl *)(void)' 1> with 1> [ 1> Ret=void 1> ] 1>source.cpp(35): note: No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called 1>source.cpp(33): error C2660: 'Unigine::Widget::setCallback0': function does not take 1 arguments Interestingly, if I remove the variable capture [=] from the lambda definition, it compiles OK, however it can't capture variables from the surrounding scope: button->setCallback0(Unigine::Gui::CLICKED, Unigine::MakeCallback<void>([]() { ... // Works, but can't capture variables from surrounding scope! })); Do you know how to get this working with a lambda function that captures variables from surrounding scope (not just static global variables)? Thanks
silent Posted April 6, 2018 Posted April 6, 2018 Hi Scott, Just checked with MSVS 2013 - and everything is working as expected. We can't add std::function into the API because it would brake the binary compatibility, sorry. We didn't have yet much time to check how else can it be improved with MSVS2017. If there will be any additional information - we would surely let you know. Sorry for the inconvenience caused. How to submit a good bug report --- FTP server for test scenes and user uploads: ftp://files.unigine.com user: upload password: 6xYkd6vLYWjpW6SN
Recommended Posts