ryobg / JContainers

JSON-based data structures for Papyrus - the TESV Skyrim SE scripting language
MIT License
107 stars 23 forks source link

Bitwise operations? #27

Closed RealAntithesis closed 6 years ago

RealAntithesis commented 6 years ago

Are bitwise operations included in the Lua implementation? I'm not sure if JContainers uses lua 5.2 or 5.3 (or other?) but bit32.bxor(x,y), x & y etc output errors in the log. I tried the following:

JValue.evalLuaInt(0, "return bit32.bxor(8, 2, 10)")

but got the following error:

Lua error: [string "local args = ...; local jobject = args;return..."]:1: attempt to index global 'bit32' (a nil value) Lua trace: stack traceback: [C]: in function '__index' [string "local args = ...; local jobject = args;return..."]:1: in function 'predicate' ...Special Edition/Data/SKSE/Plugins/JCData/lua/jc/init.lua:50: in function 'func' ...ion/Data/SKSE/Plugins/JCData/InternalLuaScripts/init.lua:202: in function <...ion/Data/SKSE/Plugins/JCData/InternalLuaScripts/init.lua:199>

Note that the example above is also the example included in the JContainers documentation. On the other hand, JValue.evalLuaInt(0, "return math.pi")) is fine (no error and returns the integer '3'). Maybe it's something I'm doing wrong? Thanks.

ryobg commented 6 years ago

It is Lua 5.1

I see that there is some bxor but maybe it is bit.bxor and not bit32.bxor (for Lua 5.2, in 5.3 it is gone as there is native operator for it).

I can't try myself currently though.

RealAntithesis commented 6 years ago

Thanks for that. I did try "bit" and got the same error. I ended up doing a custom BitAnd function, which seems to work (Google and StackOverflow to the rescue): “Bitwise AND” in Lua

function AH_Hotkeys.BitAnd(a, b) local result = 0 local bitval = 1 while a > 0 and b > 0 do if a % 2 == 1 and b % 2 == 1 then -- test the rightmost bits result = result + bitval -- set the current bit end bitval = bitval * 2 -- shift left a = math.floor(a/2) -- shift right b = math.floor(b/2) end return result end

This is probably a bit slower than a compiled library/native implementation though (probably still way faster than papyrus, especially when the iteration is being done from within the Lua script rather than papyrus). I'm using this to iterate though the entire player inventory list consisting of JMaps, which could be upwards of hundreds of items (about 600 items for me currently).

ryobg commented 6 years ago

Hmm... there is a bit faster & simple way with NAND logic, but maybe it is not so important as I have found out that the bit.* lib is not included by default as part of the evalLua environment. In the next release you will have that library available. Note it will be bit.bxor and not bit32.bxor though - I will correct the examples.

RealAntithesis commented 6 years ago

Thanks for that, much appreciated :)

ryobg commented 6 years ago

Done.