@@ -41,6 +41,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
41
41
#include " mapgen_v6.h"
42
42
43
43
44
+ // ///////////////////////////// Emerge Manager ////////////////////////////////
45
+
44
46
EmergeManager::EmergeManager (IGameDef *gamedef, BiomeDefManager *bdef) {
45
47
// register built-in mapgens
46
48
registerMapgen (" v6" , new MapgenFactoryV6 ());
@@ -166,33 +168,6 @@ bool EmergeManager::enqueueBlockEmerge(u16 peer_id, v3s16 p, bool allow_generate
166
168
}
167
169
168
170
169
- bool EmergeThread::popBlockEmerge (v3s16 *pos, u8 *flags) {
170
- std::map<v3s16, BlockEmergeData *>::iterator iter;
171
- JMutexAutoLock queuelock (emerge->queuemutex );
172
-
173
- if (blockqueue.empty ())
174
- return false ;
175
- v3s16 p = blockqueue.front ();
176
- blockqueue.pop ();
177
-
178
- *pos = p;
179
-
180
- iter = emerge->blocks_enqueued .find (p);
181
- if (iter == emerge->blocks_enqueued .end ())
182
- return false ; // uh oh, queue and map out of sync!!
183
-
184
- BlockEmergeData *bedata = iter->second ;
185
- *flags = bedata->flags ;
186
-
187
- emerge->peer_queue_count [bedata->peer_requested ]--;
188
-
189
- delete bedata;
190
- emerge->blocks_enqueued .erase (iter);
191
-
192
- return true ;
193
- }
194
-
195
-
196
171
int EmergeManager::getGroundLevelAtPoint (v2s16 p) {
197
172
if (mapgen.size () == 0 || !mapgen[0 ]) {
198
173
errorstream << " EmergeManager: getGroundLevelAtPoint() called"
@@ -290,59 +265,34 @@ bool EmergeManager::registerMapgen(std::string mgname, MapgenFactory *mgfactory)
290
265
}
291
266
292
267
268
+ // //////////////////////////// Emerge Thread //////////////////////////////////
293
269
294
- class MapEditEventIgnorer
295
- {
296
- public:
297
- MapEditEventIgnorer (bool *flag):
298
- m_flag (flag)
299
- {
300
- if (*m_flag == false )
301
- *m_flag = true ;
302
- else
303
- m_flag = NULL ;
304
- }
305
-
306
- ~MapEditEventIgnorer ()
307
- {
308
- if (m_flag)
309
- {
310
- assert (*m_flag);
311
- *m_flag = false ;
312
- }
313
- }
314
-
315
- private:
316
- bool *m_flag;
317
- };
318
-
319
- class MapEditEventAreaIgnorer
320
- {
321
- public:
322
- MapEditEventAreaIgnorer (VoxelArea *ignorevariable, const VoxelArea &a):
323
- m_ignorevariable (ignorevariable)
324
- {
325
- if (m_ignorevariable->getVolume () == 0 )
326
- *m_ignorevariable = a;
327
- else
328
- m_ignorevariable = NULL ;
329
- }
270
+ bool EmergeThread::popBlockEmerge (v3s16 *pos, u8 *flags) {
271
+ std::map<v3s16, BlockEmergeData *>::iterator iter;
272
+ JMutexAutoLock queuelock (emerge->queuemutex );
330
273
331
- ~MapEditEventAreaIgnorer ()
332
- {
333
- if (m_ignorevariable)
334
- {
335
- assert (m_ignorevariable->getVolume () != 0 );
336
- *m_ignorevariable = VoxelArea ();
337
- }
338
- }
274
+ if (blockqueue.empty ())
275
+ return false ;
276
+ v3s16 p = blockqueue.front ();
277
+ blockqueue.pop ();
278
+
279
+ *pos = p;
280
+
281
+ iter = emerge->blocks_enqueued .find (p);
282
+ if (iter == emerge->blocks_enqueued .end ())
283
+ return false ; // uh oh, queue and map out of sync!!
339
284
340
- private:
341
- VoxelArea *m_ignorevariable;
342
- };
285
+ BlockEmergeData *bedata = iter->second ;
286
+ *flags = bedata->flags ;
287
+
288
+ emerge->peer_queue_count [bedata->peer_requested ]--;
343
289
290
+ delete bedata;
291
+ emerge->blocks_enqueued .erase (iter);
292
+
293
+ return true ;
294
+ }
344
295
345
- #if 1
346
296
347
297
bool EmergeThread::getBlockOrStartGen (v3s16 p, MapBlock **b,
348
298
BlockMakeData *data, bool allow_gen) {
@@ -501,235 +451,3 @@ void *EmergeThread::Thread() {
501
451
log_deregister_thread ();
502
452
return NULL ;
503
453
}
504
-
505
- #else
506
-
507
- void *EmergeThread::Thread() {
508
- ThreadStarted();
509
- log_register_thread("EmergeThread");
510
- DSTACK(__FUNCTION_NAME);
511
- BEGIN_DEBUG_EXCEPTION_HANDLER
512
-
513
- bool enable_mapgen_debug_info = g_settings->getBool("enable_mapgen_debug_info");
514
-
515
- v3s16 last_tried_pos(-32768,-32768,-32768); // For error output
516
- ServerMap &map = ((ServerMap&)m_server->m_env->getMap());
517
- EmergeManager *emerge = m_server->m_emerge;
518
- Mapgen *mapgen = emerge->getMapgen();
519
-
520
- while(getRun())
521
- try {
522
- QueuedBlockEmerge *qptr = m_server->m_emerge_queue.pop();
523
- if(qptr == NULL)
524
- break;
525
- SharedPtr<QueuedBlockEmerge> q(qptr);
526
-
527
- v3s16 &p = q->pos;
528
- v2s16 p2d(p.X,p.Z);
529
-
530
- last_tried_pos = p;
531
-
532
- /*
533
- Do not generate over-limit
534
- */
535
- if (blockpos_over_limit(p))
536
- continue;
537
-
538
- //infostream<<"EmergeThread::Thread(): running"<<std::endl;
539
-
540
- //TimeTaker timer("block emerge");
541
-
542
- /*
543
- Try to emerge it from somewhere.
544
-
545
- If it is only wanted as optional, only loading from disk
546
- will be allowed.
547
- */
548
-
549
- /*
550
- Check if any peer wants it as non-optional. In that case it
551
- will be generated.
552
-
553
- Also decrement the emerge queue count in clients.
554
- */
555
-
556
- bool only_from_disk = true;
557
- {
558
- core::map<u16, u8>::Iterator i;
559
- for (i=q->s.getIterator(); !i.atEnd(); i++) {
560
- u8 flags = i.getNode()->getValue();
561
- if (!(flags & BLOCK_EMERGE_FLAG_FROMDISK)) {
562
- only_from_disk = false;
563
- break;
564
- }
565
- }
566
- }
567
-
568
- if (enable_mapgen_debug_info)
569
- infostream<<"EmergeThread: p="
570
- <<"("<<p.X<<","<<p.Y<<","<<p.Z<<") "
571
- <<"only_from_disk="<<only_from_disk<<std::endl;
572
-
573
- MapBlock *block = NULL;
574
- bool got_block = true;
575
- core::map<v3s16, MapBlock*> modified_blocks;
576
-
577
- /*
578
- Try to fetch block from memory or disk.
579
- If not found and asked to generate, initialize generator.
580
- */
581
-
582
- bool started_generate = false;
583
- BlockMakeData data;
584
- {
585
- JMutexAutoLock envlock(m_server->m_env_mutex);
586
-
587
- // Load sector if it isn't loaded
588
- if(map.getSectorNoGenerateNoEx(p2d) == NULL)
589
- map.loadSectorMeta(p2d);
590
-
591
- // Attempt to load block
592
- block = map.getBlockNoCreateNoEx(p);
593
- if(!block || block->isDummy() || !block->isGenerated()) {
594
- if(enable_mapgen_debug_info)
595
- infostream<<"EmergeThread: not in memory, "
596
- <<"attempting to load from disk"<<std::endl;
597
-
598
- block = map.loadBlock(p);
599
- }
600
-
601
- // If could not load and allowed to generate, start generation
602
- // inside this same envlock
603
- if(only_from_disk == false &&
604
- (block == NULL || block->isGenerated() == false)){
605
- if(enable_mapgen_debug_info)
606
- infostream<<"EmergeThread: generating"<<std::endl;
607
- started_generate = true;
608
-
609
- map.initBlockMake(&data, p);
610
- }
611
- }
612
-
613
- /*
614
- If generator was initialized, generate now when envlock is free.
615
- */
616
- if(started_generate) {
617
- {
618
- ScopeProfiler sp(g_profiler, "EmergeThread: mapgen::make_block",
619
- SPT_AVG);
620
- TimeTaker t("mapgen::make_block()");
621
-
622
- mapgen->makeChunk(&data);
623
-
624
- if (enable_mapgen_debug_info == false)
625
- t.stop(true); // Hide output
626
- }
627
-
628
- do{ // enable break
629
- // Lock environment again to access the map
630
- JMutexAutoLock envlock(m_server->m_env_mutex);
631
-
632
- ScopeProfiler sp(g_profiler, "EmergeThread: after "
633
- "mapgen::make_block (envlock)", SPT_AVG);
634
-
635
- // Blit data back on map, update lighting, add mobs and
636
- // whatever this does
637
- map.finishBlockMake(&data, modified_blocks);
638
-
639
- // Get central block
640
- block = map.getBlockNoCreateNoEx(p);
641
-
642
- // If block doesn't exist, don't try doing anything with it
643
- // This happens if the block is not in generation boundaries
644
- if(!block)
645
- break;
646
-
647
- /*
648
- Do some post-generate stuff
649
- */
650
- v3s16 minp = data.blockpos_min * MAP_BLOCKSIZE;
651
- v3s16 maxp = data.blockpos_max * MAP_BLOCKSIZE +
652
- v3s16(1,1,1) * (MAP_BLOCKSIZE - 1);
653
-
654
- /*
655
- Ignore map edit events, they will not need to be
656
- sent to anybody because the block hasn't been sent
657
- to anybody
658
- */
659
- MapEditEventAreaIgnorer ign(
660
- &m_server->m_ignore_map_edit_events_area,
661
- VoxelArea(minp, maxp));
662
- {
663
- TimeTaker timer("on_generated");
664
- scriptapi_environment_on_generated(m_server->m_lua,
665
- minp, maxp, emerge->getBlockSeed(minp));
666
- //int t = timer.stop(true);
667
- //dstream<<"on_generated took "<<t<<"ms"<<std::endl;
668
- }
669
-
670
- if (enable_mapgen_debug_info)
671
- infostream << "EmergeThread: ended up with: "
672
- << analyze_block(block) << std::endl;
673
-
674
- // Activate objects and stuff
675
- m_server->m_env->activateBlock(block, 0);
676
- }while(false);
677
- }
678
-
679
- if(block == NULL)
680
- got_block = false;
681
-
682
- /*
683
- Set sent status of modified blocks on clients
684
- */
685
-
686
- // NOTE: Server's clients are also behind the connection mutex
687
- JMutexAutoLock lock(m_server->m_con_mutex);
688
-
689
- /*
690
- Add the originally fetched block to the modified list
691
- */
692
- if(got_block)
693
- modified_blocks.insert(p, block);
694
-
695
- /*
696
- Set the modified blocks unsent for all the clients
697
- */
698
- for(core::map<u16, RemoteClient*>::Iterator
699
- i = m_server->m_clients.getIterator();
700
- i.atEnd() == false; i++) {
701
- RemoteClient *client = i.getNode()->getValue();
702
- if(modified_blocks.size() > 0) {
703
- // Remove block from sent history
704
- client->SetBlocksNotSent(modified_blocks);
705
- }
706
- }
707
-
708
-
709
- niters++;
710
- }
711
- catch (VersionMismatchException &e) {
712
- std::ostringstream err;
713
- err << "World data version mismatch in MapBlock "<<PP(last_tried_pos)<<std::endl;
714
- err << "----"<<std::endl;
715
- err << "\""<<e.what()<<"\""<<std::endl;
716
- err << "See debug.txt."<<std::endl;
717
- err << "World probably saved by a newer version of Minetest."<<std::endl;
718
- m_server->setAsyncFatalError(err.str());
719
- }
720
- catch (SerializationError &e) {
721
- std::ostringstream err;
722
- err << "Invalid data in MapBlock "<<PP(last_tried_pos)<<std::endl;
723
- err << "----"<<std::endl;
724
- err << "\""<<e.what()<<"\""<<std::endl;
725
- err << "See debug.txt."<<std::endl;
726
- err << "You can ignore this using [ignore_world_load_errors = true]."<<std::endl;
727
- m_server->setAsyncFatalError(err.str());
728
- }
729
- printf("emergethread iterated %d times\n", niters);
730
- END_DEBUG_EXCEPTION_HANDLER(errorstream)
731
- log_deregister_thread();
732
- return NULL;
733
- }
734
-
735
- #endif
0 commit comments