Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2012-06-28 01:41:17 +0400
committerCampbell Barton <ideasman42@gmail.com>2012-06-28 01:41:17 +0400
commita09feb738627abfce71026352214e1512d40bcb8 (patch)
tree8557089d05d3fddd12b69d96f33cb0ac98d34c83
parentd30c7356b7a3d9db803c227617a784dee7054371 (diff)
option so operators can be executed with undo enabled (and redo).
-rw-r--r--intern/guardedalloc/intern/mallocn.c4
-rw-r--r--release/scripts/modules/bpy/ops.py38
-rw-r--r--source/blender/python/intern/bpy_operator.c6
-rw-r--r--source/blender/windowmanager/WM_api.h6
-rw-r--r--source/blender/windowmanager/intern/wm_event_system.c14
-rw-r--r--source/blenderplayer/bad_level_call_stubs/stubs.c2
6 files changed, 40 insertions, 30 deletions
diff --git a/intern/guardedalloc/intern/mallocn.c b/intern/guardedalloc/intern/mallocn.c
index f1a83583715..a234f31f87a 100644
--- a/intern/guardedalloc/intern/mallocn.c
+++ b/intern/guardedalloc/intern/mallocn.c
@@ -57,11 +57,11 @@
* lets you count the allocations so as to find the allocator of unfreed memory
* in situations where the leak is predictable */
-// #define DEBUG_MEMCOUNTER
+#define DEBUG_MEMCOUNTER
#ifdef DEBUG_MEMCOUNTER
/* 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;
/* breakpoint here */
diff --git a/release/scripts/modules/bpy/ops.py b/release/scripts/modules/bpy/ops.py
index 056fcdb519e..c4e7e6ac19e 100644
--- a/release/scripts/modules/bpy/ops.py
+++ b/release/scripts/modules/bpy/ops.py
@@ -120,20 +120,28 @@ class BPyOpsSubModOp(object):
def _parse_args(args):
C_dict = None
C_exec = 'EXEC_DEFAULT'
-
- if len(args) == 0:
- pass
- elif len(args) == 1:
- if type(args[0]) != str:
- C_dict = args[0]
+ C_undo = False
+
+ is_dict = is_exec = is_undo = False
+
+ 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:
- C_exec = args[0]
- elif len(args) == 2:
- C_exec, C_dict = args
- else:
- raise ValueError("1 or 2 args execution context is supported")
+ raise ValueError("1-3 args execution context is supported")
- return C_dict, C_exec
+ return C_dict, C_exec, C_undo
@staticmethod
def _scene_update(context):
@@ -152,7 +160,7 @@ class BPyOpsSubModOp(object):
self.func = func
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)
def idname(self):
@@ -174,8 +182,8 @@ class BPyOpsSubModOp(object):
BPyOpsSubModOp._scene_update(context)
if args:
- C_dict, C_exec = BPyOpsSubModOp._parse_args(args)
- ret = op_call(self.idname_py(), C_dict, kw, C_exec)
+ C_dict, C_exec, C_undo = BPyOpsSubModOp._parse_args(args)
+ ret = op_call(self.idname_py(), C_dict, kw, C_exec, C_undo)
else:
ret = op_call(self.idname_py(), None, kw)
diff --git a/source/blender/python/intern/bpy_operator.c b/source/blender/python/intern/bpy_operator.c
index 10562271941..7375ad454a0 100644
--- a/source/blender/python/intern/bpy_operator.c
+++ b/source/blender/python/intern/bpy_operator.c
@@ -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 */
int context = WM_OP_EXEC_DEFAULT;
+ int is_undo = FALSE;
/* 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... */
@@ -157,7 +158,8 @@ static PyObject *pyop_call(PyObject *UNUSED(self), PyObject *args)
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;
ot = WM_operatortype_find(opname, TRUE);
@@ -236,7 +238,7 @@ static PyObject *pyop_call(PyObject *UNUSED(self), PyObject *args)
PyThreadState *ts = PyEval_SaveThread();
#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
/* regain GIL */
diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h
index bfea3f3c40b..5011c785e90 100644
--- a/source/blender/windowmanager/WM_api.h
+++ b/source/blender/windowmanager/WM_api.h
@@ -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_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_notest(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_name_call (struct bContext *C, const char *opstring, int 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_name_call (struct bContext *C, const char *opstring, short context, struct PointerRNA *properties);
+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_sanitize(struct PointerRNA *ptr, const short no_context); /* make props context sensitive or not */
diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c
index e55f7404798..9795c482af2 100644
--- a/source/blender/windowmanager/intern/wm_event_system.c
+++ b/source/blender/windowmanager/intern/wm_event_system.c
@@ -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 */
-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);
}
@@ -1068,7 +1068,7 @@ static int wm_operator_call_internal(bContext *C, wmOperatorType *ot, PointerRNA
/* 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);
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.
* - 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;
@@ -1091,13 +1091,13 @@ int WM_operator_call_py(bContext *C, wmOperatorType *ot, int context, PointerRNA
op = wm_operator_create(wm, ot, properties, reports);
if (op->type->exec) {
- if (op->type->flag & OPTYPE_UNDO)
+ if (is_undo && op->type->flag & OPTYPE_UNDO)
wm->op_undo_depth++;
retval = op->type->exec(C, op);
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--;
}
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.
*/
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);
- 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 */
if ((retval & OPERATOR_RUNNING_MODAL) ||
diff --git a/source/blenderplayer/bad_level_call_stubs/stubs.c b/source/blenderplayer/bad_level_call_stubs/stubs.c
index 97fb9435180..53f3dacbffa 100644
--- a/source/blenderplayer/bad_level_call_stubs/stubs.c
+++ b/source/blenderplayer/bad_level_call_stubs/stubs.c
@@ -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 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;}
-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_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;}