Files
Renderive/YSGraphic_Core/architecture/Renderable.cpp
T
2026-07-28 10:54:38 +08:00

189 lines
6.2 KiB
C++

#include <utility>
#include "Plot.h"
#include "Renderable_Core.h"
namespace YSG {
Renderable::Color_Buffer_Lease::Color_Buffer_Lease(Color_Buffer* buffer, Triple_Role_Buffer_Control* control, Triple_Buffer_Lease lease) : buffer(buffer), control(control), lease(lease) {
}
Renderable::Color_Buffer_Lease::Color_Buffer_Lease(Color_Buffer_Lease&& other) noexcept : buffer(std::exchange(other.buffer, nullptr)), control(std::exchange(other.control, nullptr)), lease(std::exchange(other.lease, Triple_Buffer_Lease{})) {
}
Renderable::Color_Buffer_Lease& Renderable::Color_Buffer_Lease::operator=(Color_Buffer_Lease&& other) noexcept {
if (this == &other)
return *this;
reset();
buffer = std::exchange(other.buffer, nullptr);
control = std::exchange(other.control, nullptr);
lease = std::exchange(other.lease, Triple_Buffer_Lease{});
return *this;
}
Renderable::Color_Buffer_Lease::~Color_Buffer_Lease() {
reset();
}
void Renderable::Color_Buffer_Lease::reset() {
if (!control)
return;
control->unmark_use(lease);
buffer = nullptr;
control = nullptr;
lease = {};
}
Plot_Buffer_Acquire_Mode Renderable::buffer_acquire_mode() const {
return dPtr->buffer_acquire_mode();
}
void Renderable::set_buffer_acquire_mode(Plot_Buffer_Acquire_Mode mode) {
dPtr->set_buffer_acquire_mode(mode);
}
RenderAble_Render_Schedule_Mode Renderable::render_schedule_mode() const {
return dPtr->render_schedule_mode();
}
void Renderable::set_render_schedule_mode(RenderAble_Render_Schedule_Mode mode) {
dPtr->set_render_schedule_mode(mode);
}
double Renderable::render_schedule_max_fps() const {
return dPtr->render_schedule_max_fps();
}
void Renderable::set_render_schedule_max_fps(double fps) {
dPtr->set_render_schedule_max_fps(fps);
}
bool Renderable::independent_pixel_cache() const {
return dPtr->independent_pixel_cache();
}
void Renderable::set_independent_pixel_cache(bool enabled) {
dPtr->set_independent_pixel_cache(enabled);
}
void Renderable::init(Plot* plot, QString layerName) {
if (layerName.isEmpty()) {
layerName = plot->default_layer_name;
}
plot->add_renderable(this, layerName);
mPlot = plot;
if (!dPtr)
dPtr = create_render_data();
dPtr->set_buffer_acquire_mode(plot->render_able_buffer_acquire_mode());
dPtr->clear_state_buffers();
dPtr->clear_input_buffers();
dPtr->mStateBuffers[State_Edit] = create_render_state();
dPtr->mStateBuffers[State_Ready] = create_render_state();
dPtr->mStateBuffers[State_Render] = create_render_state();
dPtr->mInputBuffers[Input_Edit].data = create_input_data();
dPtr->mInputBuffers[Input_Ready].data = create_input_data();
dPtr->mInputBuffers[Input_Render].data = create_input_data();
for (Render_State* state : dPtr->mStateBuffers) {
state->dPtr = dPtr;
}
dPtr->qPtr = this;
dPtr->mStateBuffers[State_Edit]->version = 1;
if (mPlot)
mPlot->mark_render_state_dirty();
}
void Renderable::draw(QPainter* painter) {
dPtr->draw(painter);
}
void Renderable::prepare_data() {
dPtr->prepare_data();
}
bool Renderable::select_test(const QPointF& pos) {
return dPtr->select_test(pos);
}
void Renderable::plot_event(QEvent* event) {
dPtr->plot_event(event);
}
void Renderable::mousePressEvent(QMouseEvent* event) {
dPtr->mousePressEvent(event);
}
void Renderable::mouseMoveEvent(QMouseEvent* event) {
dPtr->mouseMoveEvent(event);
}
void Renderable::mouseReleaseEvent(QMouseEvent* event) {
dPtr->mouseReleaseEvent(event);
}
void Renderable::set_hover_state(const QPoint& pos, bool active) {
dPtr->set_hover_state(pos, active);
}
void Renderable::keyPressEvent(QKeyEvent* event) {
dPtr->keyPressEvent(event);
}
void Renderable::keyReleaseEvent(QKeyEvent* event) {
dPtr->keyReleaseEvent(event);
}
void Renderable::first_resize_event(QResizeEvent* event) {
dPtr->first_resize_event(event);
}
void Renderable::resizeEvent(QResizeEvent* event) {
dPtr->resizeEvent(event);
}
void Renderable::wheelEvent(QWheelEvent* event) {
dPtr->wheelEvent(event);
}
bool Renderable::version_newer(std::uint64_t a, std::uint64_t b) {
return buffer_version_newer(a, b);
}
void Renderable::mark_state_dirty() {
if (dPtr) {
auto lease = dPtr->mStateControl.wait_mark_use_role(State_Edit);
++dPtr->state_by_index(lease.index)->version;
dPtr->mStateControl.unmark_use(lease);
}
mark_render_dirty();
}
void Renderable::mark_render_dirty() {
if (!mPlot)
return;
if (dPtr && dPtr->independent_pixel_cache()) {
dPtr->mark_pixel_dirty();
mPlot->mark_independent_render_dirty(this);
return;
}
mPlot->mark_render_state_dirty();
}
bool Renderable::ok() const {
return dPtr->mRenderStart && mPlot && !mPlot->first_resize && !mPlot->first_prepare_data;
}
Renderable::~Renderable() {
delete dPtr;
dPtr = nullptr;
}
bool Renderable::dect_cycle_rely() {
QQueue<Renderable*> queue;
queue.enqueue(this);
while (!queue.isEmpty()) {
Renderable* current = queue.dequeue();
QSet<Renderable*> visited;
QSet<Renderable*> recursionStack;
QVector<Renderable*> path;
bool has = has_cycle_rely(current, visited, recursionStack, path);
if (has) {
return true;
}
}
qDebug() << this << " 检测成功!";
return false;
}
bool Renderable::has_cycle_rely(Renderable* node, QSet<Renderable*>& visited, QSet<Renderable*>& recursionStack,
QVector<Renderable*>& currentPath) {
if (!node)
return false;
if (recursionStack.contains(node)) {
qDebug() << "Cycle detected in path:";
for (Renderable* n : currentPath) {
qDebug() << n->mObjectName << "(" << n << ")->";
}
qDebug() << node;
return true;
}
if (visited.contains(node)) {
return false;
}
visited.insert(node);
recursionStack.insert(node);
currentPath.append(node);
for (Renderable* child : node->mBeRelyList) {
if (has_cycle_rely(child, visited, recursionStack, currentPath)) {
return true;
}
}
recursionStack.remove(node);
currentPath.removeLast();
return false;
}
} // namespace YSG