forked from bartvdbraak/blender
option so operators can be executed with undo enabled (and redo).
This commit is contained in:
parent
d30c7356b7
commit
a09feb7386
@ -57,11 +57,11 @@
|
|||||||
* lets you count the allocations so as to find the allocator of unfreed memory
|
* lets you count the allocations so as to find the allocator of unfreed memory
|
||||||
* in situations where the leak is predictable */
|
* in situations where the leak is predictable */
|
||||||
|
|
||||||
// #define DEBUG_MEMCOUNTER
|
#define DEBUG_MEMCOUNTER
|
||||||
|
|
||||||
#ifdef DEBUG_MEMCOUNTER
|
#ifdef DEBUG_MEMCOUNTER
|
||||||
/* set this to the value that isn't being freed */
|
/* set this to the value that isn't being freed */
|
||||||
# define DEBUG_MEMCOUNTER_ERROR_VAL 0
|
# define DEBUG_MEMCOUNTER_ERROR_VAL 34723
|
||||||
static int _mallocn_count = 0;
|
static int _mallocn_count = 0;
|
||||||
|
|
||||||
/* breakpoint here */
|
/* breakpoint here */
|
||||||
|
@ -120,20 +120,28 @@ class BPyOpsSubModOp(object):
|
|||||||
def _parse_args(args):
|
def _parse_args(args):
|
||||||
C_dict = None
|
C_dict = None
|
||||||
C_exec = 'EXEC_DEFAULT'
|
C_exec = 'EXEC_DEFAULT'
|
||||||
|
C_undo = False
|
||||||
|
|
||||||
if len(args) == 0:
|
is_dict = is_exec = is_undo = False
|
||||||
pass
|
|
||||||
elif len(args) == 1:
|
|
||||||
if type(args[0]) != str:
|
|
||||||
C_dict = args[0]
|
|
||||||
else:
|
|
||||||
C_exec = args[0]
|
|
||||||
elif len(args) == 2:
|
|
||||||
C_exec, C_dict = args
|
|
||||||
else:
|
|
||||||
raise ValueError("1 or 2 args execution context is supported")
|
|
||||||
|
|
||||||
return C_dict, C_exec
|
for i, arg in enumerate(args):
|
||||||
|
if is_dict is False and isinstance(arg, dict):
|
||||||
|
if is_exec is True or is_undo is True:
|
||||||
|
raise ValueError("dict arg must come first")
|
||||||
|
C_dict = arg
|
||||||
|
is_dict = True
|
||||||
|
elif is_exec is False and isinstance(arg, str):
|
||||||
|
if is_undo is True:
|
||||||
|
raise ValueError("string arg must come before the boolean")
|
||||||
|
C_exec = arg
|
||||||
|
is_exec = True
|
||||||
|
elif is_undo is False and isinstance(arg, int):
|
||||||
|
C_undo = arg
|
||||||
|
is_undo = True
|
||||||
|
else:
|
||||||
|
raise ValueError("1-3 args execution context is supported")
|
||||||
|
|
||||||
|
return C_dict, C_exec, C_undo
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _scene_update(context):
|
def _scene_update(context):
|
||||||
@ -152,7 +160,7 @@ class BPyOpsSubModOp(object):
|
|||||||
self.func = func
|
self.func = func
|
||||||
|
|
||||||
def poll(self, *args):
|
def poll(self, *args):
|
||||||
C_dict, C_exec = BPyOpsSubModOp._parse_args(args)
|
C_dict, C_exec, C_undo = BPyOpsSubModOp._parse_args(args)
|
||||||
return op_poll(self.idname_py(), C_dict, C_exec)
|
return op_poll(self.idname_py(), C_dict, C_exec)
|
||||||
|
|
||||||
def idname(self):
|
def idname(self):
|
||||||
@ -174,8 +182,8 @@ class BPyOpsSubModOp(object):
|
|||||||
BPyOpsSubModOp._scene_update(context)
|
BPyOpsSubModOp._scene_update(context)
|
||||||
|
|
||||||
if args:
|
if args:
|
||||||
C_dict, C_exec = BPyOpsSubModOp._parse_args(args)
|
C_dict, C_exec, C_undo = BPyOpsSubModOp._parse_args(args)
|
||||||
ret = op_call(self.idname_py(), C_dict, kw, C_exec)
|
ret = op_call(self.idname_py(), C_dict, kw, C_exec, C_undo)
|
||||||
else:
|
else:
|
||||||
ret = op_call(self.idname_py(), None, kw)
|
ret = op_call(self.idname_py(), None, kw)
|
||||||
|
|
||||||
|
@ -147,6 +147,7 @@ static PyObject *pyop_call(PyObject *UNUSED(self), PyObject *args)
|
|||||||
|
|
||||||
/* note that context is an int, python does the conversion in this case */
|
/* note that context is an int, python does the conversion in this case */
|
||||||
int context = WM_OP_EXEC_DEFAULT;
|
int context = WM_OP_EXEC_DEFAULT;
|
||||||
|
int is_undo = FALSE;
|
||||||
|
|
||||||
/* XXX Todo, work out a better solution for passing on context,
|
/* XXX Todo, work out a better solution for passing on context,
|
||||||
* could make a tuple from self and pack the name and Context into it... */
|
* could make a tuple from self and pack the name and Context into it... */
|
||||||
@ -157,7 +158,8 @@ static PyObject *pyop_call(PyObject *UNUSED(self), PyObject *args)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "sO|O!s:_bpy.ops.call", &opname, &context_dict, &PyDict_Type, &kw, &context_str))
|
if (!PyArg_ParseTuple(args, "sO|O!si:_bpy.ops.call",
|
||||||
|
&opname, &context_dict, &PyDict_Type, &kw, &context_str, &is_undo))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
ot = WM_operatortype_find(opname, TRUE);
|
ot = WM_operatortype_find(opname, TRUE);
|
||||||
@ -236,7 +238,7 @@ static PyObject *pyop_call(PyObject *UNUSED(self), PyObject *args)
|
|||||||
PyThreadState *ts = PyEval_SaveThread();
|
PyThreadState *ts = PyEval_SaveThread();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
operator_ret = WM_operator_call_py(C, ot, context, &ptr, reports);
|
operator_ret = WM_operator_call_py(C, ot, context, &ptr, reports, is_undo);
|
||||||
|
|
||||||
#ifdef BPY_RELEASE_GIL
|
#ifdef BPY_RELEASE_GIL
|
||||||
/* regain GIL */
|
/* regain GIL */
|
||||||
|
@ -193,13 +193,13 @@ struct wmOperatorTypeMacro *WM_operatortype_macro_define(struct wmOperatorType *
|
|||||||
|
|
||||||
|
|
||||||
int WM_operator_poll (struct bContext *C, struct wmOperatorType *ot);
|
int WM_operator_poll (struct bContext *C, struct wmOperatorType *ot);
|
||||||
int WM_operator_poll_context(struct bContext *C, struct wmOperatorType *ot, int context);
|
int WM_operator_poll_context(struct bContext *C, struct wmOperatorType *ot, short context);
|
||||||
int WM_operator_call (struct bContext *C, struct wmOperator *op);
|
int WM_operator_call (struct bContext *C, struct wmOperator *op);
|
||||||
int WM_operator_call_notest(struct bContext *C, struct wmOperator *op);
|
int WM_operator_call_notest(struct bContext *C, struct wmOperator *op);
|
||||||
int WM_operator_repeat (struct bContext *C, struct wmOperator *op);
|
int WM_operator_repeat (struct bContext *C, struct wmOperator *op);
|
||||||
int WM_operator_repeat_check(const struct bContext *C, struct wmOperator *op);
|
int WM_operator_repeat_check(const struct bContext *C, struct wmOperator *op);
|
||||||
int WM_operator_name_call (struct bContext *C, const char *opstring, int context, struct PointerRNA *properties);
|
int WM_operator_name_call (struct bContext *C, const char *opstring, short context, struct PointerRNA *properties);
|
||||||
int WM_operator_call_py(struct bContext *C, struct wmOperatorType *ot, int context, struct PointerRNA *properties, struct ReportList *reports);
|
int WM_operator_call_py(struct bContext *C, struct wmOperatorType *ot, short context, struct PointerRNA *properties, struct ReportList *reports, short is_undo);
|
||||||
|
|
||||||
void WM_operator_properties_alloc(struct PointerRNA **ptr, struct IDProperty **properties, const char *opstring); /* used for keymap and macro items */
|
void WM_operator_properties_alloc(struct PointerRNA **ptr, struct IDProperty **properties, const char *opstring); /* used for keymap and macro items */
|
||||||
void WM_operator_properties_sanitize(struct PointerRNA *ptr, const short no_context); /* make props context sensitive or not */
|
void WM_operator_properties_sanitize(struct PointerRNA *ptr, const short no_context); /* make props context sensitive or not */
|
||||||
|
@ -417,7 +417,7 @@ int WM_operator_poll(bContext *C, wmOperatorType *ot)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* sets up the new context and calls 'wm_operator_invoke()' with poll_only */
|
/* sets up the new context and calls 'wm_operator_invoke()' with poll_only */
|
||||||
int WM_operator_poll_context(bContext *C, wmOperatorType *ot, int context)
|
int WM_operator_poll_context(bContext *C, wmOperatorType *ot, short context)
|
||||||
{
|
{
|
||||||
return wm_operator_call_internal(C, ot, NULL, NULL, context, TRUE);
|
return wm_operator_call_internal(C, ot, NULL, NULL, context, TRUE);
|
||||||
}
|
}
|
||||||
@ -1068,7 +1068,7 @@ static int wm_operator_call_internal(bContext *C, wmOperatorType *ot, PointerRNA
|
|||||||
|
|
||||||
|
|
||||||
/* invokes operator in context */
|
/* invokes operator in context */
|
||||||
int WM_operator_name_call(bContext *C, const char *opstring, int context, PointerRNA *properties)
|
int WM_operator_name_call(bContext *C, const char *opstring, short context, PointerRNA *properties)
|
||||||
{
|
{
|
||||||
wmOperatorType *ot = WM_operatortype_find(opstring, 0);
|
wmOperatorType *ot = WM_operatortype_find(opstring, 0);
|
||||||
if (ot)
|
if (ot)
|
||||||
@ -1082,7 +1082,7 @@ int WM_operator_name_call(bContext *C, const char *opstring, int context, Pointe
|
|||||||
* - poll() must be called by python before this runs.
|
* - poll() must be called by python before this runs.
|
||||||
* - reports can be passed to this function (so python can report them as exceptions)
|
* - reports can be passed to this function (so python can report them as exceptions)
|
||||||
*/
|
*/
|
||||||
int WM_operator_call_py(bContext *C, wmOperatorType *ot, int context, PointerRNA *properties, ReportList *reports)
|
int WM_operator_call_py(bContext *C, wmOperatorType *ot, short context, PointerRNA *properties, ReportList *reports, short is_undo)
|
||||||
{
|
{
|
||||||
int retval = OPERATOR_CANCELLED;
|
int retval = OPERATOR_CANCELLED;
|
||||||
|
|
||||||
@ -1091,13 +1091,13 @@ int WM_operator_call_py(bContext *C, wmOperatorType *ot, int context, PointerRNA
|
|||||||
op = wm_operator_create(wm, ot, properties, reports);
|
op = wm_operator_create(wm, ot, properties, reports);
|
||||||
|
|
||||||
if (op->type->exec) {
|
if (op->type->exec) {
|
||||||
if (op->type->flag & OPTYPE_UNDO)
|
if (is_undo && op->type->flag & OPTYPE_UNDO)
|
||||||
wm->op_undo_depth++;
|
wm->op_undo_depth++;
|
||||||
|
|
||||||
retval = op->type->exec(C, op);
|
retval = op->type->exec(C, op);
|
||||||
OPERATOR_RETVAL_CHECK(retval);
|
OPERATOR_RETVAL_CHECK(retval);
|
||||||
|
|
||||||
if (op->type->flag & OPTYPE_UNDO && CTX_wm_manager(C) == wm)
|
if (is_undo && op->type->flag & OPTYPE_UNDO && CTX_wm_manager(C) == wm)
|
||||||
wm->op_undo_depth--;
|
wm->op_undo_depth--;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1110,11 +1110,11 @@ int WM_operator_call_py(bContext *C, wmOperatorType *ot, int context, PointerRNA
|
|||||||
* we could have some more obvious way of doing this like passing a flag.
|
* we could have some more obvious way of doing this like passing a flag.
|
||||||
*/
|
*/
|
||||||
wmWindowManager *wm = CTX_wm_manager(C);
|
wmWindowManager *wm = CTX_wm_manager(C);
|
||||||
if (wm) wm->op_undo_depth++;
|
if (!is_undo && wm) wm->op_undo_depth++;
|
||||||
|
|
||||||
retval = wm_operator_call_internal(C, ot, properties, reports, context, FALSE);
|
retval = wm_operator_call_internal(C, ot, properties, reports, context, FALSE);
|
||||||
|
|
||||||
if (wm && (wm == CTX_wm_manager(C))) wm->op_undo_depth--;
|
if (!is_undo && wm && (wm == CTX_wm_manager(C))) wm->op_undo_depth--;
|
||||||
|
|
||||||
/* keep the reports around if needed later */
|
/* keep the reports around if needed later */
|
||||||
if ((retval & OPERATOR_RUNNING_MODAL) ||
|
if ((retval & OPERATOR_RUNNING_MODAL) ||
|
||||||
|
@ -449,7 +449,7 @@ struct wmOperatorType *WM_operatortype_find(const char *idname, int quiet) {retu
|
|||||||
struct GHashIterator *WM_operatortype_iter() {return (struct GHashIterator *) NULL;}
|
struct GHashIterator *WM_operatortype_iter() {return (struct GHashIterator *) NULL;}
|
||||||
struct wmOperatorType *WM_operatortype_exists(const char *idname) {return (struct wmOperatorType *) NULL;}
|
struct wmOperatorType *WM_operatortype_exists(const char *idname) {return (struct wmOperatorType *) NULL;}
|
||||||
struct wmOperatorTypeMacro *WM_operatortype_macro_define(struct wmOperatorType *ot, const char *idname) {return (struct wmOperatorTypeMacro *) NULL;}
|
struct wmOperatorTypeMacro *WM_operatortype_macro_define(struct wmOperatorType *ot, const char *idname) {return (struct wmOperatorTypeMacro *) NULL;}
|
||||||
int WM_operator_call_py(struct bContext *C, struct wmOperatorType *ot, int context, struct PointerRNA *properties, struct ReportList *reports) {return 0;}
|
int WM_operator_call_py(struct bContext *C, struct wmOperatorType *ot, short context, short is_undo, struct PointerRNA *properties, struct ReportList *reports) {return 0;}
|
||||||
int WM_operatortype_remove(const char *idname) {return 0;}
|
int WM_operatortype_remove(const char *idname) {return 0;}
|
||||||
int WM_operator_poll(struct bContext *C, struct wmOperatorType *ot) {return 0;}
|
int WM_operator_poll(struct bContext *C, struct wmOperatorType *ot) {return 0;}
|
||||||
int WM_operator_poll_context(struct bContext *C, struct wmOperatorType *ot, int context) {return 0;}
|
int WM_operator_poll_context(struct bContext *C, struct wmOperatorType *ot, int context) {return 0;}
|
||||||
|
Loading…
Reference in New Issue
Block a user