2022-02-11 09:07:11 +11:00
|
|
|
/* SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
|
* Copyright 2004 Blender Foundation. All rights reserved. */
|
2020-12-19 06:44:57 +01:00
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
|
|
/** \file
|
|
|
|
|
* \ingroup sequencer
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#ifdef __cplusplus
|
|
|
|
|
extern "C" {
|
|
|
|
|
#endif
|
|
|
|
|
|
2021-05-07 10:25:13 +02:00
|
|
|
#include "BLI_ghash.h"
|
|
|
|
|
|
2020-12-19 06:44:57 +01:00
|
|
|
struct Editing;
|
2021-05-07 10:25:13 +02:00
|
|
|
struct GSet;
|
|
|
|
|
struct GSetIterator;
|
2021-07-16 11:48:54 +10:00
|
|
|
struct Sequence;
|
2020-12-19 06:44:57 +01:00
|
|
|
|
2021-08-27 14:44:12 +02:00
|
|
|
/* 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`.
|
|
|
|
|
*
|
2021-09-01 21:41:23 +10:00
|
|
|
* This allows to have nested `foreach` loops.
|
2021-08-27 14:44:12 +02:00
|
|
|
*
|
|
|
|
|
* 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__)
|
2021-08-27 12:59:46 +02:00
|
|
|
|
2021-08-27 14:44:12 +02:00
|
|
|
#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)))
|
2020-12-19 06:44:57 +01:00
|
|
|
|
2021-05-07 10:25:13 +02:00
|
|
|
typedef struct SeqCollection {
|
|
|
|
|
struct GSet *set;
|
|
|
|
|
} SeqCollection;
|
|
|
|
|
|
|
|
|
|
typedef struct SeqIterator {
|
|
|
|
|
GSetIterator gsi;
|
|
|
|
|
SeqCollection *collection;
|
|
|
|
|
bool iterator_initialized;
|
|
|
|
|
} SeqIterator;
|
|
|
|
|
|
2021-12-08 21:02:29 +11:00
|
|
|
/**
|
|
|
|
|
* 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
|
|
|
|
|
*/
|
2021-05-07 10:25:13 +02:00
|
|
|
bool SEQ_iterator_ensure(SeqCollection *collection,
|
|
|
|
|
SeqIterator *iterator,
|
|
|
|
|
struct Sequence **r_seq);
|
2021-12-08 21:02:29 +11:00
|
|
|
/**
|
|
|
|
|
* 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
|
|
|
|
|
*/
|
2021-05-07 10:25:13 +02:00
|
|
|
struct Sequence *SEQ_iterator_yield(SeqIterator *iterator);
|
|
|
|
|
|
2021-12-08 21:02:29 +11:00
|
|
|
/**
|
|
|
|
|
* Callback format for the for_each function below.
|
|
|
|
|
*/
|
2021-08-20 16:30:34 +02:00
|
|
|
typedef bool (*SeqForEachFunc)(struct Sequence *seq, void *user_data);
|
|
|
|
|
|
2021-12-08 21:02:29 +11:00
|
|
|
/**
|
|
|
|
|
* 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.
|
|
|
|
|
*/
|
2021-08-20 16:30:34 +02:00
|
|
|
void SEQ_for_each_callback(struct ListBase *seqbase, SeqForEachFunc callback, void *user_data);
|
|
|
|
|
|
2021-12-08 21:02:29 +11:00
|
|
|
/**
|
|
|
|
|
* Create new empty strip collection.
|
|
|
|
|
*
|
|
|
|
|
* \return empty strip collection.
|
|
|
|
|
*/
|
2021-07-01 22:14:29 +02:00
|
|
|
SeqCollection *SEQ_collection_create(const char *name);
|
2021-12-08 21:02:29 +11:00
|
|
|
/**
|
|
|
|
|
* Duplicate collection
|
|
|
|
|
*
|
|
|
|
|
* \param collection: collection to be duplicated
|
|
|
|
|
* \return duplicate of collection
|
|
|
|
|
*/
|
2021-07-26 14:55:14 +02:00
|
|
|
SeqCollection *SEQ_collection_duplicate(SeqCollection *collection);
|
2021-12-08 21:02:29 +11:00
|
|
|
/**
|
|
|
|
|
* Return number of items in collection.
|
|
|
|
|
*/
|
2021-06-30 16:37:14 +10:00
|
|
|
uint SEQ_collection_len(const SeqCollection *collection);
|
2021-12-08 21:02:29 +11:00
|
|
|
/**
|
|
|
|
|
* Check if seq is in collection.
|
|
|
|
|
*/
|
2021-08-24 00:46:34 +02:00
|
|
|
bool SEQ_collection_has_strip(const struct Sequence *seq, const SeqCollection *collection);
|
2021-12-08 21:02:29 +11:00
|
|
|
/**
|
|
|
|
|
* 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
|
|
|
|
|
*/
|
2021-12-14 18:35:23 +11:00
|
|
|
bool SEQ_collection_append_strip(struct Sequence *seq, SeqCollection *collection);
|
2021-12-08 21:02:29 +11:00
|
|
|
/**
|
|
|
|
|
* 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
|
|
|
|
|
*/
|
2021-12-14 18:35:23 +11:00
|
|
|
bool SEQ_collection_remove_strip(struct Sequence *seq, SeqCollection *collection);
|
2021-12-08 21:02:29 +11:00
|
|
|
/**
|
|
|
|
|
* Free strip collection.
|
|
|
|
|
*
|
|
|
|
|
* \param collection: collection to be freed
|
|
|
|
|
*/
|
2021-05-07 15:57:35 +02:00
|
|
|
void SEQ_collection_free(SeqCollection *collection);
|
2021-12-08 21:02:29 +11:00
|
|
|
/**
|
|
|
|
|
* Move strips from collection_src to collection_dst. Source collection will be freed.
|
|
|
|
|
*
|
|
|
|
|
* \param collection_dst: destination collection
|
|
|
|
|
* \param collection_src: source collection
|
|
|
|
|
*/
|
2021-05-07 10:25:13 +02:00
|
|
|
void SEQ_collection_merge(SeqCollection *collection_dst, SeqCollection *collection_src);
|
2021-12-08 21:02:29 +11:00
|
|
|
/**
|
|
|
|
|
* 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
|
|
|
|
|
*/
|
2021-07-26 14:55:14 +02:00
|
|
|
void SEQ_collection_exclude(SeqCollection *collection, SeqCollection *exclude_elements);
|
2021-12-08 21:02:29 +11:00
|
|
|
/**
|
|
|
|
|
* 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
|
|
|
|
|
*/
|
2021-05-07 10:25:13 +02:00
|
|
|
void SEQ_collection_expand(struct ListBase *seqbase,
|
|
|
|
|
SeqCollection *collection,
|
2021-12-14 18:35:23 +11:00
|
|
|
void seq_query_func(struct Sequence *seq_reference,
|
|
|
|
|
struct ListBase *seqbase,
|
|
|
|
|
SeqCollection *collection));
|
2021-12-08 21:02:29 +11:00
|
|
|
/**
|
|
|
|
|
* 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
|
|
|
|
|
*/
|
2021-05-07 10:25:13 +02:00
|
|
|
SeqCollection *SEQ_query_by_reference(struct Sequence *seq_reference,
|
|
|
|
|
struct ListBase *seqbase,
|
|
|
|
|
void seq_query_func(struct Sequence *seq_reference,
|
|
|
|
|
struct ListBase *seqbase,
|
|
|
|
|
SeqCollection *collection));
|
2021-12-08 21:02:29 +11:00
|
|
|
/**
|
|
|
|
|
* Query all selected strips in seqbase.
|
|
|
|
|
*
|
|
|
|
|
* \param seqbase: ListBase in which strips are queried
|
|
|
|
|
* \return strip collection
|
|
|
|
|
*/
|
2021-05-07 10:25:13 +02:00
|
|
|
SeqCollection *SEQ_query_selected_strips(struct ListBase *seqbase);
|
2021-12-08 21:02:29 +11:00
|
|
|
/**
|
|
|
|
|
* Query all unselected strips in seqbase.
|
|
|
|
|
*
|
|
|
|
|
* \param seqbase: ListBase in which strips are queried
|
|
|
|
|
* \return strip collection
|
|
|
|
|
*/
|
2021-08-27 12:59:46 +02:00
|
|
|
SeqCollection *SEQ_query_unselected_strips(struct ListBase *seqbase);
|
2021-12-08 21:02:29 +11:00
|
|
|
/**
|
|
|
|
|
* 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
|
|
|
|
|
*/
|
2021-09-21 09:38:30 +02:00
|
|
|
SeqCollection *SEQ_query_all_strips(ListBase *seqbase);
|
2021-12-08 21:02:29 +11:00
|
|
|
/**
|
|
|
|
|
* Query all strips in seqbase and nested meta strips.
|
|
|
|
|
*
|
|
|
|
|
* \param seqbase: ListBase in which strips are queried
|
|
|
|
|
* \return strip collection
|
|
|
|
|
*/
|
2021-09-21 09:38:30 +02:00
|
|
|
SeqCollection *SEQ_query_all_strips_recursive(ListBase *seqbase);
|
2021-12-08 21:02:29 +11:00
|
|
|
/**
|
|
|
|
|
* 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
|
|
|
|
|
*/
|
2022-04-04 12:52:48 +02:00
|
|
|
SeqCollection *SEQ_query_rendered_strips(ListBase *channels,
|
|
|
|
|
ListBase *seqbase,
|
2022-01-07 11:38:08 +11:00
|
|
|
int timeline_frame,
|
|
|
|
|
int displayed_channel);
|
2021-12-08 21:02:29 +11:00
|
|
|
/**
|
|
|
|
|
* 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
|
|
|
|
|
*/
|
2021-05-18 23:28:00 +02:00
|
|
|
void SEQ_query_strip_effect_chain(struct Sequence *seq_reference,
|
|
|
|
|
struct ListBase *seqbase,
|
|
|
|
|
SeqCollection *collection);
|
2021-09-21 09:38:30 +02:00
|
|
|
void SEQ_filter_selected_strips(SeqCollection *collection);
|
2020-12-19 06:44:57 +01:00
|
|
|
|
|
|
|
|
#ifdef __cplusplus
|
|
|
|
|
}
|
|
|
|
|
#endif
|