|
View:
New views
10 Messages
—
Rating Filter:
Alert me
|
|
|
Run Io coroutines in background simultaneous to using Io> prompt in foreground?Since it looks like some people are online answering messages right now, I thought I'd ask a quick question of you. :D
For the game engine I'm working on, I want to be able to have the game running Io scripts in a loop or on threads or coroutines, and be able to pop up an Io> prompt at any time and enter new commands. For instance, I want to be able to have the game moving objects around and displaying an OpenGL loop, yet at any alt-tab over to the terminal I launched Io from and type something like "Monster clone do( attackPlayer() )". With the prompt presented by the Io executable, if I type something the prompt goes away until it is done, even if I type something like "o1 @test" to launch a coroutine. Is this a fundamental limitation of Io (can't enter new commands while coroutines are running)? I can think of several approaches; which, if any, are right? 1. Type the right Io code (I don't know what it is) at the Io> prompt to get a background thread and retain the Io prompt. 2. Change the C language portion of the Io executable to always launch Io commands in the background (possibly running commandline input on its own OS thread but all the Io coroutines on the same 2nd thread). 3. Write an Io coroutine method that does its own user input to simulate the Io> prompt, and have that eval input strings as coroutines. Thread createThread("io-string") does exactly what I want in terms of running in the background, but unfortunately it seems these threads do not share the same VM and objects, and the whole point is to be able to manipulate the game objects using an Io> prompt. |
|
|
Re: Run Io coroutines in background simultaneous to using Io> prompt in foreground?On 2009-06-07, at 9:18 PM, dennisf486 wrote: > With the prompt presented by the Io executable, if I type something > the prompt goes away until it is done, even if I type something like > "o1 @test" to launch a coroutine. Is this a fundamental limitation > of Io (can't enter new commands while coroutines are running)? I > can think of several approaches; which, if any, are right? The code that presents the user with the prompt and receives the input line can just call doString(theInputString) and I think it should have the behavior you are looking for. |
|
|
Re: Run Io coroutines in background simultaneous to using Io> prompt in foreground?Thanks that was a big help but it wasn't quite the solution. I was able to make it run a background process simultaneous to generating my own prompt. But that only solves half my problem: "EditLine readLine" is a blocking call, so it still halts other coroutines while waiting at the "fake Io>" prompt. (Because you can't yield between keypresses.) So it still only executes the background loops once per every time I hit the "return" key on a command in the prompt.
I'm thinking maybe I need something like: createThread("loop that does readLine for FakeIo> prompt") @@backgroundCoroutine("do stuff in a loop that yields at the end") loop( check for new command from other thread yield if no new command doString() if there is a command ) But how do I get the string data out of the separate VM on the thread that's displaying the FakeIo> prompt and into the original VM that has the backgroundCoroutines and the doString loop? Shared memory? Pipes? Send it to localhost via TCP/IP through a BSD socket?? For the sake of completeness, here's the test code I've got so far: (The idea is the background coroutine increments n every second, while the foreground prompt can change or print n if you type the right command. The fact that the background coroutine picks up on the change and begins incrementing the new value of n proves the foreground prompt changed a variable in the background coroutine.) n := 1 doBackground := method( loop("N is " print; n println; n = n + 1; wait(1)) ) doPrompt := method( s := ""; loop(println; s = EditLine readLine("FakeIo>"); doString(s); yield) ) @@doBackground doPrompt --- In iolanguage@..., Steve Dekorte <steve@...> wrote: > > > On 2009-06-07, at 9:18 PM, dennisf486 wrote: > > With the prompt presented by the Io executable, if I type something > > the prompt goes away until it is done, even if I type something like > > "o1 @test" to launch a coroutine. Is this a fundamental limitation > > of Io (can't enter new commands while coroutines are running)? I > > can think of several approaches; which, if any, are right? > > The code that presents the user with the prompt and receives the input > line can just call doString(theInputString) and I think it should have > the behavior you are looking for. > |
|
|
Re: Run Io coroutines in background simultaneous to using Io> prompt in foreground?If it is blocking it will block the entire thread (and that IoState).
You will probably have to use non-blocking I/O or communicate between the threads using one of the techniques you mentioned. There is a DistributedObjects addon that might help. Perhaps Steve can give you more detail. On Jun 9, 2009, at 10:09 PM, dennisf486 wrote: > > > Thanks that was a big help but it wasn't quite the solution. I was > able to make it run a background process simultaneous to generating > my own prompt. But that only solves half my problem: "EditLine > readLine" is a blocking call, so it still halts other coroutines > while waiting at the "fake Io>" prompt. (Because you can't yield > between keypresses.) So it still only executes the background loops > once per every time I hit the "return" key on a command in the prompt. > > I'm thinking maybe I need something like: > > createThread("loop that does readLine for FakeIo> prompt") > @@backgroundCoroutine("do stuff in a loop that yields at the end") > > loop( > check for new command from other thread > yield if no new command > doString() if there is a command > ) > > But how do I get the string data out of the separate VM on the > thread that's displaying the FakeIo> prompt and into the original VM > that has the backgroundCoroutines and the doString loop? Shared > memory? Pipes? Send it to localhost via TCP/IP through a BSD socket?? > > For the sake of completeness, here's the test code I've got so far: > (The idea is the background coroutine increments n every second, > while the foreground prompt can change or print n if you type the > right command. The fact that the background coroutine picks up on > the change and begins incrementing the new value of n proves the > foreground prompt changed a variable in the background coroutine.) > > n := 1 > > doBackground := method( > loop("N is " print; n println; n = n + 1; wait(1)) > ) > > doPrompt := method( > s := ""; loop(println; s = EditLine readLine("FakeIo>"); > doString(s); yield) > ) > > @@doBackground > doPrompt > > --- In iolanguage@..., Steve Dekorte <steve@...> wrote: > > > > > > On 2009-06-07, at 9:18 PM, dennisf486 wrote: > > > With the prompt presented by the Io executable, if I type > something > > > the prompt goes away until it is done, even if I type something > like > > > "o1 @test" to launch a coroutine. Is this a fundamental limitation > > > of Io (can't enter new commands while coroutines are running)? I > > > can think of several approaches; which, if any, are right? > > > > The code that presents the user with the prompt and receives the > input > > line can just call doString(theInputString) and I think it should > have > > the behavior you are looking for. > > > > > > <!-- #ygrp-mkp{ border: 1px solid #d8d8d8; font-family: Arial; > margin: 14px 0px; padding: 0px 14px; } #ygrp-mkp hr{ border: 1px > solid #d8d8d8; } #ygrp-mkp #hd{ color: #628c2a; font-size: 85%; font- > weight: bold; line-height: 122%; margin: 10px 0px; } #ygrp-mkp > #ads{ margin-bottom: 10px; } #ygrp-mkp .ad{ padding: 0 0; } #ygrp- > mkp .ad a{ color: #0000ff; text-decoration: none; } --> <!-- #ygrp- > sponsor #ygrp-lc{ font-family: Arial; } #ygrp-sponsor #ygrp-lc > #hd{ margin: 10px 0px; font-weight: bold; font-size: 78%; line- > height: 122%; } #ygrp-sponsor #ygrp-lc .ad{ margin-bottom: 10px; > padding: 0 0; } --> <!-- #ygrp-mlmsg {font-size:13px; font-family: > arial,helvetica,clean,sans-serif;*font-size:small;*font:x-small;} > #ygrp-mlmsg table {font-size:inherit;font:100%;} #ygrp-mlmsg select, > input, textarea {font:99% arial,helvetica,clean,sans-serif;} #ygrp- > mlmsg pre, code {font:115% monospace;*font-size:100%;} #ygrp-mlmsg * > {line-height:1.22em;} #ygrp-text{ font-family: Georgia; } #ygrp- > text p{ margin: 0 0 1em 0; } dd.last p a { font-family: Verdana; > font-weight: bold; } #ygrp-vitnav{ padding-top: 10px; font-family: > Verdana; font-size: 77%; margin: 0; } #ygrp-vitnav a{ padding: 0 > 1px; } #ygrp-mlmsg #logo{ padding-bottom: 10px; } #ygrp-reco > { margin-bottom: 20px; padding: 0px; } #ygrp-reco #reco-head { font- > weight: bold; color: #ff7900; } #reco-category{ font-size: 77%; } > #reco-desc{ font-size: 77%; } #ygrp-vital a{ text-decoration: > none; } #ygrp-vital a:hover{ text-decoration: underline; } #ygrp- > sponsor #ov ul{ padding: 0 0 0 8px; margin: 0; } #ygrp-sponsor #ov > li{ list-style-type: square; padding: 6px 0; font-size: 77%; } #ygrp- > sponsor #ov li a{ text-decoration: none; font-size: 130%; } #ygrp- > sponsor #nc{ background-color: #eee; margin-bottom: 20px; padding: 0 > 8px; } #ygrp-sponsor .ad{ padding: 8px 0; } #ygrp-sponsor .ad > #hd1{ font-family: Arial; font-weight: bold; color: #628c2a; font- > size: 100%; line-height: 122%; } #ygrp-sponsor .ad a{ text- > decoration: none; } #ygrp-sponsor .ad a:hover{ text-decoration: > underline; } #ygrp-sponsor .ad p{ margin: 0; font-weight: normal; > color: #000000; } o{font-size: 0; } .MsoNormal{ margin: 0 0 0 0; } > #ygrp-text tt{ font-size: 120%; } blockquote{margin: 0 0 0 > 4px;} .replbq{margin:4} dd.last p span { margin-right: 10px; font- > family: Verdana; font-weight: bold; } dd.last p span.yshortcuts > { margin-right: 0; } div.photo-title a, div.photo-title a:active, > div.photo-title a:hover, div.photo-title a:visited { text- > decoration: none; } div.file-title a, div.file-title a:active, > div.file-title a:hover, div.file-title a:visited { text-decoration: > none; } #ygrp-msg p#attach-count { clear: both; padding: 15px 0 3px > 0; overflow: hidden; } #ygrp-msg p#attach-count span { color: > #1E66AE; font-weight: bold; } div#ygrp-mlmsg #ygrp-msg p a > span.yshortcuts { font-family: Verdana; font-size: 10px; font- > weight: normal; } #ygrp-msg p a { font-family: Verdana; font-size: > 10px; } #ygrp-mlmsg a { color: #1E66AE; } div.attach-table div div a > { text-decoration: none; } div.attach-table { width: 400px; } --> |
|
|
Re: Run Io coroutines in background simultaneous to using Io> prompt in foreground?On 2009-06-09, at 10:09 PM, dennisf486 wrote: > Thanks that was a big help but it wasn't quite the solution. I was > able to make it run a background process simultaneous to generating > my own prompt. But that only solves half my problem: "EditLine > readLine" is a blocking call, so it still halts other coroutines > while waiting at the "fake Io>" prompt. (Because you can't yield > between keypresses.) So it still only executes the background loops > once per every time I hit the "return" key on a command in the prompt. The simplest solution may be to use a non blocking keyboard input call. If this is all command line stuff, then you might look at the curses binding (but may have trouble making it portable). If it's in a GUI liek GLUT/OpenGL, then you can just use its' event based keyboard input. |
|
|
Re: Run Io coroutines in background simultaneous to using Io> prompt in foreground?> The simplest solution may be to use a non blocking keyboard input
> call. If this is all command line stuff, then you might look at the > curses binding (but may have trouble making it portable). If it's in a > GUI liek GLUT/OpenGL, then you can just use its' event based keyboard > input. Thanks Steve. You guys have given me enough to answer my question but I want to talk a little more about it in case any readers are interested in the details. I actually have 3 environments this will be used in, which complicates matters. There's a server program that's command-line only and runs on Linux, a debugging client that uses OpenGL and runs on Linux/Windows, and a real game client that will use some other 3-d engine on Windows (with Linux and Mac support planned). My partner is writing the actual game client for the end users; I'm writing the debugging client to serve as a reference code example for him to see how to talk to my server, and also so that I can verify the server works without having to wait for the real game client to be finished. I don't want to spend too much time tweaking it because that takes away from work on the server (although technically it shares 90% of its codebase with the server). Since my debugging client is just for us programmers, and won't be seen by any end-users, I thought wouldn't it be cool if instead of having a GUI, it had a commandline interface with an Io> prompt. That way instead of being limited to the small repertoire of actions I have time to program into a GUI, you'd have unlimited access to the underlying game engine programmatically. (It will use an OpenGL window to display things; you just control the view programmatically in a terminal window.) My partner has talked about having it so that the server can be accessed via a telnet-like interface over TCP/IP. He was talking about writing a client to connect to in C# using a custom protocol, but I think too much recent exposure to Windows programming has got him thinking everything needs a custom GUI app - why not instead just use ssh to connect to the server (e.g. using PuTTY on Windows)? So here's what I'm thinking I'll have it do: the Io program (be it the debugging client, game client, or server program) will listen on some TCP port on 127.0.0.1. It will doString() any text sent to it over that port and return the result. We'll use a telnet-like program (or telnet itself, or socat or netcat) running in a totally separate process to connect to this port and send/receive text. AFAIK, if you bind 127.0.0.1, that's not the same as binding your public ethernet port, so programs on the internet at large can't connect to it. You have to be already on the machine. And anyway we'll block that port in the firewall on the network. The way it would still be accessible on the server even though externally it's not accessible is you first log into the server via ssh, you then run the telnet command inside the ssh session so it's actually running local to the server itself. developer pc -> ssh port 22 over network -> server PC -> telnet -> port xxxx over localhost -> Io program On Windows, I believe both PuTTY and HyperTerminal could be used to connect to a *local* instance of the debugging client or game client this way. So, it might seem like a lot of trouble to go through to just send Io commands nonblocking, but I think TCP is actually the way that will work in all the situations this will be used in. I'm curious what you guys think of this: this TCP/IP Io> prompt object would be a way to run Io programs silently as system daemons and still occaisonally communicate with them when you want to. |
|
|
Re: Run Io coroutines in background simultaneous to using Io> prompt in foreground?LMAO: I just found io/addons/Socket/samples/TerminalServer.io. I believe it already does exactly what I was describing, right?
Can't test it yet - for some reason "Socket" addon won't build. I'll figure it out though... |
|
|
Re: Run Io coroutines in background simultaneous to using Io> prompt in foreground?You probably need to install libevent.
On Jun 13, 2009, at 9:54 AM, dennisf486 wrote: > > > LMAO: I just found io/addons/Socket/samples/TerminalServer.io. I > believe it already does exactly what I was describing, right? > > Can't test it yet - for some reason "Socket" addon won't build. I'll > figure it out though... > > > > <!-- #ygrp-mkp{ border: 1px solid #d8d8d8; font-family: Arial; > margin: 14px 0px; padding: 0px 14px; } #ygrp-mkp hr{ border: 1px > solid #d8d8d8; } #ygrp-mkp #hd{ color: #628c2a; font-size: 85%; font- > weight: bold; line-height: 122%; margin: 10px 0px; } #ygrp-mkp > #ads{ margin-bottom: 10px; } #ygrp-mkp .ad{ padding: 0 0; } #ygrp- > mkp .ad a{ color: #0000ff; text-decoration: none; } --> <!-- #ygrp- > sponsor #ygrp-lc{ font-family: Arial; } #ygrp-sponsor #ygrp-lc > #hd{ margin: 10px 0px; font-weight: bold; font-size: 78%; line- > height: 122%; } #ygrp-sponsor #ygrp-lc .ad{ margin-bottom: 10px; > padding: 0 0; } --> <!-- #ygrp-mlmsg {font-size:13px; font-family: > arial,helvetica,clean,sans-serif;*font-size:small;*font:x-small;} > #ygrp-mlmsg table {font-size:inherit;font:100%;} #ygrp-mlmsg select, > input, textarea {font:99% arial,helvetica,clean,sans-serif;} #ygrp- > mlmsg pre, code {font:115% monospace;*font-size:100%;} #ygrp-mlmsg * > {line-height:1.22em;} #ygrp-text{ font-family: Georgia; } #ygrp- > text p{ margin: 0 0 1em 0; } dd.last p a { font-family: Verdana; > font-weight: bold; } #ygrp-vitnav{ padding-top: 10px; font-family: > Verdana; font-size: 77%; margin: 0; } #ygrp-vitnav a{ padding: 0 > 1px; } #ygrp-mlmsg #logo{ padding-bottom: 10px; } #ygrp-reco > { margin-bottom: 20px; padding: 0px; } #ygrp-reco #reco-head { font- > weight: bold; color: #ff7900; } #reco-category{ font-size: 77%; } > #reco-desc{ font-size: 77%; } #ygrp-vital a{ text-decoration: > none; } #ygrp-vital a:hover{ text-decoration: underline; } #ygrp- > sponsor #ov ul{ padding: 0 0 0 8px; margin: 0; } #ygrp-sponsor #ov > li{ list-style-type: square; padding: 6px 0; font-size: 77%; } #ygrp- > sponsor #ov li a{ text-decoration: none; font-size: 130%; } #ygrp- > sponsor #nc{ background-color: #eee; margin-bottom: 20px; padding: 0 > 8px; } #ygrp-sponsor .ad{ padding: 8px 0; } #ygrp-sponsor .ad > #hd1{ font-family: Arial; font-weight: bold; color: #628c2a; font- > size: 100%; line-height: 122%; } #ygrp-sponsor .ad a{ text- > decoration: none; } #ygrp-sponsor .ad a:hover{ text-decoration: > underline; } #ygrp-sponsor .ad p{ margin: 0; font-weight: normal; > color: #000000; } o{font-size: 0; } .MsoNormal{ margin: 0 0 0 0; } > #ygrp-text tt{ font-size: 120%; } blockquote{margin: 0 0 0 > 4px;} .replbq{margin:4} dd.last p span { margin-right: 10px; font- > family: Verdana; font-weight: bold; } dd.last p span.yshortcuts > { margin-right: 0; } div.photo-title a, div.photo-title a:active, > div.photo-title a:hover, div.photo-title a:visited { text- > decoration: none; } div.file-title a, div.file-title a:active, > div.file-title a:hover, div.file-title a:visited { text-decoration: > none; } #ygrp-msg p#attach-count { clear: both; padding: 15px 0 3px > 0; overflow: hidden; } #ygrp-msg p#attach-count span { color: > #1E66AE; font-weight: bold; } div#ygrp-mlmsg #ygrp-msg p a > span.yshortcuts { font-family: Verdana; font-size: 10px; font- > weight: normal; } #ygrp-msg p a { font-family: Verdana; font-size: > 10px; } #ygrp-mlmsg a { color: #1E66AE; } div.attach-table div div a > { text-decoration: none; } div.attach-table { width: 400px; } --> |
|
|
Re: Run Io coroutines in background simultaneous to using Io> prompt in foreground?Thanks Rich. It's still not working though (I started a new thread "Trouble building Socket addon with Ubuntu 9.04").
--- In iolanguage@..., Rich Collins <richcollins@...> wrote: > > You probably need to install libevent. > > On Jun 13, 2009, at 9:54 AM, dennisf486 wrote: > > > > > > > LMAO: I just found io/addons/Socket/samples/TerminalServer.io. I > > believe it already does exactly what I was describing, right? > > > > Can't test it yet - for some reason "Socket" addon won't build. I'll > > figure it out though... > > > > > > > > <!-- #ygrp-mkp{ border: 1px solid #d8d8d8; font-family: Arial; > > margin: 14px 0px; padding: 0px 14px; } #ygrp-mkp hr{ border: 1px > > solid #d8d8d8; } #ygrp-mkp #hd{ color: #628c2a; font-size: 85%; font- > > weight: bold; line-height: 122%; margin: 10px 0px; } #ygrp-mkp > > #ads{ margin-bottom: 10px; } #ygrp-mkp .ad{ padding: 0 0; } #ygrp- > > mkp .ad a{ color: #0000ff; text-decoration: none; } --> <!-- #ygrp- > > sponsor #ygrp-lc{ font-family: Arial; } #ygrp-sponsor #ygrp-lc > > #hd{ margin: 10px 0px; font-weight: bold; font-size: 78%; line- > > height: 122%; } #ygrp-sponsor #ygrp-lc .ad{ margin-bottom: 10px; > > padding: 0 0; } --> <!-- #ygrp-mlmsg {font-size:13px; font-family: > > arial,helvetica,clean,sans-serif;*font-size:small;*font:x-small;} > > #ygrp-mlmsg table {font-size:inherit;font:100%;} #ygrp-mlmsg select, > > input, textarea {font:99% arial,helvetica,clean,sans-serif;} #ygrp- > > mlmsg pre, code {font:115% monospace;*font-size:100%;} #ygrp-mlmsg * > > {line-height:1.22em;} #ygrp-text{ font-family: Georgia; } #ygrp- > > text p{ margin: 0 0 1em 0; } dd.last p a { font-family: Verdana; > > font-weight: bold; } #ygrp-vitnav{ padding-top: 10px; font-family: > > Verdana; font-size: 77%; margin: 0; } #ygrp-vitnav a{ padding: 0 > > 1px; } #ygrp-mlmsg #logo{ padding-bottom: 10px; } #ygrp-reco > > { margin-bottom: 20px; padding: 0px; } #ygrp-reco #reco-head { font- > > weight: bold; color: #ff7900; } #reco-category{ font-size: 77%; } > > #reco-desc{ font-size: 77%; } #ygrp-vital a{ text-decoration: > > none; } #ygrp-vital a:hover{ text-decoration: underline; } #ygrp- > > sponsor #ov ul{ padding: 0 0 0 8px; margin: 0; } #ygrp-sponsor #ov > > li{ list-style-type: square; padding: 6px 0; font-size: 77%; } #ygrp- > > sponsor #ov li a{ text-decoration: none; font-size: 130%; } #ygrp- > > sponsor #nc{ background-color: #eee; margin-bottom: 20px; padding: 0 > > 8px; } #ygrp-sponsor .ad{ padding: 8px 0; } #ygrp-sponsor .ad > > #hd1{ font-family: Arial; font-weight: bold; color: #628c2a; font- > > size: 100%; line-height: 122%; } #ygrp-sponsor .ad a{ text- > > decoration: none; } #ygrp-sponsor .ad a:hover{ text-decoration: > > underline; } #ygrp-sponsor .ad p{ margin: 0; font-weight: normal; > > color: #000000; } o{font-size: 0; } .MsoNormal{ margin: 0 0 0 0; } > > #ygrp-text tt{ font-size: 120%; } blockquote{margin: 0 0 0 > > 4px;} .replbq{margin:4} dd.last p span { margin-right: 10px; font- > > family: Verdana; font-weight: bold; } dd.last p span.yshortcuts > > { margin-right: 0; } div.photo-title a, div.photo-title a:active, > > div.photo-title a:hover, div.photo-title a:visited { text- > > decoration: none; } div.file-title a, div.file-title a:active, > > div.file-title a:hover, div.file-title a:visited { text-decoration: > > none; } #ygrp-msg p#attach-count { clear: both; padding: 15px 0 3px > > 0; overflow: hidden; } #ygrp-msg p#attach-count span { color: > > #1E66AE; font-weight: bold; } div#ygrp-mlmsg #ygrp-msg p a > > span.yshortcuts { font-family: Verdana; font-size: 10px; font- > > weight: normal; } #ygrp-msg p a { font-family: Verdana; font-size: > > 10px; } #ygrp-mlmsg a { color: #1E66AE; } div.attach-table div div a > > { text-decoration: none; } div.attach-table { width: 400px; } --> > |
|
|
Re: Run Io coroutines in background simultaneous to using Io> prompt in foreground?Success at last! If anyone's interest in doing this, here's the script, it's not hard to do after all. I fix some bugs in TerminalServer.io related to it calling methods that don't exist and expecting "String" when it should be "Sequence", so this is also a better TerminalServer.
// Filename: CoIo.io // // To use this script: // // In one terminal, type: // io CoIo.io // // In a second terminal type: // telnet 127.0.0.1 8460 // // 1. Observe that the first terminal prints 1, 2, 3, etc. // 2. In the 2nd terminal, observe that typing "n print" // prints the number currently in the first terminal. // 3. In the 2nd terminal, type "n = 1000", and notice // that now the 1st terminal is now counting from 1000!! n := 1 doBackground := method( loop("N is " print; n println; n = n + 1; wait(1)) ) @@doBackground Terminal := Object clone Terminal handleSocketFromServer := method(aSocket, aServer, while(aSocket isOpen, aSocket write("\nIo> ") if(aSocket read, e := try( result := Lobby doString(aSocket readBuffer asString) aSocket write(result asString) ) e catch (Exception, aSocket write("exception: ", e coroutine backtraceString) ) ) aSocket readBuffer empty ) ) write("starting io terminal server\n") server := Server clone setPort(8460) server handleSocket := method(aSocket, Terminal clone @handleSocketFromServer(aSocket, self) ) server start |
| Free embeddable forum powered by Nabble | Forum Help |