5#include <entt/entity/fwd.hpp>
7#include <initializer_list>
22using script_value = std::variant<std::monostate, bool, f64, std::string, vec2, vec3, entt::entity>;
87namespace script_detail {
88template <
class>
inline constexpr bool always_false =
false;
91template <
class T> std::remove_cvref_t<T> to(
const script_value &v) {
92 using U = std::remove_cvref_t<T>;
93 if constexpr (std::is_same_v<U, bool>) {
94 if (
const bool *b = std::get_if<bool>(&v))
96 if (
const f64 *d = std::get_if<f64>(&v))
99 }
else if constexpr (std::is_same_v<U, entt::entity>) {
100 if (
const entt::entity *e = std::get_if<entt::entity>(&v))
102 if (
const f64 *d = std::get_if<f64>(&v))
103 return entt::entity((
u32)*d);
104 return entt::entity(~
u32{0});
105 }
else if constexpr (std::is_arithmetic_v<U>) {
106 if (
const f64 *d = std::get_if<f64>(&v))
108 if (
const bool *b = std::get_if<bool>(&v))
109 return (U)(*b ? 1 : 0);
111 }
else if constexpr (std::is_same_v<U, std::string> || std::is_same_v<U, vec2> || std::is_same_v<U, vec3>) {
112 if (
const U *p = std::get_if<U>(&v))
115 }
else if constexpr (std::is_same_v<U, script_value>) {
118 static_assert(always_false<U>,
"script_register: kiểu tham số không hỗ trợ");
124 using U = std::remove_cvref_t<T>;
125 if constexpr (std::is_same_v<U, script_value>)
126 return std::forward<T>(value);
127 else if constexpr (std::is_same_v<U, bool> || std::is_same_v<U, vec2> || std::is_same_v<U, vec3> ||
128 std::is_same_v<U, entt::entity> || std::is_same_v<U, std::string>)
130 else if constexpr (std::is_arithmetic_v<U>)
132 else if constexpr (std::is_convertible_v<U, const char *>)
135 static_assert(always_false<U>,
"script_register: kiểu trả về không hỗ trợ");
140 return i < args.size() ? args[i] : none;
143template <
class R,
class... A,
usize... I>
144script_value call(
const std::function<R(context &, A...)> &f, context &ctx, std::span<const script_value> args,
145 std::index_sequence<I...>) {
146 if constexpr (std::is_void_v<R>) {
147 f(ctx, to<A>(arg(args, I))...);
150 return from(f(ctx, to<A>(arg(args, I))...));
154template <
class R,
class... A,
usize... I>
155script_value call(
const std::function<R(A...)> &f, std::span<const script_value> args, std::index_sequence<I...>) {
156 if constexpr (std::is_void_v<R>) {
157 f(to<A>(arg(args, I))...);
160 return from(f(to<A>(arg(args, I))...));
164template <
class R,
class... A>
script_fn wrap(std::function<R(context &, A...)> f) {
165 return [f = std::move(f)](context &ctx, std::span<const script_value> args) {
166 return call(f, ctx, args, std::index_sequence_for<A...>{});
170template <
class R,
class... A>
script_fn wrap(std::function<R(A...)> f) {
171 return [f = std::move(f)](context &, std::span<const script_value> args) {
172 return call(f, args, std::index_sequence_for<A...>{});
188 requires(!std::is_convertible_v<F, script_fn>)
190 script_register(ctx, name, script_detail::wrap(std::function{std::forward<F>(fn)}));
void script_init(context &ctx, const script_desc &desc={})
Tạo máy Lua với tùy chọn desc.
std::variant< std::monostate, bool, f64, std::string, vec2, vec3, entt::entity > script_value
Một giá trị đi qua lại giữa C++ và Lua: nil, bool, số, chuỗi, vec2, vec3 hay entity.
Definition njin_script.h:22
void script_register(context &ctx, const char *name, script_fn fn)
Đăng ký một hàm C++ dưới tên name (toàn cục bên Lua; có dấu chấm thì đặt trong bảng,...
i32 script_count(const context &ctx)
Số entity đang có script.
json_value script_save_state(context &ctx)
Trạng thái của mọi script có tên lưu, để ghi vào save game: các trường của self (số,...
std::function< script_value(context &, std::span< const script_value >)> script_fn
Hàm của game gọi được từ Lua, dạng chung: nhận mọi tham số, trả một giá trị.
Definition njin_script.h:77
script_value script_get_global(context &ctx, const char *name)
Đọc một biến toàn cục bên Lua.
void script_set_field(context &ctx, entt::entity entity, const char *key, const script_value &value)
Ghi trường key của bảng self.
void script_detach(context &ctx, entt::entity entity)
Gỡ script khỏi entity (gọi on_destroy).
bool script_attach(context &ctx, entt::entity entity, const char *path)
Gắn một script vào entity.
i32 script_load_state(context &ctx, const json_value &state)
Đổ trạng thái đã lưu bằng script_save_state() vào các script đang gắn có cùng tên lưu,...
bool script_run_string(context &ctx, const char *code, const char *name="string")
Chạy một đoạn mã Lua.
script_value script_field(context &ctx, entt::entity entity, const char *key)
Đọc trường key của bảng self của script gắn trên entity.
bool script_run_file(context &ctx, const char *path)
Chạy một file Lua (đường dẫn như mọi tài nguyên: cạnh file chạy hay thư mục làm việc).
bool script_attached(const context &ctx, entt::entity entity)
Entity có script không.
void script_set_global(context &ctx, const char *name, const script_value &value)
Đặt một biến toàn cục bên Lua (tên có dấu chấm đặt trong bảng).
void script_set_save_id(context &ctx, entt::entity entity, const char *id)
Đặt tên lưu (self.save_id) cho script gắn trên entity: khóa để script_load_state() tìm lại đúng entit...
script_result script_call(context &ctx, const char *function, std::initializer_list< script_value > args={})
Gọi một hàm Lua toàn cục theo tên.
std::string script_save_id(context &ctx, entt::entity entity)
Tên lưu của script gắn trên entity.
double f64
Số thực 64 bit.
Definition _types.h:29
std::int32_t i32
Số nguyên có dấu 32 bit.
Definition _types.h:14
std::size_t usize
Số nguyên không dấu cỡ con trỏ, dùng cho kích thước và chỉ số.
Definition _types.h:34
std::uint32_t u32
Số nguyên không dấu 32 bit.
Definition _types.h:22
Một giá trị JSON: null, bool, số, chuỗi, mảng hoặc object.
Definition njin_json.h:33
Tùy chọn của máy Lua, cho script_init().
Definition njin_script.h:25
bool allow_io
Cho script đọc ghi file và chạy file khác (io, dofile, loadfile, os.remove...).
Definition njin_script.h:30
Kết quả của script_call().
Definition njin_script.h:56
script_value value
Giá trị trả về đầu tiên (nil nếu không trả gì).
Definition njin_script.h:58
bool ok
Hàm có và chạy không lỗi.
Definition njin_script.h:57