gforth
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[gforth] learning multitasking; doubt about 'u8key'


From: Marcos Cruz
Subject: [gforth] learning multitasking; doubt about 'u8key'
Date: Tue, 9 Jul 2013 18:54:51 +0200
User-agent: Mutt/1.5.21 (2010-09-15)

Hi,

Some days ago, searching for info on Gforth's multitasking, I found a
link Anton Ertl mentioned in <comp.alt.forth>
(http://compgroups.net/comp.lang.forth/looking-for-more-gforth-documentation/1259909):
<http://egesund.org/forth/forth.htm>.

With the help of that little example and Gforth's <tasker.fs>, I did
many tries and finally understood how the thing works. I wrote four
little demos. The last one shows two counters on the screen while the
input line works normally.

One interesting problem was how to manage the cursor: the word used to
get the current cursor position, 'xy',  uses 'key', so the normal (say
"non-multitasking") 'key' has to be reactivated before executing 'xy'.

Another problem was at first the tasks run only when a key was pressed.
The reason was Gforth's 'u8key' is not affected by changing the action
of 'key' because it's written with 'defers key'.  Is there any reason
for that? Finally I decided to write a modified version of 'u8key',
'task-u8key'.

Since multitasking is not documented in Gforth (yet), I think my tries
can be useful to others. I will publish them in my website as soon as
possible and will announce here; but here you are the last one, the most
interesting:

========================= START OF CODE ========================

\ multitasking_test_03.fs
\
\ Test program
\ to learn how to use the Gforth's multitasking.
\
\ By Marcos Cruz (programandala.net)
\
\ Change log:
\
\ 2013-06-27 Start. First working version.
\ 2013-07-09 <galope/xy.fs> temporarily merged.

\ **************************************************************
\ Requirements

\ Save the original behaviour of 'key',
\ before the tasker changes it:
' key defer@ constant ((key))

require tasker.fs
require random.fs 

false [if]

require galope/xy.fs

[else]

\ ----8<--------------------------------------------------------
\ galope/xy.fs
\ Current cursor coordinates

\ This file is part of Galope
\ (Gforth Accessory Library of Particular Elements)

\ Extracted and modified from:
\ ansi.4th
\ ANSI Terminal words for kForth
\ Copyright (c) 1999--2004 Krishna Myneni
\ Creative Consulting for Research and Education
\ This software is provided under the terms of the GNU
\ General Public License.

\ Modifications:
\ Copyright (C) 2012 Marcos Cruz (programandala.net)

\ History
\ 2012-04 Extracted from a program of mine.
\ 2012-04-29 Added 'at-x' and 'at-y'.
\ 2012-05-08 'at-x' and 'at-y' moved to their own files.
\ 2013-06-26 Fixed some comments. 
\ 2013-06-26 Gforth's 'esc[' used instead of 'ansi_escape'.

base @ decimal

: number<c>  ( c -- n )
  \ Read a decimal numeric entry delimited by character c.
  \ xxx todo move this word to its own file:
  \ xxx todo choose a better name?:
  \   number/c
  \   keys/c>decimal
  \   keys>#
  \   keys>number
  \   keys>#number
  \ xxx todo no final char: finish at the first non-digit instead
  >r 0
  begin   key dup r@ <>
  while   swap 10 * swap '0' - +
  repeat  r> 2drop
  ;

: xy  ( -- u1 u2 )
  \ Return the current cursor position.
  \ u1 = current column
  \ u2 = current line
  esc[ ." 6n"
  key key 2drop  \ erase: <esc> [
  ';' number<c>  'R' number<c>
  1- swap 1-
  ;

base !
\ ----8<--------------------------------------------------------

[then] 

\ **************************************************************
\ Main

16 newtask constant taksk_1_id
16 newtask constant taksk_2_id

: task-u8key ( -- u )
  \ Multitasking version of Gforth's u8key (defined in <utf-8.fs>).
  \ Changes: 'defers key' to 'task-key'.
  task-key dup max-single-byte u< ?exit  \ special case ASCII
  dup $ff = ?exit  \ special resize character
  dup $c2 u< if  utf-8-err throw  then  \ malformed character
  $7f and  $40 >r
  begin  dup r@ and
  while
    r@ xor
    6 lshift r> 5 lshift >r >r task-key
    dup $c0 and $80 <> if  utf-8-err throw  then
    $3f and r> or
  repeat  rdrop  
  ;

: untasked_output  ( -- )
  \ Set the basic output words to their non-multitasking defaults.
  ['] (emit) is emit
  ['] (type) is type
  ;
: tasked_output  ( -- )
  \ Set the basic output words to their multitasking versions.
  ['] task-emit is emit
  ['] task-type is type
  ;
: untasked_key  ( -- )
  \ Set 'key' to its non-multitasking default. 
  ((key)) is key
  ;
: untasked_xkey  ( -- )
  \ Set 'xkey' to its non-multitasking default. 
  ['] u8key is xkey
  ;
: untasked_input  ( -- )
  \ Set the basic input words to their non-multitasking defaults.
  untasked_key untasked_xkey
  ;
: tasked_key  ( -- )
  \ Set 'key' to its multitasking version.
  ['] task-key is key
  ;
: tasked_xkey  ( -- )
  \ Set 'xkey' to its multitasking version.
  ['] task-u8key is xkey
  ;
: tasked_input  ( -- )
  \ Set the basic input words to their multitasking versions.
  tasked_key tasked_xkey
  ;

' page alias (page)  \ original 'page'
defer page
: tasked_page  ( -- )
  \ Safe version of 'page' when multitasking.
  untasked_output (page) tasked_output
  ;
' tasked_page is page

: (xy)  ( -- u1 u2 )
  \ Safe version of 'xy' when multitasking.
  untasked_key xy tasked_key
  ;

2048 value /ms  \ interval
: time?  ( -- flag )
  \ Is it time to execute a task?
  utime drop /ms mod 0=
  ;

variable counter1
: (task1)  ( -- )
  1 counter1 +!  
  untasked_output
  (xy) 0 0 at-xy counter1 ? at-xy
  tasked_output
  ;
: task1  ( -- )
  taksk_1_id activate
  begin  time? if  (task1)  then  pause  again
  ;

variable counter2
: (task2)  ( -- )
  10 counter2 +!  
  untasked_output
  (xy) 10 10 at-xy counter2 ? at-xy
  tasked_output
  ;
: task2  ( -- )
  taksk_2_id activate
  begin  time? if  (task2)  then  pause  again
  ;

: run  ( -- )
  page  task1 task2 
  untasked_output
  0 rows 3 - at-xy
  ." The counters run even when no key is pressed."
  tasked_input
  ;

page
.( multitasking_test_03.fs) cr 
.( Type RUN to start the demo.) cr cr

========================== END OF CODE =========================

I'd appreciate any comment, correction or improvement.

Has someone written other examples or documentation on multitasking?

Thank you.

Marcos

-- 
http://programandala.net



reply via email to

[Prev in Thread] Current Thread [Next in Thread]