Skip to content

Commit 2062c80

Browse files
sfan5nerzhul
authored andcommittedMay 5, 2020
Allow ObjDefManager instances to be cloned
1 parent d1c6cc7 commit 2062c80

13 files changed

+370
-5
lines changed
 

Diff for: ‎src/mapgen/mg_biome.cpp

+45
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,16 @@ void BiomeManager::clear()
9292
}
9393

9494

95+
BiomeManager *BiomeManager::clone() const
96+
{
97+
auto mgr = new BiomeManager();
98+
assert(mgr);
99+
ObjDefManager::cloneTo(mgr);
100+
mgr->m_server = m_server;
101+
return mgr;
102+
}
103+
104+
95105
// For BiomeGen type 'BiomeGenOriginal'
96106
float BiomeManager::getHeatAtPosOriginal(v3s16 pos, NoiseParams &np_heat,
97107
NoiseParams &np_heat_blend, u64 seed)
@@ -321,6 +331,41 @@ Biome *BiomeGenOriginal::calcBiomeFromNoise(float heat, float humidity, v3s16 po
321331

322332
////////////////////////////////////////////////////////////////////////////////
323333

334+
ObjDef *Biome::clone() const
335+
{
336+
auto obj = new Biome();
337+
ObjDef::cloneTo(obj);
338+
NodeResolver::cloneTo(obj);
339+
340+
obj->flags = flags;
341+
342+
obj->c_top = c_top;
343+
obj->c_filler = c_filler;
344+
obj->c_stone = c_stone;
345+
obj->c_water_top = c_water_top;
346+
obj->c_water = c_water;
347+
obj->c_river_water = c_river_water;
348+
obj->c_riverbed = c_riverbed;
349+
obj->c_dust = c_dust;
350+
obj->c_cave_liquid = c_cave_liquid;
351+
obj->c_dungeon = c_dungeon;
352+
obj->c_dungeon_alt = c_dungeon_alt;
353+
obj->c_dungeon_stair = c_dungeon_stair;
354+
355+
obj->depth_top = depth_top;
356+
obj->depth_filler = depth_filler;
357+
obj->depth_water_top = depth_water_top;
358+
obj->depth_riverbed = depth_riverbed;
359+
360+
obj->min_pos = min_pos;
361+
obj->max_pos = max_pos;
362+
obj->heat_point = heat_point;
363+
obj->humidity_point = humidity_point;
364+
obj->vertical_blend = vertical_blend;
365+
366+
return obj;
367+
}
368+
324369
void Biome::resolveNodeNames()
325370
{
326371
getIdFromNrBacklog(&c_top, "mapgen_stone", CONTENT_AIR, false);

Diff for: ‎src/mapgen/mg_biome.h

+6
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ enum BiomeType {
4242

4343
class Biome : public ObjDef, public NodeResolver {
4444
public:
45+
ObjDef *clone() const;
46+
4547
u32 flags;
4648

4749
content_t c_top;
@@ -191,6 +193,8 @@ class BiomeManager : public ObjDefManager {
191193
BiomeManager(Server *server);
192194
virtual ~BiomeManager() = default;
193195

196+
BiomeManager *clone() const;
197+
194198
const char *getObjectTitle() const
195199
{
196200
return "biome";
@@ -232,6 +236,8 @@ class BiomeManager : public ObjDefManager {
232236
Biome *getBiomeFromNoiseOriginal(float heat, float humidity, v3s16 pos);
233237

234238
private:
239+
BiomeManager() {};
240+
235241
Server *m_server;
236242

237243
};

Diff for: ‎src/mapgen/mg_decoration.cpp

+55
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,13 @@ size_t DecorationManager::placeAllDecos(Mapgen *mg, u32 blockseed,
6767
return nplaced;
6868
}
6969

70+
DecorationManager *DecorationManager::clone() const
71+
{
72+
auto mgr = new DecorationManager();
73+
ObjDefManager::cloneTo(mgr);
74+
return mgr;
75+
}
76+
7077

7178
///////////////////////////////////////////////////////////////////////////////
7279

@@ -269,9 +276,42 @@ size_t Decoration::placeDeco(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nmax)
269276
}
270277

271278

279+
void Decoration::cloneTo(Decoration *def) const
280+
{
281+
ObjDef::cloneTo(def);
282+
def->flags = flags;
283+
def->mapseed = mapseed;
284+
def->c_place_on = c_place_on;
285+
def->sidelen = sidelen;
286+
def->y_min = y_min;
287+
def->y_max = y_max;
288+
def->fill_ratio = fill_ratio;
289+
def->np = np;
290+
def->c_spawnby = c_spawnby;
291+
def->nspawnby = nspawnby;
292+
def->place_offset_y = place_offset_y;
293+
def->biomes = biomes;
294+
}
295+
296+
272297
///////////////////////////////////////////////////////////////////////////////
273298

274299

300+
ObjDef *DecoSimple::clone() const
301+
{
302+
auto def = new DecoSimple();
303+
Decoration::cloneTo(def);
304+
305+
def->c_decos = c_decos;
306+
def->deco_height = deco_height;
307+
def->deco_height_max = deco_height_max;
308+
def->deco_param2 = deco_param2;
309+
def->deco_param2_max = deco_param2_max;
310+
311+
return def;
312+
}
313+
314+
275315
void DecoSimple::resolveNodeNames()
276316
{
277317
Decoration::resolveNodeNames();
@@ -351,6 +391,21 @@ size_t DecoSimple::generate(MMVManip *vm, PcgRandom *pr, v3s16 p, bool ceiling)
351391
///////////////////////////////////////////////////////////////////////////////
352392

353393

394+
ObjDef *DecoSchematic::clone() const
395+
{
396+
auto def = new DecoSchematic();
397+
Decoration::cloneTo(def);
398+
NodeResolver::cloneTo(def);
399+
400+
def->rotation = rotation;
401+
/* FIXME: This is not ideal, we only have a pointer to the schematic despite
402+
* not owning it. Optimally this would be a handle. */
403+
def->schematic = schematic; // not cloned
404+
405+
return def;
406+
}
407+
408+
354409
size_t DecoSchematic::generate(MMVManip *vm, PcgRandom *pr, v3s16 p, bool ceiling)
355410
{
356411
// Schematic could have been unloaded but not the decoration

Diff for: ‎src/mapgen/mg_decoration.h

+12
Original file line numberDiff line numberDiff line change
@@ -73,11 +73,16 @@ class Decoration : public ObjDef, public NodeResolver {
7373
s16 place_offset_y = 0;
7474

7575
std::unordered_set<u8> biomes;
76+
77+
protected:
78+
void cloneTo(Decoration *def) const;
7679
};
7780

7881

7982
class DecoSimple : public Decoration {
8083
public:
84+
ObjDef *clone() const;
85+
8186
virtual void resolveNodeNames();
8287
virtual size_t generate(MMVManip *vm, PcgRandom *pr, v3s16 p, bool ceiling);
8388

@@ -91,6 +96,8 @@ class DecoSimple : public Decoration {
9196

9297
class DecoSchematic : public Decoration {
9398
public:
99+
ObjDef *clone() const;
100+
94101
DecoSchematic() = default;
95102

96103
virtual size_t generate(MMVManip *vm, PcgRandom *pr, v3s16 p, bool ceiling);
@@ -113,6 +120,8 @@ class DecorationManager : public ObjDefManager {
113120
DecorationManager(IGameDef *gamedef);
114121
virtual ~DecorationManager() = default;
115122

123+
DecorationManager *clone() const;
124+
116125
const char *getObjectTitle() const
117126
{
118127
return "decoration";
@@ -133,4 +142,7 @@ class DecorationManager : public ObjDefManager {
133142
}
134143

135144
size_t placeAllDecos(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nmax);
145+
146+
private:
147+
DecorationManager() {};
136148
};

Diff for: ‎src/mapgen/mg_ore.cpp

+97
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,14 @@ void OreManager::clear()
7272
}
7373

7474

75+
OreManager *OreManager::clone() const
76+
{
77+
auto mgr = new OreManager();
78+
ObjDefManager::cloneTo(mgr);
79+
return mgr;
80+
}
81+
82+
7583
///////////////////////////////////////////////////////////////////////////////
7684

7785

@@ -106,9 +114,37 @@ size_t Ore::placeOre(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nmax)
106114
}
107115

108116

117+
void Ore::cloneTo(Ore *def) const
118+
{
119+
ObjDef::cloneTo(def);
120+
NodeResolver::cloneTo(def);
121+
def->c_ore = c_ore;
122+
def->c_wherein = c_wherein;
123+
def->clust_scarcity = clust_scarcity;
124+
def->clust_num_ores = clust_num_ores;
125+
def->clust_size = clust_size;
126+
def->y_min = y_min;
127+
def->y_max = y_max;
128+
def->ore_param2 = ore_param2;
129+
def->flags = flags;
130+
def->nthresh = nthresh;
131+
def->np = np;
132+
def->noise = nullptr; // cannot be shared! so created on demand
133+
def->biomes = biomes;
134+
}
135+
136+
109137
///////////////////////////////////////////////////////////////////////////////
110138

111139

140+
ObjDef *OreScatter::clone() const
141+
{
142+
auto def = new OreScatter();
143+
Ore::cloneTo(def);
144+
return def;
145+
}
146+
147+
112148
void OreScatter::generate(MMVManip *vm, int mapseed, u32 blockseed,
113149
v3s16 nmin, v3s16 nmax, u8 *biomemap)
114150
{
@@ -158,6 +194,19 @@ void OreScatter::generate(MMVManip *vm, int mapseed, u32 blockseed,
158194
///////////////////////////////////////////////////////////////////////////////
159195

160196

197+
ObjDef *OreSheet::clone() const
198+
{
199+
auto def = new OreSheet();
200+
Ore::cloneTo(def);
201+
202+
def->column_height_max = column_height_max;
203+
def->column_height_min = column_height_min;
204+
def->column_midpoint_factor = column_midpoint_factor;
205+
206+
return def;
207+
}
208+
209+
161210
void OreSheet::generate(MMVManip *vm, int mapseed, u32 blockseed,
162211
v3s16 nmin, v3s16 nmax, u8 *biomemap)
163212
{
@@ -221,6 +270,20 @@ OrePuff::~OrePuff()
221270
}
222271

223272

273+
ObjDef *OrePuff::clone() const
274+
{
275+
auto def = new OrePuff();
276+
Ore::cloneTo(def);
277+
278+
def->np_puff_top = np_puff_top;
279+
def->np_puff_bottom = np_puff_bottom;
280+
def->noise_puff_top = nullptr; // cannot be shared, on-demand
281+
def->noise_puff_bottom = nullptr;
282+
283+
return def;
284+
}
285+
286+
224287
void OrePuff::generate(MMVManip *vm, int mapseed, u32 blockseed,
225288
v3s16 nmin, v3s16 nmax, u8 *biomemap)
226289
{
@@ -294,6 +357,14 @@ void OrePuff::generate(MMVManip *vm, int mapseed, u32 blockseed,
294357
///////////////////////////////////////////////////////////////////////////////
295358

296359

360+
ObjDef *OreBlob::clone() const
361+
{
362+
auto def = new OreBlob();
363+
Ore::cloneTo(def);
364+
return def;
365+
}
366+
367+
297368
void OreBlob::generate(MMVManip *vm, int mapseed, u32 blockseed,
298369
v3s16 nmin, v3s16 nmax, u8 *biomemap)
299370
{
@@ -366,6 +437,19 @@ OreVein::~OreVein()
366437
}
367438

368439

440+
ObjDef *OreVein::clone() const
441+
{
442+
auto def = new OreVein();
443+
Ore::cloneTo(def);
444+
445+
def->random_factor = random_factor;
446+
def->noise2 = nullptr; // cannot be shared, on-demand
447+
def->sizey_prev = sizey_prev;
448+
449+
return def;
450+
}
451+
452+
369453
void OreVein::generate(MMVManip *vm, int mapseed, u32 blockseed,
370454
v3s16 nmin, v3s16 nmax, u8 *biomemap)
371455
{
@@ -434,6 +518,19 @@ OreStratum::~OreStratum()
434518
}
435519

436520

521+
ObjDef *OreStratum::clone() const
522+
{
523+
auto def = new OreStratum();
524+
Ore::cloneTo(def);
525+
526+
def->np_stratum_thickness = np_stratum_thickness;
527+
def->noise_stratum_thickness = nullptr; // cannot be shared, on-demand
528+
def->stratum_thickness = stratum_thickness;
529+
530+
return def;
531+
}
532+
533+
437534
void OreStratum::generate(MMVManip *vm, int mapseed, u32 blockseed,
438535
v3s16 nmin, v3s16 nmax, u8 *biomemap)
439536
{

Diff for: ‎src/mapgen/mg_ore.h

+20
Original file line numberDiff line numberDiff line change
@@ -74,12 +74,17 @@ class Ore : public ObjDef, public NodeResolver {
7474
size_t placeOre(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nmax);
7575
virtual void generate(MMVManip *vm, int mapseed, u32 blockseed,
7676
v3s16 nmin, v3s16 nmax, u8 *biomemap) = 0;
77+
78+
protected:
79+
void cloneTo(Ore *def) const;
7780
};
7881

7982
class OreScatter : public Ore {
8083
public:
8184
static const bool NEEDS_NOISE = false;
8285

86+
ObjDef *clone() const;
87+
8388
virtual void generate(MMVManip *vm, int mapseed, u32 blockseed,
8489
v3s16 nmin, v3s16 nmax, u8 *biomemap);
8590
};
@@ -88,6 +93,8 @@ class OreSheet : public Ore {
8893
public:
8994
static const bool NEEDS_NOISE = true;
9095

96+
ObjDef *clone() const;
97+
9198
u16 column_height_min;
9299
u16 column_height_max;
93100
float column_midpoint_factor;
@@ -100,6 +107,8 @@ class OrePuff : public Ore {
100107
public:
101108
static const bool NEEDS_NOISE = true;
102109

110+
ObjDef *clone() const;
111+
103112
NoiseParams np_puff_top;
104113
NoiseParams np_puff_bottom;
105114
Noise *noise_puff_top = nullptr;
@@ -116,6 +125,8 @@ class OreBlob : public Ore {
116125
public:
117126
static const bool NEEDS_NOISE = true;
118127

128+
ObjDef *clone() const;
129+
119130
virtual void generate(MMVManip *vm, int mapseed, u32 blockseed,
120131
v3s16 nmin, v3s16 nmax, u8 *biomemap);
121132
};
@@ -124,6 +135,8 @@ class OreVein : public Ore {
124135
public:
125136
static const bool NEEDS_NOISE = true;
126137

138+
ObjDef *clone() const;
139+
127140
float random_factor;
128141
Noise *noise2 = nullptr;
129142
int sizey_prev = 0;
@@ -139,6 +152,8 @@ class OreStratum : public Ore {
139152
public:
140153
static const bool NEEDS_NOISE = false;
141154

155+
ObjDef *clone() const;
156+
142157
NoiseParams np_stratum_thickness;
143158
Noise *noise_stratum_thickness = nullptr;
144159
u16 stratum_thickness;
@@ -155,6 +170,8 @@ class OreManager : public ObjDefManager {
155170
OreManager(IGameDef *gamedef);
156171
virtual ~OreManager() = default;
157172

173+
OreManager *clone() const;
174+
158175
const char *getObjectTitle() const
159176
{
160177
return "ore";
@@ -183,4 +200,7 @@ class OreManager : public ObjDefManager {
183200
void clear();
184201

185202
size_t placeAllOres(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nmax);
203+
204+
private:
205+
OreManager() {};
186206
};

Diff for: ‎src/mapgen/mg_schematic.cpp

+7-1
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,11 @@ Schematic::~Schematic()
7777
delete []slice_probs;
7878
}
7979

80+
ObjDef *Schematic::clone() const
81+
{
82+
FATAL_ERROR("not cloneable");
83+
}
84+
8085

8186
void Schematic::resolveNodeNames()
8287
{
@@ -93,6 +98,7 @@ void Schematic::resolveNodeNames()
9398

9499
void Schematic::blitToVManip(MMVManip *vm, v3s16 p, Rotation rot, bool force_place)
95100
{
101+
assert(schemdata && slice_probs);
96102
sanity_check(m_ndef != NULL);
97103

98104
int xstride = 1;
@@ -177,7 +183,7 @@ bool Schematic::placeOnVManip(MMVManip *vm, v3s16 p, u32 flags,
177183
Rotation rot, bool force_place)
178184
{
179185
assert(vm != NULL);
180-
assert(schemdata != NULL);
186+
assert(schemdata && slice_probs);
181187
sanity_check(m_ndef != NULL);
182188

183189
//// Determine effective rotation and effective schematic dimensions

Diff for: ‎src/mapgen/mg_schematic.h

+4
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,8 @@ class Schematic : public ObjDef, public NodeResolver {
9595
Schematic();
9696
virtual ~Schematic();
9797

98+
ObjDef *clone() const;
99+
98100
virtual void resolveNodeNames();
99101

100102
bool loadSchematicFromFile(const std::string &filename,
@@ -128,6 +130,8 @@ class SchematicManager : public ObjDefManager {
128130
SchematicManager(Server *server);
129131
virtual ~SchematicManager() = default;
130132

133+
// not cloneable
134+
131135
virtual void clear();
132136

133137
const char *getObjectTitle() const

Diff for: ‎src/nodedef.cpp

+12
Original file line numberDiff line numberDiff line change
@@ -1572,6 +1572,18 @@ NodeResolver::~NodeResolver()
15721572
}
15731573

15741574

1575+
void NodeResolver::cloneTo(NodeResolver *res) const
1576+
{
1577+
FATAL_ERROR_IF(!m_resolve_done, "NodeResolver can only be cloned"
1578+
" after resolving has completed");
1579+
/* We don't actually do anything significant. Since the node resolving has
1580+
* already completed, the class that called us will already have the
1581+
* resolved IDs in its data structures (which it copies on its own) */
1582+
res->m_ndef = m_ndef;
1583+
res->m_resolve_done = true;
1584+
}
1585+
1586+
15751587
void NodeResolver::nodeResolveInternal()
15761588
{
15771589
m_nodenames_idx = 0;

Diff for: ‎src/nodedef.h

+3
Original file line numberDiff line numberDiff line change
@@ -739,6 +739,9 @@ class NodeResolver {
739739
virtual ~NodeResolver();
740740
virtual void resolveNodeNames() = 0;
741741

742+
// required because this class is used as mixin for ObjDef
743+
void cloneTo(NodeResolver *res) const;
744+
742745
bool getIdFromNrBacklog(content_t *result_out,
743746
const std::string &node_alt, content_t c_fallback,
744747
bool error_on_fallback = true);

Diff for: ‎src/objdef.cpp

+19
Original file line numberDiff line numberDiff line change
@@ -182,3 +182,22 @@ bool ObjDefManager::decodeHandle(ObjDefHandle handle, u32 *index,
182182
*uid = get_bits(handle, 24, 7);
183183
return true;
184184
}
185+
186+
// Cloning
187+
188+
void ObjDef::cloneTo(ObjDef *def) const
189+
{
190+
def->index = index;
191+
def->uid = uid;
192+
def->handle = handle;
193+
def->name = name;
194+
}
195+
196+
void ObjDefManager::cloneTo(ObjDefManager *mgr) const
197+
{
198+
mgr->m_ndef = m_ndef;
199+
mgr->m_objects.reserve(m_objects.size());
200+
for (const auto &obj : m_objects)
201+
mgr->m_objects.push_back(obj->clone());
202+
mgr->m_objtype = m_objtype;
203+
}

Diff for: ‎src/objdef.h

+18
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,22 @@ class ObjDef {
4545
public:
4646
virtual ~ObjDef() = default;
4747

48+
// Only implemented by child classes (leafs in class hierarchy)
49+
// Should create new object of its own type, call cloneTo() of parent class
50+
// and copy its own instance variables over
51+
virtual ObjDef *clone() const = 0;
52+
4853
u32 index;
4954
u32 uid;
5055
ObjDefHandle handle;
5156
std::string name;
57+
58+
protected:
59+
// Only implemented by classes that have children themselves
60+
// by copying the defintion and changing that argument type (!!!)
61+
// Should defer to parent class cloneTo() if applicable and then copy
62+
// over its own properties
63+
void cloneTo(ObjDef *def) const;
5264
};
5365

5466
// WARNING: Ownership of ObjDefs is transferred to the ObjDefManager it is
@@ -60,6 +72,8 @@ class ObjDefManager {
6072
virtual ~ObjDefManager();
6173
DISABLE_CLASS_COPY(ObjDefManager);
6274

75+
// T *clone() const; // implemented in child class with correct type
76+
6377
virtual const char *getObjectTitle() const { return "ObjDef"; }
6478

6579
virtual void clear();
@@ -88,6 +102,10 @@ class ObjDefManager {
88102
ObjDefType *type, u32 *uid);
89103

90104
protected:
105+
ObjDefManager() {};
106+
// Helper for child classes to implement clone()
107+
void cloneTo(ObjDefManager *mgr) const;
108+
91109
const NodeDefManager *m_ndef;
92110
std::vector<ObjDef *> m_objects;
93111
ObjDefType m_objtype;

Diff for: ‎src/unittest/test_objdef.cpp

+72-4
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ class TestObjDef : public TestBase
3232

3333
void testHandles();
3434
void testAddGetSetClear();
35+
void testClone();
3536
};
3637

3738
static TestObjDef g_test_instance;
@@ -40,10 +41,42 @@ void TestObjDef::runTests(IGameDef *gamedef)
4041
{
4142
TEST(testHandles);
4243
TEST(testAddGetSetClear);
44+
TEST(testClone);
4345
}
4446

4547
////////////////////////////////////////////////////////////////////////////////
4648

49+
/* Minimal implementation of ObjDef and ObjDefManager subclass */
50+
51+
class MyObjDef : public ObjDef
52+
{
53+
public:
54+
ObjDef *clone() const
55+
{
56+
auto def = new MyObjDef();
57+
ObjDef::cloneTo(def);
58+
def->testvalue = testvalue;
59+
return def;
60+
};
61+
62+
u32 testvalue;
63+
};
64+
65+
class MyObjDefManager : public ObjDefManager
66+
{
67+
public:
68+
MyObjDefManager(ObjDefType type) : ObjDefManager(NULL, type){};
69+
MyObjDefManager *clone() const
70+
{
71+
auto mgr = new MyObjDefManager();
72+
ObjDefManager::cloneTo(mgr);
73+
return mgr;
74+
};
75+
76+
protected:
77+
MyObjDefManager(){};
78+
};
79+
4780
void TestObjDef::testHandles()
4881
{
4982
u32 uid = 0;
@@ -69,25 +102,25 @@ void TestObjDef::testAddGetSetClear()
69102

70103
UASSERTEQ(ObjDefType, testmgr.getType(), OBJDEF_GENERIC);
71104

72-
obj0 = new ObjDef;
105+
obj0 = new MyObjDef;
73106
obj0->name = "foobar";
74107
hObj0 = testmgr.add(obj0);
75108
UASSERT(hObj0 != OBJDEF_INVALID_HANDLE);
76109
UASSERTEQ(u32, obj0->index, 0);
77110

78-
obj1 = new ObjDef;
111+
obj1 = new MyObjDef;
79112
obj1->name = "FooBaz";
80113
hObj1 = testmgr.add(obj1);
81114
UASSERT(hObj1 != OBJDEF_INVALID_HANDLE);
82115
UASSERTEQ(u32, obj1->index, 1);
83116

84-
obj2 = new ObjDef;
117+
obj2 = new MyObjDef;
85118
obj2->name = "asdf";
86119
hObj2 = testmgr.add(obj2);
87120
UASSERT(hObj2 != OBJDEF_INVALID_HANDLE);
88121
UASSERTEQ(u32, obj2->index, 2);
89122

90-
obj3 = new ObjDef;
123+
obj3 = new MyObjDef;
91124
obj3->name = "foobaz";
92125
hObj3 = testmgr.add(obj3);
93126
UASSERT(hObj3 == OBJDEF_INVALID_HANDLE);
@@ -104,3 +137,38 @@ void TestObjDef::testAddGetSetClear()
104137
testmgr.clear();
105138
UASSERTEQ(size_t, testmgr.getNumObjects(), 0);
106139
}
140+
141+
void TestObjDef::testClone()
142+
{
143+
MyObjDefManager testmgr(OBJDEF_GENERIC);
144+
ObjDefManager *mgrcopy;
145+
MyObjDef *obj, *temp2;
146+
ObjDef *temp1;
147+
ObjDefHandle hObj;
148+
149+
obj = new MyObjDef;
150+
obj->testvalue = 0xee00ff11;
151+
hObj = testmgr.add(obj);
152+
UASSERT(hObj != OBJDEF_INVALID_HANDLE);
153+
154+
mgrcopy = testmgr.clone();
155+
UASSERT(mgrcopy);
156+
UASSERTEQ(ObjDefType, mgrcopy->getType(), testmgr.getType());
157+
UASSERTEQ(size_t, mgrcopy->getNumObjects(), testmgr.getNumObjects());
158+
159+
// 1) check that the same handle is still valid on the copy
160+
temp1 = mgrcopy->get(hObj);
161+
UASSERT(temp1);
162+
UASSERT(temp1 == mgrcopy->getRaw(0));
163+
// 2) check that the copy has the correct C++ class
164+
temp2 = dynamic_cast<MyObjDef *>(temp1);
165+
UASSERT(temp2);
166+
// 3) check that it was correctly copied
167+
UASSERTEQ(u32, obj->testvalue, temp2->testvalue);
168+
// 4) check that it was copied AT ALL (not the same)
169+
UASSERT(obj != temp2);
170+
171+
testmgr.clear();
172+
mgrcopy->clear();
173+
delete mgrcopy;
174+
}

0 commit comments

Comments
 (0)
Please sign in to comment.