2
0

transform_cache.h 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. #pragma once
  2. #include <QMatrix4x4>
  3. #include <cstdint>
  4. #include <unordered_map>
  5. namespace Render {
  6. template <typename KeyType = std::uint64_t> class TransformCache {
  7. public:
  8. struct CachedTransform {
  9. QMatrix4x4 transform;
  10. std::uint32_t lastUpdateFrame{0};
  11. bool dirty{true};
  12. };
  13. void markDirty(KeyType key) {
  14. auto it = m_cache.find(key);
  15. if (it != m_cache.end()) {
  16. it->second.dirty = true;
  17. }
  18. }
  19. void markAllDirty() {
  20. for (auto &entry : m_cache) {
  21. entry.second.dirty = true;
  22. }
  23. }
  24. const QMatrix4x4 *get(KeyType key, std::uint32_t currentFrame) const {
  25. auto it = m_cache.find(key);
  26. if (it == m_cache.end() || it->second.dirty) {
  27. return nullptr;
  28. }
  29. if (currentFrame - it->second.lastUpdateFrame > m_maxFrameAge) {
  30. return nullptr;
  31. }
  32. return &it->second.transform;
  33. }
  34. void set(KeyType key, const QMatrix4x4 &transform,
  35. std::uint32_t currentFrame) {
  36. auto &entry = m_cache[key];
  37. entry.transform = transform;
  38. entry.lastUpdateFrame = currentFrame;
  39. entry.dirty = false;
  40. }
  41. void remove(KeyType key) { m_cache.erase(key); }
  42. void clear() { m_cache.clear(); }
  43. struct Stats {
  44. std::size_t totalEntries{0};
  45. std::size_t dirtyEntries{0};
  46. std::size_t validEntries{0};
  47. };
  48. Stats getStats() const {
  49. Stats stats;
  50. stats.totalEntries = m_cache.size();
  51. for (const auto &entry : m_cache) {
  52. if (entry.second.dirty) {
  53. ++stats.dirtyEntries;
  54. } else {
  55. ++stats.validEntries;
  56. }
  57. }
  58. return stats;
  59. }
  60. void setMaxFrameAge(std::uint32_t frames) { m_maxFrameAge = frames; }
  61. void cleanup(std::uint32_t currentFrame) {
  62. auto it = m_cache.begin();
  63. while (it != m_cache.end()) {
  64. if (currentFrame - it->second.lastUpdateFrame > m_maxFrameAge * 2) {
  65. it = m_cache.erase(it);
  66. } else {
  67. ++it;
  68. }
  69. }
  70. }
  71. private:
  72. std::unordered_map<KeyType, CachedTransform> m_cache;
  73. std::uint32_t m_maxFrameAge{300};
  74. };
  75. } // namespace Render