Sequencer: refactor clipboard copy to no longer increase user count.
authorBrecht Van Lommel <brechtvanlommel@gmail.com>
Fri, 28 Dec 2018 12:37:51 +0000 (13:37 +0100)
committerBrecht Van Lommel <brechtvanlommel@gmail.com>
Fri, 28 Dec 2018 13:08:02 +0000 (14:08 +0100)
The clipboard is not a real user and should not be counted. Only on paste
should the user count increase.

This is part of D3621, and was implemented by Richard Antalik and me.

source/blender/blenkernel/BKE_sequencer.h
source/blender/blenkernel/intern/seqeffects.c
source/blender/blenkernel/intern/sequencer.c
source/blender/editors/space_sequencer/sequencer_edit.c

index ebe732d23366ebe630598d72773bfb50a7f99ac9..a850777f3f14d88fbd89c7ce3885871d7a89a1bf 100644 (file)
@@ -148,10 +148,10 @@ struct SeqEffectHandle {
        void (*load)(struct Sequence *seq);
 
        /* duplicate */
        void (*load)(struct Sequence *seq);
 
        /* duplicate */
-       void (*copy)(struct Sequence *dst, struct Sequence *src);
+       void (*copy)(struct Sequence *dst, struct Sequence *src, const int flag);
 
        /* destruct */
 
        /* destruct */
-       void (*free)(struct Sequence *seq);
+       void (*free)(struct Sequence *seq, const bool do_id_user);
 
        /* returns: -1: no input needed,
         * 0: no early out,
 
        /* returns: -1: no input needed,
         * 0: no early out,
@@ -229,12 +229,8 @@ int BKE_sequencer_recursive_apply(struct Sequence *seq, int (*apply_func)(struct
 
 void BKE_sequencer_free_clipboard(void);
 
 
 void BKE_sequencer_free_clipboard(void);
 
-void BKE_sequence_clipboard_pointers_free(struct Sequence *seq);
-void BKE_sequence_clipboard_pointers_store(struct Sequence *seq);
-void BKE_sequence_clipboard_pointers_restore(struct Sequence *seq, struct Main *bmain);
-
 void BKE_sequencer_base_clipboard_pointers_free(struct ListBase *seqbase);
 void BKE_sequencer_base_clipboard_pointers_free(struct ListBase *seqbase);
-void BKE_sequencer_base_clipboard_pointers_store(struct ListBase *seqbase);
+void BKE_sequencer_base_clipboard_pointers_store(struct Main *bmain, struct ListBase *seqbase);
 void BKE_sequencer_base_clipboard_pointers_restore(struct ListBase *seqbase, struct Main *bmain);
 
 void BKE_sequence_free(struct Scene *scene, struct Sequence *seq);
 void BKE_sequencer_base_clipboard_pointers_restore(struct ListBase *seqbase, struct Main *bmain);
 
 void BKE_sequence_free(struct Scene *scene, struct Sequence *seq);
index d5e32ac7e39377d182b701b586b288e0d3ccc908..193db2b623f6c88739bda5ebb7e0b2f858821c15 100644 (file)
@@ -751,7 +751,7 @@ static void load_gammacross(Sequence *UNUSED(seq))
 {
 }
 
 {
 }
 
-static void free_gammacross(Sequence *UNUSED(seq))
+static void free_gammacross(Sequence *UNUSED(seq), const bool UNUSED(do_id_user))
 {
 }
 
 {
 }
 
@@ -1805,7 +1805,7 @@ static int num_inputs_wipe(void)
        return 2;
 }
 
        return 2;
 }
 
-static void free_wipe_effect(Sequence *seq)
+static void free_wipe_effect(Sequence *seq, const bool UNUSED(do_id_user))
 {
        if (seq->effectdata)
                MEM_freeN(seq->effectdata);
 {
        if (seq->effectdata)
                MEM_freeN(seq->effectdata);
@@ -1813,7 +1813,7 @@ static void free_wipe_effect(Sequence *seq)
        seq->effectdata = NULL;
 }
 
        seq->effectdata = NULL;
 }
 
-static void copy_wipe_effect(Sequence *dst, Sequence *src)
+static void copy_wipe_effect(Sequence *dst, Sequence *src, const int UNUSED(flag))
 {
        dst->effectdata = MEM_dupallocN(src->effectdata);
 }
 {
        dst->effectdata = MEM_dupallocN(src->effectdata);
 }
@@ -1996,13 +1996,13 @@ static int num_inputs_transform(void)
        return 1;
 }
 
        return 1;
 }
 
-static void free_transform_effect(Sequence *seq)
+static void free_transform_effect(Sequence *seq, const bool UNUSED(do_id_user))
 {
        if (seq->effectdata) MEM_freeN(seq->effectdata);
        seq->effectdata = NULL;
 }
 
 {
        if (seq->effectdata) MEM_freeN(seq->effectdata);
        seq->effectdata = NULL;
 }
 
-static void copy_transform_effect(Sequence *dst, Sequence *src)
+static void copy_transform_effect(Sequence *dst, Sequence *src, const int UNUSED(flag))
 {
        dst->effectdata = MEM_dupallocN(src->effectdata);
 }
 {
        dst->effectdata = MEM_dupallocN(src->effectdata);
 }
@@ -2314,7 +2314,7 @@ static int num_inputs_glow(void)
        return 1;
 }
 
        return 1;
 }
 
-static void free_glow_effect(Sequence *seq)
+static void free_glow_effect(Sequence *seq, const bool UNUSED(do_id_user))
 {
        if (seq->effectdata)
                MEM_freeN(seq->effectdata);
 {
        if (seq->effectdata)
                MEM_freeN(seq->effectdata);
@@ -2322,7 +2322,7 @@ static void free_glow_effect(Sequence *seq)
        seq->effectdata = NULL;
 }
 
        seq->effectdata = NULL;
 }
 
-static void copy_glow_effect(Sequence *dst, Sequence *src)
+static void copy_glow_effect(Sequence *dst, Sequence *src, const int UNUSED(flag))
 {
        dst->effectdata = MEM_dupallocN(src->effectdata);
 }
 {
        dst->effectdata = MEM_dupallocN(src->effectdata);
 }
@@ -2408,7 +2408,7 @@ static int num_inputs_color(void)
        return 0;
 }
 
        return 0;
 }
 
-static void free_solid_color(Sequence *seq)
+static void free_solid_color(Sequence *seq, const bool UNUSED(do_id_user))
 {
        if (seq->effectdata)
                MEM_freeN(seq->effectdata);
 {
        if (seq->effectdata)
                MEM_freeN(seq->effectdata);
@@ -2416,7 +2416,7 @@ static void free_solid_color(Sequence *seq)
        seq->effectdata = NULL;
 }
 
        seq->effectdata = NULL;
 }
 
-static void copy_solid_color(Sequence *dst, Sequence *src)
+static void copy_solid_color(Sequence *dst, Sequence *src, const int UNUSED(flag))
 {
        dst->effectdata = MEM_dupallocN(src->effectdata);
 }
 {
        dst->effectdata = MEM_dupallocN(src->effectdata);
 }
@@ -2664,7 +2664,7 @@ static int num_inputs_speed(void)
        return 1;
 }
 
        return 1;
 }
 
-static void free_speed_effect(Sequence *seq)
+static void free_speed_effect(Sequence *seq, const bool UNUSED(do_id_user))
 {
        SpeedControlVars *v = (SpeedControlVars *)seq->effectdata;
        if (v->frameMap)
 {
        SpeedControlVars *v = (SpeedControlVars *)seq->effectdata;
        if (v->frameMap)
@@ -2674,7 +2674,7 @@ static void free_speed_effect(Sequence *seq)
        seq->effectdata = NULL;
 }
 
        seq->effectdata = NULL;
 }
 
-static void copy_speed_effect(Sequence *dst, Sequence *src)
+static void copy_speed_effect(Sequence *dst, Sequence *src, const int UNUSED(flag))
 {
        SpeedControlVars *v;
        dst->effectdata = MEM_dupallocN(src->effectdata);
 {
        SpeedControlVars *v;
        dst->effectdata = MEM_dupallocN(src->effectdata);
@@ -2889,7 +2889,7 @@ static int num_inputs_gaussian_blur(void)
        return 1;
 }
 
        return 1;
 }
 
-static void free_gaussian_blur_effect(Sequence *seq)
+static void free_gaussian_blur_effect(Sequence *seq, const bool UNUSED(do_id_user))
 {
        if (seq->effectdata)
                MEM_freeN(seq->effectdata);
 {
        if (seq->effectdata)
                MEM_freeN(seq->effectdata);
@@ -2897,7 +2897,7 @@ static void free_gaussian_blur_effect(Sequence *seq)
        seq->effectdata = NULL;
 }
 
        seq->effectdata = NULL;
 }
 
-static void copy_gaussian_blur_effect(Sequence *dst, Sequence *src)
+static void copy_gaussian_blur_effect(Sequence *dst, Sequence *src, const int UNUSED(flag))
 {
        dst->effectdata = MEM_dupallocN(src->effectdata);
 }
 {
        dst->effectdata = MEM_dupallocN(src->effectdata);
 }
@@ -3503,7 +3503,7 @@ static void load_noop(Sequence *UNUSED(seq))
 
 }
 
 
 }
 
-static void free_noop(Sequence *UNUSED(seq))
+static void free_noop(Sequence *UNUSED(seq), const bool UNUSED(do_id_user))
 {
 
 }
 {
 
 }
@@ -3513,12 +3513,12 @@ static int num_inputs_default(void)
        return 2;
 }
 
        return 2;
 }
 
-static void copy_effect_default(Sequence *dst, Sequence *src)
+static void copy_effect_default(Sequence *dst, Sequence *src, const int UNUSED(flag))
 {
        dst->effectdata = MEM_dupallocN(src->effectdata);
 }
 
 {
        dst->effectdata = MEM_dupallocN(src->effectdata);
 }
 
-static void free_effect_default(Sequence *seq)
+static void free_effect_default(Sequence *seq, const bool UNUSED(do_id_user))
 {
        if (seq->effectdata)
                MEM_freeN(seq->effectdata);
 {
        if (seq->effectdata)
                MEM_freeN(seq->effectdata);
index c02a47db3219cebf8c31964b6f0d21dcb099eebb..40870fb6a0e3602c876490e69bcd6899e5440248 100644 (file)
@@ -214,8 +214,7 @@ static void BKE_sequence_free_ex(Scene *scene, Sequence *seq, const bool do_cach
 
        if (seq->type & SEQ_TYPE_EFFECT) {
                struct SeqEffectHandle sh = BKE_sequence_get_effect(seq);
 
        if (seq->type & SEQ_TYPE_EFFECT) {
                struct SeqEffectHandle sh = BKE_sequence_get_effect(seq);
-
-               sh.free(seq);
+               sh.free(seq, do_id_user);
        }
 
        if (seq->sound && do_id_user) {
        }
 
        if (seq->sound && do_id_user) {
@@ -288,16 +287,16 @@ void BKE_sequence_free_anim(Sequence *seq)
 
 /* cache must be freed before calling this function
  * since it leaves the seqbase in an invalid state */
 
 /* cache must be freed before calling this function
  * since it leaves the seqbase in an invalid state */
-static void seq_free_sequence_recurse(Scene *scene, Sequence *seq)
+static void seq_free_sequence_recurse(Scene *scene, Sequence *seq, const bool do_id_user)
 {
        Sequence *iseq, *iseq_next;
 
        for (iseq = seq->seqbase.first; iseq; iseq = iseq_next) {
                iseq_next = iseq->next;
 {
        Sequence *iseq, *iseq_next;
 
        for (iseq = seq->seqbase.first; iseq; iseq = iseq_next) {
                iseq_next = iseq->next;
-               seq_free_sequence_recurse(scene, iseq);
+               seq_free_sequence_recurse(scene, iseq, do_id_user);
        }
 
        }
 
-       BKE_sequence_free_ex(scene, seq, false, true);
+       BKE_sequence_free_ex(scene, seq, false, do_id_user);
 }
 
 
 }
 
 
@@ -317,7 +316,7 @@ void BKE_sequencer_free_clipboard(void)
 
        for (seq = seqbase_clipboard.first; seq; seq = nseq) {
                nseq = seq->next;
 
        for (seq = seqbase_clipboard.first; seq; seq = nseq) {
                nseq = seq->next;
-               seq_free_sequence_recurse(NULL, seq);
+               seq_free_sequence_recurse(NULL, seq, false);
        }
        BLI_listbase_clear(&seqbase_clipboard);
 }
        }
        BLI_listbase_clear(&seqbase_clipboard);
 }
@@ -330,7 +329,7 @@ void BKE_sequencer_free_clipboard(void)
  * since those datablocks are fully out of Main lists).
  */
 #define ID_PT (*id_pt)
  * since those datablocks are fully out of Main lists).
  */
 #define ID_PT (*id_pt)
-static void seqclipboard_ptr_free(ID **id_pt)
+static void seqclipboard_ptr_free(Main *UNUSED(bmain), ID **id_pt)
 {
        if (ID_PT) {
                BLI_assert(ID_PT->newid != NULL);
 {
        if (ID_PT) {
                BLI_assert(ID_PT->newid != NULL);
@@ -338,7 +337,7 @@ static void seqclipboard_ptr_free(ID **id_pt)
                ID_PT = NULL;
        }
 }
                ID_PT = NULL;
        }
 }
-static void seqclipboard_ptr_store(ID **id_pt)
+static void seqclipboard_ptr_store(Main *UNUSED(bmain), ID **id_pt)
 {
        if (ID_PT) {
                ID *id_prev = ID_PT;
 {
        if (ID_PT) {
                ID *id_prev = ID_PT;
@@ -388,58 +387,43 @@ static void seqclipboard_ptr_restore(Main *bmain, ID **id_pt)
                        }
                }
 
                        }
                }
 
+               /* Replace with pointer to actual datablock. */
+               seqclipboard_ptr_free(bmain, id_pt);
                ID_PT = id_restore;
        }
 }
 #undef ID_PT
 
                ID_PT = id_restore;
        }
 }
 #undef ID_PT
 
-void BKE_sequence_clipboard_pointers_free(Sequence *seq)
-{
-       seqclipboard_ptr_free((ID **)&seq->scene);
-       seqclipboard_ptr_free((ID **)&seq->scene_camera);
-       seqclipboard_ptr_free((ID **)&seq->clip);
-       seqclipboard_ptr_free((ID **)&seq->mask);
-       seqclipboard_ptr_free((ID **)&seq->sound);
-}
-void BKE_sequence_clipboard_pointers_store(Sequence *seq)
+static void sequence_clipboard_pointers(Main *bmain, Sequence *seq, void (*callback)(Main *, ID **))
 {
 {
-       seqclipboard_ptr_store((ID **)&seq->scene);
-       seqclipboard_ptr_store((ID **)&seq->scene_camera);
-       seqclipboard_ptr_store((ID **)&seq->clip);
-       seqclipboard_ptr_store((ID **)&seq->mask);
-       seqclipboard_ptr_store((ID **)&seq->sound);
+       callback(bmain, (ID **)&seq->scene);
+       callback(bmain, (ID **)&seq->scene_camera);
+       callback(bmain, (ID **)&seq->clip);
+       callback(bmain, (ID **)&seq->mask);
+       callback(bmain, (ID **)&seq->sound);
 }
 }
-void BKE_sequence_clipboard_pointers_restore(Sequence *seq, Main *bmain)
-{
-       seqclipboard_ptr_restore(bmain, (ID **)&seq->scene);
-       seqclipboard_ptr_restore(bmain, (ID **)&seq->scene_camera);
-       seqclipboard_ptr_restore(bmain, (ID **)&seq->clip);
-       seqclipboard_ptr_restore(bmain, (ID **)&seq->mask);
-       seqclipboard_ptr_restore(bmain, (ID **)&seq->sound);
-}
-
 /* recursive versions of functions above */
 void BKE_sequencer_base_clipboard_pointers_free(ListBase *seqbase)
 {
        Sequence *seq;
        for (seq = seqbase->first; seq; seq = seq->next) {
 /* recursive versions of functions above */
 void BKE_sequencer_base_clipboard_pointers_free(ListBase *seqbase)
 {
        Sequence *seq;
        for (seq = seqbase->first; seq; seq = seq->next) {
-               BKE_sequence_clipboard_pointers_free(seq);
+               sequence_clipboard_pointers(NULL, seq, seqclipboard_ptr_free);
                BKE_sequencer_base_clipboard_pointers_free(&seq->seqbase);
        }
 }
                BKE_sequencer_base_clipboard_pointers_free(&seq->seqbase);
        }
 }
-void BKE_sequencer_base_clipboard_pointers_store(ListBase *seqbase)
+void BKE_sequencer_base_clipboard_pointers_store(Main *bmain, ListBase *seqbase)
 {
        Sequence *seq;
        for (seq = seqbase->first; seq; seq = seq->next) {
 {
        Sequence *seq;
        for (seq = seqbase->first; seq; seq = seq->next) {
-               BKE_sequence_clipboard_pointers_store(seq);
-               BKE_sequencer_base_clipboard_pointers_store(&seq->seqbase);
+               sequence_clipboard_pointers(bmain, seq, seqclipboard_ptr_store);
+               BKE_sequencer_base_clipboard_pointers_store(bmain, &seq->seqbase);
        }
 }
 void BKE_sequencer_base_clipboard_pointers_restore(ListBase *seqbase, Main *bmain)
 {
        Sequence *seq;
        for (seq = seqbase->first; seq; seq = seq->next) {
        }
 }
 void BKE_sequencer_base_clipboard_pointers_restore(ListBase *seqbase, Main *bmain)
 {
        Sequence *seq;
        for (seq = seqbase->first; seq; seq = seq->next) {
-               BKE_sequence_clipboard_pointers_restore(seq, bmain);
+               sequence_clipboard_pointers(bmain, seq, seqclipboard_ptr_restore);
                BKE_sequencer_base_clipboard_pointers_restore(&seq->seqbase, bmain);
        }
 }
                BKE_sequencer_base_clipboard_pointers_restore(&seq->seqbase, bmain);
        }
 }
@@ -2084,7 +2068,7 @@ void BKE_sequencer_proxy_rebuild_finish(SeqIndexBuildContext *context, bool stop
                IMB_anim_index_rebuild_finish(context->index_context, stop);
        }
 
                IMB_anim_index_rebuild_finish(context->index_context, stop);
        }
 
-       seq_free_sequence_recurse(NULL, context->seq);
+       seq_free_sequence_recurse(NULL, context->seq, true);
 
        MEM_freeN(context);
 }
 
        MEM_freeN(context);
 }
@@ -5504,7 +5488,7 @@ static Sequence *seq_dupli(const Scene *scene_src, Scene *scene_dst, Sequence *s
                struct SeqEffectHandle sh;
                sh = BKE_sequence_get_effect(seq);
                if (sh.copy)
                struct SeqEffectHandle sh;
                sh = BKE_sequence_get_effect(seq);
                if (sh.copy)
-                       sh.copy(seq, seqn);
+                       sh.copy(seq, seqn, flag);
 
                seqn->strip->stripdata = NULL;
 
 
                seqn->strip->stripdata = NULL;
 
index e55b8d17cd4a260933047f76d8b4647fc65a0792..b6f8552bd8101cdcc22eeb42cb566fb56be5e0fb 100644 (file)
@@ -51,7 +51,7 @@
 #include "BKE_report.h"
 #include "BKE_sequencer.h"
 #include "BKE_sound.h"
 #include "BKE_report.h"
 #include "BKE_sequencer.h"
 #include "BKE_sound.h"
-
+#include "BKE_library.h"
 
 #include "WM_api.h"
 #include "WM_types.h"
 
 #include "WM_api.h"
 #include "WM_types.h"
@@ -3207,6 +3207,7 @@ static void seq_copy_del_sound(Scene *scene, Sequence *seq)
 
 static int sequencer_copy_exec(bContext *C, wmOperator *op)
 {
 
 static int sequencer_copy_exec(bContext *C, wmOperator *op)
 {
+       Main *bmain = CTX_data_main(C);
        Scene *scene = CTX_data_scene(C);
        Editing *ed = BKE_sequencer_editing_get(scene, false);
 
        Scene *scene = CTX_data_scene(C);
        Editing *ed = BKE_sequencer_editing_get(scene, false);
 
@@ -3219,7 +3220,7 @@ static int sequencer_copy_exec(bContext *C, wmOperator *op)
                return OPERATOR_CANCELLED;
        }
 
                return OPERATOR_CANCELLED;
        }
 
-       BKE_sequence_base_dupli_recursive(scene, scene, &nseqbase, ed->seqbasep, SEQ_DUPE_UNIQUE_NAME, 0);
+       BKE_sequence_base_dupli_recursive(scene, scene, &nseqbase, ed->seqbasep, SEQ_DUPE_UNIQUE_NAME, LIB_ID_CREATE_NO_USER_REFCOUNT);
 
        /* To make sure the copied strips have unique names between each other add
         * them temporarily to the end of the original seqbase. (bug 25932)
 
        /* To make sure the copied strips have unique names between each other add
         * them temporarily to the end of the original seqbase. (bug 25932)
@@ -3244,16 +3245,14 @@ static int sequencer_copy_exec(bContext *C, wmOperator *op)
        seqbase_clipboard_frame = scene->r.cfra;
 
        /* Need to remove anything that references the current scene */
        seqbase_clipboard_frame = scene->r.cfra;
 
        /* Need to remove anything that references the current scene */
-       {
-               Sequence *seq;
-               for (seq = seqbase_clipboard.first; seq; seq = seq->next) {
-                       seq_copy_del_sound(scene, seq);
-               }
-
-               /* duplicate pointers */
-               BKE_sequencer_base_clipboard_pointers_store(&seqbase_clipboard);
+       for (Sequence *seq = seqbase_clipboard.first; seq; seq = seq->next) {
+               seq_copy_del_sound(scene, seq);
        }
 
        }
 
+       /* Replace datablock pointers with copies, to keep things working in case
+        * datablocks get deleted or another .blend file is openeded. */
+       BKE_sequencer_base_clipboard_pointers_store(bmain, &seqbase_clipboard);
+
        return OPERATOR_FINISHED;
 }
 
        return OPERATOR_FINISHED;
 }
 
@@ -3285,7 +3284,12 @@ static int sequencer_paste_exec(bContext *C, wmOperator *UNUSED(op))
        ED_sequencer_deselect_all(scene);
        ofs = scene->r.cfra - seqbase_clipboard_frame;
 
        ED_sequencer_deselect_all(scene);
        ofs = scene->r.cfra - seqbase_clipboard_frame;
 
+       /* Copy strips, temporarily restoring pointers to actual datablocks. This
+        * must happen on the clipboard itself, so that copying does user counting
+        * on the actual datablocks. */
+       BKE_sequencer_base_clipboard_pointers_restore(&seqbase_clipboard, bmain);
        BKE_sequence_base_dupli_recursive(scene, scene, &nseqbase, &seqbase_clipboard, SEQ_DUPE_UNIQUE_NAME, 0);
        BKE_sequence_base_dupli_recursive(scene, scene, &nseqbase, &seqbase_clipboard, SEQ_DUPE_UNIQUE_NAME, 0);
+       BKE_sequencer_base_clipboard_pointers_store(bmain, &seqbase_clipboard);
 
        /* transform pasted strips before adding */
        if (ofs) {
 
        /* transform pasted strips before adding */
        if (ofs) {
@@ -3294,8 +3298,6 @@ static int sequencer_paste_exec(bContext *C, wmOperator *UNUSED(op))
                }
        }
 
                }
        }
 
-       BKE_sequencer_base_clipboard_pointers_restore(&nseqbase, bmain);
-
        for (iseq = nseqbase.first; iseq; iseq = iseq->next) {
                BKE_sequence_sound_init(scene, iseq);
        }
        for (iseq = nseqbase.first; iseq; iseq = iseq->next) {
                BKE_sequence_sound_init(scene, iseq);
        }
@@ -3689,7 +3691,7 @@ static int sequencer_change_effect_type_exec(bContext *C, wmOperator *op)
        }
        else {
                sh = BKE_sequence_get_effect(seq);
        }
        else {
                sh = BKE_sequence_get_effect(seq);
-               sh.free(seq);
+               sh.free(seq, true);
 
                seq->type = new_type;
 
 
                seq->type = new_type;