I got the following code which work great and do exactly what I want in Lua 5.1, however trying to port that to 5.2 (and the lack of LUA_GLOBALSINDEX) Im having issues... Anybody can tell me what is the equivalent of:
thread->L = lua_newthread( G );
lua_pushvalue( G, -1 );
thread->index = luaL_ref( G, LUA_REGISTRYINDEX );
lua_newtable( thread->L );
lua_newtable( thread->L );
lua_pushliteral( thread->L, "__index" );
-- Problem... no more LUA_GLOBALSINDEX, cannot find equivalent for push.
lua_pushvalue( thread->L, LUA_GLOBALSINDEX );
lua_settable( thread->L, -3 );
lua_setmetatable( thread->L, -2 );
-- Problem... no more LUA_GLOBALSINDEX, cannot find equivalent for replace.
lua_replace( thread->L, LUA_GLOBALSINDEX );
in Lua 5.2?
Tks!
You should use lua_pushglobaltable(thead->L) (or if you have to, lua_rawgeti(thread->L, LUA_REGISTRYINDEX, LUA_RIDX_GLOBALS). This is explained in the accepted answer to Lua 5.2 LUA_GLOBALSINDEX Alternative.
Related
Im new to Lua and can only just really read it, mainly just interpreting. I was having an error with a modification for Garrys mod where a lightsaber mod I had installed worked on client side but was invisible on server side. This is because of settings, ect. I asked on his group and he told me this :
You must call these functions on the weapon right after spawning it:
self:SetMaxLength( 42 )
self:SetCrystalColor( Vector( 255, 0, 0 ) )
self:SetDarkInner( false )
self:SetWorldModel( "models/... etc" )
self:SetBladeWidth( 2 )
self.LoopSound = "sound/lightsaber/..."
self.SwingSound = "sound/lightsaber/..."
self:SetOnSound( "sound/lightsaber/..." )
self:SetOffSound( "sound/lightsaber/..." )
self.WeaponSynched = true
Where self is the weapon.
So I put it into the code. All this does is completely remove the lightsaber and give me this error:
[ERROR] lua/weapons/weapon_lightsaber.lua:44: attempt to index global 'self' (a nil value)
1. unknown - lua/weapons/weapon_lightsaber.lua:44
Here is the pastebin of the code : http://pastebin.com/Y8kmivuv
Try using 'SWEP' instead of 'self'. self is usually defined in object-orientated code, which uses metatables in Lua.
I am trying to create an Lua addon for Garry's Mod but I keep coming across an error in my code.
This is my code:
function say (Player, text, ent)
s = "/misc/custom/"..text
s2 = s..".mp3"
sound.PlayFile(s2)
end
hook.Add("PlayerSay", "Say", say)
And this is the resulting error.
[saysoundtest25] lua/autorun/chatsounds.lua:4: attempt to call field 'PlayFile' (a nil value)
1. v - lua/autorun/chatsounds.lua:4
2. unknown - lua/includes/modules/hook.lua:84
Any ideas?
User Robotboy655 on Facepunch helped me solve this! The final code:
hook.Add( "PlayerSay", "Say", function( ply, text, team )
BroadcastLua( 'surface.PlaySound("misc/custom/' .. text .. '.mp3")' )
end )
Thanks everyone for the help!
The /lua/autorun file is serverside and there is a variable sound server-side Lua, however only in client side does sound.PlayFile exist.
if SERVER then
AddCSLuaFile() -- We're the server running this code! Let's send it to the client
else -- We're a client!
-- Your code here, only ran by the client!
end
See the Garry's Mod wiki for more info and note the orange box on the page which means it's client side.
Please remember to check what the function takes also:
sound.PlayFile( string path, string flags, function callback )
Example (taken from the wiki)
sound.PlayFile( "sound/music/vlvx_song22.mp3", "", function( station )
if ( IsValid( station ) ) then station:Play() end
end )
Also more easy way of searching the docs:
http://glua.me/
http://glua.me/docs/#?q=sound.PlayFile
How DarkRP handles this:
https://github.com/FPtje/DarkRP/blob/master/gamemode/modules/chatsounds.lua#L275
I'm using a Lua Protected call, but I'm getting an unprotected error:
lua_getfield( m_L, LUA_GLOBALSINDEX, "startIteration" ); // 1
if( lua_isfunction( m_L, -1 ) ){
lua_pushnumber( m_L, n ); // 2
auto ret = lua_pcall( m_L, 1, 0, 0 ); // 0
checkLuaReturn( m_L, ret );
}else{
lua_pop( m_L, 1 ); // 0
}
And the error is:
PANIC: unprotected error in call to Lua API (../example/ex01.lua:31: attempt to index global 'raster' (a nil value))
And the Lua code is:
function startIteration( num )
io.write( "Start iteration " .. num .. "\n" )
raster.grass.save( "output.png" )
end
How can I solver it, to get a REAL protected call?
update: fixed extra pop
It seems like this has nothing to do with your lua_pcall() but rather with your lua code.
The line raster.grass.save( "output.png" ) is where the error is.
Try channging that to something like this:
if raster and type(raster) == 'table' then
if raster.grass and type(raster.grass) then
raster.grass.save()
end
end
But, that's not going to solve your issue, the issue is that you're calling a member of the variable raster before raster was even created.
I had the same problem, and it stumped me for a while. The answer on this thread misses the point of the question. OP is using lua_pcall, yet is still receiving an unprotected error.
In my case, the Lua stack was corrupted. I ran a function that did not return a value, but popped a value off the stack anyway. Later, when I ran lua_pcall on an unrelated function, I got an unprotected error. Correcting the error of popping off the stack fixed it.
bail:
if ( err && image ) {
CGImageRelease( image );
image = NULL;
}
if ( provider ) CGDataProviderRelease( provider );
if ( colorspace ) CGColorSpaceRelease( colorspace );
*imageOut = image;
return err;
I looked at some code and found this. I have never seen this before. What does bail: mean?
It comes from here.
It's a label that the goto statement jumps to.
The code you're looking at, SquareCamViewController.m, uses a macro named require, like this:
require( error == nil, bail );
This macro is defined in the AssertMacros.h header file. It takes a label as its second argument, and uses goto if the first argument evaluates to false.
Using goto to jump to cleanup code at the end of a function is the most common use of goto and labels in C.
bail: is a label. This is standard C syntax. It's not used very often in properly written code. It's most common use is with goto. Please avoid using goto. In the code you referenced it is used by the require function. If the require fails, the code will jump ahead to the bail label, skipping all of the other code in between.
Using the D3DX library that is a part of directX, specifically directx9 in this case, I'm wondering if it's safe to use the same matrix (or vector etc) for input and ouput
D3DXMATRIX mat;
D3DXMatrixInverse(&mat, NULL, &mat);
I've been avoiding doing so, assuming that it would result in bad things happening when parts of the array got partly overwritten as results are calculated but I see an awful lot of code around that does exactly this.
A brief test indicates that it seems to work ok, so I'm assuming that the D3DX functions take a copy where necessary of the input data, or some other method to ensure that this works ok, but I can't find it documented anywhere so I'm reluctant to rely on it working.
Is there any official statement on using the functions like this?
Yes, it is. From msdn:
Each of the functions can take the same object as the passed [in] and returned [out] parameters
I'm pretty sure the answer is yes. I can't find anywhere where this is said for sure however ...
Edit: Flicking through D3DX9Math.inl it looks like care HAS been taken to make sure you can. For example if we look at the code for D3DXVec3Cross:
D3DXINLINE D3DXVECTOR3* D3DXVec3Cross
( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV1, CONST D3DXVECTOR3 *pV2 )
{
D3DXVECTOR3 v;
#ifdef D3DX_DEBUG
if(!pOut || !pV1 || !pV2)
return NULL;
#endif
v.x = pV1->y * pV2->z - pV1->z * pV2->y;
v.y = pV1->z * pV2->x - pV1->x * pV2->z;
v.z = pV1->x * pV2->y - pV1->y * pV2->x;
*pOut = v;
return pOut;
}
You can see that it performs the cross product into a temporary and THEN, in the final step, it copies it into the return. It would be nice if this was stated somewhere for sure.