mirror of
https://github.com/luanti-org/luanti.git
synced 2025-06-27 16:36:03 +00:00
Lua on each mapgen thread (#13092)
This commit is contained in:
parent
d4b107e2e8
commit
3cac17d23e
32 changed files with 1329 additions and 193 deletions
150
src/emerge.cpp
150
src/emerge.cpp
|
@ -19,19 +19,16 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
*/
|
||||
|
||||
|
||||
#include "emerge.h"
|
||||
#include "emerge_internal.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <queue>
|
||||
|
||||
#include "util/container.h"
|
||||
#include "util/thread.h"
|
||||
#include "threading/event.h"
|
||||
|
||||
#include "config.h"
|
||||
#include "constants.h"
|
||||
#include "environment.h"
|
||||
#include "irrlicht_changes/printing.h"
|
||||
#include "filesys.h"
|
||||
#include "log.h"
|
||||
#include "map.h"
|
||||
#include "mapblock.h"
|
||||
|
@ -42,76 +39,11 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
#include "nodedef.h"
|
||||
#include "profiler.h"
|
||||
#include "scripting_server.h"
|
||||
#include "scripting_emerge.h"
|
||||
#include "server.h"
|
||||
#include "settings.h"
|
||||
#include "voxel.h"
|
||||
|
||||
class EmergeThread : public Thread {
|
||||
public:
|
||||
bool enable_mapgen_debug_info;
|
||||
int id;
|
||||
|
||||
EmergeThread(Server *server, int ethreadid);
|
||||
~EmergeThread() = default;
|
||||
|
||||
void *run();
|
||||
void signal();
|
||||
|
||||
// Requires queue mutex held
|
||||
bool pushBlock(const v3s16 &pos);
|
||||
|
||||
void cancelPendingItems();
|
||||
|
||||
protected:
|
||||
|
||||
void runCompletionCallbacks(
|
||||
const v3s16 &pos, EmergeAction action,
|
||||
const EmergeCallbackList &callbacks);
|
||||
|
||||
private:
|
||||
Server *m_server;
|
||||
ServerMap *m_map;
|
||||
EmergeManager *m_emerge;
|
||||
Mapgen *m_mapgen;
|
||||
|
||||
Event m_queue_event;
|
||||
std::queue<v3s16> m_block_queue;
|
||||
|
||||
bool popBlockEmerge(v3s16 *pos, BlockEmergeData *bedata);
|
||||
|
||||
EmergeAction getBlockOrStartGen(
|
||||
const v3s16 &pos, bool allow_gen, MapBlock **block, BlockMakeData *data);
|
||||
MapBlock *finishGen(v3s16 pos, BlockMakeData *bmdata,
|
||||
std::map<v3s16, MapBlock *> *modified_blocks);
|
||||
|
||||
friend class EmergeManager;
|
||||
};
|
||||
|
||||
class MapEditEventAreaIgnorer
|
||||
{
|
||||
public:
|
||||
MapEditEventAreaIgnorer(VoxelArea *ignorevariable, const VoxelArea &a):
|
||||
m_ignorevariable(ignorevariable)
|
||||
{
|
||||
if(m_ignorevariable->getVolume() == 0)
|
||||
*m_ignorevariable = a;
|
||||
else
|
||||
m_ignorevariable = NULL;
|
||||
}
|
||||
|
||||
~MapEditEventAreaIgnorer()
|
||||
{
|
||||
if(m_ignorevariable)
|
||||
{
|
||||
assert(m_ignorevariable->getVolume() != 0);
|
||||
*m_ignorevariable = VoxelArea();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
VoxelArea *m_ignorevariable;
|
||||
};
|
||||
|
||||
EmergeParams::~EmergeParams()
|
||||
{
|
||||
infostream << "EmergeParams: destroying " << this << std::endl;
|
||||
|
@ -131,6 +63,7 @@ EmergeParams::EmergeParams(EmergeManager *parent, const BiomeGen *biomegen,
|
|||
enable_mapgen_debug_info(parent->enable_mapgen_debug_info),
|
||||
gen_notify_on(parent->gen_notify_on),
|
||||
gen_notify_on_deco_ids(&parent->gen_notify_on_deco_ids),
|
||||
gen_notify_on_custom(&parent->gen_notify_on_custom),
|
||||
biomemgr(biomemgr->clone()), oremgr(oremgr->clone()),
|
||||
decomgr(decomgr->clone()), schemmgr(schemmgr->clone())
|
||||
{
|
||||
|
@ -518,9 +451,10 @@ EmergeThread::EmergeThread(Server *server, int ethreadid) :
|
|||
enable_mapgen_debug_info(false),
|
||||
id(ethreadid),
|
||||
m_server(server),
|
||||
m_map(NULL),
|
||||
m_emerge(NULL),
|
||||
m_mapgen(NULL)
|
||||
m_map(nullptr),
|
||||
m_emerge(nullptr),
|
||||
m_mapgen(nullptr),
|
||||
m_trans_liquid(nullptr)
|
||||
{
|
||||
m_name = "Emerge-" + itos(ethreadid);
|
||||
}
|
||||
|
@ -641,13 +575,13 @@ MapBlock *EmergeThread::finishGen(v3s16 pos, BlockMakeData *bmdata,
|
|||
v3s16(1,1,1) * (MAP_BLOCKSIZE - 1);
|
||||
|
||||
// Ignore map edit events, they will not need to be sent
|
||||
// to anybody because the block hasn't been sent to anybody
|
||||
// to anyone because the block hasn't been sent yet.
|
||||
MapEditEventAreaIgnorer ign(
|
||||
&m_server->m_ignore_map_edit_events_area,
|
||||
VoxelArea(minp, maxp));
|
||||
|
||||
/*
|
||||
Run Lua on_generated callbacks
|
||||
Run Lua on_generated callbacks in the server environment
|
||||
*/
|
||||
try {
|
||||
m_server->getScriptIface()->environment_OnGenerated(
|
||||
|
@ -674,6 +608,36 @@ MapBlock *EmergeThread::finishGen(v3s16 pos, BlockMakeData *bmdata,
|
|||
}
|
||||
|
||||
|
||||
bool EmergeThread::initScripting()
|
||||
{
|
||||
m_script = std::make_unique<EmergeScripting>(this);
|
||||
|
||||
try {
|
||||
m_script->loadMod(Server::getBuiltinLuaPath() + DIR_DELIM + "init.lua",
|
||||
BUILTIN_MOD_NAME);
|
||||
m_script->checkSetByBuiltin();
|
||||
} catch (const ModError &e) {
|
||||
errorstream << "Execution of mapgen base environment failed." << std::endl;
|
||||
m_server->setAsyncFatalError(e.what());
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto &list = m_server->m_mapgen_init_files;
|
||||
try {
|
||||
for (auto &it : list)
|
||||
m_script->loadMod(it.second, it.first);
|
||||
|
||||
m_script->on_mods_loaded();
|
||||
} catch (const ModError &e) {
|
||||
errorstream << "Failed to load mod script inside mapgen environment." << std::endl;
|
||||
m_server->setAsyncFatalError(e.what());
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void *EmergeThread::run()
|
||||
{
|
||||
BEGIN_DEBUG_EXCEPTION_HANDLER
|
||||
|
@ -686,6 +650,11 @@ void *EmergeThread::run()
|
|||
m_mapgen = m_emerge->m_mapgens[id];
|
||||
enable_mapgen_debug_info = m_emerge->enable_mapgen_debug_info;
|
||||
|
||||
if (!initScripting()) {
|
||||
m_script.reset();
|
||||
stop(); // do not enter main loop
|
||||
}
|
||||
|
||||
try {
|
||||
while (!stopRequested()) {
|
||||
BlockEmergeData bedata;
|
||||
|
@ -706,6 +675,9 @@ void *EmergeThread::run()
|
|||
|
||||
action = getBlockOrStartGen(pos, allow_gen, &block, &bmdata);
|
||||
if (action == EMERGE_GENERATED) {
|
||||
bool error = false;
|
||||
m_trans_liquid = &bmdata.transforming_liquid;
|
||||
|
||||
{
|
||||
ScopeProfiler sp(g_profiler,
|
||||
"EmergeThread: Mapgen::makeChunk", SPT_AVG);
|
||||
|
@ -713,9 +685,24 @@ void *EmergeThread::run()
|
|||
m_mapgen->makeChunk(&bmdata);
|
||||
}
|
||||
|
||||
block = finishGen(pos, &bmdata, &modified_blocks);
|
||||
if (!block)
|
||||
{
|
||||
ScopeProfiler sp(g_profiler,
|
||||
"EmergeThread: Lua on_generated", SPT_AVG);
|
||||
|
||||
try {
|
||||
m_script->on_generated(&bmdata);
|
||||
} catch (const LuaError &e) {
|
||||
m_server->setAsyncFatalError(e);
|
||||
error = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!error)
|
||||
block = finishGen(pos, &bmdata, &modified_blocks);
|
||||
if (!block || error)
|
||||
action = EMERGE_ERRORED;
|
||||
|
||||
m_trans_liquid = nullptr;
|
||||
}
|
||||
|
||||
runCompletionCallbacks(pos, action, bedata.callbacks);
|
||||
|
@ -752,6 +739,13 @@ void *EmergeThread::run()
|
|||
m_server->setAsyncFatalError(err.str());
|
||||
}
|
||||
|
||||
try {
|
||||
if (m_script)
|
||||
m_script->on_shutdown();
|
||||
} catch (const ModError &e) {
|
||||
m_server->setAsyncFatalError(e.what());
|
||||
}
|
||||
|
||||
cancelPendingItems();
|
||||
|
||||
END_DEBUG_EXCEPTION_HANDLER
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue