Blender V5.0
strip_connect.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2024 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9#include "BLI_listbase.h"
10
11#include "DNA_sequence_types.h"
12
13#include "SEQ_connect.hh"
14
15namespace blender::seq {
16
17static void strip_connections_free(Strip *strip)
18{
19 if (strip == nullptr) {
20 return;
21 }
22 ListBase *connections = &strip->connections;
23 LISTBASE_FOREACH_MUTABLE (StripConnection *, con, connections) {
24 MEM_delete(con);
25 }
26 BLI_listbase_clear(connections);
27}
28
29void connections_duplicate(ListBase *connections_dst, ListBase *connections_src)
30{
31 LISTBASE_FOREACH (StripConnection *, con, connections_src) {
32 StripConnection *con_duplicate = MEM_dupallocN<StripConnection>(__func__, *con);
33 BLI_addtail(connections_dst, con_duplicate);
34 }
35}
36
37bool disconnect(Strip *strip)
38{
39 if (strip == nullptr || BLI_listbase_is_empty(&strip->connections)) {
40 return false;
41 }
42 /* Remove `StripConnections` from other strips' `connections` list that point to `strip`. */
43 LISTBASE_FOREACH (StripConnection *, con_strip, &strip->connections) {
44 Strip *other = con_strip->strip_ref;
46 if (con_other->strip_ref == strip) {
47 BLI_remlink(&other->connections, con_other);
48 MEM_delete(con_other);
49 }
50 }
51 }
52 /* Now clear `connections` for `strip` itself. */
54
55 return true;
56}
57
59{
60 bool changed = false;
61 for (Strip *strip : strip_list) {
62 changed |= disconnect(strip);
63 }
64
65 return changed;
66}
67
69{
70 if (strip == nullptr) {
71 return;
72 }
74 Strip *other = con_strip->strip_ref;
75 bool is_one_way = true;
76 LISTBASE_FOREACH (StripConnection *, con_other, &other->connections) {
77 if (con_other->strip_ref == strip) {
78 /* The `other` sequence has a bidirectional connection with `strip`. */
79 is_one_way = false;
80 break;
81 }
82 }
83 if (is_one_way) {
84 BLI_remlink(&strip->connections, con_strip);
85 MEM_delete(con_strip);
86 }
87 }
88}
89
90void connect(Strip *strip1, Strip *strip2)
91{
92 if (strip1 == nullptr || strip2 == nullptr) {
93 return;
94 }
96 strip_list.add(strip1);
97 strip_list.add(strip2);
98
99 connect(strip_list);
100}
101
103{
104 strip_list.remove_if([&](Strip *strip) { return strip == nullptr; });
105
106 for (Strip *strip1 : strip_list) {
107 disconnect(strip1);
108 for (Strip *strip2 : strip_list) {
109 if (strip1 == strip2) {
110 continue;
111 }
112 StripConnection *con = MEM_callocN<StripConnection>("stripconnection");
113 con->strip_ref = strip2;
114 BLI_addtail(&strip1->connections, con);
115 }
116 }
117}
118
120{
121 blender::VectorSet<Strip *> connections;
122 if (strip != nullptr) {
124 connections.add(con->strip_ref);
125 }
126 }
127 return connections;
128}
129
130bool is_strip_connected(const Strip *strip)
131{
132 if (strip == nullptr) {
133 return false;
134 }
135 return !BLI_listbase_is_empty(&strip->connections);
136}
137
139{
140 const int expected_connection_num = strip_list.size() - 1;
141 for (Strip *strip1 : strip_list) {
143 int found_connection_num = connections.size();
144 if (found_connection_num != expected_connection_num) {
145 return false;
146 }
147 for (Strip *strip2 : connections) {
148 if (!strip_list.contains(strip2)) {
149 return false;
150 }
151 }
152 }
153 return true;
154}
155
156} // namespace blender::seq
#define LISTBASE_FOREACH(type, var, list)
BLI_INLINE void BLI_listbase_clear(ListBase *lb)
BLI_INLINE bool BLI_listbase_is_empty(const ListBase *lb)
#define LISTBASE_FOREACH_MUTABLE(type, var, list)
void BLI_addtail(ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:111
void BLI_remlink(ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:131
bool add(const Key &key)
int64_t size() const
bool contains(const Key &key) const
int64_t remove_if(Predicate &&predicate)
void * MEM_callocN(size_t len, const char *str)
Definition mallocn.cc:118
void * MEM_dupallocN(const void *vmemh)
Definition mallocn.cc:143
bool disconnect(Strip *strip)
bool are_strips_connected_together(blender::VectorSet< Strip * > &strip_list)
static void strip_connections_free(Strip *strip)
void connect(Strip *strip1, Strip *strip2)
void cut_one_way_connections(Strip *strip)
blender::VectorSet< Strip * > connected_strips_get(const Strip *strip)
bool is_strip_connected(const Strip *strip)
void connections_duplicate(ListBase *connections_dst, ListBase *connections_src)
ListBase connections