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

SEQ_iterator.h « sequencer « blender « source - git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: e5adb2a33b14092226f1fe99b274c6ba7e96cb8e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
/* SPDX-License-Identifier: GPL-2.0-or-later
 * Copyright 2004 Blender Foundation. All rights reserved. */

#pragma once

/** \file
 * \ingroup sequencer
 */

#ifdef __cplusplus
extern "C" {
#endif

#include "BLI_ghash.h"

struct Editing;
struct GSet;
struct GSetIterator;
struct Sequence;

/* Utility macro to construct an unique (within a file) variable name for iterator macro.
 * Use indirect macro evaluation to ensure the `__LINE__` is expanded (rather than being
 * treated as a name token),
 *
 * The `__LINE__` is defined at the invocation of the `SEQ_ITERATOR_FOREACH` and is not changed
 * afterwards. This makes it safe to expand it several times in the `SEQ_ITERATOR_FOREACH`.
 *
 * This allows to have nested `foreach` loops.
 *
 * NOTE: Putting nested loop to a wrapper macro is not supported. */
#define _SEQ_ITERATOR_NAME_JOIN(x, y) x##_##y
#define _SEQ_ITERATOR_NAME_EVALUATE(x, y) _SEQ_ITERATOR_NAME_JOIN(x, y)
#define _SEQ_ITERATOR_NAME(prefix) _SEQ_ITERATOR_NAME_EVALUATE(prefix, __LINE__)

#define SEQ_ITERATOR_FOREACH(var, collection) \
  for (SeqIterator _SEQ_ITERATOR_NAME(iter) = {{{NULL}}}; \
       SEQ_iterator_ensure(collection, &_SEQ_ITERATOR_NAME(iter), &var) && var != NULL; \
       var = SEQ_iterator_yield(&_SEQ_ITERATOR_NAME(iter)))

typedef struct SeqCollection {
  struct GSet *set;
} SeqCollection;

typedef struct SeqIterator {
  GSetIterator gsi;
  SeqCollection *collection;
  bool iterator_initialized;
} SeqIterator;

/**
 * Utility function for SEQ_ITERATOR_FOREACH macro.
 * Ensure, that iterator is initialized. During initialization return pointer to collection element
 * and step gset iterator. When this function is called after iterator has been initialized, it
 * will do nothing and return true.
 *
 * \param collection: collection to iterate
 * \param iterator: iterator to be initialized
 * \param r_seq: pointer to Sequence pointer
 *
 * \return false when iterator can not be initialized, true otherwise
 */
bool SEQ_iterator_ensure(SeqCollection *collection,
                         SeqIterator *iterator,
                         struct Sequence **r_seq);
/**
 * Utility function for SEQ_ITERATOR_FOREACH macro.
 * Yield collection element
 *
 * \param iterator: iterator to be initialized
 *
 * \return collection element or NULL when iteration has ended
 */
struct Sequence *SEQ_iterator_yield(SeqIterator *iterator);

/**
 * Callback format for the for_each function below.
 */
typedef bool (*SeqForEachFunc)(struct Sequence *seq, void *user_data);

/**
 * Utility function to recursively iterate through all sequence strips in a `seqbase` list.
 * Uses callback to do operations on each sequence element.
 * The callback can stop the iteration if needed.
 *
 * \param seqbase: #ListBase of sequences to be iterated over.
 * \param callback: query function callback, returns false if iteration should stop.
 * \param user_data: pointer to user data that can be used in the callback function.
 */
void SEQ_for_each_callback(struct ListBase *seqbase, SeqForEachFunc callback, void *user_data);

/**
 * Create new empty strip collection.
 *
 * \return empty strip collection.
 */
SeqCollection *SEQ_collection_create(const char *name);
/**
 * Duplicate collection
 *
 * \param collection: collection to be duplicated
 * \return duplicate of collection
 */
SeqCollection *SEQ_collection_duplicate(SeqCollection *collection);
/**
 * Return number of items in collection.
 */
uint SEQ_collection_len(const SeqCollection *collection);
/**
 * Check if seq is in collection.
 */
bool SEQ_collection_has_strip(const struct Sequence *seq, const SeqCollection *collection);
/**
 * Add strip to collection.
 *
 * \param seq: strip to be added
 * \param collection: collection to which strip will be added
 * \return false if strip is already in set, otherwise true
 */
bool SEQ_collection_append_strip(struct Sequence *seq, SeqCollection *collection);
/**
 * Remove strip from collection.
 *
 * \param seq: strip to be removed
 * \param collection: collection from which strip will be removed
 * \return true if strip exists in set and it was removed from set, otherwise false
 */
bool SEQ_collection_remove_strip(struct Sequence *seq, SeqCollection *collection);
/**
 * Free strip collection.
 *
 * \param collection: collection to be freed
 */
void SEQ_collection_free(SeqCollection *collection);
/** Quiet compiler warning for free function. */
#define SEQ_collection_free_void_p ((GHashValFreeFP)SEQ_collection_free)

/**
 * Move strips from collection_src to collection_dst. Source collection will be freed.
 *
 * \param collection_dst: destination collection
 * \param collection_src: source collection
 */
void SEQ_collection_merge(SeqCollection *collection_dst, SeqCollection *collection_src);
/**
 * Remove strips from collection that are also in `exclude_elements`. Source collection will be
 * freed.
 *
 * \param collection: collection from which strips are removed
 * \param exclude_elements: collection of strips to be removed
 */
void SEQ_collection_exclude(SeqCollection *collection, SeqCollection *exclude_elements);
/**
 * Expand collection by running SEQ_query() for each strip, which will be used as reference.
 * Results of these queries will be merged into provided collection.
 *
 * \param seqbase: ListBase in which strips are queried
 * \param collection: SeqCollection to be expanded
 * \param seq_query_func: query function callback
 */
void SEQ_collection_expand(const struct Scene *scene,
                           struct ListBase *seqbase,
                           SeqCollection *collection,
                           void seq_query_func(const struct Scene *scene,
                                               struct Sequence *seq_reference,
                                               struct ListBase *seqbase,
                                               SeqCollection *collection));
/**
 * Query strips from seqbase. seq_reference is used by query function as filter condition.
 *
 * \param seq_reference: reference strip for query function
 * \param seqbase: ListBase in which strips are queried
 * \param seq_query_func: query function callback
 * \return strip collection
 */
SeqCollection *SEQ_query_by_reference(struct Sequence *seq_reference,
                                      const struct Scene *scene,
                                      struct ListBase *seqbase,
                                      void seq_query_func(const struct Scene *scene,
                                                          struct Sequence *seq_reference,
                                                          struct ListBase *seqbase,
                                                          SeqCollection *collection));
/**
 * Query all selected strips in seqbase.
 *
 * \param seqbase: ListBase in which strips are queried
 * \return strip collection
 */
SeqCollection *SEQ_query_selected_strips(struct ListBase *seqbase);
/**
 * Query all unselected strips in seqbase.
 *
 * \param seqbase: ListBase in which strips are queried
 * \return strip collection
 */
SeqCollection *SEQ_query_unselected_strips(struct ListBase *seqbase);
/**
 * Query all strips in seqbase. This does not include strips nested in meta strips.
 *
 * \param seqbase: ListBase in which strips are queried
 * \return strip collection
 */
SeqCollection *SEQ_query_all_strips(ListBase *seqbase);
/**
 * Query all strips in seqbase and nested meta strips.
 *
 * \param seqbase: ListBase in which strips are queried
 * \return strip collection
 */
SeqCollection *SEQ_query_all_strips_recursive(ListBase *seqbase);
/**
 * Query strips that are rendered at \a timeline_frame when \a displayed channel is viewed
 *
 * \param seqbase: ListBase in which strips are queried
 * \param timeline_frame: viewed frame
 * \param displayed_channel: viewed channel. when set to 0, no channel filter is applied
 * \return strip collection
 */
SeqCollection *SEQ_query_rendered_strips(const struct Scene *scene,
                                         ListBase *channels,
                                         ListBase *seqbase,
                                         int timeline_frame,
                                         int displayed_channel);
/**
 * Query all effect strips that are directly or indirectly connected to seq_reference.
 * This includes all effects of seq_reference, strips used by another inputs and their effects, so
 * that whole chain is fully independent of other strips.
 *
 * \param seq_reference: reference strip
 * \param seqbase: ListBase in which strips are queried
 * \param collection: collection to be filled
 */
void SEQ_query_strip_effect_chain(const struct Scene *scene,
                                  struct Sequence *seq_reference,
                                  struct ListBase *seqbase,
                                  SeqCollection *collection);
void SEQ_filter_selected_strips(SeqCollection *collection);

#ifdef __cplusplus
}
#endif