Bugfix with py operator api and modal operators. Modal operators would keep a reference to Reports locally allocated in the api functions, which would crash and burn later when the operator would actually stop.

This commit introduces a flag at the Reports level that can be used to indicate that it needs to be freed (on top of the flag already existing in the operator, which I guess could be removed).

Reports for operators called through python are only persisted if they indicate that they are running modal.
This commit is contained in:
Martin Poirier 2009-09-14 16:00:42 +00:00
parent 733b20f695
commit a3ce413f44
4 changed files with 17 additions and 6 deletions

@ -80,6 +80,7 @@ typedef enum ReportType {
enum ReportListFlags { enum ReportListFlags {
RPT_PRINT = 1, RPT_PRINT = 1,
RPT_STORE = 2, RPT_STORE = 2,
RPT_FREE = 4,
}; };
typedef struct Report { typedef struct Report {
struct Report *next, *prev; struct Report *next, *prev;

@ -79,16 +79,21 @@ static PyObject *pyop_call( PyObject * self, PyObject * args)
if (error_val==0) { if (error_val==0) {
ReportList reports; ReportList *reports;
BKE_reports_init(&reports, RPT_STORE); reports= MEM_mallocN(sizeof(ReportList), "wmOperatorReportList");
BKE_reports_init(reports, RPT_STORE);
WM_operator_call_py(C, ot, context, &ptr, &reports); WM_operator_call_py(C, ot, context, &ptr, reports);
if(BPy_reports_to_error(&reports)) if(BPy_reports_to_error(reports))
error_val = -1; error_val = -1;
BKE_reports_clear(&reports); BKE_reports_clear(reports);
if ((reports->flag & RPT_FREE) == 0)
{
MEM_freeN(reports);
}
} }
WM_operator_properties_free(&ptr); WM_operator_properties_free(&ptr);

@ -69,7 +69,7 @@ void WM_operator_free(wmOperator *op)
MEM_freeN(op->properties); MEM_freeN(op->properties);
} }
if(op->reports && (op->flag & OPERATOR_REPORT_FREE)) { if(op->reports && ((op->flag & OPERATOR_REPORT_FREE) || (op->reports->flag & RPT_FREE))) {
BKE_reports_clear(op->reports); BKE_reports_clear(op->reports);
MEM_freeN(op->reports); MEM_freeN(op->reports);
} }

@ -555,6 +555,11 @@ int WM_operator_call_py(bContext *C, wmOperatorType *ot, int context, PointerRNA
retval= wm_operator_call_internal(C, ot, context, properties, reports); retval= wm_operator_call_internal(C, ot, context, properties, reports);
if (retval & OPERATOR_RUNNING_MODAL)
{
reports->flag |= RPT_FREE;
}
return retval; return retval;
} }