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:
		@@ -80,6 +80,7 @@ typedef enum ReportType {
 | 
			
		||||
enum ReportListFlags {
 | 
			
		||||
	RPT_PRINT = 1,
 | 
			
		||||
	RPT_STORE = 2,
 | 
			
		||||
	RPT_FREE = 4,
 | 
			
		||||
};
 | 
			
		||||
typedef struct Report {
 | 
			
		||||
	struct Report *next, *prev;
 | 
			
		||||
 
 | 
			
		||||
@@ -79,16 +79,21 @@ static PyObject *pyop_call( PyObject * self, PyObject * args)
 | 
			
		||||
 | 
			
		||||
	
 | 
			
		||||
	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;
 | 
			
		||||
 | 
			
		||||
		BKE_reports_clear(&reports);
 | 
			
		||||
		BKE_reports_clear(reports);
 | 
			
		||||
		if ((reports->flag & RPT_FREE) == 0)
 | 
			
		||||
		{
 | 
			
		||||
			MEM_freeN(reports);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	WM_operator_properties_free(&ptr);
 | 
			
		||||
 
 | 
			
		||||
@@ -69,7 +69,7 @@ void WM_operator_free(wmOperator *op)
 | 
			
		||||
		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);
 | 
			
		||||
		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);
 | 
			
		||||
	
 | 
			
		||||
	if (retval & OPERATOR_RUNNING_MODAL)
 | 
			
		||||
	{
 | 
			
		||||
		reports->flag |= RPT_FREE;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	return retval;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user