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

touchpoint:13: vm error: java.lang.NegativeArraySizeException

Started by TreeOfSecrets, 16 June 2016 - 08:57 PM
TreeOfSecrets #1
Posted 16 June 2016 - 10:57 PM
I just began using ComputerCraft for the first time yesterday, although I have a little experience with coding beforehand. I wanted to make a program where a monitor displayed information about my Big Reactor such as RF/tick, energy stored, fuel remaining, etc. I completed this with no problem. The other half I wanted was a separate page that had buttons that allowed me to turn on and off the reactor and adjust the level of fuel rod insertion. I implemented a button that moved to a separate page with little to no problems, and the same thing goes for a reactor on/off button, all using Lyqyd's Touchpoint API (I haven't changed his API whatsoever).

Unfortunately when I went to display the current fuel rod insertion level, it threw the error "touchpoint:13: vm error: (next line) java.lang.NegativeArraySizeException"
Oddly enough I used the exact same code as I did on the statistics page, which worked fine, to create this "button" (the function is nil, it's basically just text. I haven't implemented the actual changing of the insertion level yet) that displays the current fuel rod insertion level except I have it under a different page.


Here is my code: http://pastebin.com/J6UUWKf4


Basically I wrote

stats:add(("Rod Insertion: "..tostring(reactor.getControlRodLevel(1)).."%"), nil, 1, 6, 22, 6, colors.black, colors.black)

(line 29)
for the statistics page (which worked fine, no errors) and I wrote

control:add(("Control Rod Insertion: "..tostring(reactor.getControlRodLevel(1)).."%"), nil, 1, 3, 20, 3, colors.black, colors.black)
for the control page, again keep in mind this is just to display the insertion level so the user can see what it is as they're adjusting the insertion level.

For the touchpoint, you can simply look at Lyqyd's Touchpoint API found at http://www.computerc...touchpoint-api/ .

And again, the error is "touchpoint:13: vm error: (next line) java.lang.NegativeArraySizeException". If anyone has an explanation of why it is doing this and what I can do to fix my code, please let me know. I apologize if this post was poorly put together or against some rule or another, I just joined this community. Thank you for your help!
KingofGamesYami #2
Posted 17 June 2016 - 12:25 AM
Anything with java.lang in the error message is pretty bad. There's no reason for touchpoint to throw that on line 13.

Looking up the error tells me that particular error means a java program attempted to create a negatively sized array. I'm going to point the finger at your Reactor mod, or whatever mod is providing peripheral support for it. In this particular case, I doubt it's your fault and I'm not sure there's any way to prevent it. It would be able to occur just about anywhere in your running code, as with computercraft's "Terminate" functionality (hold control+t).

I apologize if I'm incorrect, as I don't have your modlist and wouldn't download it to test either way.
Bomb Bloke #3
Posted 17 June 2016 - 02:53 AM
Anything with java.lang in the error message is pretty bad. There's no reason for touchpoint to throw that on line 13.

It calls string.rep(), which can't operate on negative values. In the case of touchpoint, a negative value will be used if the button label length exceeds the button length.

The line used for the "control" page is trying to stick a minimum of 25 characters into a button with a length of 20.
TreeOfSecrets #4
Posted 17 June 2016 - 04:23 AM
It calls string.rep(), which can't operate on negative values. In the case of touchpoint, a negative value will be used if the button label length exceeds the button length.

The line used for the "control" page is trying to stick a minimum of 25 characters into a button with a length of 20.

I changed the button label to be shorter and increased the Xmax to 29, so it should be a button with a length of 29 and a label length of about ~15, but it's still throwing the same error. Here's the new line of code:

control:add(("Rod Insertion: "..tostring(reactor.getControlRodLevel(1)).."%"), nil, 1, 3, 29, 3, colors.black, colors.black)
Edited on 17 June 2016 - 06:23 AM
TreeOfSecrets #5
Posted 17 June 2016 - 06:01 AM
The line used for the "control" page is trying to stick a minimum of 25 characters into a button with a length of 20.
Ignore my first reply to you, I "fixed" the wrong line of code, it's displaying correctly now.

However I implemented changing the fuel rod insertion levels, which works, but when I went to make it so it would update the display whenever you changed the insertion level, I got another weird error message. Basically I was testing it using the button for decreasing the fuel rod insertion level. Increasing the insertion worked fine, turning the reactor on and off worked fine, flipping the pages between statistics and controls worked fine, but when I hit the decrease rod insertion button, it would decrease it by 10% (just like I wanted) but then it would not allow me to use any of the buttons any more, and it sent the following error message: "touchpoint:129: attempt to index ? (a nil value)"

I know that attempt to index ? (a nil value) is a common mistake, especially for noobs, but I can't figure out what I did wrong, or what information I gave to the API incorrectly. Sorry for continuing to bug you, but I would greatly appreciate your help! Here's my entire program again:
http://pastebin.com/fxN5kxtv

and here's the specific line of code that updates the display:

control:rename(("Rod Insertion: "..tostring(reactor.getControlRodLevel(1)).."%"), ("Rod Insertion: "..tostring(reactor.get(ControlRodLevel(1)).."%"))
Bomb Bloke #6
Posted 17 June 2016 - 07:42 AM
That line appears to be attempting to update a button with the new label to the same new label. Since a button with the new label is unlikely to already exist at that point, I imagine that's where the error's coming from.

I'm guessing something like this should sort it:

local function fuelrodup()
	local oldLabel = "Rod Insertion: "..tostring(reactor.getControlRodLevel(1)).."%"
	reactor.setAllControlRodLevels(reactor.getControlRodLevel(1)+10)
	control:rename(oldLabel, "Rod Insertion: "..tostring(reactor.getControlRodLevel(1)).."%")
end

local function fuelroddown()
	local oldLabel = "Rod Insertion: "..tostring(reactor.getControlRodLevel(1)).."%"
	reactor.setAllControlRodLevels(reactor.getControlRodLevel(1)-10)
	control:rename(oldLabel, "Rod Insertion: "..tostring(reactor.getControlRodLevel(1)).."%")
end
TreeOfSecrets #7
Posted 23 June 2016 - 06:21 AM
Hey, I'm back! Hopefully you will see this reply. I've gotten everything to work so far, but right now I'm having problems with two things: One, getting the statistics page to constantly update so the information is accurate, and two, having the reactor automatically shut off when it is full (the reactor has an internal capacity of 10 million RF, so I just checked if it was above 9.5 million RF).

Neither seems to be working, and it's not throwing me any error messages either. Here's the new pastebin for my code:
http://pastebin.com/mCaddGRk

I'm doing both things in the while true do loop at the bottom of my code, although the initial variable assignments for the reactor statistics are near the middle/top of the code.
I tried messing around with both quite a bit to get it to work but to no avail. Any tips?
Bomb Bloke #8
Posted 23 June 2016 - 10:06 AM
Line 71 has the script waiting until an event occurs; currently you're reliant on user input for those. Check into os.startTimer().
TreeOfSecrets #9
Posted 24 June 2016 - 11:58 AM
So I'm having more trouble, what else is new?

I was a little bit confused with how os.startTimer() works at first, but I think I figured it out now. I thought the problem was that there were multiple events for the os to pull because of the timer and the button click (especially since the button to switch to reactor controls no longer works) and I tried to fix this by having the pullevent meant for the timer to look for the timer specifically and… it didn't work. Maybe I'm not supposed to have the button check inside the os timer check if>then statement, or maybe I should have the check for the amount of energy in the reactor in the timer statement and the button on its own, I'm just starting to get more confused than ever. Again, I'm a noob, so thank you for all the help you can give me.

I mentioned my problem and what I thought the cause was to someone who has had a little experience in CC before and they said maybe I should check out the parallel api or the coroutine api, but I'm not so sure that this is actually my problem so I don't want to invest a lot of time into those api's.

A thorough explanation of how I need to use the os.startTimer() and where I should put some of my if>thens would be super great! Thank you for any help you can give!

Here's my code: http://pastebin.com/22HmiwXi
Bomb Bloke #10
Posted 24 June 2016 - 01:32 PM
Instead of:

  local eventt, ID = os.pullEvent("timer")
  local event, p1 = page:handleEvents(os.pullEvent())
  if eventt == "timer" and ID == MyTimer then
    if event == "button_click" then
      page.buttonList[p1].func()
    end
  end

… do:

  local event, p1 = page:handleEvents(os.pullEvent())

  if event == "button_click" then
    page.buttonList[p1].func()
  elseif event == "timer" and p1 == MyTimer then
    MyTimer = os.startTimer(1)
  end

page:handleEvents() accepts data about an event, and either returns that same data or a new event representing a button click (depending on whether the original event was a mouse click aimed at one of your buttons or not).
Edited on 24 June 2016 - 11:35 AM