diff --git a/src/misc/CMakeLists.txt b/src/misc/CMakeLists.txt
index f088dd5f8d..f45fa06960 100644
--- a/src/misc/CMakeLists.txt
+++ b/src/misc/CMakeLists.txt
@@ -1,7 +1,5 @@
add_files(
binaryheap.hpp
- countedobj.cpp
- countedptr.hpp
dbg_helpers.cpp
dbg_helpers.h
endian_buffer.hpp
diff --git a/src/misc/countedobj.cpp b/src/misc/countedobj.cpp
deleted file mode 100644
index 563ae3f4bb..0000000000
--- a/src/misc/countedobj.cpp
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * 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 countedobj.cpp Support for reference counted objects. */
-
-#include "../stdafx.h"
-
-#include "countedptr.hpp"
-
-#include "../safeguards.h"
-
-int32_t SimpleCountedObject::AddRef()
-{
- return ++m_ref_cnt;
-}
-
-int32_t SimpleCountedObject::Release()
-{
- int32_t res = --m_ref_cnt;
- assert(res >= 0);
- if (res == 0) {
- try {
- FinalRelease(); // may throw, for example ScriptTest/ExecMode
- } catch (...) {
- delete this;
- throw;
- }
- delete this;
- }
- return res;
-}
diff --git a/src/misc/countedptr.hpp b/src/misc/countedptr.hpp
deleted file mode 100644
index 625b124200..0000000000
--- a/src/misc/countedptr.hpp
+++ /dev/null
@@ -1,213 +0,0 @@
-/*
- * 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 countedptr.hpp CCountedPtr - smart pointer implementation. */
-
-#ifndef COUNTEDPTR_HPP
-#define COUNTEDPTR_HPP
-
-/**
- * CCountedPtr - simple reference counting smart pointer.
- *
- * One of the standard ways how to maintain object's lifetime.
- *
- * See http://ootips.org/yonat/4dev/smart-pointers.html for more
- * general info about smart pointers.
- *
- * This class implements ref-counted pointer for objects/interfaces that
- * support AddRef() and Release() methods.
- */
-template
-class CCountedPtr {
- /** redefine the template argument to make it visible for derived classes */
-public:
- typedef Tcls_ Tcls;
-
-protected:
- /** here we hold our pointer to the target */
- Tcls *m_pT;
-
-public:
- /** default (nullptr) construct or construct from a raw pointer */
- inline CCountedPtr(Tcls *pObj = nullptr) : m_pT(pObj)
- {
- AddRef();
- }
-
- /** copy constructor (invoked also when initializing from another smart ptr) */
- inline CCountedPtr(const CCountedPtr &src) : m_pT(src.m_pT)
- {
- AddRef();
- }
-
- /** destructor releasing the reference */
- inline ~CCountedPtr()
- {
- Release();
- }
-
-protected:
- /** add one ref to the underlying object */
- inline void AddRef()
- {
- if (m_pT != nullptr) m_pT->AddRef();
- }
-
-public:
- /** release smart pointer (and decrement ref count) if not null */
- inline void Release()
- {
- if (m_pT != nullptr) {
- Tcls *pT = m_pT;
- m_pT = nullptr;
- pT->Release();
- }
- }
-
- /** dereference of smart pointer - const way */
- inline const Tcls *operator->() const
- {
- assert(m_pT != nullptr);
- return m_pT;
- }
-
- /** dereference of smart pointer - non const way */
- inline Tcls *operator->()
- {
- assert(m_pT != nullptr);
- return m_pT;
- }
-
- /** raw pointer casting operator - const way */
- inline operator const Tcls*() const
- {
- assert(m_pT == nullptr);
- return m_pT;
- }
-
- /** raw pointer casting operator - non-const way */
- inline operator Tcls*()
- {
- return m_pT;
- }
-
- /** operator & to support output arguments */
- inline Tcls** operator&()
- {
- assert(m_pT == nullptr);
- return &m_pT;
- }
-
- /** assignment operator from raw ptr */
- inline CCountedPtr& operator=(Tcls *pT)
- {
- Assign(pT);
- return *this;
- }
-
- /** assignment operator from another smart ptr */
- inline CCountedPtr& operator=(const CCountedPtr &src)
- {
- Assign(src.m_pT);
- return *this;
- }
-
- /** assignment operator helper */
- inline void Assign(Tcls *pT);
-
- /** one way how to test for nullptr value */
- inline bool IsNull() const
- {
- return m_pT == nullptr;
- }
-
- /** assign pointer w/o incrementing ref count */
- inline void Attach(Tcls *pT)
- {
- Release();
- m_pT = pT;
- }
-
- /** detach pointer w/o decrementing ref count */
- inline Tcls *Detach()
- {
- Tcls *pT = m_pT;
- m_pT = nullptr;
- return pT;
- }
-};
-
-template
-inline void CCountedPtr::Assign(Tcls *pT)
-{
- /* if they are the same, we do nothing */
- if (pT != m_pT) {
- if (pT != nullptr) pT->AddRef(); // AddRef new pointer if any
- Tcls *pTold = m_pT; // save original ptr
- m_pT = pT; // update m_pT to new value
- if (pTold != nullptr) pTold->Release(); // release old ptr if any
- }
-}
-
-/**
- * Adapter wrapper for CCountedPtr like classes that can't be used directly by stl
- * collections as item type. For example CCountedPtr has overloaded operator & which
- * prevents using CCountedPtr in stl collections (i.e. std::list >)
- */
-template struct AdaptT {
- T m_t;
-
- /** construct by wrapping the given object */
- AdaptT(const T &t)
- : m_t(t)
- {}
-
- /** assignment operator */
- T& operator = (const T &t)
- {
- m_t = t;
- return t;
- }
-
- /** type-cast operator (used when AdaptT is used instead of T) */
- operator T& ()
- {
- return m_t;
- }
-
- /** const type-cast operator (used when AdaptT is used instead of const T) */
- operator const T& () const
- {
- return m_t;
- }
-};
-
-/**
- * Simple counted object. Use it as base of your struct/class if you want to use
- * basic reference counting. Your struct/class will destroy and free itself when
- * last reference to it is released (using Release() method). The initial reference
- * count (when it is created) is zero (don't forget AddRef() at least one time if
- * not using CCountedPtr.
- *
- * @see misc/countedobj.cpp for implementation.
- */
-struct SimpleCountedObject {
- int32_t m_ref_cnt;
-
- SimpleCountedObject()
- : m_ref_cnt(0)
- {}
-
- virtual ~SimpleCountedObject()
- {}
-
- virtual int32_t AddRef();
- virtual int32_t Release();
- virtual void FinalRelease() {};
-};
-
-#endif /* COUNTEDPTR_HPP */
diff --git a/src/newgrf_config.h b/src/newgrf_config.h
index b664bb8cb1..aad86f7d33 100644
--- a/src/newgrf_config.h
+++ b/src/newgrf_config.h
@@ -12,7 +12,6 @@
#include "strings_type.h"
#include "core/alloc_type.hpp"
-#include "misc/countedptr.hpp"
#include "fileio_type.h"
#include "textfile_type.h"
#include "newgrf_text.h"
diff --git a/src/script/api/script_basestation.cpp b/src/script/api/script_basestation.cpp
index 2c450937b5..7aff814c6a 100644
--- a/src/script/api/script_basestation.cpp
+++ b/src/script/api/script_basestation.cpp
@@ -37,7 +37,7 @@
/* static */ bool ScriptBaseStation::SetName(StationID station_id, Text *name)
{
- CCountedPtr counter(name);
+ ScriptObjectRef counter(name);
EnforceCompanyModeValid(false);
EnforcePrecondition(false, IsValidBaseStation(station_id));
diff --git a/src/script/api/script_company.cpp b/src/script/api/script_company.cpp
index 842a51c9fc..340b31918b 100644
--- a/src/script/api/script_company.cpp
+++ b/src/script/api/script_company.cpp
@@ -46,7 +46,7 @@
/* static */ bool ScriptCompany::SetName(Text *name)
{
- CCountedPtr counter(name);
+ ScriptObjectRef counter(name);
EnforceCompanyModeValid(false);
EnforcePrecondition(false, name != nullptr);
@@ -68,7 +68,7 @@
/* static */ bool ScriptCompany::SetPresidentName(Text *name)
{
- CCountedPtr counter(name);
+ ScriptObjectRef counter(name);
EnforceCompanyModeValid(false);
EnforcePrecondition(false, name != nullptr);
diff --git a/src/script/api/script_goal.cpp b/src/script/api/script_goal.cpp
index 416a8df295..cb7235f395 100644
--- a/src/script/api/script_goal.cpp
+++ b/src/script/api/script_goal.cpp
@@ -44,7 +44,7 @@
/* static */ ScriptGoal::GoalID ScriptGoal::New(ScriptCompany::CompanyID company, Text *goal, GoalType type, SQInteger destination)
{
- CCountedPtr counter(goal);
+ ScriptObjectRef counter(goal);
EnforceDeityMode(GOAL_INVALID);
EnforcePrecondition(GOAL_INVALID, goal != nullptr);
@@ -79,7 +79,7 @@
/* static */ bool ScriptGoal::SetText(GoalID goal_id, Text *goal)
{
- CCountedPtr counter(goal);
+ ScriptObjectRef counter(goal);
EnforcePrecondition(false, IsValidGoal(goal_id));
EnforceDeityMode(false);
@@ -92,7 +92,7 @@
/* static */ bool ScriptGoal::SetProgress(GoalID goal_id, Text *progress)
{
- CCountedPtr counter(progress);
+ ScriptObjectRef counter(progress);
EnforcePrecondition(false, IsValidGoal(goal_id));
EnforceDeityMode(false);
@@ -119,7 +119,7 @@
/* static */ bool ScriptGoal::DoQuestion(SQInteger uniqueid, uint32_t target, bool is_client, Text *question, QuestionType type, SQInteger buttons)
{
- CCountedPtr counter(question);
+ ScriptObjectRef counter(question);
EnforceDeityMode(false);
EnforcePrecondition(false, question != nullptr);
diff --git a/src/script/api/script_group.cpp b/src/script/api/script_group.cpp
index 427aa48cb5..3f36fb6fca 100644
--- a/src/script/api/script_group.cpp
+++ b/src/script/api/script_group.cpp
@@ -56,7 +56,7 @@
/* static */ bool ScriptGroup::SetName(GroupID group_id, Text *name)
{
- CCountedPtr counter(name);
+ ScriptObjectRef counter(name);
EnforceCompanyModeValid(false);
EnforcePrecondition(false, IsValidGroup(group_id));
diff --git a/src/script/api/script_industry.cpp b/src/script/api/script_industry.cpp
index 79e89a075f..d4db67dabd 100644
--- a/src/script/api/script_industry.cpp
+++ b/src/script/api/script_industry.cpp
@@ -58,7 +58,7 @@
/* static */ bool ScriptIndustry::SetText(IndustryID industry_id, Text *text)
{
- CCountedPtr counter(text);
+ ScriptObjectRef counter(text);
EnforceDeityMode(false);
EnforcePrecondition(false, IsValidIndustry(industry_id));
@@ -305,7 +305,7 @@
/* static */ bool ScriptIndustry::SetProductionLevel(IndustryID industry_id, SQInteger prod_level, bool show_news, Text *custom_news)
{
- CCountedPtr counter(custom_news);
+ ScriptObjectRef counter(custom_news);
EnforceDeityMode(false);
EnforcePrecondition(false, IsValidIndustry(industry_id));
diff --git a/src/script/api/script_league.cpp b/src/script/api/script_league.cpp
index a2b6b93795..cc8fbec712 100644
--- a/src/script/api/script_league.cpp
+++ b/src/script/api/script_league.cpp
@@ -26,9 +26,9 @@
/* static */ ScriptLeagueTable::LeagueTableID ScriptLeagueTable::New(Text *title, Text *header, Text *footer)
{
- CCountedPtr title_counter(title);
- CCountedPtr header_counter(header);
- CCountedPtr footer_counter(footer);
+ ScriptObjectRef title_counter(title);
+ ScriptObjectRef header_counter(header);
+ ScriptObjectRef footer_counter(footer);
EnforceDeityMode(LEAGUE_TABLE_INVALID);
EnforcePrecondition(LEAGUE_TABLE_INVALID, title != nullptr);
@@ -51,8 +51,8 @@
/* static */ ScriptLeagueTable::LeagueTableElementID ScriptLeagueTable::NewElement(ScriptLeagueTable::LeagueTableID table, SQInteger rating, ScriptCompany::CompanyID company, Text *text, Text *score, LinkType link_type, SQInteger link_target)
{
- CCountedPtr text_counter(text);
- CCountedPtr score_counter(score);
+ ScriptObjectRef text_counter(text);
+ ScriptObjectRef score_counter(score);
EnforceDeityMode(LEAGUE_TABLE_ELEMENT_INVALID);
@@ -80,7 +80,7 @@
/* static */ bool ScriptLeagueTable::UpdateElementData(LeagueTableElementID element, ScriptCompany::CompanyID company, Text *text, LinkType link_type, SQInteger link_target)
{
- CCountedPtr text_counter(text);
+ ScriptObjectRef text_counter(text);
EnforceDeityMode(false);
EnforcePrecondition(false, IsValidLeagueTableElement(element));
@@ -100,7 +100,7 @@
/* static */ bool ScriptLeagueTable::UpdateElementScore(LeagueTableElementID element, SQInteger rating, Text *score)
{
- CCountedPtr score_counter(score);
+ ScriptObjectRef score_counter(score);
EnforceDeityMode(false);
EnforcePrecondition(false, IsValidLeagueTableElement(element));
diff --git a/src/script/api/script_news.cpp b/src/script/api/script_news.cpp
index 93462436f0..f195a754e1 100644
--- a/src/script/api/script_news.cpp
+++ b/src/script/api/script_news.cpp
@@ -22,7 +22,7 @@
/* static */ bool ScriptNews::Create(NewsType type, Text *text, ScriptCompany::CompanyID company, NewsReferenceType ref_type, SQInteger reference)
{
- CCountedPtr counter(text);
+ ScriptObjectRef counter(text);
EnforceDeityMode(false);
EnforcePrecondition(false, text != nullptr);
diff --git a/src/script/api/script_object.cpp b/src/script/api/script_object.cpp
index 637d662125..cc94b18ff0 100644
--- a/src/script/api/script_object.cpp
+++ b/src/script/api/script_object.cpp
@@ -25,6 +25,21 @@
#include "../../safeguards.h"
+void SimpleCountedObject::Release()
+{
+ int32_t res = --this->ref_count;
+ assert(res >= 0);
+ if (res == 0) {
+ try {
+ this->FinalRelease(); // may throw, for example ScriptTest/ExecMode
+ } catch (...) {
+ delete this;
+ throw;
+ }
+ delete this;
+ }
+}
+
/**
* Get the storage associated with the current ScriptInstance.
* @return The storage.
diff --git a/src/script/api/script_object.hpp b/src/script/api/script_object.hpp
index 28cac81d59..10ad2aefd9 100644
--- a/src/script/api/script_object.hpp
+++ b/src/script/api/script_object.hpp
@@ -10,7 +10,6 @@
#ifndef SCRIPT_OBJECT_HPP
#define SCRIPT_OBJECT_HPP
-#include "../../misc/countedptr.hpp"
#include "../../road_type.h"
#include "../../rail_type.h"
#include "../../string_func.h"
@@ -34,6 +33,27 @@ typedef bool (ScriptModeProc)();
*/
typedef bool (ScriptAsyncModeProc)();
+/**
+ * Simple counted object. Use it as base of your struct/class if you want to use
+ * basic reference counting. Your struct/class will destroy and free itself when
+ * last reference to it is released (using Release() method). The initial reference
+ * count (when it is created) is zero (don't forget AddRef() at least one time if
+ * not using ScriptObjectRef.
+ * @api -all
+ */
+class SimpleCountedObject {
+public:
+ SimpleCountedObject() : ref_count(0) {}
+ virtual ~SimpleCountedObject() {}
+
+ inline void AddRef() { ++this->ref_count; }
+ void Release();
+ virtual void FinalRelease() {};
+
+private:
+ int32_t ref_count;
+};
+
/**
* Uper-parent object of all API classes. You should never use this class in
* your script, as it doesn't publish any public functions. It is used
@@ -406,7 +426,7 @@ public:
*/
ScriptObjectRef(T *data) : data(data)
{
- this->data->AddRef();
+ if (this->data != nullptr) this->data->AddRef();
}
/* No copy constructor. */
diff --git a/src/script/api/script_sign.cpp b/src/script/api/script_sign.cpp
index 59077aa55c..19fcd04abb 100644
--- a/src/script/api/script_sign.cpp
+++ b/src/script/api/script_sign.cpp
@@ -35,7 +35,7 @@
/* static */ bool ScriptSign::SetName(SignID sign_id, Text *name)
{
- CCountedPtr counter(name);
+ ScriptObjectRef counter(name);
EnforceDeityOrCompanyModeValid(false);
EnforcePrecondition(false, IsValidSign(sign_id));
@@ -72,7 +72,7 @@
/* static */ SignID ScriptSign::BuildSign(TileIndex location, Text *name)
{
- CCountedPtr counter(name);
+ ScriptObjectRef counter(name);
EnforceDeityOrCompanyModeValid(INVALID_SIGN);
EnforcePrecondition(INVALID_SIGN, ::IsValidTile(location));
diff --git a/src/script/api/script_story_page.cpp b/src/script/api/script_story_page.cpp
index 0476c16ef1..d1cd5004b0 100644
--- a/src/script/api/script_story_page.cpp
+++ b/src/script/api/script_story_page.cpp
@@ -45,7 +45,7 @@ static inline bool StoryPageElementTypeRequiresText(StoryPageElementType type)
/* static */ ScriptStoryPage::StoryPageID ScriptStoryPage::New(ScriptCompany::CompanyID company, Text *title)
{
- CCountedPtr counter(title);
+ ScriptObjectRef counter(title);
EnforceDeityMode(STORY_PAGE_INVALID);
EnforcePrecondition(STORY_PAGE_INVALID, company == ScriptCompany::COMPANY_INVALID || ScriptCompany::ResolveCompanyID(company) != ScriptCompany::COMPANY_INVALID);
@@ -62,7 +62,7 @@ static inline bool StoryPageElementTypeRequiresText(StoryPageElementType type)
/* static */ ScriptStoryPage::StoryPageElementID ScriptStoryPage::NewElement(StoryPageID story_page_id, StoryPageElementType type, SQInteger reference, Text *text)
{
- CCountedPtr counter(text);
+ ScriptObjectRef counter(text);
::StoryPageElementType btype = static_cast<::StoryPageElementType>(type);
@@ -109,7 +109,7 @@ static inline bool StoryPageElementTypeRequiresText(StoryPageElementType type)
/* static */ bool ScriptStoryPage::UpdateElement(StoryPageElementID story_page_element_id, SQInteger reference, Text *text)
{
- CCountedPtr counter(text);
+ ScriptObjectRef counter(text);
EnforceDeityMode(false);
EnforcePrecondition(false, IsValidStoryPageElement(story_page_element_id));
@@ -165,7 +165,7 @@ static inline bool StoryPageElementTypeRequiresText(StoryPageElementType type)
/* static */ bool ScriptStoryPage::SetTitle(StoryPageID story_page_id, Text *title)
{
- CCountedPtr counter(title);
+ ScriptObjectRef counter(title);
EnforcePrecondition(false, IsValidStoryPage(story_page_id));
EnforceDeityMode(false);
diff --git a/src/script/api/script_town.cpp b/src/script/api/script_town.cpp
index 3a4e302667..7c601e3884 100644
--- a/src/script/api/script_town.cpp
+++ b/src/script/api/script_town.cpp
@@ -42,7 +42,7 @@
/* static */ bool ScriptTown::SetName(TownID town_id, Text *name)
{
- CCountedPtr counter(name);
+ ScriptObjectRef counter(name);
EnforceDeityMode(false);
EnforcePrecondition(false, IsValidTown(town_id));
@@ -57,7 +57,7 @@
/* static */ bool ScriptTown::SetText(TownID town_id, Text *text)
{
- CCountedPtr counter(text);
+ ScriptObjectRef counter(text);
EnforceDeityMode(false);
EnforcePrecondition(false, IsValidTown(town_id));
@@ -283,7 +283,7 @@
/* static */ bool ScriptTown::FoundTown(TileIndex tile, TownSize size, bool city, RoadLayout layout, Text *name)
{
- CCountedPtr counter(name);
+ ScriptObjectRef counter(name);
EnforceDeityOrCompanyModeValid(false);
EnforcePrecondition(false, ScriptCompanyMode::IsDeity() || _settings_game.economy.found_town != TF_FORBIDDEN);
diff --git a/src/script/api/script_vehicle.cpp b/src/script/api/script_vehicle.cpp
index 35a6d74dda..c73ddee05c 100644
--- a/src/script/api/script_vehicle.cpp
+++ b/src/script/api/script_vehicle.cpp
@@ -247,7 +247,7 @@
/* static */ bool ScriptVehicle::SetName(VehicleID vehicle_id, Text *name)
{
- CCountedPtr counter(name);
+ ScriptObjectRef counter(name);
EnforceCompanyModeValid(false);
EnforcePrecondition(false, IsPrimaryVehicle(vehicle_id));
diff --git a/src/script/script_info.hpp b/src/script/script_info.hpp
index 90a04d13d8..9c01bca671 100644
--- a/src/script/script_info.hpp
+++ b/src/script/script_info.hpp
@@ -11,8 +11,8 @@
#define SCRIPT_INFO_HPP
#include
-#include "../misc/countedptr.hpp"
+#include "script_object.hpp"
#include "script_config.hpp"
/** The maximum number of operations for saving or loading the data of a script. */