This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
Jyzarc's profile picture

Not sure if this is a bug...

Started by Jyzarc, 17 January 2014 - 02:05 PM
Jyzarc #1
Posted 17 January 2014 - 03:05 PM
Ok so this is a fairly large program, my apologies for that. This is also still a WIP so some of the code will be rewritten to be a little cleaner. Basically to sum up how the program SHOULD work, you configure a couple variables and tables at the top, then the computers will be able to send RS signal updates through modems. So if computer A is on the same frequency as computer B and, and A got an input signal, it would send a message to B to update. To do this, there is a "stack", so if you have multiple inputs, each input would add to the stack if it turned on, and remove if it turns off. That all works fine and well. The problem I am having is with computers outputting on startup. So every time the stack gets updated the computer saves it to memory, then when it starts up again, it is supposed to update the signal. Here is the strange part, the stack gets saved and everything if fine and good, but it does not update the signal. I tested this by printing out various variables when that part of the code was reached. The even weirder part is, even if lets say the stack is at 3, and the output doesnt turn on for whatever reason, if a 4th computer sends a signal the output still won't turn on. The "stack" has to reach 0, then after that all updates work as they should. Another odd thing, is that when I exit the program with ctrl+t the RS updates and it starts outputting the right signal. I cant figure out for the life of me why this is happening or how to fix it. Also if you have any other suggestions for making my code a little better, feel free.

Code: http://pastebin.com/YHmTWFdi

Edit: I haven't done my error checking code yet, but make sure that any input sides are not output sides as well and vice versa, by default both are "all", so you will need to change that, everything else should run fine straight away.
Edited on 17 January 2014 - 02:10 PM
Bomb Bloke #2
Posted 18 January 2014 - 07:24 PM
The main issue I see is that you don't save your "lastState" values.

Say you've got two computers running your default config, but rigged so that only some sides take input and only some are used for output. You start the script on both, and then enable a redstone signal to one. "digital.lastState" on that system gets set to true. This means that if you disable the redstone signal, digital.get() will return -1.

But if you reboot both computers before disabling the signal, "digital.lastState" is now false - that means if you then disable the signal, digital.get() will return 0.

Another issue is that the systems don't save what their inputs are doing. This means that if a computer is receiving a signal, gets shut down and then has that signal removed, when it boots back up it's got no way of knowing that it's supposed to immediately notify the other computer to reduce its stack.

Things get more complicated when you take into account that the systems are unlikely to all be up and running at the same moment - signals sent immediately on startup may not be received at all as a result. It may be worth coding a system whereby computers joining a frequency request a status update from other computers already on that frequency, instead of relying on saved stack data (that is to say, they should only save info about what their own redstone inputs were doing, not try to save data about what the other computer's redstone inputs were doing).

A couple of other points that don't matter:

Rather then constantly checking whether INPUT_SIDES[1] == "all" etc, you could just do it once during startup(), and if true, build new tables which literally contain all sides in them. This'd allow you to simplify the loops throughout the rest of your code, shrinking it down a little.

Also, you're able to reduce code like this:

        if OUTPUT_LOGIC[1] == "r" then
                if digital.stack >= OUTPUT_LOGIC[2]
                and (digital.stack <= OUTPUT_LOGIC[3]
                or OUTPUT_LOGIC[3] == 0) then
                        digital.updateSignal(true)
                else
                        digital.updateSignal(false)
                end
        elseif OUTPUT_LOGIC[1] == "l" then
                for i = 1,#OUTPUT_LOGIC-1 do
                        digital.temp = digital.temp or digital.stack == OUTPUT_LOGIC[i+1]
                end
                if digital.temp then
                        digital.updateSignal(true)
                else
                        digital.updateSignal(false)
                end
        end

Could be reduced somewhat:

        if OUTPUT_LOGIC[1] == "r" then
                digital.updateSignal(digital.stack >= OUTPUT_LOGIC[2]
                and (digital.stack <= OUTPUT_LOGIC[3]
                or OUTPUT_LOGIC[3] == 0))
        elseif OUTPUT_LOGIC[1] == "l" then
                for i = 1,#OUTPUT_LOGIC-1 do
                        digital.temp = digital.temp or digital.stack == OUTPUT_LOGIC[i+1]
                end
                digital.updateSignal(digital.temp)
        end