on bbbdccd help sign in
124 lines 3.6 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 operator bool() const { return item != nullptr; }
65 int index;
66 ItemType *item;
67 };
69 ItemType &getEmptySlot() {
70 Q_ASSERT(m_lastUsedIndex < m_slots.size());
72 // Look for an in-between vacancy first
73 for (int i = 0; i < m_lastUsedIndex; ++i) {
74 ItemType &item = m_slots[i];
75 if (!item.isValid()) {
76 return item;
77 }
78 }
80 ++m_lastUsedIndex;
81 if (m_lastUsedIndex >= m_slots.size()) {
82 m_slots.resize(m_lastUsedIndex + 1);
83 }
85 return m_slots[m_lastUsedIndex];
86 }
88 void freeSlot(Iterator &iterator) {
89 m_slots[iterator.index].reset();
90 if (iterator.index == m_lastUsedIndex) {
91 do {
92 --m_lastUsedIndex;
93 } while (m_lastUsedIndex >= 0 && !m_slots.at(m_lastUsedIndex).isValid());
94 }
95 }
97 // Iterates through all valid items (i.e. the occupied slots)
98 // calling the given function, with the option of ending the loop early.
99 //
100 // bool Func(Iterator& item)
101 //
102 // Returning true means it wants to continue the "for" loop, false
103 // terminates the loop.
104 template<typename Func> void forEach(Func func) {
105 Iterator it;
106 for (it.index = 0; it.index <= m_lastUsedIndex; ++it.index) {
107 it.item = &m_slots[it.index];
108 if (!it.item->isValid())
109 continue;
111 if (!func(it))
112 break;
113 }
114 }
116 bool isEmpty() const { return m_lastUsedIndex == -1; }
119private:
120 QVector<ItemType> m_slots;
121 int m_lastUsedIndex;
122};
124#endif // UBUNTUGESTURES_POOL_H