[Python-checkins] CVS: python/dist/src/Mac/Modules/carbonevt CarbonEvtscan.py,1.3,1.4 CarbonEvtsupport.py,1.6,1.7 _CarbonEvtmodule.c,1.3,1.4

Just van Rossum jvr@users.sourceforge.net
Fri, 14 Dec 2001 15:16:06 -0800


Update of /cvsroot/python/python/dist/src/Mac/Modules/carbonevt
In directory usw-pr-cvs1:/tmp/cvs-serv23350

Modified Files:
	CarbonEvtscan.py CarbonEvtsupport.py _CarbonEvtmodule.c 
Log Message:
Made event callbacks more rubust: keep an actual reference to the
python callback, and do RemoveEventHandler() upon deallocation.

Index: CarbonEvtscan.py
===================================================================
RCS file: /cvsroot/python/python/dist/src/Mac/Modules/carbonevt/CarbonEvtscan.py,v
retrieving revision 1.3
retrieving revision 1.4
diff -C2 -d -r1.3 -r1.4
*** CarbonEvtscan.py	2001/12/12 20:48:53	1.3
--- CarbonEvtscan.py	2001/12/14 23:16:04	1.4
***************
*** 42,52 ****
  		if arglist:
  			t, n, m = arglist[0]
- 			print "*********", t,
  			if t in RefObjectTypes and m == "InMode":
! 				print "method"
! 				classname = "CarbonEventsMethod"
  				listname = t + "methods"
! 			else:
! 				print "not method"
  		return classname, listname
  
--- 42,53 ----
  		if arglist:
  			t, n, m = arglist[0]
  			if t in RefObjectTypes and m == "InMode":
! 				if t == "EventHandlerRef":
! 					classname = "EventHandlerRefMethod"
! 				else:
! 					classname = "CarbonEventsMethod"
  				listname = t + "methods"
! 			#else:
! 			#	print "not method"
  		return classname, listname
  
***************
*** 83,86 ****
--- 84,88 ----
  			# Wrote by hand
  			"InstallEventHandler",
+ 			"RemoveEventHandler",
  			"RunApplicationEventLoop",
  						

Index: CarbonEvtsupport.py
===================================================================
RCS file: /cvsroot/python/python/dist/src/Mac/Modules/carbonevt/CarbonEvtsupport.py,v
retrieving revision 1.6
retrieving revision 1.7
diff -C2 -d -r1.6 -r1.7
*** CarbonEvtsupport.py	2001/12/12 21:48:00	1.6
--- CarbonEvtsupport.py	2001/12/14 23:16:04	1.7
***************
*** 12,15 ****
--- 12,16 ----
  	exec execstr
  
+ 
  if 0:
  	# these types will have no methods and will merely be opaque blobs
***************
*** 54,57 ****
--- 55,66 ----
  CarbonEventsMethod = OSErrMethodGenerator
  
+ class EventHandlerRefMethod(OSErrMethodGenerator):
+ 	def precheck(self):
+ 		OutLbrace('if (_self->ob_itself == NULL)')
+ 		Output('PyErr_SetString(CarbonEvents_Error, "Handler has been removed");')
+ 		Output('return NULL;')
+ 		OutRbrace()
+ 
+ 
  includestuff = r"""
  #ifdef WITHOUT_FRAMEWORKS
***************
*** 189,201 ****
  module = MacModule('_CarbonEvt', 'CarbonEvents', includestuff, finalstuff, initstuff)
  
- #class CFReleaserObj(GlobalObjectDefinition):
- #	def outputFreeIt(self, name):
- #		Output("CFRelease(%s);" % name)
  
  for typ in RefObjectTypes:
! 	execstr = typ + 'object = GlobalObjectDefinition(typ)'
! 	exec execstr
  	module.addobject(eval(typ + 'object'))
  
  functions = []
  for typ in RefObjectTypes: ## go thru all ObjectTypes as defined in CarbonEventsscan.py
--- 198,226 ----
  module = MacModule('_CarbonEvt', 'CarbonEvents', includestuff, finalstuff, initstuff)
  
  
+ 
+ 
+ class EventHandlerRefObjectDefinition(GlobalObjectDefinition):
+ 	def outputStructMembers(self):
+ 		Output("%s ob_itself;", self.itselftype)
+ 		Output("PyObject *ob_callback;")
+ 	def outputInitStructMembers(self):
+ 		Output("it->ob_itself = %sitself;", self.argref)
+ 		Output("it->ob_callback = NULL;")
+ 	def outputFreeIt(self, name):
+ 		OutLbrace("if (self->ob_itself != NULL)")
+ 		Output("RemoveEventHandler(self->ob_itself);")
+ 		Output("Py_DECREF(self->ob_callback);")
+ 		OutRbrace()
+ 
  for typ in RefObjectTypes:
! 	if typ == 'EventHandlerRef':
! 		EventHandlerRefobject = EventHandlerRefObjectDefinition('EventHandlerRef')
! 	else:
! 		execstr = typ + 'object = GlobalObjectDefinition(typ)'
! 		exec execstr
  	module.addobject(eval(typ + 'object'))
  
+ 
  functions = []
  for typ in RefObjectTypes: ## go thru all ObjectTypes as defined in CarbonEventsscan.py
***************
*** 206,209 ****
--- 231,236 ----
  execfile('CarbonEventsgen.py')
  
+ 
+ 
  for f in functions: module.add(f)	# add all the functions carboneventsgen put in the list
  
***************
*** 213,216 ****
--- 240,266 ----
  	for m in methods: obj.add(m)	## add each method in the list to the object
  
+ 
+ removeeventhandler = """
+ OSStatus _err;
+ if (_self->ob_itself == NULL) {
+ 	PyErr_SetString(CarbonEvents_Error, "Handler has been removed");
+ 	return NULL;
+ }
+ if (!PyArg_ParseTuple(_args, ""))
+ 	return NULL;
+ _err = RemoveEventHandler(_self->ob_itself);
+ if (_err != noErr) return PyMac_Error(_err);
+ _self->ob_itself = NULL;
+ Py_DECREF(_self->ob_callback);
+ _self->ob_callback = NULL;
+ Py_INCREF(Py_None);
+ _res = Py_None;
+ return _res;"""
+ 
+ f = ManualGenerator("RemoveEventHandler", removeeventhandler);
+ f.docstring = lambda: "() -> None"
+ EventHandlerRefobject.add(f)
+ 
+ 
  installeventhandler = """
  EventTypeSpec inSpec;
***************
*** 225,232 ****
  if (_err != noErr) return PyMac_Error(_err);
  
! return Py_BuildValue("O&", EventHandlerRef_New, outRef);"""
  
  f = ManualGenerator("InstallEventHandler", installeventhandler);
! f.docstring = lambda: "(EventTargetRef inTarget, EventTypeSpec inSpec, Method callback) -> (EventHandlerRef outRef)"
  EventTargetRefobject.add(f)
  
--- 275,287 ----
  if (_err != noErr) return PyMac_Error(_err);
  
! _res = EventHandlerRef_New(outRef);
! if (_res != NULL) {
! 	((EventHandlerRefObject*)_res)->ob_callback = callback;
! 	Py_INCREF(callback);
! }
! return _res;"""
  
  f = ManualGenerator("InstallEventHandler", installeventhandler);
! f.docstring = lambda: "(EventTypeSpec inSpec, Method callback) -> (EventHandlerRef outRef)"
  EventTargetRefobject.add(f)
  

Index: _CarbonEvtmodule.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Mac/Modules/carbonevt/_CarbonEvtmodule.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -C2 -d -r1.3 -r1.4
*** _CarbonEvtmodule.c	2001/12/12 21:48:00	1.3
--- _CarbonEvtmodule.c	2001/12/14 23:16:04	1.4
***************
*** 800,803 ****
--- 800,804 ----
  	PyObject_HEAD
  	EventHandlerRef ob_itself;
+ 	PyObject *ob_callback;
  } EventHandlerRefObject;
  
***************
*** 808,811 ****
--- 809,813 ----
  	if (it == NULL) return NULL;
  	it->ob_itself = itself;
+ 	it->ob_callback = NULL;
  	return (PyObject *)it;
  }
***************
*** 823,843 ****
  static void EventHandlerRef_dealloc(EventHandlerRefObject *self)
  {
! 	/* Cleanup of self->ob_itself goes here */
  	PyMem_DEL(self);
  }
  
- static PyObject *EventHandlerRef_RemoveEventHandler(EventHandlerRefObject *_self, PyObject *_args)
- {
- 	PyObject *_res = NULL;
- 	OSStatus _err;
- 	if (!PyArg_ParseTuple(_args, ""))
- 		return NULL;
- 	_err = RemoveEventHandler(_self->ob_itself);
- 	if (_err != noErr) return PyMac_Error(_err);
- 	Py_INCREF(Py_None);
- 	_res = Py_None;
- 	return _res;
- }
- 
  static PyObject *EventHandlerRef_AddEventTypesToHandler(EventHandlerRefObject *_self, PyObject *_args)
  {
--- 825,835 ----
  static void EventHandlerRef_dealloc(EventHandlerRefObject *self)
  {
! 	if (self->ob_itself != NULL) {
! 		RemoveEventHandler(self->ob_itself);
! 		Py_DECREF(self->ob_callback);
! 	}
  	PyMem_DEL(self);
  }
  
  static PyObject *EventHandlerRef_AddEventTypesToHandler(EventHandlerRefObject *_self, PyObject *_args)
  {
***************
*** 846,849 ****
--- 838,845 ----
  	UInt32 inNumTypes;
  	EventTypeSpec inList;
+ 	if (_self->ob_itself == NULL) {
+ 		PyErr_SetString(CarbonEvents_Error, "Handler has been removed");
+ 		return NULL;
+ 	}
  	if (!PyArg_ParseTuple(_args, "lO&",
  	                      &inNumTypes,
***************
*** 865,868 ****
--- 861,868 ----
  	UInt32 inNumTypes;
  	EventTypeSpec inList;
+ 	if (_self->ob_itself == NULL) {
+ 		PyErr_SetString(CarbonEvents_Error, "Handler has been removed");
+ 		return NULL;
+ 	}
  	if (!PyArg_ParseTuple(_args, "lO&",
  	                      &inNumTypes,
***************
*** 878,888 ****
  }
  
  static PyMethodDef EventHandlerRef_methods[] = {
- 	{"RemoveEventHandler", (PyCFunction)EventHandlerRef_RemoveEventHandler, 1,
- 	 "() -> None"},
  	{"AddEventTypesToHandler", (PyCFunction)EventHandlerRef_AddEventTypesToHandler, 1,
  	 "(UInt32 inNumTypes, EventTypeSpec inList) -> None"},
  	{"RemoveEventTypesFromHandler", (PyCFunction)EventHandlerRef_RemoveEventTypesFromHandler, 1,
  	 "(UInt32 inNumTypes, EventTypeSpec inList) -> None"},
  	{NULL, NULL, 0}
  };
--- 878,909 ----
  }
  
+ static PyObject *EventHandlerRef_RemoveEventHandler(EventHandlerRefObject *_self, PyObject *_args)
+ {
+ 	PyObject *_res = NULL;
+ 
+ 	OSStatus _err;
+ 	if (_self->ob_itself == NULL) {
+ 		PyErr_SetString(CarbonEvents_Error, "Handler has been removed");
+ 		return NULL;
+ 	}
+ 	if (!PyArg_ParseTuple(_args, ""))
+ 		return NULL;
+ 	_err = RemoveEventHandler(_self->ob_itself);
+ 	if (_err != noErr) return PyMac_Error(_err);
+ 	_self->ob_itself = NULL;
+ 	Py_DECREF(_self->ob_callback);
+ 	_self->ob_callback = NULL;
+ 	Py_INCREF(Py_None);
+ 	_res = Py_None;
+ 	return _res;
+ }
+ 
  static PyMethodDef EventHandlerRef_methods[] = {
  	{"AddEventTypesToHandler", (PyCFunction)EventHandlerRef_AddEventTypesToHandler, 1,
  	 "(UInt32 inNumTypes, EventTypeSpec inList) -> None"},
  	{"RemoveEventTypesFromHandler", (PyCFunction)EventHandlerRef_RemoveEventTypesFromHandler, 1,
  	 "(UInt32 inNumTypes, EventTypeSpec inList) -> None"},
+ 	{"RemoveEventHandler", (PyCFunction)EventHandlerRef_RemoveEventHandler, 1,
+ 	 "() -> None"},
  	{NULL, NULL, 0}
  };
***************
*** 1084,1088 ****
  	if (_err != noErr) return PyMac_Error(_err);
  
! 	return Py_BuildValue("O&", EventHandlerRef_New, outRef);
  }
  
--- 1105,1114 ----
  	if (_err != noErr) return PyMac_Error(_err);
  
! 	_res = EventHandlerRef_New(outRef);
! 	if (_res != NULL) {
! 		((EventHandlerRefObject*)_res)->ob_callback = callback;
! 		Py_INCREF(callback);
! 	}
! 	return _res;
  }
  
***************
*** 1091,1095 ****
  	 "() -> None"},
  	{"InstallEventHandler", (PyCFunction)EventTargetRef_InstallEventHandler, 1,
! 	 "(EventTargetRef inTarget, EventTypeSpec inSpec, Method callback) -> (EventHandlerRef outRef)"},
  	{NULL, NULL, 0}
  };
--- 1117,1121 ----
  	 "() -> None"},
  	{"InstallEventHandler", (PyCFunction)EventTargetRef_InstallEventHandler, 1,
! 	 "(EventTypeSpec inSpec, Method callback) -> (EventHandlerRef outRef)"},
  	{NULL, NULL, 0}
  };