Kstars

starblockfactory.cpp
1 /*
2  SPDX-FileCopyrightText: 2008 Akarsh Simha <[email protected]>
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 
17 StarBlockFactory *StarBlockFactory::pInstance = nullptr;
18 
19 StarBlockFactory *StarBlockFactory::Instance()
20 {
21  if (!pInstance)
22  pInstance = new StarBlockFactory();
23  return pInstance;
24 }
25 
26 StarBlockFactory::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 
42 std::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 
82 bool 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 
122 bool 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 /*
188 bool 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 
234 int 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 }
bool markFirst(std::shared_ptr< StarBlock > &block)
Mark a StarBlock as most recently used and sync its drawID with the current drawID.
std::shared_ptr< StarBlock > getBlock()
Return a StarBlock available for use.
void printStructure() const
Prints the structure of the cache, for debugging.
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.
~StarBlockFactory()
Destructor Deletes the linked list that maintains the Cache, sets the pointer to nullptr.
A factory that creates StarBlocks and recycles them in an LRU Cache.
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Mon May 8 2023 03:57:35 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.