Kstars

starblockfactory.cpp
1/*
2 SPDX-FileCopyrightText: 2008 Akarsh Simha <akarshsimha@gmail.com>
3
4 SPDX-License-Identifier: GPL-2.0-or-later
5*/
6
7#include "starblockfactory.h"
8
9#include "starblock.h"
10#include "starobject.h"
11
12#include <kstars_debug.h>
13
14// TODO: Implement a better way of deciding this
15#define DEFAULT_NCACHE 12
16
17StarBlockFactory *StarBlockFactory::pInstance = nullptr;
18
19StarBlockFactory *StarBlockFactory::Instance()
20{
21 if (!pInstance)
22 pInstance = new StarBlockFactory();
23 return pInstance;
24}
25
26StarBlockFactory::StarBlockFactory()
27{
28 first = nullptr;
29 last = nullptr;
30 nBlocks = 0;
31 drawID = 0;
32 nCache = DEFAULT_NCACHE;
33}
34
36{
37 deleteBlocks(nBlocks);
38 if (pInstance)
39 pInstance = nullptr;
40}
41
42std::shared_ptr<StarBlock> StarBlockFactory::getBlock()
43{
44 std::shared_ptr<StarBlock> freeBlock;
45
46 if (nBlocks < nCache)
47 {
48 freeBlock.reset(new StarBlock);
49 if (freeBlock.get())
50 {
51 ++nBlocks;
52 return freeBlock;
53 }
54 }
55 if (last && (last->drawID != drawID || last->drawID == 0))
56 {
57 // qCDebug(KSTARS) << "Recycling block with drawID =" << last->drawID << "and current drawID =" << drawID;
58 if (last->parent->block(last->parent->getBlockCount() - 1) != last)
59 qCDebug(KSTARS) << "ERROR: Goof up here!";
60 freeBlock = last;
61 last = last->prev;
62 if (last)
63 {
64 last->next = nullptr;
65 }
66 if (freeBlock == first)
67 {
68 first = nullptr;
69 }
70 freeBlock->reset();
71 freeBlock->prev = nullptr;
72 freeBlock->next = nullptr;
73 return freeBlock;
74 }
75 freeBlock.reset(new StarBlock);
76 if (freeBlock.get())
77 ++nBlocks;
78
79 return freeBlock;
80}
81
82bool StarBlockFactory::markFirst(std::shared_ptr<StarBlock>& block)
83{
84 if (!block.get())
85 return false;
86
87 // fprintf(stderr, "markFirst()!\n");
88 if (!first)
89 {
90 // qCDebug(KSTARS) << "INFO: Linking in first block";
91 last = first = block;
92 first->prev = first->next = nullptr;
93 first->drawID = drawID;
94 return true;
95 }
96
97 if (block == first) // Block is already in the front
98 {
99 block->drawID = drawID;
100 return true;
101 }
102
103 if (block == last)
104 last = block->prev;
105
106 if (block->prev)
107 block->prev->next = block->next;
108
109 if (block->next)
110 block->next->prev = block->prev;
111
112 first->prev = block;
113 block->next = first;
114 block->prev = nullptr;
115 first = block;
116
117 block->drawID = drawID;
118
119 return true;
120}
121
122bool StarBlockFactory::markNext(std::shared_ptr<StarBlock>& after, std::shared_ptr<StarBlock>& block)
123{
124 // fprintf(stderr, "markNext()!\n");
125 if (!block.get() || !after.get())
126 {
127 qCDebug(KSTARS) << "WARNING: markNext called with nullptr argument";
128 return false;
129 }
130
131 if (!first.get())
132 {
133 qCDebug(KSTARS) << "WARNING: markNext called without an existing linked list";
134 return false;
135 }
136
137 if (block == after)
138 {
139 qCDebug(KSTARS) << "ERROR: Trying to mark a block after itself!";
140 return false;
141 }
142
143 if (block->prev == after) // Block is already after 'after'
144 {
145 block->drawID = drawID;
146 return true;
147 }
148
149 if (block == first)
150 {
151 if (block->next == nullptr)
152 {
153 qCDebug(KSTARS) << "ERROR: Trying to mark only block after some other block";
154 return false;
155 }
156 first = block->next;
157 }
158
159 if (after->getFaintMag() > block->getFaintMag() && block->getFaintMag() != -5)
160 {
161 qCDebug(KSTARS) << "WARNING: Marking block with faint mag = " << block->getFaintMag() << " after block with faint mag "
162 << after->getFaintMag() << "in trixel" << block->parent->getTrixel();
163 }
164
165 if (block == last)
166 last = block->prev;
167
168 if (block->prev)
169 block->prev->next = block->next;
170 if (block->next)
171 block->next->prev = block->prev;
172
173 block->next = after->next;
174 if (block->next)
175 block->next->prev = block;
176 block->prev = after;
177 after->next = block;
178
179 if (after == last)
180 last = block;
181
182 block->drawID = drawID;
183
184 return true;
185}
186
187/*
188bool StarBlockFactory::groupMove( StarBlock *start, const int nblocks ) {
189
190 StarBlock * end = nullptr;
191
192 // Check for trivial cases
193 if( !start || nblocks < 0 )
194 return false;
195
196 if( nblocks == 0 )
197 return true;
198
199 if( !first )
200 return false;
201
202 // Check for premature end
203 end = start;
204 for( int i = 1; i < nblocks; ++i ) {
205 if( end == nullptr )
206 return false;
207 end = end->next;
208 }
209 if( end == nullptr )
210 return false;
211
212 // Update drawIDs
213 end = start;
214 for( int i = 1; i < nblocks; ++i ) {
215 end->drawID = drawID;
216 end = end->next;
217 }
218 end->drawID = drawID;
219
220 // Check if we are already in the front
221 if( !start->prev )
222 return true;
223
224 start->prev->next = end->next;
225 end->next->prev = start->prev;
226
227 first->prev = end;
228 end->next = first;
229 start->prev = nullptr;
230 first = start;
231}
232*/
233
234int StarBlockFactory::deleteBlocks(int nblocks)
235{
236 int i = 0;
237 std::shared_ptr<StarBlock> temp;
238
239 while (last != nullptr && i != nblocks)
240 {
241 temp = last->prev;
242 last.reset();
243 last = temp;
244 i++;
245 }
246 if (last)
247 last->next = nullptr;
248 else
249 first = nullptr;
250
251 qCDebug(KSTARS) << nblocks << "StarBlocks freed from StarBlockFactory";
252
253 nBlocks -= i;
254 return i;
255}
256
258{
259 std::shared_ptr<StarBlock> cur;
260 Trixel curTrixel = 513; // TODO: Change if we change HTMesh level
261 int index = 0;
262 bool draw = false;
263
264 cur = first;
265 do
266 {
267 if (curTrixel != cur->parent->getTrixel())
268 {
269 qCDebug(KSTARS) << "Trixel" << cur->parent->getTrixel() << "starts at index" << index;
270 curTrixel = cur->parent->getTrixel();
271 }
272 if (cur->drawID == drawID && !draw)
273 {
274 qCDebug(KSTARS) << "Blocks from index" << index << "are drawn";
275 draw = true;
276 }
277 if (cur->drawID != drawID && draw)
278 {
279 qCDebug(KSTARS) << "Blocks from index" << index << "are not drawn";
280 draw = false;
281 }
282 cur = cur->next;
283 ++index;
284 } while (cur != last);
285}
286
288{
289 int i = 0;
290 std::shared_ptr<StarBlock> temp;
291
292 while (last != nullptr && last->drawID < drawID && i != nBlocks)
293 {
294 temp = last->prev;
295 last.reset();
296 last = temp;
297 i++;
298 }
299 if (last)
300 last->next = nullptr;
301 else
302 first = nullptr;
303
304 qCDebug(KSTARS) << i << "StarBlocks freed from StarBlockFactory";
305
306 nBlocks -= i;
307 return i;
308}
A factory that creates StarBlocks and recycles them in an LRU Cache.
~StarBlockFactory()
Destructor Deletes the linked list that maintains the Cache, sets the pointer to nullptr.
bool markNext(std::shared_ptr< StarBlock > &after, std::shared_ptr< StarBlock > &block)
Rank a given StarBlock after another given StarBlock in the LRU list and sync its drawID with the cur...
int freeUnused()
Frees all StarBlocks that are not used in this draw cycle.
std::shared_ptr< StarBlock > getBlock()
Return a StarBlock available for use.
void printStructure() const
Prints the structure of the cache, for debugging.
bool markFirst(std::shared_ptr< StarBlock > &block)
Mark a StarBlock as most recently used and sync its drawID with the current drawID.
Holds a block of stars and various peripheral variables to mark its place in data structures.
Definition starblock.h:43
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:19:04 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.