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 17 StarBlockFactory *StarBlockFactory::pInstance = nullptr; 18 Instance()19StarBlockFactory *StarBlockFactory::Instance() 20 { 21 if (!pInstance) 22 pInstance = new StarBlockFactory(); 23 return pInstance; 24 } 25 StarBlockFactory()26StarBlockFactory::StarBlockFactory() 27 { 28 first = nullptr; 29 last = nullptr; 30 nBlocks = 0; 31 drawID = 0; 32 nCache = DEFAULT_NCACHE; 33 } 34 ~StarBlockFactory()35StarBlockFactory::~StarBlockFactory() 36 { 37 deleteBlocks(nBlocks); 38 if (pInstance) 39 pInstance = nullptr; 40 } 41 getBlock()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 markFirst(std::shared_ptr<StarBlock> & block)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 markNext(std::shared_ptr<StarBlock> & after,std::shared_ptr<StarBlock> & block)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 /* 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 deleteBlocks(int nblocks)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 printStructure() const257void StarBlockFactory::printStructure() const 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 freeUnused()287int StarBlockFactory::freeUnused() 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 } 309