/* * Olive Community Edition - Non-Linear Video Editor * Copyright (C) 2025 Olive CE Team * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef RENDERTICKET_H #define RENDERTICKET_H #include #include #include #include "codec/frame.h" #include "common/cancelableobject.h" #include "node/output/viewer/viewer.h" namespace olive { class RenderTicket : public QObject, public CancelableObject { Q_OBJECT public: RenderTicket(); /** * @brief Get the ticket's current state * * This function is thread safe, unless `lock` is set to false. Then the caller has responsibility * of locking the mutex before and unlocking after this function is called. */ bool IsRunning(bool lock = true); /** * @brief Determine how many times ticket has been finished * * This function is thread safe, unless `lock` is set to false. Then the caller has responsibility * of locking the mutex before and unlocking after this function is called. */ int GetFinishCount(bool lock = true); /** * @brief Check if this ticket has a result * * If this ticket is running, this will always return false. */ bool HasResult(); /** * @brief Get value, if any */ QVariant Get(); /** * @brief Wait for ticket to be finished * * If this ticket is not running, this function returns immediately. */ void WaitForFinished(); void WaitForFinished(QMutex *mutex); /** * @brief Access this ticket's mutex * * Use if you're doing several operations on a ticket and need to ensure thread safety while * doing so. Most of the time this isn't necessary since all functions are thread safe by default. */ QMutex *lock() { return &lock_; } /** * @brief Signal to the ticket that it is running * * If any value is set, it is cleared. */ void Start(); /** * @brief Finish ticket with no value * * Sets ticket to no longer running and assume it has received no result. */ void Finish(); /** * @brief Finish ticket with value * * Sets ticket to no longer running and provide a value generated by the operation requested. */ void Finish(QVariant result); signals: /** * @brief Emitted when finish has been called by any means (either cancelled or with a result) */ void Finished(); private: void FinishInternal(bool has_result, QVariant result); bool is_running_; QVariant result_; bool has_result_; int finish_count_; QMutex lock_; QWaitCondition wait_; }; using RenderTicketPtr = std::shared_ptr; class RenderTicketWatcher : public QObject { Q_OBJECT public: RenderTicketWatcher(QObject *parent = nullptr); RenderTicketPtr GetTicket() const { return ticket_; } void SetTicket(RenderTicketPtr ticket); bool IsRunning(); void WaitForFinished(); QVariant Get(); bool HasResult(); void Cancel(); signals: void Finished(RenderTicketWatcher *watcher); private: RenderTicketPtr ticket_; private slots: void TicketFinished(); }; } Q_DECLARE_METATYPE(olive::RenderTicketPtr) #endif // RENDERTICKET_H