From 8a0f012a5443eb2b559afdda1d40b0698acf76ca Mon Sep 17 00:00:00 2001
From: Tim Felgentreff <timfelgentreff@gmail.com>
Date: Wed, 27 Apr 2022 21:04:08 +0200
Subject: [PATCH] share mngs

---
 src/include/video.h   | 15 +++++++++++----
 src/tolua/video.pkg   |  5 +++--
 src/unit/unittype.cpp |  7 +++----
 src/video/mng.cpp     | 29 ++++++++++++++++++++++++++---
 4 files changed, 43 insertions(+), 13 deletions(-)

diff --git a/src/include/video.h b/src/include/video.h
index 132ee2bf0..ba200f145 100644
--- a/src/include/video.h
+++ b/src/include/video.h
@@ -234,10 +234,15 @@ public:
 
 class Mng : public gcn::Image
 {
-public:
 	Mng();
 	~Mng();
-	bool Load(const std::string &name);
+
+	uint32_t refcnt = 0;
+
+public:
+	static Mng *New(const std::string &name);
+	static void Free(Mng *mng);
+	bool Load();
 	void Reset();
 	void Draw(int x, int y);
 
@@ -260,10 +265,12 @@ public:
 /// empty class for lua scripts
 class Mng : public gcn::Image
 {
-public:
 	Mng() {};
 	~Mng() {};
-	bool Load(const std::string &name) { return false; };
+public:
+	Mng *New(const std::string &name) { return NULL; }
+	static void Free(Mng *mng) {};
+	bool Load() { return false; };
 	void Reset() {};
 	void Draw(int x, int y) {};
 
diff --git a/src/tolua/video.pkg b/src/tolua/video.pkg
index ed3e26d9a..3ffc8ce5b 100644
--- a/src/tolua/video.pkg
+++ b/src/tolua/video.pkg
@@ -58,8 +58,9 @@ unsigned int SetColorCycleSpeed(unsigned int speed);
 class Mng
 {
 public:
-        Mng();
-        bool Load(const std::string name);
+		static Mng *New(const std::string name);
+		static void Free(Mng *mng);
+        bool Load();
         void Draw(int x, int y);
         void Reset();
 }
diff --git a/src/unit/unittype.cpp b/src/unit/unittype.cpp
index c2eea6277..88ca0b736 100644
--- a/src/unit/unittype.cpp
+++ b/src/unit/unittype.cpp
@@ -593,8 +593,7 @@ CUnitType::~CUnitType()
 #ifdef USE_MNG
 	if (this->Portrait.Num) {
 		for (int j = 0; j < this->Portrait.Num; ++j) {
-			delete this->Portrait.Mngs[j];
-			// delete[] this->Portrait.Files[j];
+			Mng::Free(this->Portrait.Mngs[j]);
 		}
 		delete[] this->Portrait.Mngs;
 		delete[] this->Portrait.Files;
@@ -1042,8 +1041,8 @@ void LoadUnitTypeSprite(CUnitType &type)
 #ifdef USE_MNG
 	if (type.Portrait.Num) {
 		for (int i = 0; i < type.Portrait.Num; ++i) {
-			type.Portrait.Mngs[i] = new Mng;
-			type.Portrait.Mngs[i]->Load(type.Portrait.Files[i]);
+			type.Portrait.Mngs[i] = Mng::New(type.Portrait.Files[i]);
+			type.Portrait.Mngs[i]->Load();
 		}
 		// FIXME: should be configurable
 		type.Portrait.CurrMng = 0;
diff --git a/src/video/mng.cpp b/src/video/mng.cpp
index e517029f0..4079e1ac7 100644
--- a/src/video/mng.cpp
+++ b/src/video/mng.cpp
@@ -189,7 +189,6 @@ Mng::Mng() :
 
 Mng::~Mng()
 {
-	//	delete[] name;
 	if (handle) {
 		mng_cleanup(&handle);
 	}
@@ -216,14 +215,38 @@ void Mng::Draw(int x, int y)
 	SDL_BlitSurface(surface, NULL, TheScreen, &rect);
 }
 
+static std::map<std::string, Mng *> MngCache;
+
+Mng *Mng::New(const std::string &name)
+{
+	const std::string file = LibraryFileName(name.c_str());
+	Mng *mng = MngCache[file];
+	if (mng == NULL) {
+		mng = new Mng();
+		mng->name = LibraryFileName(name.c_str());
+		Assert(mng);
+	} else {
+		mng->refcnt++;
+	}
+	return mng;
+}
+
+void Mng::Free(Mng *mng)
+{
+	mng->refcnt--;
+	if (mng->refcnt == 0) {
+		MngCache.erase(mng->name);
+		delete mng;
+	}
+}
+
 /**
 **  Load a MNG
 **
 **  @param name  Name of the MNG file
 */
-bool Mng::Load(const std::string &name)
+bool Mng::Load()
 {
-	this->name = LibraryFileName(name.c_str());
 	handle = mng_initialize(this, my_alloc, my_free, MNG_NULL);
 	if (handle == MNG_NULL) {
 		return false;