/* * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or * its licensors. * * For complete copyright and license terms please see the LICENSE at the root of this * distribution (the "License"). All use of this software is governed by the License, * or, if provided, by the license below or the license accompanying this file. Do not * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * */ // Original file Copyright Crytek GMBH or its affiliates, used under license. // Description : Interface to manage SoftCode module loading and patching #ifndef CRYINCLUDE_CRYCOMMON_ISOFTCODEMGR_H #define CRYINCLUDE_CRYCOMMON_ISOFTCODEMGR_H #pragma once // Provides the generic interface for exchanging member values between SoftCode modules, struct IExchangeValue { // virtual ~IExchangeValue() {} // Allocates a new IExchangeValue with the underlying type virtual IExchangeValue* Clone() const = 0; // Returns the size of the underlying type (to check compatibility) virtual size_t GetSizeOf() const = 0; // }; template struct ExchangeValue : public IExchangeValue { ExchangeValue(T& value) : m_value(value) {} virtual IExchangeValue* Clone() const { return new ExchangeValue(*this); } virtual size_t GetSizeOf() const { return sizeof(m_value); } T m_value; }; template struct ExchangeArray : public IExchangeValue { ExchangeArray(T* pArr) { for (size_t i = 0; i < S; ++i) { m_array[i] = pArr[i]; } } virtual IExchangeValue* Clone() const { return new ExchangeArray(*this); } virtual size_t GetSizeOf() const { return sizeof(m_array); } T m_array[S]; }; /* This is a non-intrusive support function for types where default construction does no initialization. SoftCoding relies on default construction to initialize object state correctly. For most types this works as expected but for some types (typically things like vectors or matrices) default initialization would be too costly and is therefore not implemented. This function allows a specialized implementation to be used for such types that will perform initialization on the newly constructed instance. For example: inline void DefaultInitialize(Matrix34& matrix) { matrix.SetIdentity(); } */ template void DefaultInitialize(T& t) { t = T(); } // Vector support template struct Vec2_tpl; template struct Vec3_tpl; template void DefaultInitialize(Vec2_tpl& vec) { vec.zero(); } template void DefaultInitialize(Vec3_tpl& vec) { vec.zero(); } // Matrix support template struct Matrix33_tpl; template struct Matrix34_tpl; template struct Matrix44_tpl; template void DefaultInitialize(Matrix33_tpl& matrix) { matrix.SetIdentity(); } template void DefaultInitialize(Matrix34_tpl& matrix) { matrix.SetIdentity(); } template void DefaultInitialize(Matrix44_tpl& matrix) { matrix.SetIdentity(); } // Quat support template struct Quat_tpl; template void DefaultInitialize(Quat_tpl& quat) { quat.SetIdentity(); } // Interface for performing an exchange of instance data struct IExchanger { // virtual ~IExchanger() {} // True if data is being read from instance members virtual bool IsLoading() const = 0; virtual size_t InstanceCount() const = 0; virtual bool BeginInstance(void* pInstance) = 0; virtual bool SetValue(const char* name, IExchangeValue& value) = 0; virtual IExchangeValue* GetValue(const char* name, void* pTarget, size_t targetSize) = 0; // template void Visit(const char* name, T& instance); template void Visit(const char* name, T (&arr)[S]); }; template void IExchanger::Visit(const char* name, T& value) { if (IsLoading()) { IExchangeValue* pValue = GetValue(name, &value, sizeof(value)); if (pValue) { ExchangeValue* pTypedValue = static_cast*>(pValue); value = pTypedValue->m_value; } } else // Saving { // If this member is stored if (SetValue(name, ExchangeValue(value))) { // Set the original value to the default state (to allow safe destruction) DefaultInitialize(value); } } } template void IExchanger::Visit(const char* name, T (&arr)[S]) { if (IsLoading()) { IExchangeValue* pValue = GetValue(name, &arr, sizeof(arr)); if (pValue) { ExchangeArray* pTypedArray = static_cast*>(pValue); // TODO: Accommodate array resizing? Complex however... for (size_t i = 0; i < S; ++i) { arr[i] = pTypedArray->m_array[i]; } } } else // Saving { // If this member is stored if (SetValue(name, ExchangeArray(arr))) { T defaultValue; DefaultInitialize(defaultValue); // Set the original value to the default value (to allow safe destruction) for (size_t i = 0; i < S; ++i) { arr[i] = defaultValue; } } } } struct InstanceTracker; struct ITypeRegistrar { // virtual ~ITypeRegistrar() {} virtual const char* GetName() const = 0; // Creates an instance of the type virtual void* CreateInstance() = 0; // #ifdef SOFTCODE_ENABLED // How many active instances exist of this type? virtual size_t InstanceCount() const = 0; // Used to remove a tracked instance from the Registrar virtual void RemoveInstance(InstanceTracker* pTracker) = 0; // Exchanges the instance state with the given exchanger data set virtual bool ExchangeInstances(IExchanger& exchanger) = 0; // Destroys all tracked instances of this type virtual bool DestroyInstances() = 0; // Returns true if pInstance is of this type (linear search) virtual bool HasInstance(void* pInstance) const = 0; #endif }; struct ITypeLibrary { // virtual ~ITypeLibrary() {} virtual const char* GetName() = 0; virtual void* CreateInstanceVoid(const char* typeName) = 0; // #ifdef SOFTCODE_ENABLED virtual void SetOverride(ITypeLibrary* pOverrideLib) = 0; // Fills in the supplied type list if large enough, and sets count to number of types virtual size_t GetTypes(ITypeRegistrar** ppRegistrar, size_t& count) const = 0; #endif }; struct ISoftCodeListener { // virtual ~ISoftCodeListener() {} // Called when an instance is replaced to allow managing systems to fixup pointers virtual void InstanceReplaced(void* pOldInstance, void* pNewInstance) = 0; // }; /// Interface for ... struct ISoftCodeMgr { // virtual ~ISoftCodeMgr() {} // Used to register built-in libraries on first use virtual void RegisterLibrary(ITypeLibrary* pLib) = 0; // Loads any new SoftCode modules virtual void LoadNewModules() = 0; virtual void AddListener(const char* libraryName, ISoftCodeListener* pListener, const char* listenerName) = 0; virtual void RemoveListener(const char* libraryName, ISoftCodeListener* pListener) = 0; // To be called regularly to poll for library updates virtual void PollForNewModules() = 0; // Stops thread execution until a new SoftCode instance is available virtual void* WaitForUpdate(void* pInstance) = 0; /// Frees this instance from memory //virtual void Release() = 0; // }; #endif // CRYINCLUDE_CRYCOMMON_ISOFTCODEMGR_H