summaryrefslogtreecommitdiffstats
path: root/RenderScript/include/LuaBindings.h
diff options
context:
space:
mode:
authorassiduous <assiduous@diligentgraphics.com>2019-12-12 23:16:42 +0000
committerassiduous <assiduous@diligentgraphics.com>2019-12-12 23:16:42 +0000
commitd9ff664e3d796f9526ed29b7a1066b3d3fb443b1 (patch)
treebc94032e85347cdd26cc4c3c67d288bcfa9ef540 /RenderScript/include/LuaBindings.h
parentappveyor: swithced to VS2019 and enabled tests (diff)
downloadDiligentTools-d9ff664e3d796f9526ed29b7a1066b3d3fb443b1.tar.gz
DiligentTools-d9ff664e3d796f9526ed29b7a1066b3d3fb443b1.zip
Removed RenderScript and lua
Diffstat (limited to 'RenderScript/include/LuaBindings.h')
-rw-r--r--RenderScript/include/LuaBindings.h684
1 files changed, 0 insertions, 684 deletions
diff --git a/RenderScript/include/LuaBindings.h b/RenderScript/include/LuaBindings.h
deleted file mode 100644
index 997b1b3..0000000
--- a/RenderScript/include/LuaBindings.h
+++ /dev/null
@@ -1,684 +0,0 @@
-/* Copyright 2019 Diligent Graphics LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS.
- *
- * In no event and under no legal theory, whether in tort (including negligence),
- * contract, or otherwise, unless required by applicable law (such as deliberate
- * and grossly negligent acts) or agreed to in writing, shall any Contributor be
- * liable for any damages, including any direct, indirect, special, incidental,
- * or consequential damages of any character arising as a result of this License or
- * out of the use or inability to use the software (including but not limited to damages
- * for loss of goodwill, work stoppage, computer failure or malfunction, or any and
- * all other commercial damages or losses), even if such Contributor has been advised
- * of the possibility of such damages.
- */
-
-#pragma once
-
-#include "lua.h"
-#include "lualib.h"
-#include "lauxlib.h"
-#include "EnumMappings.h"
-
-namespace Diligent
-{
- template< typename ValueType>
- ValueType ReadValueFromLua( lua_State *L, int Index )
- {
- UNSUPPORTED( "Type is not supported" );
- return static_cast<ValueType>(0);
- }
- template<>int ReadValueFromLua<int>( lua_State *L, int Index );
- template<>double ReadValueFromLua<double>( lua_State *L, int Index );
- template<>float ReadValueFromLua<float>( lua_State *L, int Index );
- template<>String ReadValueFromLua<String>( lua_State *L, int Index );
- template<>const Char* ReadValueFromLua<const Char*>( lua_State *L, int Index );
- template<>Bool ReadValueFromLua<Bool>( lua_State *L, int Index );
- template<>Uint32 ReadValueFromLua<Uint32>( lua_State *L, int Index );
- template<>Uint8 ReadValueFromLua<Uint8>( lua_State *L, int Index );
-
-
- inline void CheckType( lua_State *L, int Index, int ExpectedType )
- {
- auto Type = lua_type( L, Index );
- if( Type != ExpectedType )
- {
- auto TypeName = lua_typename( L, Type );
- auto ExpectedTypeName = lua_typename( L, ExpectedType );
- auto Param = lua_tostring( L, Index );
- SCRIPT_PARSING_ERROR( L, "Incorrect argument: \"", Param ? Param : "<Unknown>", "\". \"", ExpectedTypeName, "\" is expected, while \"", TypeName, "\" is provided." );
- }
- }
-
- // Special version of luaL_testudata() which takes an array of allowed metatables
- void *luaL_testudata( lua_State *L, int ud, const std::vector<String> &MetatableNames );
-
- template<typename DataType, typename MetatableNameType>
- DataType GetUserData( lua_State *L, int Index, MetatableNameType MetatableName )
- {
- CheckType( L, Index, LUA_TUSERDATA );
- auto pUserData = luaL_testudata( L, Index, MetatableName );
- if( pUserData == nullptr )
- {
- auto Type = lua_type( L, Index );
- auto TypeName = lua_typename( L, Type );
- SCRIPT_PARSING_ERROR( L, "Bad argument #", Index, ". User data with metatable \"", MetatableName, "\" is expected. \"", TypeName, "\" is provided." );
- }
- return reinterpret_cast<DataType>(pUserData);
- }
-
- template<typename DataType>
- DataType GetGlobalObject( lua_State *L, const Char* ObjectName, const Char* MetatableName )
- {
- INIT_LUA_STACK_TRACKING( L );
- // Pushes onto the stack the value of the given global name
- lua_getglobal( L, ObjectName ); // -0 | +1 -> +1
- auto pData = GetUserData<DataType>( L, -1, MetatableName ); // -0 | +0 -> 0
- lua_pop( L, 1 ); // -1 | +0 -> -1
- CHECK_LUA_STACK_HEIGHT();
- return pData;
- }
-
-
-
- template<typename Type>
- void PushValue( lua_State *L, Type )
- {
- UNSUPPORTED( "Type is not supported" );
- }
- // Forward declarations of template specializations
- template<> void PushValue<double>( lua_State *L, double Val );
- template<> void PushValue<const float&>( lua_State *L, const float& Val );
- template<> void PushValue<const Int32&>( lua_State *L, const Int32& Val );
- template<> void PushValue<const Uint32&>( lua_State *L, const Uint32& Val );
- template<> void PushValue<const Uint8&>( lua_State *L, const Uint8& Val );
- template<> void PushValue<const Char*>( lua_State *L, const Char* Val );
- template<> void PushValue<const Char* const&>( lua_State *L, const Char* const& Val );
- template<> void PushValue<const String&>( lua_State *L, const String& Val );
- template<> void PushValue<bool>( lua_State *L, bool Val );
- template<> void PushValue<const bool &>( lua_State *L, const bool &Val );
-
-
- class MemberBinderBase
- {
- public:
- MemberBinderBase( size_t MemberOffset ) :
- m_MemberOffset( MemberOffset )
- {}
- virtual ~MemberBinderBase(){}
- virtual void GetValue( lua_State *L, const void* pBasePointer ) = 0;
- virtual void SetValue( lua_State *L, int Index, void* pBasePointer ) = 0;
-
- protected:
- const size_t m_MemberOffset;
- };
- typedef std::unordered_map<HashMapStringKey, std::unique_ptr<MemberBinderBase>, HashMapStringKey::Hasher> BindingsMapType;
-
-#define DEFINE_BINDER_EX(BindingsMap, Struct, Member, type, ValidationFunc) \
- do{\
- auto *pNewBinder = new MemberBinder<type>( offsetof( Struct, Member ), ValidationFunc ); \
- /* No need to make a copy of #Member since it is constant string. */ \
- /* HashMapStringKey will simply keep pointer to it */ \
- BindingsMap.insert( std::make_pair( #Member, std::unique_ptr<MemberBinderBase>(pNewBinder) ) ); \
- }while(false)
-
-#define DEFINE_BINDER(BindingsMap, Struct, Member) DEFINE_BINDER_EX(BindingsMap, Struct, Member, decltype(Struct::Member), Validator<decltype(Struct::Member)>() )
-
- template<typename ValueType>
- void SkipValidationFunc( const ValueType & )
- {
- // Do nothing
- }
-
- template<typename ValueType>
- class Validator
- {
- public:
- typedef void( *ValidationFuncType )(const ValueType &);
- Validator( const char *pParameterName, ValueType MinValue, ValueType MaxValue ) :
- m_pParameterName( pParameterName ),
- m_MinValue( MinValue ),
- m_MaxValue( MaxValue ),
- m_ValidationFunc( nullptr )
- {}
-
- Validator( ValidationFuncType ValidationFunc = SkipValidationFunc<ValueType> ) :
- m_pParameterName( nullptr ),
- m_MinValue( ValueType() ),
- m_MaxValue( ValueType() ),
- m_ValidationFunc( ValidationFunc )
- {}
-
- void SetParameterName( const char *NewName ){ m_pParameterName = NewName; }
-
- void operator()( lua_State *L, const ValueType &Value )const
- {
- if( m_ValidationFunc )
- {
- m_ValidationFunc( Value );
- }
- else
- {
- if( Value < m_MinValue || Value > m_MaxValue )
- {
- SCRIPT_PARSING_ERROR( L, "Parameter '", m_pParameterName, "' (", Value, ") is out of range [", m_MinValue, ",", m_MaxValue, "]\n" );
- }
- }
- }
-
- private:
- const char *m_pParameterName;
- ValueType m_MinValue, m_MaxValue;
- ValidationFuncType m_ValidationFunc;
- };
-
- template<>
- class Validator < Bool >
- {
- public:
- void operator()( lua_State *L, const Bool & )const
- {
- // Do nothing
- }
- };
-
- template<typename MemberType>
- MemberType& GetMemberByOffest( void* pBasePointer, size_t Offset )
- {
- return *(reinterpret_cast<MemberType*>(reinterpret_cast<char*>(pBasePointer)+Offset));
- }
-
- template<typename MemberType>
- const MemberType& GetMemberByOffest( const void* pBasePointer, size_t Offset )
- {
- return *(reinterpret_cast<const MemberType*>(reinterpret_cast<const char*>(pBasePointer)+Offset));
- }
-
- template<typename MemberType>
- class MemberBinder : public MemberBinderBase
- {
- public:
- MemberBinder( size_t MemberOffset, Validator<MemberType> Validator ) :
- MemberBinderBase( MemberOffset ),
- m_Validator( Validator )
- {}
-
- virtual void GetValue( lua_State *L, const void* pBasePointer )
- {
- const auto &Value = GetMemberByOffest<MemberType>(pBasePointer, m_MemberOffset);
- PushValue<const MemberType &>( L, Value );
- }
-
- virtual void SetValue( lua_State *L, int Index, void* pBasePointer )
- {
- auto Value = ReadValueFromLua<MemberType>( L, Index );
- m_Validator( L, Value );
- GetMemberByOffest<MemberType>( pBasePointer, m_MemberOffset ) = Value;
- }
- protected:
- Validator<MemberType> m_Validator;
- };
-
-
- template<typename TableElementParser>
- inline void ParseLuaTable( lua_State *L, int Index, void* pBasePointer, TableElementParser ElemParser )
- {
- CheckType( L, Index, LUA_TTABLE );
-
- lua_pushnil( L ); // first key which will be popped out in the first call to lua_next()
- // lua_next() pops a key from the stack, and pushes a key–value pair from the table at the given index
- // (the "next" pair after the given key). If there are no more elements in the table, then lua_next returns
- // 0 (and pushes nothing).
- if( Index < 0 )
- --Index;
- while( lua_next( L, Index ) != 0 )
- {
- // Key is now at index -2 and Value is at index -1
- auto IsString = lua_isstring( L, -2 );
- if( !IsString )
- {
- SCRIPT_PARSING_ERROR( L, "Table key value must be string")
- }
- // NOTE: the lua_tostring function returns a pointer to an internal copy of the string.
- // The string is always zero-terminated and Lua ensures that this pointer is valid as long
- // as the corresponding value is in the stack.
- auto Key = lua_tostring( L, -2 );
- ElemParser(-1, pBasePointer, Key);
-
- // Pop value from the stack, but KEEP Key for the next iteration
- lua_pop( L, 1 );
- }
- }
-
- inline void ParseLuaTable( lua_State *L, int Index, void* pBasePointer, BindingsMapType &Bindings )
- {
- ParseLuaTable( L, Index, pBasePointer,
- [&](int Index, void* pBasePointer, const char *Key)
- {
- auto Binding = Bindings.find( Key );
- if( Binding != Bindings.end() )
- {
- Binding->second->SetValue( L, Index, pBasePointer );
- }
- else
- {
- SCRIPT_PARSING_ERROR( L, "Unknown Member \"", Key, '\"' );
- }
- }
- );
- }
-
- template<class ArrayElemParser>
- inline void ParseLuaArray( lua_State *L, int Index, void* pBasePointer, ArrayElemParser ElemParser )
- {
- CheckType( L, Index, LUA_TTABLE );
-
- lua_pushnil( L ); // first key which will be popped out in the first call to lua_next()
- // lua_next() pops a key from the stack, and pushes a key–value pair from the table at the given index
- // (the "next" pair after the given key). If there are no more elements in the table, then lua_next returns
- // 0 (and pushes nothing).
- if( Index < 0 )
- --Index;
- while( lua_next( L, Index ) != 0 )
- {
- // Key is now at index -2 and Value is at index -1
- CheckType( L, -2, LUA_TNUMBER );
-
- auto NewArrayIndex = static_cast<int>( lua_tointeger( L, -2 ) );
- ElemParser( pBasePointer, -1, NewArrayIndex );
-
- // Pop value from the stack, but KEEP Key for the next iteration
- lua_pop( L, 1 );
- }
- }
-
- inline void PushLuaTable( lua_State *L, const void* pBasePointer, BindingsMapType &Bindings )
- {
- lua_newtable( L );
- for( auto it = Bindings.begin(); it != Bindings.end(); ++it )
- {
- const auto &Field = it->first.GetStr();
- lua_pushstring( L, Field );
- it->second->GetValue( L, pBasePointer );
- lua_settable( L, -3 ); // Stack: 0
- }
- }
-
- template<typename ItType, class ElemPushAlg>
- void PushLuaArray( lua_State *L, ItType Begin, ItType End, ElemPushAlg PushAlg )
- {
- lua_newtable( L );
- int ArrayInd = 1; // Lua arrays are 1-based
- for( auto it = Begin; it != End; ++it, ++ArrayInd )
- {
- lua_pushnumber( L, ArrayInd ); // -0 | +1 -> +1
- PushAlg( *it ); // -0 | +1 -> +1
- lua_settable( L, -3 ); // -2 | +0 -> -2
- }
- }
-
- template<typename ArrayType, class ElemPushAlg>
- void PushLuaArray( lua_State *L, const ArrayType& Arr, ElemPushAlg PushAlg )
- {
- PushLuaArray( L, Arr.begin(), Arr.end(), PushAlg );
- }
-
- inline void PushField( lua_State *L, const void* pBasePointer, const Char *Field, BindingsMapType &Bindings )
- {
- auto It = Bindings.find( Field );
- if( It != Bindings.end() )
- {
- It->second->GetValue( L, pBasePointer );
- }
- else
- {
- SCRIPT_PARSING_ERROR( L, "Unknown Member \"", Field, '\"' );
- }
- }
-
- inline void UpdateField( lua_State *L, int Index, void* pBasePointer, const Char *Field, BindingsMapType &Bindings )
- {
- auto It = Bindings.find( Field );
- if( It != Bindings.end() )
- {
- It->second->SetValue( L, Index, pBasePointer );
- }
- else
- {
- SCRIPT_PARSING_ERROR( L, "Unknown Member \"", Field, '\"' );
- }
- }
-
- class RGBALoader; // Used only as a template switch
- template<>
- class MemberBinder<RGBALoader> : public MemberBinderBase
- {
- public:
- MemberBinder( size_t MemberOffset, size_t Dummy ) :
- MemberBinderBase( MemberOffset )
- {
- const char* Members[] = { "r", "g", "b", "a" };
- for( int c = 0; c < 4; ++c )
- {
- auto *pNewBinder = new MemberBinder<Float32>( MemberOffset + sizeof( Float32 )*c, Validator<float>() );
- // No need to make a copy of Members[c] since it is constant string.
- // HashMapStringKey will simply keep pointer to it
- Bindings.insert( std::make_pair( Members[c], std::unique_ptr<MemberBinderBase>( pNewBinder ) ) );
- }
- }
- virtual void GetValue( lua_State *L, const void* pBasePointer )
- {
- PushLuaTable( L, pBasePointer, Bindings );
- }
-
- virtual void SetValue( lua_State *L, int Index, void* pBasePointer )
- {
- ParseLuaTable( L, Index, pBasePointer, Bindings );
- }
- private:
- BindingsMapType Bindings;
- };
-
-
- template< typename EnumType >
- String GetEnumMappingsString( const EnumMapping<EnumType> &EnumMapping )
- {
- String Values;
- bool bFirst = true;
- for( auto it = EnumMapping.m_Str2ValMap.begin(); it != EnumMapping.m_Str2ValMap.end(); ++it )
- {
- if( !bFirst )
- Values += ", ";
- Values += '\"';
- Values.append( it->first.GetStr() );
- Values += '\"';
- bFirst = false;
- }
- return Values;
- }
-
- template<typename EnumType>
- class EnumMemberBinder : public MemberBinderBase
- {
- public:
- EnumMemberBinder( size_t MemberOffset, const Char* MemberName, const EnumMapping<EnumType> &EnumMapping ) :
- MemberBinderBase( MemberOffset ),
- m_MemberName( MemberName ),
- m_EnumMapping( EnumMapping )
- {
- }
-
- virtual void GetValue( lua_State *L, const void* pBasePointer )
- {
- const auto &Val = GetMemberByOffest<EnumType>( pBasePointer, m_MemberOffset );
- auto It = m_EnumMapping.m_Val2StrMap.find( Val );
- if( It != m_EnumMapping.m_Val2StrMap.end() )
- {
- const String& StrVal = It->second;
- PushValue<const String&>( L, StrVal );
- }
- else
- {
- UNEXPECTED( "Enum value (", static_cast<Int32>(Val), ") not found in the map" );
- SCRIPT_PARSING_ERROR( L, "Enum value (", static_cast<Int32>(Val), ") not found in the map" );
- }
- }
-
- virtual void SetValue( lua_State *L, int Index, void* pBasePointer )
- {
- auto Str = ReadValueFromLua<String>( L, Index );
- auto It = m_EnumMapping.m_Str2ValMap.find( Str.c_str() );
- if( It != m_EnumMapping.m_Str2ValMap.end() )
- {
- auto Val = It->second;
- GetMemberByOffest<EnumType>(pBasePointer, m_MemberOffset) = Val;
- }
- else
- {
- String AllowableValues = GetEnumMappingsString<EnumType>( m_EnumMapping );
- SCRIPT_PARSING_ERROR( L, "Unknown value (\"", Str, "\") provided for parameter ", m_MemberName, ". Only the following values are allowed:\n", AllowableValues );
- }
- }
-
- private:
- const Char *m_MemberName;
- const EnumMapping<EnumType> &m_EnumMapping;
- };
-
-#define DEFINE_ENUM_BINDER(BindingsMap, Struct, Member, EnumMapping ) \
- do{\
- auto *pNewBinder = new EnumMemberBinder<decltype(Struct::Member)>( offsetof( Struct, Member ), #Member, EnumMapping ); \
- /* No need to make a copy of #Member since it is constant string. */ \
- /* HashMapStringKey will simply keep pointer to it */ \
- BindingsMap.insert( std::make_pair( #Member, std::unique_ptr<MemberBinderBase>(pNewBinder) ) ); \
- }while(false)
-
- template< typename EnumType, typename FlagsType = typename std::underlying_type<EnumType>::type >
- class FlagsLoader : public MemberBinderBase
- {
- public:
- FlagsLoader( size_t MemberOffset, const Char* MemberName, const EnumMapping<EnumType> &EnumMapping ) :
- MemberBinderBase( MemberOffset ),
- m_MemberName( MemberName ),
- m_EnumMapping( EnumMapping )
- {
- }
- virtual void GetValue( lua_State *L, const void* pBasePointer )
- {
- auto Flags = GetMemberByOffest<FlagsType>( pBasePointer, m_MemberOffset );
- lua_newtable( L );
- int ArrayInd = 1;
- for( auto it = m_EnumMapping.m_Val2StrMap.begin(); it != m_EnumMapping.m_Val2StrMap.end(); ++it )
- {
- if( (it->first != 0 && static_cast<EnumType>(Flags & it->first) == it->first) ||
- (Flags == 0 && it->first == 0) )
- {
- lua_pushnumber( L, ArrayInd ); // -0 | +1 -> +1
- PushValue<const String&>( L, it->second ); // -0 | +1 -> +1
- lua_settable( L, -3 ); // -2 | +0 -> -2
- ++ArrayInd;
- }
- }
- }
-
- virtual void SetValue( lua_State *L, int Index, void* pBasePointer )
- {
- FlagsType Flags = static_cast<FlagsType>(0);
- if( lua_isnumber( L, Index ) )
- {
- Flags = static_cast<FlagsType>( ReadValueFromLua<Uint32>( L, Index ) );
- }
- else if( lua_isstring( L, Index ) )
- {
- Flags = ReadFlag( L, Index );
- }
- else if( lua_istable( L, Index ) )
- {
- ParseLuaArray( L, Index, pBasePointer, [ &]( void* _pBasePointer, int StackIndex, int NewArrayIndex )
- {
- auto CurrFlag = ReadFlag( L, StackIndex );
- Flags |= CurrFlag;
- }
- );
- }
- else
- {
- SCRIPT_PARSING_ERROR( L, m_MemberName, "must be specified as a single string or an array of strings." );
- }
- GetMemberByOffest<FlagsType>( pBasePointer, m_MemberOffset ) = Flags;
- }
-
- private:
- FlagsType ReadFlag( lua_State *L, int StackIndex )
- {
- auto CurrFlagName = ReadValueFromLua<const Char *>( L, StackIndex );
- auto It = m_EnumMapping.m_Str2ValMap.find( CurrFlagName );
- if( It != m_EnumMapping.m_Str2ValMap.end() )
- {
- return It->second;
- }
- else
- {
- String AllowableValues = GetEnumMappingsString<EnumType>( m_EnumMapping );
- SCRIPT_PARSING_ERROR( L, "Unknown flag (\"", CurrFlagName, "\") provided for parameter ", m_MemberName, ". Only the following flags are allowed:\n", AllowableValues );
- return static_cast<FlagsType>(0);
- }
- }
-
- const Char *m_MemberName;
- const EnumMapping<EnumType> &m_EnumMapping;
- };
-#define DEFINE_FLAGS_BINDER(BindingsMap, Struct, Member, type, EnumMapping ) \
- do{\
- auto *pNewBinder = new FlagsLoader<type, decltype(Struct::Member)>( offsetof( Struct, Member ), #Member, EnumMapping ); \
- /* No need to make a copy of #Member since it is constant string. */ \
- /* HashMapStringKey will simply keep pointer to it */ \
- BindingsMap.insert( std::make_pair( #Member, std::unique_ptr<MemberBinderBase>(pNewBinder) ) ); \
- }while(false)
-
-
- template<typename FieldType>
- void SetTableField( lua_State *L, const char *FieldName, int TableStackIndex, FieldType Value )
- {
- INIT_LUA_STACK_TRACKING( L );
-
- lua_pushstring( L, FieldName ); // -0 | +1 -> +1
- PushValue<FieldType>( L, Value ); // -0 | +1 -> +1
-
- // lua_settable() does the equivalent to t[k] = v, where t is the value at the given index,
- // v is the value at the top of the stack (-1), and k is the value just below the top (-2)
- // The function pops both the key and the value from the stack. As in Lua, this function may
- // trigger a metamethod for the "newindex" event
- lua_settable( L, TableStackIndex - 2 ); // -2 | +0 -> -2
-
- CHECK_LUA_STACK_HEIGHT();
- }
-
- class NumericArrayLoader
- {
- public:
- NumericArrayLoader();
- void LoadArray( lua_State *L, int StackIndex, std::vector< Uint8 >& RawData );
- private:
- EnumMapping<VALUE_TYPE> m_ValueTypeEnumMapping;
- EnumMemberBinder<VALUE_TYPE> m_ValueTypeBinder;
- typedef void (*ParseNumericArrayFuncType)(lua_State *L, int StackIndex, std::vector< Uint8 >& RawData);
- std::unordered_map< VALUE_TYPE, ParseNumericArrayFuncType, std::hash<std::underlying_type<VALUE_TYPE>::type> > m_ParseFuncJumpTbl;
- };
-
-
- template<typename EngineObjectType>
- class EngineObjectPtrLoader
- {
- public:
- typedef EngineObjectType ObjectType;
- };
-
- template<typename EngineObjectType>
- class MemberBinder< EngineObjectPtrLoader<EngineObjectType> > : public MemberBinderBase
- {
- public:
- typedef typename EngineObjectPtrLoader<EngineObjectType>::ObjectType ObjectType;
-
- MemberBinder( size_t MemberOffset, const std::vector<String> &_Metatables ) :
- MemberBinderBase( MemberOffset ),
- Metatables( _Metatables )
- {
- }
-
- virtual void GetValue( lua_State *L, const void* pBasePointer )
- {
- VERIFY( Metatables.size() == 1, "Ambiguous metatable" );
- const auto& MetatableName = *Metatables.begin();
- auto pObject = GetMemberByOffest<ObjectType*>( pBasePointer, m_MemberOffset );
- if( pObject )
- {
- auto ppNewObject = reinterpret_cast<ObjectType**>(lua_newuserdata( L, sizeof( ObjectType* ) ));
- *ppNewObject = pObject;
- pObject->AddRef();
- // Push onto the stack the metatable associated with name given in the registry
- luaL_getmetatable( L, MetatableName.c_str() ); // -0 | +1 -> +1
- // Pop a table from the top of the stack and set it as the new metatable
- // for the value at the given index (which is where the new user datum is)
- lua_setmetatable( L, -2 ); // -1 | +0 -> -1
- }
- else
- {
- lua_pushnil(L);
- }
- }
-
- virtual void SetValue( lua_State *L, int Index, void* pBasePointer )
- {
- ObjectType *pObject = nullptr;
- pObject = *GetUserData<ObjectType**>( L, -1, Metatables );
- GetMemberByOffest<ObjectType*>( pBasePointer, m_MemberOffset ) = pObject;
- }
- private:
- BindingsMapType Bindings;
- std::vector<String> Metatables;
- };
-
- // None of the graphics engine structures (such as BufferDesc or TextureDesc)
- // provide storage for strings, but only contain const Char* pointers.
- // The script wraps every such structure to provide the storage
- // This binder handles such strings
- class BufferedStringBinder : public MemberBinderBase
- {
- public:
- BufferedStringBinder(
- size_t StringPtrOffset, // This is the offset of the const Char* pointer
- size_t StringBuffOffset // This is the offset of the buffer that contains string data
- ) :
- MemberBinderBase( StringBuffOffset ),
- m_StringPtrOffset( StringPtrOffset )
- {
- }
-
- virtual void GetValue( lua_State *L, const void* pBasePointer )
- {
- // Always use const Char* pointer to push value to Lua as there
- // might be no valid buffer
- auto *StringPtr = GetMemberByOffest<const Char*>( pBasePointer, m_StringPtrOffset );
- PushValue<const Char*>( L, StringPtr );
- }
-
- virtual void SetValue( lua_State *L, int Index, void* pBasePointer )
- {
- // When reading the string from Lua, we need to make
- // sure that the string pointer contains the right data
- auto SrcString = ReadValueFromLua<String>( L, Index );
- // Set the const Char* pointer
- auto &DstStrBuff = GetMemberByOffest<String>( pBasePointer, m_MemberOffset );
- auto &DstStringPtr = GetMemberByOffest<const Char*>( pBasePointer, m_StringPtrOffset );
- DstStrBuff = SrcString;
- DstStringPtr = DstStrBuff.data();
- }
- protected:
- size_t m_StringPtrOffset;
- };
-
-#define DEFINE_BUFFERED_STRING_BINDER(BindingsMap, Struct, StringPtr, StringBuffer) \
- {\
- auto *pNewBinder = new BufferedStringBinder( offsetof( Struct, StringPtr ), offsetof( Struct, StringBuffer ) ); \
- /* No need to make a copy of #Member since it is constant string. */ \
- /* HashMapStringKey will simply keep pointer to it */ \
- BindingsMap.insert( std::make_pair( #StringPtr, std::unique_ptr<MemberBinderBase>(pNewBinder) ) ); \
- }
-
- // Object description wrapper that provides storage for
- // the Name field
- template<typename ObjectDescType>
- struct ObjectDescWrapper : ObjectDescType
- {
- String NameBuffer;
- };
-}