diff --git a/projects/openttd_vs140.vcxproj b/projects/openttd_vs140.vcxproj index 4acddaf242..d2ef91a877 100644 --- a/projects/openttd_vs140.vcxproj +++ b/projects/openttd_vs140.vcxproj @@ -1152,6 +1152,7 @@ + @@ -1219,6 +1220,7 @@ + diff --git a/projects/openttd_vs140.vcxproj.filters b/projects/openttd_vs140.vcxproj.filters index f5220a6c3c..f37355d847 100644 --- a/projects/openttd_vs140.vcxproj.filters +++ b/projects/openttd_vs140.vcxproj.filters @@ -2553,6 +2553,9 @@ Script API + + Script API + Script API @@ -2754,6 +2757,9 @@ Script API Implementation + + Script API Implementation + Script API Implementation diff --git a/projects/openttd_vs141.vcxproj b/projects/openttd_vs141.vcxproj index 6f12343986..1e2c8aa668 100644 --- a/projects/openttd_vs141.vcxproj +++ b/projects/openttd_vs141.vcxproj @@ -1152,6 +1152,7 @@ + @@ -1219,6 +1220,7 @@ + diff --git a/projects/openttd_vs141.vcxproj.filters b/projects/openttd_vs141.vcxproj.filters index f5220a6c3c..f37355d847 100644 --- a/projects/openttd_vs141.vcxproj.filters +++ b/projects/openttd_vs141.vcxproj.filters @@ -2553,6 +2553,9 @@ Script API + + Script API + Script API @@ -2754,6 +2757,9 @@ Script API Implementation + + Script API Implementation + Script API Implementation diff --git a/projects/openttd_vs142.vcxproj b/projects/openttd_vs142.vcxproj index ce748dd11d..66a7de6918 100644 --- a/projects/openttd_vs142.vcxproj +++ b/projects/openttd_vs142.vcxproj @@ -1152,6 +1152,7 @@ + @@ -1219,6 +1220,7 @@ + diff --git a/projects/openttd_vs142.vcxproj.filters b/projects/openttd_vs142.vcxproj.filters index f5220a6c3c..f37355d847 100644 --- a/projects/openttd_vs142.vcxproj.filters +++ b/projects/openttd_vs142.vcxproj.filters @@ -2553,6 +2553,9 @@ Script API + + Script API + Script API @@ -2754,6 +2757,9 @@ Script API Implementation + + Script API Implementation + Script API Implementation diff --git a/source.list b/source.list index 05c1bcbac4..f2dbf76563 100644 --- a/source.list +++ b/source.list @@ -887,6 +887,7 @@ script/api/script_marine.hpp script/api/script_news.hpp script/api/script_object.hpp script/api/script_order.hpp +script/api/script_priorityqueue.hpp script/api/script_rail.hpp script/api/script_railtypelist.hpp script/api/script_road.hpp @@ -956,6 +957,7 @@ script/api/script_marine.cpp script/api/script_news.cpp script/api/script_object.cpp script/api/script_order.cpp +script/api/script_priorityqueue.cpp script/api/script_rail.cpp script/api/script_railtypelist.cpp script/api/script_road.cpp diff --git a/src/ai/ai_instance.cpp b/src/ai/ai_instance.cpp index a4d06763fa..49f8cff64d 100644 --- a/src/ai/ai_instance.cpp +++ b/src/ai/ai_instance.cpp @@ -57,6 +57,7 @@ #include "../script/api/ai/ai_map.hpp.sq" #include "../script/api/ai/ai_marine.hpp.sq" #include "../script/api/ai/ai_order.hpp.sq" +#include "../script/api/ai/ai_priorityqueue.hpp.sq" #include "../script/api/ai/ai_rail.hpp.sq" #include "../script/api/ai/ai_railtypelist.hpp.sq" #include "../script/api/ai/ai_road.hpp.sq" @@ -164,6 +165,7 @@ void AIInstance::RegisterAPI() SQAIMap_Register(this->engine); SQAIMarine_Register(this->engine); SQAIOrder_Register(this->engine); + SQAIPriorityQueue_Register(this->engine); SQAIRail_Register(this->engine); SQAIRailTypeList_Register(this->engine); SQAIRoad_Register(this->engine); diff --git a/src/game/game_instance.cpp b/src/game/game_instance.cpp index 4424c801c6..47d51e28ee 100644 --- a/src/game/game_instance.cpp +++ b/src/game/game_instance.cpp @@ -59,6 +59,7 @@ #include "../script/api/game/game_marine.hpp.sq" #include "../script/api/game/game_news.hpp.sq" #include "../script/api/game/game_order.hpp.sq" +#include "../script/api/game/game_priorityqueue.hpp.sq" #include "../script/api/game/game_rail.hpp.sq" #include "../script/api/game/game_railtypelist.hpp.sq" #include "../script/api/game/game_road.hpp.sq" @@ -173,6 +174,7 @@ void GameInstance::RegisterAPI() SQGSMarine_Register(this->engine); SQGSNews_Register(this->engine); SQGSOrder_Register(this->engine); + SQGSPriorityQueue_Register(this->engine); SQGSRail_Register(this->engine); SQGSRailTypeList_Register(this->engine); SQGSRoad_Register(this->engine); diff --git a/src/lang/croatian.txt b/src/lang/croatian.txt index 0a51385f38..deadd33a80 100644 --- a/src/lang/croatian.txt +++ b/src/lang/croatian.txt @@ -1031,6 +1031,7 @@ STR_GAME_OPTIONS_CURRENCY_MXN :Meksički Pesos STR_GAME_OPTIONS_CURRENCY_NTD :Novi Tajvanski Dolar (NTD) STR_GAME_OPTIONS_CURRENCY_CNY :Kineski Renminbi (CNY) STR_GAME_OPTIONS_CURRENCY_HKD :Hongkonški Dolar (HKD) +STR_GAME_OPTIONS_CURRENCY_INR :Indijska Rupija (INR) ############ end of currency region STR_GAME_OPTIONS_ROAD_VEHICLES_FRAME :{BLACK}Cestovna vozila diff --git a/src/network/network_content_gui.cpp b/src/network/network_content_gui.cpp index 6083396eeb..dd87a4948b 100644 --- a/src/network/network_content_gui.cpp +++ b/src/network/network_content_gui.cpp @@ -951,7 +951,7 @@ public: { if (this->auto_select && !rci->IsSelected()) _network_content_client.ToggleSelectedState(rci); this->content.ForceRebuild(); - this->InvalidateData(); + this->InvalidateData(0, false); } void OnDownloadComplete(ContentID cid) override diff --git a/src/newgrf.cpp b/src/newgrf.cpp index e20c94e3e0..1e03c5f6be 100644 --- a/src/newgrf.cpp +++ b/src/newgrf.cpp @@ -9279,18 +9279,18 @@ GRFFile::GRFFile(const GRFConfig *config) } /* Initialise rail type map with default rail types */ - memset(this->railtype_map, INVALID_RAILTYPE, sizeof(this->railtype_map)); + std::fill(std::begin(this->railtype_map), std::end(this->railtype_map), INVALID_RAILTYPE); this->railtype_map[0] = RAILTYPE_RAIL; this->railtype_map[1] = RAILTYPE_ELECTRIC; this->railtype_map[2] = RAILTYPE_MONO; this->railtype_map[3] = RAILTYPE_MAGLEV; /* Initialise road type map with default road types */ - memset(this->roadtype_map, INVALID_ROADTYPE, sizeof(this->roadtype_map)); + std::fill(std::begin(this->roadtype_map), std::end(this->roadtype_map), INVALID_ROADTYPE); this->roadtype_map[0] = ROADTYPE_ROAD; /* Initialise tram type map with default tram types */ - memset(this->tramtype_map, INVALID_ROADTYPE, sizeof(this->tramtype_map)); + std::fill(std::begin(this->tramtype_map), std::end(this->tramtype_map), INVALID_ROADTYPE); this->tramtype_map[0] = ROADTYPE_TRAM; /* Copy the initial parameter list diff --git a/src/newgrf.h b/src/newgrf.h index 8b6362db7d..24093f6564 100644 --- a/src/newgrf.h +++ b/src/newgrf.h @@ -244,7 +244,7 @@ struct GRFFile : ZeroedMemoryAllocator { std::vector roadtype_list; ///< Roadtype translation table (road) RoadType roadtype_map[ROADTYPE_END]; - std::vector tramtype_list; ///, Roadtype translation table (tram) + std::vector tramtype_list; ///< Roadtype translation table (tram) RoadType tramtype_map[ROADTYPE_END]; CanalProperties canal_local_properties[CF_END]; ///< Canal properties as set by this NewGRF diff --git a/src/os/windows/crashlog_win.cpp b/src/os/windows/crashlog_win.cpp index 7e4bb2aec4..bc164c12ce 100644 --- a/src/os/windows/crashlog_win.cpp +++ b/src/os/windows/crashlog_win.cpp @@ -617,6 +617,9 @@ void *_safe_esp = nullptr; static LONG WINAPI ExceptionHandler(EXCEPTION_POINTERS *ep) { + /* Disable our event loop. */ + SetWindowLongPtr(GetActiveWindow(), GWLP_WNDPROC, (LONG_PTR)&DefWindowProc); + if (CrashLogWindows::current != nullptr) { CrashLog::AfterCrashLogCleanup(); ExitProcess(2); diff --git a/src/os/windows/ottdres.rc.in b/src/os/windows/ottdres.rc.in index 44c04c919d..861015eb70 100644 --- a/src/os/windows/ottdres.rc.in +++ b/src/os/windows/ottdres.rc.in @@ -44,17 +44,17 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_DEFAULT // Dialog // -100 DIALOG DISCARDABLE 0, 0, 305, 99 +100 DIALOG DISCARDABLE 0, 0, 305, 101 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Fatal Application Failure" FONT 8, "MS Sans Serif" BEGIN - PUSHBUTTON "&Close",12,7,80,50,14 - PUSHBUTTON "&Emergency save",13,155,80,68,14 - PUSHBUTTON "",15,243,80,55,14 - EDITTEXT 11,7,101,291,118,ES_MULTILINE | ES_READONLY | WS_VSCROLL | + PUSHBUTTON "&Close",12,7,82,60,14 + PUSHBUTTON "&Emergency save",13,158,82,60,14 + PUSHBUTTON "",15,238,82,60,14 + EDITTEXT 11,7,103,291,118,ES_MULTILINE | ES_READONLY | WS_VSCROLL | WS_HSCROLL | NOT WS_TABSTOP - LTEXT "",10,36,7,262,65 + LTEXT "",10,36,5,262,72 ICON 100,IDC_STATIC,9,9,20,20 END diff --git a/src/script/api/ai/ai_priorityqueue.hpp.sq b/src/script/api/ai/ai_priorityqueue.hpp.sq new file mode 100644 index 0000000000..6e5fcf82e9 --- /dev/null +++ b/src/script/api/ai/ai_priorityqueue.hpp.sq @@ -0,0 +1,31 @@ +/* + * This file is part of OpenTTD. + * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. + * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . + */ + +/* THIS FILE IS AUTO-GENERATED; PLEASE DO NOT ALTER MANUALLY */ + +#include "../script_priorityqueue.hpp" +#include "../template/template_priorityqueue.hpp.sq" + + +template <> const char *GetClassName() { return "AIPriorityQueue"; } + +void SQAIPriorityQueue_Register(Squirrel *engine) +{ + DefSQClass SQAIPriorityQueue("AIPriorityQueue"); + SQAIPriorityQueue.PreRegister(engine); + SQAIPriorityQueue.AddConstructor(engine, "x"); + + SQAIPriorityQueue.DefSQAdvancedMethod(engine, &ScriptPriorityQueue::Insert, "Insert"); + SQAIPriorityQueue.DefSQAdvancedMethod(engine, &ScriptPriorityQueue::Pop, "Pop"); + SQAIPriorityQueue.DefSQAdvancedMethod(engine, &ScriptPriorityQueue::Peek, "Peek"); + SQAIPriorityQueue.DefSQAdvancedMethod(engine, &ScriptPriorityQueue::Exists, "Exists"); + SQAIPriorityQueue.DefSQAdvancedMethod(engine, &ScriptPriorityQueue::Clear, "Clear"); + SQAIPriorityQueue.DefSQMethod(engine, &ScriptPriorityQueue::IsEmpty, "IsEmpty", 1, "x"); + SQAIPriorityQueue.DefSQMethod(engine, &ScriptPriorityQueue::Count, "Count", 1, "x"); + + SQAIPriorityQueue.PostRegister(engine); +} diff --git a/src/script/api/ai_changelog.hpp b/src/script/api/ai_changelog.hpp index bcb7df67f2..a579bb27bc 100644 --- a/src/script/api/ai_changelog.hpp +++ b/src/script/api/ai_changelog.hpp @@ -17,6 +17,9 @@ * * This version is not yet released. The following changes are not set in stone yet. * + * API additions: + * \li AIPriorityQueue + * * \b 1.10.0 * * API additions: diff --git a/src/script/api/game/game_priorityqueue.hpp.sq b/src/script/api/game/game_priorityqueue.hpp.sq new file mode 100644 index 0000000000..fade5e2a1e --- /dev/null +++ b/src/script/api/game/game_priorityqueue.hpp.sq @@ -0,0 +1,31 @@ +/* + * This file is part of OpenTTD. + * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. + * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . + */ + +/* THIS FILE IS AUTO-GENERATED; PLEASE DO NOT ALTER MANUALLY */ + +#include "../script_priorityqueue.hpp" +#include "../template/template_priorityqueue.hpp.sq" + + +template <> const char *GetClassName() { return "GSPriorityQueue"; } + +void SQGSPriorityQueue_Register(Squirrel *engine) +{ + DefSQClass SQGSPriorityQueue("GSPriorityQueue"); + SQGSPriorityQueue.PreRegister(engine); + SQGSPriorityQueue.AddConstructor(engine, "x"); + + SQGSPriorityQueue.DefSQAdvancedMethod(engine, &ScriptPriorityQueue::Insert, "Insert"); + SQGSPriorityQueue.DefSQAdvancedMethod(engine, &ScriptPriorityQueue::Pop, "Pop"); + SQGSPriorityQueue.DefSQAdvancedMethod(engine, &ScriptPriorityQueue::Peek, "Peek"); + SQGSPriorityQueue.DefSQAdvancedMethod(engine, &ScriptPriorityQueue::Exists, "Exists"); + SQGSPriorityQueue.DefSQAdvancedMethod(engine, &ScriptPriorityQueue::Clear, "Clear"); + SQGSPriorityQueue.DefSQMethod(engine, &ScriptPriorityQueue::IsEmpty, "IsEmpty", 1, "x"); + SQGSPriorityQueue.DefSQMethod(engine, &ScriptPriorityQueue::Count, "Count", 1, "x"); + + SQGSPriorityQueue.PostRegister(engine); +} diff --git a/src/script/api/game_changelog.hpp b/src/script/api/game_changelog.hpp index 69c4d971a5..fc917a0120 100644 --- a/src/script/api/game_changelog.hpp +++ b/src/script/api/game_changelog.hpp @@ -24,6 +24,7 @@ * \li GSStoryPage::MakePushButtonReference * \li GSStoryPage::MakeTileButtonReference * \li GSStoryPage::MakeVehicleButtonReference + * \li GSPriorityQueue * * \b 1.10.0 * diff --git a/src/script/api/script_priorityqueue.cpp b/src/script/api/script_priorityqueue.cpp new file mode 100644 index 0000000000..3130084126 --- /dev/null +++ b/src/script/api/script_priorityqueue.cpp @@ -0,0 +1,107 @@ +/* + * This file is part of OpenTTD. + * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. + * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . + */ + +/** @file script_priorityqueue.cpp Implementation of ScriptPriorityQueue. */ + +#include "../../stdafx.h" +#include "script_priorityqueue.hpp" +#include "script_error.hpp" +#include "../squirrel_helper.hpp" +#include "../script_instance.hpp" +#include "../../debug.h" +#include + +#include "../../safeguards.h" + + +static bool operator==(const ScriptPriorityQueue::PriorityItem &lhs, const HSQOBJECT &rhs) +{ + return lhs.second._type == rhs._type && lhs.second._unVal.raw == rhs._unVal.raw; +} + + +ScriptPriorityQueue::~ScriptPriorityQueue() +{ + /* Release reference to stored objects. */ + auto inst = ScriptObject::GetActiveInstance(); + if (!inst->InShutdown()) { + for (auto &i : this->queue) inst->ReleaseSQObject(const_cast(&i.second)); + } +} + +SQInteger ScriptPriorityQueue::Insert(HSQUIRRELVM vm) +{ + HSQOBJECT item; + int64 priority; + sq_resetobject(&item); + sq_getstackobj(vm, 2, &item); + sq_getinteger(vm, 3, &priority); + + sq_addref(vm, &item); // Keep object alive. + + this->queue.emplace_back(priority, item); + std::push_heap(this->queue.begin(), this->queue.end(), this->comp); + + return SQConvert::Return(vm, true); +} + +SQInteger ScriptPriorityQueue::Pop(HSQUIRRELVM vm) +{ + if (this->IsEmpty()) { + ScriptObject::SetLastError(ScriptError::ERR_PRECONDITION_FAILED); + sq_pushnull(vm); + return 1; + } + + HSQOBJECT item = this->queue.front().second; + std::pop_heap(this->queue.begin(), this->queue.end(), this->comp); + this->queue.pop_back(); + + /* Store the object on the Squirrel stack before releasing it to make sure the ref count can't drop to zero. */ + auto ret = SQConvert::Return(vm, item); + sq_release(vm, &item); + return ret; +} + +SQInteger ScriptPriorityQueue::Peek(HSQUIRRELVM vm) +{ + if (this->IsEmpty()) { + ScriptObject::SetLastError(ScriptError::ERR_PRECONDITION_FAILED); + sq_pushnull(vm); + return 1; + } + + return SQConvert::Return(vm, this->queue.front().second); +} + +SQInteger ScriptPriorityQueue::Exists(HSQUIRRELVM vm) +{ + HSQOBJECT item; + sq_resetobject(&item); + sq_getstackobj(vm, 2, &item); + + return SQConvert::Return(vm, std::find(this->queue.cbegin(), this->queue.cend(), item) != this->queue.cend()); +} + +SQInteger ScriptPriorityQueue::Clear(HSQUIRRELVM vm) +{ + /* Release reference to stored objects. */ + for (auto &i : this->queue) sq_release(vm, const_cast(&i.second)); + this->queue.clear(); + + return 0; +} + +bool ScriptPriorityQueue::IsEmpty() +{ + return this->queue.empty(); +} + +SQInteger ScriptPriorityQueue::Count() +{ + return (SQInteger)this->queue.size(); +} diff --git a/src/script/api/script_priorityqueue.hpp b/src/script/api/script_priorityqueue.hpp new file mode 100644 index 0000000000..5f8718e424 --- /dev/null +++ b/src/script/api/script_priorityqueue.hpp @@ -0,0 +1,94 @@ +/* + * This file is part of OpenTTD. + * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. + * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . + */ + +/** @file script_priorityqueue.hpp A queue that keeps a list of items sorted by a priority. */ +/** @defgroup ScriptPriorityQueue Classes that create a priority queue of items. */ + +#ifndef SCRIPT_PRIORITYQUEUE_HPP +#define SCRIPT_PRIORITYQUEUE_HPP + +#include "script_object.hpp" +#include +#include + +/** + * Class that creates a queue which keeps its items ordered by an item priority. + * @api ai game + */ +class ScriptPriorityQueue : public ScriptObject { +public: + typedef std::pair PriorityItem; +private: + struct PriorityComparator { + bool operator()(const PriorityItem &lhs, const PriorityItem &rhs) const noexcept + { + return lhs.first > rhs.first; + } + }; + + PriorityComparator comp; + std::vector queue; ///< The priority list + +public: + ~ScriptPriorityQueue(); + +#ifdef DOXYGEN_API + /** + * Add a single item to the queue. + * @param item The item to add. Can be any Squirrel type. Should be unique, otherwise it is ignored. + * @param priority The priority to assign the item. + * @return True if the item was inserted, false if it was already in the queue. + */ + bool Insert(void *item, int64 priority); + + /** + * Remove and return the item with the lowest priority. + * @return The item with the lowest priority, removed from the queue. Returns null on an empty queue. + * @pre !IsEmpty() + */ + void *Pop(); + + /** + * Get the item with the lowest priority, keeping it in the queue. + * @return The item with the lowest priority. Returns null on an empty queue. + * @pre !IsEmpty() + */ + void *Peek(); + + /** + * Check if an items is already included in the queue. + * @return true if the items is already in the queue. + * @note Performance is O(n), use only when absolutely required. + */ + bool Exists(void *item); + + /** + * Clear the queue, making Count() returning 0 and IsEmpty() returning true. + */ + void Clear(); +#else + SQInteger Insert(HSQUIRRELVM vm); + SQInteger Pop(HSQUIRRELVM vm); + SQInteger Peek(HSQUIRRELVM vm); + SQInteger Exists(HSQUIRRELVM vm); + SQInteger Clear(HSQUIRRELVM vm); +#endif + + /** + * Check if the queue is empty. + * @return true if the queue is empty. + */ + bool IsEmpty(); + + /** + * Returns the amount of items in the queue. + * @return amount of items in the queue. + */ + SQInteger Count(); +}; + +#endif /* SCRIPT_PRIORITYQUEUE_HPP */ diff --git a/src/script/api/script_story_page.cpp b/src/script/api/script_story_page.cpp index 39ae3d53ff..8fda69e6f5 100644 --- a/src/script/api/script_story_page.cpp +++ b/src/script/api/script_story_page.cpp @@ -83,6 +83,10 @@ static inline bool StoryPageElementTypeRequiresText(StoryPageElementType type) case SPET_BUTTON_VEHICLE: refid = reference; break; + case SPET_TEXT: + break; + default: + NOT_REACHED(); } if (!ScriptObject::DoCommand(reftile, @@ -124,6 +128,10 @@ static inline bool StoryPageElementTypeRequiresText(StoryPageElementType type) case SPET_BUTTON_VEHICLE: refid = reference; break; + case SPET_TEXT: + break; + default: + NOT_REACHED(); } return ScriptObject::DoCommand(reftile, diff --git a/src/script/api/template/template_priorityqueue.hpp.sq b/src/script/api/template/template_priorityqueue.hpp.sq new file mode 100644 index 0000000000..14c63324fb --- /dev/null +++ b/src/script/api/template/template_priorityqueue.hpp.sq @@ -0,0 +1,19 @@ +/* + * This file is part of OpenTTD. + * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. + * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . + */ + +/* THIS FILE IS AUTO-GENERATED; PLEASE DO NOT ALTER MANUALLY */ + +#include "../script_priorityqueue.hpp" + +namespace SQConvert { + /* Allow ScriptPriorityQueue to be used as Squirrel parameter */ + template <> inline ScriptPriorityQueue *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptPriorityQueue *)instance; } + template <> inline ScriptPriorityQueue &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptPriorityQueue *)instance; } + template <> inline const ScriptPriorityQueue *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptPriorityQueue *)instance; } + template <> inline const ScriptPriorityQueue &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptPriorityQueue *)instance; } + template <> inline int Return(HSQUIRRELVM vm, ScriptPriorityQueue *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "PriorityQueue", res, nullptr, DefSQDestructorCallback, true); return 1; } +} // namespace SQConvert diff --git a/src/script/script_instance.cpp b/src/script/script_instance.cpp index a38a315ffc..81283cb772 100644 --- a/src/script/script_instance.cpp +++ b/src/script/script_instance.cpp @@ -58,6 +58,7 @@ ScriptInstance::ScriptInstance(const char *APIName) : is_save_data_on_stack(false), suspend(0), is_paused(false), + in_shutdown(false), callback(nullptr) { this->storage = new ScriptStorage(); @@ -136,6 +137,7 @@ bool ScriptInstance::LoadCompatibilityScripts(const char *api_version, Subdirect ScriptInstance::~ScriptInstance() { ScriptObject::ActiveInstance active(this); + this->in_shutdown = true; if (instance != nullptr) this->engine->ReleaseObject(this->instance); if (engine != nullptr) delete this->engine; @@ -154,6 +156,7 @@ void ScriptInstance::Died() { DEBUG(script, 0, "The script died unexpectedly."); this->is_dead = true; + this->in_shutdown = true; this->last_allocated_memory = this->GetAllocatedMemory(); // Update cache @@ -718,3 +721,8 @@ size_t ScriptInstance::GetAllocatedMemory() const if (this->engine == nullptr) return this->last_allocated_memory; return this->engine->GetAllocatedMemory(); } + +void ScriptInstance::ReleaseSQObject(HSQOBJECT *obj) +{ + if (!this->in_shutdown) this->engine->ReleaseObject(obj); +} diff --git a/src/script/script_instance.hpp b/src/script/script_instance.hpp index e5024c80bc..c097e0eb7b 100644 --- a/src/script/script_instance.hpp +++ b/src/script/script_instance.hpp @@ -200,6 +200,17 @@ public: size_t GetAllocatedMemory() const; + /** + * Indicate whether this instance is currently being destroyed. + */ + inline bool InShutdown() const { return this->in_shutdown; } + + /** + * Decrease the ref count of a squirrel object. + * @param obj The object to release. + **/ + void ReleaseSQObject(HSQOBJECT *obj); + protected: class Squirrel *engine; ///< A wrapper around the squirrel vm. const char *versionAPI; ///< Current API used by this script. @@ -242,6 +253,7 @@ private: bool is_save_data_on_stack; ///< Is the save data still on the squirrel stack? int suspend; ///< The amount of ticks to suspend this script before it's allowed to continue. bool is_paused; ///< Is the script paused? (a paused script will not be executed until unpaused) + bool in_shutdown; ///< Is this instance currently being destructed? Script_SuspendCallbackProc *callback; ///< Callback that should be called in the next tick the script runs. size_t last_allocated_memory; ///< Last known allocated memory value (for display for crashed scripts) diff --git a/src/story_gui.cpp b/src/story_gui.cpp index 96c411fe9c..2de96a1a52 100644 --- a/src/story_gui.cpp +++ b/src/story_gui.cpp @@ -459,7 +459,7 @@ protected: } } /* Position element in main column */ - LayoutCacheElement ce{ pe }; + LayoutCacheElement ce{ pe, {} }; ce.bounds.left = left_offset; ce.bounds.right = max_width - right_offset; ce.bounds.top = main_y; @@ -479,7 +479,7 @@ protected: std::vector &cur_floats = (fl == ElementFloat::Left) ? left_floats : right_floats; /* Position element */ cur_width = max(cur_width, this->GetPageElementFloatWidth(*pe)); - LayoutCacheElement ce{ pe }; + LayoutCacheElement ce{ pe, {} }; ce.bounds.left = (fl == ElementFloat::Left) ? 0 : (max_width - cur_width); ce.bounds.right = (fl == ElementFloat::Left) ? cur_width : max_width; ce.bounds.top = cur_y; @@ -745,11 +745,7 @@ public: case SPET_BUTTON_PUSH: case SPET_BUTTON_TILE: case SPET_BUTTON_VEHICLE: { - const int height = FONT_HEIGHT_NORMAL; const int tmargin = WD_BEVEL_TOP + WD_FRAMETEXT_TOP; - const int bmargin = WD_BEVEL_BOTTOM + WD_FRAMETEXT_BOTTOM; - const int width = ce.bounds.right - ce.bounds.left; - const int hmargin = width / 5; const FrameFlags frame = this->active_button_id == ce.pe->index ? FR_LOWERED : FR_NONE; const Colours bgcolour = StoryPageButtonData{ ce.pe->referenced_id }.GetColour(); diff --git a/src/video/cocoa/wnd_quartz.mm b/src/video/cocoa/wnd_quartz.mm index 5183b51f2f..fbb8db77cf 100644 --- a/src/video/cocoa/wnd_quartz.mm +++ b/src/video/cocoa/wnd_quartz.mm @@ -318,6 +318,8 @@ bool WindowQuartzSubdriver::SetVideoMode(int width, int height, int bpp) [this->window setColorSpace:[NSColorSpace sRGBColorSpace]]; this->color_space = CGColorSpaceCreateWithName(kCGColorSpaceSRGB); + if (this->color_space == nullptr) this->color_space = CGColorSpaceCreateDeviceRGB(); + if (this->color_space == nullptr) error("Could not get a valid colour space for drawing."); bool ret = WindowResized(); this->UpdatePalette(0, 256);