Added class to schedule custom tasks from scripts
parent
22f17f6294
commit
f58199e7de
1
SCsub
1
SCsub
|
@ -39,6 +39,7 @@ voxel_files = [
|
|||
"util/noise/gd_noise_range.cpp",
|
||||
|
||||
"util/tasks/*.cpp",
|
||||
"util/tasks/godot/*.cpp",
|
||||
|
||||
"terrain/*.cpp",
|
||||
"terrain/instancing/*.cpp",
|
||||
|
|
|
@ -18,6 +18,7 @@ Godot 4 is required from this version.
|
|||
- Added `FastNoise2` for faster SIMD noise
|
||||
- Added experimental support functions to help setting up basic multiplayer with `VoxelTerrain` (might change in the future)
|
||||
- Improved support for 64-bit floats
|
||||
- Added `ZN_ThreadedTask` to allow running custom tasks using the thread pool system
|
||||
- `VoxelGeneratorGraph`: added support for outputting to the TYPE channel, allowing use with `VoxelMesherBlocky`
|
||||
- `VoxelGeneratorGraph`: editor: unconnected inputs show their default value directly on the node
|
||||
- `VoxelGeneratorGraph`: editor: allow to change the axes on preview nodes 3D slices
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#include "util/macros.h"
|
||||
#include "util/noise/fast_noise_lite/fast_noise_lite.h"
|
||||
#include "util/noise/fast_noise_lite/fast_noise_lite_gradient.h"
|
||||
#include "util/tasks/godot/threaded_task_gd.h"
|
||||
|
||||
#ifdef VOXEL_ENABLE_FAST_NOISE_2
|
||||
#include "util/noise/fast_noise_2.h"
|
||||
|
@ -131,6 +132,7 @@ void register_voxel_types() {
|
|||
ClassDB::register_class<VoxelVoxLoader>();
|
||||
ClassDB::register_class<ZN_FastNoiseLite>();
|
||||
ClassDB::register_class<ZN_FastNoiseLiteGradient>();
|
||||
ClassDB::register_class<ZN_ThreadedTask>();
|
||||
// See SCsub
|
||||
#ifdef VOXEL_ENABLE_FAST_NOISE_2
|
||||
ClassDB::register_class<FastNoise2>();
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "voxel_server_gd.h"
|
||||
#include "../util/macros.h"
|
||||
#include "../util/profiling.h"
|
||||
#include "../util/tasks/godot/threaded_task_gd.h"
|
||||
#include "voxel_server.h"
|
||||
|
||||
namespace zylann::voxel::gd {
|
||||
|
@ -34,6 +35,12 @@ Dictionary VoxelServer::get_stats() const {
|
|||
return zylann::voxel::VoxelServer::get_singleton()->get_stats().to_dict();
|
||||
}
|
||||
|
||||
void VoxelServer::schedule_task(Ref<ZN_ThreadedTask> task) {
|
||||
ERR_FAIL_COND(task.is_null());
|
||||
ERR_FAIL_COND_MSG(task->is_scheduled(), "Cannot schedule again a task that is already scheduled");
|
||||
zylann::voxel::VoxelServer::get_singleton()->push_async_task(task->create_task());
|
||||
}
|
||||
|
||||
void VoxelServer::_on_rendering_server_frame_post_draw() {
|
||||
#ifdef VOXEL_PROFILER_ENABLED
|
||||
VOXEL_PROFILE_MARK_FRAME();
|
||||
|
|
|
@ -4,6 +4,10 @@
|
|||
#include "core/object/class_db.h"
|
||||
#include <core/object/object.h>
|
||||
|
||||
namespace zylann {
|
||||
class ZN_ThreadedTask;
|
||||
} // namespace zylann
|
||||
|
||||
namespace zylann::voxel::gd {
|
||||
|
||||
// Godot-facing singleton class.
|
||||
|
@ -12,6 +16,7 @@ class VoxelServer : public Object {
|
|||
GDCLASS(VoxelServer, Object)
|
||||
public:
|
||||
Dictionary get_stats() const;
|
||||
void schedule_task(Ref<ZN_ThreadedTask> task);
|
||||
|
||||
VoxelServer();
|
||||
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
#include "threaded_task_gd.h"
|
||||
|
||||
namespace zylann {
|
||||
|
||||
// Using a decoupled pattern so we can do a few more safety checks for scripters
|
||||
class ZN_ThreadedTaskInternal : public IThreadedTask {
|
||||
public:
|
||||
Ref<ZN_ThreadedTask> ref;
|
||||
|
||||
void run(ThreadedTaskContext ctx) override {
|
||||
ref->run(ctx.thread_index);
|
||||
}
|
||||
|
||||
void apply_result() override {
|
||||
// Not exposed. Scripters may prefer to use a `completed` signal instead.
|
||||
ref->mark_completed();
|
||||
}
|
||||
|
||||
int get_priority() override {
|
||||
return ref->get_priority();
|
||||
}
|
||||
|
||||
bool is_cancelled() override {
|
||||
return ref->is_cancelled();
|
||||
}
|
||||
};
|
||||
|
||||
void ZN_ThreadedTask::run(int thread_index) {
|
||||
GDVIRTUAL_CALL(_run, thread_index);
|
||||
}
|
||||
|
||||
int ZN_ThreadedTask::get_priority() {
|
||||
int priority = 0;
|
||||
if (GDVIRTUAL_CALL(_get_priority, priority)) {
|
||||
return priority;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool ZN_ThreadedTask::is_cancelled() {
|
||||
bool cancelled = false;
|
||||
if (GDVIRTUAL_CALL(_is_cancelled, cancelled)) {
|
||||
return cancelled;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ZN_ThreadedTask::is_scheduled() const {
|
||||
return _scheduled_task != nullptr;
|
||||
}
|
||||
|
||||
void ZN_ThreadedTask::mark_completed() {
|
||||
_scheduled_task = nullptr;
|
||||
emit_signal(SNAME("completed"));
|
||||
}
|
||||
|
||||
IThreadedTask *ZN_ThreadedTask::create_task() {
|
||||
CRASH_COND(_scheduled_task != nullptr);
|
||||
_scheduled_task = memnew(ZN_ThreadedTaskInternal);
|
||||
_scheduled_task->ref.reference_ptr(this);
|
||||
return _scheduled_task;
|
||||
}
|
||||
|
||||
void ZN_ThreadedTask::_bind_methods() {
|
||||
ADD_SIGNAL(MethodInfo("completed"));
|
||||
|
||||
GDVIRTUAL_BIND(_run, "thread_index");
|
||||
GDVIRTUAL_BIND(_get_priority);
|
||||
GDVIRTUAL_BIND(_is_cancelled);
|
||||
}
|
||||
|
||||
} // namespace zylann
|
|
@ -0,0 +1,39 @@
|
|||
#ifndef ZN_THREADED_TASK_GD
|
||||
#define ZN_THREADED_TASK_GD
|
||||
|
||||
#include "../threaded_task.h"
|
||||
#include <core/object/ref_counted.h>
|
||||
#include <core/object/script_language.h> // needed for GDVIRTUAL macro
|
||||
#include <core/object/gdvirtual.gen.inc> // Also needed for GDVIRTUAL macro...
|
||||
|
||||
namespace zylann {
|
||||
|
||||
class ZN_ThreadedTaskInternal;
|
||||
|
||||
class ZN_ThreadedTask : public RefCounted {
|
||||
GDCLASS(ZN_ThreadedTask, RefCounted)
|
||||
public:
|
||||
void run(int thread_index);
|
||||
int get_priority();
|
||||
bool is_cancelled();
|
||||
|
||||
// Internal
|
||||
bool is_scheduled() const;
|
||||
void mark_completed();
|
||||
IThreadedTask *create_task();
|
||||
|
||||
private:
|
||||
GDVIRTUAL1(_run, int);
|
||||
GDVIRTUAL0R(int, _get_priority);
|
||||
GDVIRTUAL0R(bool, _is_cancelled);
|
||||
|
||||
static void _bind_methods();
|
||||
|
||||
// Created upon scheduling, owned by the task runner
|
||||
ZN_ThreadedTaskInternal *_scheduled_task = nullptr;
|
||||
bool _completed = false;
|
||||
};
|
||||
|
||||
} // namespace zylann
|
||||
|
||||
#endif // ZN_THREADED_TASK_GD
|
Loading…
Reference in New Issue