diff --git a/projects/openttd_vs140.vcxproj b/projects/openttd_vs140.vcxproj index 6453d62b86..29921e387c 100644 --- a/projects/openttd_vs140.vcxproj +++ b/projects/openttd_vs140.vcxproj @@ -1094,6 +1094,7 @@ + @@ -1161,6 +1162,7 @@ + diff --git a/projects/openttd_vs140.vcxproj.filters b/projects/openttd_vs140.vcxproj.filters index 0405740d4c..1c6422b7fa 100644 --- a/projects/openttd_vs140.vcxproj.filters +++ b/projects/openttd_vs140.vcxproj.filters @@ -2370,6 +2370,9 @@ Script API + + Script API + Script API @@ -2571,6 +2574,9 @@ Script API Implementation + + Script API Implementation + Script API Implementation diff --git a/projects/openttd_vs141.vcxproj b/projects/openttd_vs141.vcxproj index ecfed4a038..aea1947d8f 100644 --- a/projects/openttd_vs141.vcxproj +++ b/projects/openttd_vs141.vcxproj @@ -1094,6 +1094,7 @@ + @@ -1161,6 +1162,7 @@ + diff --git a/projects/openttd_vs141.vcxproj.filters b/projects/openttd_vs141.vcxproj.filters index 0405740d4c..1c6422b7fa 100644 --- a/projects/openttd_vs141.vcxproj.filters +++ b/projects/openttd_vs141.vcxproj.filters @@ -2370,6 +2370,9 @@ Script API + + Script API + Script API @@ -2571,6 +2574,9 @@ Script API Implementation + + Script API Implementation + Script API Implementation diff --git a/projects/openttd_vs142.vcxproj b/projects/openttd_vs142.vcxproj index 49858a3e1d..e9b31a3d77 100644 --- a/projects/openttd_vs142.vcxproj +++ b/projects/openttd_vs142.vcxproj @@ -1094,6 +1094,7 @@ + @@ -1161,6 +1162,7 @@ + diff --git a/projects/openttd_vs142.vcxproj.filters b/projects/openttd_vs142.vcxproj.filters index 0405740d4c..1c6422b7fa 100644 --- a/projects/openttd_vs142.vcxproj.filters +++ b/projects/openttd_vs142.vcxproj.filters @@ -2370,6 +2370,9 @@ Script API + + Script API + Script API @@ -2571,6 +2574,9 @@ Script API Implementation + + Script API Implementation + Script API Implementation diff --git a/source.list b/source.list index ce3c50729a..e4b0e23f6b 100644 --- a/source.list +++ b/source.list @@ -826,6 +826,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 @@ -895,6 +896,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 57b2213ea9..fa9ead1774 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" @@ -170,6 +171,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/script/api/ai/ai_priorityqueue.hpp.sq b/src/script/api/ai/ai_priorityqueue.hpp.sq new file mode 100644 index 0000000000..a2885ab3e2 --- /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.DefSQMethod(engine, &ScriptPriorityQueue::Insert, "Insert", 3, "xii"); + SQAIPriorityQueue.DefSQMethod(engine, &ScriptPriorityQueue::Pop, "Pop", 1, "x"); + SQAIPriorityQueue.DefSQMethod(engine, &ScriptPriorityQueue::Peek, "Peek", 1, "x"); + SQAIPriorityQueue.DefSQMethod(engine, &ScriptPriorityQueue::Exists, "Exists", 2, "xi"); + SQAIPriorityQueue.DefSQMethod(engine, &ScriptPriorityQueue::Clear, "Clear", 1, "x"); + 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/game/game_priorityqueue.hpp.sq b/src/script/api/game/game_priorityqueue.hpp.sq new file mode 100644 index 0000000000..8bd1ac6466 --- /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.DefSQMethod(engine, &ScriptPriorityQueue::Insert, "Insert", 3, "xii"); + SQGSPriorityQueue.DefSQMethod(engine, &ScriptPriorityQueue::Pop, "Pop", 1, "x"); + SQGSPriorityQueue.DefSQMethod(engine, &ScriptPriorityQueue::Peek, "Peek", 1, "x"); + SQGSPriorityQueue.DefSQMethod(engine, &ScriptPriorityQueue::Exists, "Exists", 2, "xi"); + SQGSPriorityQueue.DefSQMethod(engine, &ScriptPriorityQueue::Clear, "Clear", 1, "x"); + 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/script_priorityqueue.cpp b/src/script/api/script_priorityqueue.cpp new file mode 100644 index 0000000000..7b5c170aa7 --- /dev/null +++ b/src/script/api/script_priorityqueue.cpp @@ -0,0 +1,61 @@ +/* + * 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 "../../debug.h" + +#include "../../safeguards.h" + + +bool ScriptPriorityQueue::Insert(int64 item, int64 priority) +{ + auto inserted = this->items.insert(item); + if (inserted.second) this->queue.emplace(priority, item); + return inserted.second; +} + +int64 ScriptPriorityQueue::Pop() +{ + EnforcePrecondition(INT64_MAX, !this->IsEmpty()); + + int64 item = this->queue.top().second; + this->queue.pop(); + this->items.erase(item); + return item; +} + +int64 ScriptPriorityQueue::Peek() +{ + EnforcePrecondition(INT64_MAX, !this->IsEmpty()); + + return this->queue.top().second; +} + +bool ScriptPriorityQueue::Exists(int64 item) +{ + return this->items.find(item) != this->items.end(); +} + +void ScriptPriorityQueue::Clear() +{ + this->items.clear(); + this->queue = ItemQueue(); +} + +bool ScriptPriorityQueue::IsEmpty() +{ + return this->items.empty(); +} + +int32 ScriptPriorityQueue::Count() +{ + return (int32)this->items.size(); +} diff --git a/src/script/api/script_priorityqueue.hpp b/src/script/api/script_priorityqueue.hpp new file mode 100644 index 0000000000..82b03defb2 --- /dev/null +++ b/src/script/api/script_priorityqueue.hpp @@ -0,0 +1,85 @@ +/* + * 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 { +private: + typedef std::pair PriorityItem; + struct PriorityComparator { + bool operator()(const PriorityItem &lhs, const PriorityItem &rhs) + { + return lhs.first > rhs.first; + } + }; + + typedef std::priority_queue, PriorityComparator> ItemQueue; + typedef std::unordered_set ItemSet; + + ItemSet items; ///< The items in the queue + ItemQueue queue; ///< The priority list + +public: + /** + * Add a single item to the queue. + * @param item The item to add. 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(int64 item, int64 priority); + + /** + * Remove and return the item with the lowest priority. + * @return The item with the lowest priority, removed from the queue. + * @pre !IsEmpty() + */ + int64 Pop(); + + /** + * Get the item with the lowest priority, keeping it in the queue. + * @return The item with the lowest priority. + * @pre !IsEmpty() + */ + int64 Peek(); + + /** + * Check if an items is already included in the queue. + * @return true if the items is already in the queue. + */ + bool Exists(int64 item); + + /** + * Clear the queue, making Count() returning 0 and IsEmpty() returning true. + */ + void Clear(); + + /** + * 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. + */ + int32 Count(); +}; + +#endif /* SCRIPT_PRIORITYQUEUE_HPP */ 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