mirror of
https://github.com/minetest/minetest.git
synced 2024-07-04 15:05:27 +02:00
Merge branch 'master' of https://github.com/minetest/minetest
This commit is contained in:
commit
94a48e9672
@ -2190,9 +2190,6 @@ curl_file_download_timeout (cURL file download timeout) int 300000 5000 21474836
|
||||
|
||||
[**Miscellaneous]
|
||||
|
||||
# Adjust dpi configuration to your screen (non X11/Android only) e.g. for 4k screens.
|
||||
screen_dpi (DPI) int 72 1
|
||||
|
||||
# Adjust the detected display density, used for scaling UI elements.
|
||||
display_density_factor (Display Density Scaling Factor) float 1 0.5 5.0
|
||||
|
||||
|
@ -5720,6 +5720,8 @@ Call these functions only at load time!
|
||||
aliases handled.
|
||||
* `minetest.register_on_shutdown(function())`
|
||||
* Called before server shutdown
|
||||
* Players that were kicked by the shutdown procedure are still fully accessible
|
||||
in `minetest.get_connected_players()`.
|
||||
* **Warning**: If the server terminates abnormally (i.e. crashes), the
|
||||
registered callbacks **will likely not be run**. Data should be saved at
|
||||
semi-frequent intervals as well as on server shutdown.
|
||||
|
@ -186,6 +186,7 @@ dofile(modpath .. "/metadata.lua")
|
||||
dofile(modpath .. "/raycast.lua")
|
||||
dofile(modpath .. "/inventory.lua")
|
||||
dofile(modpath .. "/load_time.lua")
|
||||
dofile(modpath .. "/on_shutdown.lua")
|
||||
|
||||
--------------
|
||||
|
||||
|
22
games/devtest/mods/unittests/on_shutdown.lua
Normal file
22
games/devtest/mods/unittests/on_shutdown.lua
Normal file
@ -0,0 +1,22 @@
|
||||
-- Test whether players still exist on shutdown
|
||||
local players = {}
|
||||
|
||||
core.register_on_joinplayer(function(player)
|
||||
players[player:get_player_name()] = true
|
||||
end)
|
||||
|
||||
core.register_on_leaveplayer(function(player)
|
||||
local name = player:get_player_name();
|
||||
assert(players[name], "Unrecorded player join.")
|
||||
players[name] = nil
|
||||
end)
|
||||
|
||||
core.register_on_shutdown(function()
|
||||
for _, player in pairs(core.get_connected_players()) do
|
||||
local name = player:get_player_name()
|
||||
assert(players[name], "Unrecorded player join or left too early.")
|
||||
players[name] = nil
|
||||
end
|
||||
|
||||
assert(not next(players), "Invalid connected players on shutdown.")
|
||||
end)
|
@ -205,6 +205,9 @@ enum EAPPLICATION_EVENT_TYPE
|
||||
//! The application received a memory warning.
|
||||
EAET_MEMORY_WARNING,
|
||||
|
||||
//! The display density changed (only works on SDL).
|
||||
EAET_DPI_CHANGED,
|
||||
|
||||
//! No real event, but to get number of event types.
|
||||
EAET_COUNT
|
||||
};
|
||||
|
@ -285,6 +285,11 @@ CIrrDeviceSDL::CIrrDeviceSDL(const SIrrlichtCreationParameters ¶m) :
|
||||
SDL_SetHint(SDL_HINT_TV_REMOTE_AS_JOYSTICK, "0");
|
||||
#endif
|
||||
|
||||
#if SDL_VERSION_ATLEAST(2, 24, 0)
|
||||
// highdpi support on Windows
|
||||
SDL_SetHint(SDL_HINT_WINDOWS_DPI_SCALING, "1");
|
||||
#endif
|
||||
|
||||
// Minetest has its own code to synthesize mouse events from touch events,
|
||||
// so we prevent SDL from doing it.
|
||||
SDL_SetHint(SDL_HINT_TOUCH_MOUSE_EVENTS, "0");
|
||||
@ -475,6 +480,7 @@ bool CIrrDeviceSDL::createWindow()
|
||||
bool CIrrDeviceSDL::createWindowWithContext()
|
||||
{
|
||||
u32 SDL_Flags = 0;
|
||||
SDL_Flags |= SDL_WINDOW_ALLOW_HIGHDPI;
|
||||
|
||||
SDL_Flags |= getFullscreenFlag(CreationParams.Fullscreen);
|
||||
if (Resizable)
|
||||
@ -589,13 +595,16 @@ bool CIrrDeviceSDL::createWindowWithContext()
|
||||
return false;
|
||||
}
|
||||
|
||||
// Update Width and Height to match the actual window size.
|
||||
// In fullscreen mode, the window size specified in SIrrlichtCreationParameters
|
||||
// is ignored, so we cannot rely on it.
|
||||
int w = 0, h = 0;
|
||||
SDL_GetWindowSize(Window, &w, &h);
|
||||
Width = w;
|
||||
Height = h;
|
||||
updateSizeAndScale();
|
||||
if (ScaleX != 1.0f || ScaleY != 1.0f) {
|
||||
// The given window size is in pixels, not in screen coordinates.
|
||||
// We can only do the conversion now since we didn't know the scale before.
|
||||
SDL_SetWindowSize(Window, CreationParams.WindowSize.Width / ScaleX,
|
||||
CreationParams.WindowSize.Height / ScaleY);
|
||||
// Re-center, otherwise large, non-maximized windows go offscreen.
|
||||
SDL_SetWindowPosition(Window, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);
|
||||
updateSizeAndScale();
|
||||
}
|
||||
|
||||
return true;
|
||||
#endif // !_IRR_EMSCRIPTEN_PLATFORM_
|
||||
@ -659,10 +668,10 @@ bool CIrrDeviceSDL::run()
|
||||
|
||||
irrevent.EventType = irr::EET_MOUSE_INPUT_EVENT;
|
||||
irrevent.MouseInput.Event = irr::EMIE_MOUSE_MOVED;
|
||||
MouseX = irrevent.MouseInput.X = SDL_event.motion.x;
|
||||
MouseY = irrevent.MouseInput.Y = SDL_event.motion.y;
|
||||
MouseXRel = SDL_event.motion.xrel;
|
||||
MouseYRel = SDL_event.motion.yrel;
|
||||
MouseX = irrevent.MouseInput.X = SDL_event.motion.x * ScaleX;
|
||||
MouseY = irrevent.MouseInput.Y = SDL_event.motion.y * ScaleY;
|
||||
MouseXRel = SDL_event.motion.xrel * ScaleX;
|
||||
MouseYRel = SDL_event.motion.yrel * ScaleY;
|
||||
irrevent.MouseInput.ButtonStates = MouseButtonStates;
|
||||
irrevent.MouseInput.Shift = (keymod & KMOD_SHIFT) != 0;
|
||||
irrevent.MouseInput.Control = (keymod & KMOD_CTRL) != 0;
|
||||
@ -694,8 +703,8 @@ bool CIrrDeviceSDL::run()
|
||||
SDL_Keymod keymod = SDL_GetModState();
|
||||
|
||||
irrevent.EventType = irr::EET_MOUSE_INPUT_EVENT;
|
||||
irrevent.MouseInput.X = SDL_event.button.x;
|
||||
irrevent.MouseInput.Y = SDL_event.button.y;
|
||||
irrevent.MouseInput.X = SDL_event.button.x * ScaleX;
|
||||
irrevent.MouseInput.Y = SDL_event.button.y * ScaleY;
|
||||
irrevent.MouseInput.Shift = (keymod & KMOD_SHIFT) != 0;
|
||||
irrevent.MouseInput.Control = (keymod & KMOD_CTRL) != 0;
|
||||
|
||||
@ -827,14 +836,25 @@ bool CIrrDeviceSDL::run()
|
||||
case SDL_WINDOWEVENT:
|
||||
switch (SDL_event.window.event) {
|
||||
case SDL_WINDOWEVENT_RESIZED:
|
||||
if ((SDL_event.window.data1 != (int)Width) || (SDL_event.window.data2 != (int)Height)) {
|
||||
Width = SDL_event.window.data1;
|
||||
Height = SDL_event.window.data2;
|
||||
case SDL_WINDOWEVENT_SIZE_CHANGED:
|
||||
#if SDL_VERSION_ATLEAST(2, 0, 18)
|
||||
case SDL_WINDOWEVENT_DISPLAY_CHANGED:
|
||||
#endif
|
||||
u32 old_w = Width, old_h = Height;
|
||||
f32 old_scale_x = ScaleX, old_scale_y = ScaleY;
|
||||
updateSizeAndScale();
|
||||
if (old_w != Width || old_h != Height) {
|
||||
if (VideoDriver)
|
||||
VideoDriver->OnResize(core::dimension2d<u32>(Width, Height));
|
||||
}
|
||||
if (old_scale_x != ScaleX || old_scale_y != ScaleY) {
|
||||
irrevent.EventType = EET_APPLICATION_EVENT;
|
||||
irrevent.ApplicationEvent.EventType = EAET_DPI_CHANGED;
|
||||
postEventFromUser(irrevent);
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case SDL_USEREVENT:
|
||||
irrevent.EventType = irr::EET_USER_EVENT;
|
||||
@ -1030,25 +1050,26 @@ bool CIrrDeviceSDL::activateJoysticks(core::array<SJoystickInfo> &joystickInfo)
|
||||
return false;
|
||||
}
|
||||
|
||||
void CIrrDeviceSDL::updateSizeAndScale()
|
||||
{
|
||||
int window_w, window_h;
|
||||
SDL_GetWindowSize(Window, &window_w, &window_h);
|
||||
|
||||
int drawable_w, drawable_h;
|
||||
SDL_GL_GetDrawableSize(Window, &drawable_w, &drawable_h);
|
||||
|
||||
ScaleX = (float)drawable_w / (float)window_w;
|
||||
ScaleY = (float)drawable_h / (float)window_h;
|
||||
|
||||
Width = drawable_w;
|
||||
Height = drawable_h;
|
||||
}
|
||||
|
||||
//! Get the display density in dots per inch.
|
||||
float CIrrDeviceSDL::getDisplayDensity() const
|
||||
{
|
||||
if (!Window)
|
||||
return 0.0f;
|
||||
|
||||
int window_w;
|
||||
int window_h;
|
||||
SDL_GetWindowSize(Window, &window_w, &window_h);
|
||||
|
||||
int drawable_w;
|
||||
int drawable_h;
|
||||
SDL_GL_GetDrawableSize(Window, &drawable_w, &drawable_h);
|
||||
|
||||
// assume 96 dpi
|
||||
float dpi_w = (float)drawable_w / (float)window_w * 96.0f;
|
||||
float dpi_h = (float)drawable_h / (float)window_h * 96.0f;
|
||||
|
||||
return std::max(dpi_w, dpi_h);
|
||||
return std::max(ScaleX * 96.0f, ScaleY * 96.0f);
|
||||
}
|
||||
|
||||
void CIrrDeviceSDL::SwapWindow()
|
||||
|
@ -158,7 +158,8 @@ class CIrrDeviceSDL : public CIrrDeviceStub
|
||||
//! Sets the new position of the cursor.
|
||||
void setPosition(s32 x, s32 y) override
|
||||
{
|
||||
SDL_WarpMouseInWindow(Device->Window, x, y);
|
||||
SDL_WarpMouseInWindow(Device->Window,
|
||||
x / Device->ScaleX, y / Device->ScaleY);
|
||||
|
||||
if (SDL_GetRelativeMouseMode()) {
|
||||
// There won't be an event for this warp (details on libsdl-org/SDL/issues/6034)
|
||||
@ -300,6 +301,8 @@ class CIrrDeviceSDL : public CIrrDeviceStub
|
||||
u32 MouseButtonStates;
|
||||
|
||||
u32 Width, Height;
|
||||
f32 ScaleX = 1.0f, ScaleY = 1.0f;
|
||||
void updateSizeAndScale();
|
||||
|
||||
bool Resizable;
|
||||
|
||||
|
@ -1,3 +1,5 @@
|
||||
# When enabling SDL2 by default on macOS, don't forget to change
|
||||
# "NSHighResolutionCapable" to true in "Info.plist".
|
||||
if(NOT APPLE)
|
||||
set(DEFAULT_SDL2 ON)
|
||||
endif()
|
||||
|
@ -10,7 +10,9 @@
|
||||
</trustInfo>
|
||||
<application xmlns="urn:schemas-microsoft-com:asm.v3">
|
||||
<windowsSettings>
|
||||
<!-- https://learn.microsoft.com/en-us/windows/win32/hidpi/setting-the-default-dpi-awareness-for-a-process#setting-default-awareness-with-the-application-manifest -->
|
||||
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
|
||||
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2</dpiAwareness>
|
||||
<activeCodePage xmlns="http://schemas.microsoft.com/SMI/2019/WindowsSettings">UTF-8</activeCodePage>
|
||||
<heapType xmlns="http://schemas.microsoft.com/SMI/2020/WindowsSettings">SegmentHeap</heapType>
|
||||
</windowsSettings>
|
||||
|
@ -70,6 +70,7 @@ static void dump_start_data(const GameStartData &data)
|
||||
ClientLauncher::~ClientLauncher()
|
||||
{
|
||||
delete input;
|
||||
g_settings->deregisterChangedCallback("dpi_change_notifier", setting_changed_callback, this);
|
||||
g_settings->deregisterChangedCallback("gui_scaling", setting_changed_callback, this);
|
||||
|
||||
delete g_fontengine;
|
||||
@ -130,6 +131,7 @@ bool ClientLauncher::run(GameStartData &start_data, const Settings &cmd_args)
|
||||
|
||||
guienv = m_rendering_engine->get_gui_env();
|
||||
config_guienv();
|
||||
g_settings->registerChangedCallback("dpi_change_notifier", setting_changed_callback, this);
|
||||
g_settings->registerChangedCallback("gui_scaling", setting_changed_callback, this);
|
||||
|
||||
g_fontengine = new FontEngine(guienv);
|
||||
|
@ -59,7 +59,7 @@ FontEngine::FontEngine(gui::IGUIEnvironment* env) :
|
||||
"mono_font_path", "mono_font_path_bold", "mono_font_path_italic",
|
||||
"mono_font_path_bold_italic",
|
||||
"fallback_font_path",
|
||||
"screen_dpi", "gui_scaling",
|
||||
"dpi_change_notifier", "gui_scaling",
|
||||
};
|
||||
|
||||
for (auto name : settings)
|
||||
|
@ -1914,6 +1914,10 @@ void Game::updateDebugState()
|
||||
if (!has_debug) {
|
||||
draw_control->show_wireframe = false;
|
||||
m_flags.disable_camera_update = false;
|
||||
auto formspec = m_game_ui->getFormspecGUI();
|
||||
if (formspec) {
|
||||
formspec->setDebugView(false);
|
||||
}
|
||||
}
|
||||
|
||||
// noclip
|
||||
|
@ -60,6 +60,7 @@ Hud::Hud(Client *client, LocalPlayer *player,
|
||||
this->inventory = inventory;
|
||||
|
||||
readScalingSetting();
|
||||
g_settings->registerChangedCallback("dpi_change_notifier", setting_changed_callback, this);
|
||||
g_settings->registerChangedCallback("hud_scaling", setting_changed_callback, this);
|
||||
|
||||
for (auto &hbar_color : hbar_colors)
|
||||
@ -153,6 +154,7 @@ void Hud::readScalingSetting()
|
||||
|
||||
Hud::~Hud()
|
||||
{
|
||||
g_settings->deregisterChangedCallback("dpi_change_notifier", setting_changed_callback, this);
|
||||
g_settings->deregisterChangedCallback("hud_scaling", setting_changed_callback, this);
|
||||
|
||||
if (m_selection_mesh)
|
||||
|
@ -113,6 +113,15 @@ bool MyEventReceiver::OnEvent(const SEvent &event)
|
||||
return true;
|
||||
}
|
||||
|
||||
if (event.EventType == EET_APPLICATION_EVENT &&
|
||||
event.ApplicationEvent.EventType == EAET_DPI_CHANGED) {
|
||||
// This is a fake setting so that we can use (de)registerChangedCallback
|
||||
// not only to listen for gui/hud_scaling changes, but also for DPI changes.
|
||||
g_settings->setU16("dpi_change_notifier",
|
||||
g_settings->getU16("dpi_change_notifier") + 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
// This is separate from other keyboard handling so that it also works in menus.
|
||||
if (event.EventType == EET_KEY_INPUT_EVENT) {
|
||||
const KeyPress keyCode(event.KeyInput);
|
||||
|
@ -24,18 +24,20 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#include "mapblock.h"
|
||||
#include "map.h"
|
||||
#include "util/directiontables.h"
|
||||
#include "porting.h"
|
||||
|
||||
static class BlockPlaceholder {
|
||||
public:
|
||||
MapNode data[MAP_BLOCKSIZE * MAP_BLOCKSIZE * MAP_BLOCKSIZE];
|
||||
// Data placeholder used for copying from non-existent blocks
|
||||
static struct BlockPlaceholder {
|
||||
MapNode data[MapBlock::nodecount];
|
||||
|
||||
BlockPlaceholder()
|
||||
{
|
||||
for (std::size_t i = 0; i < MAP_BLOCKSIZE * MAP_BLOCKSIZE * MAP_BLOCKSIZE; i++)
|
||||
for (std::size_t i = 0; i < MapBlock::nodecount; i++)
|
||||
data[i] = MapNode(CONTENT_IGNORE);
|
||||
}
|
||||
|
||||
} block_placeholder;
|
||||
|
||||
/*
|
||||
QueuedMeshUpdate
|
||||
*/
|
||||
@ -225,12 +227,13 @@ void MeshUpdateWorkerThread::doUpdate()
|
||||
while ((q = m_queue_in->pop())) {
|
||||
if (m_generation_interval)
|
||||
sleep_ms(m_generation_interval);
|
||||
|
||||
porting::TriggerMemoryTrim();
|
||||
|
||||
ScopeProfiler sp(g_profiler, "Client: Mesh making (sum)");
|
||||
|
||||
MapBlockMesh *mesh_new = new MapBlockMesh(m_client, q->data, *m_camera_offset);
|
||||
|
||||
|
||||
|
||||
MeshUpdateResult r;
|
||||
r.p = q->p;
|
||||
r.mesh = mesh_new;
|
||||
|
@ -462,18 +462,14 @@ const VideoDriverInfo &RenderingEngine::getVideoDriverInfo(irr::video::E_DRIVER_
|
||||
|
||||
float RenderingEngine::getDisplayDensity()
|
||||
{
|
||||
float user_factor = g_settings->getFloat("display_density_factor", 0.5f, 5.0f);
|
||||
#ifndef __ANDROID__
|
||||
static float cached_display_density = [&] {
|
||||
float dpi = get_raw_device()->getDisplayDensity();
|
||||
// fall back to manually specified dpi
|
||||
if (dpi == 0.0f)
|
||||
dpi = g_settings->getFloat("screen_dpi");
|
||||
return dpi / 96.0f;
|
||||
}();
|
||||
return std::max(cached_display_density * g_settings->getFloat("display_density_factor"), 0.5f);
|
||||
|
||||
float dpi = get_raw_device()->getDisplayDensity();
|
||||
if (dpi == 0.0f)
|
||||
dpi = 96.0f;
|
||||
return std::max(dpi / 96.0f * user_factor, 0.5f);
|
||||
#else // __ANDROID__
|
||||
return porting::getDisplayDensity();
|
||||
return porting::getDisplayDensity() * user_factor;
|
||||
#endif // __ANDROID__
|
||||
}
|
||||
|
||||
|
@ -40,3 +40,4 @@
|
||||
#cmakedefine01 CURSES_HAVE_NCURSESW_CURSES_H
|
||||
#cmakedefine01 BUILD_UNITTESTS
|
||||
#cmakedefine01 BUILD_BENCHMARKS
|
||||
#cmakedefine01 USE_SDL2
|
||||
|
@ -537,11 +537,11 @@ void set_default_settings()
|
||||
settings->setDefault("server_description", "");
|
||||
|
||||
settings->setDefault("enable_console", "false");
|
||||
settings->setDefault("screen_dpi", "72");
|
||||
settings->setDefault("display_density_factor", "1");
|
||||
settings->setDefault("dpi_change_notifier", "0");
|
||||
|
||||
// Altered settings for macOS
|
||||
#if defined(__MACH__) && defined(__APPLE__)
|
||||
// Altered settings for CIrrDeviceOSX
|
||||
#if !USE_SDL2 && defined(__MACH__) && defined(__APPLE__)
|
||||
settings->setDefault("keymap_sneak", "KEY_SHIFT");
|
||||
#endif
|
||||
|
||||
|
@ -662,6 +662,8 @@ void *EmergeThread::run()
|
||||
EmergeAction action;
|
||||
MapBlock *block = nullptr;
|
||||
|
||||
porting::TriggerMemoryTrim();
|
||||
|
||||
if (!popBlockEmerge(&pos, &bedata)) {
|
||||
m_queue_event.wait();
|
||||
continue;
|
||||
|
@ -4184,8 +4184,10 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event)
|
||||
m_client->makeScreenshot();
|
||||
}
|
||||
|
||||
if (event.KeyInput.PressedDown && kp == getKeySetting("keymap_toggle_debug"))
|
||||
m_show_debug = !m_show_debug;
|
||||
if (event.KeyInput.PressedDown && kp == getKeySetting("keymap_toggle_debug")) {
|
||||
if (!m_client || m_client->checkPrivilege("debug"))
|
||||
m_show_debug = !m_show_debug;
|
||||
}
|
||||
|
||||
if (event.KeyInput.PressedDown &&
|
||||
(event.KeyInput.Key==KEY_RETURN ||
|
||||
|
@ -223,6 +223,11 @@ class GUIFormSpecMenu : public GUIModalMenu
|
||||
m_allowclose = value;
|
||||
}
|
||||
|
||||
void setDebugView(bool value)
|
||||
{
|
||||
m_show_debug = value;
|
||||
}
|
||||
|
||||
void lockSize(bool lock,v2u32 basescreensize=v2u32(0,0))
|
||||
{
|
||||
m_lock = lock;
|
||||
|
@ -920,22 +920,29 @@ double perf_freq = get_perf_freq();
|
||||
*
|
||||
* As a workaround we track freed memory coarsely and call malloc_trim() once a
|
||||
* certain amount is reached.
|
||||
*
|
||||
* Because trimming can take more than 10ms and would cause jitter if done
|
||||
* uncontrolled we have a separate function, which is called from background threads.
|
||||
*/
|
||||
|
||||
static std::atomic<size_t> memory_freed;
|
||||
|
||||
constexpr size_t MEMORY_TRIM_THRESHOLD = 128 * 1024 * 1024;
|
||||
constexpr size_t MEMORY_TRIM_THRESHOLD = 256 * 1024 * 1024;
|
||||
|
||||
void TrackFreedMemory(size_t amount)
|
||||
{
|
||||
memory_freed.fetch_add(amount, std::memory_order_relaxed);
|
||||
}
|
||||
|
||||
void TriggerMemoryTrim()
|
||||
{
|
||||
constexpr auto MO = std::memory_order_relaxed;
|
||||
memory_freed.fetch_add(amount, MO);
|
||||
if (memory_freed.load(MO) >= MEMORY_TRIM_THRESHOLD) {
|
||||
// Synchronize call
|
||||
if (memory_freed.exchange(0, MO) < MEMORY_TRIM_THRESHOLD)
|
||||
return;
|
||||
// Leave some headroom for future allocations
|
||||
malloc_trim(1 * 1024 * 1024);
|
||||
malloc_trim(8 * 1024 * 1024);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -290,15 +290,22 @@ void osSpecificInit();
|
||||
// This attaches to the parents process console, or creates a new one if it doesnt exist.
|
||||
void attachOrCreateConsole();
|
||||
|
||||
#if HAVE_MALLOC_TRIM
|
||||
/**
|
||||
* Call this after freeing bigger blocks of memory. Used on some platforms to
|
||||
* properly give memory back to the OS.
|
||||
* @param amount Number of bytes freed
|
||||
*/
|
||||
#if HAVE_MALLOC_TRIM
|
||||
void TrackFreedMemory(size_t amount);
|
||||
|
||||
/**
|
||||
* Call this regularly from background threads. This performs the actual trimming
|
||||
* and is potentially slow.
|
||||
*/
|
||||
void TriggerMemoryTrim();
|
||||
#else
|
||||
inline void TrackFreedMemory(size_t amount) { (void)amount; }
|
||||
static inline void TrackFreedMemory(size_t amount) { (void)amount; }
|
||||
static inline void TriggerMemoryTrim() { (void)0; }
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
|
@ -330,27 +330,6 @@ Server::~Server()
|
||||
SendChatMessage(PEER_ID_INEXISTENT, ChatMessage(CHATMESSAGE_TYPE_ANNOUNCE,
|
||||
L"*** Server shutting down"));
|
||||
|
||||
if (m_env) {
|
||||
MutexAutoLock envlock(m_env_mutex);
|
||||
|
||||
infostream << "Server: Saving players" << std::endl;
|
||||
m_env->saveLoadedPlayers();
|
||||
|
||||
infostream << "Server: Kicking players" << std::endl;
|
||||
std::string kick_msg;
|
||||
bool reconnect = false;
|
||||
if (isShutdownRequested()) {
|
||||
reconnect = m_shutdown_state.should_reconnect;
|
||||
kick_msg = m_shutdown_state.message;
|
||||
}
|
||||
if (kick_msg.empty()) {
|
||||
kick_msg = g_settings->get("kick_msg_shutdown");
|
||||
}
|
||||
m_env->saveLoadedPlayers(true);
|
||||
kickAllPlayers(SERVER_ACCESSDENIED_SHUTDOWN,
|
||||
kick_msg, reconnect);
|
||||
}
|
||||
|
||||
actionstream << "Server: Shutting down" << std::endl;
|
||||
|
||||
// Stop server step from happening
|
||||
@ -370,16 +349,33 @@ Server::~Server()
|
||||
if (m_env) {
|
||||
MutexAutoLock envlock(m_env_mutex);
|
||||
|
||||
infostream << "Server: Executing shutdown hooks" << std::endl;
|
||||
try {
|
||||
// Empty out the environment, this can also invoke callbacks.
|
||||
m_env->deactivateBlocksAndObjects();
|
||||
m_script->on_shutdown();
|
||||
} catch (ModError &e) {
|
||||
addShutdownError(e);
|
||||
}
|
||||
|
||||
infostream << "Server: Executing shutdown hooks" << std::endl;
|
||||
infostream << "Server: Saving players" << std::endl;
|
||||
m_env->saveLoadedPlayers();
|
||||
|
||||
infostream << "Server: Kicking players" << std::endl;
|
||||
std::string kick_msg;
|
||||
bool reconnect = false;
|
||||
if (isShutdownRequested()) {
|
||||
reconnect = m_shutdown_state.should_reconnect;
|
||||
kick_msg = m_shutdown_state.message;
|
||||
}
|
||||
if (kick_msg.empty()) {
|
||||
kick_msg = g_settings->get("kick_msg_shutdown");
|
||||
}
|
||||
m_env->saveLoadedPlayers(true);
|
||||
kickAllPlayers(SERVER_ACCESSDENIED_SHUTDOWN,
|
||||
kick_msg, reconnect);
|
||||
|
||||
try {
|
||||
m_script->on_shutdown();
|
||||
// Empty out the environment, this can also invoke callbacks.
|
||||
m_env->deactivateBlocksAndObjects();
|
||||
} catch (ModError &e) {
|
||||
addShutdownError(e);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user