The Battle for Wesnoth  1.19.27+dev
lua_rng.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2014 - 2025
3  by Chris Beck <render787@gmail.com>
4  Part of the Battle for Wesnoth Project https://www.wesnoth.org/
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY.
12 
13  See the COPYING file for more details.
14 */
15 
16 #include "scripting/lua_rng.hpp"
17 
18 #include "log.hpp"
19 #include "mt_rng.hpp"
21 #include "scripting/lua_common.hpp" // for new(L)
22 #include "scripting/push_check.hpp"
23 
24 #include <string>
25 
26 #include "lua/wrapper_lauxlib.h"
27 
28 static lg::log_domain log_lua("scripting/lua");
29 #define ERR_LUA LOG_STREAM(err, log_lua)
30 
31 // Begin lua rng bindings
32 namespace lua_rng {
33 
34 using randomness::mt_rng;
35 
36 static const char * Rng = "Rng";
37 
38 int impl_rng_create(lua_State* L)
39 {
40  uint32_t seed = lua_kernel_base::get_lua_kernel<lua_kernel_base>(L).get_random_seed();
41  new(L) mt_rng(seed);
42  luaL_setmetatable(L, Rng);
43 
44  return 1;
45 }
46 
47 int impl_rng_destroy(lua_State* L)
48 {
49  mt_rng * d = static_cast< mt_rng *> (luaL_testudata(L, 1, Rng));
50  if (d == nullptr) {
51  ERR_LUA << "rng_destroy called on data of type: " << lua_typename( L, lua_type( L, 1 ) );
52  ERR_LUA << "This may indicate a memory leak, please report at bugs.wesnoth.org";
53  lua_pushstring(L, "Rng object garbage collection failure");
54  lua_error(L);
55  } else {
56  d->~mt_rng();
57  }
58  return 0;
59 }
60 
61 int impl_rng_seed(lua_State* L)
62 {
63  mt_rng * rng = static_cast<mt_rng *>(luaL_checkudata(L, 1, Rng));
64  std::string seed = luaL_checkstring(L, 2);
65 
66  rng->seed_random(seed);
67  return 0;
68 }
69 
70 int impl_rng_draw(lua_State* L)
71 {
72  mt_rng * rng = static_cast<mt_rng *>(luaL_checkudata(L, 1, Rng));
73 
74  lua_pushnumber(L, rng->get_next_random());
75  return 1;
76 }
77 
78 int impl_rng_tostring(lua_State* L)
79 {
80  mt_rng* rng = static_cast<mt_rng*>(luaL_checkudata(L, 1, Rng));
81  luaW_getglobal(L, "string", "format");
82  lua_pushstring(L, "Rng: %#x");
83  lua_pushinteger(L, rng->get_random_seed());
84  lua_call(L, 2, 1);
85  return 1;
86 }
87 
88 int impl_rng_dir(lua_State* L)
89 {
90  static const std::vector<std::string> fields = {"draw", "seed"};
91  lua_push(L, fields);
92  return 1;
93 }
94 
95 // End Lua Rng bindings
96 
97 void load_tables(lua_State* L)
98 {
99  // Create the global Rng table, with create() as its only element
100  lua_createtable(L, 0, 1);
101  lua_pushcfunction(L, &impl_rng_create);
102  lua_setfield(L, -2, "create");
103  lua_setglobal(L, Rng);
104 
105  // Create the metatable for Rng objects
106  luaL_newmetatable(L, Rng);
107  static luaL_Reg const meta_callbacks[] {
108  { "__gc", &impl_rng_destroy},
109  { "__tostring", &impl_rng_tostring},
110  { "__dir", &impl_rng_dir},
111  { nullptr, nullptr }
112  };
113  luaL_setfuncs(L, meta_callbacks, 0);
114 
115  static luaL_Reg const callbacks[] {
116  { "seed", &impl_rng_seed},
117  { "draw", &impl_rng_draw},
118  { nullptr, nullptr }
119  };
120  luaL_newlibtable(L, callbacks);
121  luaL_setfuncs(L, callbacks, 0);
122 
123  lua_setfield(L, -2, "__index");
124  lua_pushstring(L, Rng);
125  lua_setfield(L, -2, "__metatable");
126  lua_pop(L, 1);
127 }
128 
129 } // end namespace lua_map_rng
uint32_t get_random_seed() const
Definition: mt_rng.hpp:54
uint32_t get_next_random()
Get a new random number.
Definition: mt_rng.cpp:62
void seed_random(const std::string &seed, const unsigned int call_count=0)
Same as uint32_t version, but uses a stringstream to convert given hex string.
Definition: mt_rng.cpp:88
Standard logging facilities (interface).
bool luaW_getglobal(lua_State *L, const std::vector< std::string > &path)
Pushes the value found by following the variadic names (char *), if the value is not nil.
static lg::log_domain log_lua("scripting/lua")
#define ERR_LUA
Definition: lua_rng.cpp:29
int impl_rng_create(lua_State *L)
Implementations for lua callbacks.
Definition: lua_rng.cpp:38
int impl_rng_draw(lua_State *L)
Definition: lua_rng.cpp:70
int impl_rng_seed(lua_State *L)
Definition: lua_rng.cpp:61
int impl_rng_tostring(lua_State *L)
Definition: lua_rng.cpp:78
static const char * Rng
Definition: lua_rng.cpp:36
int impl_rng_destroy(lua_State *L)
Definition: lua_rng.cpp:47
int impl_rng_dir(lua_State *L)
Definition: lua_rng.cpp:88
void load_tables(lua_State *L)
Creates the metatable for RNG objects, and adds the Rng table which contains the constructor.
Definition: lua_rng.cpp:97
void lua_push(lua_State *L, const T &val)
Definition: push_check.hpp:425
#define d