00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef __UT_Interrupt__
00021 #define __UT_Interrupt__
00022
00023 #include "UT_API.h"
00024
00025 #include <sys/types.h>
00026 #include "UT_String.h"
00027 #include "UT_PtrArray.h"
00028 #include "UT_RefArray.h"
00029 #include "UT_Signal.h"
00030 #include "UT_SysClone.h"
00031
00032 #include "UT_Lock.h"
00033 #ifndef GAMEOS
00034 #include "UT_SharedMem.h"
00035 #endif
00036
00037 class ut_IserverInterface;
00038 class ut_Iclient;
00039 class UT_Interrupt;
00040
00041 typedef void (*UT_InterruptCB)(UT_Interrupt *me, int state, const char *op);
00042 typedef void (*OPUI_UpdateModeCB)();
00043 typedef bool (*UI_CheckForEscapeCB)();
00044
00045 class UT_API UT_InterruptHandler
00046 {
00047 public:
00048 virtual ~UT_InterruptHandler() {}
00049 virtual void start(UT_Interrupt *intr,
00050 const char *optext,
00051 const char *main_op_text) =0;
00052 virtual void push(const char *text) =0;
00053 virtual void busyCheck(bool interrupted,
00054 float percent,
00055 float longpercent) = 0;
00056 virtual void pop() =0;
00057 virtual void stop() =0;
00058
00059 virtual void interruptAllowed(bool allowed, bool allow_ui) =0;
00060 };
00061
00062
00063
00064
00065 enum
00066 {
00067 ACTIVE_STOP,
00068 ACTIVE_START,
00069 ACTIVE_PUSH,
00070 ACTIVE_POP,
00071 ACTIVE_BUSY,
00072 ACTIVE_ALLOW_CHANGE
00073 };
00074
00075
00076 #ifdef GAMEOS
00077 class UT_API UT_Interrupt
00078 #else
00079 class UT_API UT_Interrupt : protected UT_SharedMem
00080 #endif
00081 {
00082 public:
00083 explicit UT_Interrupt(const char *app_title = 0);
00084 virtual ~UT_Interrupt();
00085
00086
00087
00088
00089
00090 void setEnabled(int state, int print_longtext = 0);
00091 bool isEnabled() const { return (bool) myEnableFlag; }
00092
00093
00094
00095 void setUseLocks(int state) { myUseLockFlag = (state != 0); }
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106 bool setInterruptable(bool allow, bool *prev_enabled = NULL,
00107 bool allow_ui = false);
00108 bool getInterruptable() const { return myInterruptable; }
00109 UT_Lock & getInterruptableLock() { return myInterruptableLock; }
00110 bool getAllowUI() const { return myAllowUI; }
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138 int opStart(const char *opname = 0, int npoll = 0,
00139 int immediate_dialog=0, int *opid=0);
00140 int opInterrupt(int percent = -1);
00141
00142 void opEnd(int opid=-1);
00143
00144
00145
00146
00147
00148 void setLongOpText(const char *longoptext);
00149 void setLongPercent(float percent);
00150
00151
00152
00153 void setAppTitle(const char *title);
00154 const char *getAppTitle() const { return myAppTitle; }
00155
00156
00157
00158
00159
00160 void setActiveCallback(UT_InterruptCB function)
00161 { myActiveCallback = function; }
00162
00163 void setInterruptHandler(UT_InterruptHandler *hand)
00164 {
00165 myUIHandler = hand;
00166 if(hand)
00167 hand->interruptAllowed(myInterruptable, myAllowUI);
00168 }
00169 UT_InterruptHandler *getInterruptHandler() { return myUIHandler; }
00170
00171
00172
00173 static void setUpdateModeCallback(OPUI_UpdateModeCB function)
00174 { ourMemoryThresholdCallback = function; }
00175
00176
00177
00178 static void setEscapeCheckCallback(UI_CheckForEscapeCB function)
00179 { ourEscapeCheckCallback = function; }
00180 static bool getIsEscapeCheckCallbackSet()
00181 { return ourEscapeCheckCallback; }
00182
00183
00184
00185
00186
00187
00188
00189
00190 void pushInterruptCallback(void (*callback)());
00191 void popInterruptCallback();
00192
00193
00194
00195
00196 void interrupt(int use_semaphore = 0);
00197
00198 void pause(bool dopause);
00199
00200 bool isPaused() const;
00201
00202
00203
00204 void setSignalCallback(UTsigHandler function);
00205
00206
00207 bool testMemoryThreshold()
00208 {
00209 return ourMemoryThresholdCallback
00210 ? doTestMemoryThreshold() : false;
00211 }
00212 protected:
00213
00214
00215 const char *getSharedKey() const;
00216
00217 virtual int detach();
00218
00219 #ifdef GAMEOS
00220 void *getMemory(int reuse=1) { return 0; }
00221 void destroy() {}
00222 int setKey(const char *, int id=0) { return -1; }
00223 int setKey(key_t key) { return -1; }
00224 int setSize(int size) { return size; }
00225 UT_String ourKeyPath;
00226 #endif
00227
00228 private:
00229 bool doTestMemoryThreshold();
00230 void testIdialogInterrupt();
00231 void testEscCallbackInterrupt();
00232
00233 void updateTitle(const char *);
00234 void operationComplete();
00235 void startServer();
00236 void stopServer();
00237 const char *getOpName() const;
00238 void callInterruptCB();
00239
00240
00241 UT_PtrArray<const char *> myOpNameStack;
00242
00243 UT_RefArray<void(*)()> myInterruptCBStack;
00244
00245 UT_String myAppTitle;
00246 UT_String myLongOpText;
00247 UT_InterruptCB myActiveCallback;
00248 UT_InterruptHandler *myUIHandler;
00249 char *myServerPath;
00250 char myPidString[16];
00251 const char *myArgv[16];
00252 int myOpDepth;
00253 UT_Interrupt *myPreviousInterrupt;
00254 UT_Signal *mySignal;
00255 UT_Signal *mySignalSubstitute;
00256 UTsigHandler mySignalCallback;
00257 pid_t myServerPID;
00258
00259 int myStartTime;
00260
00261 short myEnableFlag;
00262 short myStartedFlag;
00263 short myInterruptedFlag;
00264 char myPrintLongTextFlag;
00265 char myUseLockFlag;
00266 bool myInterruptable;
00267 bool myAllowUI;
00268 float myPercent;
00269 float myLongPercent;
00270 volatile bool myPaused;
00271
00272
00273
00274 static OPUI_UpdateModeCB ourMemoryThresholdCallback;
00275
00276
00277
00278 static UI_CheckForEscapeCB ourEscapeCheckCallback;
00279
00280 UT_Lock myLock;
00281 UT_Lock myInterruptableLock;
00282
00283 static void ut_interruptHandler(UTsignalHandlerArg);
00284 };
00285
00286 UT_API extern UT_Interrupt *UTgetInterrupt();
00287 UT_API extern void UTsetInterrupt(UT_Interrupt *);
00288
00289
00290
00291 class UT_API ut_InterruptTransactionData
00292 {
00293 public:
00294 volatile int myCommand;
00295 volatile float myPercent;
00296 volatile float myLongPercent;
00297 volatile int myNumMessages;
00298 volatile char myMessage[128];
00299 volatile char myLongMessage[128];
00300 };
00301
00302
00303
00304
00305 #ifdef GAMEOS
00306 class UT_API UT_InterruptClient
00307 #else
00308 class UT_API UT_InterruptClient : public UT_SharedMem
00309 #endif
00310 {
00311 public:
00312 UT_InterruptClient(pid_t server_id);
00313 ~UT_InterruptClient();
00314
00315 bool isInterrupted();
00316
00317 void setPercent(float p);
00318 void setLongPercent(float p);
00319
00320 void setMessage(const char *title);
00321
00322 #ifdef GAMEOS
00323 void *getMemory(int reuse=1) { return 0; }
00324 void destroy() {}
00325 int setKey(const char *, int id=0) { return -1; }
00326 int setKey(key_t key) { return -1; }
00327 int setSize(int size) { return size; }
00328 UT_String ourKeyPath;
00329 #endif
00330
00331 };
00332
00333
00334
00335 class UT_API UT_AutoInterrupt
00336 {
00337 public:
00338 UT_AutoInterrupt(const char* operation_name,
00339 UT_Interrupt *boss=UTgetInterrupt())
00340 : myInterrupt(boss)
00341 {
00342 myRunOk = myInterrupt ? (bool)myInterrupt->opStart(operation_name)
00343 : true;
00344 }
00345
00346 ~UT_AutoInterrupt()
00347 {
00348 if (myInterrupt)
00349 myInterrupt->opEnd();
00350 }
00351
00352 bool wasInterrupted()
00353 {
00354 if (myRunOk && myInterrupt && myInterrupt->opInterrupt())
00355 myRunOk = false;
00356 return !myRunOk;
00357 }
00358
00359 UT_Interrupt *getInterrupt() const { return myInterrupt; }
00360
00361 private:
00362 UT_Interrupt *myInterrupt;
00363 bool myRunOk;
00364 };
00365
00366 #endif