/*** Olive - Non-Linear Video Editor Copyright (C) 2022 Olive Team Modifications Copyright (C) 2025 mikesolar 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 OAK_RENDERTICKET_H #define OAK_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 is_running(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 get_finish_count(bool lock = true); /** * @brief Check if this ticket has a result * * If this ticket is running, this will always return false. */ bool has_result(); /** * @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 wait_for_finished(); void wait_for_finished(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 finish_internal(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 get_ticket() const { return ticket_; } void set_ticket(RenderTicketPtr ticket); bool is_running(); void wait_for_finished(); QVariant get(); bool has_result(); void cancel(); signals: void finished(RenderTicketWatcher *watcher); private: RenderTicketPtr ticket_; private slots: void ticket_finished(); }; } Q_DECLARE_METATYPE(olive::RenderTicketPtr) #endif // OAK_RENDERTICKET_H