[q-lang-cvs] qcalc calclib.q,1.27,1.28
Brought to you by:
agraef
From: Albert G. <ag...@us...> - 2007-11-15 09:26:40
|
Update of /cvsroot/q-lang/qcalc In directory sc8-pr-cvs16.sourceforge.net:/tmp/cvs-serv821 Modified Files: calclib.q Log Message: allow a task to reexecute itself by a recursive invocation of the taskbutton function, bugfixes Index: calclib.q =================================================================== RCS file: /cvsroot/q-lang/qcalc/calclib.q,v retrieving revision 1.27 retrieving revision 1.28 diff -C2 -d -r1.27 -r1.28 *** calclib.q 15 Nov 2007 00:36:41 -0000 1.27 --- calclib.q 15 Nov 2007 09:26:36 -0000 1.28 *************** *** 168,187 **** if at all. However, it is a good idea to have the task at least empty the semaphore in regular time intervals to prevent the semaphore from being ! flooded with useless messages. (In any case the semaphore queue will be ! initially empty when the tread is started.) ! The task_input semaphore may also yield a quoted expression value to ! indicate that the task button itself was updated while the task is still ! running. This happens when a triggered update of the button is caused by ! some requisite cells of the task button formula changing values. In such a ! case, rather than reexecuting the taskbutton function and restarting the ! task from scratch, the button's X parameter is send via the semaphore as a ! quoted expression. Again, it is completely up to the task how it handles ! such messages. It may completely ignore the message, but a more appropriate ! response would be to just replace itself with the sent expression. ! Alternatively, the task may update its own internal state accordingly and ! continue processing. In the latter case, it is often convenient to employ ! the standard library special form 'case' to extract the needed values from ! the quoted expression. At any time, the background task can also send values back to the hosting --- 168,189 ---- if at all. However, it is a good idea to have the task at least empty the semaphore in regular time intervals to prevent the semaphore from being ! flooded with useless messages. In any case the semaphore queue will ! initially contain just the "startup" message (true if the task is initially ! started, false otherwise) when the tread is kicked off. ! The task_input semaphore may also yield a triple (S,INIT,'X) to indicate ! that the task button itself was updated while the task is still running. ! This happens when a triggered update of the button is caused by some ! requisite cells of the task button formula changing values. In such a case, ! rather than reexecuting the taskbutton function and restarting the task ! from scratch, the button's new parameters are sent via the semaphore, ! including the new thread expression which is transmitted in quoted form to ! prevent premature evaluation. Again, it is completely up to the task how it ! handles such a message; it may completely ignore it, or it may just ! reexecute the taskbutton function with the new parameters (unquoting the ! thread expression) to replace itself with the new task (to support this, ! the taskbutton function, unlike the other GUI elements, may also be ! executed asynchronously). Alternatively, the task may also cannibalize the ! given data and update its own internal state accordingly. At any time, the background task can also send values back to the hosting *************** *** 451,467 **** taskbutton (S:String,INIT:Bool) X where (I,J) = get YYKEY: ! // update an old task if still present ! = do (yytask (I,J)) ['X,INIT] || ! printf "\f+++ Taskbutton: %s %s\n" ! (str (I,J),str (S,INIT)) || yyset (I,J) INIT || INIT ! where (H,_,'_) = get YYTASKS!(I,J); // start up a new task = YYTASKS := insert (get YYTASKS) (I,J;H,SEM,'X) || post SEM INIT || ! printf "\f+++ Taskbutton: %s %s\n" ! (str (I,J),str (S,INIT)) || yyset (I,J) INIT || INIT where SEM:Semaphore = semaphore, H:Thread = thread (begin_task (I,J,SEM) || catch id X || end_task); /* Watchdogs for the beginning and end of a task. */ --- 453,476 ---- taskbutton (S:String,INIT:Bool) X where (I,J) = get YYKEY: ! // update existing task ! = yytask (I,J) (S,INIT,'X) if member (get YYTASKS) (I,J); // start up a new task = YYTASKS := insert (get YYTASKS) (I,J;H,SEM,'X) || post SEM INIT || ! yyset (I,J) INIT || INIT where SEM:Semaphore = semaphore, H:Thread = + printf "\f+++ Taskbutton: %s %s\n" + (str (I,J),str (S,INIT)) || thread (begin_task (I,J,SEM) || catch id X || end_task); + if active H where (I,J,_) = get YYSEM!thread_no this_thread, + (H:Thread,SEM,'_) = get YYTASKS!(I,J): + // request by a task to replace itself with a new task + = // update the button + do (setval (I,J)) [S,INIT] || + // update the task data + YYTASKS := insert (get YYTASKS) (I,J;H,SEM,'X) || + // send the startup message and tail-execute the new thread + post SEM INIT || yyset (I,J) INIT || X; /* Watchdogs for the beginning and end of a task. */ *************** *** 566,575 **** if isthread H; ! /* Update a task with a new thread expression. */ ! yytask (I:Int,J:Int) 'X where (H,SEM,'_) = get YYTASKS!(I,J): ! = post SEM (subst 'X) if isthread H and then active H; ! = YYTASKS := insert (get YYTASKS) (I,J;H,SEM,subst 'X); /* Kill a task. */ --- 575,587 ---- if isthread H; ! /* Update a task with new data. */ ! yytask (I:Int,J:Int) (S,INIT,'X) where (H,SEM,'_) = get YYTASKS!(I,J): ! // task is alive and kicking, update it with the new data ! = post SEM (S,INIT,subst 'X) || INIT ! if isthread H and then active H; ! // zombie: kill it, then restart ! = yytask (I,J) () || taskbutton (S,INIT) X; /* Kill a task. */ |