Quick Links: Download Gideros Studio | Gideros Documentation | Gideros Development Center | Gideros community chat
Lua: bitwise operators with new metamethods - Gideros Forum

Lua: bitwise operators with new metamethods

n1cken1cke Maintainer
edited August 2016 in Step by step tutorials
With 2016.08 release we get full support of Lua 5.3 bitwise operators and integer division operator:
|  __bor  -- bitwise or (binary)
&  __band -- bitwise and (binary)
~  __bxor -- bitwise exclusive or (binary)
<< __shl  -- bitwise left shift (binary)
>> __shr  -- bitwise right shift (binary)
~  __bnot -- bitwise not (unary)
// __idiv -- integer division (binary)
All operators and their according metamethods are same as Lua 5.3 ones.
Example 1:
This function encodes any integer number (32 bits) to 4 chars to pass it over network later:
local function encodeInt(n)
	local t = {}
	local char = string.char
	t[1] = char(n >> 24 & 0xFF)
	t[2] = char(n >> 16 & 0xFF)
	t[3] = char(n >> 08 & 0xFF)
	t[4] = char(n >> 00 & 0xFF)
	return t:concat()
end
Example 2:
You can use new metamethods same way as old ones:
mt = {
	__bnot = function(t)
		local r = {}
		for i = 1, #t do r[i] = ~t[i] end
		return r
	end
}
t = {1, 2, 3, 4 ,5}
setmetatable(t, mt)
 
print(require"json".encode(~t)) --> [-2,-3,-4,-5,-6]
+1 -1 (+6 / -0 ) Share on Facebook

Comments

  • I'm sorry, i don't get how to switch to the embedded bit manipulation: how would you write the following?
    local flipHor = bit.band(v, FLIPPED_HORIZONTALLY_FLAG)
    local flipVer = bit.band(v, FLIPPED_VERTICALLY_FLAG)
    local flipDia = bit.band(v, FLIPPED_DIAGONALLY_FLAG)
     
    v = bit.band(v, bit.bnot(bit.bor(FLIPPED_HORIZONTALLY_FLAG, FLIPPED_VERTICALLY_FLAG, FLIPPED_DIAGONALLY_FLAG)))
    Thank you
  • hgy29hgy29 Maintainer
    edited September 2016
    local flipHor = v&FLIPPED_HORIZONTALLY_FLAG
    local flipVer = v&FLIPPED_VERTICALLY_FLAG
    local flipDia = v&FLIPPED_DIAGONALLY_FLAG
     
    v = v&(~(FLIPPED_HORIZONTALLY_FLAG|FLIPPED_VERTICALLY_FLAG|FLIPPED_DIAGONALLY_FLAG))

    Likes: pie

    +1 -1 (+1 / -0 ) Share on Facebook
  • piepie Member
    edited September 2016
    Thanks. I will never learn that... :)
    Do I need to do anything on my android player to enable "embedded bit"?
    Just updated isometric tilemap to that.
    I noticed it works as expected on desktop, but it shows a white screen on android, even with custom player with BitOp plugin.
    Here you can find the complete project:
    https://github.com/piretro/Isometric-Tilemap

    thank you
  • 2016.8.2, same release of my gideros studio.
    @SinisterSoft can you please try it on one of your devices to be sure I am not the only one having this issue? (the zip coming from github should be ready to run)

    thank you
  • I've tried it and I think I know what is happening.

    Because you are using bit 31 then on a 32 bit computer it's getting confused as between each operation it has to make it an integer and back again.

    So on the device the result of the or'ed flags will actually be 0xffffffff, so that inverted = 0, so the and'ed value is cleared. On the emulator for some reason (64 bit internal?) it doesn't process after the &, so the result is that the value isn't and'ed with anything, so it stays the same. So on the device the block no is 0, on the emulator the block no is the original number.

    If you used bits 30,29, and 28 then I don't think the problem will occur.
  • Thank you, however in the "old bit library" there is no issue like that on the same device with the same operations.
    I'm sorry @n1cke is this a bug or it is "expected"? :)
    Thank you
  • n1cken1cke Maintainer
    The problem is bit ops are implemented differently (it is not a bug). They work exactly as native C bit ops for 32-bit integers with minimal conversion overhead (to achieve best speed) while bit plugin has more complex implementation. IDK, should we fully simulate bit plugin behavior?
  • SinisterSoftSinisterSoft Maintainer
    edited October 2016
    I think so, if possible. I think that surrounding the operations with &$ffffffff will limit the extension to the bits before the conversion to and from a regular lua number. That might work.

    (i mean on the C side of things)
  • piepie Member
    Thank you both :)
    I don't know what's "better" because I don't know the backgrounds of bit.
    From my user point of view, if SinisterSoft' suggestion will make it retrocompatible without losing the recently gained speed it would be really cool;
    otherwise I could really use your help to "update" isometricTilemap to make it work, if it's possible (I am not even able to determine if it's possible doing it just editing lua code: bits on texture ids are applied by Tiled )
    My other option is to stick to the old bit manipulation, which is what I am doing now.

    Thanks
  • For a quick fix all you have to do is loop through the bits when the map is loaded using the bit library, reading bit 31 and setting/clearing bit 28 instead. Then use the faster method when you actually access the map for real.
  • piepie Member
    I have to say I don't know how to read bit 31 or 28 (I used some common sense to copy the whole bit/flip thing from tiledAsWorldEditor, but I've never really understood it :) )
    However, won't this be overdoing things? I load the map only once, when I place its tiles on stage, so I would just double the operations needed to flip my tiles.

    Thank you
  • So you don't need to read the flip bits whilst the game is running? If not then use the slower lib. If you do then just do the quick patch to the map as it is loaded.

    to read bit 31 you AND with 0x80000000, if the result is not zero then you then set bit 28.

    to set bit 28 you OR with 0x10000000 :)

    Likes: pie

    +1 -1 (+1 / -0 ) Share on Facebook
  • antixantix Member
    edited June 2017
    So how do I actually use this stuff??
    local function encodeInt(n)
    	local t = {}
    	local char = string.char
    	t[1] = char(n >> 24 & 0xFF)
    	t[2] = char(n >> 16 & 0xFF)
    	t[3] = char(n >> 08 & 0xFF)
    	t[4] = char(n >> 00 & 0xFF)
    	return t:concat()
    end
    After pasting that directly into any code I get an error..
    Compilation error on line 260:
    C:\Projects\Gideros\pt101\agui\agui.lua:260: unexpected symbol near '>'
    Follow me on FaceBook Check out my DevBlog, my GitHub, and try my games...
    Falling Animals | Breaky Wall | Exetor | Mini Putt Golfing
  • SinisterSoftSinisterSoft Maintainer
    No error here, what version of Gideros are you using?
  • antixantix Member
    2017.2
    Follow me on FaceBook Check out my DevBlog, my GitHub, and try my games...
    Falling Animals | Breaky Wall | Exetor | Mini Putt Golfing
  • hgy29hgy29 Maintainer

    Compilation error on line 260:
    I've never seen gideros studio ever saying 'compilation error' could it be that you are using ZBS or some other tool that tries to check syntax with a standard lua parser ?

    Likes: antix

    +1 -1 (+1 / -0 ) Share on Facebook
  • antixantix Member
    edited June 2017
    @hgy29, ahh maybe that's exactly the issue since I use ZeroBrane Studio. I'll check that in the morning and report back :)

    If this is the issue then maybe it is something that @paulclinger can lend a hand with ;)
    Follow me on FaceBook Check out my DevBlog, my GitHub, and try my games...
    Falling Animals | Breaky Wall | Exetor | Mini Putt Golfing
  • @antix, the latest version of zbs (maybe you need dev version) handles these operators perfectly for me.

    Likes: SinisterSoft

    +1 -1 (+1 / -0 ) Share on Facebook
  • antixantix Member
    @keszegh, thanks! I was still on ZBS 1.20 :D

    Likes: keszegh

    Follow me on FaceBook Check out my DevBlog, my GitHub, and try my games...
    Falling Animals | Breaky Wall | Exetor | Mini Putt Golfing
    +1 -1 (+1 / -0 ) Share on Facebook
Sign In or Register to comment.