1
0
Fork 0
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:
sfan5 2024-02-13 22:47:30 +01:00 committed by GitHub
parent d4b107e2e8
commit 3cac17d23e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
32 changed files with 1329 additions and 193 deletions

View file

@ -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