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

paralell.waitForAny() cursor problems,multiple cursors

Started by grimofdoom, 17 December 2014 - 04:59 AM
grimofdoom #1
Posted 17 December 2014 - 05:59 AM
I am creating a client-to-client chatroom system using broadcast, and when away from computer or at computer, the cursor position does not move on after receiving a message. I tried doing a grabbing cursor position, add 1-2 with y, and then apply for whenever receiving…but this did not work away from computer for it only added gap between printed messages instead of moving of overall. this may be because i am running my two function with parallel, so the cursor does not adjust for both.(removed the cursor stuff. this is annoying for me and my friends when we try and read and type when the typing happens over previously printed text/lines)


rednet.open("left")
function receive()
  while true do
	id,ms=rednet.receive()
	if id~=os.getComputerID() then
	  print("["..id.."] "..msg)
	end
  end
end

function send()
  while true do
	rednet.broadcast(read())
  end
end

while true do
  parallel.waitForAny(receive,send)
end

This is day 3 of my learning LUA and computercraft, sorry if it is not the same format you normaly see. Thank you for taking the time to read this post of a total "newb" at computercraft and LUA
Edited on 17 December 2014 - 05:47 AM
Bomb Bloke #2
Posted 17 December 2014 - 08:43 AM
Remember that if a computer is in an unloaded chunk, it'll shut down (then restart itself when the chunk next loads again).

The main problem I see here is that your print calls can potentially go off while you're busy typing stuff for your read calls. There are a number of ways to deal with this, but assuming you're on CC 1.6 or later, the simplest is probably the window API. It allows you to divide up your screen into multiple "displays", so you can work in one without worrying too much about what's happening in the other (by redirecting ComputerCraft's terminal output between the two of them).

The code might look a little something like this:

rednet.open("left")

local xSize, ySize = term.getSize()  -- Get the size of the whole display.

local incoming = window.create(term.current(), 1, 1, xSize, ySize - 2)  -- A window covering the whole screen minus the last two lines.
local outgoing = window.create(term.current(), 1, ySize, xSize, 1)      -- A window covering just the last line of the screen.

-- Draw a dividing line between the two windows:
term.setCursorPos(1,ySize - 1)
term.write(string.rep("-", xSize))

local function receive()
	while true do
		local id, ms = rednet.receive()
		if id ~= os.getComputerID() and type(ms) == "string" then
			term.redirect(incoming)  -- The larger window is now our "screen".
			print("["..id.."] "..msg)
			term.redirect(outgoing)  -- The one-line window down the bottom of the display is now our "screen".
		end
	end
end

local function send()
	while true do
		term.setCursorPos(1,1)
		rednet.broadcast(read())
	end
end

term.redirect(outgoing)  -- The one-line window down the bottom of the display is now our "screen".

parallel.waitForAny(receive, send)  -- No need to loop this; the functions already loop themselves.
grimofdoom #3
Posted 17 December 2014 - 02:20 PM
I just tried this. I understand the code and all, but the [local incoming=window.createsize(1,1,xsize,ysize-2)] creates the error message [attempt to index?(a nil value)]
I have triple checked and there isn't any noticable errors in copying.
Dog #4
Posted 17 December 2014 - 04:28 PM
If you typed BB's program in via keyboard (instead of copy/paste) then it's likely you made an error. The first thing I would point out is that BB's code has window.create, not window.createsize.
Bomb Bloke #5
Posted 17 December 2014 - 09:51 PM
"window.createsize" would throw an "attempt to call nil" - so long as you're on ComputerCraft 1.6 or later (because there's no "createsize" function in the window API, thus it can't be called).

If you're not up to date, you'll get an "attempt to index nil" as there's no window table to index into (as mentioned, it's not available in older versions).
grimofdoom #6
Posted 17 December 2014 - 11:26 PM
You know, I think that the version is old. I am using tekkit lite, and when I turn on the computer in tekkit, it says 1.5 and not 1.6. Is there a good modpack that has and supports the computercraft 1.6 from technic?
Lyqyd #7
Posted 17 December 2014 - 11:29 PM
I'd move away from Tekkit, to be honest. The Feed The Beast mod packs are very good, and the Direwolf20 modpack for 1.7.10 has the very latest version of ComputerCraft. You can always build your own pack, though!
Bomb Bloke #8
Posted 18 December 2014 - 06:45 AM
You could probably just drop CC 1.63 straight into your current install (while removing the older mod version) - that way you'd probably even be able to keep your world, computers, etc. It's not recommended to update without creating a new world (I've seen a success and I've seen a failure), but it's worth a shot if you backup your current one first.

It also wouldn't surprise me if you could just pull the "window" file from an updated version of the mod archive, stick it on your CC computer's drive, and add an os.loadAPI("window") line to the top of the script. Dunno, haven't tried that tactic myself, though I'd be interested to know if it works…

Updating isn't all roses - the main issue is you won't be able to use any script that wants to make use of bundled cables (that functionality is, for all purposes, gone). Though that might not be an "issue" for you at all. Depends on your needs.

This sort of screen management doesn't need the window API at all, mind you - that's just the "simple" way of doing it (dividing up the display so that functions used in each area can't interfere). The "next easiest" ways would be to re-write either read() or print() so that they can play nicely with each other. Easier said than done, but making a custom read() function is a good exercise for any beginning coder.
Lyqyd #9
Posted 18 December 2014 - 03:28 PM
I believe the built-in window API uses term.current, so it cannot be added to earlier versions unmodified.

Edit: However, it may work to also copy the newer term API back. I'd discourage this as there were unrelated API changes in the 1.6 builds that I (and probably others) use term.current's existence as a simple version check to determine what kind of rednet behavior to use, among other things.
Bomb Bloke #10
Posted 18 December 2014 - 09:36 PM
I must confess I also use the existence of functions to decide whether I'm on 1.6 or not, though we should probably be using os.version() for that. Problem is that function isn't precise (it fails to return that crucial third digit), meaning it usually doesn't fulfil its purpose.

Really what I'd like to see is a version of term that incorporates both term.current() etc and term.restore(). There's no good reason for them to be mutually exclusive. I've been considering making a resource pack for this purpose (and to add in a few other "obvious" functions where appropriate).