Prepare scripting scheduler

This commit is contained in:
momo5502 2019-01-20 18:29:13 +01:00
parent 4c86842b7f
commit 7256cc786c
8 changed files with 194 additions and 154 deletions

View File

@ -5,7 +5,7 @@ namespace game
{ {
namespace scripting namespace scripting
{ {
context::context() : executer_(this), parameters_(this), event_handler_(this) context::context() : executer_(this), scheduler_(this), parameters_(this), event_handler_(this)
{ {
context_initializer::initialize(this); context_initializer::initialize(this);
} }
@ -15,6 +15,11 @@ namespace game
return &this->executer_; return &this->executer_;
} }
scheduler* context::get_scheduler()
{
return &this->scheduler_;
}
parameters* context::get_parameters() parameters* context::get_parameters()
{ {
return &this->parameters_; return &this->parameters_;

View File

@ -1,5 +1,6 @@
#pragma once #pragma once
#include "executer.hpp" #include "executer.hpp"
#include "scheduler.hpp"
#include "parameters.hpp" #include "parameters.hpp"
#include "event_handler.hpp" #include "event_handler.hpp"
@ -13,12 +14,14 @@ namespace game
context(); context();
executer* get_executer(); executer* get_executer();
scheduler* get_scheduler();
parameters* get_parameters(); parameters* get_parameters();
event_handler* get_event_handler(); event_handler* get_event_handler();
chaiscript::ChaiScript* get_chai(); chaiscript::ChaiScript* get_chai();
private: private:
executer executer_; executer executer_;
scheduler scheduler_;
parameters parameters_; parameters parameters_;
event_handler event_handler_; event_handler event_handler_;
chaiscript::ChaiScript chai_; chaiscript::ChaiScript chai_;

View File

@ -9,6 +9,11 @@ namespace game
{ {
} }
void event_handler::run_frame()
{
}
void event_handler::dispatch(event* event) void event_handler::dispatch(event* event)
{ {
try try

View File

@ -31,6 +31,7 @@ namespace game
public: public:
explicit event_handler(context* context); explicit event_handler(context* context);
void run_frame();
void dispatch(event* event); void dispatch(event* event);
void add_event_listener(const event_listener& listener); void add_event_listener(const event_listener& listener);

View File

@ -0,0 +1,17 @@
#include "std_include.hpp"
#include "context.hpp"
namespace game
{
namespace scripting
{
scheduler::scheduler(context* context) : context_(context)
{
}
void scheduler::run_frame()
{
}
}
}

View File

@ -0,0 +1,20 @@
#pragma once
namespace game
{
namespace scripting
{
class context;
class scheduler final
{
public:
explicit scheduler(context* context);
void run_frame();
private:
context* context_;
};
}
}

View File

@ -1,15 +1,15 @@
#include <std_include.hpp> #include <std_include.hpp>
#include "loader/module_loader.hpp"
#include "utils/hook.hpp" #include "utils/hook.hpp"
#include "utils/io.hpp" #include "utils/io.hpp"
#include "game/scripting/context.hpp"
#include "scheduler.hpp" #include "scheduler.hpp"
#include "scripting.hpp"
utils::hook scripting::start_hook_; class scripting final : public module
utils::hook scripting::stop_hook_;
void scripting::post_load()
{ {
public:
void post_load() override
{
start_hook_.initialize(SELECT_VALUE(0x50C575, 0x50D4F2, 0x48A026), &start_execution_stub, HOOK_CALL) // start_hook_.initialize(SELECT_VALUE(0x50C575, 0x50D4F2, 0x48A026), &start_execution_stub, HOOK_CALL) //
->install() // ->install() //
->quick(); ->quick();
@ -25,15 +25,20 @@ void scripting::post_load()
{ {
utils::hook(0x610970, &vm_notify_stub, HOOK_JUMP).install()->quick(); utils::hook(0x610970, &vm_notify_stub, HOOK_JUMP).install()->quick();
} }
}
void scripting::pre_destroy() scheduler::on_frame(std::bind(&scripting::run_frame, this));
{ }
void pre_destroy() override
{
this->scripts_.clear(); this->scripts_.clear();
} }
void scripting::load_scripts() private:
{ std::vector<std::unique_ptr<game::scripting::context>> scripts_;
void load_scripts()
{
const auto scripts = utils::io::list_files("open-iw5/scripts/"); const auto scripts = utils::io::list_files("open-iw5/scripts/");
for (const auto& script : scripts) for (const auto& script : scripts)
@ -52,10 +57,10 @@ void scripting::load_scripts()
} }
} }
} }
} }
void scripting::start_execution() void start_execution()
{ {
try try
{ {
this->load_scripts(); this->load_scripts();
@ -64,45 +69,56 @@ void scripting::start_execution()
{ {
propagate_error(e); propagate_error(e);
} }
} }
void scripting::stop_execution() void stop_execution()
{ {
this->scripts_.clear(); this->scripts_.clear();
} }
void scripting::dispatch(game::scripting::event* event) void run_frame()
{ {
for (const auto& script : this->scripts_)
{
script->get_scheduler()->run_frame();
}
}
void dispatch(game::scripting::event* event)
{
for (const auto& script : this->scripts_) for (const auto& script : this->scripts_)
{ {
script->get_event_handler()->dispatch(event); script->get_event_handler()->dispatch(event);
} }
} }
void scripting::propagate_error(const std::exception& e) static utils::hook start_hook_;
{ static utils::hook stop_hook_;
static void propagate_error(const std::exception& e)
{
printf("\n******* Script execution error *******\n"); printf("\n******* Script execution error *******\n");
printf("%s\n", e.what()); printf("%s\n", e.what());
printf("**************************************\n\n"); printf("**************************************\n\n");
scheduler::error("Script execution error\n(see console for actual details)\n", 5); scheduler::error("Script execution error\n(see console for actual details)\n", 5);
} }
void scripting::start_execution_stub() static void start_execution_stub()
{ {
module_loader::get<scripting>()->start_execution(); module_loader::get<scripting>()->start_execution();
reinterpret_cast<void(*)()>(start_hook_.get_original())(); reinterpret_cast<void(*)()>(start_hook_.get_original())();
} }
void scripting::stop_execution_stub() static void stop_execution_stub()
{ {
module_loader::get<scripting>()->stop_execution(); module_loader::get<scripting>()->stop_execution();
reinterpret_cast<void(*)()>(stop_hook_.get_original())(); reinterpret_cast<void(*)()>(stop_hook_.get_original())();
} }
void scripting::vm_notify_stub(const unsigned int notify_id, const unsigned short type, static void vm_notify_stub(const unsigned int notify_id, const unsigned short type,
game::native::VariableValue* stack) game::native::VariableValue* stack)
{ {
try try
{ {
game::scripting::event e; game::scripting::event e;
@ -126,6 +142,10 @@ void scripting::vm_notify_stub(const unsigned int notify_id, const unsigned shor
} }
game::native::VM_Notify(notify_id, type, stack); game::native::VM_Notify(notify_id, type, stack);
} }
};
utils::hook scripting::start_hook_;
utils::hook scripting::stop_hook_;
REGISTER_MODULE(scripting) REGISTER_MODULE(scripting)

View File

@ -1,31 +0,0 @@
#pragma once
#include "loader/module_loader.hpp"
#include "utils/hook.hpp"
#include "game/scripting/context.hpp"
class scripting final : public module
{
public:
void post_load() override;
void pre_destroy() override;
static void propagate_error(const std::exception& e);
private:
std::vector<std::unique_ptr<game::scripting::context>> scripts_;
void load_scripts();
void start_execution();
void stop_execution();
void dispatch(game::scripting::event* event);
static utils::hook start_hook_;
static utils::hook stop_hook_;
static void start_execution_stub();
static void stop_execution_stub();
static void vm_notify_stub(const unsigned int notify_id, const unsigned short type,
game::native::VariableValue* stack);
};