Use function class

This commit is contained in:
Federico Cecchetto 2021-06-19 22:17:41 +02:00
parent 7ac6443b2c
commit 97371d8f44
7 changed files with 105 additions and 38 deletions

View File

@ -8,12 +8,13 @@
#include "game/scripting/execution.hpp" #include "game/scripting/execution.hpp"
#include "game/scripting/functions.hpp" #include "game/scripting/functions.hpp"
#include "game/scripting/array.hpp" #include "game/scripting/array.hpp"
#include "game/scripting/function.hpp"
#include "gsc.hpp" #include "gsc.hpp"
namespace gsc namespace gsc
{ {
std::unordered_map<unsigned, unsigned> replaced_functions; std::unordered_map<const char*, const char*> replaced_functions;
function_args::function_args(std::vector<scripting::script_value> values) function_args::function_args(std::vector<scripting::script_value> values)
: values_(values) : values_(values)
@ -201,9 +202,9 @@ namespace gsc
} }
} }
unsigned int replaced_pos = 0; const char* replaced_pos = 0;
void get_replaced_pos(unsigned int pos) void get_replaced_pos(const char* pos)
{ {
if (replaced_functions.find(pos) != replaced_functions.end()) if (replaced_functions.find(pos) != replaced_functions.end())
{ {
@ -285,28 +286,23 @@ namespace gsc
public: public:
void post_unpack() override void post_unpack() override
{ {
function::add("executecommand", [](function_args args) -> scripting::script_value function::add("executecommand", [](const function_args& args) -> scripting::script_value
{ {
game::Cbuf_AddText(0, args[0].as<const char*>()); game::Cbuf_AddText(0, args[0].as<const char*>());
return {}; return {};
}); });
function::add("replacefunc", [](function_args args) -> scripting::script_value function::add("replacefunc", [](const function_args& args) -> scripting::script_value
{ {
const auto what = args[0].get_raw(); const auto what = args[0].as<scripting::function>();
const auto with = args[1].get_raw(); const auto with = args[1].as<scripting::function>();
if (what.type != game::SCRIPT_FUNCTION || with.type != game::SCRIPT_FUNCTION) replaced_functions[what.get_pos()] = with.get_pos();
{
throw std::runtime_error("Invalid type");
}
replaced_functions[what.u.uintValue] = with.u.uintValue;
return {}; return {};
}); });
function::add("addcommand", [](function_args args) -> scripting::script_value function::add("addcommand", [](const function_args& args) -> scripting::script_value
{ {
const auto name = args[0].as<std::string>(); const auto name = args[0].as<std::string>();
const auto function = args[1].get_raw(); const auto function = args[1].get_raw();
@ -331,7 +327,7 @@ namespace gsc
return {}; return {};
}); });
function::add("say", [](function_args args) -> scripting::script_value function::add("say", [](const function_args& args) -> scripting::script_value
{ {
const auto message = args[0].as<std::string>(); const auto message = args[0].as<std::string>();
game::SV_GameSendServerCommand(-1, 0, utils::string::va("%c \"%s\"", 84, message.data())); game::SV_GameSendServerCommand(-1, 0, utils::string::va("%c \"%s\"", 84, message.data()));
@ -339,7 +335,7 @@ namespace gsc
return {}; return {};
}); });
method::add("tell", [](game::scr_entref_t ent, function_args args) -> scripting::script_value method::add("tell", [](const game::scr_entref_t ent, const function_args& args) -> scripting::script_value
{ {
if (ent.classnum != 0) if (ent.classnum != 0)
{ {

View File

@ -2,7 +2,7 @@
namespace gsc namespace gsc
{ {
extern std::unordered_map<unsigned, unsigned> replaced_functions; extern std::unordered_map<const char*, const char*> replaced_functions;
class function_args class function_args
{ {
@ -24,8 +24,8 @@ namespace gsc
using builtin_function = void(*)(); using builtin_function = void(*)();
using builtin_method = void(*)(game::scr_entref_t); using builtin_method = void(*)(game::scr_entref_t);
using script_function = std::function<scripting::script_value(function_args)>; using script_function = std::function<scripting::script_value(const function_args&)>;
using script_method = std::function<scripting::script_value(game::scr_entref_t, function_args)>; using script_method = std::function<scripting::script_value(const game::scr_entref_t, const function_args&)>;
namespace function namespace function
{ {

View File

@ -20,13 +20,13 @@ namespace io
const auto path = game::Dvar_FindVar("fs_basegame")->current.string; const auto path = game::Dvar_FindVar("fs_basegame")->current.string;
std::filesystem::current_path(path); std::filesystem::current_path(path);
gsc::function::add("fremove", [](gsc::function_args args) gsc::function::add("fremove", [](const gsc::function_args& args)
{ {
const auto path = args[0].as<const char*>(); const auto path = args[0].as<const char*>();
return std::remove(path); return std::remove(path);
}); });
gsc::function::add("fopen", [](gsc::function_args args) gsc::function::add("fopen", [](const gsc::function_args& args)
{ {
const auto* path = args[0].as<const char*>(); const auto* path = args[0].as<const char*>();
const auto* mode = args[1].as<const char*>(); const auto* mode = args[1].as<const char*>();
@ -41,13 +41,13 @@ namespace io
return handle; return handle;
}); });
gsc::function::add("fclose", [](gsc::function_args args) gsc::function::add("fclose", [](const gsc::function_args& args)
{ {
const auto handle = args[0].as_ptr<FILE>(); const auto handle = args[0].as_ptr<FILE>();
return fclose(handle); return fclose(handle);
}); });
gsc::function::add("fwrite", [](gsc::function_args args) gsc::function::add("fwrite", [](const gsc::function_args& args)
{ {
const auto handle = args[0].as_ptr<FILE>(); const auto handle = args[0].as_ptr<FILE>();
const auto text = args[1].as<const char*>(); const auto text = args[1].as<const char*>();
@ -55,7 +55,7 @@ namespace io
return fprintf(handle, text); return fprintf(handle, text);
}); });
gsc::function::add("fread", [](gsc::function_args args) gsc::function::add("fread", [](const gsc::function_args& args)
{ {
const auto handle = args[0].as_ptr<FILE>(); const auto handle = args[0].as_ptr<FILE>();
@ -74,13 +74,13 @@ namespace io
return result; return result;
}); });
gsc::function::add("fileexists", [](gsc::function_args args) gsc::function::add("fileexists", [](const gsc::function_args& args)
{ {
const auto path = args[0].as<std::string>(); const auto path = args[0].as<std::string>();
return utils::io::file_exists(path); return utils::io::file_exists(path);
}); });
gsc::function::add("writefile", [](gsc::function_args args) gsc::function::add("writefile", [](const gsc::function_args& args)
{ {
const auto path = args[0].as<std::string>(); const auto path = args[0].as<std::string>();
const auto data = args[1].as<std::string>(); const auto data = args[1].as<std::string>();
@ -94,37 +94,37 @@ namespace io
return utils::io::write_file(path, data, append); return utils::io::write_file(path, data, append);
}); });
gsc::function::add("readfile", [](gsc::function_args args) gsc::function::add("readfile", [](const gsc::function_args& args)
{ {
const auto path = args[0].as<std::string>(); const auto path = args[0].as<std::string>();
return utils::io::read_file(path); return utils::io::read_file(path);
}); });
gsc::function::add("filesize", [](gsc::function_args args) gsc::function::add("filesize", [](const gsc::function_args& args)
{ {
const auto path = args[0].as<std::string>(); const auto path = args[0].as<std::string>();
return utils::io::file_size(path); return utils::io::file_size(path);
}); });
gsc::function::add("createdirectory", [](gsc::function_args args) gsc::function::add("createdirectory", [](const gsc::function_args& args)
{ {
const auto path = args[0].as<std::string>(); const auto path = args[0].as<std::string>();
return utils::io::create_directory(path); return utils::io::create_directory(path);
}); });
gsc::function::add("directoryexists", [](gsc::function_args args) gsc::function::add("directoryexists", [](const gsc::function_args& args)
{ {
const auto path = args[0].as<std::string>(); const auto path = args[0].as<std::string>();
return utils::io::directory_exists(path); return utils::io::directory_exists(path);
}); });
gsc::function::add("directoryisempty", [](gsc::function_args args) gsc::function::add("directoryisempty", [](const gsc::function_args& args)
{ {
const auto path = args[0].as<std::string>(); const auto path = args[0].as<std::string>();
return utils::io::directory_is_empty(path); return utils::io::directory_is_empty(path);
}); });
gsc::function::add("listfiles", [](gsc::function_args args) gsc::function::add("listfiles", [](const gsc::function_args& args)
{ {
const auto path = args[0].as<std::string>(); const auto path = args[0].as<std::string>();
const auto files = utils::io::list_files(path); const auto files = utils::io::list_files(path);
@ -138,7 +138,7 @@ namespace io
return array.get_raw(); return array.get_raw();
}); });
gsc::function::add("copyfolder", [](gsc::function_args args) gsc::function::add("copyfolder", [](const gsc::function_args& args)
{ {
const auto source = args[0].as<std::string>(); const auto source = args[0].as<std::string>();
const auto target = args[1].as<std::string>(); const auto target = args[1].as<std::string>();

View File

@ -141,13 +141,13 @@ namespace json
public: public:
void post_unpack() override void post_unpack() override
{ {
gsc::function::add("array", [](gsc::function_args args) gsc::function::add("array", [](const gsc::function_args& args)
{ {
scripting::array array(args.get_raw()); scripting::array array(args.get_raw());
return array.get_raw(); return array.get_raw();
}); });
gsc::function::add("map", [](gsc::function_args args) gsc::function::add("map", [](const gsc::function_args& args)
{ {
scripting::array array; scripting::array array;
@ -165,7 +165,7 @@ namespace json
return array.get_raw(); return array.get_raw();
}); });
gsc::function::add("jsonparse", [](gsc::function_args args) gsc::function::add("jsonparse", [](const gsc::function_args& args)
{ {
const auto json = args[0].as<std::string>(); const auto json = args[0].as<std::string>();
const auto obj = nlohmann::json::parse(json); const auto obj = nlohmann::json::parse(json);
@ -173,7 +173,7 @@ namespace json
return json_to_gsc(obj); return json_to_gsc(obj);
}); });
gsc::function::add("jsonserialize", [](gsc::function_args args) gsc::function::add("jsonserialize", [](const gsc::function_args& args)
{ {
const auto value = args[0]; const auto value = args[0];
auto indent = -1; auto indent = -1;

View File

@ -0,0 +1,30 @@
#include <stdinc.hpp>
#include "function.hpp"
#include "execution.hpp"
namespace scripting
{
function::function(const char* pos)
: pos_(pos)
{
}
script_value function::get_raw() const
{
game::VariableValue value;
value.type = game::SCRIPT_FUNCTION;
value.u.codePosValue = this->pos_;
return value;
}
const char* function::get_pos() const
{
return this->pos_;
}
script_value function::call(entity self, std::vector<script_value> arguments) const
{
return exec_ent_thread(self, this->pos_, arguments);
}
}

View File

@ -0,0 +1,34 @@
#pragma once
#include "entity.hpp"
#include "script_value.hpp"
namespace scripting
{
class function
{
public:
function(const char*);
script_value get_raw() const;
const char* get_pos() const;
script_value call(entity self, std::vector<script_value> arguments) const;
script_value operator()(entity self, std::vector<script_value> arguments) const
{
return this->call(self, arguments);
}
script_value operator()(std::vector<script_value> arguments) const
{
return this->call(*game::levelEntityId, arguments);
}
script_value operator()() const
{
return this->call(*game::levelEntityId, {});
}
private:
const char* pos_;
};
}

View File

@ -2,6 +2,7 @@
#include "script_value.hpp" #include "script_value.hpp"
#include "entity.hpp" #include "entity.hpp"
#include "array.hpp" #include "array.hpp"
#include "function.hpp"
namespace scripting namespace scripting
{ {
@ -261,11 +262,17 @@ namespace scripting
**************************************************************/ **************************************************************/
template <> template <>
bool script_value::is<std::function<void()>>() const bool script_value::is<function>() const
{ {
return this->get_raw().type == game::SCRIPT_FUNCTION; return this->get_raw().type == game::SCRIPT_FUNCTION;
} }
template <>
function script_value::get() const
{
return function(this->get_raw().u.codePosValue);
}
/*************************************************************** /***************************************************************
* Vector * Vector
**************************************************************/ **************************************************************/