ChildWindow: wait for termination and read stdin on separate fibers, use exit; taro-ls: scrollbar, fix performance

This commit is contained in:
Iris Lightshard 2023-03-15 23:26:31 -06:00
parent 1cad71b488
commit d4f9a80dc6
Signed by: nilix
GPG key ID: 3B7FBC22144E6398
2 changed files with 227 additions and 62 deletions

View file

@ -9,17 +9,38 @@ module Taro
COMPOSE
end
class Mesg
@type : UInt8
@data : Slice(UInt8)
def type
@type
end
def data
@data
end
def initialize(@type, @data)
end
end
class ChildWindow
@status : Channel(String)
@lifetime : Channel(UInt8)
@msg : Channel(Mesg)
@stdout_w : IO::FileDescriptor
@stdout_r : IO::FileDescriptor
@stdin_w : IO::FileDescriptor
@stdin_r : IO::FileDescriptor
@decoding : Bool = false
@szshort : UInt16 = 0
def initialize(w : WinType = WinType::LIST)
@stdout_r, @stdout_w = IO.pipe
@stdin_r, @stdin_w = IO.pipe
@status = Channel(String).new
@lifetime = Channel(UInt8).new
@msg = Channel(Mesg).new
uxnrom : String = ""
@ -33,12 +54,17 @@ module Taro
spawn do
Process.run(command: "uxnemu", args: uxnargs, input: @stdin_r, output: @stdout_w, error: Process::Redirect::Inherit)
@status.send("ls closed")
@lifetime.send(0)
end
spawn do
loop do
@msg.send(read_msg)
end
end
end
def lifetime
return @status
return @lifetime
end
def write_msg(msgtype : UInt8, data : Slice)
@ -54,10 +80,31 @@ module Taro
end
end
def read_msg()
slc = Slice.new(16384)
@stdout_r.read(slc)
return slc[0].to_u8, slc[1..slc.size - 1]
def read_msg
msgType : UInt8 = 0
data : Slice(UInt8) = Slice(UInt8).new(0)
loop do
if @stdout_r.closed?
break
end
if !@decoding
msgType = @stdout_r.read_byte || 0_u8
@decoding = true
elsif @szshort == 0
szslice = Slice(UInt8).new(2)
@stdout_r.read_fully(szslice)
szlow : UInt16 = UInt16.new(szslice[0])*256
szhigh : UInt16 = UInt16.new(szslice[1])
@szshort = szlow + szhigh
else
slc = Slice(UInt8).new(@szshort)
@stdout_r.read_fully(slc)
@decoding = false
data = slc
break
end
end
return Mesg.new(msgType, data)
end
end
@ -74,6 +121,14 @@ module Taro
Process.run(mailCmd, shell: true, output: io)
return io.to_s
end
def list_mboxes
mailCmd ="mdirs ${MBOX_ROOT}"
io = IO::Memory.new
Process.run(mailCmd, shell: true, output: io)
return io.to_s
end
end
class TaroCtl
@ -97,6 +152,7 @@ module Taro
def mainWindow
@lsWin
end
end
end
@ -106,6 +162,6 @@ taro = Taro::TaroCtl.new
loop do
select
when taro.mainWindow.lifetime.receive?
break
exit
end
end

View file

@ -1,6 +1,8 @@
( a blank file )
( taro-ls: list mail, navigate mailboxes, and perform actions on mail )
%MAIL_LIST { #02 }
%TOP_SECTION { #0020 }
%BOTTOM_SECTION { #0040 }
|00 @System &vector $2 &wst $1 &rst $1 &eaddr $2 &ecode $1 &pad $1 &r $2 &g $2 &b $2 &debug $1 &halt $1
|10 @Console &vector $2 &read $1 &pad $5 &write $1 &error $1
@ -19,14 +21,15 @@
|0000
@wipe_fg [ $1 ]
@resizing [ $1 &x $2 &y $2 &dx $2 &dy $2 ]
@decoding [ $1 &msg_type $1 &counting $1 &count $2 &processed $2 ]
@list [ &bytes $2 &len $1 &offset $2 &elem_offset $1 &top $2 &height $1 &select_index $2 ]
@sb [ &len $1 &pos $1 &step $1 ]
@list [ &bytes $2 &len $1 &offset $2 &elem_offset $1 &top $2 &height $1 &select_index $2 &update $1 ]
@sb [ &len $1 &pos $2 &step $2 ]
( program )
|0100 ( -> )
|0100 ( _> )
( theme )
#028d .System/r DEO2
@ -36,15 +39,15 @@
#0180 .Screen/width DEO2
#0200 .Screen/height DEO2
.Screen/height DEI2 #0060 SUB2 #03 SFT2 NIP .list/height STZ
.Screen/height DEI2 TOP_SECTION BOTTOM_SECTION ADD2 SUB2 #03 SFT2 NIP .list/height STZ
#01 .wipe_fg STZ
;on_screen .Screen/vector DEO2
;on_mouse .Mouse/vector DEO2
;on_stdin .Console/vector DEO2
BRK
@on_stdin ( -> )
@on_stdin ( _> )
.decoding LDZ #01 EQU ,&must_decode JCN
#01 .decoding STZ
@ -61,9 +64,10 @@ BRK
.Console/read DEI
.decoding/msg_type LDZ
DUP MAIL_LIST NEQ ,&no_mail_list JCN
POP ;list-data .decoding/processed LDZ2 ADD2 STA
POP ;list_data .decoding/processed LDZ2 ADD2 STA
decode_inc_count .list/bytes STZ2
,&count JMP
#01 .list/update STZ
&no_mail_list
POP
@ -84,15 +88,18 @@ BRK
BRK
@decode_inc_count ( -- current* )
@decode_inc_count ( __ current* )
.decoding/processed LDZ2 INC2 DUP2 .decoding/processed STZ2
JMP2r
@decode_is_done ( -- bit )
@decode_is_done ( __ bit )
#01 .list/update STZ
.decoding/processed LDZ2 .decoding/count LDZ2 EQU2
JMP2r
@on_mouse ( -> )
@on_mouse ( _> )
get_select_idx_by_mouse
.resizing LDZ #00 EQU ,&resz_check JCN
( resizing )
@ -115,10 +122,12 @@ JMP2r
.Mouse/y DEI2 .resizing/y STZ2
BRK
#01 .wipe_fg STZ
&done
BRK
@handle_rsz ( -- mousestate )
@handle_rsz ( __ mousestate )
( chk_x_rsz )
.Mouse/x DEI2 .Screen/width DEI2 #0002 SUB2 GTH2 ,&inc_x JCN
@ -146,22 +155,29 @@ BRK
&chk_release
.Screen/height DEI2 #0060 SUB2 #03 SFT2 NIP .list/height STZ
.Screen/height DEI2 TOP_SECTION BOTTOM_SECTION ADD2 SUB2 #03 SFT2 NIP .list/height STZ
.Mouse/state DEI
JMP2r
@on_screen ( -> )
@on_screen ( _> )
.list/update LDZ #00 EQU ,&no_list JCN
draw_mail_list
draw_resize_handle
draw_scrollbar
#00 .list/update STZ
&no_list
.wipe_fg LDZ #00 EQU ,&no_fg JCN
clear_fg
draw_resize_handle
draw_cursor
#00 .wipe_fg STZ
&no_fg
BRK
@clear_fg ( -> )
@clear_fg ( _> )
.Screen/width DEI2 #0000 &whilex EQU2k ,&endx JCN
DUP2 ,&x STR2
@ -178,7 +194,7 @@ JMP2r
&x $2
&y $2
@draw_resize_handle ( -> )
@draw_resize_handle ( _> )
.Screen/width DEI2 #0008 SUB2 .Screen/x DEO2
.Screen/height DEI2 #0008 SUB2 .Screen/y DEO2
@ -187,7 +203,7 @@ JMP2r
JMP2r
@strlen ( addr -- len )
@strlen ( addr __ len )
DUP2
&loop
@ -196,14 +212,14 @@ JMP2r
JMP2r
@store_char ( char -- char )
@store_char ( char __ char )
#00 .list/elem_offset LDZ ;word ADD2 STA
.list/elem_offset LDZ INC .list/elem_offset STZ
JMP2r
@shouldnt_draw_word ( -- flag )
@shouldnt_draw_word ( __ flag )
.list/offset LDZ2 .list/top LDZ2 LTH2 ,&no JCN
.list/offset LDZ2 .list/top LDZ2 #00 .list/height LDZ ADD2 #0001 SUB2 GTH2 ,&no JCN
@ -213,20 +229,20 @@ JMP2r
#01
JMP2r
@draw_list_elem ( -> )
@draw_list_elem ( _> )
( ;get-entry-color JSR2 #0c NEQ ,&no-store-cart JCN
;store-cart JSR2 )
&no-store-cart
( ;get_entry_color JSR2 #0c NEQ ,&no_store_cart JCN
;store_cart JSR2 )
&no_store_cart
[ ;word
.Screen/x DEI2
.Screen/y DEI2
get-entry-color ] draw_str
finish-line
get_entry_color ] draw_str
finish_line
JMP2r
@get-entry-color ( -- colorByte )
@get_entry_color ( __ colorByte )
.list/offset LDZ2
.list/select_index LDZ2
@ -239,25 +255,24 @@ JMP2r
#03
JMP2r
@finish-line ( -> )
;get-entry-color JSR2 #03 EQU ,&end JCN
@finish_line ( _> )
;blank .Screen/addr DEO2
&while
.Screen/x DEI2
.Screen/width DEI2 #0018 SUB2
.Screen/width DEI2 #0010 SUB2
GTH2 ,&end JCN
#04 .Screen/sprite DEO
get_entry_color .Screen/sprite DEO
.Screen/x DEI2 #0008 ADD2 .Screen/x DEO2
,&while JMP &end
JMP2r
@draw_mail_list ( -> )
@draw_mail_list ( _> )
#0008 .Screen/x DEO2
#0020 .Screen/y DEO2
#0000 .Screen/x DEO2
TOP_SECTION .Screen/y DEO2
.decoding LDZ #01 NEQ ,&proceed JCN
;loading .Screen/x DEI2 .Screen/y DEI2 #03 draw_str
@ -266,7 +281,7 @@ JMP2r
#0000 .list/offset STZ2
.list/bytes LDZ2 #0000 &while EQU2k ,&end JCN
DUP2 ;list-data ADD2 LDA
DUP2 ;list_data ADD2 LDA
DUP #00 EQU ,&end JCN
( if not newline, store the character and increment the offsets )
DUP #0a EQU ,&inc_line JCN
@ -275,16 +290,16 @@ JMP2r
&inc_line
POP #0000 .list/elem_offset LDZ ;word ADD2 STA
shouldnt_draw_word ,&no-draw JCN
shouldnt_draw_word ,&no_draw JCN
draw_list_elem
#0008 .Screen/x DEO2
#0000 .Screen/x DEO2
.Screen/y DEI2 #0008 ADD2 .Screen/y DEO2
&no-draw
&no_draw
.list/offset LDZ2 INC2 .list/offset STZ2
#ff #00 &word_clr EQUk ,&end-clr JCN
#ff #00 &word_clr EQUk ,&end_clr JCN
#00 OVR SWP DUP ROT ;word ADD2 STA
INC ,&word_clr JMP &end-clr POP2
INC ,&word_clr JMP &end_clr POP2
#00 .list/elem_offset STZ
&continue INC2 ,&while JMP
&end
@ -292,7 +307,7 @@ JMP2r
JMP2r
@draw_cursor ( -> )
@draw_cursor ( _> )
.Mouse/x DEI2 .Screen/x DEO2
.Mouse/y DEI2 .Screen/y DEO2
@ -301,15 +316,15 @@ JMP2r
JMP2r
@print ( short* -- )
@print ( short* __ )
SWP ,&byte JSR
&byte ( byte -- ) DUP #04 SFT ,&char JSR
&char ( char -- ) #0f AND DUP #09 GTH #27 MUL ADD #30 ADD #18 DEO
&byte ( byte __ ) DUP #04 SFT ,&char JSR
&char ( char __ ) #0f AND DUP #09 GTH #27 MUL ADD #30 ADD #18 DEO
JMP2r
@print-str ( str* -- )
@print_str ( str* __ )
&while
LDAk #18 DEO
@ -318,7 +333,98 @@ JMP2r
JMP2r
@draw_str ( addr x y color -- )
@get_select_idx_by_mouse ( _> )
.Mouse/scrolly DEI2 #0000 EQU2 ,&no_scroll JCN
.Mouse/scrolly DEI2 #0001 EQU2 ,&scroll_down JCN
( scroll_up )
;try_scroll_up_mouse JSR2
,&no_scroll JMP
&scroll_down
;try_scroll_down_mouse JSR2
&no_scroll
.Mouse/x DEI2 #0008 LTH2 ,&done JCN
.Mouse/x DEI2 .Screen/width DEI2 #0008 SUB2 GTH2 ,&done JCN
.Mouse/y DEI2 TOP_SECTION LTH2 ,&done JCN
.Mouse/y DEI2 .Screen/height DEI2 BOTTOM_SECTION SUB2 GTH2 ,&done JCN
.Mouse/y DEI2 TOP_SECTION SUB2 #03 SFT2 .list/top LDZ2 ADD2 .list/select_index STZ2
#01 .list/update STZ
.Mouse/state DEI #00 EQU ,&no_click JCN
.list/select_index LDZ2 .list/len LDZ2 GTH2 ,&no_click JCN
&no_click
JMP2r
( click handler here )
&done
JMP2r
@try_scroll_up_mouse ( _> )
.list/len LDZ2 #00 .list/height LDZ LTH2 ,&no_scroll_up JCN
.list/top LDZ2 #0000 EQU2 ,&no_scroll_up JCN
.list/top LDZ2 #0001 SUB2 .list/top STZ2
;update_sb_pos JSR2
#01 .list/update STZ
&no_scroll_up
JMP2r
@try_scroll_down_mouse ( _> )
.list/len LDZ2 #00 .list/height LDZ LTH2 ,&no_scroll_down JCN
.list/top LDZ2 #00 .list/height LDZ ADD2 .list/len LDZ2 EQU2 ,&no_scroll_down JCN
.list/top LDZ2 INC2 .list/top STZ2
;update_sb_pos JSR2
#01 .list/update STZ
&no_scroll_down
JMP2r
@draw_scrollbar ( _> )
.Screen/width DEI2 #0008 SUB2 .Screen/x DEO2
TOP_SECTION .Screen/y DEO2
( draw the trough no matter what )
;blank .Screen/addr DEO2
.list/height LDZ #00
&while_trough EQUk ,&end_trough JCN
#00 .Screen/sprite DEO
.Screen/y DEI2 #0008 ADD2 .Screen/y DEO2
INC ,&while_trough JMP &end_trough POP2
( stop here if there is no overflow )
.list/len LDZ2 #00 .list/height LDZ LTH2 ,&no_handle JCN
,&draw_handle JMP
&no_handle
JMP2r
( if there are more entries than will fit in the view area, draw the handle )
&draw_handle
( store the number of entries per tile of the scrollbar )
.list/len LDZ2 #00 .list/height LDZ DIV2 .sb/step STZ2
( set the length of the scrollbar )
.list/height LDZ .list/len LDZ2 #00 .list/height LDZ SUB2 .sb/step LDZ2 DIV2 NIP SUB .sb/len STZ
;scrollbar .Screen/addr DEO2
TOP_SECTION .sb/pos LDZ2 #30 SFT2 ADD2 .Screen/y DEO2
.sb/len LDZ #00 &while_handle EQUk ,&end_handle JCN
.Screen/y DEI2 .Screen/height DEI2 #0040 SUB2 EQU2 ,&end_handle JCN
#01 .Screen/sprite DEO
INC .Screen/y DEI2 #0008 ADD2 .Screen/y DEO2 ,&while_handle JMP &end_handle POP2
JMP2r
@update_sb_pos ( _> )
.list/top LDZ2 .sb/step LDZ2 DIV2 .sb/pos STZ2
JMP2r
@draw_str ( addr x y color __ )
STH ( save color )
.Screen/y DEO2 ( set y )
@ -327,7 +433,9 @@ JMP2r
( now the string address is at the top of the stack )
&loop
.Screen/x DEI2 .Screen/width DEI2 #0010 SUB2 GTH2 ,&done JCN
LDAk DUP #00 NEQ #20 MUL SUB #00 SWP #30 SFT2 ;font ADD2 .Screen/addr DEO2
LDAk DUP
#7f LTH ,&ascii JCN POP #3f ( replace non_ascii characters with ? )
&ascii DUP #00 NEQ #20 MUL SUB #00 SWP #30 SFT2 ;font ADD2 .Screen/addr DEO2
STHkr .Screen/sprite DEO
.Screen/x DEI2 #0008 ADD2 .Screen/x DEO2
INC2
@ -339,6 +447,7 @@ JMP2r
@resize_handle [ e2c2 aa1a 3a02 fe00 ]
@cursor [ f8e0 e090 8804 0000 ]
@scrollbar [ 0707 0707 0707 0707 ]
@blank [ 0000 0000 0000 0000 ]
@loading "Loading... 00
@ -371,5 +480,5 @@ JMP2r
@word $ff
@list-data $4000
@input-buf $4000
@list_data $4000
@input_buf $4000