int ShaderResourceBindingParser::BindResources( lua_State *L ) { try { auto NumArgs = lua_gettop( L ); if( NumArgs < 3 ) { SCRIPT_PARSING_ERROR( L, "At least 2 arguments (shader flags and resource mapping) are expected" ); } int ArgStackInd = 1; auto *pResBinding = *GetUserData<IShaderResourceBinding**>( L, ArgStackInd, m_MetatableRegistryName.c_str() ); VERIFY( pResBinding, "Resource mapping pointer is null" ); if( !pResBinding )return 0; ++ArgStackInd; Uint32 ShaderFlags = 0; { FlagsLoader<SHADER_TYPE> FlagsLoader(0, "BindShaderResourceFlags", m_ShaderTypeEnumMapping); FlagsLoader.SetValue( L, ArgStackInd, &ShaderFlags ); } ++ArgStackInd; auto *pResourceMapping = *GetUserData<IResourceMapping**>( L, ArgStackInd, m_ResMappingMetatableName.c_str() ); if( !pResourceMapping ) { SCRIPT_PARSING_ERROR( L, "Incorrect 2nd argument type: resource mapping is expected" ); } ++ArgStackInd; Uint32 Flags = 0; // The last argument may be flags if( NumArgs >= ArgStackInd && (lua_type( L, ArgStackInd ) == LUA_TSTRING || lua_type( L, ArgStackInd ) == LUA_TTABLE ) ) { FlagsLoader<BIND_SHADER_RESOURCES_FLAGS> FlagsLoader(0, "BindShaderResourceFlags", m_BindShaderResFlagEnumMapping); FlagsLoader.SetValue( L, ArgStackInd, &Flags ); } pResBinding->BindResources( ShaderFlags, pResourceMapping, Flags ); } catch( const std::runtime_error& ) { } return 0; }
int EngineObjectParserBase::LuaCreate( lua_State *L ) { INIT_LUA_STACK_TRACKING( L ); EngineObjectParserBase *This = static_cast<EngineObjectParserBase *>(lua_touserdata( L, lua_upvalueindex( 1 ) )); // This pointer cannot be null because we stored it in an up value when created the library VERIFY( This, "This pointer is null" ); if( !This )return 0; try { This->CreateObj( L ); } catch( const std::runtime_error &err ) { SCRIPT_PARSING_ERROR( L, "Failed to create ", This->m_LibName, " object: \n", err.what() ); } // Push onto the stack the metatable associated with name given in the registry luaL_getmetatable( L, This->m_MetatableRegistryName.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 CHECK_LUA_STACK_HEIGHT( +1 ); // Return number of return arguments // New userdatum is on the top of the stack return 1; }
Type ReadIntValueFromLua( lua_State *L, int Index ) { CheckType( L, Index, LUA_TNUMBER ); int isnum; auto Val = lua_tonumberx( L, Index, &isnum ); if( !isnum ) { auto Str = lua_tostring( L, Index ); SCRIPT_PARSING_ERROR( L, "Failed to convert parameter ", Str, " to int" ); } if( static_cast<Type>(Val) != Val ) { SCRIPT_PARSING_ERROR( L, "Parameter value (", Val, ") is not integer. Truncating to int" ); } return static_cast<Type>(Val); }
Type ReadFPValueFromLua( lua_State *L, int Index ) { CheckType( L, Index, LUA_TNUMBER ); int isnum; auto Val = lua_tonumberx( L, Index, &isnum ); if( !isnum ) { auto Str = lua_tostring( L, Index ); SCRIPT_PARSING_ERROR( L, "Failed to convert parameter ", Str, " to floating point" ); } return static_cast<Type>(Val); }
void NumericArrayLoader::LoadArray( lua_State *L, int StackIndex, std::vector< Uint8 >& RawData ) { VALUE_TYPE ValueType; m_ValueTypeBinder.SetValue( L, StackIndex-1, &ValueType ); auto it = m_ParseFuncJumpTbl.find( ValueType ); if( it != m_ParseFuncJumpTbl.end() ) { it->second( L, StackIndex, RawData ); } else { SCRIPT_PARSING_ERROR( L, "No method to parse array of value VALUE_TYPE==", ValueType); } }
void SamplerParser::CreateObj( lua_State *L ) { INIT_LUA_STACK_TRACKING( L ); SSamDescWrapper SamplerDesc; ParseLuaTable( L, -1, &SamplerDesc, m_Bindings ); CHECK_LUA_STACK_HEIGHT(); auto ppSampler = reinterpret_cast<ISampler**>(lua_newuserdata( L, sizeof( ISampler* ) )); *ppSampler = nullptr; m_pRenderDevice->CreateSampler( SamplerDesc, ppSampler ); if( *ppSampler == nullptr ) SCRIPT_PARSING_ERROR(L, "Failed to create a sampler") CHECK_LUA_STACK_HEIGHT( +1 ); }
void TextureViewParser::CreateObj( lua_State *L ) { INIT_LUA_STACK_TRACKING(L); auto *pTexture = *GetUserData<ITexture**>( L, 1, m_TextureLibMetatableName.c_str() ); STexViewDescWrapper TextureViewDesc; ParseLuaTable( L, 2, &TextureViewDesc, m_Bindings ); CHECK_LUA_STACK_HEIGHT(); auto ppTextureView = reinterpret_cast<ITextureView**>(lua_newuserdata( L, sizeof( ITextureView* ) )); *ppTextureView = nullptr; pTexture->CreateView( TextureViewDesc, ppTextureView ); if( *ppTextureView == nullptr ) SCRIPT_PARSING_ERROR(L, "Failed to create texture view") CHECK_LUA_STACK_HEIGHT( +1 ); }
void ParseNumericArray( lua_State *L, int StackIndex, std::vector< Uint8 >& RawData ) { typedef typename VALUE_TYPE2CType<VTType>::CType ElemType; CheckType( L, StackIndex, LUA_TTABLE ); auto ArraySize = lua_rawlen( L, StackIndex ); auto ElemSize = sizeof( ElemType ); RawData.reserve( ArraySize * ElemSize ); ParseLuaArray( L, StackIndex, &RawData, [ &]( void* pBasePointer, int StackIndex, int NewArrayIndex ) { VERIFY( pBasePointer == &RawData, "Sanity check failed" ); auto CurrIndex = RawData.size() / ElemSize; if(static_cast<int>(CurrIndex) != NewArrayIndex - 1 ) SCRIPT_PARSING_ERROR( L, "Explicit array indices are not allowed in array initialization. Provided index ", NewArrayIndex - 1, " conflicts with actual index ", CurrIndex, "." ); RawData.resize( (CurrIndex + 1) * ElemSize ); auto CurrValue = ReadValueFromLua<double>( L, StackIndex ); reinterpret_cast<ElemType&>(RawData[CurrIndex * ElemSize]) = static_cast<ElemType>(CurrValue); } ); }
int ShaderResourceBindingParser::GetVariable( lua_State *L ) { auto NumArgs = lua_gettop( L ); if( NumArgs < 3 ) { SCRIPT_PARSING_ERROR( L, "2 arguments (shader type and variable name) are expected" ); } INIT_LUA_STACK_TRACKING(L); int ArgStackInd = 1; // The object itself goes first auto *pShaderResBinding = *GetUserData<IShaderResourceBinding**>( L, ArgStackInd, m_MetatableRegistryName.c_str() ); // Shader type should be the first argument ++ArgStackInd; SHADER_TYPE ShaderType = SHADER_TYPE_UNKNOWN; EnumMemberBinder<SHADER_TYPE> ShaderTypeParser(0, "ShaderType", m_ShaderTypeEnumMapping); ShaderTypeParser.SetValue(L, ArgStackInd, &ShaderType); ++ArgStackInd; // Variable name should be the second argument auto VarName = ReadValueFromLua<String>( L, ArgStackInd ); auto pVar = pShaderResBinding->GetVariable(ShaderType, VarName.c_str()); auto pNewShaderVarLuaObj = reinterpret_cast<IShaderVariable**>(lua_newuserdata( L, sizeof( IShaderVariable* ) )); *pNewShaderVarLuaObj = pVar; pVar->AddRef(); // Push onto the stack the metatable associated with name given in the registry luaL_getmetatable( L, m_ShaderVarMetatableRegistryName.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 CHECK_LUA_STACK_HEIGHT( +1 ); return 1; }
int TextureViewParser::GetDefaultView( lua_State *L ) { INIT_LUA_STACK_TRACKING( L ); // Texture should be the first argument auto *pTexture = *GetUserData<ITexture**>( L, 1, m_TextureLibMetatableName.c_str() ); // View type should be the second argument TEXTURE_VIEW_TYPE ViewType; m_ViewTypeParser.SetValue( L, 2, &ViewType ); auto pView = pTexture->GetDefaultView( ViewType ); if( !pView ) SCRIPT_PARSING_ERROR( L, "Failed to get default texture view of type ", GetTexViewTypeLiteralName( ViewType ) ); // Push existing object PushObject(L, pView); CHECK_LUA_STACK_HEIGHT( +1 ); // Returning one value to Lua return 1; }
CHECK_LUA_STACK_HEIGHT( +1 ); } void ShaderResourceBindingParser::DestroyObj( void *pData ) { if( pData != nullptr ) { auto ppShaderResBinding = reinterpret_cast<IShaderResourceBinding**>(pData); if( *ppShaderResBinding != nullptr ) (*ppShaderResBinding)->Release(); } } void ShaderResourceBindingParser::ReadField( lua_State *L, void *pData, const Char *Field ) { SCRIPT_PARSING_ERROR(L, "Shader resource binding have no fields that can be read") } void ShaderResourceBindingParser::UpdateField( lua_State *L, void *pData, const Char *Field ) { SCRIPT_PARSING_ERROR(L, "Shader resource binding have no fields that can be updated") } void ShaderResourceBindingParser::PushExistingObject( lua_State *L, const void *pObject ) { auto pShaderResourceBinding = reinterpret_cast<IShaderResourceBinding**>(lua_newuserdata( L, sizeof( IShaderResourceBinding* ) )); *pShaderResourceBinding = reinterpret_cast<IShaderResourceBinding*>( const_cast<void*>(pObject) ); (*pShaderResourceBinding)->AddRef(); }
void EngineObjectParserBase::UpdateField( lua_State *L, void *pData, const Char *Field ) { SCRIPT_PARSING_ERROR( L, "Attempting to update \"", Field, "\" field of a read-only object \"", m_LibName.c_str(), '\"' ); }