Added eventhandling in mainloop/busywait routine plus leaving some

cycles for background apps. MacOS has a new method to set the amount
of time for bg apps.
This commit is contained in:
Jack Jansen 1995-01-26 16:36:45 +00:00
parent 9eeb82dde1
commit e8e8ae0f2c
2 changed files with 142 additions and 18 deletions

View File

@ -107,6 +107,8 @@ MacOS_HighLevelEventProc(EventRecord *e)
}
}
/* XXXX Need to come here from PyMac_DoYield too... */
static PyObject *
MacOS_SetHighLevelEventHandler(self, args)
PyObject *self;
@ -166,6 +168,26 @@ MacOS_AcceptHighLevelEvent(self, args)
return res;
}
/*
** Set poll frequency and cpu-yield-time
*/
static PyObject *
MacOS_SetScheduleTimes(PyObject *self, PyObject *args)
{
long fgi, fgy, bgi, bgy;
bgi = bgy = -2;
if (!PyArg_ParseTuple(args, "ll|ll", &fgi, &fgy, &bgi, &bgy))
return NULL;
if ( bgi == -2 ) {
bgi = fgi;
bgy = fgy;
}
PyMac_SetYield(fgi, fgy, bgi, bgy);
Py_INCREF(Py_None);
return Py_None;
}
static PyMethodDef MacOS_Methods[] = {
{"AcceptHighLevelEvent", MacOS_AcceptHighLevelEvent, 1},
{"GetCreatorAndType", MacOS_GetCreatorAndType, 1},
@ -173,6 +195,7 @@ static PyMethodDef MacOS_Methods[] = {
#ifdef USE_STDWIN
{"SetHighLevelEventHandler", MacOS_SetHighLevelEventHandler, 1},
#endif
{"SetScheduleTimes", MacOS_SetScheduleTimes, 1},
{NULL, NULL} /* Sentinel */
};

View File

@ -26,16 +26,43 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include "macglue.h"
#include <OSUtils.h> /* for Set(Current)A5 */
#include <Files.h>
#include <Resources.h>
#include <Memory.h>
#include <Events.h>
#include <Windows.h>
#include <Desk.h>
#include <Traps.h>
#ifdef __MWERKS__
#include <SIOUX.h>
#endif /* __MWERKS__ */
#include <signal.h>
/* XXX We should include Errors.h here, but it has a name conflict
** with the python errors.h. */
#define fnfErr -43
/* Declared in macfsmodule.c: */
extern FSSpec *mfs_GetFSSpecFSSpec();
/*
** We attempt to be a good citizen by giving up the CPU periodically.
** When in the foreground we do this less often and for shorter periods
** than when in the background. At this time we also check for events and
** pass them off to stdwin (or SIOUX, if compiling with mwerks).
** The counts here are in ticks of 1/60th second.
** XXXX The initial values here are not based on anything.
** FG-python gives up the cpu for 1/60th 5 times per second,
** BG-python for .2 second 10 times per second.
*/
static long interval_fg = 12;
static long interval_bg = 6;
static long yield_fg = 1;
static long yield_bg = 12;
static long lastyield, in_background;
/* Convert C to Pascal string. Returns pointer to static buffer. */
unsigned char *
Pstring(char *str)
@ -111,28 +138,101 @@ PyMac_Error(OSErr err)
}
/*
** Idle routine for busy-wait loops.
** This is rather tricky: if we see an event we check whether it is
** for somebody else (i.e. a click outside our windows) and, if so,
** we pass the event on (so the user can switch processes). However,
** by doing this we loose events meant for our windows. Too bad, I guess...
** Set yield timeouts
*/
int
PyMac_Idle()
void
PyMac_SetYield(long fgi, long fgy, long bgi, long bgy)
{
interval_fg = fgi;
yield_fg = fgy;
interval_bg = bgi;
yield_bg = bgy;
}
/*
** Yield the CPU to other tasks.
*/
static
PyMac_DoYield()
{
EventRecord ev;
WindowPtr wp;
long yield;
extern int StdwinIsActive;
static int no_waitnextevent = -1;
int gotone;
if ( no_waitnextevent < 0 ) {
no_waitnextevent = (NGetTrapAddress(_WaitNextEvent, ToolTrap) ==
NGetTrapAddress(_Unimplemented, ToolTrap));
}
SystemTask();
if ( intrpeek() )
return 0;
if ( GetNextEvent(0xffff, &ev) ) {
if ( StdwinIsActive )
return;
if ( in_background )
yield = yield_bg;
else
yield = yield_fg;
while ( 1 ) {
if ( no_waitnextevent ) {
SystemTask();
gotone = GetNextEvent(0xffff, &ev);
} else {
gotone = WaitNextEvent(everyEvent, &ev, yield, NULL);
}
/* Get out quickly if nothing interesting is happening */
if ( !gotone || ev.what == nullEvent )
break;
/* Check whether we've moved to foreground or background */
if ( ev.what == osEvt &&
(ev.message & osEvtMessageMask) == (suspendResumeMessage<<24)) {
if ( ev.message & resumeFlag ) {
in_background = 0;
} else {
in_background = 1;
}
}
#ifdef __MWERKS__
/* If SIOUX wants it we're done too */
(void)SIOUXHandleOneEvent(&ev);
#else
/* Other compilers are just unlucky: we only weed out clicks in other applications */
if ( ev.what == mouseDown ) {
if ( FindWindow(ev.where, &wp) == inSysWindow )
SystemClick(&ev, wp);
}
#endif /* !__MWERKS__ */
}
return 1;
lastyield = TickCount();
}
/*
** Yield the CPU to other tasks if opportune
*/
void
PyMac_Yield() {
long iv;
if ( in_background )
iv = interval_bg;
else
iv = interval_fg;
if ( TickCount() > lastyield + iv )
PyMac_DoYield();
}
/*
** Idle routine for busy-wait loops.
** Gives up CPU, handles events and returns true if an interrupt is pending
** (but not actually handled yet).
*/
int
PyMac_Idle()
{
PyMac_DoYield();
return intrpeek();
}
@ -196,7 +296,14 @@ PyMac_GetFSSpec(PyObject *v, FSSpec *fs)
short refnum;
long parid;
OSErr err;
FSSpec *fs2;
/* first check whether it already is an FSSpec */
fs2 = mfs_GetFSSpecFSSpec(v);
if ( fs2 ) {
fs = fs2;
return 1;
}
if ( PyString_Check(v) ) {
/* It's a pathname */
if( !PyArg_Parse(v, "O&", PyMac_GetStr255, &path) )
@ -217,12 +324,6 @@ PyMac_GetFSSpec(PyObject *v, FSSpec *fs)
return 1;
}
/* Convert an FSSpec to a Python object -- a triple (vrefnum, dirid, path) */
PyObject *
PyMac_BuildFSSpec(FSSpec *fs)
{
return Py_BuildValue("(iis#)", fs->vRefNum, fs->parID, &fs->name[1], fs->name[0]);
}
/* Convert a Python object to a Rect.