子图可选
This commit is contained in:
@@ -98,7 +98,7 @@ protected:
|
|||||||
static void run_prepare_data(Attached auto* object) {
|
static void run_prepare_data(Attached auto* object) {
|
||||||
using Object = std::remove_pointer_t<decltype(object)>;
|
using Object = std::remove_pointer_t<decltype(object)>;
|
||||||
auto& private_data = static_cast<typename Object::Private&>(object->d);
|
auto& private_data = static_cast<typename Object::Private&>(object->d);
|
||||||
if constexpr (requires { private_data.prepare_data(object); }) private_data.prepare_data(object);
|
private_data.prepare_data(object);
|
||||||
auto callback = [&](auto& value) {
|
auto callback = [&](auto& value) {
|
||||||
if constexpr (requires { value.after_prepare_data(object); }) value.after_prepare_data(object);
|
if constexpr (requires { value.after_prepare_data(object); }) value.after_prepare_data(object);
|
||||||
};
|
};
|
||||||
@@ -108,6 +108,7 @@ public:
|
|||||||
struct Private : Prev_Private {
|
struct Private : Prev_Private {
|
||||||
using Run_Predicate = bool (*)(Root*, bool);
|
using Run_Predicate = bool (*)(Root*, bool);
|
||||||
using Rebuild_Predicate = bool (*)(Root*);
|
using Rebuild_Predicate = bool (*)(Root*);
|
||||||
|
using Stage_Run = void (*)(Root*);
|
||||||
using Graph_Builder = tf::Taskflow (*)(Root*, std::pmr::memory_resource*);
|
using Graph_Builder = tf::Taskflow (*)(Root*, std::pmr::memory_resource*);
|
||||||
using State_Access = State* (*)(Root*);
|
using State_Access = State* (*)(Root*);
|
||||||
using State_Notify = void (*)(Root*);
|
using State_Notify = void (*)(Root*);
|
||||||
@@ -116,14 +117,16 @@ public:
|
|||||||
Run_Predicate paint_predicate;
|
Run_Predicate paint_predicate;
|
||||||
Rebuild_Predicate prepare_rebuild_predicate;
|
Rebuild_Predicate prepare_rebuild_predicate;
|
||||||
Rebuild_Predicate paint_rebuild_predicate;
|
Rebuild_Predicate paint_rebuild_predicate;
|
||||||
|
Stage_Run prepare_run;
|
||||||
|
Stage_Run paint_run;
|
||||||
Graph_Builder prepare_builder;
|
Graph_Builder prepare_builder;
|
||||||
Graph_Builder paint_builder;
|
Graph_Builder paint_builder;
|
||||||
State_Access state_access;
|
State_Access state_access;
|
||||||
State_Notify state_notify;
|
State_Notify state_notify;
|
||||||
};
|
};
|
||||||
const Dispatch* dispatch{};
|
const Dispatch* dispatch{};
|
||||||
tf::Taskflow prepare_graph;
|
std::unique_ptr<tf::Taskflow> prepare_graph;
|
||||||
tf::Taskflow paint_graph;
|
std::unique_ptr<tf::Taskflow> paint_graph;
|
||||||
bool prepare_graph_built{};
|
bool prepare_graph_built{};
|
||||||
bool paint_graph_built{};
|
bool paint_graph_built{};
|
||||||
bool should_rebuild_prepare_graph(Attached auto*, const State&) {
|
bool should_rebuild_prepare_graph(Attached auto*, const State&) {
|
||||||
@@ -138,22 +141,6 @@ public:
|
|||||||
bool should_paint(Attached auto*, const State&, bool dirty) {
|
bool should_paint(Attached auto*, const State&, bool dirty) {
|
||||||
return dirty;
|
return dirty;
|
||||||
}
|
}
|
||||||
tf::Taskflow build_prepare_graph(Attached auto* object, const State&, std::pmr::memory_resource*) {
|
|
||||||
tf::Taskflow taskflow;
|
|
||||||
taskflow.emplace([object] {
|
|
||||||
run_prepare_data(object);
|
|
||||||
}).name("renderable.prepare.data");
|
|
||||||
return taskflow;
|
|
||||||
}
|
|
||||||
tf::Taskflow build_paint_graph(Attached auto* object, const State&, std::pmr::memory_resource*) {
|
|
||||||
using Object = std::remove_pointer_t<decltype(object)>;
|
|
||||||
tf::Taskflow taskflow;
|
|
||||||
taskflow.emplace([object] {
|
|
||||||
auto& private_data = static_cast<typename Object::Private&>(object->d);
|
|
||||||
private_data.paint(object);
|
|
||||||
}).name("renderable.paint.data");
|
|
||||||
return taskflow;
|
|
||||||
}
|
|
||||||
void prepare_data(Attached auto*) {}
|
void prepare_data(Attached auto*) {}
|
||||||
void after_prepare_data(Attached auto*) {}
|
void after_prepare_data(Attached auto*) {}
|
||||||
void paint(Attached auto*) {}
|
void paint(Attached auto*) {}
|
||||||
@@ -183,16 +170,43 @@ private:
|
|||||||
auto& private_data = static_cast<typename Object::Private&>(value->d);
|
auto& private_data = static_cast<typename Object::Private&>(value->d);
|
||||||
return private_data.should_rebuild_paint_graph(value, *value->d.state.current);
|
return private_data.should_rebuild_paint_graph(value, *value->d.state.current);
|
||||||
},
|
},
|
||||||
[](Root* root, std::pmr::memory_resource* resource) {
|
[](Root* root) {
|
||||||
|
auto* value = static_cast<Object*>(root);
|
||||||
|
run_prepare_data(value);
|
||||||
|
},
|
||||||
|
[](Root* root) {
|
||||||
|
auto* value = static_cast<Object*>(root);
|
||||||
|
auto& private_data = static_cast<typename Object::Private&>(value->d);
|
||||||
|
private_data.paint(value);
|
||||||
|
},
|
||||||
|
[]() -> Private::Graph_Builder {
|
||||||
|
if constexpr (requires(typename Object::Private& private_data, Object* value, const typename Object::State& state, std::pmr::memory_resource* resource) {
|
||||||
|
{ private_data.build_prepare_graph(value, state, resource) } -> std::same_as<tf::Taskflow>;
|
||||||
|
}) {
|
||||||
|
return [](Root* root, std::pmr::memory_resource* resource) {
|
||||||
auto* value = static_cast<Object*>(root);
|
auto* value = static_cast<Object*>(root);
|
||||||
auto& private_data = static_cast<typename Object::Private&>(value->d);
|
auto& private_data = static_cast<typename Object::Private&>(value->d);
|
||||||
return private_data.build_prepare_graph(value, *value->d.state.current, resource);
|
return private_data.build_prepare_graph(value, *value->d.state.current, resource);
|
||||||
},
|
};
|
||||||
[](Root* root, std::pmr::memory_resource* resource) {
|
}
|
||||||
|
else {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}(),
|
||||||
|
[]() -> Private::Graph_Builder {
|
||||||
|
if constexpr (requires(typename Object::Private& private_data, Object* value, const typename Object::State& state, std::pmr::memory_resource* resource) {
|
||||||
|
{ private_data.build_paint_graph(value, state, resource) } -> std::same_as<tf::Taskflow>;
|
||||||
|
}) {
|
||||||
|
return [](Root* root, std::pmr::memory_resource* resource) {
|
||||||
auto* value = static_cast<Object*>(root);
|
auto* value = static_cast<Object*>(root);
|
||||||
auto& private_data = static_cast<typename Object::Private&>(value->d);
|
auto& private_data = static_cast<typename Object::Private&>(value->d);
|
||||||
return private_data.build_paint_graph(value, *value->d.state.current, resource);
|
return private_data.build_paint_graph(value, *value->d.state.current, resource);
|
||||||
},
|
};
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}(),
|
||||||
[](Root* root) {
|
[](Root* root) {
|
||||||
auto* value = static_cast<Object*>(root);
|
auto* value = static_cast<Object*>(root);
|
||||||
return static_cast<State*>(value->d.state.current);
|
return static_cast<State*>(value->d.state.current);
|
||||||
@@ -317,20 +331,34 @@ void Scene::Private::after_exchange(Attached auto* object, Prop*, State*, const
|
|||||||
auto& state = *dispatch->state_access(root);
|
auto& state = *dispatch->state_access(root);
|
||||||
state.prepare_graph_rebuilt = false;
|
state.prepare_graph_rebuilt = false;
|
||||||
state.prepare_execution_time_ns = 0;
|
state.prepare_execution_time_ns = 0;
|
||||||
|
if (dispatch->prepare_builder) {
|
||||||
bool rebuild = dispatch->prepare_rebuild_predicate(root);
|
bool rebuild = dispatch->prepare_rebuild_predicate(root);
|
||||||
if (!data->prepare_graph_built || rebuild) {
|
if (!data->prepare_graph_built || rebuild) {
|
||||||
data->prepare_graph = dispatch->prepare_builder(root, detail::task_memory_resource());
|
*data->prepare_graph = dispatch->prepare_builder(root, detail::task_memory_resource());
|
||||||
data->prepare_graph_built = true;
|
data->prepare_graph_built = true;
|
||||||
state.prepare_graph_rebuilt = true;
|
state.prepare_graph_rebuilt = true;
|
||||||
root->template mark_dirty<Prepare_Data_Tag>();
|
root->template mark_dirty<Prepare_Data_Tag>();
|
||||||
}
|
}
|
||||||
|
state.prepare_task_count = data->prepare_graph->num_tasks();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
state.prepare_task_count = 1;
|
||||||
|
}
|
||||||
bool dirty = root->template dirty<Prepare_Data_Tag>();
|
bool dirty = root->template dirty<Prepare_Data_Tag>();
|
||||||
state.prepare_dirty = dirty;
|
state.prepare_dirty = dirty;
|
||||||
state.prepare_task_count = data->prepare_graph.num_tasks();
|
|
||||||
state.prepare_executed = dispatch->prepare_predicate(root, dirty);
|
state.prepare_executed = dispatch->prepare_predicate(root, dirty);
|
||||||
return state.prepare_executed ? 0 : 1;
|
return state.prepare_executed ? 0 : 1;
|
||||||
}).name("renderable.prepare.condition");
|
}).name("renderable.prepare.condition");
|
||||||
auto prepare_run = taskflow.composed_of(data->prepare_graph).name("renderable.prepare.graph");
|
tf::Task prepare_run;
|
||||||
|
if (dispatch->prepare_builder) {
|
||||||
|
if (!data->prepare_graph) data->prepare_graph = std::make_unique<tf::Taskflow>();
|
||||||
|
prepare_run = taskflow.composed_of(*data->prepare_graph).name("renderable.prepare.graph");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
prepare_run = taskflow.emplace([dispatch, root] {
|
||||||
|
dispatch->prepare_run(root);
|
||||||
|
}).name("renderable.prepare.data");
|
||||||
|
}
|
||||||
auto prepare_done = taskflow.emplace([dispatch, root] {
|
auto prepare_done = taskflow.emplace([dispatch, root] {
|
||||||
auto& state = *dispatch->state_access(root);
|
auto& state = *dispatch->state_access(root);
|
||||||
if (!state.prepare_executed) return;
|
if (!state.prepare_executed) return;
|
||||||
@@ -343,20 +371,34 @@ void Scene::Private::after_exchange(Attached auto* object, Prop*, State*, const
|
|||||||
auto& state = *dispatch->state_access(root);
|
auto& state = *dispatch->state_access(root);
|
||||||
state.paint_graph_rebuilt = false;
|
state.paint_graph_rebuilt = false;
|
||||||
state.paint_execution_time_ns = 0;
|
state.paint_execution_time_ns = 0;
|
||||||
|
if (dispatch->paint_builder) {
|
||||||
bool rebuild = dispatch->paint_rebuild_predicate(root);
|
bool rebuild = dispatch->paint_rebuild_predicate(root);
|
||||||
if (!data->paint_graph_built || rebuild) {
|
if (!data->paint_graph_built || rebuild) {
|
||||||
data->paint_graph = dispatch->paint_builder(root, detail::task_memory_resource());
|
*data->paint_graph = dispatch->paint_builder(root, detail::task_memory_resource());
|
||||||
data->paint_graph_built = true;
|
data->paint_graph_built = true;
|
||||||
state.paint_graph_rebuilt = true;
|
state.paint_graph_rebuilt = true;
|
||||||
root->template mark_dirty<Paint_Tag>();
|
root->template mark_dirty<Paint_Tag>();
|
||||||
}
|
}
|
||||||
|
state.paint_task_count = data->paint_graph->num_tasks();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
state.paint_task_count = 1;
|
||||||
|
}
|
||||||
bool dirty = root->template dirty<Paint_Tag>();
|
bool dirty = root->template dirty<Paint_Tag>();
|
||||||
state.paint_dirty = dirty;
|
state.paint_dirty = dirty;
|
||||||
state.paint_task_count = data->paint_graph.num_tasks();
|
|
||||||
state.paint_executed = dispatch->paint_predicate(root, dirty);
|
state.paint_executed = dispatch->paint_predicate(root, dirty);
|
||||||
return state.paint_executed ? 0 : 1;
|
return state.paint_executed ? 0 : 1;
|
||||||
}).name("renderable.paint.condition");
|
}).name("renderable.paint.condition");
|
||||||
auto paint_run = taskflow.composed_of(data->paint_graph).name("renderable.paint.graph");
|
tf::Task paint_run;
|
||||||
|
if (dispatch->paint_builder) {
|
||||||
|
if (!data->paint_graph) data->paint_graph = std::make_unique<tf::Taskflow>();
|
||||||
|
paint_run = taskflow.composed_of(*data->paint_graph).name("renderable.paint.graph");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
paint_run = taskflow.emplace([dispatch, root] {
|
||||||
|
dispatch->paint_run(root);
|
||||||
|
}).name("renderable.paint.data");
|
||||||
|
}
|
||||||
auto paint_done = taskflow.emplace([dispatch, root] {
|
auto paint_done = taskflow.emplace([dispatch, root] {
|
||||||
auto& state = *dispatch->state_access(root);
|
auto& state = *dispatch->state_access(root);
|
||||||
if (state.paint_executed) root->template take_dirty<Paint_Tag>();
|
if (state.paint_executed) root->template take_dirty<Paint_Tag>();
|
||||||
|
|||||||
Reference in New Issue
Block a user