189 lines
6.2 KiB
C++
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
|