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

[Question] Best way to define / calculate positions for buttons?

Started by Goof, 23 April 2014 - 03:27 PM
Goof #1
Posted 23 April 2014 - 05:27 PM
IMPORTANT NOTE:

This is now closed, since i dont think this will come to an end…
This is being more like a discussion of "coding skills" instead of actually solving the problem.
However, i know i'm not a good coder at all, but i would still like some respect, instead of someone. pointing me down and
directly saying im bad. We're all the same, but with different skills and knowledge. Why point down the ones who doesnt give the best solution?

Im not going to discuss this any further.

Thanks for reading




SpoilerHello Everyone.


While i was making the Nexus portal code for Cranium's server, i decided to check if there is a "best"
way to define positions for buttons created on a monitor ( to resize to monitor )

Currently i use some variables as follows:

local colonsPerPage = 3 -- It should explain itself
local rowsPerColon = 12 -- Still should explain itself
local currentColon = 1 -- used to go through all colons and combine pages
local currentRow = 1 -- used to count which position to use in X

local destinationsPerPage = colonsPerPage * rowsPerColon


Then i just add 3 ( the height of a button ) to the currentRow…

But is this the most effiecent way to do so?


Thanks in Advance

( Btw: im going to watch this thread again in 4 hours )
Edited on 24 April 2014 - 07:14 PM
Lyqyd #2
Posted 23 April 2014 - 05:45 PM
It's "column", not "colon", FYI.

I'd think it would be better to define a button size and spacing, then simply place as many buttons on the screen as possible, given the screen size. Pagination would be automatic. This seems like the most adaptable solution, allowing you to fit more buttons on a larger monitor, or fewer on a smaller one, rather than trying to keep the button count constant and resizing them.
Goof #3
Posted 24 April 2014 - 03:42 PM
First of: Sorry for the late answer
On topic:
Hmm Okay, i managed to do all that stuffz, but im not sure how to do "multiple" pages on the monitor, if the monitor is completely filled with buttons.


And inside the same code, im having trouble with a os.startTimer( x ) event. ( its not equal to the started timer )

code:
pastebin.com/jwc8y1gu

Are you able to see why the os.startTimer doesnt fire the event with the matching timer?

( line 102 - 110 )


Thanks in Advance
CometWolf #4
Posted 24 April 2014 - 04:22 PM
I can't see anything that would cause the aforementioned behavior, provided you're not causing any events of your own, which would start another timer and overwrite the current ID. I do wonder however, why are you defining the global variable updateInterval as nil, then storing the timer ID in the local variable updateInterval? Also, you got an unusual style of calling api calling, and OMG what happened at the lines 15-20 lol
Goof #5
Posted 24 April 2014 - 04:28 PM
I know im using another way of calling apis… but thats just how i like it sometimes.

And line 15-20 is my Button program ( just smalled down to 5 lines xD ) ( else it would fit a lot of lines )

And im making the updateInterval nil, just for checking. ( if it receives a message 1.7 seconds later and then I forgot that the updateInterval variable is getting overwritten by the os.startTimer() )


But i still dont know that weird behavior of that timer event not working properly.

Is this a bug to computerCraft itself?
CometWolf #6
Posted 24 April 2014 - 06:30 PM
The one which you actually use would be overwritten regardless, and the 2 are not the same variable. I still fail to see the purpose.

do
  updateInterval = "derp" --points to _G.updateInterval
  local updateInterval = "herp" --local variable updateInterval
end
print(updateInterval)
--prints derp

Does it not print "TimerEvent!"?
Edited on 24 April 2014 - 04:32 PM
Goof #7
Posted 24 April 2014 - 06:42 PM
It indeed prints timerEvent… but the event argument is never the same as "updateInterval"'s

Btw… Updated pastebin code with the edited code … ( no major changes )
CometWolf #8
Posted 24 April 2014 - 06:58 PM
Id suggest you add the following to the failed timer part

print(e[2])
print(updateInterval)
However chances are the issue is simply caused by another event being fired before your timer. This will cause updateInterval to be overwritten, and it has to wait another 5 seconds. Adding a print where it starts the timer aswell would probably reveal this to you.
Edited on 24 April 2014 - 04:58 PM
Goof #9
Posted 24 April 2014 - 08:05 PM
Hmmm… that actually prints out useful data… but the values are SO close to eachother… ( like within 200 in difference )

e[2] = 3928
updateInterval = 3927

… so in this case its so small difference…


Whats the sourcecode for os.startTimer(x) ? maybe there is a way to find out the weirdness by lookin through that.


Thanks
Edited on 24 April 2014 - 06:05 PM
Lyqyd #10
Posted 24 April 2014 - 08:19 PM
Please post the latest version of your code. I'm not sure why you keep trying to blame ComputerCraft for your bad code. I would be highly surprised if you found an issue with code paths that many, many people use very often without any problems.
Bomb Bloke #11
Posted 25 April 2014 - 01:32 AM
However chances are the issue is simply caused by another event being fired before your timer. This will cause updateInterval to be overwritten, and it has to wait another 5 seconds. Adding a print where it starts the timer aswell would probably reveal this to you.

It's this. You shouldn't be starting a new timer until the previous one has been acted on.

That is to say, this structure:

  while true do
    pingTimeout = os[ "startTimer" ]( updatefreq )
    local e2 = { os[ "pullEvent" ]( "timer" ) }
    if e2[ 1 ] == "timer" then
      if e2[ 2 ] == pingTimeout then
        .
        .
        .
      end
    end
  end

Should be changed into this structure:

  pingTimeout = os[ "startTimer" ]( updatefreq )
  while true do
    local e2 = { os[ "pullEvent" ]( "timer" ) }
    if e2[ 1 ] == "timer" then
      if e2[ 2 ] == pingTimeout then
        .
        .
        pingTimeout = os[ "startTimer" ]( updatefreq )
      end
    end
  end

By the way, I'm not sure why you're using this sort of thing:

os[ "startTimer" ]( updatefreq )

… but if you're thinking it's more efficient, "os.startTimer( updatefreq )" would in fact execute faster.

Edit:

The timer thing may call for more explanation.

Remember that you're running two sets of functions via the parallel API, and both are starting timers. Each co-routine gets its own copy of the event queue. Pulling an event out of one co-routine's copy of the queue does not pull it from the other co-routine's copy. Whenever an event is fired, it goes into BOTH copies of the queue, regardless as to which co-routine triggered it. Since you're setting timers all over the place you should hence be able to see why your code was messing up.

Even if you weren't using the parallel API, you should always account for the possibility that something entirely external to your code may be firing off new timers.

Another point, I'm not sure what's with the "if e2[ 1 ] == "timer" then" check. You've already filtered the os.pullEvent() call to only return timer events.
Edited on 24 April 2014 - 11:46 PM