metaforce/Runtime/MkCastTo.py

206 lines
7.1 KiB
Python
Raw Permalink Normal View History

2017-01-14 19:07:01 -08:00
"Generates TCastTo source files for constexpr-enabled CEntity casts"
2021-06-07 12:29:18 -07:00
2017-01-14 19:07:01 -08:00
class Namespace:
def __init__(self, name):
self.name = name
2021-06-07 12:29:18 -07:00
2017-01-14 19:07:01 -08:00
class EndNamespace:
pass
2021-06-07 12:29:18 -07:00
2017-01-14 19:07:01 -08:00
CENTITY_TYPES = (
2017-10-14 22:44:07 -07:00
# Class, Header
2017-01-14 19:07:01 -08:00
('CActor', 'World/CActor.hpp'),
2017-01-18 14:30:02 -08:00
('CBallCamera', 'Camera/CBallCamera.hpp'),
('CBomb', 'Weapon/CBomb.hpp'),
('CCinematicCamera', 'Camera/CCinematicCamera.hpp'),
('CCollisionActor', 'Collision/CCollisionActor.hpp'),
('CDestroyableRock', 'World/CDestroyableRock.hpp'),
('CEnergyProjectile', 'Weapon/CEnergyProjectile.hpp'),
('CEntity', 'World/CEntity.hpp'),
2017-04-14 23:16:38 -07:00
('CExplosion', 'World/CExplosion.hpp'),
2017-01-18 14:30:02 -08:00
('CFirstPersonCamera', 'Camera/CFirstPersonCamera.hpp'),
('CFishCloud', 'World/CFishCloud.hpp'),
2017-01-14 19:07:01 -08:00
('CGameCamera', 'Camera/CGameCamera.hpp'),
('CGameLight', 'World/CGameLight.hpp'),
2017-01-18 14:30:02 -08:00
('CGameProjectile', 'Weapon/CGameProjectile.hpp'),
('CHUDBillboardEffect', 'World/CHUDBillboardEffect.hpp'),
2017-03-23 22:30:16 -07:00
('CInterpolationCamera', 'Camera/CInterpolationCamera.hpp'),
2017-01-18 14:30:02 -08:00
Namespace('MP1'),
2017-02-03 15:32:15 -08:00
('CMetroidPrimeRelay', 'MP1/World/CMetroidPrimeRelay.hpp', 'MP1'),
2019-01-15 20:22:44 -08:00
('CWarWasp', 'MP1/World/CWarWasp.hpp', 'MP1'),
('CActorContraption', 'MP1/World/CActorContraption.hpp', 'MP1'),
2017-01-18 14:30:02 -08:00
EndNamespace(),
('CPathCamera', 'Camera/CPathCamera.hpp'),
2017-01-14 19:07:01 -08:00
('CAi', 'World/CAi.hpp'),
2017-06-11 21:23:34 -07:00
('CPatterned', 'World/CPatterned.hpp'),
2017-01-18 14:30:02 -08:00
('CPhysicsActor', 'World/CPhysicsActor.hpp'),
2017-11-25 19:04:25 -08:00
('CPlayer', 'World/CPlayer.hpp'),
2017-01-14 19:07:01 -08:00
('CRepulsor', 'World/CRepulsor.hpp'),
2017-01-18 14:30:02 -08:00
('CScriptActor', 'World/CScriptActor.hpp'),
('CScriptActorKeyframe', 'World/CScriptActorKeyframe.hpp'),
2017-01-14 19:07:01 -08:00
('CScriptAiJumpPoint', 'World/CScriptAiJumpPoint.hpp'),
2017-01-18 14:30:02 -08:00
('CScriptCameraHint', 'World/CScriptCameraHint.hpp'),
2017-01-14 19:07:01 -08:00
('CScriptCameraPitchVolume', 'World/CScriptCameraPitchVolume.hpp'),
('CScriptCameraShaker', 'World/CScriptCameraShaker.hpp'),
2017-01-18 14:30:02 -08:00
('CScriptCameraWaypoint', 'World/CScriptCameraWaypoint.hpp'),
('CScriptControllerAction', 'World/CScriptControllerAction.hpp'),
2017-01-18 14:30:02 -08:00
('CScriptCoverPoint', 'World/CScriptCoverPoint.hpp'),
('CScriptDebugCameraWaypoint', 'World/CScriptDebugCameraWaypoint.hpp'),
('CScriptDistanceFog', 'World/CScriptDistanceFog.hpp'),
('CScriptDock', 'World/CScriptDock.hpp'),
2017-01-14 19:07:01 -08:00
('CScriptDoor', 'World/CScriptDoor.hpp'),
('CScriptEffect', 'World/CScriptEffect.hpp'),
('CScriptGrapplePoint', 'World/CScriptGrapplePoint.hpp'),
2017-01-18 14:30:02 -08:00
('CScriptGunTurret', 'World/CScriptGunTurret.hpp'),
('CScriptMazeNode', 'World/CScriptMazeNode.hpp'),
('CScriptPickup', 'World/CScriptPickup.hpp'),
('CScriptPlatform', 'World/CScriptPlatform.hpp'),
('CScriptPlayerHint', 'World/CScriptPlayerHint.hpp'),
2017-01-14 19:07:01 -08:00
('CScriptPointOfInterest', 'World/CScriptPointOfInterest.hpp'),
2017-01-18 14:30:02 -08:00
('CScriptRoomAcoustics', 'World/CScriptRoomAcoustics.hpp'),
('CScriptSound', 'World/CScriptSound.hpp'),
('CScriptMidi', 'World/CScriptMidi.hpp'),
2017-01-18 14:30:02 -08:00
('CScriptSpawnPoint', 'World/CScriptSpawnPoint.hpp'),
2017-01-14 19:07:01 -08:00
('CScriptSpecialFunction', 'World/CScriptSpecialFunction.hpp'),
2017-01-18 14:30:02 -08:00
('CScriptSpiderBallAttractionSurface', 'World/CScriptSpiderBallAttractionSurface.hpp'),
('CScriptSpiderBallWaypoint', 'World/CScriptSpiderBallWaypoint.hpp'),
('CScriptTargetingPoint', 'World/CScriptTargetingPoint.hpp'),
('CTeamAiMgr', 'World/CTeamAiMgr.hpp'),
('CScriptTimer', 'World/CScriptTimer.hpp'),
('CScriptTrigger', 'World/CScriptTrigger.hpp'),
('CScriptVisorFlare', 'World/CScriptVisorFlare.hpp'),
2017-11-11 21:14:57 -08:00
('CScriptVisorGoo', 'World/CScriptVisorGoo.hpp'),
2017-01-18 14:30:02 -08:00
('CScriptWater', 'World/CScriptWater.hpp'),
('CScriptWaypoint', 'World/CScriptWaypoint.hpp'),
('CSnakeWeedSwarm', 'World/CSnakeWeedSwarm.hpp'),
('CScriptSpindleCamera', 'World/CScriptSpindleCamera.hpp'),
('CWallCrawlerSwarm', 'World/CWallCrawlerSwarm.hpp'),
('CWeapon', 'Weapon/CWeapon.hpp'),
('CScriptDebris', 'World/CScriptDebris.hpp'),
2017-01-14 19:07:01 -08:00
)
2021-06-07 12:29:18 -07:00
2017-01-14 19:07:01 -08:00
def getqualified(tp):
if len(tp) >= 3:
return tp[2] + '::' + tp[0]
else:
return tp[0]
2021-06-07 12:29:18 -07:00
2017-01-14 19:07:01 -08:00
headerf = open('TCastTo.hpp', 'w')
sourcef = open('TCastTo.cpp', 'w')
2018-10-06 20:42:33 -07:00
headerf.write('''#pragma once
2017-01-14 19:07:01 -08:00
2021-04-10 01:42:06 -07:00
namespace metaforce {
2017-01-14 19:07:01 -08:00
class CEntity;
''')
for tp in CENTITY_TYPES:
if type(tp) == tuple:
headerf.write('class %s;\n' % tp[0])
elif isinstance(tp, Namespace):
2019-03-24 01:06:59 -07:00
headerf.write('namespace %s {\n' % tp.name)
2017-01-14 19:07:01 -08:00
elif isinstance(tp, EndNamespace):
headerf.write('}\n')
2019-03-24 01:06:59 -07:00
headerf.write('\nclass IVisitor {\npublic:\n')
2017-01-14 19:07:01 -08:00
for tp in CENTITY_TYPES:
if type(tp) == tuple:
2019-03-24 01:06:59 -07:00
headerf.write(' virtual void Visit(%s* p)=0;\n' % getqualified(tp))
2017-01-14 19:07:01 -08:00
headerf.write('''};
template <class T>
2019-03-24 01:06:59 -07:00
class TCastToPtr : public IVisitor {
2017-01-14 19:07:01 -08:00
protected:
2019-03-24 01:06:59 -07:00
T* ptr = nullptr;
2017-01-14 19:07:01 -08:00
public:
2019-03-24 01:06:59 -07:00
TCastToPtr() = default;
TCastToPtr(CEntity* p);
TCastToPtr(CEntity& p);
TCastToPtr<T>& operator=(CEntity& p);
TCastToPtr<T>& operator=(CEntity* p);
2017-01-14 19:07:01 -08:00
''')
for tp in CENTITY_TYPES:
if type(tp) == tuple:
headerf.write(' void Visit(%s* p) override;\n' % getqualified(tp))
2017-01-14 19:07:01 -08:00
headerf.write('''
2019-03-24 01:06:59 -07:00
T* GetPtr() const { return ptr; }
operator T*() const { return GetPtr(); }
T& operator*() const { return *GetPtr(); }
T* operator->() const { return GetPtr(); }
bool IsValid() const { return ptr != nullptr; }
explicit operator bool() const { return IsValid(); }
2017-01-14 19:07:01 -08:00
};
template <class T>
2019-03-24 01:06:59 -07:00
class TCastToConstPtr : TCastToPtr<T> {
2017-01-14 19:07:01 -08:00
public:
2019-03-24 01:06:59 -07:00
TCastToConstPtr() = default;
TCastToConstPtr(const CEntity* p) : TCastToPtr<T>(const_cast<CEntity*>(p)) {}
TCastToConstPtr(const CEntity& p) : TCastToPtr<T>(const_cast<CEntity&>(p)) {}
TCastToConstPtr<T>& operator=(const CEntity& p) { TCastToPtr<T>::operator=(const_cast<CEntity&>(p)); return *this; }
TCastToConstPtr<T>& operator=(const CEntity* p) { TCastToPtr<T>::operator=(const_cast<CEntity*>(p)); return *this; }
const T* GetPtr() const { return TCastToPtr<T>::ptr; }
operator const T*() const { return GetPtr(); }
const T& operator*() const { return *GetPtr(); }
const T* operator->() const { return GetPtr(); }
bool IsValid() const { return TCastToPtr<T>::ptr != nullptr; }
explicit operator bool() const { return IsValid(); }
2017-01-14 19:07:01 -08:00
};
}
''')
headerf.close()
sourcef.write('#include "TCastTo.hpp"\n\n')
for tp in CENTITY_TYPES:
if type(tp) == tuple:
sourcef.write('#include "%s"\n' % tp[1])
sourcef.write('''
2021-04-10 01:42:06 -07:00
namespace metaforce {
2017-01-14 19:07:01 -08:00
template <class T>
TCastToPtr<T>::TCastToPtr(CEntity* p) { if (p) p->Accept(*this); else ptr = nullptr; }
2017-01-14 19:07:01 -08:00
template <class T>
TCastToPtr<T>::TCastToPtr(CEntity& p) { p.Accept(*this); }
2017-10-13 23:34:57 -07:00
template <class T>
TCastToPtr<T>& TCastToPtr<T>::operator=(CEntity* p) { if (p) p->Accept(*this); else ptr = nullptr; return *this; }
2017-10-13 23:34:57 -07:00
template <class T>
TCastToPtr<T>& TCastToPtr<T>::operator=(CEntity& p) { p.Accept(*this); return *this; }
2017-01-14 19:07:01 -08:00
''')
for tp in CENTITY_TYPES:
if type(tp) == tuple:
qual = getqualified(tp)
sourcef.write('''template <class T>
2019-03-24 01:06:59 -07:00
void TCastToPtr<T>::Visit(%s* p) {
static_assert(sizeof(T) > 0 && !std::is_void_v<T>, "TCastToPtr can not cast to incomplete type");
2019-10-01 07:27:20 -07:00
ptr = reinterpret_cast<T*>(std::is_convertible_v<%s*, T*> ? p : nullptr);
2017-01-14 19:07:01 -08:00
}
''' % (qual, qual))
for tp in CENTITY_TYPES:
if type(tp) == tuple:
sourcef.write('template class TCastToPtr<%s>;\n' % getqualified(tp))
sourcef.write('\n}\n')
sourcef.close()