Page 1 of 1
Asynchronous console input
Posted: Sat Sep 10, 2016 2:54 am
by Lunasole
The Input() locks program, but seems that without it you can only use threads to make program async, or do all the input handling and displaying by yourself.
I don't know is it right to do things like following (implementing own base editing functions for every key), but anyway I did it for fun while playing with console a bit ^^
Code: Select all
EnableExplicit
If OpenConsole()
PrintN("Type something and try to delete it using backspace & moving arrow keys")
Define Buffer$, BufferSize, BufferPos
Define VK, Key$
Define Back
Repeat
Key$ = Inkey()
VK = RawKey()
Select VK
Case #VK_RETURN:
; display buffer content (receive collected input with enter)
ConsoleTitle(Buffer$)
; clear current line
Print(Chr(#VK_RETURN))
Print(Space(BufferSize))
Print(Chr(#VK_RETURN))
; or can simply jumt to next line
; PrintN("")
; reset buffer
Buffer$ = ""
BufferSize = 0
BufferPos = 0
Case #VK_BACK:
; display: move by 1 char left and erase it (replace by space)
; Print(Chr(#VK_BACK))
; Print(" " + Chr(#VK_BACK))
; edit buffer
If BufferSize
Print(Chr(#VK_RETURN))
Print(Space(BufferSize))
Print(Chr(#VK_RETURN))
Buffer$ = Left(Buffer$, BufferPos - 1) + Right(Buffer$, BufferSize - BufferPos)
BufferSize - 1
BufferPos - 1
Print(Buffer$)
Back = BufferSize - BufferPos
While Back
Print(Chr(#VK_BACK))
Back - 1
Wend
EndIf
Case #VK_DELETE:
; TODO
Case #VK_LEFT:
; move cursor left
If BufferPos
Print(Chr(#VK_BACK))
BufferPos - 1
EndIf
Case #VK_RIGHT:
; move cursor right
If BufferPos <= BufferSize - 1
BufferPos + 1
Print(Mid(Buffer$, BufferPos, 1))
EndIf
Default:
; add regular key to a buffer
If Key$
If Not BufferSize > 64
Buffer$ = Left(Buffer$, BufferPos) + Key$ + Right(Buffer$, BufferSize - BufferPos)
BufferSize + 1
Print(Right(Buffer$, BufferSize - BufferPos))
BufferPos + 1
Back = BufferSize - BufferPos
While Back
Print(Chr(#VK_BACK))
Back - 1
Wend
EndIf
Else
Delay(32)
EndIf
EndSelect
ForEver
EndIf
Re: Asynchronous console input
Posted: Sat Sep 10, 2016 4:01 am
by es_91
PB console function input () is very static. It locks the "pipe". I do not think a thread could change the console while inputing ()... should crash probably.
do all the input handling and displaying by yourself
That is what you should do. I once wrote a CLI GUI handling include. Sorry, i do not know where it is. If i find soon, i'll post, if you could use with.
By-the-way, two or three hours ago you posted a similar-topic question and I really had a helpful answer for you. I know, you got it by yourself, but erasing threads is kind of a sad thing to do if you can re-use them.

Re: Asynchronous console input
Posted: Sat Sep 10, 2016 4:34 am
by Lunasole
es_91 wrote:
By-the-way, two or three hours ago you posted a similar-topic question and I really had a helpful answer for you. I know, you got it by yourself, but erasing threads is kind of a sad thing to do if you can re-use them.

That was the same topic but in question form ^^ Sorry if you going to post to it, I've removed it in few minutes after creation as I thought that question was too obvious and coded what posted here.
Btw that example has problem when buffer size becomes larger > console line width.
If you remove following limitation, the things going bad:
Maybe you remember how you solved this in your code?
Re: Asynchronous console input
Posted: Sat Sep 10, 2016 4:41 am
by es_91
Please describe that more closely. I notice so far no errors lifting up the buffer size.
Re: Asynchronous console input
Posted: Sat Sep 10, 2016 4:47 am
by Lunasole
es_91 wrote:Please describe that more closely. I notice so far no errors lifting up the buffer size.
If only typing something, all is OK. The problem for example if using Backspace key with buffer > line width.
So generally following questions:
- How to return cursor to a previous line?
- How to know console line width?
Re: Asynchronous console input
Posted: Sat Sep 10, 2016 5:04 am
by es_91
I think i saw what you mean: the display doubles with all content into a new line when pushing backspace in a following line to the first.
Lunasole wrote:- How to return cursor to a previous line?
- How to know console line width?
Look:
ConsoleLocate () ... is what you need !
ClearConsole () ... might come in handy, as well.
NewList and AddElement () should do your buffering job, if you want to learn it the "proper" and easy way. See "List" library.
And finally, if you jump inside your console, use EnableGraphicalConsole ().
Re: Asynchronous console input
Posted: Sat Sep 10, 2016 5:06 am
by es_91
Wait 20 minutes, please. I'll code you an example using lists and graphical mode.
Re: Asynchronous console input
Posted: Sat Sep 10, 2016 5:57 am
by Lunasole
es_91 wrote:Wait 20 minutes, please. I'll code you an example using lists and graphical mode.
That should take much more than 20m

I was thinking about graphical mode and it is clear with it if that's only solution. I just though it is possible to perform multi-line edit without using it (some control code to jump line back?).
Re: Asynchronous console input
Posted: Sat Sep 10, 2016 6:43 am
by es_91
Not to my knowledge, sorry.
Here's my prospect given:
Code: Select all
enableExplicit
#CWIDTH = 80
#CHEIGHT = 25
#KEY_SPACE = 32
define key$ { 1 } ; primitive string for educational purpose (static)
define key. w ; primitive word for educational purpose
define quitSwitch. b ; primitive byte for educational purpose (boolean use)
define cursorPosition. w ; primitive word for educational purpose
define temporaryPosition. w ; primitive word for educational purpose
dim characterBuffer. c ( #CWIDTH * #CHEIGHT ) ; primitive character for educational purpose
newList characterHistory. c ( ) ; primitive character for educational purpose
for temporaryPosition = 1 to 80 * 25
characterBuffer ( temporaryPosition ) = #KEY_SPACE
next
procedure updateCursor ()
shared cursorPosition
consoleLocate ( cursorPosition - int ( 1.0 * cursorPosition / #CWIDTH ) * #CWIDTH, int ( 1.0 * cursorPosition / #CWIDTH ) )
endProcedure
procedure redrawConsole ()
shared characterBuffer ( )
protected line. b; primitive byte for educational purpose
protected column. b; primitive byte for educational purpose
protected temporaryCharacterChain$ { #CWIDTH }; primitive string for educational purpose (static)
for line = 1 to #CHEIGHT
temporaryCharacterChain$ = #empty$
for column = 1 to #CWIDTH
temporaryCharacterChain$ = temporaryCharacterChain$ + chr ( characterBuffer ( #CWIDTH * ( line - 1 ) + column - 1 ) )
next
consoleLocate ( 0, line - 1 )
print ( temporaryCharacterChain$ )
next
updateCursor ( )
endProcedure
procedure addNewSign ()
shared characterBuffer ( )
shared cursorPosition
shared key$
if cursorPosition < ( #CWIDTH * #CHEIGHT )
characterBuffer ( cursorPosition ) = asc ( key$ )
cursorPosition = cursorPosition + 1
redrawConsole ( )
endIf
endProcedure
openConsole ( )
enableGraphicalConsole ( #true )
consoleColor ( 0, 7 )
printn ( "The whole console will be your input area.")
printn ( "Only letters and numbers are allowed! Type 'close' to exit." )
consoleLocate ( 0, ( #CHEIGHT / 2 ) )
printn ( "1 1x 2x 3x 4x 5x 6x 3 5 7 7x 3 5 7 9 " )
consoleLocate ( 0, ( #CHEIGHT - 1 ) )
print ( "Just press <Enter> or <Return> to start." )
consoleColor ( 7, 7 )
if ( lCase ( input ( ) ) = "close" )
quitSwitch = #true
endIf
consoleColor ( 7, 0 )
clearConsole ( )
while ( not quitSwitch )
key$ = inkey ( )
key = rawKey ( )
if ( ( not asc ( key$ ) ) and ( not key ) ); [AUTHOR0] both zero-set means no input/inkey
delay ( 40 )
else
if ( ( key$ = "" ) or ( ( uCase ( key$ ) = key$ ) and ( not ( str ( val ( key$ ) ) = key$ ) ) ) )
select key
case 8
if cursorPosition > 0
characterBuffer ( cursorPosition - 1 ) = #KEY_SPACE
cursorPosition = cursorPosition - 1
redrawConsole ( )
endIf
case 27
quitSwitch = #true
case 32
addNewSign ( )
case 37
if cursorPosition > 1
cursorPosition = cursorPosition - 1
redrawConsole ( )
endIf
case 38
if cursorPosition > #CWIDTH
cursorPosition = cursorPosition - #CWIDTH
redrawConsole ( )
endIf
case 39
if cursorPosition < ( #CWIDTH * #CHEIGHT )
cursorPosition = cursorPosition + 1
redrawConsole ( )
endIf
case 40
if cursorPosition < ( #CWIDTH * ( #CHEIGHT - 1 ) )
cursorPosition = cursorPosition + #CWIDTH
redrawConsole ( )
endIf
default
debug key
endSelect
else
addNewSign ( )
endIf
endIf
wEnd
enableGraphicalConsole ( #false )
end
Okay... unfinished, imperfect and took 2 hours. Phew !
BTW: How do these guys come up with some 10'000 lines include codes just around the corner saying "here's my implementation" ... you guys work over-night ??
/ed: it's actually noth'n but a rough toy, but hey, i made a rough toy !

- i MADE This ... many like 'em, but this one... 's mine.

^^
Re: Asynchronous console input
Posted: Sat Sep 10, 2016 3:44 pm
by Lunasole
es_91 wrote:
/ed: it's actually noth'n but a rough toy, but hey, i made a rough toy !

- i MADE This ... many like 'em, but this one... 's mine.

^^
Kind of familiar feeling, I have whole separated folder full of "rough toys" ^^ That's nice generally, sometimes they are very useful as starting point if going to do something real.