add 'random' library

This commit is contained in:
MihailRis 2025-09-16 19:01:47 +03:00
parent 78574f2460
commit eb760e1776
5 changed files with 111 additions and 0 deletions

View File

@ -42,6 +42,7 @@ extern const luaL_Reg pathfindinglib[];
extern const luaL_Reg playerlib[];
extern const luaL_Reg posteffectslib[]; // gfx.posteffects
extern const luaL_Reg quatlib[];
extern const luaL_Reg randomlib[];
extern const luaL_Reg text3dlib[]; // gfx.text3d
extern const luaL_Reg timelib[];
extern const luaL_Reg tomllib[];

View File

@ -0,0 +1,46 @@
#include "api_lua.hpp"
#include "util/random.hpp"
static std::random_device random_device;
static int l_random(lua::State* L) {
int argc = lua::gettop(L);
auto randomEngine = util::seeded_random_engine(random_device);
if (argc == 0) {
std::uniform_real_distribution<> dist(0.0, 1.0);
return lua::pushnumber(L, dist(randomEngine));
} else if (argc == 1) {
std::uniform_int_distribution<integer_t> dist(0, lua::tointeger(L, 1) - 1);
return lua::pushinteger(L, dist(randomEngine));
} else {
std::uniform_int_distribution<integer_t> dist(
lua::tointeger(L, 1), lua::tointeger(L, 2) - 1
);
return lua::pushinteger(L, dist(randomEngine));
}
}
static int l_bytes(lua::State* L) {
size_t size = lua::tointeger(L, 1);
auto randomEngine = util::seeded_random_engine(random_device);
static std::uniform_int_distribution<integer_t> dist(0, 0xFF);
std::vector<ubyte> bytes (size);
for (size_t i = 0; i < bytes.size(); i++) {
bytes[i] = dist(randomEngine);
}
return lua::create_bytearray(L, bytes);
}
static int l_uuid(lua::State* L) {
return lua::pushlstring(L, util::generate_uuid());
}
const luaL_Reg randomlib[] = {
{"random", lua::wrap<l_random>},
{"bytes", lua::wrap<l_bytes>},
{"uuid", lua::wrap<l_uuid>},
{NULL, NULL}
};

View File

@ -51,6 +51,7 @@ static void create_libs(State* L, StateType stateType) {
openlib(L, "mat4", mat4lib);
openlib(L, "pack", packlib);
openlib(L, "quat", quatlib);
openlib(L, "random", randomlib);
openlib(L, "toml", tomllib);
openlib(L, "utf8", utf8lib);
openlib(L, "vec2", vec2lib);

44
src/util/random.cpp Normal file
View File

@ -0,0 +1,44 @@
#include "random.hpp"
#include <random>
static std::random_device random_device;
static const char* uuid_hex_chars = "0123456789abcdef";
static const char* uuid_hex_variant_chars = "89ab";
std::string util::generate_uuid() {
auto randomEngine = seeded_random_engine(random_device);
static std::uniform_int_distribution<> dist(0, 15);
static std::uniform_int_distribution<> dist2(0, 3);
std::string uuid;
uuid.resize(36);
for (int i = 0; i < 8; i++) {
uuid[i] = uuid_hex_chars[dist(randomEngine)];
}
uuid[8] = '-';
for (int i = 9; i < 13; i++) {
uuid[i] = uuid_hex_chars[dist(randomEngine)];
}
uuid[13] = '-';
uuid[14] = '4';
for (int i = 15; i < 18; i++) {
uuid[i] = uuid_hex_chars[dist(randomEngine)];
}
uuid[18] = '-';
uuid[19] = uuid_hex_variant_chars[dist2(randomEngine)];
for (int i = 20; i < 23; i++) {
uuid[i] = uuid_hex_chars[dist(randomEngine)];
}
uuid[23] = '-';
for (int i = 24; i < 36; i++) {
uuid[i] = uuid_hex_chars[dist(randomEngine)];
}
return uuid;
}

19
src/util/random.hpp Normal file
View File

@ -0,0 +1,19 @@
#pragma once
#include <random>
#include <string>
#include <algorithm>
namespace util {
template <class T = std::mt19937, std::size_t N = T::state_size * sizeof(typename T::result_type)>
typename std::enable_if<N, T>::type seeded_random_engine(
std::random_device& source
) {
std::random_device::result_type randomData[(N - 1) / sizeof(source()) + 1];
std::generate(std::begin(randomData), std::end(randomData), std::ref(source));
std::seed_seq seeds(std::begin(randomData), std::end(randomData));
return T(seeds);
}
std::string generate_uuid();
}