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/functions.hpp"
#include "game/scripting/array.hpp"
#include "game/scripting/function.hpp"
#include "gsc.hpp"
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)
: 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())
{
@ -285,28 +286,23 @@ namespace gsc
public:
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*>());
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 with = args[1].get_raw();
const auto what = args[0].as<scripting::function>();
const auto with = args[1].as<scripting::function>();
if (what.type != game::SCRIPT_FUNCTION || with.type != game::SCRIPT_FUNCTION)
{
throw std::runtime_error("Invalid type");
}
replaced_functions[what.u.uintValue] = with.u.uintValue;
replaced_functions[what.get_pos()] = with.get_pos();
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 function = args[1].get_raw();
@ -331,7 +327,7 @@ namespace gsc
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>();
game::SV_GameSendServerCommand(-1, 0, utils::string::va("%c \"%s\"", 84, message.data()));
@ -339,7 +335,7 @@ namespace gsc
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)
{

View File

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

View File

@ -20,13 +20,13 @@ namespace io
const auto path = game::Dvar_FindVar("fs_basegame")->current.string;
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*>();
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* mode = args[1].as<const char*>();
@ -41,13 +41,13 @@ namespace io
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>();
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 text = args[1].as<const char*>();
@ -55,7 +55,7 @@ namespace io
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>();
@ -74,13 +74,13 @@ namespace io
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>();
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 data = args[1].as<std::string>();
@ -94,37 +94,37 @@ namespace io
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>();
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>();
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>();
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>();
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>();
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 files = utils::io::list_files(path);
@ -138,7 +138,7 @@ namespace io
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 target = args[1].as<std::string>();

View File

@ -141,13 +141,13 @@ namespace json
public:
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());
return array.get_raw();
});
gsc::function::add("map", [](gsc::function_args args)
gsc::function::add("map", [](const gsc::function_args& args)
{
scripting::array array;
@ -165,7 +165,7 @@ namespace json
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 obj = nlohmann::json::parse(json);
@ -173,7 +173,7 @@ namespace json
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];
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 "entity.hpp"
#include "array.hpp"
#include "function.hpp"
namespace scripting
{
@ -261,11 +262,17 @@ namespace scripting
**************************************************************/
template <>
bool script_value::is<std::function<void()>>() const
bool script_value::is<function>() const
{
return this->get_raw().type == game::SCRIPT_FUNCTION;
}
template <>
function script_value::get() const
{
return function(this->get_raw().u.codePosValue);
}
/***************************************************************
* Vector
**************************************************************/