Created
March 7, 2019 17:32
-
-
Save Cry-Flare/50280148d6ceae8e3ef961625bcb4eb5 to your computer and use it in GitHub Desktop.
Example showing how to store interface offsets for use with the CRYENGINE EntityComponent system
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <StdAfx.h> | |
#include "DerivedComponent.h" | |
#include <CryCore/StaticInstanceList.h> | |
void DerivedComponent::func1() | |
{ | |
CryLogAlways("DerivedComponent: 1"); | |
} | |
void DerivedComponent::func2() | |
{ | |
CryLogAlways("DerivedComponent: 2"); | |
} | |
static void RegisterDerivedComponent(Schematyc::IEnvRegistrar& registrar) | |
{ | |
Schematyc::CEnvRegistrationScope scope = registrar.Scope(IEntity::GetEntityScopeGUID()); | |
{ | |
Schematyc::CEnvRegistrationScope componentScope = scope.Register(SCHEMATYC_MAKE_ENV_COMPONENT(DerivedComponent)); | |
} | |
} | |
CRY_STATIC_AUTO_REGISTER_FUNCTION(&RegisterDerivedComponent); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
#include "IDerivableComponent.h" | |
#include "Interface1.h" | |
#include "Interface2.h" | |
class DerivedComponent : public IDerivableComponent, public Interface1, public Interface2 | |
{ | |
public: | |
DerivedComponent() | |
{ | |
StoreBases<DerivedComponent, Interface1, Interface2>(); | |
}; | |
virtual ~DerivedComponent() {} | |
static void ReflectType(Schematyc::CTypeDesc<DerivedComponent>& desc) | |
{ | |
desc.SetEditorCategory("TestCat"); | |
desc.SetLabel("DerivedComponent"); | |
desc.SetGUID("{BE7743A4-041B-41F0-849E-15408E237C4C}"_cry_guid); | |
desc.AddBase<IDerivableComponent>(); | |
desc.AddBase<Interface1>(); | |
desc.AddBase<Interface2>(); | |
} | |
virtual void func1() override; | |
virtual void func2() override; | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
#include <CrySchematyc/CoreAPI.h> | |
class IDerivableComponent : public IEntityComponent | |
{ | |
public: | |
static void ReflectType(Schematyc::CTypeDesc<IDerivableComponent>& desc) | |
{ | |
desc.SetGUID("{BE7743A4-041B-41F0-849E-15402E237C4A}"_cry_guid); | |
} | |
template <class Base> | |
Base* GetBase() const | |
{ | |
uintptr_t offset; | |
if (GetBaseOffset<Base>(offset)) | |
{ | |
uintptr_t ptrBase = reinterpret_cast<uintptr_t>(this) + offset; | |
return reinterpret_cast<Base*>(ptrBase); | |
} | |
else | |
{ | |
return nullptr; | |
} | |
} | |
protected: | |
template <class Derived, class... Bases> | |
void StoreBases() | |
{ | |
m_baseOffsets = {StoreBase<Derived, Bases>(Schematyc::GetTypeGUID<Bases>())...}; | |
} | |
private: | |
template <class Derived, class Base> | |
const std::pair<CryGUID, uintptr_t> StoreBase(CryGUID guid) | |
{ | |
const uintptr_t offset = CalculateBaseOffset<Derived, Base>(); | |
return std::pair<CryGUID, uintptr_t>(guid, offset); | |
} | |
template <class Derived, class Base> | |
uintptr_t CalculateBaseOffset() const | |
{ | |
const uintptr_t ptrBase = reinterpret_cast<uintptr_t>(static_cast<const Base*>(reinterpret_cast<const Derived*>(this))); | |
const uintptr_t ptrDerived = reinterpret_cast<uintptr_t>(this); | |
return ptrBase - ptrDerived; | |
} | |
template <class Base> | |
bool GetBaseOffset(uintptr_t& out_offset) const | |
{ | |
for (const std::pair<CryGUID, uintptr_t>& pair : m_baseOffsets) | |
{ | |
if (pair.first == Schematyc::GetTypeGUID<Base>()) | |
{ | |
out_offset = pair.second; | |
return true; | |
} | |
} | |
return false; | |
} | |
protected: | |
std::vector<std::pair<CryGUID, uintptr_t>> m_baseOffsets; | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
#include <CrySchematyc/CoreAPI.h> | |
struct Interface1 | |
{ | |
virtual void func1() = 0; | |
static void ReflectType(Schematyc::CTypeDesc<Interface1>& desc) { | |
desc.SetGUID("{2AC2CF46-127E-4A81-B38E-5FE84BAFC476}"_cry_guid); | |
} | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
#include <CrySchematyc/CoreAPI.h> | |
struct Interface2 | |
{ | |
virtual void func2() = 0; | |
static void ReflectType(Schematyc::CTypeDesc<Interface2>& desc) { | |
desc.SetGUID("{2AC2CF46-127E-4A81-B38E-5FE84BAFC475}"_cry_guid); | |
} | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "StdAfx.h" | |
#include "Player.h" | |
#include "IDerivableComponent.h" | |
#include "DerivedComponent.h" | |
#include <CryRenderer/IRenderAuxGeom.h> | |
void CPlayerComponent::Initialize() | |
{ | |
// Add Derived Component to this entity: | |
DerivedComponent* pD = m_pEntity->GetOrCreateComponent<DerivedComponent>(); | |
// Get the pointer to the IEntityComponent interface | |
IEntityComponent* pEntityComponent = m_pEntity->QueryComponentByInterfaceID(Schematyc::GetTypeGUID<Interface1>()); | |
// Get the IDerivableComponent by casting from the IEntityComponent pointer | |
IDerivableComponent* pDerivable = reinterpret_cast<IDerivableComponent*>(pEntityComponent); | |
// Try to get the Interface1 from this pointer (Should be garunteed as that was what we queried earlier) | |
if (Interface1* pInterface1 = pDerivable->GetBase<Interface1>()) | |
pInterface1->func1(); | |
// We know this is the case, but this is not garunteed and will give nullptr if this interface doesnt exist in this component. | |
if (Interface2* pInterface2 = pDerivable->GetBase<Interface2>()) | |
pInterface2->func2(); | |
... |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment