Sequencer: Avoid storing un-tracked pointers in blend files
Currently, sequencer structs contain several pointers to data within other structs. These pointers need to be remapped as the structs are reallocated when reading from blend files. That has worked so far because the pointers are exactly the values from the Blender session that saved the file. With the implementation of #127706, the pointers in the file aren't "real" anymore, and we can't offset them to get the struct that contained the data. I'm working on the pointer stability solution now to address a memfile undo performance regression in 5.0 due to the `AttributeStorage` read/write design. This commit replaces these 4 mid-struct pointers to point to the containing strips instead, and uses some trivial logic to access the fallback root sequence channels and strips. This makes the pointer remapping on file load possible again. This change is backward compatible but not forward compatible. Second try after #144626 Pull Request: https://projects.blender.org/blender/blender/pulls/144878
This commit is contained in:
@@ -329,7 +329,6 @@ static void scene_copy_data(Main *bmain,
|
||||
/* Copy sequencer, this is local data! */
|
||||
if (scene_src->ed) {
|
||||
scene_dst->ed = MEM_callocN<Editing>(__func__);
|
||||
scene_dst->ed->seqbasep = &scene_dst->ed->seqbase;
|
||||
scene_dst->ed->cache_flag = scene_src->ed->cache_flag;
|
||||
scene_dst->ed->show_missing_media_flag = scene_src->ed->show_missing_media_flag;
|
||||
scene_dst->ed->proxy_storage = scene_src->ed->proxy_storage;
|
||||
@@ -342,7 +341,6 @@ static void scene_copy_data(Main *bmain,
|
||||
blender::seq::StripDuplicate::All,
|
||||
flag_subdata);
|
||||
BLI_duplicatelist(&scene_dst->ed->channels, &scene_src->ed->channels);
|
||||
scene_dst->ed->displayed_channels = &scene_dst->ed->channels;
|
||||
}
|
||||
|
||||
if ((flag & LIB_ID_COPY_NO_PREVIEW) == 0) {
|
||||
@@ -1353,14 +1351,13 @@ static void scene_blend_read_data(BlendDataReader *reader, ID *id)
|
||||
}
|
||||
|
||||
if (sce->ed) {
|
||||
ListBase *old_seqbasep = &sce->ed->seqbase;
|
||||
ListBase *old_displayed_channels = &sce->ed->channels;
|
||||
|
||||
BLO_read_struct(reader, Editing, &sce->ed);
|
||||
Editing *ed = sce->ed;
|
||||
|
||||
ed->act_strip = static_cast<Strip *>(
|
||||
BLO_read_get_new_data_address_no_us(reader, ed->act_strip, sizeof(Strip)));
|
||||
ed->current_meta_strip = static_cast<Strip *>(
|
||||
BLO_read_get_new_data_address_no_us(reader, ed->current_meta_strip, sizeof(Strip)));
|
||||
ed->prefetch_job = nullptr;
|
||||
ed->runtime.strip_lookup = nullptr;
|
||||
ed->runtime.media_presence = nullptr;
|
||||
@@ -1377,88 +1374,14 @@ static void scene_blend_read_data(BlendDataReader *reader, ID *id)
|
||||
blender::seq::blend_read(reader, &ed->seqbase);
|
||||
BLO_read_struct_list(reader, SeqTimelineChannel, &ed->channels);
|
||||
|
||||
/* link metastack, slight abuse of structs here,
|
||||
* have to restore pointer to internal part in struct */
|
||||
{
|
||||
const int seqbase_offset_file = BLO_read_struct_member_offset(
|
||||
reader, "Strip", "ListBase", "seqbase");
|
||||
const int channels_offset_file = BLO_read_struct_member_offset(
|
||||
reader, "Strip", "ListBase", "channels");
|
||||
const size_t seqbase_offset_mem = offsetof(Strip, seqbase);
|
||||
const size_t channels_offset_mem = offsetof(Strip, channels);
|
||||
/* stack */
|
||||
BLO_read_struct_list(reader, MetaStack, &(ed->metastack));
|
||||
|
||||
/* seqbase root pointer */
|
||||
if (ed->seqbasep == old_seqbasep || seqbase_offset_file < 0) {
|
||||
ed->seqbasep = &ed->seqbase;
|
||||
}
|
||||
else {
|
||||
void *seqbase_poin = POINTER_OFFSET(ed->seqbasep, -seqbase_offset_file);
|
||||
LISTBASE_FOREACH (MetaStack *, ms, &ed->metastack) {
|
||||
BLO_read_struct(reader, Strip, &ms->parent_strip);
|
||||
|
||||
seqbase_poin = BLO_read_get_new_data_address_no_us(reader, seqbase_poin, sizeof(Strip));
|
||||
|
||||
if (seqbase_poin) {
|
||||
ed->seqbasep = (ListBase *)POINTER_OFFSET(seqbase_poin, seqbase_offset_mem);
|
||||
}
|
||||
else {
|
||||
ed->seqbasep = &ed->seqbase;
|
||||
}
|
||||
}
|
||||
|
||||
/* Active channels root pointer. */
|
||||
if (ELEM(ed->displayed_channels, old_displayed_channels, nullptr) ||
|
||||
channels_offset_file < 0)
|
||||
{
|
||||
ed->displayed_channels = &ed->channels;
|
||||
}
|
||||
else {
|
||||
void *channels_poin = POINTER_OFFSET(ed->displayed_channels, -channels_offset_file);
|
||||
channels_poin = BLO_read_get_new_data_address_no_us(
|
||||
reader, channels_poin, sizeof(SeqTimelineChannel));
|
||||
|
||||
if (channels_poin) {
|
||||
ed->displayed_channels = (ListBase *)POINTER_OFFSET(channels_poin, channels_offset_mem);
|
||||
}
|
||||
else {
|
||||
ed->displayed_channels = &ed->channels;
|
||||
}
|
||||
}
|
||||
|
||||
/* stack */
|
||||
BLO_read_struct_list(reader, MetaStack, &(ed->metastack));
|
||||
|
||||
LISTBASE_FOREACH (MetaStack *, ms, &ed->metastack) {
|
||||
BLO_read_struct(reader, Strip, &ms->parent_strip);
|
||||
|
||||
if (ms->oldbasep == old_seqbasep || seqbase_offset_file < 0) {
|
||||
ms->oldbasep = &ed->seqbase;
|
||||
}
|
||||
else {
|
||||
void *seqbase_poin = POINTER_OFFSET(ms->oldbasep, -seqbase_offset_file);
|
||||
seqbase_poin = BLO_read_get_new_data_address_no_us(reader, seqbase_poin, sizeof(Strip));
|
||||
if (seqbase_poin) {
|
||||
ms->oldbasep = (ListBase *)POINTER_OFFSET(seqbase_poin, seqbase_offset_mem);
|
||||
}
|
||||
else {
|
||||
ms->oldbasep = &ed->seqbase;
|
||||
}
|
||||
}
|
||||
|
||||
if (ELEM(ms->old_channels, old_displayed_channels, nullptr) || channels_offset_file < 0) {
|
||||
ms->old_channels = &ed->channels;
|
||||
}
|
||||
else {
|
||||
void *channels_poin = POINTER_OFFSET(ms->old_channels, -channels_offset_file);
|
||||
channels_poin = BLO_read_get_new_data_address_no_us(
|
||||
reader, channels_poin, sizeof(SeqTimelineChannel));
|
||||
|
||||
if (channels_poin) {
|
||||
ms->old_channels = (ListBase *)POINTER_OFFSET(channels_poin, channels_offset_mem);
|
||||
}
|
||||
else {
|
||||
ms->old_channels = &ed->channels;
|
||||
}
|
||||
}
|
||||
}
|
||||
ms->old_strip = static_cast<Strip *>(
|
||||
BLO_read_get_new_data_address_no_us(reader, ms->old_strip, sizeof(Strip)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -377,11 +377,6 @@ void BLO_read_glob_list(BlendDataReader *reader, ListBase *list);
|
||||
BlendFileReadReport *BLO_read_data_reports(BlendDataReader *reader);
|
||||
struct Library *BLO_read_data_current_library(BlendDataReader *reader);
|
||||
|
||||
int BLO_read_struct_member_offset(const BlendDataReader *reader,
|
||||
const char *stype,
|
||||
const char *vartype,
|
||||
const char *name);
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
||||
@@ -5224,14 +5224,6 @@ int BLO_read_fileversion_get(BlendDataReader *reader)
|
||||
return reader->fd->fileversion;
|
||||
}
|
||||
|
||||
int BLO_read_struct_member_offset(const BlendDataReader *reader,
|
||||
const char *stype,
|
||||
const char *vartype,
|
||||
const char *name)
|
||||
{
|
||||
return DNA_struct_member_offset_by_name_with_alias(reader->fd->filesdna, stype, vartype, name);
|
||||
}
|
||||
|
||||
void BLO_read_struct_list_with_size(BlendDataReader *reader,
|
||||
const size_t expected_elem_size,
|
||||
ListBase *list)
|
||||
|
||||
@@ -378,7 +378,8 @@ static void seq_update_meta_disp_range(Scene *scene)
|
||||
blender::seq::time_right_handle_frame_set(scene, ms->parent_strip, ms->disp_range[1]);
|
||||
|
||||
/* Recalculate effects using meta strip. */
|
||||
LISTBASE_FOREACH (Strip *, strip, ms->oldbasep) {
|
||||
ListBase *old_seqbasep = ms->old_strip ? &ms->old_strip->seqbase : &ed->seqbase;
|
||||
LISTBASE_FOREACH (Strip *, strip, old_seqbasep) {
|
||||
if (strip->input2) {
|
||||
strip->start = strip->startdisp = max_ii(strip->input1->startdisp,
|
||||
strip->input2->startdisp);
|
||||
@@ -386,9 +387,8 @@ static void seq_update_meta_disp_range(Scene *scene)
|
||||
}
|
||||
}
|
||||
|
||||
/* Ensure that active seqbase points to active meta strip seqbase. */
|
||||
MetaStack *active_ms = blender::seq::meta_stack_active_get(ed);
|
||||
blender::seq::active_seqbase_set(ed, &active_ms->parent_strip->seqbase);
|
||||
active_ms->old_strip = ms->parent_strip;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3424,16 +3424,6 @@ void blo_do_versions_300(FileData *fd, Library * /*lib*/, Main *bmain)
|
||||
}
|
||||
blender::seq::channels_ensure(&ed->channels);
|
||||
blender::seq::for_each_callback(&scene->ed->seqbase, strip_meta_channels_ensure, nullptr);
|
||||
|
||||
ed->displayed_channels = &ed->channels;
|
||||
|
||||
ListBase *previous_channels = &ed->channels;
|
||||
LISTBASE_FOREACH (MetaStack *, ms, &ed->metastack) {
|
||||
ms->old_channels = previous_channels;
|
||||
previous_channels = &ms->parent_strip->channels;
|
||||
/* If `MetaStack` exists, active channels must point to last link. */
|
||||
ed->displayed_channels = &ms->parent_strip->channels;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2126,6 +2126,20 @@ static void remove_in_and_out_node_interface(bNodeTree &node_tree)
|
||||
remove_in_and_out_node_panel_recursive(node_tree.tree_interface.root_panel);
|
||||
}
|
||||
|
||||
static void sequencer_remove_listbase_pointers(Scene &scene)
|
||||
{
|
||||
Editing *ed = scene.ed;
|
||||
if (!ed) {
|
||||
return;
|
||||
}
|
||||
const MetaStack *last_meta_stack = blender::seq::meta_stack_active_get(ed);
|
||||
if (!last_meta_stack) {
|
||||
return;
|
||||
}
|
||||
ed->current_meta_strip = last_meta_stack->parent_strip;
|
||||
blender::seq::meta_stack_set(&scene, last_meta_stack->parent_strip);
|
||||
}
|
||||
|
||||
void blo_do_versions_500(FileData * /*fd*/, Library * /*lib*/, Main *bmain)
|
||||
{
|
||||
using namespace blender;
|
||||
@@ -2882,6 +2896,12 @@ void blo_do_versions_500(FileData * /*fd*/, Library * /*lib*/, Main *bmain)
|
||||
FOREACH_NODETREE_END;
|
||||
}
|
||||
|
||||
if (!MAIN_VERSION_FILE_ATLEAST(bmain, 500, 68)) {
|
||||
LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
|
||||
sequencer_remove_listbase_pointers(*scene);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Always bump subversion in BKE_blender_version.h when adding versioning
|
||||
* code here, and wrap it inside a MAIN_VERSION_FILE_ATLEAST check.
|
||||
|
||||
@@ -167,7 +167,6 @@ static bool sequencer_write_copy_paste_file(Main *bmain_src,
|
||||
|
||||
/* Create an empty sequence editor data to store all copied strips. */
|
||||
scene_dst->ed = MEM_callocN<Editing>(__func__);
|
||||
scene_dst->ed->seqbasep = &scene_dst->ed->seqbase;
|
||||
seq::seqbase_duplicate_recursive(bmain_src,
|
||||
scene_src,
|
||||
scene_dst,
|
||||
@@ -177,7 +176,6 @@ static bool sequencer_write_copy_paste_file(Main *bmain_src,
|
||||
0);
|
||||
|
||||
BLI_duplicatelist(&scene_dst->ed->channels, &scene_src->ed->channels);
|
||||
scene_dst->ed->displayed_channels = &scene_dst->ed->channels;
|
||||
|
||||
/* Save current frame and active strip. */
|
||||
scene_dst->r.cfra = scene_src->r.cfra;
|
||||
@@ -499,7 +497,7 @@ wmOperatorStatus sequencer_clipboard_paste_exec(bContext *C, wmOperator *op)
|
||||
BKE_id_delete(bmain_dst, scene_src);
|
||||
|
||||
Strip *iseq_first = static_cast<Strip *>(nseqbase.first);
|
||||
BLI_movelisttolist(ed_dst->seqbasep, &nseqbase);
|
||||
BLI_movelisttolist(ed_dst->current_strips(), &nseqbase);
|
||||
/* Restore "first" pointer as BLI_movelisttolist sets it to nullptr */
|
||||
nseqbase.first = iseq_first;
|
||||
|
||||
@@ -517,8 +515,8 @@ wmOperatorStatus sequencer_clipboard_paste_exec(bContext *C, wmOperator *op)
|
||||
* strip. */
|
||||
seq::transform_translate_strip(scene_dst, istrip, ofs);
|
||||
/* Ensure, that pasted strips don't overlap. */
|
||||
if (seq::transform_test_overlap(scene_dst, ed_dst->seqbasep, istrip)) {
|
||||
seq::transform_seqbase_shuffle(ed_dst->seqbasep, istrip, scene_dst);
|
||||
if (seq::transform_test_overlap(scene_dst, ed_dst->current_strips(), istrip)) {
|
||||
seq::transform_seqbase_shuffle(ed_dst->current_strips(), istrip, scene_dst);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1360,7 +1360,7 @@ static void preview_draw_all_image_overlays(const bContext *C,
|
||||
{
|
||||
ListBase *channels = seq::channels_displayed_get(&editing);
|
||||
VectorSet strips = seq::query_rendered_strips(
|
||||
scene, channels, editing.seqbasep, timeline_frame, 0);
|
||||
scene, channels, editing.current_strips(), timeline_frame, 0);
|
||||
Strip *active_seq = seq::select_active_get(scene);
|
||||
for (Strip *strip : strips) {
|
||||
/* TODO(sergey): Avoid having per-strip strip-independent checks. */
|
||||
|
||||
@@ -305,8 +305,11 @@ typedef struct Strip {
|
||||
|
||||
typedef struct MetaStack {
|
||||
struct MetaStack *next, *prev;
|
||||
ListBase *oldbasep;
|
||||
ListBase *old_channels;
|
||||
/**
|
||||
* The meta-strip that contains `parent_strip`. May be null (that means it is the top-most
|
||||
* strips).
|
||||
*/
|
||||
Strip *old_strip;
|
||||
Strip *parent_strip;
|
||||
/* The startdisp/enddisp when entering the metastrip. */
|
||||
int disp_range[2];
|
||||
@@ -336,16 +339,11 @@ typedef struct EditingRuntime {
|
||||
|
||||
typedef struct Editing {
|
||||
/**
|
||||
* Pointer to the current list of strips being edited (can be within a meta-strip).
|
||||
* \note Use #current_strips() to access, rather than using this variable directly.
|
||||
* The current meta-strip being edited and/or viewed, may be null, in which case the top-most
|
||||
* strips are used.
|
||||
*/
|
||||
ListBase *seqbasep;
|
||||
/**
|
||||
* Pointer to the current list of channels being displayed (can be within a meta-strip).
|
||||
* \note Use #current_channels() to access, rather than using this variable directly.
|
||||
*/
|
||||
ListBase *displayed_channels;
|
||||
void *_pad0;
|
||||
Strip *current_meta_strip;
|
||||
|
||||
/** Pointer to the top-most strips. */
|
||||
ListBase seqbase;
|
||||
ListBase metastack;
|
||||
|
||||
@@ -15,8 +15,8 @@ struct Strip;
|
||||
|
||||
namespace blender::seq {
|
||||
|
||||
/** The active displayed channels list, either from the root sequence or from a meta-strip. */
|
||||
ListBase *channels_displayed_get(const Editing *ed);
|
||||
void channels_displayed_set(Editing *ed, ListBase *channels);
|
||||
void channels_ensure(ListBase *channels);
|
||||
void channels_duplicate(ListBase *channels_dst, ListBase *channels_src);
|
||||
void channels_free(ListBase *channels);
|
||||
|
||||
@@ -69,13 +69,6 @@ void editing_free(Scene *scene, bool do_id_user);
|
||||
* \return pointer to active seqbase. returns NULL if ed is NULL
|
||||
*/
|
||||
ListBase *active_seqbase_get(const Editing *ed);
|
||||
/**
|
||||
* Set seqbase that is being viewed currently. This can be main seqbase or meta strip seqbase
|
||||
*
|
||||
* \param ed: sequence editor data
|
||||
* \param seqbase: ListBase with strips
|
||||
*/
|
||||
void active_seqbase_set(Editing *ed, ListBase *seqbase);
|
||||
Strip *strip_alloc(ListBase *lb, int timeline_frame, int channel, int type);
|
||||
void strip_free(Scene *scene, Strip *strip);
|
||||
/**
|
||||
|
||||
@@ -30,11 +30,6 @@ ListBase *channels_displayed_get(const Editing *ed)
|
||||
return ed ? ed->current_channels() : nullptr;
|
||||
}
|
||||
|
||||
void channels_displayed_set(Editing *ed, ListBase *channels)
|
||||
{
|
||||
ed->displayed_channels = channels;
|
||||
}
|
||||
|
||||
void channels_ensure(ListBase *channels)
|
||||
{
|
||||
/* Allocate channels. Channel 0 is never used, but allocated to prevent off by 1 issues. */
|
||||
|
||||
@@ -372,10 +372,10 @@ static void seq_prefetch_update_active_seqbase(PrefetchJob *pfjob)
|
||||
|
||||
if (ms_orig != nullptr) {
|
||||
Strip *meta_eval = original_strip_get(ms_orig->parent_strip, pfjob->scene_eval);
|
||||
active_seqbase_set(ed_eval, &meta_eval->seqbase);
|
||||
ed_eval->current_meta_strip = meta_eval;
|
||||
}
|
||||
else {
|
||||
active_seqbase_set(ed_eval, &ed_eval->seqbase);
|
||||
ed_eval->current_meta_strip = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1985,8 +1985,9 @@ ImBuf *render_give_ibuf(const RenderData *context, float timeline_frame, int cha
|
||||
if ((chanshown < 0) && !BLI_listbase_is_empty(&ed->metastack)) {
|
||||
int count = BLI_listbase_count(&ed->metastack);
|
||||
count = max_ii(count + chanshown, 0);
|
||||
seqbasep = ((MetaStack *)BLI_findlink(&ed->metastack, count))->oldbasep;
|
||||
channels = ((MetaStack *)BLI_findlink(&ed->metastack, count))->old_channels;
|
||||
MetaStack *ms = static_cast<MetaStack *>(BLI_findlink(&ed->metastack, count));
|
||||
seqbasep = &ms->old_strip->seqbase;
|
||||
channels = &ms->old_strip->channels;
|
||||
chanshown = 0;
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -284,11 +284,9 @@ Editing *editing_ensure(Scene *scene)
|
||||
Editing *ed;
|
||||
|
||||
ed = scene->ed = MEM_callocN<Editing>("addseq");
|
||||
ed->seqbasep = &ed->seqbase;
|
||||
ed->cache_flag = (SEQ_CACHE_PREFETCH_ENABLE | SEQ_CACHE_STORE_FINAL_OUT | SEQ_CACHE_STORE_RAW);
|
||||
ed->show_missing_media_flag = SEQ_EDIT_SHOW_MISSING_MEDIA;
|
||||
ed->displayed_channels = &ed->channels;
|
||||
channels_ensure(ed->displayed_channels);
|
||||
channels_ensure(&ed->channels);
|
||||
}
|
||||
|
||||
return scene->ed;
|
||||
@@ -427,11 +425,6 @@ ListBase *active_seqbase_get(const Editing *ed)
|
||||
return ed ? ed->current_strips() : nullptr;
|
||||
}
|
||||
|
||||
void active_seqbase_set(Editing *ed, ListBase *seqbase)
|
||||
{
|
||||
ed->seqbasep = seqbase;
|
||||
}
|
||||
|
||||
static MetaStack *seq_meta_stack_alloc(const Scene *scene, Strip *strip_meta)
|
||||
{
|
||||
Editing *ed = editing_get(scene);
|
||||
@@ -441,9 +434,7 @@ static MetaStack *seq_meta_stack_alloc(const Scene *scene, Strip *strip_meta)
|
||||
ms->parent_strip = strip_meta;
|
||||
|
||||
/* Reference to previously displayed timeline data. */
|
||||
Strip *higher_level_meta = lookup_meta_by_strip(ed, strip_meta);
|
||||
ms->oldbasep = higher_level_meta ? &higher_level_meta->seqbase : &ed->seqbase;
|
||||
ms->old_channels = higher_level_meta ? &higher_level_meta->channels : &ed->channels;
|
||||
ms->old_strip = lookup_meta_by_strip(ed, strip_meta);
|
||||
|
||||
ms->disp_range[0] = time_left_handle_frame_get(scene, ms->parent_strip);
|
||||
ms->disp_range[1] = time_right_handle_frame_get(scene, ms->parent_strip);
|
||||
@@ -473,13 +464,10 @@ void meta_stack_set(const Scene *scene, Strip *dst)
|
||||
seq_meta_stack_alloc(scene, meta_parent);
|
||||
}
|
||||
|
||||
active_seqbase_set(ed, &dst->seqbase);
|
||||
channels_displayed_set(ed, &dst->channels);
|
||||
ed->current_meta_strip = dst;
|
||||
}
|
||||
else {
|
||||
/* Go to top level, exiting meta strip. */
|
||||
active_seqbase_set(ed, &ed->seqbase);
|
||||
channels_displayed_set(ed, &ed->channels);
|
||||
ed->current_meta_strip = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -487,8 +475,7 @@ Strip *meta_stack_pop(Editing *ed)
|
||||
{
|
||||
MetaStack *ms = meta_stack_active_get(ed);
|
||||
Strip *meta_parent = ms->parent_strip;
|
||||
active_seqbase_set(ed, ms->oldbasep);
|
||||
channels_displayed_set(ed, ms->old_channels);
|
||||
ed->current_meta_strip = ms->old_strip;
|
||||
BLI_remlink(&ed->metastack, ms);
|
||||
MEM_freeN(ms);
|
||||
return meta_parent;
|
||||
@@ -1159,20 +1146,34 @@ void eval_strips(Depsgraph *depsgraph, Scene *scene, ListBase *seqbase)
|
||||
|
||||
ListBase *Editing::current_strips()
|
||||
{
|
||||
return this->seqbasep;
|
||||
if (this->current_meta_strip) {
|
||||
return &this->current_meta_strip->seqbase;
|
||||
}
|
||||
return &this->seqbase;
|
||||
}
|
||||
|
||||
ListBase *Editing::current_strips() const
|
||||
{
|
||||
if (this->current_meta_strip) {
|
||||
return &this->current_meta_strip->seqbase;
|
||||
}
|
||||
/* NOTE: Const correctness is non-existent with ListBase anyway. */
|
||||
return this->seqbasep;
|
||||
return &const_cast<ListBase &>(this->seqbase);
|
||||
}
|
||||
|
||||
ListBase *Editing::current_channels()
|
||||
{
|
||||
return this->displayed_channels;
|
||||
if (this->current_meta_strip) {
|
||||
return &this->current_meta_strip->channels;
|
||||
}
|
||||
return &this->channels;
|
||||
}
|
||||
|
||||
ListBase *Editing::current_channels() const
|
||||
{
|
||||
if (this->current_meta_strip) {
|
||||
return &this->current_meta_strip->channels;
|
||||
}
|
||||
/* NOTE: Const correctness is non-existent with ListBase anyway. */
|
||||
return this->displayed_channels;
|
||||
return &const_cast<ListBase &>(this->channels);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user