Working scheduler - potentially thread-unsafe!
This commit is contained in:
parent
85077ec512
commit
180af9d404
@ -13,18 +13,20 @@ namespace game
|
|||||||
public:
|
public:
|
||||||
context();
|
context();
|
||||||
|
|
||||||
|
chaiscript::ChaiScript* get_chai();
|
||||||
|
|
||||||
executer* get_executer();
|
executer* get_executer();
|
||||||
scheduler* get_scheduler();
|
scheduler* get_scheduler();
|
||||||
parameters* get_parameters();
|
parameters* get_parameters();
|
||||||
event_handler* get_event_handler();
|
event_handler* get_event_handler();
|
||||||
chaiscript::ChaiScript* get_chai();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
chaiscript::ChaiScript chai_;
|
||||||
|
|
||||||
executer executer_;
|
executer executer_;
|
||||||
scheduler scheduler_;
|
scheduler scheduler_;
|
||||||
parameters parameters_;
|
parameters parameters_;
|
||||||
event_handler event_handler_;
|
event_handler event_handler_;
|
||||||
chaiscript::ChaiScript chai_;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,11 @@ namespace game
|
|||||||
chai->add(chaiscript::constructor<entity()>(), "entity");
|
chai->add(chaiscript::constructor<entity()>(), "entity");
|
||||||
chai->add(chaiscript::constructor<entity(const entity&)>(), "entity");
|
chai->add(chaiscript::constructor<entity(const entity&)>(), "entity");
|
||||||
|
|
||||||
|
chai->add(chaiscript::fun([](entity& lhs, const entity& rhs) -> entity&
|
||||||
|
{
|
||||||
|
return lhs = rhs;
|
||||||
|
}), "=");
|
||||||
|
|
||||||
chai->add(chaiscript::fun(&entity::get), "get");
|
chai->add(chaiscript::fun(&entity::get), "get");
|
||||||
chai->add(chaiscript::fun(&entity::set), "set");
|
chai->add(chaiscript::fun(&entity::set), "set");
|
||||||
|
|
||||||
@ -27,11 +32,6 @@ namespace game
|
|||||||
return ent.on_notify(event, callback, false);
|
return ent.on_notify(event, callback, false);
|
||||||
}), "onNotify");
|
}), "onNotify");
|
||||||
|
|
||||||
chai->add(chaiscript::fun([](entity& lhs, const entity& rhs) -> entity&
|
|
||||||
{
|
|
||||||
return lhs = rhs;
|
|
||||||
}), "=");
|
|
||||||
|
|
||||||
chai->add(chaiscript::fun([context](const std::string& event,
|
chai->add(chaiscript::fun([context](const std::string& event,
|
||||||
const std::function<void(const entity&,
|
const std::function<void(const entity&,
|
||||||
const std::vector<chaiscript::
|
const std::vector<chaiscript::
|
||||||
|
@ -7,11 +7,86 @@ namespace game
|
|||||||
{
|
{
|
||||||
scheduler::scheduler(context* context) : context_(context)
|
scheduler::scheduler(context* context) : context_(context)
|
||||||
{
|
{
|
||||||
|
const auto chai = this->context_->get_chai();
|
||||||
|
|
||||||
|
chai->add(chaiscript::user_type<task_handle>(), "task_handle");
|
||||||
|
chai->add(chaiscript::constructor<task_handle()>(), "task_handle");
|
||||||
|
chai->add(chaiscript::constructor<task_handle(const task_handle&)>(), "task_handle");
|
||||||
|
|
||||||
|
chai->add(chaiscript::fun([](task_handle& lhs, const task_handle& rhs) -> task_handle&
|
||||||
|
{
|
||||||
|
return lhs = rhs;
|
||||||
|
}), "=");
|
||||||
|
|
||||||
|
chai->add(chaiscript::fun([this](const std::function<void()>& callback, const long long milliseconds) -> task_handle
|
||||||
|
{
|
||||||
|
return this->add(callback, milliseconds, true);
|
||||||
|
}), "setTimeout");
|
||||||
|
|
||||||
|
chai->add(chaiscript::fun([this](const std::function<void()>& callback, const long long milliseconds) -> task_handle
|
||||||
|
{
|
||||||
|
return this->add(callback, milliseconds, false);
|
||||||
|
}), "setInterval");
|
||||||
|
|
||||||
|
const auto clear = [this](const task_handle& handle)
|
||||||
|
{
|
||||||
|
this->remove(handle);
|
||||||
|
};
|
||||||
|
|
||||||
|
chai->add(chaiscript::fun(clear), "clear");
|
||||||
|
chai->add(chaiscript::fun(clear), "clearTimeout");
|
||||||
|
chai->add(chaiscript::fun(clear), "clearInterval");
|
||||||
}
|
}
|
||||||
|
|
||||||
void scheduler::run_frame()
|
void scheduler::run_frame()
|
||||||
{
|
{
|
||||||
|
for (auto task = this->tasks_.begin(); task.is_valid(); ++task)
|
||||||
|
{
|
||||||
|
const auto now = std::chrono::steady_clock::now();
|
||||||
|
if ((now - task->last_execution) > task->delay)
|
||||||
|
{
|
||||||
|
task->last_execution = now;
|
||||||
|
if (task->is_volatile)
|
||||||
|
{
|
||||||
|
this->tasks_.remove(task);
|
||||||
|
}
|
||||||
|
|
||||||
|
task->callback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
task_handle scheduler::add(const std::function<void()>& callback, const long long milliseconds,
|
||||||
|
const bool is_volatile)
|
||||||
|
{
|
||||||
|
return this->add(callback, std::chrono::milliseconds(milliseconds), is_volatile);
|
||||||
|
}
|
||||||
|
|
||||||
|
task_handle scheduler::add(const std::function<void()>& callback, const std::chrono::milliseconds delay,
|
||||||
|
const bool is_volatile)
|
||||||
|
{
|
||||||
|
task task;
|
||||||
|
task.is_volatile = is_volatile;
|
||||||
|
task.callback = callback;
|
||||||
|
task.delay = delay;
|
||||||
|
task.last_execution = std::chrono::steady_clock::now();
|
||||||
|
task.id = ++this->current_task_id_;
|
||||||
|
|
||||||
|
this->tasks_.add(task);
|
||||||
|
|
||||||
|
return { task.id };
|
||||||
|
}
|
||||||
|
|
||||||
|
void scheduler::remove(const task_handle& handle)
|
||||||
|
{
|
||||||
|
for (auto task = this->tasks_.begin(); task.is_valid(); ++task)
|
||||||
|
{
|
||||||
|
if(task->id == handle.id)
|
||||||
|
{
|
||||||
|
this->tasks_.remove(task);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
#include "utils/chain.hpp"
|
||||||
|
|
||||||
namespace game
|
namespace game
|
||||||
{
|
{
|
||||||
@ -6,6 +7,21 @@ namespace game
|
|||||||
{
|
{
|
||||||
class context;
|
class context;
|
||||||
|
|
||||||
|
class task_handle
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
unsigned long long id = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class task final : public task_handle
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
std::chrono::steady_clock::time_point last_execution;
|
||||||
|
std::function<void()> callback;
|
||||||
|
std::chrono::milliseconds delay;
|
||||||
|
bool is_volatile;
|
||||||
|
};
|
||||||
|
|
||||||
class scheduler final
|
class scheduler final
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -15,6 +31,14 @@ namespace game
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
context* context_;
|
context* context_;
|
||||||
|
|
||||||
|
utils::chain<task> tasks_;
|
||||||
|
std::atomic_int64_t current_task_id_ = 0;
|
||||||
|
|
||||||
|
task_handle add(const std::function<void()>& callback, long long milliseconds, bool is_volatile);
|
||||||
|
task_handle add(const std::function<void()>& callback, std::chrono::milliseconds delay, bool is_volatile);
|
||||||
|
|
||||||
|
void remove(const task_handle& handle);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -35,6 +35,7 @@
|
|||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <queue>
|
#include <queue>
|
||||||
#include <regex>
|
#include <regex>
|
||||||
|
#include <chrono>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
namespace utils
|
namespace utils
|
||||||
{
|
{
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class chain
|
class chain final
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
class entry
|
class entry final
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<T> object_;
|
std::shared_ptr<T> object_;
|
||||||
@ -23,7 +25,7 @@ namespace utils
|
|||||||
|
|
||||||
void set(T object)
|
void set(T object)
|
||||||
{
|
{
|
||||||
this->object_ = std::shared_ptr<T>(new T());
|
this->object_ = std::make_shared<T>();
|
||||||
*this->object_.get() = object;
|
*this->object_.get() = object;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,7 +87,7 @@ namespace utils
|
|||||||
if (!this->empty())
|
if (!this->empty())
|
||||||
{
|
{
|
||||||
// Create new chain entry
|
// Create new chain entry
|
||||||
std::shared_ptr<entry> current_object = std::shared_ptr<entry>(new entry);
|
std::shared_ptr<entry> current_object = std::make_shared<entry>();
|
||||||
*current_object.get() = this->object_;
|
*current_object.get() = this->object_;
|
||||||
|
|
||||||
// Add it to the chain
|
// Add it to the chain
|
||||||
|
Loading…
Reference in New Issue
Block a user