diff options
author | Steve Bennett <steveb@workware.net.au> | 2016-03-25 18:09:56 +1000 |
---|---|---|
committer | Steve Bennett <steveb@workware.net.au> | 2025-03-13 10:26:16 +1000 |
commit | 15477c68e844200114bb3e13d895b7897b482864 (patch) | |
tree | add7c619d76390ebe46a964d431c911374f02bf1 | |
parent | 54c9f51c15e7cbb3e2a62e04b1ad87402cb41486 (diff) | |
download | jimtcl-15477c68e844200114bb3e13d895b7897b482864.zip jimtcl-15477c68e844200114bb3e13d895b7897b482864.tar.gz jimtcl-15477c68e844200114bb3e13d895b7897b482864.tar.bz2 |
eventloop: Add support for vwait script
An additional arg to vwait is now supported:
vwait ?-signal? var ?script?
If the script is given it is evaluated on every event.
If the script returns a break or error code, the vwait terminates.
This approach makes it easier to avoid using global variables to
control the eventloop.
Signed-off-by: Steve Bennett <steveb@workware.net.au>
-rw-r--r-- | jim-eventloop.c | 27 |
1 files changed, 22 insertions, 5 deletions
diff --git a/jim-eventloop.c b/jim-eventloop.c index fa5631f..a3880ad 100644 --- a/jim-eventloop.c +++ b/jim-eventloop.c @@ -564,19 +564,24 @@ static void JimELAssocDataDeleProc(Jim_Interp *interp, void *data) static int JimELVwaitCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { Jim_EventLoop *eventLoop = Jim_CmdPrivData(interp); - Jim_Obj *oldValue; + Jim_Obj *oldValue = NULL; + Jim_Obj *scriptObjPtr = NULL; int rc; int signal = 0; - if (argc == 3 && Jim_CompareStringImmediate(interp, argv[1], "-signal")) { + if (argc > 2 && Jim_CompareStringImmediate(interp, argv[1], "-signal")) { signal++; } - if (argc - signal != 2) { + if (argc - signal == 3) { + scriptObjPtr = argv[2 + signal]; + } + else if (argc - signal != 2) { return JIM_USAGE; } oldValue = Jim_GetGlobalVariable(interp, argv[1 + signal], JIM_NONE); + if (oldValue) { Jim_IncrRefCount(oldValue); } @@ -590,6 +595,8 @@ static int JimELVwaitCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) eventLoop->suppress_bgerror = 0; while ((rc = Jim_ProcessEvents(interp, JIM_ALL_EVENTS)) >= 0) { + Jim_Obj *currValue; + if (signal && interp->sigmask) { /* vwait -signal and handled signals were received, so transfer them * to ignored signals so that 'signal check -clear' will return them. @@ -602,7 +609,7 @@ static int JimELVwaitCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) interp->sigmask = 0; break; } - Jim_Obj *currValue; + currValue = Jim_GetGlobalVariable(interp, argv[1 + signal], JIM_NONE); /* Stop the loop if the vwait-ed variable changed value, * or if was unset and now is set (or the contrary) @@ -614,6 +621,16 @@ static int JimELVwaitCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) Jim_CheckSignal(interp)) { break; } + if (scriptObjPtr) { + /* Stop the loop if a provided script returns BREAK or ERR */ + int retval = Jim_EvalObj(interp, scriptObjPtr); + if (retval == JIM_ERR || retval == JIM_BREAK) { + if (retval == JIM_ERR) { + rc = -2; + } + break; + } + } } if (oldValue) Jim_DecrRefCount(interp, oldValue); @@ -785,7 +802,7 @@ int Jim_eventloopInit(Jim_Interp *interp) Jim_SetAssocData(interp, "eventloop", JimELAssocDataDeleProc, eventLoop); - Jim_RegisterCmd(interp, "vwait", "?-signal? name", 1, 2, JimELVwaitCommand, NULL, eventLoop, 0); + Jim_RegisterCmd(interp, "vwait", "?-signal? name ?script?", 1, 3, JimELVwaitCommand, NULL, eventLoop, 0); Jim_RegisterCmd(interp, "update", "?idletasks?", 0, 1, JimELUpdateCommand, NULL, eventLoop, 0); Jim_RegisterCmd(interp, "after", "option ?arg ...?", 1, -1, JimELAfterCommand, NULL, eventLoop, 0); |