Working scheduler - potentially thread-unsafe!
This commit is contained in:
parent
85077ec512
commit
180af9d404
@ -13,18 +13,20 @@ namespace game
|
||||
public:
|
||||
context();
|
||||
|
||||
chaiscript::ChaiScript* get_chai();
|
||||
|
||||
executer* get_executer();
|
||||
scheduler* get_scheduler();
|
||||
parameters* get_parameters();
|
||||
event_handler* get_event_handler();
|
||||
chaiscript::ChaiScript* get_chai();
|
||||
|
||||
private:
|
||||
chaiscript::ChaiScript chai_;
|
||||
|
||||
executer executer_;
|
||||
scheduler scheduler_;
|
||||
parameters parameters_;
|
||||
event_handler event_handler_;
|
||||
chaiscript::ChaiScript chai_;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -15,6 +15,11 @@ namespace game
|
||||
chai->add(chaiscript::constructor<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::set), "set");
|
||||
|
||||
@ -27,11 +32,6 @@ namespace game
|
||||
return ent.on_notify(event, callback, false);
|
||||
}), "onNotify");
|
||||
|
||||
chai->add(chaiscript::fun([](entity& lhs, const entity& rhs) -> entity&
|
||||
{
|
||||
return lhs = rhs;
|
||||
}), "=");
|
||||
|
||||
chai->add(chaiscript::fun([context](const std::string& event,
|
||||
const std::function<void(const entity&,
|
||||
const std::vector<chaiscript::
|
||||
|
@ -7,11 +7,86 @@ namespace game
|
||||
{
|
||||
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()
|
||||
{
|
||||
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
|
||||
#include "utils/chain.hpp"
|
||||
|
||||
namespace game
|
||||
{
|
||||
@ -6,6 +7,21 @@ namespace game
|
||||
{
|
||||
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
|
||||
{
|
||||
public:
|
||||
@ -15,6 +31,14 @@ namespace game
|
||||
|
||||
private:
|
||||
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 <queue>
|
||||
#include <regex>
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
#include <fstream>
|
||||
#include <utility>
|
||||
|
@ -1,10 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
namespace utils
|
||||
{
|
||||
template <typename T>
|
||||
class chain
|
||||
class chain final
|
||||
{
|
||||
public:
|
||||
class entry
|
||||
class entry final
|
||||
{
|
||||
private:
|
||||
std::shared_ptr<T> object_;
|
||||
@ -23,7 +25,7 @@ namespace utils
|
||||
|
||||
void set(T object)
|
||||
{
|
||||
this->object_ = std::shared_ptr<T>(new T());
|
||||
this->object_ = std::make_shared<T>();
|
||||
*this->object_.get() = object;
|
||||
}
|
||||
|
||||
@ -85,7 +87,7 @@ namespace utils
|
||||
if (!this->empty())
|
||||
{
|
||||
// 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_;
|
||||
|
||||
// Add it to the chain
|
||||
|
Loading…
Reference in New Issue
Block a user