Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add bitwise AND, OR and XOR modes to math block #91

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/cache/
/Cache/
/description.json
preview.png
preview.png
Binary file modified Objects/Textures/maths.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
65 changes: 64 additions & 1 deletion Scripts/interactable/NumberLogic/MathBlock.lua
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ MathBlock.modetable = {--"value" aka "savevalue", gets saved, gets loaded.
{value = 29, icon = "seated", name = "Seated" ,description = "Becomes active and outputs the value of input seats occupied"},
{value = 30, icon = "A/D", name = "A/D" ,description = "Outputs the A/D value, range: -1 to 1\nMultiple driverseat inputs: average of A/D output of inputs,\nExcellent for teamwork!"},
{value = 31, icon = "W/S", name = "W/S" ,description = "Outputs the W/S value, range: -1 to 1\nMultiple driverseat inputs: average of W/S output of inputs,\nExcellent for teamwork!"},
{value = 39, icon = "OR", name = "Bitwise OR" ,description = "Outputs a number where each bit is 1 if the corresponding bit of ANY input is 1\n\nNegative inputs are treated as 0, non-integer inputs are rounded"},
{value = 40, icon = "AND", name = "Bitwise AND" ,description = "Outputs a number where each bit is 1 if the corresponding bit of ALL inputs is 1\n\nNegative inputs are treated as 0, non-integer inputs are rounded"},
{value = 41, icon = "XOR", name = "Bitwise XOR" ,description = "Outputs a number where each bit is 1 if the corresponding bit of AN ODD NUMBER of inputs is 1\n\nNegative inputs are treated as 0, non-integer inputs are rounded"},
}
MathBlock.savemodes = {}
for k,v in pairs(MathBlock.modetable) do
Expand Down Expand Up @@ -823,7 +826,67 @@ MathBlock.modeFunctions = {
end
end
self:sv_setValue(power)
end,

[39] = function(self, parents) -- bitiwise or
local bits = {}

for k, parent in pairs(parents) do
local value = math.round(sm.interactable.getValue(parent) or parent.power)
for bit in math.bitsiter(value) do
bits[bit] = true
end
end

local result = 0
for bit, value in pairs(bits) do
if value == true then
result = result + 2 ^ bit
end
end

self:sv_setValue(result)
end,

[40] = function(self, parents) -- bitiwise and
local bitcounts = {}

for k, parent in pairs(parents) do
local value = math.round(sm.interactable.getValue(parent) or parent.power)
for bit in math.bitsiter(value) do
bitcounts[bit] = (bitcounts[bit] or 0) + 1
end
end

local result = 0
for bit, value in pairs(bitcounts) do
if value == #parents then
result = result + 2 ^ bit
end
end

self:sv_setValue(result)
end,

[41] = function(self, parents) -- bitiwise xor
local bits = {}

for k, parent in pairs(parents) do
local value = math.round(sm.interactable.getValue(parent) or parent.power)
for bit in math.bitsiter(value) do
bits[bit] = not bits[bit]
end
end

local result = 0
for bit, value in pairs(bits) do
if value == true then
result = result + 2 ^ bit
end
end

self:sv_setValue(result)
end,
}


Expand Down Expand Up @@ -904,7 +967,7 @@ function MathBlock.client_onInteract(self, character, lookAt)
for i = 0, 23 do
self.gui:setButtonCallback( "Operation" .. tostring( i ), "cl_onModeButtonClick" )
end

for i = 1, 3 do
self.gui:setButtonCallback( "Page" .. tostring( i ), "cl_onPageButtonClick" )
end
Expand Down
35 changes: 34 additions & 1 deletion Scripts/libs/math.lua
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,43 @@ function math.roundby( x, by)

end

--- Returns a stateful iterator function that returns the indexes
--- of the bits of x, from least significant to most significant.
---
--- The iterator returns no bits if x is negative.
--- If x is not an integer, it will be rounded to the nearest integer
--- using math.round().
---
--- Generator complexity: O(log2 x)
function math.bitsiter(x)
x = math.round(x)

if x < 0 then
return function ()
return nil
end
end

local i = 0
return function()
while x % 2 == 0 do
x = math.floor(x / 2)
i = i + 1
if x <= 0 then
return nil
end
end

x = math.floor(x / 2)
i = i + 1
return i-1
end
end

function table.size(tablename)
local i = 0
for k, v in pairs(tablename) do
i = i +1
end
return i
end
end