Skip to content

Commit 6bd82df

Browse files
authored
Merge pull request #299 from Hoikas/key_helpers
Add convert helper for `plKey::getObj()`.
2 parents 7faafff + 835bcda commit 6bd82df

7 files changed

Lines changed: 48 additions & 26 deletions

File tree

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
cmake_minimum_required(VERSION 3.12)
22
project(libhsplasma)
33

4-
set(CMAKE_CXX_STANDARD 14)
4+
set(CMAKE_CXX_STANDARD 17)
55
set(CMAKE_CXX_STANDARD_REQUIRED ON)
66
set(CMAKE_CXX_EXTENSIONS OFF)
77
set(CMAKE_CXX_VISIBILITY_PRESET hidden)

Tools/src/Prp2Obj.cpp

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ int main(int argc, char* argv[])
116116
try {
117117
std::vector<plKey> MObjs = rm.getKeys(page->getLocation(), kGMaterial);
118118
for (size_t i = 0; i < MObjs.size(); i++) {
119-
hsGMaterial* mat = hsGMaterial::Convert(rm.getObject(MObjs[i]));
119+
hsGMaterial* mat = rm.getObject<hsGMaterial>(MObjs[i]);
120120
WriteMat(mat, &OS);
121121
}
122122
} catch (const hsException& e) {
@@ -138,7 +138,7 @@ int main(int argc, char* argv[])
138138
for (size_t i = 0; i < SObjs.size(); i++) {
139139
auto obj_f = std::find(objects.begin(), objects.end(), SObjs[i]->getName());
140140
if (obj_f != objects.end() || objects.size() == 0) {
141-
plSceneObject* obj = plSceneObject::Convert(rm.getObject(SObjs[i]));
141+
plSceneObject* obj = rm.getObject<plSceneObject>(SObjs[i]);
142142
if (obj->getDrawInterface().Exists())
143143
WriteObj(obj, &OS, objects.empty());
144144
nObjects++;
@@ -163,17 +163,17 @@ static void WriteObj(plSceneObject* obj, hsStream* S, bool doXform)
163163
plDebug::Warning("Cannot get draw interface for {}", obj->getKey()->getName());
164164
return;
165165
}
166-
plDrawInterface* draw = plDrawInterface::Convert(obj->getDrawInterface()->getObj());
166+
plDrawInterface* draw = obj->getDrawInterface()->getObj<plDrawInterface>();
167167
plCoordinateInterface* coord = nullptr;
168168
if (obj->getCoordInterface().Exists())
169-
coord = plCoordinateInterface::Convert(obj->getCoordInterface()->getObj());
169+
coord = obj->getCoordInterface()->getObj<plCoordinateInterface>();
170170

171171
S->writeStr(ST::format("\ng {}\n", obj->getKey()->getName()));
172172
for (size_t i=0; i<draw->getNumDrawables(); i++) {
173173
if (draw->getDrawableKey(i) == -1)
174174
continue;
175175

176-
plDrawableSpans* span = plDrawableSpans::Convert(draw->getDrawable(i)->getObj());
176+
plDrawableSpans* span = draw->getDrawable(i)->getObj<plDrawableSpans>();
177177
plDISpanIndex di = span->getDIIndex(draw->getDrawableKey(i));
178178
if ((di.fFlags & plDISpanIndex::kMatrixOnly) != 0)
179179
continue;
@@ -187,11 +187,11 @@ static void WriteObj(plSceneObject* obj, hsStream* S, bool doXform)
187187
hsMatrix44 uvwXform;
188188
plKey matKey = span->getMaterials()[ice->getMaterialIdx()];
189189
if (matKey.Exists()) {
190-
hsGMaterial* mat = hsGMaterial::Convert(matKey->getObj(), false);
190+
hsGMaterial* mat = matKey->getObj<hsGMaterial>(false);
191191
if (mat && mat->getLayers().size() > 0) {
192-
plLayerInterface* lay = plLayerInterface::Convert(mat->getLayers()[0]->getObj(), false);
192+
plLayerInterface* lay = mat->getLayers()[0]->getObj<plLayerInterface>(false);
193193
while (lay && lay->getUnderLay().Exists())
194-
lay = plLayerInterface::Convert(lay->getUnderLay()->getObj(), false);
194+
lay = lay->getUnderLay()->getObj<plLayerInterface>(false);
195195
uvwSrc = lay->getUVWSrc();
196196
uvwXform = lay->getTransform();
197197
}
@@ -263,9 +263,9 @@ static void WriteMat(hsGMaterial* mat, hsStream* S)
263263

264264
// Obj doesn't support multiple textures, so we just get the texture
265265
// on the base of the first layer in each material...
266-
plLayerInterface* lay = plLayerInterface::Convert(mat->getLayers()[0]->getObj(), false);
266+
plLayerInterface* lay = mat->getLayers()[0]->getObj<plLayerInterface>(false);
267267
while (lay && lay->getUnderLay().Exists())
268-
lay = plLayerInterface::Convert(lay->getUnderLay()->getObj(), false);
268+
lay = lay->getUnderLay()->getObj<plLayerInterface>(false);
269269
if (lay == nullptr) {
270270
plDebug::Warning("Cannot get layer for {}", mat->getKey()->getName());
271271
return;

core/PRP/KeyedObject/plKey.h

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include <cstddef>
2222
#include <functional>
2323
#include <list>
24+
#include <type_traits>
2425

2526
#define GET_KEY_OBJECT(key, classname) \
2627
((key.Exists() && key.isLoaded()) \
@@ -138,10 +139,32 @@ class HSPLASMA_EXPORT plKeyData
138139
const plUoid& getUoid() const { return fUoid; }
139140

140141
/** Returns a pointer to the object referenced by this key */
141-
class hsKeyedObject* getObj() { return fObjPtr; }
142+
template<typename _KeyedObjT = class hsKeyedObject>
143+
_KeyedObjT* getObj(bool requireValid = true)
144+
{
145+
static_assert(
146+
std::is_base_of_v<class hsKeyedObject, _KeyedObjT>,
147+
"Cannot convert to a type that does not derive from hsKeyedObject"
148+
);
149+
// If they just want the KeyedObject, avoid calling all the convert functions.
150+
if constexpr (std::is_same_v<class hsKeyedObject, _KeyedObjT>)
151+
return fObjPtr;
152+
return _KeyedObjT::Convert(fObjPtr, requireValid);
153+
}
142154

143155
/** Returns a const pointer to the object referenced by this key */
144-
const class hsKeyedObject* getObj() const { return fObjPtr; }
156+
template<typename _KeyedObjT = class hsKeyedObject>
157+
const _KeyedObjT* getObj(bool requireValid = true) const
158+
{
159+
static_assert(
160+
std::is_base_of_v<class hsKeyedObject, _KeyedObjT>,
161+
"Cannot convert to a type that does not derive from hsKeyedObject"
162+
);
163+
// If they just want the KeyedObject, avoid calling all the convert functions.
164+
if constexpr (std::is_same_v<class hsKeyedObject, _KeyedObjT>)
165+
return fObjPtr;
166+
return _KeyedObjT::Convert(fObjPtr, requireValid);
167+
}
145168

146169
/** Sets the object referenced by this key. */
147170
void setObj(class hsKeyedObject* obj);

core/PRP/Object/plSceneObject.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ void plSceneObject::delModifier(size_t idx)
154154
if (key->getObj()->isStub()) {
155155
plDebug::Warning("WARNING: Removing STUB modifier from SceneObject");
156156
} else {
157-
plModifier* mod = plModifier::Convert(key->getObj());
157+
plModifier* mod = key->getObj<plModifier>();
158158
mod->removeTarget(getKey());
159159
}
160160
}
@@ -169,7 +169,7 @@ void plSceneObject::clearModifiers()
169169
plDebug::Warning("WARNING: Removing STUB modifier from SceneObject");
170170
continue;
171171
}
172-
plModifier* mod = plModifier::Convert(key->getObj(), false);
172+
plModifier* mod = key->getObj<plModifier>(false);
173173
mod->removeTarget(getKey());
174174
}
175175
}

core/PRP/Surface/plLayerInterface.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ plKey plLayerInterface::getBottomOfStack() const
5757
// What use is returning an unloaded bottom layer?
5858
break;
5959
}
60-
const plLayerInterface* underLay = plLayerInterface::Convert(bottom->fUnderLay->getObj(), false);
60+
const plLayerInterface* underLay = bottom->fUnderLay->getObj<plLayerInterface>(false);
6161
if (underLay == nullptr)
6262
break;
6363
bottom = underLay;

core/ResManager/plResManager.cpp

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -145,14 +145,6 @@ void plResManager::PrcWriteKey(pfPrcHelper* prc, hsKeyedObject* ko)
145145
PrcWriteKey(prc, ko->getKey());
146146
}
147147

148-
hsKeyedObject* plResManager::getObject(const plKey& key)
149-
{
150-
plKey fk = keys.findKey(key);
151-
if (!fk.Exists())
152-
return nullptr;
153-
return fk->getObj();
154-
}
155-
156148
plPageInfo* plResManager::ReadPage(const ST::string& filename, bool stub)
157149
{
158150
bool packed = true;
@@ -744,7 +736,7 @@ plSceneNode* plResManager::getSceneNode(const plLocation& loc)
744736
std::vector<plKey> kList = keys.getKeys(loc, kSceneNode);
745737
if (kList.empty())
746738
return nullptr;
747-
return plSceneNode::Convert(kList[0]->getObj());
739+
return kList[0]->getObj<plSceneNode>();
748740
}
749741

750742
std::vector<plLocation> plResManager::getLocations()

core/ResManager/plResManager.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,14 @@ class HSPLASMA_EXPORT plResManager
177177
* the key's internal object pointer.
178178
* \sa plKeyData::getObj()
179179
*/
180-
class hsKeyedObject* getObject(const plKey& key);
180+
template<typename _KeyedObjectT = class hsKeyedObject>
181+
_KeyedObjectT* getObject(const plKey& key, bool requireValid = true)
182+
{
183+
plKey fk = keys.findKey(key);
184+
if (!fk.Exists())
185+
return nullptr;
186+
return fk->getObj<_KeyedObjectT>(requireValid);
187+
}
181188

182189
/** Returns the total number of keys registered for the specified plLocation */
183190
unsigned int countKeys(const plLocation& loc) { return keys.countKeys(loc); }

0 commit comments

Comments
 (0)