on 436b607 help sign in
132 lines 3.8 kB history raw
1/*
2 * Copyright (C) 2014 Canonical, Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
17#ifndef UBUNTUGESTURES_POOL_H
18#define UBUNTUGESTURES_POOL_H
20#include <QVector>
22#include "UbuntuGesturesGlobal.h"
24/*
25 An object pool.
26 Avoids unnecessary creations/initializations and deletions/destructions of items. Useful
27 in a scenario where items are created and destroyed very frequently but the total number
28 of items at any given time remains small. They're stored in a unordered fashion.
30 To be used in Pool, ItemType needs to have the following methods:
32 - ItemType();
34 A constructor that takes no parameters. An object contructed with it must return false if
35 isValid() is called.
37 - bool isValid() const;
39 Returns wheter the object holds a valid , "filled" state or is empty.
40 Used by Pool to check if the slot occupied by this object is actually available.
42 - void reset();
44 Resets the object to its initial, empty, state. After calling this method, isValid() must
45 return false.
46 */
47template <class ItemType> class Pool
49public:
50 Pool() : m_lastUsedIndex(-1) {
51 }
53 class Iterator {
54 public:
55 Iterator() : index(-1), item(nullptr) {}
56 Iterator(int index, ItemType *item)
57 : index(index), item(item) {}
59 ItemType *operator->() const { return item; }
60 ItemType &operator*() const { return *item; }
61 ItemType &value() const { return *item; }
63 Iterator &operator= (const Iterator& other) {
64 index = other.index;
65 item = other.item;
67 // by convention, always return *this
68 return *this;
69 }
71 operator bool() const { return item != nullptr; }
73 int index;
74 ItemType *item;
75 };
77 ItemType &getEmptySlot() {
78 Q_ASSERT(m_lastUsedIndex < m_slots.size());
80 // Look for an in-between vacancy first
81 for (int i = 0; i < m_lastUsedIndex; ++i) {
82 ItemType &item = m_slots[i];
83 if (!item.isValid()) {
84 return item;
85 }
86 }
88 ++m_lastUsedIndex;
89 if (m_lastUsedIndex >= m_slots.size()) {
90 m_slots.resize(m_lastUsedIndex + 1);
91 }
93 return m_slots[m_lastUsedIndex];
94 }
96 void freeSlot(Iterator &iterator) {
97 m_slots[iterator.index].reset();
98 if (iterator.index == m_lastUsedIndex) {
99 do {
100 --m_lastUsedIndex;
101 } while (m_lastUsedIndex >= 0 && !m_slots.at(m_lastUsedIndex).isValid());
102 }
103 }
105 // Iterates through all valid items (i.e. the occupied slots)
106 // calling the given function, with the option of ending the loop early.
107 //
108 // bool Func(Iterator& item)
109 //
110 // Returning true means it wants to continue the "for" loop, false
111 // terminates the loop.
112 template<typename Func> void forEach(Func func) {
113 Iterator it;
114 for (it.index = 0; it.index <= m_lastUsedIndex; ++it.index) {
115 it.item = &m_slots[it.index];
116 if (!it.item->isValid())
117 continue;
119 if (!func(it))
120 break;
121 }
122 }
124 bool isEmpty() const { return m_lastUsedIndex == -1; }
127private:
128 QVector<ItemType> m_slots;
129 int m_lastUsedIndex;
130};
132#endif // UBUNTUGESTURES_POOL_H