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
97 lines
2.3 KiB
C++
97 lines
2.3 KiB
C++
/* SPDX-FileCopyrightText: 2022 Blender Authors
|
|
*
|
|
* SPDX-License-Identifier: GPL-2.0-or-later */
|
|
|
|
/** \file
|
|
* \ingroup sequencer
|
|
*/
|
|
|
|
#include <cstring>
|
|
|
|
#include "MEM_guardedalloc.h"
|
|
|
|
#include "DNA_listBase.h"
|
|
#include "DNA_sequence_types.h"
|
|
|
|
#include "BLI_listbase.h"
|
|
#include "BLI_string_utf8.h"
|
|
|
|
#include "BLT_translation.hh"
|
|
|
|
#include "sequencer.hh"
|
|
|
|
#include "SEQ_channels.hh"
|
|
#include "SEQ_sequencer.hh"
|
|
|
|
namespace blender::seq {
|
|
|
|
ListBase *channels_displayed_get(const Editing *ed)
|
|
{
|
|
return ed ? ed->current_channels() : nullptr;
|
|
}
|
|
|
|
void channels_ensure(ListBase *channels)
|
|
{
|
|
/* Allocate channels. Channel 0 is never used, but allocated to prevent off by 1 issues. */
|
|
for (int i = 0; i < MAX_CHANNELS + 1; i++) {
|
|
SeqTimelineChannel *channel = MEM_callocN<SeqTimelineChannel>("seq timeline channel");
|
|
SNPRINTF_UTF8(channel->name, DATA_("Channel %d"), i);
|
|
channel->index = i;
|
|
BLI_addtail(channels, channel);
|
|
}
|
|
}
|
|
|
|
void channels_duplicate(ListBase *channels_dst, ListBase *channels_src)
|
|
{
|
|
LISTBASE_FOREACH (SeqTimelineChannel *, channel, channels_src) {
|
|
SeqTimelineChannel *channel_duplicate = static_cast<SeqTimelineChannel *>(
|
|
MEM_dupallocN(channel));
|
|
BLI_addtail(channels_dst, channel_duplicate);
|
|
}
|
|
}
|
|
|
|
void channels_free(ListBase *channels)
|
|
{
|
|
LISTBASE_FOREACH_MUTABLE (SeqTimelineChannel *, channel, channels) {
|
|
MEM_freeN(channel);
|
|
}
|
|
}
|
|
|
|
SeqTimelineChannel *channel_get_by_index(const ListBase *channels, const int channel_index)
|
|
{
|
|
return static_cast<SeqTimelineChannel *>(BLI_findlink(channels, channel_index));
|
|
}
|
|
|
|
char *channel_name_get(ListBase *channels, const int channel_index)
|
|
{
|
|
SeqTimelineChannel *channel = channel_get_by_index(channels, channel_index);
|
|
return channel->name;
|
|
}
|
|
|
|
int channel_index_get(const SeqTimelineChannel *channel)
|
|
{
|
|
return channel->index;
|
|
}
|
|
|
|
bool channel_is_locked(const SeqTimelineChannel *channel)
|
|
{
|
|
return (channel->flag & SEQ_CHANNEL_LOCK) != 0;
|
|
}
|
|
|
|
bool channel_is_muted(const SeqTimelineChannel *channel)
|
|
{
|
|
return (channel->flag & SEQ_CHANNEL_MUTE) != 0;
|
|
}
|
|
|
|
ListBase *get_channels_by_strip(Editing *ed, const Strip *strip)
|
|
{
|
|
Strip *strip_owner = lookup_meta_by_strip(ed, strip);
|
|
if (strip_owner != nullptr) {
|
|
return &strip_owner->channels;
|
|
}
|
|
|
|
return &ed->channels;
|
|
}
|
|
|
|
} // namespace blender::seq
|