maint: update deps

This commit is contained in:
Ahrimdon
2024-08-13 05:15:34 -04:00
parent 71843c3821
commit f0d2362fb5
8385 changed files with 2911785 additions and 7484 deletions

View File

@ -0,0 +1,21 @@
#define SOL_ALL_SAFETIES_ON 1
#include <sol/sol.hpp>
int main() {
struct callable {
int operator()(int a, bool b) {
return a + (b ? 10 : 20);
}
};
sol::state lua;
// Binds struct as userdata
// can still be callable, but beware
// caveats
lua.set("not_func", callable());
// Binds struct as function
lua.set("func", sol::as_function(callable()));
// equivalent: lua.set_function( "func", callable() );
// equivalent: lua["func"] = callable();
}

View File

@ -0,0 +1,29 @@
#define SOL_ALL_SAFETIES_ON 1
#include <sol/sol.hpp>
int main() {
class B {
public:
int bvar = 24;
};
sol::state lua;
lua.open_libraries(sol::lib::base);
lua.new_usertype<B>("B",
// bind as variable
"b",
&B::bvar,
// bind as function
"f",
sol::as_function(&B::bvar));
B b;
lua.set("b", &b);
lua.script(R"(x = b:f()
y = b.b
assert(x == 24)
assert(y == 24)
)");
return 0;
}

View File

@ -0,0 +1,17 @@
#define SOL_ALL_SAFETIES_ON 1
#include <sol/sol.hpp>
#include <vector>
int main(int, char*[]) {
sol::state lua;
lua.open_libraries();
lua.set("my_table",
sol::as_table(std::vector<int> { 1, 2, 3, 4, 5 }));
lua.script(
"for k, v in ipairs(my_table) do print(k, v) assert(k "
"== v) end");
return 0;
}

View File

@ -0,0 +1,52 @@
#define SOL_ALL_SAFTIES_ON 1
#include <sol/sol.hpp>
#include <iostream>
int main() {
const auto& co_lua_script = R"(
function loop()
while counter ~= 30
do
coroutine.yield(counter);
counter = counter + 1;
end
return counter
end
)";
sol::state lua;
lua.open_libraries(sol::lib::base, sol::lib::coroutine);
/*
lua.script_file("co.lua");
we load string directly rather than use a file
*/
lua.script(co_lua_script);
sol::coroutine loop_coroutine = lua["loop"];
// set counter variable in C++
// (can set it to something else to
// have loop_coroutine() yield different values)
lua["counter"] = 20;
// example of using and re-using coroutine
// you do not have to use coroutines in a loop,
// this is just the example
// we start from 0;
// we want 10 values, and we only want to
// run if the coroutine "loop_coroutine" is valid
for (int counter = 0; counter < 10 && loop_coroutine;
++counter) {
// Alternative: counter < 10 && cr.valid()
// Call the coroutine, does the computation and then
// suspends once it returns, we get the value back from
// the return and then can use it we can either leave
// the coroutine like that can come to it later, or
// loop back around
int value = loop_coroutine();
std::cout << "In C++: " << value << std::endl;
}
return 0;
}

View File

@ -0,0 +1,39 @@
#define SOL_ALL_SAFTIES_ON 1
#include <sol/sol.hpp>
#include <iostream>
int main() {
const auto& co_lua_script = R"(
function loop()
while counter ~= 30
do
coroutine.yield(counter);
counter = counter + 1;
end
return counter
end
)";
sol::state lua;
lua.open_libraries(sol::lib::base, sol::lib::coroutine);
/*
lua.script_file("co.lua");
we load string directly rather than use a file
*/
lua.script(co_lua_script);
sol::thread runner = sol::thread::create(lua.lua_state());
sol::state_view runnerstate = runner.state();
sol::coroutine loop_coroutine = runnerstate["loop"];
lua["counter"] = 20;
for (int counter = 0; counter < 10 && loop_coroutine;
++counter) {
// Call the coroutine, does the computation and then
// suspends
int value = loop_coroutine();
std::cout << "value is " << value << std::endl;
}
return 0;
}

View File

@ -0,0 +1,32 @@
#define SOL_ALL_SAFETIES_ON 1
#include <sol/sol.hpp>
struct A {
int a = 10;
virtual int call() {
return 0;
}
virtual ~A() {
}
};
struct B : A {
int b = 11;
virtual int call() override {
return 20;
}
};
int main(int, char*[]) {
sol::state lua;
lua.new_usertype<B>("A", "call", &A::call);
lua.new_usertype<B>("B",
"call",
&B::call,
sol::base_classes,
sol::bases<A>());
return 0;
}

View File

@ -0,0 +1,29 @@
#define SOL_ALL_SAFETIES_ON 1
#include <sol/sol.hpp>
#include <iostream>
inline void my_panic(sol::optional<std::string> maybe_msg) {
std::cerr << "Lua is in a panic state and will now abort() "
"the application"
<< std::endl;
if (maybe_msg) {
const std::string& msg = maybe_msg.value();
std::cerr << "\terror message: " << msg << std::endl;
}
// When this function exits, Lua will exhibit default
// behavior and abort()
}
int main(int, char*[]) {
sol::state lua(sol::c_call<decltype(&my_panic), &my_panic>);
// or, if you already have a lua_State* L
// lua_atpanic( L, sol::c_call<decltype(&my_panic),
// &my_panic> ); or, with state/state_view: sol::state_view
// lua(L); lua.set_panic( sol::c_call<decltype(&my_panic),
// &my_panic> );
// uncomment the below to see
// lua.script("boom_goes.the_dynamite");
return 0;
}

View File

@ -0,0 +1,30 @@
#define SOL_ALL_SAFETIES_ON 1
#include <sol/sol.hpp>
int main(int, char*[]) {
sol::state lua;
lua.open_libraries();
sol::environment my_env(lua, sol::create);
// set value, and we need to explicitly allow for
// access to "print", since a new environment hides
// everything that's not defined inside of it
// NOTE: hiding also hides library functions (!!)
// BE WARNED
my_env["var"] = 50;
my_env["print"] = lua["print"];
sol::environment my_other_env(
lua, sol::create, lua.globals());
// do not need to explicitly allow access to "print",
// since we used the "Set a fallback" version
// of the sol::environment constructor
my_other_env["var"] = 443;
// output: 50
lua.script("print(var)", my_env);
// output: 443
lua.script("print(var)", my_other_env);
return 0;
}

View File

@ -0,0 +1,28 @@
#define SOL_ALL_SAFETIES_ON 1
#include <sol/sol.hpp>
int main(int, char*[]) {
struct test {
int blah = 0;
};
test t;
sol::state lua;
lua.set_function("f", [&t]() { return t; });
lua.set_function("g", [&t]() -> test& { return t; });
lua.script("t1 = f()");
lua.script("t2 = g()");
test& from_lua_t1 = lua["t1"];
test& from_lua_t2 = lua["t2"];
// not the same: 'f' lambda copied
SOL_ASSERT(&from_lua_t1 != &t);
// the same: 'g' lambda returned reference
SOL_ASSERT(&from_lua_t2 == &t);
return 0;
}

View File

@ -0,0 +1,29 @@
#define SOL_ALL_SAFETIES_ON 1
#include <sol/sol.hpp>
#include <iostream>
struct object {
int value = 0;
};
int main(int, char*[]) {
std::cout << "==== runtime_extension =====" << std::endl;
sol::state lua;
lua.open_libraries(sol::lib::base);
lua.new_usertype<object>("object");
// runtime additions: through the sol API
lua["object"]["func"] = [](object& o) { return o.value; };
// runtime additions: through a lua script
lua.script(
"function object:print () print(self:func()) end");
// see it work
lua.script("local obj = object.new() \n obj:print()");
return 0;
}

View File

@ -0,0 +1,17 @@
#define SOL_ALL_SAFETIES_ON 1
#include <sol/sol.hpp>
int main() {
sol::state lua;
int x = 0;
lua.set_function("beep", [&x] { ++x; });
lua.script("beep()");
SOL_ASSERT(x == 1);
sol::function beep = lua["beep"];
beep();
SOL_ASSERT(x == 2);
return 0;
}

View File

@ -0,0 +1,31 @@
#define SOL_ALL_SAFETIES_ON 1
#include <sol/sol.hpp>
struct vars {
int boop = 0;
int bop() const {
return boop + 1;
}
};
int main() {
sol::state lua;
lua.new_usertype<vars>(
"vars", "boop", &vars::boop, "bop", &vars::bop);
lua.script(
"beep = vars.new()\n"
"beep.boop = 1\n"
"bopvalue = beep:bop()");
vars& beep = lua["beep"];
int bopvalue = lua["bopvalue"];
SOL_ASSERT(beep.boop == 1);
SOL_ASSERT(lua.get<vars>("beep").boop == 1);
SOL_ASSERT(beep.bop() == 2);
SOL_ASSERT(bopvalue == 2);
return 0;
}

View File

@ -0,0 +1,44 @@
#define SOL_ALL_SAFETIES_ON 1
#include <sol/sol.hpp>
#include <iostream>
int main() {
std::cout << "=== safe_script usage ===" << std::endl;
sol::state lua;
// uses sol::script_default_on_error, which either panics or
// throws, depending on your configuration and compiler
// settings
try {
auto result1 = lua.safe_script("bad.code");
}
catch (const sol::error& e) {
std::cout << "an expected error has occurred: "
<< e.what() << std::endl;
}
// a custom handler that you write yourself
// is only called when an error happens with loading or
// running the script
auto result2 = lua.safe_script("123 bad.code",
[](lua_State*, sol::protected_function_result pfr) {
// pfr will contain things that went wrong, for
// either loading or executing the script the user
// can do whatever they like here, including
// throw. Otherwise...
sol::error err = pfr;
std::cout
<< "An error (an expected one) occurred: "
<< err.what() << std::endl;
// ... they need to return the
// protected_function_result
return pfr;
});
std::cout << std::endl;
return 0;
}

View File

@ -0,0 +1,50 @@
#define SOL_ALL_SAFETIES_ON 1
#include <sol/sol.hpp>
#include <iostream>
int main(int, char*[]) {
sol::state lua;
lua.open_libraries();
sol::function transferred_into;
lua["f"] = [&lua, &transferred_into](
sol::object t, sol::this_state this_L) {
std::cout << "state of main : "
<< (void*)lua.lua_state() << std::endl;
std::cout << "state of function : "
<< (void*)this_L.lua_state() << std::endl;
// pass original lua_State* (or
// sol::state/sol::state_view) transfers ownership from
// the state of "t", to the "lua" sol::state
transferred_into = sol::function(lua, t);
};
lua.script(R"(
i = 0
function test()
co = coroutine.create(
function()
local g = function() i = i + 1 end
f(g)
g = nil
collectgarbage()
end
)
coroutine.resume(co)
co = nil
collectgarbage()
end
)");
// give it a try
lua.safe_script("test()");
// should call 'g' from main thread, increment i by 1
transferred_into();
// check
int i = lua["i"];
SOL_ASSERT(i == 1);
return 0;
}

View File

@ -0,0 +1,157 @@
#define SOL_ALL_SAFETIES_ON 1
#include <sol/sol.hpp>
#include <mutex>
#include <condition_variable>
#include <thread>
#include <variant>
#include <cstddef>
#include <iostream>
struct worker_data {
std::mutex until_ready_mutex;
std::condition_variable until_ready_condition;
bool is_ready = false;
bool is_processed = false;
sol::state worker_lua;
sol::bytecode payload;
std::variant<double, std::vector<double>> return_payload;
worker_data() {
worker_lua.open_libraries(sol::lib::base);
}
};
void worker_thread(worker_data& data) {
for ([[maybe_unused]] std::uint64_t loops = 0; true; ++loops) {
// Wait until main() sends data
std::unique_lock<std::mutex> data_lock(
data.until_ready_mutex);
data.until_ready_condition.wait(
data_lock, [&data] { return data.is_ready; });
if (data.payload.size() == 0) {
// signaling we are done
return;
}
// just for easier typing
sol::state& lua = data.worker_lua;
// we own the lock now, do the work
std::variant<double, std::vector<double>> result
= lua.safe_script(data.payload.as_string_view());
// store returning payload,
// clear current payload
data.return_payload = std::move(result);
data.payload.clear();
// Send result back to main
std::cout << "worker_thread data processing is "
"completed: signaling & unlocking\n";
data.is_processed = true;
data.is_ready = false;
data_lock.unlock();
data.until_ready_condition.notify_one();
}
}
int main() {
// main lua state
sol::state lua;
lua.open_libraries(sol::lib::base);
// set up functions, etc. etc.
lua.script("function f () return 4.5 end");
lua.script("function g () return { 1.1, 2.2, 3.3 } end");
// kick off worker
worker_data data;
std::thread worker(worker_thread, std::ref(data));
// main Lua state
bool done_working = false;
for (std::uint64_t loops = 0; !done_working; ++loops) {
// finished working? send nothing
// even loop? use f
// otherwise, use g
if (loops >= 3) {
data.payload.clear();
done_working = true;
}
else if ((loops % 2) == 0) {
sol::function target = lua["f"];
data.payload = target.dump();
}
else {
sol::function target = lua["g"];
data.payload = target.dump();
}
// send data to the worker thread
{
std::lock_guard<std::mutex> lk(
data.until_ready_mutex);
data.is_ready = true;
std::cout
<< "function serialized: sending to worker "
"thread to execute on Lua state...\n";
}
data.until_ready_condition.notify_one();
if (done_working) {
break;
}
// wait for the worker
{
std::unique_lock<std::mutex>
lock_waiting_for_worker(
data.until_ready_mutex);
data.until_ready_condition.wait(
lock_waiting_for_worker,
[&data] { return data.is_processed; });
data.is_processed = false;
}
auto data_processor = [](auto& returned_data) {
using option_type
= std::remove_cv_t<std::remove_reference_t<
decltype(returned_data)>>;
if constexpr (std::is_same_v<option_type,
double>) {
std::cout << "received a double: "
<< returned_data << "\n";
}
else if constexpr (std::is_same_v<option_type,
std::vector<double>>) {
std::cout
<< "received a std::vector<double>: { ";
for (std::size_t i = 0;
i < returned_data.size();
++i) {
std::cout << returned_data[i];
if (i
!= static_cast<std::size_t>(
returned_data.size() - 1)) {
std::cout << ", ";
}
}
std::cout << " }\n";
}
else {
std::cerr << "OH MY GOD YOU FORGOT TO "
"HANDLE A TYPE OF DATA FROM A "
"WORKER ABORT ABORT ABORT\n";
std::abort();
}
};
std::visit(data_processor, data.return_payload);
}
// join and wait for workers to come back
worker.join();
// workers are back, exit program
return 0;
}