更新缓存机制

This commit is contained in:
codeboss 2025-10-12 23:04:18 +08:00
parent 927909da8d
commit e5846ed637
4 changed files with 97 additions and 23 deletions

View File

@ -12,6 +12,7 @@ int main(int argc, char* argv[])
MapPresent p;
p.show();
p.zoomTo(1);
//QObject::connect(&p, &MapPresent::mouseIn, [=]() {
// qDebug() << "Mouse Enter";

View File

@ -20,15 +20,34 @@ MapPresent::MapPresent(QWidget* parent /*= nullptr*/)
_type_present_delegate[delegate->unitType()] = delegate;
connect(this, &MapPresent::mouseOut, delegate, &BasicUnitDelegate::hotClear);
connect(this, &MapPresent::mouseHover, delegate, &BasicUnitDelegate::hotIndexSet);
connect(delegate, &BasicUnitDelegate::updateRequest, [=]() { this->update(); });
connect(delegate, &BasicUnitDelegate::updateRequest, [=](const PresentIndex& idx) {
if (idx.isValid() && !_updated_units.contains(idx)) {
_updated_units.append(idx);
}
this->update();
});
this->setMouseTracking(true);
}
void MapPresent::zoomTo(double percent)
{
this->_scale_times = std::max(1.0 / 2, percent);
this->visible_units_tidy();
this->update();
}
double MapPresent::zoomTimes() const
{
return _scale_times;
}
PresentIndex MapPresent::indexGet(const QPointF& pos) const
{
QList<PresentOption> templist;
for (auto unit : _visible_units) {
for (auto& unit : _visible_units) {
if (unit.outline.contains(pos)) {
templist << unit;
@ -59,7 +78,7 @@ QRectF MapPresent::outlineGet(const PresentIndex& idx) const
auto widget_rect = this->rect();
auto widget_center = widget_rect.center();
const float ap_len = _primitive_region_len / 2;
const float ap_len = _primitive_region_len * _scale_times / 2;
auto a2_vec = ap_len * sqrt(3) / 2;
auto n_yinc = QVector3D(a2_vec, ap_len * 3 / 2, 0);
auto n_xinc = QVector3D(a2_vec, -ap_len * 3 / 2, 0);
@ -75,24 +94,34 @@ QRectF MapPresent::outlineGet(const PresentIndex& idx) const
void MapPresent::paintEvent(QPaintEvent* ev)
{
QWidget::paintEvent(ev);
UnitPresentDelegate& t = *_type_present_delegate[0];
QPainter p(this);
for (auto opt : _visible_units) {
p.save();
if (_updated_units.size()) {
QPainter pic_painter(&_paint_buffer);
for (auto idx : _updated_units) {
pic_painter.save();
auto opt = _visible_units[idx];
auto rect = opt.outline;
p.translate(rect.topLeft());
pic_painter.translate(rect.topLeft());
rect.moveTo(0, 0);
auto clip_path = BasicUnitDelegate::clipPathGet(rect);
p.setClipPath(clip_path);
pic_painter.setClipPath(clip_path);
opt.outline = rect;
t.paint(&p, opt);
UnitPresentDelegate& t = *_type_present_delegate[0];
t.paint(&pic_painter, opt);
p.restore();
pic_painter.restore();
}
_updated_units.clear();
}
QPainter widget_painter(this);
// ת·¢ÀÛ»ý
widget_painter.drawPixmap(rect(), _paint_buffer);
}
void MapPresent::resizeEvent(QResizeEvent* event)
@ -138,8 +167,9 @@ void MapPresent::visible_units_tidy() {
_visible_units.clear();
QRectF curr_outline = this->rect();
_visible_units << AssumeOpt(_center_index, outlineGet(_center_index));
_paint_buffer = QPixmap(curr_outline.toRect().size());
_visible_units[_center_index] = AssumeOpt(_center_index, outlineGet(_center_index));
int visible_count = 1, deduce_x = 1;
while (visible_count) {
visible_count = 0;
@ -148,13 +178,14 @@ void MapPresent::visible_units_tidy() {
for (auto unit : siblings) {
auto visible_rect = outlineGet(unit);
if (curr_outline.intersects(visible_rect)) {
_visible_units << AssumeOpt(unit, visible_rect);
_visible_units[unit] = AssumeOpt(unit, visible_rect);
visible_count++;
}
}
}
// TODO ¹¹½¨¿ìËÙ²âÊÔ×éÖ¯½á¹¹
for (auto optx : _visible_units)
_updated_units.append(optx.index);
}
QList<PresentIndex> MapPresent::siblingsGet(const PresentIndex& center, uint16_t dist) const
@ -192,6 +223,21 @@ QList<PresentIndex> MapPresent::item_supply(const PresentIndex& a, const Present
return items;
}
void MapPresent::unit_option_paint(QPainter& widget_painter, const PresentOption& xopt)
{
auto opt = xopt;
auto rect = opt.outline;
widget_painter.translate(rect.topLeft());
rect.moveTo(0, 0);
auto clip_path = BasicUnitDelegate::clipPathGet(rect);
widget_painter.setClipPath(clip_path);
opt.outline = rect;
UnitPresentDelegate& t = *_type_present_delegate[0];
t.paint(&widget_painter, opt);
}
PresentIndex& PresentIndex::operator+=(const PresentIndex& other)
{
row += other.row;
@ -209,6 +255,13 @@ bool PresentIndex::isValid() const
return row != INT_MAX && col != INT_MAX;
}
bool PresentIndex::operator<(const PresentIndex& other) const
{
if (row == other.row)
return col < other.col;
return row < other.row;
}
bool PresentIndex::operator==(const PresentIndex& other) const
{
return row == other.row && col == other.col;

View File

@ -3,6 +3,7 @@
#include "mappresent_global.h"
#include <QWidget>
#include <memory>
#include <QMap>
/// <summary>
@ -23,6 +24,7 @@ struct MAPPRESENT_EXPORT PresentIndex {
PresentIndex& operator+=(const PresentIndex& other);
bool operator!=(const PresentIndex& other) const;
bool operator==(const PresentIndex& other) const;
bool operator<(const PresentIndex& other) const;
};
/// <summary>
@ -79,11 +81,11 @@ private:
/// <summary>
/// 初级区域矩形变长
/// </summary>
const float _primitive_region_len = 100;
const float _primitive_region_len = 64;
/// <summary>
/// 缩放倍数
/// </summary>
short _scale_times = 1;
double _scale_times = 1;
/// <summary>
/// 当前瓦片地图中心索引
/// </summary>
@ -91,9 +93,18 @@ private:
// ===================================
/// <summary>
/// 绘制中转缓冲区
/// </summary>
QPixmap _paint_buffer;
/// <summary>
/// 试图核心索引
/// </summary>
QList<PresentOption> _visible_units;
QMap<PresentIndex, PresentOption> _visible_units;
/// <summary>
/// 被更新的单元索引
/// </summary>
QList<PresentIndex> _updated_units;
/// <summary>
/// 可视化单元整理
/// </summary>
@ -111,11 +122,15 @@ private:
/// 类型化绘制委托
/// </summary>
QHash<int, UnitPresentDelegate*> _type_present_delegate;
void unit_option_paint(QPainter& widget_painter, const PresentOption &opt);
public:
MapPresent(QWidget* parent = nullptr);
void zoomTo(double percent);
double zoomTimes() const;
/// <summary>
/// 通过widget上定位获取绘制索引
/// </summary>

View File

@ -38,7 +38,7 @@ void BasicUnitDelegate::paint(QPainter* p, const PresentOption& option)
ft.setPixelSize(alen * 0.3);
p->setFont(ft);
p->setPen(Qt::white);
p->setPen(Qt::black);
auto text_rect = QRectF(center.x() - xspan, center.y() - alen / 2, xspan * 2, alen);
auto text_str = QString("(%1,%2)").arg(option.index.row).arg(option.index.col);
p->drawText(text_rect, Qt::AlignCenter, text_str);
@ -69,14 +69,19 @@ QPainterPath BasicUnitDelegate::clipPathGet(const QRectF& rect)
void BasicUnitDelegate::hotClear()
{
auto prev_idx = _hot_index;
_hot_index = PresentIndex();
emit this->updateRequest(_hot_index);
emit this->updateRequest(prev_idx);
}
void BasicUnitDelegate::hotIndexSet(const PresentIndex& idx)
{
if (_hot_index != idx) {
auto prev_idx = _hot_index;
_hot_index = idx;
emit this->updateRequest(prev_idx);
emit this->updateRequest(idx);
}
}