From 630a5d2dd7f5c5fb786de96e4857e1fd0e21ca5d Mon Sep 17 00:00:00 2001 From: kunitoki Date: Fri, 2 Aug 2024 10:31:52 +0200 Subject: [PATCH 01/22] New module for data modelling (undo, value trees, ...) --- CMakeLists.txt | 1 + .../yup_data_model/undo/yup_UndoManager.cpp | 190 ++++++++++++++ modules/yup_data_model/undo/yup_UndoManager.h | 239 ++++++++++++++++++ .../yup_data_model/undo/yup_UndoableAction.h | 81 ++++++ modules/yup_data_model/yup_data_model.cpp | 36 +++ modules/yup_data_model/yup_data_model.h | 49 ++++ modules/yup_data_model/yup_data_model.mm | 22 ++ modules/yup_gui/yup_gui.h | 3 +- 8 files changed, 620 insertions(+), 1 deletion(-) create mode 100644 modules/yup_data_model/undo/yup_UndoManager.cpp create mode 100644 modules/yup_data_model/undo/yup_UndoManager.h create mode 100644 modules/yup_data_model/undo/yup_UndoableAction.h create mode 100644 modules/yup_data_model/yup_data_model.cpp create mode 100644 modules/yup_data_model/yup_data_model.h create mode 100644 modules/yup_data_model/yup_data_model.mm diff --git a/CMakeLists.txt b/CMakeLists.txt index e4af10a29..a2467f14e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -51,6 +51,7 @@ yup_add_module (modules/juce_audio_devices) # New yup modules yup_add_module (modules/yup_audio_processors) yup_add_module (modules/yup_audio_plugin_client) +yup_add_module (modules/yup_data_model) yup_add_module (modules/yup_graphics) yup_add_module (modules/yup_gui) diff --git a/modules/yup_data_model/undo/yup_UndoManager.cpp b/modules/yup_data_model/undo/yup_UndoManager.cpp new file mode 100644 index 000000000..3446e689a --- /dev/null +++ b/modules/yup_data_model/undo/yup_UndoManager.cpp @@ -0,0 +1,190 @@ +/* + ============================================================================== + + This file is part of the YUP library. + Copyright (c) 2024 - kunitoki@gmail.com + + YUP is an open source library subject to open-source licensing. + + The code included in this file is provided under the terms of the ISC license + http://www.isc.org/downloads/software-support-policy/isc-license. Permission + to use, copy, modify, and/or distribute this software for any purpose with or + without fee is hereby granted provided that the above copyright notice and + this permission notice appear in all copies. + + YUP IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace yup +{ + +//============================================================================== + +void UndoManager::CoalescedItem::add (UndoableAction::Ptr action) +{ + if (action != nullptr) + childItems.add (action); +} + +bool UndoManager::CoalescedItem::perform (UndoableActionState stateToPerform) +{ + if (stateToPerform == UndoableActionState::Undo) + { + for (int i = childItems.size() - 1; i >= 0; i--) + { + if (! childItems[i]->perform (stateToPerform)) + childItems.remove (i); + } + } + else + { + for (int i = 0; i < childItems.size(); i++) + { + if (! childItems[i]->perform (stateToPerform)) + childItems.remove (i--); + } + } + + return ! childItems.isEmpty(); +} + +bool UndoManager::CoalescedItem::isValid() const +{ + return childItems.isEmpty(); +} + +//============================================================================== + +UndoManager::ScopedTransaction::ScopedTransaction(UndoManager& undoManager) + : undoManager (undoManager) +{ + undoManager.flushCurrentAction(); +} + +UndoManager::ScopedTransaction::~ScopedTransaction() +{ + undoManager.flushCurrentAction(); +} + +//============================================================================== + +UndoManager::UndoManager (int maxHistorySize) + : maxHistorySize (maxHistorySize) +{ + setEnabled (true); +} + +//============================================================================== + +bool UndoManager::perform (UndoableAction::Ptr action) +{ + jassert (action != nullptr); + + if (action->perform (UndoableActionState::Redo)) + { + currentlyBuiltAction->add (action); + return true; + } + + return false; +} + +//============================================================================== + +bool UndoManager::undo() +{ + return internalPerform (UndoableActionState::Undo); +} + +bool UndoManager::redo() +{ + return internalPerform (UndoableActionState::Redo); +} + +//============================================================================== + +void UndoManager::setEnabled (bool shouldBeEnabled) +{ + if (isEnabled() != shouldBeEnabled) + { + if (shouldBeEnabled) + { + startTimer (500); + + currentlyBuiltAction = new CoalescedItem; + } + else + { + stopTimer(); + + currentlyBuiltAction = nullptr; + + undoHistory.clear(); + } + } +} + +bool UndoManager::isEnabled() const +{ + return isTimerRunning(); +} + +//============================================================================== + +void UndoManager::timerCallback() +{ + flushCurrentAction(); +} + +//============================================================================== + +bool UndoManager::internalPerform (UndoableActionState stateToPerform) +{ + flushCurrentAction(); + + auto& actionIndex = (stateToPerform == UndoableActionState::Undo) ? nextUndoAction : nextRedoAction; + + if (auto current = undoHistory[actionIndex]) + { + current->perform (stateToPerform); + + const auto delta = (stateToPerform == UndoableActionState::Undo) ? -1 : 1; + nextUndoAction += delta; + nextRedoAction += delta; + + return true; + } + + return false; +} + +//============================================================================== + +bool UndoManager::flushCurrentAction() +{ + if (! currentlyBuiltAction->isValid()) + return false; + + // Remove all future actions + if (nextRedoAction < undoHistory.size()) + undoHistory.removeRange (nextRedoAction, undoHistory.size() - nextRedoAction); + + undoHistory.add (currentlyBuiltAction.get()); + currentlyBuiltAction = new CoalescedItem; + + // Clean up to keep the undo history in check + const int numToRemove = jmax (0, undoHistory.size() - maxHistorySize); + if (numToRemove > 0) + undoHistory.removeRange (0, numToRemove); + + nextUndoAction = undoHistory.size() - 1; + nextRedoAction = undoHistory.size(); + + return true; +} + +} // namespace yup diff --git a/modules/yup_data_model/undo/yup_UndoManager.h b/modules/yup_data_model/undo/yup_UndoManager.h new file mode 100644 index 000000000..7facac7c8 --- /dev/null +++ b/modules/yup_data_model/undo/yup_UndoManager.h @@ -0,0 +1,239 @@ +/* + ============================================================================== + + This file is part of the YUP library. + Copyright (c) 2024 - kunitoki@gmail.com + + YUP is an open source library subject to open-source licensing. + + The code included in this file is provided under the terms of the ISC license + http://www.isc.org/downloads/software-support-policy/isc-license. Permission + to use, copy, modify, and/or distribute this software for any purpose with or + without fee is hereby granted provided that the above copyright notice and + this permission notice appear in all copies. + + YUP IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace yup +{ + +//============================================================================== +/** + @class UndoManager + + @brief Manages undo and redo functionality for a set of actions. + + The UndoManager class provides a way to manage undo and redo functionality + for a set of actions. It allows you to perform actions, undo them, redo them, + enable or disable the undo manager, and group actions together as a single action. + + To use the UndoManager, create an instance of the class and call the `perform` + method to add actions to the timeline. You can also use the `undo` and `redo` + methods to reverse or perform the action in the current timeline position. + + The UndoManager class also provides a ScopedActionIsolator helper class that + allows you to group certain actions as a single action. This can be useful + when you want to ensure that multiple actions are treated as a single unit + for undo and redo purposes. + + @see UndoableAction +*/ +class UndoManager : private Timer +{ +public: + //============================================================================== + /** + Creates a new UndoManager and starts the timer. + + @param maxHistorySize The maximum number of items to keep in the history. Default is 100. + */ + UndoManager (int maxHistorySize = 100); + + //============================================================================== + /** + Adds a new action to the timeline and performs its `redo` method. + + @param f The action to be performed. + + @return true if the action was added and performed successfully, false otherwise. + */ + bool perform (UndoableAction::Ptr f); + + //============================================================================== + /** + @brief A type alias for an action callback function. + + This type alias represents a std::function that takes a reference to a WeakReferenceable object + and an UndoableActionState object as parameters, and returns a boolean value. + + The callback function is used by the UndoManager to perform an undoable action on a WeakReferenceable + object. It should return true if the action was successfully performed, and false otherwise. + + @tparam WeakReferenceable The type of the object that can be weakly referenced. + + @param referenceable A reference to the WeakReferenceable object on which the action should be performed. + @param actionState The state of the undoable action. + + @return true if the action was successfully performed, false otherwise. + */ + template + using ActionCallback = std::function; + + /** + Adds a new action to the timeline and performs its `redo` method. + + This method allows you to create an action using a weak referenceable object and a lambda + that will be performed if the object is still alive. + + @tparam T The type of the object. + + @param obj The object to be used in the action. + @param f The lambda function to be performed. + + @return true if the action was added and performed successfully, false otherwise. + */ + template + bool perform (T& obj, const ActionCallback& f) + { + return perform (new Item (obj, f)); + } + + //============================================================================== + /** + Reverses the action in the current timeline position. + + @return true if an action was reversed, false otherwise. + */ + bool undo(); + + /** + Performs the action in the current timeline position. + + @return true if an action was performed, false otherwise. + */ + bool redo(); + + //============================================================================== + /** + Enables or disables the undo manager. + + @param shouldBeEnabled true to enable the undo manager, false to disable it. + + Disabling the undo manager will clear the history and stop the timer. + */ + void setEnabled (bool shouldBeEnabled); + + /** + Checks if the undo manager is enabled. + + @return true if the undo manager is enabled, false otherwise. + */ + bool isEnabled() const; + + //============================================================================== + /** + Helper class to ensure that certain actions are grouped as a single action. + + By default, the undo manager groups all actions within a 500ms time window + into one action. If you need to have a separate item in the timeline for + certain actions, you can use this class. + + Example usage: + + @code + void doSomething() + { + UndoManager::ScopedTransaction transaction (um); + + um.perform (action1); + um.perform (action2); + } + @endcode + */ + struct ScopedTransaction + { + /** + Constructs a ScopedTransaction object. + + @param undoManager The UndoManager to be used. + */ + ScopedTransaction (UndoManager& undoManager); + + /** + Destructs the ScopedTransaction object. + */ + ~ScopedTransaction(); + + private: + UndoManager& undoManager; + }; + +private: + template + struct Item : public UndoableAction + { + Item (T& obj, std::function function) + : object (std::addressof (object)) + , function (std::move (function)) + { + jassert (function != nullptr); + } + + bool perform (UndoableActionState stateToPerform) override + { + if (object.wasObjectDeleted()) + return false; + + return function (*object, stateToPerform); + } + + bool isValid() const override + { + return !object.wasObjectDeleted(); + } + + private: + WeakReference object; + std::function function; + }; + + struct CoalescedItem : public UndoableAction + { + using Ptr = ReferenceCountedObjectPtr; + + CoalescedItem() = default; + + void add (UndoableAction::Ptr action); + + bool perform (UndoableActionState stateToPerform) override; + bool isValid() const override; + + private: + ReferenceCountedArray childItems; + }; + + /** @internal */ + void timerCallback() override; + /** @internal */ + bool internalPerform (UndoableActionState stateToPerform); + /** @internal */ + bool flushCurrentAction(); + + int maxHistorySize; + + UndoableAction::List undoHistory; + CoalescedItem::Ptr currentlyBuiltAction; + + // the position in the timeline for the next actions. + int nextUndoAction = -1; + int nextRedoAction = -1; + + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (UndoManager) +}; + +} // namespace yup diff --git a/modules/yup_data_model/undo/yup_UndoableAction.h b/modules/yup_data_model/undo/yup_UndoableAction.h new file mode 100644 index 000000000..b7a9589d7 --- /dev/null +++ b/modules/yup_data_model/undo/yup_UndoableAction.h @@ -0,0 +1,81 @@ +/* + ============================================================================== + + This file is part of the YUP library. + Copyright (c) 2024 - kunitoki@gmail.com + + YUP is an open source library subject to open-source licensing. + + The code included in this file is provided under the terms of the ISC license + http://www.isc.org/downloads/software-support-policy/isc-license. Permission + to use, copy, modify, and/or distribute this software for any purpose with or + without fee is hereby granted provided that the above copyright notice and + this permission notice appear in all copies. + + YUP IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace yup +{ + +//============================================================================== +/** + @enum ActionState + + Represents the state of an action in the undo/redo system. + + The ActionState enum is used to indicate whether an action should be undone or redone. + + @see yup_UndoManager +*/ +enum class UndoableActionState +{ + Undo, /**< Indicates that the action should be undone. */ + Redo /**< Indicates that the action should be redone. */ +}; + +//============================================================================== +/** + @class UndoableAction + @brief The base class for all actions in the timeline. + + You can subclass from this class to define your actions, + but a better way is to just use a lambda with a WeakReferenceable object. +*/ +class UndoableAction : public ReferenceCountedObject +{ +public: + using List = ReferenceCountedArray; + using Ptr = ReferenceCountedObjectPtr; + + /** + @brief Destructor. + */ + ~UndoableAction() override {} + + /** + @brief Checks if the action is valid. + + This should return true if the action is invalidated (e.g., because the object it operates on was deleted). + + @return True if the action is valid, false otherwise. + */ + virtual bool isValid() const = 0; + + /** + @brief Performs the undo action. + + This function performs the undo action based on the given state. + + @param stateToPerform The state of the action to perform (Undo or Redo). + + @return True if the undo action was successful, false otherwise. + */ + virtual bool perform (UndoableActionState stateToPerform) = 0; +}; + +} // namespace yup diff --git a/modules/yup_data_model/yup_data_model.cpp b/modules/yup_data_model/yup_data_model.cpp new file mode 100644 index 000000000..b92595cb0 --- /dev/null +++ b/modules/yup_data_model/yup_data_model.cpp @@ -0,0 +1,36 @@ +/* + ============================================================================== + + This file is part of the YUP library. + Copyright (c) 2024 - kunitoki@gmail.com + + YUP is an open source library subject to open-source licensing. + + The code included in this file is provided under the terms of the ISC license + http://www.isc.org/downloads/software-support-policy/isc-license. Permission + to use, copy, modify, and/or distribute this software for any purpose with or + without fee is hereby granted provided that the above copyright notice and + this permission notice appear in all copies. + + YUP IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +// clang-format off +#ifdef YUP_AUDIO_PROCESSORS_H_INCLUDED +/* When you add this cpp file to your project, you mustn't include it in a file where you've + already included any other headers - just put it inside a file on its own, possibly with your config + flags preceding it, but don't include anything else. That also includes avoiding any automatic prefix + header files that the compiler may be using. + */ +#error "Incorrect use of YUP cpp file" +#endif +// clang-format on + +#include "yup_data_model.h" + +//============================================================================== +#include "undo/yup_UndoManager.cpp" diff --git a/modules/yup_data_model/yup_data_model.h b/modules/yup_data_model/yup_data_model.h new file mode 100644 index 000000000..3b7a46f19 --- /dev/null +++ b/modules/yup_data_model/yup_data_model.h @@ -0,0 +1,49 @@ +/* + ============================================================================== + + This file is part of the YUP library. + Copyright (c) 2024 - kunitoki@gmail.com + + YUP is an open source library subject to open-source licensing. + + The code included in this file is provided under the terms of the ISC license + http://www.isc.org/downloads/software-support-policy/isc-license. Permission + to use, copy, modify, and/or distribute this software for any purpose with or + without fee is hereby granted provided that the above copyright notice and + this permission notice appear in all copies. + + YUP IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +/******************************************************************************* + + BEGIN_JUCE_MODULE_DECLARATION + + ID: yup_data_model + vendor: yup + version: 1.0.0 + name: YUP Data Model + description: The essential set of basic YUP data model classes. + website: https://github.com/kunitoki/yup + license: ISC + minimumCppStandard: 17 + + dependencies: juce_events + enableARC: 1 + + END_JUCE_MODULE_DECLARATION + +*******************************************************************************/ + +#pragma once +#define YUP_DATA_MODEL_H_INCLUDED + +#include + +//============================================================================== +#include "undo/yup_UndoableAction.h" +#include "undo/yup_UndoManager.h" diff --git a/modules/yup_data_model/yup_data_model.mm b/modules/yup_data_model/yup_data_model.mm new file mode 100644 index 000000000..b362ba23a --- /dev/null +++ b/modules/yup_data_model/yup_data_model.mm @@ -0,0 +1,22 @@ +/* + ============================================================================== + + This file is part of the YUP library. + Copyright (c) 2024 - kunitoki@gmail.com + + YUP is an open source library subject to open-source licensing. + + The code included in this file is provided under the terms of the ISC license + http://www.isc.org/downloads/software-support-policy/isc-license. Permission + to use, copy, modify, and/or distribute this software for any purpose with or + without fee is hereby granted provided that the above copyright notice and + this permission notice appear in all copies. + + YUP IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +#include "yup_data_model.cpp" diff --git a/modules/yup_gui/yup_gui.h b/modules/yup_gui/yup_gui.h index 2c5fb0668..5ce681c21 100644 --- a/modules/yup_gui/yup_gui.h +++ b/modules/yup_gui/yup_gui.h @@ -33,7 +33,7 @@ license: ISC minimumCppStandard: 17 - dependencies: juce_events + dependencies: juce_events yup_data_model OSXFrameworks: Metal iOSFrameworks: Metal enableARC: 1 @@ -48,6 +48,7 @@ #include +#include #include #include From 40625b164b2fab422a8743853747368d9b9130c1 Mon Sep 17 00:00:00 2001 From: Yup Bot Date: Fri, 2 Aug 2024 08:37:58 +0000 Subject: [PATCH 02/22] Code formatting --- .../yup_data_model/undo/yup_UndoManager.cpp | 106 +++++++++--------- modules/yup_data_model/undo/yup_UndoManager.h | 14 +-- 2 files changed, 60 insertions(+), 60 deletions(-) diff --git a/modules/yup_data_model/undo/yup_UndoManager.cpp b/modules/yup_data_model/undo/yup_UndoManager.cpp index 3446e689a..61974bc9a 100644 --- a/modules/yup_data_model/undo/yup_UndoManager.cpp +++ b/modules/yup_data_model/undo/yup_UndoManager.cpp @@ -59,7 +59,7 @@ bool UndoManager::CoalescedItem::isValid() const //============================================================================== -UndoManager::ScopedTransaction::ScopedTransaction(UndoManager& undoManager) +UndoManager::ScopedTransaction::ScopedTransaction (UndoManager& undoManager) : undoManager (undoManager) { undoManager.flushCurrentAction(); @@ -75,7 +75,7 @@ UndoManager::ScopedTransaction::~ScopedTransaction() UndoManager::UndoManager (int maxHistorySize) : maxHistorySize (maxHistorySize) { - setEnabled (true); + setEnabled (true); } //============================================================================== @@ -84,48 +84,48 @@ bool UndoManager::perform (UndoableAction::Ptr action) { jassert (action != nullptr); - if (action->perform (UndoableActionState::Redo)) - { - currentlyBuiltAction->add (action); - return true; - } + if (action->perform (UndoableActionState::Redo)) + { + currentlyBuiltAction->add (action); + return true; + } - return false; + return false; } //============================================================================== bool UndoManager::undo() { - return internalPerform (UndoableActionState::Undo); + return internalPerform (UndoableActionState::Undo); } bool UndoManager::redo() { - return internalPerform (UndoableActionState::Redo); + return internalPerform (UndoableActionState::Redo); } //============================================================================== void UndoManager::setEnabled (bool shouldBeEnabled) { - if (isEnabled() != shouldBeEnabled) - { - if (shouldBeEnabled) - { - startTimer (500); - - currentlyBuiltAction = new CoalescedItem; - } - else - { - stopTimer(); - - currentlyBuiltAction = nullptr; - - undoHistory.clear(); - } - } + if (isEnabled() != shouldBeEnabled) + { + if (shouldBeEnabled) + { + startTimer (500); + + currentlyBuiltAction = new CoalescedItem; + } + else + { + stopTimer(); + + currentlyBuiltAction = nullptr; + + undoHistory.clear(); + } + } } bool UndoManager::isEnabled() const @@ -137,54 +137,54 @@ bool UndoManager::isEnabled() const void UndoManager::timerCallback() { - flushCurrentAction(); + flushCurrentAction(); } //============================================================================== bool UndoManager::internalPerform (UndoableActionState stateToPerform) { - flushCurrentAction(); + flushCurrentAction(); - auto& actionIndex = (stateToPerform == UndoableActionState::Undo) ? nextUndoAction : nextRedoAction; + auto& actionIndex = (stateToPerform == UndoableActionState::Undo) ? nextUndoAction : nextRedoAction; - if (auto current = undoHistory[actionIndex]) - { - current->perform (stateToPerform); + if (auto current = undoHistory[actionIndex]) + { + current->perform (stateToPerform); - const auto delta = (stateToPerform == UndoableActionState::Undo) ? -1 : 1; - nextUndoAction += delta; - nextRedoAction += delta; + const auto delta = (stateToPerform == UndoableActionState::Undo) ? -1 : 1; + nextUndoAction += delta; + nextRedoAction += delta; - return true; - } + return true; + } - return false; + return false; } //============================================================================== bool UndoManager::flushCurrentAction() { - if (! currentlyBuiltAction->isValid()) - return false; + if (! currentlyBuiltAction->isValid()) + return false; - // Remove all future actions - if (nextRedoAction < undoHistory.size()) - undoHistory.removeRange (nextRedoAction, undoHistory.size() - nextRedoAction); + // Remove all future actions + if (nextRedoAction < undoHistory.size()) + undoHistory.removeRange (nextRedoAction, undoHistory.size() - nextRedoAction); - undoHistory.add (currentlyBuiltAction.get()); - currentlyBuiltAction = new CoalescedItem; + undoHistory.add (currentlyBuiltAction.get()); + currentlyBuiltAction = new CoalescedItem; - // Clean up to keep the undo history in check - const int numToRemove = jmax (0, undoHistory.size() - maxHistorySize); - if (numToRemove > 0) - undoHistory.removeRange (0, numToRemove); + // Clean up to keep the undo history in check + const int numToRemove = jmax (0, undoHistory.size() - maxHistorySize); + if (numToRemove > 0) + undoHistory.removeRange (0, numToRemove); - nextUndoAction = undoHistory.size() - 1; - nextRedoAction = undoHistory.size(); + nextUndoAction = undoHistory.size() - 1; + nextRedoAction = undoHistory.size(); - return true; + return true; } } // namespace yup diff --git a/modules/yup_data_model/undo/yup_UndoManager.h b/modules/yup_data_model/undo/yup_UndoManager.h index 7facac7c8..5ebcdaa9d 100644 --- a/modules/yup_data_model/undo/yup_UndoManager.h +++ b/modules/yup_data_model/undo/yup_UndoManager.h @@ -82,7 +82,7 @@ class UndoManager : private Timer @return true if the action was successfully performed, false otherwise. */ template - using ActionCallback = std::function; + using ActionCallback = std::function; /** Adds a new action to the timeline and performs its `redo` method. @@ -176,8 +176,8 @@ class UndoManager : private Timer private: template struct Item : public UndoableAction - { - Item (T& obj, std::function function) + { + Item (T& obj, std::function function) : object (std::addressof (object)) , function (std::move (function)) { @@ -186,7 +186,7 @@ class UndoManager : private Timer bool perform (UndoableActionState stateToPerform) override { - if (object.wasObjectDeleted()) + if (object.wasObjectDeleted()) return false; return function (*object, stateToPerform); @@ -194,13 +194,13 @@ class UndoManager : private Timer bool isValid() const override { - return !object.wasObjectDeleted(); + return ! object.wasObjectDeleted(); } private: WeakReference object; - std::function function; - }; + std::function function; + }; struct CoalescedItem : public UndoableAction { From 309987d291db8ff7046aa057dff428cd73f831d1 Mon Sep 17 00:00:00 2001 From: kunitoki Date: Fri, 2 Aug 2024 12:43:01 +0200 Subject: [PATCH 03/22] Improved tests --- .../yup_data_model/undo/yup_UndoManager.cpp | 201 ++++++++--- modules/yup_data_model/undo/yup_UndoManager.h | 132 ++++--- .../yup_data_model/undo/yup_UndoableAction.h | 2 +- tests/CMakeLists.txt | 8 +- tests/yup_data_model/yup_UndoManager.cpp | 328 ++++++++++++++++++ 5 files changed, 573 insertions(+), 98 deletions(-) create mode 100644 tests/yup_data_model/yup_UndoManager.cpp diff --git a/modules/yup_data_model/undo/yup_UndoManager.cpp b/modules/yup_data_model/undo/yup_UndoManager.cpp index 61974bc9a..eb6458b67 100644 --- a/modules/yup_data_model/undo/yup_UndoManager.cpp +++ b/modules/yup_data_model/undo/yup_UndoManager.cpp @@ -24,13 +24,28 @@ namespace yup //============================================================================== -void UndoManager::CoalescedItem::add (UndoableAction::Ptr action) +void UndoManager::Transaction::add (UndoableAction::Ptr action) { if (action != nullptr) childItems.add (action); } -bool UndoManager::CoalescedItem::perform (UndoableActionState stateToPerform) +int UndoManager::Transaction::size() const +{ + return childItems.size(); +} + +String UndoManager::Transaction::getTransactionName() const +{ + return transactionName; +} + +void UndoManager::Transaction::setTransactionName (StringRef newName) +{ + transactionName = newName; +} + +bool UndoManager::Transaction::perform (UndoableActionState stateToPerform) { if (stateToPerform == UndoableActionState::Undo) { @@ -49,10 +64,10 @@ bool UndoManager::CoalescedItem::perform (UndoableActionState stateToPerform) } } - return ! childItems.isEmpty(); + return ! isEmpty(); } -bool UndoManager::CoalescedItem::isValid() const +bool UndoManager::Transaction::isEmpty() const { return childItems.isEmpty(); } @@ -62,20 +77,48 @@ bool UndoManager::CoalescedItem::isValid() const UndoManager::ScopedTransaction::ScopedTransaction (UndoManager& undoManager) : undoManager (undoManager) { - undoManager.flushCurrentAction(); + undoManager.beginNewTransaction(); +} + +UndoManager::ScopedTransaction::ScopedTransaction (UndoManager& undoManager, StringRef transactionName) + : undoManager (undoManager) +{ + undoManager.beginNewTransaction (transactionName); } UndoManager::ScopedTransaction::~ScopedTransaction() { - undoManager.flushCurrentAction(); + undoManager.flushCurrentTransaction(); } //============================================================================== +UndoManager::UndoManager() + : maxHistorySize (100) + , actionGroupThreshold (RelativeTime::milliseconds (500)) +{ + setEnabled (true); +} + UndoManager::UndoManager (int maxHistorySize) : maxHistorySize (maxHistorySize) + , actionGroupThreshold (RelativeTime::milliseconds (500)) +{ + setEnabled (true); +} + +UndoManager::UndoManager (RelativeTime actionGroupThreshold) + : maxHistorySize (100) + , actionGroupThreshold (actionGroupThreshold) +{ + setEnabled (true); +} + +UndoManager::UndoManager (int maxHistorySize, RelativeTime actionGroupThreshold) + : maxHistorySize (maxHistorySize) + , actionGroupThreshold (actionGroupThreshold) { - setEnabled (true); + setEnabled (true); } //============================================================================== @@ -84,107 +127,151 @@ bool UndoManager::perform (UndoableAction::Ptr action) { jassert (action != nullptr); - if (action->perform (UndoableActionState::Redo)) - { - currentlyBuiltAction->add (action); - return true; - } + if (! isEnabled()) + return false; + + if (action->perform (UndoableActionState::Redo)) + { + if (currentTransaction == nullptr) + beginNewTransaction(); - return false; + currentTransaction->add (action); + + return true; + } + + return false; } //============================================================================== -bool UndoManager::undo() +void UndoManager::beginNewTransaction() { - return internalPerform (UndoableActionState::Undo); + beginNewTransaction ({}); } -bool UndoManager::redo() +void UndoManager::beginNewTransaction (StringRef transactionName) { - return internalPerform (UndoableActionState::Redo); + flushCurrentTransaction(); + + if (currentTransaction == nullptr) + currentTransaction = new Transaction (transactionName); + + else if (currentTransaction->isEmpty()) + currentTransaction->setTransactionName (transactionName); } //============================================================================== -void UndoManager::setEnabled (bool shouldBeEnabled) +bool UndoManager::canUndo() const { - if (isEnabled() != shouldBeEnabled) - { - if (shouldBeEnabled) - { - startTimer (500); + return + (currentTransaction != nullptr && ! currentTransaction->isEmpty()) + || isPositiveAndBelow (nextUndoAction, undoHistory.size()); +} - currentlyBuiltAction = new CoalescedItem; - } - else - { - stopTimer(); +bool UndoManager::undo() +{ + return internalPerform (UndoableActionState::Undo); +} - currentlyBuiltAction = nullptr; +bool UndoManager::canRedo() const +{ + return + (currentTransaction != nullptr && ! currentTransaction->isEmpty()) + || isPositiveAndBelow (nextRedoAction, undoHistory.size()); +} - undoHistory.clear(); - } - } +bool UndoManager::redo() +{ + return internalPerform (UndoableActionState::Redo); +} + +//============================================================================== + +void UndoManager::setEnabled (bool shouldBeEnabled) +{ + if (isEnabled() != shouldBeEnabled) + { + isUndoEnabled = shouldBeEnabled; + + if (shouldBeEnabled) + { + if (actionGroupThreshold > RelativeTime()) + startTimer (static_cast (actionGroupThreshold.inMilliseconds())); + } + else + { + if (actionGroupThreshold > RelativeTime()) + stopTimer(); + + flushCurrentTransaction(); + + undoHistory.clear(); + } + } } bool UndoManager::isEnabled() const { - return isTimerRunning(); + return isUndoEnabled; } //============================================================================== void UndoManager::timerCallback() { - flushCurrentAction(); + beginNewTransaction(); } //============================================================================== bool UndoManager::internalPerform (UndoableActionState stateToPerform) { - flushCurrentAction(); + flushCurrentTransaction(); - auto& actionIndex = (stateToPerform == UndoableActionState::Undo) ? nextUndoAction : nextRedoAction; + auto actionIndex = (stateToPerform == UndoableActionState::Undo) ? nextUndoAction : nextRedoAction; + if (! isPositiveAndBelow(actionIndex, undoHistory.size())) + return false; - if (auto current = undoHistory[actionIndex]) - { - current->perform (stateToPerform); + auto current = undoHistory[actionIndex]; + if (current == nullptr) + return false; + auto result = current->perform (stateToPerform); + if (result) + { const auto delta = (stateToPerform == UndoableActionState::Undo) ? -1 : 1; nextUndoAction += delta; nextRedoAction += delta; - - return true; } - return false; + return result; } //============================================================================== -bool UndoManager::flushCurrentAction() +bool UndoManager::flushCurrentTransaction() { - if (! currentlyBuiltAction->isValid()) - return false; + if (currentTransaction == nullptr || currentTransaction->isEmpty()) + return false; - // Remove all future actions - if (nextRedoAction < undoHistory.size()) - undoHistory.removeRange (nextRedoAction, undoHistory.size() - nextRedoAction); + // Remove all future actions + if (nextRedoAction < undoHistory.size()) + undoHistory.removeRange (nextRedoAction, undoHistory.size() - nextRedoAction); - undoHistory.add (currentlyBuiltAction.get()); - currentlyBuiltAction = new CoalescedItem; + undoHistory.add (currentTransaction.get()); + currentTransaction = nullptr; - // Clean up to keep the undo history in check - const int numToRemove = jmax (0, undoHistory.size() - maxHistorySize); - if (numToRemove > 0) - undoHistory.removeRange (0, numToRemove); + // Clean up to keep the undo history in check + const int numToRemove = jmax (0, undoHistory.size() - maxHistorySize); + if (numToRemove > 0) + undoHistory.removeRange (0, numToRemove); - nextUndoAction = undoHistory.size() - 1; - nextRedoAction = undoHistory.size(); + nextUndoAction = undoHistory.size() - 1; + nextRedoAction = undoHistory.size(); - return true; + return true; } } // namespace yup diff --git a/modules/yup_data_model/undo/yup_UndoManager.h b/modules/yup_data_model/undo/yup_UndoManager.h index 5ebcdaa9d..74297edcb 100644 --- a/modules/yup_data_model/undo/yup_UndoManager.h +++ b/modules/yup_data_model/undo/yup_UndoManager.h @@ -49,41 +49,42 @@ class UndoManager : private Timer //============================================================================== /** Creates a new UndoManager and starts the timer. - - @param maxHistorySize The maximum number of items to keep in the history. Default is 100. */ - UndoManager (int maxHistorySize = 100); + UndoManager(); - //============================================================================== /** - Adds a new action to the timeline and performs its `redo` method. - - @param f The action to be performed. + Creates a new UndoManager and starts the timer. - @return true if the action was added and performed successfully, false otherwise. + @param maxHistorySize The maximum number of items to keep in the history. */ - bool perform (UndoableAction::Ptr f); + UndoManager (int maxHistorySize); - //============================================================================== /** - @brief A type alias for an action callback function. + Creates a new UndoManager and starts the timer. - This type alias represents a std::function that takes a reference to a WeakReferenceable object - and an UndoableActionState object as parameters, and returns a boolean value. + @param actionGroupThreshold The time used to coalesce actions in the same transaction. + */ + UndoManager (RelativeTime actionGroupThreshold); + + /** + Creates a new UndoManager and starts the timer. - The callback function is used by the UndoManager to perform an undoable action on a WeakReferenceable - object. It should return true if the action was successfully performed, and false otherwise. + @param maxHistorySize The maximum number of items to keep in the history. + @param actionGroupThreshold The time used to coalesce actions in the same transaction. + */ + UndoManager (int maxHistorySize, RelativeTime actionGroupThreshold); - @tparam WeakReferenceable The type of the object that can be weakly referenced. + //============================================================================== + /** + Adds a new action to the timeline and performs its `redo` method. - @param referenceable A reference to the WeakReferenceable object on which the action should be performed. - @param actionState The state of the undoable action. + @param f The action to be performed. - @return true if the action was successfully performed, false otherwise. + @return true if the action was added and performed successfully, false otherwise. */ - template - using ActionCallback = std::function; + bool perform (UndoableAction::Ptr f); + //============================================================================== /** Adds a new action to the timeline and performs its `redo` method. @@ -92,18 +93,40 @@ class UndoManager : private Timer @tparam T The type of the object. - @param obj The object to be used in the action. + @param object The object to be used in the action. @param f The lambda function to be performed. @return true if the action was added and performed successfully, false otherwise. */ - template - bool perform (T& obj, const ActionCallback& f) + template + bool perform (T object, F&& function) { - return perform (new Item (obj, f)); + static_assert (std::is_base_of_v); + + return perform (new Item (object, std::forward (function))); } //============================================================================== + /** + Begins a new transaction. + */ + void beginNewTransaction(); + + /** + Begins a new transaction with a given name. + + @param transactionName The name of the transaction. + */ + void beginNewTransaction (StringRef transactionName); + + //============================================================================== + /** + Check if undo action can be performed. + + @return true if an undo action can be performed, false otherwise. + */ + bool canUndo() const; + /** Reverses the action in the current timeline position. @@ -111,6 +134,14 @@ class UndoManager : private Timer */ bool undo(); + //============================================================================== + /** + Check if redo action can be performed. + + @return true if a redo action can be performed, false otherwise. + */ + bool canRedo() const; + /** Performs the action in the current timeline position. @@ -164,6 +195,14 @@ class UndoManager : private Timer */ ScopedTransaction (UndoManager& undoManager); + /** + Constructs a ScopedTransaction object. + + @param undoManager The UndoManager to be used. + @param transactionName The name of the transaction. + */ + ScopedTransaction (UndoManager& undoManager, StringRef transactionName); + /** Destructs the ScopedTransaction object. */ @@ -176,9 +215,11 @@ class UndoManager : private Timer private: template struct Item : public UndoableAction - { - Item (T& obj, std::function function) - : object (std::addressof (object)) + { + using PerformCallback = std::function; + + Item (typename T::Ptr object, PerformCallback function) + : object (object) , function (std::move (function)) { jassert (function != nullptr); @@ -186,34 +227,44 @@ class UndoManager : private Timer bool perform (UndoableActionState stateToPerform) override { - if (object.wasObjectDeleted()) + if (object.wasObjectDeleted()) return false; return function (*object, stateToPerform); } - bool isValid() const override + bool isEmpty() const override { - return ! object.wasObjectDeleted(); + return !object.wasObjectDeleted(); } private: WeakReference object; - std::function function; - }; + PerformCallback function; + }; - struct CoalescedItem : public UndoableAction + struct Transaction : public UndoableAction { - using Ptr = ReferenceCountedObjectPtr; + using Ptr = ReferenceCountedObjectPtr; + + Transaction() = default; - CoalescedItem() = default; + explicit Transaction (StringRef name) + : transactionName (name) + { + } void add (UndoableAction::Ptr action); + int size() const; + + String getTransactionName() const; + void setTransactionName (StringRef newName); bool perform (UndoableActionState stateToPerform) override; - bool isValid() const override; + bool isEmpty() const override; private: + String transactionName; ReferenceCountedArray childItems; }; @@ -222,17 +273,20 @@ class UndoManager : private Timer /** @internal */ bool internalPerform (UndoableActionState stateToPerform); /** @internal */ - bool flushCurrentAction(); + bool flushCurrentTransaction(); int maxHistorySize; + RelativeTime actionGroupThreshold; UndoableAction::List undoHistory; - CoalescedItem::Ptr currentlyBuiltAction; + Transaction::Ptr currentTransaction; // the position in the timeline for the next actions. int nextUndoAction = -1; int nextRedoAction = -1; + bool isUndoEnabled = false; + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (UndoManager) }; diff --git a/modules/yup_data_model/undo/yup_UndoableAction.h b/modules/yup_data_model/undo/yup_UndoableAction.h index b7a9589d7..d9d732da8 100644 --- a/modules/yup_data_model/undo/yup_UndoableAction.h +++ b/modules/yup_data_model/undo/yup_UndoableAction.h @@ -64,7 +64,7 @@ class UndoableAction : public ReferenceCountedObject @return True if the action is valid, false otherwise. */ - virtual bool isValid() const = 0; + virtual bool isEmpty() const = 0; /** @brief Performs the undo action. diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index d551cd279..48eeaf7ca 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -40,7 +40,13 @@ set_target_properties (gmock_main PROPERTIES FOLDER "Tests") # ==== Create executable set (target_name yup_tests) set (target_version "1.0.0") -set (target_modules juce_core juce_events juce_audio_basics juce_audio_devices) +set (target_modules + juce_core + juce_events + juce_audio_basics + juce_audio_devices + yup_data_model + yup_graphics) enable_testing() diff --git a/tests/yup_data_model/yup_UndoManager.cpp b/tests/yup_data_model/yup_UndoManager.cpp new file mode 100644 index 000000000..37f8ecde6 --- /dev/null +++ b/tests/yup_data_model/yup_UndoManager.cpp @@ -0,0 +1,328 @@ +/* + ============================================================================== + + This file is part of the YUP library. + Copyright (c) 2024 - kunitoki@gmail.com + + YUP is an open source library subject to open-source licensing. + + The code included in this file is provided under the terms of the ISC license + http://www.isc.org/downloads/software-support-policy/isc-license. Permission + to use, copy, modify, and/or distribute this software for any purpose with or + without fee is hereby granted provided that the above copyright notice and + this permission notice appear in all copies. + + YUP IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +#include + +#include + +using namespace yup; + +// A simple UndoableAction class for testing purposes +class TestAction : public UndoableAction +{ +public: + using Ptr = ReferenceCountedObjectPtr; + + TestAction (bool& flag) : flag (flag) {} + + bool perform (UndoableActionState) override + { + flag = !flag; + return true; + } + + bool isEmpty() const override + { + return true; + } + +private: + bool& flag; +}; + +// A more complex UndoableAction class for additional testing purposes +class ToggleAction : public UndoableAction +{ +public: + using Ptr = ReferenceCountedObjectPtr; + + ToggleAction (int& counter) : counter (counter) {} + + bool perform (UndoableActionState state) override + { + if (state == UndoableActionState::Redo) + ++counter; + else if (state == UndoableActionState::Undo) + --counter; + + return true; + } + + bool isEmpty() const override + { + return true; + } + +private: + int& counter; +}; + +class UndoManagerTest : public ::testing::Test +{ +protected: + void SetUp() override + { + actionFlag = false; + counter = 0; + undoManager = std::make_unique (10, RelativeTime::milliseconds (0)); + } + + void TearDown() override + { + } + + bool actionFlag; + int counter; + std::unique_ptr undoManager; +}; + +TEST_F(UndoManagerTest, PerformAction) +{ + TestAction::Ptr action = new TestAction(actionFlag); + EXPECT_TRUE(undoManager->perform(action)); + EXPECT_TRUE(actionFlag); +} + +TEST_F(UndoManagerTest, UndoAction) +{ + TestAction::Ptr action = new TestAction(actionFlag); + undoManager->perform(action); + EXPECT_TRUE(actionFlag); + + EXPECT_TRUE(undoManager->undo()); + EXPECT_FALSE(actionFlag); +} + +TEST_F(UndoManagerTest, RedoAction) +{ + TestAction::Ptr action = new TestAction(actionFlag); + undoManager->perform(action); + EXPECT_TRUE(actionFlag); + + undoManager->undo(); + EXPECT_FALSE(actionFlag); + + EXPECT_TRUE(undoManager->redo()); + EXPECT_TRUE(actionFlag); +} + +TEST_F(UndoManagerTest, SetEnabled) +{ + undoManager->setEnabled(false); + EXPECT_FALSE(undoManager->isEnabled()); + + TestAction::Ptr action = new TestAction(actionFlag); + EXPECT_FALSE(undoManager->perform(action)); + EXPECT_FALSE(actionFlag); + + undoManager->setEnabled(true); + EXPECT_TRUE(undoManager->isEnabled()); + EXPECT_TRUE(undoManager->perform(action)); + EXPECT_TRUE(actionFlag); +} + +TEST_F(UndoManagerTest, ScopedTransaction) +{ + actionFlag = false; + + { + UndoManager::ScopedTransaction transaction (*undoManager); + + TestAction::Ptr action1 = new TestAction(actionFlag); + undoManager->perform(action1); + EXPECT_TRUE(actionFlag); + + TestAction::Ptr action2 = new TestAction(actionFlag); + undoManager->perform(action2); + EXPECT_FALSE(actionFlag); + } + + EXPECT_TRUE(undoManager->undo()); + EXPECT_FALSE(actionFlag); +} + +TEST_F(UndoManagerTest, PerformWithLambda) +{ + struct Object : ReferenceCountedObject + { + public: + using Ptr = ReferenceCountedObjectPtr; + + int counter = 0; + + private: + JUCE_DECLARE_WEAK_REFERENCEABLE(Object) + }; + + auto lambdaAction = [](Object::Ptr x, UndoableActionState s) -> bool + { + x->counter = (s == UndoableActionState::Undo) ? 1 : 2; + return true; + }; + + Object::Ptr x = new Object; + EXPECT_TRUE(undoManager->perform (x, lambdaAction)); + EXPECT_EQ(x->counter, 2); + + EXPECT_TRUE(undoManager->undo()); + EXPECT_EQ(x->counter, 1); + + EXPECT_TRUE(undoManager->redo()); + EXPECT_EQ(x->counter, 2); +} + +TEST_F(UndoManagerTest, ComplexPerformUndoRedo) +{ + ToggleAction::Ptr action1 = new ToggleAction(counter); + ToggleAction::Ptr action2 = new ToggleAction(counter); + + undoManager->beginNewTransaction(); + EXPECT_TRUE(undoManager->perform(action1)); + EXPECT_EQ(counter, 1); + + undoManager->beginNewTransaction(); + EXPECT_TRUE(undoManager->perform(action2)); + EXPECT_EQ(counter, 2); + + EXPECT_TRUE(undoManager->undo()); + EXPECT_EQ(counter, 1); + + EXPECT_TRUE(undoManager->undo()); + EXPECT_EQ(counter, 0); + + EXPECT_TRUE(undoManager->redo()); + EXPECT_EQ(counter, 1); + + EXPECT_TRUE(undoManager->redo()); + EXPECT_EQ(counter, 2); +} + +TEST_F(UndoManagerTest, RedoWithoutUndo) +{ + ToggleAction::Ptr action = new ToggleAction(counter); + EXPECT_TRUE(undoManager->perform(action)); + EXPECT_EQ(counter, 1); + + EXPECT_FALSE(undoManager->redo()); + EXPECT_EQ(counter, 1); +} + +TEST_F(UndoManagerTest, UndoWithoutPerform) +{ + EXPECT_FALSE(undoManager->undo()); +} + +TEST_F(UndoManagerTest, RedoAfterDisableEnable) +{ + ToggleAction::Ptr action = new ToggleAction(counter); + EXPECT_TRUE(undoManager->perform(action)); + EXPECT_EQ(counter, 1); + + undoManager->undo(); + EXPECT_EQ(counter, 0); + + undoManager->setEnabled(false); + EXPECT_FALSE(undoManager->redo()); + EXPECT_EQ(counter, 0); + + undoManager->setEnabled(true); + EXPECT_FALSE(undoManager->redo()); + EXPECT_EQ(counter, 0); +} + +TEST_F(UndoManagerTest, MaxHistorySize) +{ + undoManager = std::make_unique(2, RelativeTime::milliseconds(0)); + + ToggleAction::Ptr action1 = new ToggleAction(counter); + ToggleAction::Ptr action2 = new ToggleAction(counter); + ToggleAction::Ptr action3 = new ToggleAction(counter); + + undoManager->beginNewTransaction(); + EXPECT_TRUE(undoManager->perform(action1)); + EXPECT_EQ(counter, 1); + + undoManager->beginNewTransaction(); + EXPECT_TRUE(undoManager->perform(action2)); + EXPECT_EQ(counter, 2); + + undoManager->beginNewTransaction(); + EXPECT_TRUE(undoManager->perform(action3)); + EXPECT_EQ(counter, 3); + + EXPECT_TRUE(undoManager->undo()); + EXPECT_EQ(counter, 2); + + EXPECT_TRUE(undoManager->undo()); + EXPECT_EQ(counter, 1); + + EXPECT_FALSE(undoManager->undo()); // action1 should be removed due to max history size + EXPECT_EQ(counter, 1); +} + +TEST_F(UndoManagerTest, ScopedTransactionGrouping) +{ + { + UndoManager::ScopedTransaction transaction (*undoManager); + + ToggleAction::Ptr action1 = new ToggleAction(counter); + ToggleAction::Ptr action2 = new ToggleAction(counter); + + undoManager->perform(action1); + EXPECT_EQ(counter, 1); + + undoManager->perform(action2); + EXPECT_EQ(counter, 2); + } + + EXPECT_EQ(counter, 2); + + EXPECT_TRUE(undoManager->undo()); + EXPECT_EQ(counter, 0); +} + +TEST_F(UndoManagerTest, DISABLED_NestedScopedTransactions) +{ + { + UndoManager::ScopedTransaction transaction(*undoManager); + + ToggleAction::Ptr action1 = new ToggleAction(counter); + EXPECT_TRUE(undoManager->perform(action1)); + EXPECT_EQ(counter, 1); + + { + UndoManager::ScopedTransaction nestedTransaction(*undoManager); + + ToggleAction::Ptr action2 = new ToggleAction(counter); + EXPECT_TRUE(undoManager->perform(action2)); + EXPECT_EQ(counter, 2); + } + + ToggleAction::Ptr action3 = new ToggleAction(counter); + EXPECT_TRUE(undoManager->perform(action3)); + EXPECT_EQ(counter, 3); + } + + EXPECT_EQ(counter, 3); + + EXPECT_TRUE(undoManager->undo()); + EXPECT_EQ(counter, 0); +} From 574561481ad32788e83b3a26648365136a5901ac Mon Sep 17 00:00:00 2001 From: Yup Bot Date: Fri, 2 Aug 2024 10:43:54 +0000 Subject: [PATCH 04/22] Code formatting --- .../yup_data_model/undo/yup_UndoManager.cpp | 84 +++--- modules/yup_data_model/undo/yup_UndoManager.h | 12 +- tests/yup_data_model/yup_UndoManager.cpp | 258 +++++++++--------- 3 files changed, 179 insertions(+), 175 deletions(-) diff --git a/modules/yup_data_model/undo/yup_UndoManager.cpp b/modules/yup_data_model/undo/yup_UndoManager.cpp index eb6458b67..098e34ba2 100644 --- a/modules/yup_data_model/undo/yup_UndoManager.cpp +++ b/modules/yup_data_model/undo/yup_UndoManager.cpp @@ -97,28 +97,28 @@ UndoManager::UndoManager() : maxHistorySize (100) , actionGroupThreshold (RelativeTime::milliseconds (500)) { - setEnabled (true); + setEnabled (true); } UndoManager::UndoManager (int maxHistorySize) : maxHistorySize (maxHistorySize) , actionGroupThreshold (RelativeTime::milliseconds (500)) { - setEnabled (true); + setEnabled (true); } UndoManager::UndoManager (RelativeTime actionGroupThreshold) : maxHistorySize (100) , actionGroupThreshold (actionGroupThreshold) { - setEnabled (true); + setEnabled (true); } UndoManager::UndoManager (int maxHistorySize, RelativeTime actionGroupThreshold) : maxHistorySize (maxHistorySize) , actionGroupThreshold (actionGroupThreshold) { - setEnabled (true); + setEnabled (true); } //============================================================================== @@ -130,17 +130,17 @@ bool UndoManager::perform (UndoableAction::Ptr action) if (! isEnabled()) return false; - if (action->perform (UndoableActionState::Redo)) - { + if (action->perform (UndoableActionState::Redo)) + { if (currentTransaction == nullptr) beginNewTransaction(); - currentTransaction->add (action); + currentTransaction->add (action); - return true; - } + return true; + } - return false; + return false; } //============================================================================== @@ -165,51 +165,49 @@ void UndoManager::beginNewTransaction (StringRef transactionName) bool UndoManager::canUndo() const { - return - (currentTransaction != nullptr && ! currentTransaction->isEmpty()) + return (currentTransaction != nullptr && ! currentTransaction->isEmpty()) || isPositiveAndBelow (nextUndoAction, undoHistory.size()); } bool UndoManager::undo() { - return internalPerform (UndoableActionState::Undo); + return internalPerform (UndoableActionState::Undo); } bool UndoManager::canRedo() const { - return - (currentTransaction != nullptr && ! currentTransaction->isEmpty()) + return (currentTransaction != nullptr && ! currentTransaction->isEmpty()) || isPositiveAndBelow (nextRedoAction, undoHistory.size()); } bool UndoManager::redo() { - return internalPerform (UndoableActionState::Redo); + return internalPerform (UndoableActionState::Redo); } //============================================================================== void UndoManager::setEnabled (bool shouldBeEnabled) { - if (isEnabled() != shouldBeEnabled) - { + if (isEnabled() != shouldBeEnabled) + { isUndoEnabled = shouldBeEnabled; - if (shouldBeEnabled) - { + if (shouldBeEnabled) + { if (actionGroupThreshold > RelativeTime()) startTimer (static_cast (actionGroupThreshold.inMilliseconds())); - } - else - { + } + else + { if (actionGroupThreshold > RelativeTime()) stopTimer(); flushCurrentTransaction(); - undoHistory.clear(); - } - } + undoHistory.clear(); + } + } } bool UndoManager::isEnabled() const @@ -221,17 +219,17 @@ bool UndoManager::isEnabled() const void UndoManager::timerCallback() { - beginNewTransaction(); + beginNewTransaction(); } //============================================================================== bool UndoManager::internalPerform (UndoableActionState stateToPerform) { - flushCurrentTransaction(); + flushCurrentTransaction(); - auto actionIndex = (stateToPerform == UndoableActionState::Undo) ? nextUndoAction : nextRedoAction; - if (! isPositiveAndBelow(actionIndex, undoHistory.size())) + auto actionIndex = (stateToPerform == UndoableActionState::Undo) ? nextUndoAction : nextRedoAction; + if (! isPositiveAndBelow (actionIndex, undoHistory.size())) return false; auto current = undoHistory[actionIndex]; @@ -253,25 +251,25 @@ bool UndoManager::internalPerform (UndoableActionState stateToPerform) bool UndoManager::flushCurrentTransaction() { - if (currentTransaction == nullptr || currentTransaction->isEmpty()) - return false; + if (currentTransaction == nullptr || currentTransaction->isEmpty()) + return false; - // Remove all future actions - if (nextRedoAction < undoHistory.size()) - undoHistory.removeRange (nextRedoAction, undoHistory.size() - nextRedoAction); + // Remove all future actions + if (nextRedoAction < undoHistory.size()) + undoHistory.removeRange (nextRedoAction, undoHistory.size() - nextRedoAction); - undoHistory.add (currentTransaction.get()); + undoHistory.add (currentTransaction.get()); currentTransaction = nullptr; - // Clean up to keep the undo history in check - const int numToRemove = jmax (0, undoHistory.size() - maxHistorySize); - if (numToRemove > 0) - undoHistory.removeRange (0, numToRemove); + // Clean up to keep the undo history in check + const int numToRemove = jmax (0, undoHistory.size() - maxHistorySize); + if (numToRemove > 0) + undoHistory.removeRange (0, numToRemove); - nextUndoAction = undoHistory.size() - 1; - nextRedoAction = undoHistory.size(); + nextUndoAction = undoHistory.size() - 1; + nextRedoAction = undoHistory.size(); - return true; + return true; } } // namespace yup diff --git a/modules/yup_data_model/undo/yup_UndoManager.h b/modules/yup_data_model/undo/yup_UndoManager.h index 74297edcb..31b67ce51 100644 --- a/modules/yup_data_model/undo/yup_UndoManager.h +++ b/modules/yup_data_model/undo/yup_UndoManager.h @@ -215,8 +215,8 @@ class UndoManager : private Timer private: template struct Item : public UndoableAction - { - using PerformCallback = std::function; + { + using PerformCallback = std::function; Item (typename T::Ptr object, PerformCallback function) : object (object) @@ -227,7 +227,7 @@ class UndoManager : private Timer bool perform (UndoableActionState stateToPerform) override { - if (object.wasObjectDeleted()) + if (object.wasObjectDeleted()) return false; return function (*object, stateToPerform); @@ -235,13 +235,13 @@ class UndoManager : private Timer bool isEmpty() const override { - return !object.wasObjectDeleted(); + return ! object.wasObjectDeleted(); } private: WeakReference object; - PerformCallback function; - }; + PerformCallback function; + }; struct Transaction : public UndoableAction { diff --git a/tests/yup_data_model/yup_UndoManager.cpp b/tests/yup_data_model/yup_UndoManager.cpp index 37f8ecde6..f8ead3d85 100644 --- a/tests/yup_data_model/yup_UndoManager.cpp +++ b/tests/yup_data_model/yup_UndoManager.cpp @@ -31,11 +31,14 @@ class TestAction : public UndoableAction public: using Ptr = ReferenceCountedObjectPtr; - TestAction (bool& flag) : flag (flag) {} + TestAction (bool& flag) + : flag (flag) + { + } bool perform (UndoableActionState) override { - flag = !flag; + flag = ! flag; return true; } @@ -54,7 +57,10 @@ class ToggleAction : public UndoableAction public: using Ptr = ReferenceCountedObjectPtr; - ToggleAction (int& counter) : counter (counter) {} + ToggleAction (int& counter) + : counter (counter) + { + } bool perform (UndoableActionState state) override { @@ -94,72 +100,72 @@ class UndoManagerTest : public ::testing::Test std::unique_ptr undoManager; }; -TEST_F(UndoManagerTest, PerformAction) +TEST_F (UndoManagerTest, PerformAction) { - TestAction::Ptr action = new TestAction(actionFlag); - EXPECT_TRUE(undoManager->perform(action)); - EXPECT_TRUE(actionFlag); + TestAction::Ptr action = new TestAction (actionFlag); + EXPECT_TRUE (undoManager->perform (action)); + EXPECT_TRUE (actionFlag); } -TEST_F(UndoManagerTest, UndoAction) +TEST_F (UndoManagerTest, UndoAction) { - TestAction::Ptr action = new TestAction(actionFlag); - undoManager->perform(action); - EXPECT_TRUE(actionFlag); + TestAction::Ptr action = new TestAction (actionFlag); + undoManager->perform (action); + EXPECT_TRUE (actionFlag); - EXPECT_TRUE(undoManager->undo()); - EXPECT_FALSE(actionFlag); + EXPECT_TRUE (undoManager->undo()); + EXPECT_FALSE (actionFlag); } -TEST_F(UndoManagerTest, RedoAction) +TEST_F (UndoManagerTest, RedoAction) { - TestAction::Ptr action = new TestAction(actionFlag); - undoManager->perform(action); - EXPECT_TRUE(actionFlag); + TestAction::Ptr action = new TestAction (actionFlag); + undoManager->perform (action); + EXPECT_TRUE (actionFlag); undoManager->undo(); - EXPECT_FALSE(actionFlag); + EXPECT_FALSE (actionFlag); - EXPECT_TRUE(undoManager->redo()); - EXPECT_TRUE(actionFlag); + EXPECT_TRUE (undoManager->redo()); + EXPECT_TRUE (actionFlag); } -TEST_F(UndoManagerTest, SetEnabled) +TEST_F (UndoManagerTest, SetEnabled) { - undoManager->setEnabled(false); - EXPECT_FALSE(undoManager->isEnabled()); + undoManager->setEnabled (false); + EXPECT_FALSE (undoManager->isEnabled()); - TestAction::Ptr action = new TestAction(actionFlag); - EXPECT_FALSE(undoManager->perform(action)); - EXPECT_FALSE(actionFlag); + TestAction::Ptr action = new TestAction (actionFlag); + EXPECT_FALSE (undoManager->perform (action)); + EXPECT_FALSE (actionFlag); - undoManager->setEnabled(true); - EXPECT_TRUE(undoManager->isEnabled()); - EXPECT_TRUE(undoManager->perform(action)); - EXPECT_TRUE(actionFlag); + undoManager->setEnabled (true); + EXPECT_TRUE (undoManager->isEnabled()); + EXPECT_TRUE (undoManager->perform (action)); + EXPECT_TRUE (actionFlag); } -TEST_F(UndoManagerTest, ScopedTransaction) +TEST_F (UndoManagerTest, ScopedTransaction) { actionFlag = false; { UndoManager::ScopedTransaction transaction (*undoManager); - TestAction::Ptr action1 = new TestAction(actionFlag); - undoManager->perform(action1); - EXPECT_TRUE(actionFlag); + TestAction::Ptr action1 = new TestAction (actionFlag); + undoManager->perform (action1); + EXPECT_TRUE (actionFlag); - TestAction::Ptr action2 = new TestAction(actionFlag); - undoManager->perform(action2); - EXPECT_FALSE(actionFlag); + TestAction::Ptr action2 = new TestAction (actionFlag); + undoManager->perform (action2); + EXPECT_FALSE (actionFlag); } - EXPECT_TRUE(undoManager->undo()); - EXPECT_FALSE(actionFlag); + EXPECT_TRUE (undoManager->undo()); + EXPECT_FALSE (actionFlag); } -TEST_F(UndoManagerTest, PerformWithLambda) +TEST_F (UndoManagerTest, PerformWithLambda) { struct Object : ReferenceCountedObject { @@ -169,160 +175,160 @@ TEST_F(UndoManagerTest, PerformWithLambda) int counter = 0; private: - JUCE_DECLARE_WEAK_REFERENCEABLE(Object) + JUCE_DECLARE_WEAK_REFERENCEABLE (Object) }; - auto lambdaAction = [](Object::Ptr x, UndoableActionState s) -> bool + auto lambdaAction = [] (Object::Ptr x, UndoableActionState s) -> bool { x->counter = (s == UndoableActionState::Undo) ? 1 : 2; return true; }; Object::Ptr x = new Object; - EXPECT_TRUE(undoManager->perform (x, lambdaAction)); - EXPECT_EQ(x->counter, 2); + EXPECT_TRUE (undoManager->perform (x, lambdaAction)); + EXPECT_EQ (x->counter, 2); - EXPECT_TRUE(undoManager->undo()); - EXPECT_EQ(x->counter, 1); + EXPECT_TRUE (undoManager->undo()); + EXPECT_EQ (x->counter, 1); - EXPECT_TRUE(undoManager->redo()); - EXPECT_EQ(x->counter, 2); + EXPECT_TRUE (undoManager->redo()); + EXPECT_EQ (x->counter, 2); } -TEST_F(UndoManagerTest, ComplexPerformUndoRedo) +TEST_F (UndoManagerTest, ComplexPerformUndoRedo) { - ToggleAction::Ptr action1 = new ToggleAction(counter); - ToggleAction::Ptr action2 = new ToggleAction(counter); + ToggleAction::Ptr action1 = new ToggleAction (counter); + ToggleAction::Ptr action2 = new ToggleAction (counter); undoManager->beginNewTransaction(); - EXPECT_TRUE(undoManager->perform(action1)); - EXPECT_EQ(counter, 1); + EXPECT_TRUE (undoManager->perform (action1)); + EXPECT_EQ (counter, 1); undoManager->beginNewTransaction(); - EXPECT_TRUE(undoManager->perform(action2)); - EXPECT_EQ(counter, 2); + EXPECT_TRUE (undoManager->perform (action2)); + EXPECT_EQ (counter, 2); - EXPECT_TRUE(undoManager->undo()); - EXPECT_EQ(counter, 1); + EXPECT_TRUE (undoManager->undo()); + EXPECT_EQ (counter, 1); - EXPECT_TRUE(undoManager->undo()); - EXPECT_EQ(counter, 0); + EXPECT_TRUE (undoManager->undo()); + EXPECT_EQ (counter, 0); - EXPECT_TRUE(undoManager->redo()); - EXPECT_EQ(counter, 1); + EXPECT_TRUE (undoManager->redo()); + EXPECT_EQ (counter, 1); - EXPECT_TRUE(undoManager->redo()); - EXPECT_EQ(counter, 2); + EXPECT_TRUE (undoManager->redo()); + EXPECT_EQ (counter, 2); } -TEST_F(UndoManagerTest, RedoWithoutUndo) +TEST_F (UndoManagerTest, RedoWithoutUndo) { - ToggleAction::Ptr action = new ToggleAction(counter); - EXPECT_TRUE(undoManager->perform(action)); - EXPECT_EQ(counter, 1); + ToggleAction::Ptr action = new ToggleAction (counter); + EXPECT_TRUE (undoManager->perform (action)); + EXPECT_EQ (counter, 1); - EXPECT_FALSE(undoManager->redo()); - EXPECT_EQ(counter, 1); + EXPECT_FALSE (undoManager->redo()); + EXPECT_EQ (counter, 1); } -TEST_F(UndoManagerTest, UndoWithoutPerform) +TEST_F (UndoManagerTest, UndoWithoutPerform) { - EXPECT_FALSE(undoManager->undo()); + EXPECT_FALSE (undoManager->undo()); } -TEST_F(UndoManagerTest, RedoAfterDisableEnable) +TEST_F (UndoManagerTest, RedoAfterDisableEnable) { - ToggleAction::Ptr action = new ToggleAction(counter); - EXPECT_TRUE(undoManager->perform(action)); - EXPECT_EQ(counter, 1); + ToggleAction::Ptr action = new ToggleAction (counter); + EXPECT_TRUE (undoManager->perform (action)); + EXPECT_EQ (counter, 1); undoManager->undo(); - EXPECT_EQ(counter, 0); + EXPECT_EQ (counter, 0); - undoManager->setEnabled(false); - EXPECT_FALSE(undoManager->redo()); - EXPECT_EQ(counter, 0); + undoManager->setEnabled (false); + EXPECT_FALSE (undoManager->redo()); + EXPECT_EQ (counter, 0); - undoManager->setEnabled(true); - EXPECT_FALSE(undoManager->redo()); - EXPECT_EQ(counter, 0); + undoManager->setEnabled (true); + EXPECT_FALSE (undoManager->redo()); + EXPECT_EQ (counter, 0); } -TEST_F(UndoManagerTest, MaxHistorySize) +TEST_F (UndoManagerTest, MaxHistorySize) { - undoManager = std::make_unique(2, RelativeTime::milliseconds(0)); + undoManager = std::make_unique (2, RelativeTime::milliseconds (0)); - ToggleAction::Ptr action1 = new ToggleAction(counter); - ToggleAction::Ptr action2 = new ToggleAction(counter); - ToggleAction::Ptr action3 = new ToggleAction(counter); + ToggleAction::Ptr action1 = new ToggleAction (counter); + ToggleAction::Ptr action2 = new ToggleAction (counter); + ToggleAction::Ptr action3 = new ToggleAction (counter); undoManager->beginNewTransaction(); - EXPECT_TRUE(undoManager->perform(action1)); - EXPECT_EQ(counter, 1); + EXPECT_TRUE (undoManager->perform (action1)); + EXPECT_EQ (counter, 1); undoManager->beginNewTransaction(); - EXPECT_TRUE(undoManager->perform(action2)); - EXPECT_EQ(counter, 2); + EXPECT_TRUE (undoManager->perform (action2)); + EXPECT_EQ (counter, 2); undoManager->beginNewTransaction(); - EXPECT_TRUE(undoManager->perform(action3)); - EXPECT_EQ(counter, 3); + EXPECT_TRUE (undoManager->perform (action3)); + EXPECT_EQ (counter, 3); - EXPECT_TRUE(undoManager->undo()); - EXPECT_EQ(counter, 2); + EXPECT_TRUE (undoManager->undo()); + EXPECT_EQ (counter, 2); - EXPECT_TRUE(undoManager->undo()); - EXPECT_EQ(counter, 1); + EXPECT_TRUE (undoManager->undo()); + EXPECT_EQ (counter, 1); - EXPECT_FALSE(undoManager->undo()); // action1 should be removed due to max history size - EXPECT_EQ(counter, 1); + EXPECT_FALSE (undoManager->undo()); // action1 should be removed due to max history size + EXPECT_EQ (counter, 1); } -TEST_F(UndoManagerTest, ScopedTransactionGrouping) +TEST_F (UndoManagerTest, ScopedTransactionGrouping) { { UndoManager::ScopedTransaction transaction (*undoManager); - ToggleAction::Ptr action1 = new ToggleAction(counter); - ToggleAction::Ptr action2 = new ToggleAction(counter); - - undoManager->perform(action1); - EXPECT_EQ(counter, 1); - - undoManager->perform(action2); - EXPECT_EQ(counter, 2); + ToggleAction::Ptr action1 = new ToggleAction (counter); + ToggleAction::Ptr action2 = new ToggleAction (counter); + + undoManager->perform (action1); + EXPECT_EQ (counter, 1); + + undoManager->perform (action2); + EXPECT_EQ (counter, 2); } - EXPECT_EQ(counter, 2); + EXPECT_EQ (counter, 2); - EXPECT_TRUE(undoManager->undo()); - EXPECT_EQ(counter, 0); + EXPECT_TRUE (undoManager->undo()); + EXPECT_EQ (counter, 0); } -TEST_F(UndoManagerTest, DISABLED_NestedScopedTransactions) +TEST_F (UndoManagerTest, DISABLED_NestedScopedTransactions) { { - UndoManager::ScopedTransaction transaction(*undoManager); + UndoManager::ScopedTransaction transaction (*undoManager); - ToggleAction::Ptr action1 = new ToggleAction(counter); - EXPECT_TRUE(undoManager->perform(action1)); - EXPECT_EQ(counter, 1); + ToggleAction::Ptr action1 = new ToggleAction (counter); + EXPECT_TRUE (undoManager->perform (action1)); + EXPECT_EQ (counter, 1); { - UndoManager::ScopedTransaction nestedTransaction(*undoManager); + UndoManager::ScopedTransaction nestedTransaction (*undoManager); - ToggleAction::Ptr action2 = new ToggleAction(counter); - EXPECT_TRUE(undoManager->perform(action2)); - EXPECT_EQ(counter, 2); + ToggleAction::Ptr action2 = new ToggleAction (counter); + EXPECT_TRUE (undoManager->perform (action2)); + EXPECT_EQ (counter, 2); } - ToggleAction::Ptr action3 = new ToggleAction(counter); - EXPECT_TRUE(undoManager->perform(action3)); - EXPECT_EQ(counter, 3); + ToggleAction::Ptr action3 = new ToggleAction (counter); + EXPECT_TRUE (undoManager->perform (action3)); + EXPECT_EQ (counter, 3); } - EXPECT_EQ(counter, 3); + EXPECT_EQ (counter, 3); - EXPECT_TRUE(undoManager->undo()); - EXPECT_EQ(counter, 0); + EXPECT_TRUE (undoManager->undo()); + EXPECT_EQ (counter, 0); } From b4c98a2f96c8744121a6d27de8579b8663d4bdf1 Mon Sep 17 00:00:00 2001 From: kunitoki Date: Fri, 2 Aug 2024 12:46:51 +0200 Subject: [PATCH 05/22] More stuff in undo manager --- modules/yup_data_model/undo/yup_UndoManager.cpp | 5 +++++ modules/yup_data_model/undo/yup_UndoManager.h | 6 +----- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/modules/yup_data_model/undo/yup_UndoManager.cpp b/modules/yup_data_model/undo/yup_UndoManager.cpp index 098e34ba2..de2fa5088 100644 --- a/modules/yup_data_model/undo/yup_UndoManager.cpp +++ b/modules/yup_data_model/undo/yup_UndoManager.cpp @@ -24,6 +24,11 @@ namespace yup //============================================================================== +UndoManager::Transaction::Transaction (StringRef name) + : transactionName (name) +{ +} + void UndoManager::Transaction::add (UndoableAction::Ptr action) { if (action != nullptr) diff --git a/modules/yup_data_model/undo/yup_UndoManager.h b/modules/yup_data_model/undo/yup_UndoManager.h index 31b67ce51..672246b15 100644 --- a/modules/yup_data_model/undo/yup_UndoManager.h +++ b/modules/yup_data_model/undo/yup_UndoManager.h @@ -248,11 +248,7 @@ class UndoManager : private Timer using Ptr = ReferenceCountedObjectPtr; Transaction() = default; - - explicit Transaction (StringRef name) - : transactionName (name) - { - } + explicit Transaction (StringRef name); void add (UndoableAction::Ptr action); int size() const; From 2fa5707d39a1095d780c0d7b658ab47489e126b6 Mon Sep 17 00:00:00 2001 From: kunitoki Date: Mon, 19 Aug 2024 22:45:01 +0200 Subject: [PATCH 06/22] Improved transaction management --- .../yup_data_model/undo/yup_UndoManager.cpp | 60 ++++++++++-- modules/yup_data_model/undo/yup_UndoManager.h | 19 +++- .../yup_data_model/undo/yup_UndoableAction.h | 4 +- tests/yup_data_model/yup_UndoManager.cpp | 93 ++++++++++++++++++- 4 files changed, 161 insertions(+), 15 deletions(-) diff --git a/modules/yup_data_model/undo/yup_UndoManager.cpp b/modules/yup_data_model/undo/yup_UndoManager.cpp index de2fa5088..c9066ff0e 100644 --- a/modules/yup_data_model/undo/yup_UndoManager.cpp +++ b/modules/yup_data_model/undo/yup_UndoManager.cpp @@ -69,12 +69,12 @@ bool UndoManager::Transaction::perform (UndoableActionState stateToPerform) } } - return ! isEmpty(); + return isValid(); } -bool UndoManager::Transaction::isEmpty() const +bool UndoManager::Transaction::isValid() const { - return childItems.isEmpty(); + return ! childItems.isEmpty(); } //============================================================================== @@ -162,15 +162,50 @@ void UndoManager::beginNewTransaction (StringRef transactionName) if (currentTransaction == nullptr) currentTransaction = new Transaction (transactionName); - else if (currentTransaction->isEmpty()) + else if (currentTransaction->isValid()) currentTransaction->setTransactionName (transactionName); } //============================================================================== +int UndoManager::getNumTransactions() const +{ + return undoHistory.size() + (currentTransaction != nullptr ? 1 : 0); +} + +String UndoManager::getTransactionName (int index) const +{ + if (isPositiveAndBelow (index, getNumTransactions ())) + { + if (isPositiveAndBelow (index, undoHistory.size())) + return undoHistory.getUnchecked (index)->getTransactionName(); + + else if (currentTransaction != nullptr) + return currentTransaction->getTransactionName(); + } + + return {}; +} + +String UndoManager::getCurrentTransactionName() const +{ + if (currentTransaction != nullptr) + return currentTransaction->getTransactionName(); + + return {}; +} + +void UndoManager::setCurrentTransactionName (StringRef newName) +{ + if (currentTransaction != nullptr) + currentTransaction->setTransactionName (newName); +} + +//============================================================================== + bool UndoManager::canUndo() const { - return (currentTransaction != nullptr && ! currentTransaction->isEmpty()) + return (currentTransaction != nullptr && currentTransaction->isValid()) || isPositiveAndBelow (nextUndoAction, undoHistory.size()); } @@ -181,7 +216,7 @@ bool UndoManager::undo() bool UndoManager::canRedo() const { - return (currentTransaction != nullptr && ! currentTransaction->isEmpty()) + return (currentTransaction != nullptr && currentTransaction->isValid()) || isPositiveAndBelow (nextRedoAction, undoHistory.size()); } @@ -192,6 +227,17 @@ bool UndoManager::redo() //============================================================================== +void UndoManager::clear() +{ + nextUndoAction = -1; + nextRedoAction = -1; + + undoHistory.clearQuick(); + currentTransaction.reset(); +} + +//============================================================================== + void UndoManager::setEnabled (bool shouldBeEnabled) { if (isEnabled() != shouldBeEnabled) @@ -256,7 +302,7 @@ bool UndoManager::internalPerform (UndoableActionState stateToPerform) bool UndoManager::flushCurrentTransaction() { - if (currentTransaction == nullptr || currentTransaction->isEmpty()) + if (currentTransaction == nullptr || ! currentTransaction->isValid()) return false; // Remove all future actions diff --git a/modules/yup_data_model/undo/yup_UndoManager.h b/modules/yup_data_model/undo/yup_UndoManager.h index 672246b15..a1fa5716a 100644 --- a/modules/yup_data_model/undo/yup_UndoManager.h +++ b/modules/yup_data_model/undo/yup_UndoManager.h @@ -119,6 +119,13 @@ class UndoManager : private Timer */ void beginNewTransaction (StringRef transactionName); + //============================================================================== + int getNumTransactions() const; + String getTransactionName (int index) const; + + String getCurrentTransactionName() const; + void setCurrentTransactionName (StringRef newName); + //============================================================================== /** Check if undo action can be performed. @@ -149,6 +156,9 @@ class UndoManager : private Timer */ bool redo(); + //============================================================================== + void clear(); + //============================================================================== /** Enables or disables the undo manager. @@ -233,7 +243,7 @@ class UndoManager : private Timer return function (*object, stateToPerform); } - bool isEmpty() const override + bool isValid() const override { return ! object.wasObjectDeleted(); } @@ -245,6 +255,7 @@ class UndoManager : private Timer struct Transaction : public UndoableAction { + using Array = ReferenceCountedArray; using Ptr = ReferenceCountedObjectPtr; Transaction() = default; @@ -257,11 +268,11 @@ class UndoManager : private Timer void setTransactionName (StringRef newName); bool perform (UndoableActionState stateToPerform) override; - bool isEmpty() const override; + bool isValid() const override; private: String transactionName; - ReferenceCountedArray childItems; + UndoableAction::Array childItems; }; /** @internal */ @@ -274,7 +285,7 @@ class UndoManager : private Timer int maxHistorySize; RelativeTime actionGroupThreshold; - UndoableAction::List undoHistory; + Transaction::Array undoHistory; Transaction::Ptr currentTransaction; // the position in the timeline for the next actions. diff --git a/modules/yup_data_model/undo/yup_UndoableAction.h b/modules/yup_data_model/undo/yup_UndoableAction.h index d9d732da8..3949f1c7d 100644 --- a/modules/yup_data_model/undo/yup_UndoableAction.h +++ b/modules/yup_data_model/undo/yup_UndoableAction.h @@ -49,7 +49,7 @@ enum class UndoableActionState class UndoableAction : public ReferenceCountedObject { public: - using List = ReferenceCountedArray; + using Array = ReferenceCountedArray; using Ptr = ReferenceCountedObjectPtr; /** @@ -64,7 +64,7 @@ class UndoableAction : public ReferenceCountedObject @return True if the action is valid, false otherwise. */ - virtual bool isEmpty() const = 0; + virtual bool isValid() const = 0; /** @brief Performs the undo action. diff --git a/tests/yup_data_model/yup_UndoManager.cpp b/tests/yup_data_model/yup_UndoManager.cpp index f8ead3d85..85ed049bd 100644 --- a/tests/yup_data_model/yup_UndoManager.cpp +++ b/tests/yup_data_model/yup_UndoManager.cpp @@ -42,7 +42,7 @@ class TestAction : public UndoableAction return true; } - bool isEmpty() const override + bool isValid() const override { return true; } @@ -72,7 +72,7 @@ class ToggleAction : public UndoableAction return true; } - bool isEmpty() const override + bool isValid() const override { return true; } @@ -117,6 +117,69 @@ TEST_F (UndoManagerTest, UndoAction) EXPECT_FALSE (actionFlag); } +TEST_F (UndoManagerTest, TransactionCount) +{ + actionFlag = false; + + EXPECT_EQ (undoManager->getNumTransactions(), 0); + + { + undoManager->beginNewTransaction(); + EXPECT_EQ (undoManager->getNumTransactions(), 1); + + undoManager->perform (new TestAction (actionFlag)); + EXPECT_EQ (undoManager->getNumTransactions(), 1); + } + + { + undoManager->beginNewTransaction(); + EXPECT_EQ (undoManager->getNumTransactions(), 2); + + undoManager->perform (new TestAction (actionFlag)); + EXPECT_EQ (undoManager->getNumTransactions(), 2); + } + + EXPECT_TRUE (undoManager->undo()); + EXPECT_EQ (undoManager->getNumTransactions(), 2); + + EXPECT_TRUE (undoManager->undo()); + EXPECT_EQ (undoManager->getNumTransactions(), 2); + + EXPECT_FALSE (undoManager->undo()); + EXPECT_EQ (undoManager->getNumTransactions(), 2); + + undoManager->clear(); + EXPECT_EQ (undoManager->getNumTransactions(), 0); +} + +TEST_F (UndoManagerTest, TransactionIteration) +{ + actionFlag = false; + + EXPECT_EQ (undoManager->getNumTransactions(), 0); + + { + undoManager->beginNewTransaction ("1"); + EXPECT_EQ (undoManager->getNumTransactions(), 1); + undoManager->perform (new TestAction (actionFlag)); + EXPECT_EQ (undoManager->getNumTransactions(), 1); + undoManager->perform (new TestAction (actionFlag)); + EXPECT_EQ (undoManager->getNumTransactions(), 1); + } + + { + undoManager->beginNewTransaction ("2"); + EXPECT_EQ (undoManager->getNumTransactions(), 2); + undoManager->perform (new TestAction (actionFlag)); + EXPECT_EQ (undoManager->getNumTransactions(), 2); + undoManager->perform (new TestAction (actionFlag)); + EXPECT_EQ (undoManager->getNumTransactions(), 2); + } + + EXPECT_EQ (juce::String ("1"), undoManager->getTransactionName (0)); + EXPECT_EQ (juce::String ("2"), undoManager->getTransactionName (1)); +} + TEST_F (UndoManagerTest, RedoAction) { TestAction::Ptr action = new TestAction (actionFlag); @@ -165,6 +228,32 @@ TEST_F (UndoManagerTest, ScopedTransaction) EXPECT_FALSE (actionFlag); } +TEST_F (UndoManagerTest, ScopedTransactionWithName) +{ + actionFlag = false; + + EXPECT_EQ (undoManager->getCurrentTransactionName(), ""); + + { + UndoManager::ScopedTransaction transaction (*undoManager, "custom name"); + + TestAction::Ptr action1 = new TestAction (actionFlag); + undoManager->perform (action1); + EXPECT_TRUE (actionFlag); + + TestAction::Ptr action2 = new TestAction (actionFlag); + undoManager->perform (action2); + EXPECT_FALSE (actionFlag); + + EXPECT_EQ (undoManager->getCurrentTransactionName(), "custom name"); + } + + EXPECT_TRUE (undoManager->undo()); + EXPECT_FALSE (actionFlag); + + EXPECT_EQ (undoManager->getCurrentTransactionName(), ""); +} + TEST_F (UndoManagerTest, PerformWithLambda) { struct Object : ReferenceCountedObject From 1c35d09fee005d3c660aa921f479230fdcc2eaa1 Mon Sep 17 00:00:00 2001 From: Yup Bot Date: Mon, 19 Aug 2024 20:45:34 +0000 Subject: [PATCH 07/22] Code formatting --- modules/yup_data_model/undo/yup_UndoManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/yup_data_model/undo/yup_UndoManager.cpp b/modules/yup_data_model/undo/yup_UndoManager.cpp index c9066ff0e..7958379d5 100644 --- a/modules/yup_data_model/undo/yup_UndoManager.cpp +++ b/modules/yup_data_model/undo/yup_UndoManager.cpp @@ -175,7 +175,7 @@ int UndoManager::getNumTransactions() const String UndoManager::getTransactionName (int index) const { - if (isPositiveAndBelow (index, getNumTransactions ())) + if (isPositiveAndBelow (index, getNumTransactions())) { if (isPositiveAndBelow (index, undoHistory.size())) return undoHistory.getUnchecked (index)->getTransactionName(); From 67f67ee0cb0ee61156f5d789d62a7c8f59135cec Mon Sep 17 00:00:00 2001 From: kunitoki Date: Mon, 19 Aug 2024 23:14:43 +0200 Subject: [PATCH 08/22] Improved doxygen --- .../yup_data_model/undo/yup_UndoManager.cpp | 2 ++ modules/yup_data_model/undo/yup_UndoManager.h | 31 ++++++++++++++++++- .../yup_data_model/undo/yup_UndoableAction.h | 5 +-- 3 files changed, 35 insertions(+), 3 deletions(-) diff --git a/modules/yup_data_model/undo/yup_UndoManager.cpp b/modules/yup_data_model/undo/yup_UndoManager.cpp index 7958379d5..452d3d995 100644 --- a/modules/yup_data_model/undo/yup_UndoManager.cpp +++ b/modules/yup_data_model/undo/yup_UndoManager.cpp @@ -187,6 +187,8 @@ String UndoManager::getTransactionName (int index) const return {}; } +//============================================================================== + String UndoManager::getCurrentTransactionName() const { if (currentTransaction != nullptr) diff --git a/modules/yup_data_model/undo/yup_UndoManager.h b/modules/yup_data_model/undo/yup_UndoManager.h index a1fa5716a..3c05f289a 100644 --- a/modules/yup_data_model/undo/yup_UndoManager.h +++ b/modules/yup_data_model/undo/yup_UndoManager.h @@ -26,7 +26,7 @@ namespace yup /** @class UndoManager - @brief Manages undo and redo functionality for a set of actions. + Manages undo and redo functionality for a set of actions. The UndoManager class provides a way to manage undo and redo functionality for a set of actions. It allows you to perform actions, undo them, redo them, @@ -120,10 +120,34 @@ class UndoManager : private Timer void beginNewTransaction (StringRef transactionName); //============================================================================== + /** + Returns the number of transactions in the undo manager. + + @return The number of transactions. + */ int getNumTransactions() const; + + /** Retrieves the name of a transaction at the specified index. + + @param index The index of the transaction. + + @return The name of the transaction. + */ String getTransactionName (int index) const; + //============================================================================== + /** + Returns the name of the current transaction. + + @return The name of the current transaction as a String. + */ String getCurrentTransactionName() const; + + /** + Sets the name of the current transaction. + + @param newName the new name for the transaction + */ void setCurrentTransactionName (StringRef newName); //============================================================================== @@ -157,6 +181,11 @@ class UndoManager : private Timer bool redo(); //============================================================================== + /** + @brief Clears the undo manager. + + This function clears the undo manager, removing all the stored undo/redo actions. + */ void clear(); //============================================================================== diff --git a/modules/yup_data_model/undo/yup_UndoableAction.h b/modules/yup_data_model/undo/yup_UndoableAction.h index 3949f1c7d..cc5973d91 100644 --- a/modules/yup_data_model/undo/yup_UndoableAction.h +++ b/modules/yup_data_model/undo/yup_UndoableAction.h @@ -30,7 +30,7 @@ namespace yup The ActionState enum is used to indicate whether an action should be undone or redone. - @see yup_UndoManager + @see UndoManager */ enum class UndoableActionState { @@ -41,7 +41,8 @@ enum class UndoableActionState //============================================================================== /** @class UndoableAction - @brief The base class for all actions in the timeline. + + The base class for all actions in the timeline. You can subclass from this class to define your actions, but a better way is to just use a lambda with a WeakReferenceable object. From 134918a7d033a993c0837684a1493299329dad6d Mon Sep 17 00:00:00 2001 From: kunitoki Date: Tue, 20 Aug 2024 23:18:32 +0200 Subject: [PATCH 09/22] Fix tests --- modules/yup_graphics/yup_graphics.h | 4 +-- modules/yup_gui/yup_gui.cpp | 8 ----- modules/yup_gui/yup_gui.h | 4 +-- tests/CMakeLists.txt | 3 +- thirdparty/rive/rive.h | 34 +++++++++++++------ .../rive_pls_renderer/rive_pls_renderer.h | 12 ++++++- 6 files changed, 37 insertions(+), 28 deletions(-) diff --git a/modules/yup_graphics/yup_graphics.h b/modules/yup_graphics/yup_graphics.h index 4d4690131..cc49ea49a 100644 --- a/modules/yup_graphics/yup_graphics.h +++ b/modules/yup_graphics/yup_graphics.h @@ -50,9 +50,7 @@ #include #include -#include - -#include +#include #include diff --git a/modules/yup_gui/yup_gui.cpp b/modules/yup_gui/yup_gui.cpp index 683be22db..93a200958 100644 --- a/modules/yup_gui/yup_gui.cpp +++ b/modules/yup_gui/yup_gui.cpp @@ -52,14 +52,6 @@ #include #endif -//============================================================================== -#include -#include -#include -#include -#include -#include - //============================================================================== #include "native/yup_Windowing_glfw.cpp" diff --git a/modules/yup_gui/yup_gui.h b/modules/yup_gui/yup_gui.h index 5ce681c21..9f514bfa7 100644 --- a/modules/yup_gui/yup_gui.h +++ b/modules/yup_gui/yup_gui.h @@ -51,9 +51,7 @@ #include #include -#include -#include -#include +#include //============================================================================== diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 48eeaf7ca..51713b939 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -45,8 +45,7 @@ set (target_modules juce_events juce_audio_basics juce_audio_devices - yup_data_model - yup_graphics) + yup_data_model) enable_testing() diff --git a/thirdparty/rive/rive.h b/thirdparty/rive/rive.h index 3bd2c68e9..2df2f7d02 100644 --- a/thirdparty/rive/rive.h +++ b/thirdparty/rive/rive.h @@ -24,17 +24,18 @@ BEGIN_JUCE_MODULE_DECLARATION - ID: rive - vendor: rive - version: 1.0 - name: Rive C++ is a runtime library for Rive. - description: Rive C++ is a runtime library for Rive, a real-time interactive design and animation tool. - website: https://github.com/rive-app/rive-cpp - license: MIT - - dependencies: harfbuzz sheenbidi - defines: WITH_RIVE_TEXT=1 - searchpaths: include + ID: rive + vendor: rive + version: 1.0 + name: Rive C++ is a runtime library for Rive. + description: Rive C++ is a runtime library for Rive, a real-time interactive design and animation tool. + website: https://github.com/rive-app/rive-cpp + license: MIT + minimumCppStandard: 17 + + dependencies: harfbuzz sheenbidi + defines: WITH_RIVE_TEXT=1 + searchpaths: include END_JUCE_MODULE_DECLARATION @@ -42,3 +43,14 @@ */ #pragma once + +#include "include/rive/text/utf.hpp" +#include "include/rive/artboard.hpp" +#include "include/rive/file.hpp" +#include "include/rive/static_scene.hpp" +#include "include/rive/layout.hpp" +#include "include/rive/custom_property_number.hpp" +#include "include/rive/custom_property_boolean.hpp" +#include "include/rive/custom_property_string.hpp" +#include "include/rive/animation/state_machine_instance.hpp" +#include "include/rive/animation/state_machine_input_instance.hpp" diff --git a/thirdparty/rive_pls_renderer/rive_pls_renderer.h b/thirdparty/rive_pls_renderer/rive_pls_renderer.h index 9a91080bc..5d86820cf 100644 --- a/thirdparty/rive_pls_renderer/rive_pls_renderer.h +++ b/thirdparty/rive_pls_renderer/rive_pls_renderer.h @@ -31,6 +31,7 @@ description: The Rive Renderer is a vector and raster graphics renderer custom-built for Rive content, for animation, and for runtime. website: https://github.com/rive-app/rive-renderer license: MIT + minimumCppStandard: 17 dependencies: rive glad OSXFrameworks: Metal QuartzCore @@ -46,4 +47,13 @@ #pragma once -// TODO - Other deps: rive-decoders rive-dependencies glad +#if __clang__ + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wattributes" +#endif + +#include "include/rive/pls/pls_render_context.hpp" + +#if __clang__ + #pragma clang diagnostic pop +#endif From 51b221353f1924c415f9ab4fa665bca492cde9b3 Mon Sep 17 00:00:00 2001 From: Yup Bot Date: Tue, 20 Aug 2024 21:19:23 +0000 Subject: [PATCH 10/22] Code formatting --- modules/yup_gui/yup_gui.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/yup_gui/yup_gui.cpp b/modules/yup_gui/yup_gui.cpp index 93a200958..d4f6163dd 100644 --- a/modules/yup_gui/yup_gui.cpp +++ b/modules/yup_gui/yup_gui.cpp @@ -20,7 +20,7 @@ */ #ifdef YUP_GUI_H_INCLUDED -/* When you add this cpp file to your project, you mustn't include it in a file where you've + /* When you add this cpp file to your project, you mustn't include it in a file where you've already included any other headers - just put it inside a file on its own, possibly with your config flags preceding it, but don't include anything else. That also includes avoiding any automatic prefix header files that the compiler may be using. From 28527c52de26544203cb490740d88c8dbd6538f8 Mon Sep 17 00:00:00 2001 From: Yup Bot Date: Wed, 30 Oct 2024 19:53:10 +0000 Subject: [PATCH 11/22] Code formatting --- modules/yup_gui/yup_gui.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/yup_gui/yup_gui.cpp b/modules/yup_gui/yup_gui.cpp index 9ff5f4bbe..67332927b 100644 --- a/modules/yup_gui/yup_gui.cpp +++ b/modules/yup_gui/yup_gui.cpp @@ -20,7 +20,7 @@ */ #ifdef YUP_GUI_H_INCLUDED - /* When you add this cpp file to your project, you mustn't include it in a file where you've +/* When you add this cpp file to your project, you mustn't include it in a file where you've already included any other headers - just put it inside a file on its own, possibly with your config flags preceding it, but don't include anything else. That also includes avoiding any automatic prefix header files that the compiler may be using. From ab3d61747b40ae22c84274034dc8278eacf34928 Mon Sep 17 00:00:00 2001 From: Yup Bot Date: Sat, 22 Mar 2025 23:06:42 +0000 Subject: [PATCH 12/22] Code formatting --- .../midi/juce_MidiBuffer.cpp | 6 +- .../audio_io/juce_AudioDeviceManager.cpp | 30 +-- .../audio_io/juce_AudioDeviceManager.h | 6 +- .../audio_io/juce_AudioIODeviceType.cpp | 6 +- .../native/juce_CoreAudio_mac.cpp | 144 +++++------ .../native/juce_JackAudio.cpp | 54 ++-- .../native/juce_Midi_linux.cpp | 158 ++++++------ .../native/juce_Midi_windows.cpp | 118 ++++----- .../juce_core/containers/juce_ListenerList.h | 18 +- modules/juce_core/files/juce_File.cpp | 6 +- .../javascript/juce_JSONSerialisation.h | 16 +- .../juce_core/javascript/juce_JSONUtils.cpp | 6 +- .../native/juce_AndroidDocument_android.cpp | 6 +- .../juce_core/native/juce_SharedCode_posix.h | 12 +- .../native/juce_SystemStats_windows.cpp | 6 +- modules/juce_core/threads/juce_Thread.cpp | 6 +- modules/juce_core/zip/juce_ZipFile.cpp | 6 +- .../messages/juce_MessageManager.cpp | 38 +-- .../native/juce_Messaging_linux.cpp | 56 ++--- .../native/juce_Messaging_windows.cpp | 6 +- .../yup_graphics/graphics/yup_Graphics.cpp | 8 +- modules/yup_gui/component/yup_Component.cpp | 6 +- modules/yup_gui/component/yup_Component.h | 4 +- modules/yup_gui/native/yup_Windowing_sdl2.cpp | 2 +- .../juce_AudioDeviceManager.cpp | 6 +- tests/juce_core/juce_AbstractFifo.cpp | 24 +- tests/juce_core/juce_CharacterFunctions.cpp | 36 +-- tests/juce_core/juce_DynamicObject.cpp | 148 +++++------ tests/juce_core/juce_ListenerList.cpp | 208 +++++++-------- tests/juce_core/juce_Variant.cpp | 238 +++++++++--------- 30 files changed, 692 insertions(+), 692 deletions(-) diff --git a/modules/juce_audio_basics/midi/juce_MidiBuffer.cpp b/modules/juce_audio_basics/midi/juce_MidiBuffer.cpp index 057678c9b..83d20bf2d 100644 --- a/modules/juce_audio_basics/midi/juce_MidiBuffer.cpp +++ b/modules/juce_audio_basics/midi/juce_MidiBuffer.cpp @@ -225,9 +225,9 @@ int MidiBuffer::getLastEventTime() const noexcept MidiBufferIterator MidiBuffer::findNextSamplePosition (int samplePosition) const noexcept { return std::find_if (cbegin(), cend(), [&] (const MidiMessageMetadata& metadata) noexcept - { - return metadata.samplePosition >= samplePosition; - }); + { + return metadata.samplePosition >= samplePosition; + }); } } // namespace juce diff --git a/modules/juce_audio_devices/audio_io/juce_AudioDeviceManager.cpp b/modules/juce_audio_devices/audio_io/juce_AudioDeviceManager.cpp index d70417f0a..3d00b75fc 100644 --- a/modules/juce_audio_devices/audio_io/juce_AudioDeviceManager.cpp +++ b/modules/juce_audio_devices/audio_io/juce_AudioDeviceManager.cpp @@ -482,9 +482,9 @@ void AudioDeviceManager::openLastRequestedMidiDevices (const Arrayidentifier); @@ -507,16 +507,16 @@ void AudioDeviceManager::openLastRequestedMidiDevices (const Array tempBuffer; MidiDeviceListConnection midiDeviceListConnection = MidiDeviceListConnection::make ([this] - { - midiDeviceListChanged(); - }); + { + midiDeviceListChanged(); + }); struct MidiCallbackInfo { diff --git a/modules/juce_audio_devices/audio_io/juce_AudioIODeviceType.cpp b/modules/juce_audio_devices/audio_io/juce_AudioIODeviceType.cpp index da4ffbc06..a8bd80acc 100644 --- a/modules/juce_audio_devices/audio_io/juce_AudioIODeviceType.cpp +++ b/modules/juce_audio_devices/audio_io/juce_AudioIODeviceType.cpp @@ -57,9 +57,9 @@ void AudioIODeviceType::removeListener (Listener* l) { listeners.remove (l); } void AudioIODeviceType::callDeviceChangeListeners() { listeners.call ([] (Listener& l) - { - l.audioDeviceListChanged(); - }); + { + l.audioDeviceListChanged(); + }); } //============================================================================== diff --git a/modules/juce_audio_devices/native/juce_CoreAudio_mac.cpp b/modules/juce_audio_devices/native/juce_CoreAudio_mac.cpp index c06b3c953..eb3c9aa27 100644 --- a/modules/juce_audio_devices/native/juce_CoreAudio_mac.cpp +++ b/modules/juce_audio_devices/native/juce_CoreAudio_mac.cpp @@ -380,9 +380,9 @@ struct CoreAudioClasses auto streams = getStreams(); const auto total = std::accumulate (streams.begin(), streams.end(), 0, [] (int n, const auto& s) - { - return n + (s != nullptr ? s->channels : 0); - }); + { + return n + (s != nullptr ? s->channels : 0); + }); audioBuffer.calloc (total * tempBufSize); auto channels = 0; @@ -505,9 +505,9 @@ struct CoreAudioClasses if (auto* workgroup = audioObjectGetProperty (deviceID, pa).value_or (nullptr)) { ScopeGuard scope { [&] - { - os_release (workgroup); - } }; + { + os_release (workgroup); + } }; return makeRealAudioWorkgroup (workgroup); } @@ -651,9 +651,9 @@ struct CoreAudioClasses { callbacksAllowed = false; const ScopeGuard scope { [&] - { - callbacksAllowed = true; - } }; + { + callbacksAllowed = true; + } }; stopTimer(); @@ -871,11 +871,11 @@ struct CoreAudioClasses , bitDepth (getBitDepthFromDevice (isInput, parent)) , chanNames (getChannelNames (isInput, parent)) , activeChans ([&activeRequested, clearFrom = chanNames.size()] - { - auto result = activeRequested; - result.setRange (clearFrom, result.getHighestBit() + 1 - clearFrom, false); - return result; - }()) + { + auto result = activeRequested; + result.setRange (clearFrom, result.getHighestBit() + 1 - clearFrom, false); + return result; + }()) , channelInfo (getChannelInfos (isInput, parent, activeChans)) , channels (static_cast (channelInfo.size())) { @@ -926,32 +926,32 @@ struct CoreAudioClasses static Array getChannelInfos (bool isInput, CoreAudioInternal& parent, const BigInteger& active) { return visitChannels (isInput, parent, [&] (const auto& args) -> std::optional - { - if (! active[args.chanNum]) - return {}; + { + if (! active[args.chanNum]) + return {}; - return CallbackDetailsForChannel { args.stream, args.channelIdx, args.streamChannels }; - }); + return CallbackDetailsForChannel { args.stream, args.channelIdx, args.streamChannels }; + }); } static StringArray getChannelNames (bool isInput, CoreAudioInternal& parent) { auto names = visitChannels (isInput, parent, [&] (const auto& args) -> std::optional - { - String name; - const auto element = static_cast (args.chanNum + 1); + { + String name; + const auto element = static_cast (args.chanNum + 1); - if (auto nameNSString = audioObjectGetProperty (parent.deviceID, { kAudioObjectPropertyElementName, getScope (isInput), element }).value_or (nullptr)) - { - name = nsStringToJuce (nameNSString); - [nameNSString release]; - } + if (auto nameNSString = audioObjectGetProperty (parent.deviceID, { kAudioObjectPropertyElementName, getScope (isInput), element }).value_or (nullptr)) + { + name = nsStringToJuce (nameNSString); + [nameNSString release]; + } - if (name.isEmpty()) - name << (isInput ? "Input " : "Output ") << (args.chanNum + 1); + if (name.isEmpty()) + name << (isInput ? "Input " : "Output ") << (args.chanNum + 1); - return name; - }); + return name; + }); return { names }; } @@ -1025,9 +1025,9 @@ struct CoreAudioClasses static auto getWithDefault (const std::unique_ptr& ptr, Value (Stream::*member)) { return getWithDefault (ptr, [&] (Stream& s) - { - return s.*member; - }); + { + return s.*member; + }); } static int getLatency (const std::unique_ptr& ptr) { return getWithDefault (ptr, &Stream::latency); } @@ -1045,9 +1045,9 @@ struct CoreAudioClasses static float** getTempBuffers (const std::unique_ptr& ptr) { return getWithDefault (ptr, [] (auto& s) - { - return s.tempBuffers.get(); - }); + { + return s.tempBuffers.get(); + }); } //============================================================================== @@ -1159,35 +1159,35 @@ struct CoreAudioClasses auto& intern = *static_cast (inClientData); const auto xruns = std::count_if (pa, pa + numAddresses, [] (const AudioObjectPropertyAddress& x) - { - return x.mSelector == kAudioDeviceProcessorOverload; - }); + { + return x.mSelector == kAudioDeviceProcessorOverload; + }); intern.xruns += xruns; const auto detailsChanged = std::any_of (pa, pa + numAddresses, [] (const AudioObjectPropertyAddress& x) - { - constexpr UInt32 selectors[] { - kAudioDevicePropertyBufferSize, - kAudioDevicePropertyBufferFrameSize, - kAudioDevicePropertyNominalSampleRate, - kAudioDevicePropertyStreamFormat, - kAudioDevicePropertyDeviceIsAlive, - kAudioStreamPropertyPhysicalFormat, - }; - - return std::find (std::begin (selectors), std::end (selectors), x.mSelector) != std::end (selectors); - }); + { + constexpr UInt32 selectors[] { + kAudioDevicePropertyBufferSize, + kAudioDevicePropertyBufferFrameSize, + kAudioDevicePropertyNominalSampleRate, + kAudioDevicePropertyStreamFormat, + kAudioDevicePropertyDeviceIsAlive, + kAudioStreamPropertyPhysicalFormat, + }; + + return std::find (std::begin (selectors), std::end (selectors), x.mSelector) != std::end (selectors); + }); const auto requestedRestart = std::any_of (pa, pa + numAddresses, [] (const AudioObjectPropertyAddress& x) - { - constexpr UInt32 selectors[] { - kAudioDevicePropertyDeviceHasChanged, - kAudioObjectPropertyOwnedObjects, - }; + { + constexpr UInt32 selectors[] { + kAudioDevicePropertyDeviceHasChanged, + kAudioObjectPropertyOwnedObjects, + }; - return std::find (std::begin (selectors), std::end (selectors), x.mSelector) != std::end (selectors); - }); + return std::find (std::begin (selectors), std::end (selectors), x.mSelector) != std::end (selectors); + }); if (detailsChanged) intern.deviceDetailsChanged(); @@ -1483,9 +1483,9 @@ struct CoreAudioClasses void* inClientData) { const auto detailsChanged = std::any_of (pa, pa + numAddresses, [] (const AudioObjectPropertyAddress& x) - { - return x.mSelector == kAudioHardwarePropertyDevices; - }); + { + return x.mSelector == kAudioHardwarePropertyDevices; + }); if (detailsChanged) static_cast (inClientData)->deviceDetailsChanged(); @@ -1903,11 +1903,11 @@ struct CoreAudioClasses } accessFifo (currentWritePos, scratchBuffer.getNumChannels(), n, [&] (const auto& args) - { - FloatVectorOperations::copy (fifo.getWritePointer (args.channel, args.fifoPos), - scratchBuffer.getReadPointer (args.channel, args.inputPos), - args.nItems); - }); + { + FloatVectorOperations::copy (fifo.getWritePointer (args.channel, args.fifoPos), + scratchBuffer.getReadPointer (args.channel, args.inputPos), + args.nItems); + }); { auto invalid = invalidSampleTime; @@ -1949,11 +1949,11 @@ struct CoreAudioClasses std::fill (channels[i], channels[i] + numZerosToWrite, 0.0f); accessFifo (currentReadPos + numZerosToWrite, numChannels, static_cast (longN - numZerosToWrite), [&] (const auto& args) - { - FloatVectorOperations::copy (channels[args.channel] + args.inputPos + numZerosToWrite, - fifo.getReadPointer (args.channel, args.fifoPos), - args.nItems); - }); + { + FloatVectorOperations::copy (channels[args.channel] + args.inputPos + numZerosToWrite, + fifo.getReadPointer (args.channel, args.fifoPos), + args.nItems); + }); // use compare exchange here as we need to avoid the case // where we overwrite readPos being equal to invalidSampleTime diff --git a/modules/juce_audio_devices/native/juce_JackAudio.cpp b/modules/juce_audio_devices/native/juce_JackAudio.cpp index d60e5c8c7..73a0db9c1 100644 --- a/modules/juce_audio_devices/native/juce_JackAudio.cpp +++ b/modules/juce_audio_devices/native/juce_JackAudio.cpp @@ -331,43 +331,43 @@ class JackAudioIODevice final : public AudioIODevice if (! inputChannels.isZero()) { forEachClientChannel (inputName, false, [&] (const char* portName, int index) - { - if (! inputChannels[index]) - return; + { + if (! inputChannels[index]) + return; - jassert (index < inputPorts.size()); + jassert (index < inputPorts.size()); - const auto* source = portName; - const auto* inputPort = inputPorts[index]; + const auto* source = portName; + const auto* inputPort = inputPorts[index]; - jassert (juce::jack_port_flags (juce::jack_port_by_name (client, source)) & JackPortIsOutput); - jassert (juce::jack_port_flags (inputPort) & JackPortIsInput); + jassert (juce::jack_port_flags (juce::jack_port_by_name (client, source)) & JackPortIsOutput); + jassert (juce::jack_port_flags (inputPort) & JackPortIsInput); - auto error = juce::jack_connect (client, source, juce::jack_port_name (inputPort)); - if (error != 0) - JUCE_JACK_LOG ("Cannot connect input port " + String (index) + " (" + portName + "), error " + String (error)); - }); + auto error = juce::jack_connect (client, source, juce::jack_port_name (inputPort)); + if (error != 0) + JUCE_JACK_LOG ("Cannot connect input port " + String (index) + " (" + portName + "), error " + String (error)); + }); } if (! outputChannels.isZero()) { forEachClientChannel (outputName, true, [&] (const char* portName, int index) - { - if (! outputChannels[index]) - return; + { + if (! outputChannels[index]) + return; - jassert (index < outputPorts.size()); + jassert (index < outputPorts.size()); - const auto* outputPort = outputPorts[index]; - const auto* destination = portName; + const auto* outputPort = outputPorts[index]; + const auto* destination = portName; - jassert (juce::jack_port_flags (outputPort) & JackPortIsOutput); - jassert (juce::jack_port_flags (juce::jack_port_by_name (client, destination)) & JackPortIsInput); + jassert (juce::jack_port_flags (outputPort) & JackPortIsOutput); + jassert (juce::jack_port_flags (juce::jack_port_by_name (client, destination)) & JackPortIsInput); - auto error = juce::jack_connect (client, juce::jack_port_name (outputPort), destination); - if (error != 0) - JUCE_JACK_LOG ("Cannot connect output port " + String (index) + " (" + portName + "), error " + String (error)); - }); + auto error = juce::jack_connect (client, juce::jack_port_name (outputPort), destination); + if (error != 0) + JUCE_JACK_LOG ("Cannot connect output port " + String (index) + " (" + portName + "), error " + String (error)); + }); } updateActivePorts(); @@ -716,9 +716,9 @@ class JackAudioIODeviceType final : public AudioIODeviceType if (inputIndex >= 0 || outputIndex >= 0) return new JackAudioIODevice (inputDeviceName, outputDeviceName, [this] - { - callDeviceChangeListeners(); - }); + { + callDeviceChangeListeners(); + }); return nullptr; } diff --git a/modules/juce_audio_devices/native/juce_Midi_linux.cpp b/modules/juce_audio_devices/native/juce_Midi_linux.cpp index bd1e54d5f..2846d4c1c 100644 --- a/modules/juce_audio_devices/native/juce_Midi_linux.cpp +++ b/modules/juce_audio_devices/native/juce_Midi_linux.cpp @@ -371,82 +371,82 @@ class AlsaClient std::atomic shouldStop { false }; UpdateNotifier notifier; std::thread thread { [this] - { - Thread::setCurrentThreadName ("JUCE MIDI Input"); - - auto seqHandle = client.get(); - - const int maxEventSize = 16 * 1024; - snd_midi_event_t* midiParser; - - if (snd_midi_event_new (maxEventSize, &midiParser) >= 0) - { - const ScopeGuard freeMidiEvent { [&] - { - snd_midi_event_free (midiParser); - } }; - - const auto numPfds = snd_seq_poll_descriptors_count (seqHandle, POLLIN); - std::vector pfd (static_cast (numPfds)); - snd_seq_poll_descriptors (seqHandle, pfd.data(), (unsigned int) numPfds, POLLIN); - - std::vector buffer (maxEventSize); - - while (! shouldStop) - { - // This timeout shouldn't be too long, so that the program can exit in a timely manner - if (poll (pfd.data(), (nfds_t) numPfds, 100) > 0) - { - if (shouldStop) - break; - - do - { - snd_seq_event_t* inputEvent = nullptr; - - if (snd_seq_event_input (seqHandle, &inputEvent) >= 0) - { - const ScopeGuard freeInputEvent { [&] - { - snd_seq_free_event (inputEvent); - } }; - - constexpr int systemEvents[] { - SND_SEQ_EVENT_CLIENT_CHANGE, - SND_SEQ_EVENT_CLIENT_START, - SND_SEQ_EVENT_CLIENT_EXIT, - SND_SEQ_EVENT_PORT_CHANGE, - SND_SEQ_EVENT_PORT_START, - SND_SEQ_EVENT_PORT_EXIT, - SND_SEQ_EVENT_PORT_SUBSCRIBED, - SND_SEQ_EVENT_PORT_UNSUBSCRIBED, - }; - - const auto foundEvent = std::find (std::begin (systemEvents), - std::end (systemEvents), - inputEvent->type); - - if (foundEvent != std::end (systemEvents)) - { - notifier.triggerAsyncUpdate(); - continue; - } - - // xxx what about SYSEXes that are too big for the buffer? - const auto numBytes = snd_midi_event_decode (midiParser, - buffer.data(), - maxEventSize, - inputEvent); - - snd_midi_event_reset_decode (midiParser); - - concatenator.pushMidiData (buffer.data(), (int) numBytes, Time::getMillisecondCounter() * 0.001, inputEvent, client); - } - } while (snd_seq_event_input_pending (seqHandle, 0) > 0); - } - } - } - } }; + { + Thread::setCurrentThreadName ("JUCE MIDI Input"); + + auto seqHandle = client.get(); + + const int maxEventSize = 16 * 1024; + snd_midi_event_t* midiParser; + + if (snd_midi_event_new (maxEventSize, &midiParser) >= 0) + { + const ScopeGuard freeMidiEvent { [&] + { + snd_midi_event_free (midiParser); + } }; + + const auto numPfds = snd_seq_poll_descriptors_count (seqHandle, POLLIN); + std::vector pfd (static_cast (numPfds)); + snd_seq_poll_descriptors (seqHandle, pfd.data(), (unsigned int) numPfds, POLLIN); + + std::vector buffer (maxEventSize); + + while (! shouldStop) + { + // This timeout shouldn't be too long, so that the program can exit in a timely manner + if (poll (pfd.data(), (nfds_t) numPfds, 100) > 0) + { + if (shouldStop) + break; + + do + { + snd_seq_event_t* inputEvent = nullptr; + + if (snd_seq_event_input (seqHandle, &inputEvent) >= 0) + { + const ScopeGuard freeInputEvent { [&] + { + snd_seq_free_event (inputEvent); + } }; + + constexpr int systemEvents[] { + SND_SEQ_EVENT_CLIENT_CHANGE, + SND_SEQ_EVENT_CLIENT_START, + SND_SEQ_EVENT_CLIENT_EXIT, + SND_SEQ_EVENT_PORT_CHANGE, + SND_SEQ_EVENT_PORT_START, + SND_SEQ_EVENT_PORT_EXIT, + SND_SEQ_EVENT_PORT_SUBSCRIBED, + SND_SEQ_EVENT_PORT_UNSUBSCRIBED, + }; + + const auto foundEvent = std::find (std::begin (systemEvents), + std::end (systemEvents), + inputEvent->type); + + if (foundEvent != std::end (systemEvents)) + { + notifier.triggerAsyncUpdate(); + continue; + } + + // xxx what about SYSEXes that are too big for the buffer? + const auto numBytes = snd_midi_event_decode (midiParser, + buffer.data(), + maxEventSize, + inputEvent); + + snd_midi_event_reset_decode (midiParser); + + concatenator.pushMidiData (buffer.data(), (int) numBytes, Time::getMillisecondCounter() * 0.001, inputEvent, client); + } + } while (snd_seq_event_input_pending (seqHandle, 0) > 0); + } + } + } + } }; }; std::optional inputThread; @@ -709,9 +709,9 @@ MidiDeviceListConnection MidiDeviceListConnection::make (std::function c // as the MidiDeviceListConnection. This is necessary because system change messages will only // be processed when the AlsaClient's SequencerThread is running. return { &broadcaster, broadcaster.add ([fn = std::move (cb), client = AlsaClient::getInstance()] - { - NullCheckedInvocation::invoke (fn); - }) }; + { + NullCheckedInvocation::invoke (fn); + }) }; } //============================================================================== diff --git a/modules/juce_audio_devices/native/juce_Midi_windows.cpp b/modules/juce_audio_devices/native/juce_Midi_windows.cpp index 5495b18a3..8100d1884 100644 --- a/modules/juce_audio_devices/native/juce_Midi_windows.cpp +++ b/modules/juce_audio_devices/native/juce_Midi_windows.cpp @@ -1068,27 +1068,27 @@ struct WinRTMidiService final : public MidiServiceType watcher->add_Added ( Callback> ( [handlerPtr] (IDeviceWatcher*, IDeviceInformation* info) - { - return handlerPtr->addDevice (info); - }) + { + return handlerPtr->addDevice (info); + }) .Get(), &deviceAddedToken); watcher->add_Removed ( Callback> ( [handlerPtr] (IDeviceWatcher*, IDeviceInformationUpdate* infoUpdate) - { - return handlerPtr->removeDevice (infoUpdate); - }) + { + return handlerPtr->removeDevice (infoUpdate); + }) .Get(), &deviceRemovedToken); watcher->add_Updated ( Callback> ( [handlerPtr] (IDeviceWatcher*, IDeviceInformationUpdate* infoUpdate) - { - return handlerPtr->updateDevice (infoUpdate); - }) + { + return handlerPtr->updateDevice (infoUpdate); + }) .Get(), &deviceUpdatedToken); @@ -1202,9 +1202,9 @@ struct WinRTMidiService final : public MidiServiceType { auto& info = devices.getReference (removedDeviceId); listeners.call ([&info] (Listener& l) - { - l.bleDeviceDisconnected (info.containerID); - }); + { + l.bleDeviceDisconnected (info.containerID); + }); devices.remove (removedDeviceId); JUCE_WINRT_MIDI_LOG ("Removed BLE device: " << removedDeviceId); } @@ -1252,9 +1252,9 @@ struct WinRTMidiService final : public MidiServiceType { JUCE_WINRT_MIDI_LOG ("BLE device connection status change: " << updatedDeviceId << " " << info.containerID << " " << (isConnected ? "connected" : "disconnected")); listeners.call ([&info] (Listener& l) - { - l.bleDeviceDisconnected (info.containerID); - }); + { + l.bleDeviceDisconnected (info.containerID); + }); } info.isConnected = isConnected; @@ -1511,48 +1511,48 @@ struct WinRTMidiService final : public MidiServiceType ComSmartPtr& comPort) { std::thread { [&] - { - Thread::setCurrentThreadName (threadName); + { + Thread::setCurrentThreadName (threadName); - const WinRTWrapper::ScopedHString hDeviceId { midiDeviceID }; - ComSmartPtr> asyncOp; - const auto hr = comFactory->FromIdAsync (hDeviceId.get(), asyncOp.resetAndGetPointerAddress()); + const WinRTWrapper::ScopedHString hDeviceId { midiDeviceID }; + ComSmartPtr> asyncOp; + const auto hr = comFactory->FromIdAsync (hDeviceId.get(), asyncOp.resetAndGetPointerAddress()); - if (FAILED (hr)) - return; + if (FAILED (hr)) + return; - std::promise> promise; - auto future = promise.get_future(); + std::promise> promise; + auto future = promise.get_future(); - auto callback = [p = std::move (promise)] (IAsyncOperation* asyncOpPtr, AsyncStatus) mutable - { - if (asyncOpPtr == nullptr) - { - p.set_value (nullptr); - return E_ABORT; - } + auto callback = [p = std::move (promise)] (IAsyncOperation* asyncOpPtr, AsyncStatus) mutable + { + if (asyncOpPtr == nullptr) + { + p.set_value (nullptr); + return E_ABORT; + } - ComSmartPtr result; - const auto hr = asyncOpPtr->GetResults (result.resetAndGetPointerAddress()); + ComSmartPtr result; + const auto hr = asyncOpPtr->GetResults (result.resetAndGetPointerAddress()); - if (FAILED (hr)) - { - p.set_value (nullptr); - return hr; - } + if (FAILED (hr)) + { + p.set_value (nullptr); + return hr; + } - p.set_value (std::move (result)); - return S_OK; - }; + p.set_value (std::move (result)); + return S_OK; + }; - const auto ir = asyncOp->put_Completed (Callback> (std::move (callback)).Get()); + const auto ir = asyncOp->put_Completed (Callback> (std::move (callback)).Get()); - if (FAILED (ir)) - return; + if (FAILED (ir)) + return; - if (future.wait_for (std::chrono::milliseconds (2000)) == std::future_status::ready) - comPort = future.get(); - } } + if (future.wait_for (std::chrono::milliseconds (2000)) == std::future_status::ready) + comPort = future.get(); + } } .join(); } @@ -1663,17 +1663,17 @@ struct WinRTMidiService final : public MidiServiceType auto hr = midiPort->add_MessageReceived ( Callback> ( [self = checkedReference] (IMidiInPort*, IMidiMessageReceivedEventArgs* args) - { - HRESULT hr = S_OK; + { + HRESULT hr = S_OK; - self->access ([&hr, args] (auto* ptr) - { - if (ptr != nullptr) - hr = ptr->midiInMessageReceived (args); - }); + self->access ([&hr, args] (auto* ptr) + { + if (ptr != nullptr) + hr = ptr->midiInMessageReceived (args); + }); - return hr; - }) + return hr; + }) .Get(), &midiInMessageToken); @@ -1929,9 +1929,9 @@ struct MidiService final : public DeletedAtShutdown private: std::unique_ptr internal; DeviceChangeDetector detector { L"JuceMidiDeviceDetector_", [] - { - MidiDeviceListConnectionBroadcaster::get().notify(); - } }; + { + MidiDeviceListConnectionBroadcaster::get().notify(); + } }; }; JUCE_IMPLEMENT_SINGLETON (MidiService) diff --git a/modules/juce_core/containers/juce_ListenerList.h b/modules/juce_core/containers/juce_ListenerList.h index 694117a8e..5801e7419 100644 --- a/modules/juce_core/containers/juce_ListenerList.h +++ b/modules/juce_core/containers/juce_ListenerList.h @@ -161,9 +161,9 @@ class ListenerList { add (&listenerToAdd); return ErasedScopeGuard { [this, &listenerToAdd] - { - remove (&listenerToAdd); - } }; + { + remove (&listenerToAdd); + } }; } /** Returns the number of registered listeners. */ @@ -271,9 +271,9 @@ class ListenerList iterators->push_back (&it); const ScopeGuard scope { [i = iterators, &it] - { - i->erase (std::remove (i->begin(), i->end(), &it), i->end()); - } }; + { + i->erase (std::remove (i->begin(), i->end(), &it), i->end()); + } }; for (; it.index < it.end; ++it.index) { @@ -344,9 +344,9 @@ class ListenerList Args&&... args) { callCheckedExcluding (listenerToExclude, bailOutChecker, [&] (ListenerClass& l) - { - (l.*callbackFunction) (args...); - }); + { + (l.*callbackFunction) (args...); + }); } //============================================================================== diff --git a/modules/juce_core/files/juce_File.cpp b/modules/juce_core/files/juce_File.cpp index b04c9b13d..e67dad6c1 100644 --- a/modules/juce_core/files/juce_File.cpp +++ b/modules/juce_core/files/juce_File.cpp @@ -654,9 +654,9 @@ int File::getNumberOfChildFiles (const int whatToLookFor, const String& wildCard RangedDirectoryIterator(), 0, [] (int acc, const DirectoryEntry&) - { - return acc + 1; - }); + { + return acc + 1; + }); } bool File::containsSubDirectories() const diff --git a/modules/juce_core/javascript/juce_JSONSerialisation.h b/modules/juce_core/javascript/juce_JSONSerialisation.h index 53f3e2239..0db73cf80 100644 --- a/modules/juce_core/javascript/juce_JSONSerialisation.h +++ b/modules/juce_core/javascript/juce_JSONSerialisation.h @@ -140,14 +140,14 @@ class ToVar Visitor (const std::optional& explicitVersion, bool includeVersion) : version (explicitVersion) , value ([&]() -> var - { - if (! (version.has_value() && includeVersion)) - return var(); - - auto obj = std::make_unique(); - obj->setProperty ("__version__", *version); - return obj.release(); - }()) + { + if (! (version.has_value() && includeVersion)) + return var(); + + auto obj = std::make_unique(); + obj->setProperty ("__version__", *version); + return obj.release(); + }()) , versionIncluded (includeVersion) { } diff --git a/modules/juce_core/javascript/juce_JSONUtils.cpp b/modules/juce_core/javascript/juce_JSONUtils.cpp index ea1329c3c..66a95880c 100644 --- a/modules/juce_core/javascript/juce_JSONUtils.cpp +++ b/modules/juce_core/javascript/juce_JSONUtils.cpp @@ -155,9 +155,9 @@ bool JSONUtils::deepEqual (const var& a, const var& b) if (auto* i = a.getArray()) if (auto* j = b.getArray()) return std::equal (i->begin(), i->end(), j->begin(), j->end(), [] (const var& x, const var& y) - { - return deepEqual (x, y); - }); + { + return deepEqual (x, y); + }); return a == b; } diff --git a/modules/juce_core/native/juce_AndroidDocument_android.cpp b/modules/juce_core/native/juce_AndroidDocument_android.cpp index 28264037c..b42b25166 100644 --- a/modules/juce_core/native/juce_AndroidDocument_android.cpp +++ b/modules/juce_core/native/juce_AndroidDocument_android.cpp @@ -497,9 +497,9 @@ struct AndroidDocument::Utils const auto indices = { flagsColumnIndex, nameColumnIndex, mimeColumnIndex, idColumnIndex, modColumnIndex, sizeColumnIndex }; if (std::any_of (indices.begin(), indices.end(), [] (auto index) - { - return index < 0; - })) + { + return index < 0; + })) return AndroidDocumentInfo::Args {}; const LocalRef nameString { (jstring) env->CallObjectMethod (cursor, AndroidCursor.getString, nameColumnIndex) }; diff --git a/modules/juce_core/native/juce_SharedCode_posix.h b/modules/juce_core/native/juce_SharedCode_posix.h index af01996ec..26c540883 100644 --- a/modules/juce_core/native/juce_SharedCode_posix.h +++ b/modules/juce_core/native/juce_SharedCode_posix.h @@ -1234,9 +1234,9 @@ class ChildProcess::ActiveProcess ActiveProcess (const StringArray& arguments, int streamFlags) { startProcess (arguments, streamFlags, {}, [] (const String& exe, const Array& argv, const Array&) - { - execvp (exe.toRawUTF8(), argv.getRawDataPointer()); - }); + { + execvp (exe.toRawUTF8(), argv.getRawDataPointer()); + }); } ActiveProcess (const StringArray& arguments, const StringPairArray& environment, int streamFlags) @@ -1273,9 +1273,9 @@ class ChildProcess::ActiveProcess } startProcess (args, streamFlags, env, [] (const String& exe, const Array& argv, const Array& env) - { - execve (exe.toRawUTF8(), argv.getRawDataPointer(), env.getRawDataPointer()); - }); + { + execve (exe.toRawUTF8(), argv.getRawDataPointer(), env.getRawDataPointer()); + }); } ~ActiveProcess() diff --git a/modules/juce_core/native/juce_SystemStats_windows.cpp b/modules/juce_core/native/juce_SystemStats_windows.cpp index 29f138814..4ff935daf 100644 --- a/modules/juce_core/native/juce_SystemStats_windows.cpp +++ b/modules/juce_core/native/juce_SystemStats_windows.cpp @@ -84,9 +84,9 @@ static int findNumberOfPhysicalCores() noexcept } return (int) std::count_if (buffer.get(), buffer.get() + numBuffers, [] (const auto& info) - { - return info.Relationship == RelationProcessorCore; - }); + { + return info.Relationship == RelationProcessorCore; + }); #endif // JUCE_MINGW } diff --git a/modules/juce_core/threads/juce_Thread.cpp b/modules/juce_core/threads/juce_Thread.cpp index e201a1321..49ec66102 100644 --- a/modules/juce_core/threads/juce_Thread.cpp +++ b/modules/juce_core/threads/juce_Thread.cpp @@ -215,9 +215,9 @@ void Thread::signalThreadShouldExit() { shouldExit = true; listeners.call ([] (Listener& l) - { - l.exitSignalSent(); - }); + { + l.exitSignalSent(); + }); } bool Thread::threadShouldExit() const diff --git a/modules/juce_core/zip/juce_ZipFile.cpp b/modules/juce_core/zip/juce_ZipFile.cpp index 15706ab8f..b4fc1032f 100644 --- a/modules/juce_core/zip/juce_ZipFile.cpp +++ b/modules/juce_core/zip/juce_ZipFile.cpp @@ -362,9 +362,9 @@ InputStream* ZipFile::createStreamForEntry (const ZipEntry& entry) void ZipFile::sortEntriesByFilename() { std::sort (entries.begin(), entries.end(), [] (const ZipEntryHolder* e1, const ZipEntryHolder* e2) - { - return e1->entry.filename < e2->entry.filename; - }); + { + return e1->entry.filename < e2->entry.filename; + }); } //============================================================================== diff --git a/modules/juce_events/messages/juce_MessageManager.cpp b/modules/juce_events/messages/juce_MessageManager.cpp index cd2831577..b97764ae7 100644 --- a/modules/juce_events/messages/juce_MessageManager.cpp +++ b/modules/juce_events/messages/juce_MessageManager.cpp @@ -328,17 +328,17 @@ struct MessageManager::Lock::BlockingMessage final : public MessageManager::Mess owner->setAcquired (true); condvar.wait (lock, [&] - { - return owner == nullptr; - }); + { + return owner == nullptr; + }); } void stopWaiting() { const ScopeGuard scope { [&] - { - condvar.notify_one(); - } }; + { + condvar.notify_one(); + } }; const std::scoped_lock lock { mutex }; owner = nullptr; } @@ -387,10 +387,10 @@ bool MessageManager::Lock::tryAcquire (bool lockIsMandatory) const noexcept } if (! lockIsMandatory && [&] - { - const std::scoped_lock lock { mutex }; - return std::exchange (abortWait, false); - }()) + { + const std::scoped_lock lock { mutex }; + return std::exchange (abortWait, false); + }()) { return false; } @@ -421,9 +421,9 @@ bool MessageManager::Lock::tryAcquire (bool lockIsMandatory) const noexcept { std::unique_lock lock { mutex }; condvar.wait (lock, [&] - { - return std::exchange (abortWait, false); - }); + { + return std::exchange (abortWait, false); + }); } if (acquired) @@ -455,9 +455,9 @@ void MessageManager::Lock::exit() const noexcept return; const ScopeGuard unlocker { [&] - { - entryMutex.exit(); - } }; + { + entryMutex.exit(); + } }; if (blockingMessage == nullptr) return; @@ -481,9 +481,9 @@ void MessageManager::Lock::abort() const noexcept void MessageManager::Lock::setAcquired (bool x) const noexcept { const ScopeGuard scope { [&] - { - condvar.notify_one(); - } }; + { + condvar.notify_one(); + } }; const std::scoped_lock lock { mutex }; abortWait = true; acquired = x; diff --git a/modules/juce_events/native/juce_Messaging_linux.cpp b/modules/juce_events/native/juce_Messaging_linux.cpp index 89b64fe8b..48cf2e09c 100644 --- a/modules/juce_events/native/juce_Messaging_linux.cpp +++ b/modules/juce_events/native/juce_Messaging_linux.cpp @@ -51,16 +51,16 @@ class InternalMessageQueue LinuxEventLoop::registerFdCallback (getReadHandle(), [this] (int fd) - { - while (auto msg = popNextMessage (fd)) - { - JUCE_TRY - { - msg->messageCallback(); - } - JUCE_CATCH_EXCEPTION - } - }); + { + while (auto msg = popNextMessage (fd)) + { + JUCE_TRY + { + msg->messageCallback(); + } + JUCE_CATCH_EXCEPTION + } + }); } ~InternalMessageQueue() @@ -166,9 +166,9 @@ struct InternalRunLoop } listeners.call ([] (auto& l) - { - l.fdCallbacksChanged(); - }); + { + l.fdCallbacksChanged(); + }); } void unregisterFdCallback (int fd) @@ -189,9 +189,9 @@ struct InternalRunLoop } listeners.call ([] (auto& l) - { - l.fdCallbacksChanged(); - }); + { + l.fdCallbacksChanged(); + }); } bool dispatchPendingEvents() @@ -237,9 +237,9 @@ struct InternalRunLoop callbacks.end(), std::back_inserter (result), [] (const auto& pair) - { - return pair.first; - }); + { + return pair.first; + }); return result; } @@ -282,17 +282,17 @@ struct InternalRunLoop std::vector::iterator getPollfd (int fd) { return std::lower_bound (pfds.begin(), pfds.end(), fd, [] (auto descriptor, auto toFind) - { - return descriptor.fd < toFind; - }); + { + return descriptor.fd < toFind; + }); } bool pfdsAreSorted() const { return std::is_sorted (pfds.begin(), pfds.end(), [] (auto a, auto b) - { - return a.fd < b.fd; - }); + { + return a.fd < b.fd; + }); } CriticalSection lock; @@ -391,9 +391,9 @@ void LinuxEventLoop::registerFdCallback (int fd, std::function readC if (auto* runLoop = InternalRunLoop::getInstanceWithoutCreating()) runLoop->registerFdCallback ( fd, [cb = std::move (readCallback), fd] - { - cb (fd); - }, + { + cb (fd); + }, eventMask); } diff --git a/modules/juce_events/native/juce_Messaging_windows.cpp b/modules/juce_events/native/juce_Messaging_windows.cpp index 270198ab5..8a7aa885c 100644 --- a/modules/juce_events/native/juce_Messaging_windows.cpp +++ b/modules/juce_events/native/juce_Messaging_windows.cpp @@ -332,9 +332,9 @@ struct MountedVolumeListChangeDetector::Pimpl } DeviceChangeDetector detector { L"MountedVolumeList", [this] - { - systemDeviceChanged(); - } }; + { + systemDeviceChanged(); + } }; MountedVolumeListChangeDetector& owner; Array lastVolumeList; }; diff --git a/modules/yup_graphics/graphics/yup_Graphics.cpp b/modules/yup_graphics/graphics/yup_Graphics.cpp index 9a764454a..d0454116d 100644 --- a/modules/yup_graphics/graphics/yup_Graphics.cpp +++ b/modules/yup_graphics/graphics/yup_Graphics.cpp @@ -231,10 +231,10 @@ void convertRawPathToRenderPath (const rive::RawPath& input, rive::RenderPath* o void convertRawPathToRenderPath (const rive::RawPath& input, rive::RenderPath* output, const AffineTransform& transform) { auto newInput = input.morph ([&transform] (auto point) - { - transform.transformPoints (point.x, point.y); - return point; - }); + { + transform.transformPoints (point.x, point.y); + return point; + }); newInput.addTo (output); } diff --git a/modules/yup_gui/component/yup_Component.cpp b/modules/yup_gui/component/yup_Component.cpp index f655bc556..85b2012ba 100644 --- a/modules/yup_gui/component/yup_Component.cpp +++ b/modules/yup_gui/component/yup_Component.cpp @@ -255,7 +255,7 @@ float Component::getScaleDpi() const return parentComponent->getScaleDpi(); } -void Component::contentScaleChanged(float dpiScale) +void Component::contentScaleChanged (float dpiScale) { } @@ -788,9 +788,9 @@ void Component::internalMoved (int xpos, int ypos) moved(); } -void Component::internalContentScaleChanged(float dpiScale) +void Component::internalContentScaleChanged (float dpiScale) { - contentScaleChanged(dpiScale); + contentScaleChanged (dpiScale); } void Component::internalUserTriedToCloseWindow() diff --git a/modules/yup_gui/component/yup_Component.h b/modules/yup_gui/component/yup_Component.h index ded6d0dc8..5f47dd6cc 100644 --- a/modules/yup_gui/component/yup_Component.h +++ b/modules/yup_gui/component/yup_Component.h @@ -74,7 +74,7 @@ class JUCE_API Component //============================================================================== float getScaleDpi() const; - virtual void contentScaleChanged(float dpiScale); + virtual void contentScaleChanged (float dpiScale); //============================================================================== float getOpacity() const; @@ -200,7 +200,7 @@ class JUCE_API Component void internalTextInput (const String& text); void internalMoved (int xpos, int ypos); void internalResized (int width, int height); - void internalContentScaleChanged(float dpiScale); + void internalContentScaleChanged (float dpiScale); void internalUserTriedToCloseWindow(); friend class ComponentNative; diff --git a/modules/yup_gui/native/yup_Windowing_sdl2.cpp b/modules/yup_gui/native/yup_Windowing_sdl2.cpp index 3160c2895..d98fa5b3a 100644 --- a/modules/yup_gui/native/yup_Windowing_sdl2.cpp +++ b/modules/yup_gui/native/yup_Windowing_sdl2.cpp @@ -884,7 +884,7 @@ void SDL2ComponentNative::handleContentScaleChanged() handleResized (screenBounds.getWidth(), screenBounds.getHeight()); - component.internalContentScaleChanged(getScaleDpi()); + component.internalContentScaleChanged (getScaleDpi()); } void SDL2ComponentNative::handleUserTriedToCloseWindow() diff --git a/tests/juce_audio_devices/juce_AudioDeviceManager.cpp b/tests/juce_audio_devices/juce_AudioDeviceManager.cpp index bfc1f580f..6239c928d 100644 --- a/tests/juce_audio_devices/juce_AudioDeviceManager.cpp +++ b/tests/juce_audio_devices/juce_AudioDeviceManager.cpp @@ -192,9 +192,9 @@ class MockDeviceType final : public AudioIODeviceType void restartDevices (double newSr, int newBs) { listeners.call ([&] (auto& l) - { - return l.restart (newSr, newBs); - }); + { + return l.restart (newSr, newBs); + }); } private: diff --git a/tests/juce_core/juce_AbstractFifo.cpp b/tests/juce_core/juce_AbstractFifo.cpp index b5c6273bf..8ee7ef998 100644 --- a/tests/juce_core/juce_AbstractFifo.cpp +++ b/tests/juce_core/juce_AbstractFifo.cpp @@ -79,9 +79,9 @@ struct WriteThread : public Thread || (writer.startIndex2 >= 0 && writer.startIndex2 < fifo.getTotalSize())); writer.forEach ([this, &n] (int index) - { - this->buffer[index] = n++; - }); + { + this->buffer[index] = n++; + }); } } @@ -117,9 +117,9 @@ TEST (AbstractFifoTests, BasicFunctionality) bool failed = false; reader.forEach ([&failed, &buffer, &n] (int index) - { - failed = (buffer[index] != n++) || failed; - }); + { + failed = (buffer[index] != n++) || failed; + }); ASSERT_FALSE (failed) << "Read values were incorrect"; } @@ -340,9 +340,9 @@ TEST (AbstractFifoTests, AbstractFifoThreaded) || (writer.startIndex2 >= 0 && writer.startIndex2 < fifo.getTotalSize())); writer.forEach ([this, &n] (int index) - { - this->buffer[index] = n++; - }); + { + this->buffer[index] = n++; + }); } } @@ -379,9 +379,9 @@ TEST (AbstractFifoTests, AbstractFifoThreaded) bool failed = false; reader.forEach ([&failed, &buffer, &n] (int index) - { - failed = (buffer[index] != n++) || failed; - }); + { + failed = (buffer[index] != n++) || failed; + }); if (failed) { diff --git a/tests/juce_core/juce_CharacterFunctions.cpp b/tests/juce_core/juce_CharacterFunctions.cpp index 585c70508..df3da341f 100644 --- a/tests/juce_core/juce_CharacterFunctions.cpp +++ b/tests/juce_core/juce_CharacterFunctions.cpp @@ -357,11 +357,11 @@ class CharacterFunctionsTests : public ::testing::Test auto nans = asciiToMemoryBlocks (nanCharPtrs, true); withAllPrefixesAndSuffixes (prefixes, separators.terminals, nans, [this] (const MemoryBlock& data, const MemoryBlock& suffix) - { - CharPointerType charPtr { (CharType*) data.getData() }; - EXPECT_TRUE (std::isnan (CharacterFunctions::readDoubleValue (charPtr))); - EXPECT_TRUE (*charPtr == *(CharPointerType ((CharType*) suffix.getData()))); - }); + { + CharPointerType charPtr { (CharType*) data.getData() }; + EXPECT_TRUE (std::isnan (CharacterFunctions::readDoubleValue (charPtr))); + EXPECT_TRUE (*charPtr == *(CharPointerType ((CharType*) suffix.getData()))); + }); } { @@ -369,13 +369,13 @@ class CharacterFunctionsTests : public ::testing::Test auto infs = asciiToMemoryBlocks (infCharPtrs, true); withAllPrefixesAndSuffixes (prefixes, separators.terminals, infs, [this] (const MemoryBlock& data, const MemoryBlock& suffix) - { - CharPointerType charPtr { (CharType*) data.getData() }; - auto expected = charPtr[0] == '-' ? -std::numeric_limits::infinity() - : std::numeric_limits::infinity(); - EXPECT_EQ (CharacterFunctions::readDoubleValue (charPtr), expected); - EXPECT_TRUE (*charPtr == *(CharPointerType ((CharType*) suffix.getData()))); - }); + { + CharPointerType charPtr { (CharType*) data.getData() }; + auto expected = charPtr[0] == '-' ? -std::numeric_limits::infinity() + : std::numeric_limits::infinity(); + EXPECT_EQ (CharacterFunctions::readDoubleValue (charPtr), expected); + EXPECT_TRUE (*charPtr == *(CharPointerType ((CharType*) suffix.getData()))); + }); } { @@ -383,12 +383,12 @@ class CharacterFunctionsTests : public ::testing::Test auto zeros = asciiToMemoryBlocks (zeroCharPtrs, true); withAllPrefixesAndSuffixes (prefixes, separators.terminals, zeros, [this] (const MemoryBlock& data, const MemoryBlock& suffix) - { - CharPointerType charPtr { (CharType*) data.getData() }; - auto expected = charPtr[0] == '-' ? -0.0 : 0.0; - EXPECT_EQ (CharacterFunctions::readDoubleValue (charPtr), expected); - EXPECT_TRUE (*charPtr == *(CharPointerType ((CharType*) suffix.getData()))); - }); + { + CharPointerType charPtr { (CharType*) data.getData() }; + auto expected = charPtr[0] == '-' ? -0.0 : 0.0; + EXPECT_EQ (CharacterFunctions::readDoubleValue (charPtr), expected); + EXPECT_TRUE (*charPtr == *(CharPointerType ((CharType*) suffix.getData()))); + }); } { diff --git a/tests/juce_core/juce_DynamicObject.cpp b/tests/juce_core/juce_DynamicObject.cpp index 07a6b5e11..4bf919f48 100644 --- a/tests/juce_core/juce_DynamicObject.cpp +++ b/tests/juce_core/juce_DynamicObject.cpp @@ -129,14 +129,14 @@ TEST_F (DynamicObjectTests, SetAndHasMethod) EXPECT_FALSE (obj.hasMethod (methodName)); var::NativeFunction func = createNativeFunction ([] (const var::NativeFunctionArgs& args) -> var - { - if (args.numArguments > 0) - { - double currentVolume = args.arguments[0]; - return var (currentVolume + 10.0); - } - return var(); - }); + { + if (args.numArguments > 0) + { + double currentVolume = args.arguments[0]; + return var (currentVolume + 10.0); + } + return var(); + }); obj.setMethod (methodName, func); EXPECT_TRUE (obj.hasMethod (methodName)); @@ -150,15 +150,15 @@ TEST_F (DynamicObjectTests, InvokeMethod) // Define a method that multiplies two numbers var::NativeFunction multiplyFunc = createNativeFunction ([] (const var::NativeFunctionArgs& args) -> var - { - if (args.numArguments >= 2) - { - double a = args.arguments[0]; - double b = args.arguments[1]; - return var (a * b); - } - return var(); - }); + { + if (args.numArguments >= 2) + { + double a = args.arguments[0]; + double b = args.arguments[1]; + return var (a * b); + } + return var(); + }); obj->setMethod (methodName, multiplyFunc); EXPECT_TRUE (obj->hasMethod (methodName)); @@ -279,14 +279,14 @@ TEST_F (DynamicObjectTests, OverwriteMethod) Identifier methodName ("greet"); var::NativeFunction greetFunc1 = createNativeFunction ([] (const var::NativeFunctionArgs& args) -> var - { - return var ("Hello"); - }); + { + return var ("Hello"); + }); var::NativeFunction greetFunc2 = createNativeFunction ([] (const var::NativeFunctionArgs& args) -> var - { - return var ("Hi"); - }); + { + return var ("Hi"); + }); obj->setMethod (methodName, greetFunc1); EXPECT_TRUE (obj->hasMethod (methodName)); @@ -311,15 +311,15 @@ TEST_F (DynamicObjectTests, InvokeMethodInsufficientArguments) Identifier methodName ("sum"); var::NativeFunction sumFunc = createNativeFunction ([] (const var::NativeFunctionArgs& args) -> var - { - if (args.numArguments >= 2) - { - double a = args.arguments[0]; - double b = args.arguments[1]; - return var (a + b); - } - return var(); - }); + { + if (args.numArguments >= 2) + { + double a = args.arguments[0]; + double b = args.arguments[1]; + return var (a + b); + } + return var(); + }); obj->setMethod (methodName, sumFunc); @@ -355,10 +355,10 @@ TEST_F (DynamicObjectTests, SetMethodWithLambdaCapture) double externalCounter = 0.0; var::NativeFunction incrementFunc = createNativeFunction ([&externalCounter] (const var::NativeFunctionArgs& args) -> var - { - externalCounter += 1.0; - return var (externalCounter); - }); + { + externalCounter += 1.0; + return var (externalCounter); + }); obj->setMethod (methodName, incrementFunc); EXPECT_TRUE (obj->hasMethod (methodName)); @@ -457,9 +457,9 @@ TEST_F (DynamicObjectTests, InvokeMethodAfterRemoval) Identifier methodName ("sayHello"); var::NativeFunction sayHelloFunc = createNativeFunction ([] (const var::NativeFunctionArgs& args) -> var - { - return var ("Hello, World!"); - }); + { + return var ("Hello, World!"); + }); obj->setMethod (methodName, sayHelloFunc); EXPECT_TRUE (obj->hasMethod (methodName)); @@ -497,9 +497,9 @@ TEST_F (DynamicObjectTests, SetMethodWithIdentifierAndFunction) Identifier methodName ("getStatus"); var::NativeFunction getStatusFunc = createNativeFunction ([] (const var::NativeFunctionArgs& args) -> var - { - return var ("OK"); - }); + { + return var ("OK"); + }); obj->setMethod (methodName, getStatusFunc); EXPECT_TRUE (obj->hasMethod (methodName)); @@ -533,9 +533,9 @@ TEST_F (DynamicObjectTests, PropertiesAndMethodsAreNotSeparate) var propValue = makeVar (1); var::NativeFunction statusFunc = createNativeFunction ([] (const var::NativeFunctionArgs& args) -> var - { - return var ("Method Status"); - }); + { + return var ("Method Status"); + }); obj->setProperty (propName, propValue); obj->setMethod (methodName, statusFunc); @@ -558,15 +558,15 @@ TEST_F (DynamicObjectTests, InvokeMethodWithArguments) Identifier methodName ("concat"); var::NativeFunction concatFunc = createNativeFunction ([] (const var::NativeFunctionArgs& args) -> var - { - if (args.numArguments >= 2) - { - String a = args.arguments[0]; - String b = args.arguments[1]; - return var (a + b); - } - return var(); - }); + { + if (args.numArguments >= 2) + { + String a = args.arguments[0]; + String b = args.arguments[1]; + return var (a + b); + } + return var(); + }); obj->setMethod (methodName, concatFunc); @@ -627,9 +627,9 @@ TEST_F (DynamicObjectTests, ClearRemovesMethods) Identifier methodName ("doSomething"); var::NativeFunction func = createNativeFunction ([] (const var::NativeFunctionArgs& args) -> var - { - return var ("Done"); - }); + { + return var ("Done"); + }); obj->setMethod (methodName, func); EXPECT_TRUE (obj->hasMethod (methodName)); @@ -647,9 +647,9 @@ TEST_F (DynamicObjectTests, ClearDoesNotAffectOtherProperties) obj->setProperty (propName, makeVar (999)); var::NativeFunction func = createNativeFunction ([] (const var::NativeFunctionArgs& args) -> var - { - return var ("Removed"); - }); + { + return var ("Removed"); + }); obj->setMethod (methodName, func); EXPECT_TRUE (obj->hasProperty (propName)); @@ -669,9 +669,9 @@ TEST_F (DynamicObjectTests, DISABLED_WriteAsJSONExcludesMethods) Identifier methodName ("method"); var::NativeFunction func = createNativeFunction ([] (const var::NativeFunctionArgs& args) -> var - { - return var ("MethodResult"); - }); + { + return var ("MethodResult"); + }); obj->setMethod (methodName, func); MemoryOutputStream stream; @@ -693,9 +693,9 @@ TEST_F (DynamicObjectTests, SetMethodDoesNotClearPropertiesFlag) Identifier methodName ("activate"); var::NativeFunction func = createNativeFunction ([] (const var::NativeFunctionArgs& args) -> var - { - return var ("Activated"); - }); + { + return var ("Activated"); + }); obj->setMethod (methodName, func); EXPECT_TRUE (obj->hasProperty (propName)); @@ -715,14 +715,14 @@ TEST_F (DynamicObjectTests, InvokeMethodDoesNotAffectOtherProperties) obj->setProperty (propName, makeVar (0)); var::NativeFunction incrementFunc = createNativeFunction ([] (const var::NativeFunctionArgs& args) -> var - { - if (args.numArguments > 0) - { - double current = args.arguments[0]; - return var (current + 1.0); - } - return var(); - }); + { + if (args.numArguments > 0) + { + double current = args.arguments[0]; + return var (current + 1.0); + } + return var(); + }); obj->setMethod (methodName, incrementFunc); diff --git a/tests/juce_core/juce_ListenerList.cpp b/tests/juce_core/juce_ListenerList.cpp index 4abf218a5..12df2e339 100644 --- a/tests/juce_core/juce_ListenerList.cpp +++ b/tests/juce_core/juce_ListenerList.cpp @@ -91,9 +91,9 @@ class ListenerListTests : public ::testing::Test { ++callLevel; listenerList.call ([] (auto& l) - { - l.doCallback(); - }); + { + l.doCallback(); + }); --callLevel; } @@ -106,9 +106,9 @@ class ListenerListTests : public ::testing::Test bool wereAllNonRemovedListenersCalled (int numCalls) const { return std::all_of (std::begin (listeners), std::end (listeners), [&] (auto& listener) - { - return (! listenerList.contains (listener.get())) || listener->getNumCalls() == numCalls; - }); + { + return (! listenerList.contains (listener.get())) || listener->getNumCalls() == numCalls; + }); } private: @@ -347,9 +347,9 @@ TEST_F (ListenerListTests, Call_During_Callback) EXPECT_CALL (listener1, myCallbackMethod (1234, true)) .WillOnce (testing::Invoke ([&] (int, bool) - { - listeners.add (&listener1); - })); + { + listeners.add (&listener1); + })); EXPECT_CALL (listener2, myCallbackMethod (1234, true)).Times (1); listeners.call (&MockListener::myCallbackMethod, 1234, true); @@ -366,9 +366,9 @@ TEST_F (ListenerListTests, Remove_During_Callback) EXPECT_CALL (listener1, myCallbackMethod (1234, true)) .WillOnce (testing::Invoke ([&] (int, bool) - { - listeners.remove (&listener2); - })); + { + listeners.remove (&listener2); + })); EXPECT_CALL (listener2, myCallbackMethod (1234, true)).Times (0); @@ -386,9 +386,9 @@ TEST_F (ListenerListTests, Clear_During_Callback) listeners.add (&listener2); EXPECT_CALL (listener1, myCallbackMethod (1234, true)).Times (1).WillOnce (testing::Invoke ([&] (int, bool) - { - listeners.clear(); - })); + { + listeners.clear(); + })); EXPECT_CALL (listener2, myCallbackMethod (1234, true)).Times (0); listeners.call (&MockListener::myCallbackMethod, 1234, true); @@ -404,9 +404,9 @@ TEST_F (ListenerListTests, Nested_Call) listeners.add (&listener2); EXPECT_CALL (listener1, myCallbackMethod (1234, true)).Times (1).WillOnce (testing::Invoke ([&] (int, bool) - { - listeners.call (&MockListener::myCallbackMethod, 5678, false); - })); + { + listeners.call (&MockListener::myCallbackMethod, 5678, false); + })); EXPECT_CALL (listener2, myCallbackMethod (1234, true)).Times (1); EXPECT_CALL (listener1, myCallbackMethod (5678, false)).Times (1); EXPECT_CALL (listener2, myCallbackMethod (5678, false)).Times (1); @@ -420,10 +420,10 @@ TEST_F (ListenerListTests, RemovingAlreadyCalledListener) for (int i = 0; i < 20; ++i) { test.addListener ([i, &test] - { - if (i == 5) - test.removeListener (6); - }); + { + if (i == 5) + test.removeListener (6); + }); } test.callListeners(); @@ -436,10 +436,10 @@ TEST_F (ListenerListTests, RemovingYetUncalledListener) for (int i = 0; i < 20; ++i) { test.addListener ([i, &test] - { - if (i == 5) - test.removeListener (4); - }); + { + if (i == 5) + test.removeListener (4); + }); } test.callListeners(); @@ -452,13 +452,13 @@ TEST_F (ListenerListTests, RemoveMultipleListenersInCallback) for (int i = 0; i < 20; ++i) { test.addListener ([i, &test] - { - if (i == 19) - { - test.removeListener (19); - test.removeListener (0); - } - }); + { + if (i == 19) + { + test.removeListener (19); + test.removeListener (0); + } + }); } test.callListeners(); @@ -481,14 +481,14 @@ TEST_F (ListenerListTests, RemovingListenersRandomly) for (int i = 0; i < numListeners; ++i) { test.addListener ([i, &removals, &test] - { - const auto iter = removals.find (i); - if (iter == removals.end()) - return; - - for (auto j : iter->second) - test.removeListener (j); - }); + { + const auto iter = removals.find (i); + if (iter == removals.end()) + return; + + for (auto j : iter->second) + test.removeListener (j); + }); } test.callListeners(); @@ -503,10 +503,10 @@ TEST_F (ListenerListTests, AddListenerDuringIteration) for (int i = 0; i < numStartingListeners; ++i) { test.addListener ([i, &test] - { - if (i == 5 || i == 6) - test.addListener ([] {}); - }); + { + if (i == 5 || i == 6) + test.addListener ([] {}); + }); } test.callListeners(); @@ -527,19 +527,19 @@ TEST_F (ListenerListTests, NestedCall) for (int i = 0; i < 20; ++i) { test.addListener ([i, &test] - { - const auto callLevel = test.getCallLevel(); - if (i == 6 && callLevel == 1) - test.callListeners(); - - if (i == 5) - { - if (callLevel == 1) - test.removeListener (4); - else if (callLevel == 2) - test.removeListener (6); - } - }); + { + const auto callLevel = test.getCallLevel(); + if (i == 6 && callLevel == 1) + test.callListeners(); + + if (i == 5) + { + if (callLevel == 1) + test.removeListener (4); + else if (callLevel == 2) + test.removeListener (6); + } + }); } test.callListeners(); @@ -560,21 +560,21 @@ TEST_F (ListenerListTests, RandomCall) for (int i = 0; i < numListeners; ++i) { test.addListener ([&] - { - const auto callLevel = test.getCallLevel(); - if (callLevel < 4 && random.nextFloat() < 0.05f) - { - ++numCalls; - test.callListeners(); - } - - if (random.nextFloat() < 0.5f) - { - const auto listenerToRemove = random.nextInt ({ 0, numListeners }); - if (listenersToRemove.erase (listenerToRemove) > 0) - test.removeListener (listenerToRemove); - } - }); + { + const auto callLevel = test.getCallLevel(); + if (callLevel < 4 && random.nextFloat() < 0.05f) + { + ++numCalls; + test.callListeners(); + } + + if (random.nextFloat() < 0.5f) + { + const auto listenerToRemove = random.nextInt ({ 0, numListeners }); + if (listenersToRemove.erase (listenerToRemove) > 0) + test.removeListener (listenerToRemove); + } + }); } while (listenersToRemove.size() > 0) @@ -629,17 +629,17 @@ TEST_F (ListenerListTests, BailOutChecker) bool listener3Called = false; Listener listener1 { [&] - { - listener1Called = true; - } }; + { + listener1Called = true; + } }; Listener listener2 { [&] - { - listener2Called = true; - } }; + { + listener2Called = true; + } }; Listener listener3 { [&] - { - listener3Called = true; - } }; + { + listener3Called = true; + } }; listeners.add (&listener1); listeners.add (&listener2); @@ -732,15 +732,15 @@ TEST_F (ListenerListTests, AddListenerDuringCallback) bool listenerCalled = false; listeners.call ([&] (auto& l) - { - listeners.remove (&l); - EXPECT_EQ (listeners.size(), 0); + { + listeners.remove (&l); + EXPECT_EQ (listeners.size(), 0); - listeners.add (&l); - EXPECT_EQ (listeners.size(), 1); + listeners.add (&l); + EXPECT_EQ (listeners.size(), 1); - listenerCalled = true; - }); + listenerCalled = true; + }); EXPECT_TRUE (listenerCalled); EXPECT_EQ (listeners.size(), 1); @@ -764,13 +764,13 @@ TEST_F (ListenerListTests, ClearListenersDuringCallback) bool called = false; Listener listener1 { [&] - { - listeners.clear(); - } }; + { + listeners.clear(); + } }; Listener listener2 { [&] - { - called = true; - } }; + { + called = true; + } }; listeners.add (&listener1); listeners.add (&listener2); @@ -809,9 +809,9 @@ TEST_F (ListenerListTests, ThreadSafeAddRemoveListeners) { for (int i = 0; i < 1000; ++i) listeners.call ([] (MyListenerType& l) - { - l.myCallbackMethod (1234, true); - }); + { + l.myCallbackMethod (1234, true); + }); }; std::thread thread1 (addListeners); @@ -838,9 +838,9 @@ TEST_F (ListenerListTests, ThreadSafeCallListeners) { for (int i = 0; i < 1000; ++i) listeners.call ([] (MyListenerType& l) - { - l.myCallbackMethod (1234, true); - }); + { + l.myCallbackMethod (1234, true); + }); }; std::thread thread1 (callListeners); @@ -868,9 +868,9 @@ TEST_F (ListenerListTests, ThreadSafeAddRemoveWhileCalling) { for (int i = 0; i < 1000; ++i) listeners.call ([] (MyListenerType& l) - { - l.myCallbackMethod (1234, true); - }); + { + l.myCallbackMethod (1234, true); + }); }; auto addRemoveListeners = [&] diff --git a/tests/juce_core/juce_Variant.cpp b/tests/juce_core/juce_Variant.cpp index c38d18001..566b1edda 100644 --- a/tests/juce_core/juce_Variant.cpp +++ b/tests/juce_core/juce_Variant.cpp @@ -233,9 +233,9 @@ TEST_F (VariantTests, IsTypeMethods) var vBinaryData { MemoryBlock() }; var vObject { new DynamicObject() }; var vMethod { createNativeFunction ([] (const var::NativeFunctionArgs&) -> var - { - return var(); - }) }; + { + return var(); + }) }; EXPECT_TRUE (vVoid.isVoid()); EXPECT_FALSE (vVoid.isUndefined()); @@ -448,10 +448,10 @@ TEST_F (VariantTests, MethodOperations) double counter = 0.0; var::NativeFunction incrementFunc = createNativeFunction ([&counter] (const var::NativeFunctionArgs& args) -> var - { - counter += 1.0; - return var (counter); - }); + { + counter += 1.0; + return var (counter); + }); obj->setMethod (methodName, incrementFunc); @@ -570,15 +570,15 @@ TEST_F (VariantTests, InvokeMethodWithArguments) Identifier methodName ("add"); var::NativeFunction addFunc = createNativeFunction ([] (const var::NativeFunctionArgs& args) -> var - { - if (args.numArguments >= 2 && args.arguments[0].isDouble() && args.arguments[1].isDouble()) - { - double a = args.arguments[0]; - double b = args.arguments[1]; - return var (a + b); - } - return var(); - }); + { + if (args.numArguments >= 2 && args.arguments[0].isDouble() && args.arguments[1].isDouble()) + { + double a = args.arguments[0]; + double b = args.arguments[1]; + return var (a + b); + } + return var(); + }); obj->setMethod (methodName, addFunc); @@ -625,9 +625,9 @@ TEST_F (VariantTests, InvokeMethodReturnsString) Identifier methodName ("greet"); var::NativeFunction greetFunc = createNativeFunction ([] (const var::NativeFunctionArgs& args) -> var - { - return var ("Hello, JUCE!"); - }); + { + return var ("Hello, JUCE!"); + }); obj->setMethod (methodName, greetFunc); @@ -739,10 +739,10 @@ TEST_F (VariantTests, InvokeMethodModifiesExternalState) int counter = 0; var::NativeFunction increaseFunc = createNativeFunction ([&counter] (const var::NativeFunctionArgs& args) -> var - { - counter += 5; - return var (counter); - }); + { + counter += 5; + return var (counter); + }); obj->setMethod (methodName, increaseFunc); @@ -867,15 +867,15 @@ TEST_F (VariantTests, MethodWithMultipleArguments) Identifier methodName ("multiply"); var::NativeFunction multiplyFunc = createNativeFunction ([] (const var::NativeFunctionArgs& args) -> var - { - if (args.numArguments >= 2 && args.arguments[0].isDouble() && args.arguments[1].isDouble()) - { - double a = args.arguments[0]; - double b = args.arguments[1]; - return var (a * b); - } - return var(); - }); + { + if (args.numArguments >= 2 && args.arguments[0].isDouble() && args.arguments[1].isDouble()) + { + double a = args.arguments[0]; + double b = args.arguments[1]; + return var (a * b); + } + return var(); + }); obj->setMethod (methodName, multiplyFunc); @@ -916,9 +916,9 @@ TEST_F (VariantTests, MethodReturnsObject) Identifier methodName ("getChild"); var::NativeFunction getChildFunc = createNativeFunction ([childObj] (const var::NativeFunctionArgs& args) -> var - { - return var (childObj); - }); + { + return var (childObj); + }); parentObj->setMethod (methodName, getChildFunc); @@ -942,16 +942,16 @@ TEST_F (VariantTests, MethodReturnsMethod) Identifier innerMethod ("inner"); var::NativeFunction innerFunc = createNativeFunction ([] (const var::NativeFunctionArgs& args) -> var - { - return var ("Inner Method Called"); - }); + { + return var ("Inner Method Called"); + }); var::NativeFunction outerFunc = createNativeFunction ([innerFunc, &innerMethod] (const var::NativeFunctionArgs& args) -> var - { - DynamicObject::Ptr innerObj = new DynamicObject(); - innerObj->setMethod (innerMethod, innerFunc); - return var (innerObj); - }); + { + DynamicObject::Ptr innerObj = new DynamicObject(); + innerObj->setMethod (innerMethod, innerFunc); + return var (innerObj); + }); obj->setMethod (outerMethod, outerFunc); @@ -1024,10 +1024,10 @@ TEST_F (VariantTests, MethodReturnsVoid) Identifier methodName ("doNothing"); var::NativeFunction doNothingFunc = createNativeFunction ([] (const var::NativeFunctionArgs& args) -> var - { - // Does nothing, returns void - return var(); - }); + { + // Does nothing, returns void + return var(); + }); obj->setMethod (methodName, doNothingFunc); @@ -1069,13 +1069,13 @@ TEST_F (VariantTests, InvokeMethodWithIncorrectArguments) Identifier methodName ("concat"); var::NativeFunction concatFunc = createNativeFunction ([] (const var::NativeFunctionArgs& args) -> var - { - if (args.numArguments >= 2 && args.arguments[0].isString() && args.arguments[1].isString()) - { - return var (args.arguments[0].toString() + args.arguments[1].toString()); - } - return var(); - }); + { + if (args.numArguments >= 2 && args.arguments[0].isString() && args.arguments[1].isString()) + { + return var (args.arguments[0].toString() + args.arguments[1].toString()); + } + return var(); + }); obj->setMethod (methodName, concatFunc); @@ -1131,13 +1131,13 @@ TEST_F (VariantTests, MethodReturnsArray) Identifier methodName ("createArray"); var::NativeFunction createArrayFunc = createNativeFunction ([] (const var::NativeFunctionArgs& args) -> var - { - Array array; - array.add (1); - array.add (2); - array.add (3); - return var (array); - }); + { + Array array; + array.add (1); + array.add (2); + array.add (3); + return var (array); + }); obj->setMethod (methodName, createArrayFunc); @@ -1159,15 +1159,15 @@ TEST_F (VariantTests, InvokeMethodWithExtraArguments) Identifier methodName ("sum"); var::NativeFunction sumFunc = createNativeFunction ([] (const var::NativeFunctionArgs& args) -> var - { - double total = 0.0; - for (int i = 0; i < args.numArguments; ++i) - { - if (args.arguments[i].isDouble()) - total += static_cast (args.arguments[i]); - } - return var (total); - }); + { + double total = 0.0; + for (int i = 0; i < args.numArguments; ++i) + { + if (args.arguments[i].isDouble()) + total += static_cast (args.arguments[i]); + } + return var (total); + }); obj->setMethod (methodName, sumFunc); @@ -1324,9 +1324,9 @@ TEST_F (VariantTests, InvokeMethodWithNullArguments) Identifier methodName ("sayHello"); var::NativeFunction sayHelloFunc = createNativeFunction ([] (const var::NativeFunctionArgs& args) -> var - { - return var ("Hello!"); - }); + { + return var ("Hello!"); + }); obj->setMethod (methodName, sayHelloFunc); @@ -1422,22 +1422,22 @@ TEST_F (VariantTests, MethodReturnsAnotherMethod) Identifier innerMethod ("multiply"); var::NativeFunction multiplyFunc = createNativeFunction ([] (const var::NativeFunctionArgs& args) -> var - { - if (args.numArguments >= 2 && args.arguments[0].isDouble() && args.arguments[1].isDouble()) - { - double a = args.arguments[0]; - double b = args.arguments[1]; - return var (a * b); - } - return var(); - }); + { + if (args.numArguments >= 2 && args.arguments[0].isDouble() && args.arguments[1].isDouble()) + { + double a = args.arguments[0]; + double b = args.arguments[1]; + return var (a * b); + } + return var(); + }); var::NativeFunction getMultiplierFunc = createNativeFunction ([multiplyFunc] (const var::NativeFunctionArgs& args) -> var - { - DynamicObject::Ptr multiplierObj = new DynamicObject(); - multiplierObj->setMethod ("multiply", multiplyFunc); - return var (multiplierObj); - }); + { + DynamicObject::Ptr multiplierObj = new DynamicObject(); + multiplierObj->setMethod ("multiply", multiplyFunc); + return var (multiplierObj); + }); obj->setMethod (outerMethod, getMultiplierFunc); @@ -1460,9 +1460,9 @@ TEST_F (VariantTests, CloneMethodVar) Identifier methodName ("getValue"); var::NativeFunction getValueFunc = createNativeFunction ([] (const var::NativeFunctionArgs& args) -> var - { - return var (999); - }); + { + return var (999); + }); obj->setMethod (methodName, getValueFunc); @@ -1533,15 +1533,15 @@ TEST_F (VariantTests, CallMethodsWithVaryingArguments) Identifier methodName ("concatenate"); var::NativeFunction concatenateFunc = createNativeFunction ([] (const var::NativeFunctionArgs& args) -> var - { - std::string result; - for (int i = 0; i < args.numArguments; ++i) - { - if (args.arguments[i].isString()) - result += args.arguments[i].toString().toStdString(); - } - return var (result); - }); + { + std::string result; + for (int i = 0; i < args.numArguments; ++i) + { + if (args.arguments[i].isString()) + result += args.arguments[i].toString().toStdString(); + } + return var (result); + }); obj->setMethod (methodName, concatenateFunc); @@ -1565,15 +1565,15 @@ TEST_F (VariantTests, InvokeMethodVariousSignatures) Identifier methodName ("compute"); var::NativeFunction computeFunc = createNativeFunction ([] (const var::NativeFunctionArgs& args) -> var - { - if (args.numArguments == 0) - return var (0); - if (args.numArguments == 1 && args.arguments[0].isInt()) - return var (static_cast (args.arguments[0]) * 2); - if (args.numArguments == 2 && args.arguments[0].isInt() && args.arguments[1].isInt()) - return var (static_cast (args.arguments[0]) + static_cast (args.arguments[1])); - return var(); - }); + { + if (args.numArguments == 0) + return var (0); + if (args.numArguments == 1 && args.arguments[0].isInt()) + return var (static_cast (args.arguments[0]) * 2); + if (args.numArguments == 2 && args.arguments[0].isInt() && args.arguments[1].isInt()) + return var (static_cast (args.arguments[0]) + static_cast (args.arguments[1])); + return var(); + }); obj->setMethod (methodName, computeFunc); @@ -1636,15 +1636,15 @@ TEST_F (VariantTests, MethodReturnsFunction) Identifier methodName ("getAdder"); var::NativeFunction adderFunc = createNativeFunction ([] (const var::NativeFunctionArgs& args) -> var - { - return var::NativeFunction ([] (const var::NativeFunctionArgs& innerArgs) -> var - { - if (innerArgs.numArguments >= 1 && innerArgs.arguments[0].isInt()) - return var (static_cast (innerArgs.arguments[0]) + 10); + { + return var::NativeFunction ([] (const var::NativeFunctionArgs& innerArgs) -> var + { + if (innerArgs.numArguments >= 1 && innerArgs.arguments[0].isInt()) + return var (static_cast (innerArgs.arguments[0]) + 10); - return var(); - }); - }); + return var(); + }); + }); obj->setMethod (methodName, adderFunc); @@ -1666,9 +1666,9 @@ TEST_F (VariantTests, MethodReturnsUndefined) Identifier methodName ("returnUndefined"); var::NativeFunction undefinedFunc = createNativeFunction ([] (const var::NativeFunctionArgs& args) -> var - { - return var::undefined(); - }); + { + return var::undefined(); + }); obj->setMethod (methodName, undefinedFunc); From 8af0533ffc0799ed302cc44eb09e817e7182cdb7 Mon Sep 17 00:00:00 2001 From: Yup Bot Date: Sun, 6 Apr 2025 16:29:27 +0000 Subject: [PATCH 13/22] Code formatting --- examples/render/source/main.cpp | 2 +- .../native/juce_ALSA_linux.cpp | 18 +++++----- .../native/juce_ASIO_windows.cpp | 4 +-- .../native/juce_Audio_android.cpp | 34 +++++++++---------- .../native/juce_Audio_ios.cpp | 4 ++- .../native/juce_DirectSound_windows.cpp | 22 ++++++------ .../native/juce_Midi_windows.cpp | 4 ++- .../native/juce_Oboe_android.cpp | 12 ++++--- .../native/juce_OpenSL_android.cpp | 8 ++--- .../juce_HeavyweightLeakedObjectDetector.h | 8 ++--- .../memory/juce_LeakedObjectDetector.h | 8 ++--- .../juce_core/native/juce_SharedCode_posix.h | 21 ++++++------ modules/yup_gui/component/yup_Component.cpp | 4 +-- modules/yup_gui/component/yup_Component.h | 2 +- modules/yup_gui/native/yup_Windowing_sdl2.h | 4 ++- .../yup_gui/native/yup_Windowing_utils.cpp | 6 ++-- standalone/app/main.cpp | 2 +- 17 files changed, 86 insertions(+), 77 deletions(-) diff --git a/examples/render/source/main.cpp b/examples/render/source/main.cpp index ed8d39c68..0615e90b0 100644 --- a/examples/render/source/main.cpp +++ b/examples/render/source/main.cpp @@ -219,7 +219,7 @@ struct Application : yup::YUPApplication window->centreWithSize ({ 1280, 866 }); #endif window->setVisible (true); - window->toFront(true); + window->toFront (true); //window2 = std::make_unique(); //window2->centreWithSize ({ 300, 300 }); diff --git a/modules/juce_audio_devices/native/juce_ALSA_linux.cpp b/modules/juce_audio_devices/native/juce_ALSA_linux.cpp index 72c258a33..8981d7292 100644 --- a/modules/juce_audio_devices/native/juce_ALSA_linux.cpp +++ b/modules/juce_audio_devices/native/juce_ALSA_linux.cpp @@ -48,13 +48,13 @@ namespace #endif #if JUCE_ALSA_LOGGING -#define JUCE_ALSA_LOG(dbgtext) \ -{ \ -juce::String tempDbgBuf ("ALSA: "); \ -tempDbgBuf << dbgtext; \ -Logger::writeToLog (tempDbgBuf); \ -JUCE_DBG (tempDbgBuf); \ -} +#define JUCE_ALSA_LOG(dbgtext) \ + { \ + juce::String tempDbgBuf ("ALSA: "); \ + tempDbgBuf << dbgtext; \ + Logger::writeToLog (tempDbgBuf); \ + JUCE_DBG (tempDbgBuf); \ + } #define JUCE_CHECKED_RESULT(x) (logErrorMessage (x, __LINE__)) static int logErrorMessage (int err, int lineNum) @@ -65,7 +65,9 @@ static int logErrorMessage (int err, int lineNum) return err; } #else -#define JUCE_ALSA_LOG(x) {} +#define JUCE_ALSA_LOG(x) \ + { \ + } #define JUCE_CHECKED_RESULT(x) (x) #endif diff --git a/modules/juce_audio_devices/native/juce_ASIO_windows.cpp b/modules/juce_audio_devices/native/juce_ASIO_windows.cpp index 2027c6a32..709e90d35 100644 --- a/modules/juce_audio_devices/native/juce_ASIO_windows.cpp +++ b/modules/juce_audio_devices/native/juce_ASIO_windows.cpp @@ -107,8 +107,8 @@ static void dummyLog() #define JUCE_ASIO_LOG(msg) ASIODebugging::dummyLog() #define JUCE_ASIO_LOG_ERROR(msg, errNum) \ -ignoreUnused (errNum); \ -ASIODebugging::dummyLog() + ignoreUnused (errNum); \ + ASIODebugging::dummyLog() #endif } // namespace ASIODebugging diff --git a/modules/juce_audio_devices/native/juce_Audio_android.cpp b/modules/juce_audio_devices/native/juce_Audio_android.cpp index 1f21af306..e868fad46 100644 --- a/modules/juce_audio_devices/native/juce_Audio_android.cpp +++ b/modules/juce_audio_devices/native/juce_Audio_android.cpp @@ -40,29 +40,29 @@ namespace juce { -#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ -STATICMETHOD (getMinBufferSize, "getMinBufferSize", "(III)I") \ -STATICMETHOD (getNativeOutputSampleRate, "getNativeOutputSampleRate", "(I)I") \ -METHOD (constructor, "", "(IIIIII)V") \ -METHOD (getState, "getState", "()I") \ -METHOD (play, "play", "()V") \ -METHOD (stop, "stop", "()V") \ -METHOD (release, "release", "()V") \ -METHOD (flush, "flush", "()V") \ -METHOD (write, "write", "([SII)I") +#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ + STATICMETHOD (getMinBufferSize, "getMinBufferSize", "(III)I") \ + STATICMETHOD (getNativeOutputSampleRate, "getNativeOutputSampleRate", "(I)I") \ + METHOD (constructor, "", "(IIIIII)V") \ + METHOD (getState, "getState", "()I") \ + METHOD (play, "play", "()V") \ + METHOD (stop, "stop", "()V") \ + METHOD (release, "release", "()V") \ + METHOD (flush, "flush", "()V") \ + METHOD (write, "write", "([SII)I") DECLARE_JNI_CLASS (AudioTrack, "android/media/AudioTrack") #undef JNI_CLASS_MEMBERS //============================================================================== #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ -STATICMETHOD (getMinBufferSize, "getMinBufferSize", "(III)I") \ -METHOD (constructor, "", "(IIIII)V") \ -METHOD (getState, "getState", "()I") \ -METHOD (startRecording, "startRecording", "()V") \ -METHOD (stop, "stop", "()V") \ -METHOD (read, "read", "([SII)I") \ -METHOD (release, "release", "()V") + STATICMETHOD (getMinBufferSize, "getMinBufferSize", "(III)I") \ + METHOD (constructor, "", "(IIIII)V") \ + METHOD (getState, "getState", "()I") \ + METHOD (startRecording, "startRecording", "()V") \ + METHOD (stop, "stop", "()V") \ + METHOD (read, "read", "([SII)I") \ + METHOD (release, "release", "()V") DECLARE_JNI_CLASS (AudioRecord, "android/media/AudioRecord") #undef JNI_CLASS_MEMBERS diff --git a/modules/juce_audio_devices/native/juce_Audio_ios.cpp b/modules/juce_audio_devices/native/juce_Audio_ios.cpp index f67b2eb69..50cccf1cb 100644 --- a/modules/juce_audio_devices/native/juce_Audio_ios.cpp +++ b/modules/juce_audio_devices/native/juce_Audio_ios.cpp @@ -228,7 +228,9 @@ namespace juce #if JUCE_IOS_AUDIO_LOGGING #define JUCE_IOS_AUDIO_LOG(x) JUCE_DBG (x) #else -#define JUCE_IOS_AUDIO_LOG(x) {} +#define JUCE_IOS_AUDIO_LOG(x) \ + { \ + } #endif static void logNSError (NSError* e) diff --git a/modules/juce_audio_devices/native/juce_DirectSound_windows.cpp b/modules/juce_audio_devices/native/juce_DirectSound_windows.cpp index 8872e008b..bcd096f80 100644 --- a/modules/juce_audio_devices/native/juce_DirectSound_windows.cpp +++ b/modules/juce_audio_devices/native/juce_DirectSound_windows.cpp @@ -295,15 +295,15 @@ static void logError (HRESULT hr, int lineNum) //============================================================================== namespace { -#define DSOUND_FUNCTION(functionName, params) \ -typedef HRESULT (WINAPI* type##functionName) params; \ -static type##functionName ds##functionName = nullptr; +#define DSOUND_FUNCTION(functionName, params) \ + typedef HRESULT (WINAPI* type##functionName) params; \ + static type##functionName ds##functionName = nullptr; -#define DSOUND_FUNCTION_LOAD(functionName) \ -JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wcast-function-type") \ -ds##functionName = (type##functionName) GetProcAddress (h, #functionName); \ -JUCE_END_IGNORE_WARNINGS_GCC_LIKE \ -jassert (ds##functionName != nullptr); +#define DSOUND_FUNCTION_LOAD(functionName) \ + JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wcast-function-type") \ + ds##functionName = (type##functionName) GetProcAddress (h, #functionName); \ + JUCE_END_IGNORE_WARNINGS_GCC_LIKE \ + jassert (ds##functionName != nullptr); typedef BOOL (CALLBACK* LPDSENUMCALLBACKW) (LPGUID, LPCWSTR, LPCWSTR, LPVOID); typedef BOOL (CALLBACK* LPDSENUMCALLBACKA) (LPGUID, LPCSTR, LPCSTR, LPVOID); @@ -1433,9 +1433,9 @@ class DSoundAudioIODeviceType final : public AudioIODeviceType private: DeviceChangeDetector detector { L"DirectSound", [this] - { - systemDeviceChanged(); - } }; + { + systemDeviceChanged(); + } }; DSoundDeviceList deviceList; bool hasScanned = false; diff --git a/modules/juce_audio_devices/native/juce_Midi_windows.cpp b/modules/juce_audio_devices/native/juce_Midi_windows.cpp index 42a51e467..c1d201732 100644 --- a/modules/juce_audio_devices/native/juce_Midi_windows.cpp +++ b/modules/juce_audio_devices/native/juce_Midi_windows.cpp @@ -771,7 +771,9 @@ Array Win32MidiService::Mid #if JUCE_WINRT_MIDI_LOGGING #define JUCE_WINRT_MIDI_LOG(x) JUCE_DBG (x) #else -#define JUCE_WINRT_MIDI_LOG(x) {} +#define JUCE_WINRT_MIDI_LOG(x) \ + { \ + } #endif using namespace Microsoft::WRL; diff --git a/modules/juce_audio_devices/native/juce_Oboe_android.cpp b/modules/juce_audio_devices/native/juce_Oboe_android.cpp index bf6a96f94..9b153eb52 100644 --- a/modules/juce_audio_devices/native/juce_Oboe_android.cpp +++ b/modules/juce_audio_devices/native/juce_Oboe_android.cpp @@ -44,7 +44,9 @@ #if JUCE_OBOE_LOG_ENABLED #define JUCE_OBOE_LOG(x) JUCE_DBG (x) #else -#define JUCE_OBOE_LOG(x) {} +#define JUCE_OBOE_LOG(x) \ + { \ + } #endif namespace juce @@ -510,7 +512,7 @@ class OboeAudioIODevice final : public AudioIODevice startResult = stream->waitForStateChange (expectedState, &nextState, timeoutNanos); JUCE_OBOE_LOG ("Starting Oboe stream with result: " + getOboeString (startResult); - + "\nUses AAudio = " + String ((int) stream->usesAAudio()) + +"\nUses AAudio = " + String ((int) stream->usesAAudio()) + "\nDirection = " + getOboeString (stream->getDirection()) + "\nSharingMode = " + getOboeString (stream->getSharingMode()) + "\nChannelCount = " + String (stream->getChannelCount()) @@ -1434,9 +1436,9 @@ class OboeRealtimeThread final : private oboe::AudioStreamCallback threadEntryProc = nullptr; MessageManager::callAsync ([this]() - { - delete this; - }); + { + delete this; + }); return oboe::DataCallbackResult::Stop; } diff --git a/modules/juce_audio_devices/native/juce_OpenSL_android.cpp b/modules/juce_audio_devices/native/juce_OpenSL_android.cpp index 720499df9..6b9ed93fb 100644 --- a/modules/juce_audio_devices/native/juce_OpenSL_android.cpp +++ b/modules/juce_audio_devices/native/juce_OpenSL_android.cpp @@ -41,7 +41,7 @@ namespace juce { #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ -DECLARE_JNI_CLASS (AndroidAudioManager, "android/media/AudioManager") + DECLARE_JNI_CLASS (AndroidAudioManager, "android/media/AudioManager") #undef JNI_CLASS_MEMBERS //============================================================================== @@ -1386,9 +1386,9 @@ class SLRealtimeThread (*player)->SetPlayState (player, SL_PLAYSTATE_STOPPED); MessageManager::callAsync ([this]() - { - delete this; - }); + { + delete this; + }); } } diff --git a/modules/juce_core/memory/juce_HeavyweightLeakedObjectDetector.h b/modules/juce_core/memory/juce_HeavyweightLeakedObjectDetector.h index fd167a91e..6f3f14f43 100644 --- a/modules/juce_core/memory/juce_HeavyweightLeakedObjectDetector.h +++ b/modules/juce_core/memory/juce_HeavyweightLeakedObjectDetector.h @@ -151,10 +151,10 @@ class HeavyweightLeakedObjectDetector @see HeavyweightLeakedObjectDetector, JUCE_LEAK_DETECTOR, LeakedObjectDetector */ -#define JUCE_HEAVYWEIGHT_LEAK_DETECTOR(OwnerClass) \ -friend class juce::HeavyweightLeakedObjectDetector; \ -static const char* getLeakedObjectClassName() noexcept { return #OwnerClass; } \ -juce::HeavyweightLeakedObjectDetector JUCE_JOIN_MACRO (leakDetector, __LINE__); +#define JUCE_HEAVYWEIGHT_LEAK_DETECTOR(OwnerClass) \ + friend class juce::HeavyweightLeakedObjectDetector; \ + static const char* getLeakedObjectClassName() noexcept { return #OwnerClass; } \ + juce::HeavyweightLeakedObjectDetector JUCE_JOIN_MACRO (leakDetector, __LINE__); #else #define JUCE_HEAVYWEIGHT_LEAK_DETECTOR(OwnerClass) #endif diff --git a/modules/juce_core/memory/juce_LeakedObjectDetector.h b/modules/juce_core/memory/juce_LeakedObjectDetector.h index f8c85f2a9..1cc02cf57 100644 --- a/modules/juce_core/memory/juce_LeakedObjectDetector.h +++ b/modules/juce_core/memory/juce_LeakedObjectDetector.h @@ -148,10 +148,10 @@ class LeakedObjectDetector @see JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR, LeakedObjectDetector */ -#define JUCE_LEAK_DETECTOR(OwnerClass) \ -friend class juce::LeakedObjectDetector; \ -static const char* getLeakedObjectClassName() noexcept { return #OwnerClass; } \ -juce::LeakedObjectDetector JUCE_JOIN_MACRO (leakDetector, __LINE__); +#define JUCE_LEAK_DETECTOR(OwnerClass) \ + friend class juce::LeakedObjectDetector; \ + static const char* getLeakedObjectClassName() noexcept { return #OwnerClass; } \ + juce::LeakedObjectDetector JUCE_JOIN_MACRO (leakDetector, __LINE__); #else #define JUCE_LEAK_DETECTOR(OwnerClass) #endif diff --git a/modules/juce_core/native/juce_SharedCode_posix.h b/modules/juce_core/native/juce_SharedCode_posix.h index 21b9aea88..71c7c3fac 100644 --- a/modules/juce_core/native/juce_SharedCode_posix.h +++ b/modules/juce_core/native/juce_SharedCode_posix.h @@ -95,18 +95,18 @@ StringPairArray SystemStats::getEnvironmentVariables() void JUCE_CALLTYPE Thread::sleep (int millisecs) { while (millisecs > 0) - { - struct timespec time; - time.tv_sec = millisecs / 1000; - time.tv_nsec = (millisecs % 1000) * 1000000; + { + struct timespec time; + time.tv_sec = millisecs / 1000; + time.tv_nsec = (millisecs % 1000) * 1000000; - struct timespec remaining; + struct timespec remaining; - if (nanosleep (&time, &remaining) == -1) - millisecs = int (remaining.tv_sec * 1000 + time.tv_nsec / 1000000); - else + if (nanosleep (&time, &remaining) == -1) + millisecs = int (remaining.tv_sec * 1000 + time.tv_nsec / 1000000); + else break; - } + } } void JUCE_CALLTYPE Process::terminate() @@ -1074,8 +1074,7 @@ class PosixSchedulerPriority void apply ([[maybe_unused]] PosixThreadAttribute& attr) const { #if JUCE_LINUX || JUCE_BSD - const struct sched_param param - { + const struct sched_param param { getPriority() }; diff --git a/modules/yup_gui/component/yup_Component.cpp b/modules/yup_gui/component/yup_Component.cpp index aae79a5b8..049a2056c 100644 --- a/modules/yup_gui/component/yup_Component.cpp +++ b/modules/yup_gui/component/yup_Component.cpp @@ -418,7 +418,7 @@ void Component::removeFromDesktop() //============================================================================== -void Component::toFront(bool shouldGainKeyboardFocus) +void Component::toFront (bool shouldGainKeyboardFocus) { if (parentComponent == nullptr) return; @@ -557,7 +557,7 @@ void Component::removeChildComponent (Component* component) void Component::removeChildComponent (int index) { - if (! isPositiveAndBelow(index, children.size())) + if (! isPositiveAndBelow (index, children.size())) return; auto component = children.removeAndReturn (index); diff --git a/modules/yup_gui/component/yup_Component.h b/modules/yup_gui/component/yup_Component.h index 59962ed35..2d7879706 100644 --- a/modules/yup_gui/component/yup_Component.h +++ b/modules/yup_gui/component/yup_Component.h @@ -358,7 +358,7 @@ class JUCE_API Component /** Bring the component to the front. */ - void toFront(bool shouldGainKeyboardFocus); + void toFront (bool shouldGainKeyboardFocus); /** Bring the component to the back. diff --git a/modules/yup_gui/native/yup_Windowing_sdl2.h b/modules/yup_gui/native/yup_Windowing_sdl2.h index 579dc222a..0b750f31d 100644 --- a/modules/yup_gui/native/yup_Windowing_sdl2.h +++ b/modules/yup_gui/native/yup_Windowing_sdl2.h @@ -30,7 +30,9 @@ namespace yup #if YUP_WINDOWING_LOGGING #define YUP_WINDOWING_LOG(textToWrite) JUCE_DBG (textToWrite) #else -#define YUP_WINDOWING_LOG(textToWrite) {} +#define YUP_WINDOWING_LOG(textToWrite) \ + { \ + } #endif //============================================================================== diff --git a/modules/yup_gui/native/yup_Windowing_utils.cpp b/modules/yup_gui/native/yup_Windowing_utils.cpp index 9fc31c410..bda7cef73 100644 --- a/modules/yup_gui/native/yup_Windowing_utils.cpp +++ b/modules/yup_gui/native/yup_Windowing_utils.cpp @@ -199,11 +199,12 @@ KeyPress toKeyPress (SDL_Keycode key, SDL_Scancode scancode, KeyModifiers modifi return {}; } + // clang-format on //============================================================================== -bool isMouseOutsideWindow(SDL_Window* window) +bool isMouseOutsideWindow (SDL_Window* window) { int windowX, windowY, windowW, windowH; SDL_GetWindowPosition (window, &windowX, &windowY); @@ -212,8 +213,7 @@ bool isMouseOutsideWindow(SDL_Window* window) int mouseX, mouseY; Uint32 mouseState = SDL_GetGlobalMouseState (&mouseX, &mouseY); - return (mouseX < windowX || mouseX > windowX + windowW || - mouseY < windowY || mouseY > windowY + windowH); + return (mouseX < windowX || mouseX > windowX + windowW || mouseY < windowY || mouseY > windowY + windowH); } //============================================================================== diff --git a/standalone/app/main.cpp b/standalone/app/main.cpp index 64ea3df4b..a673e60f9 100644 --- a/standalone/app/main.cpp +++ b/standalone/app/main.cpp @@ -42,7 +42,7 @@ struct MyApplication : yup::YUPApplication window = std::make_unique(); window->centreWithSize ({ 1080, 2400 }); window->setVisible (true); - window->toFront(true); + window->toFront (true); } void shutdown() override From 54d7c5237d6e8e72099b460bcf9abd485b5d9c4b Mon Sep 17 00:00:00 2001 From: Yup Bot Date: Sun, 6 Apr 2025 16:37:03 +0000 Subject: [PATCH 14/22] Code formatting --- .../standalone/yup_audio_plugin_client_Standalone.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/yup_audio_plugin_client/standalone/yup_audio_plugin_client_Standalone.cpp b/modules/yup_audio_plugin_client/standalone/yup_audio_plugin_client_Standalone.cpp index 22bf0b469..8a6842945 100644 --- a/modules/yup_audio_plugin_client/standalone/yup_audio_plugin_client_Standalone.cpp +++ b/modules/yup_audio_plugin_client/standalone/yup_audio_plugin_client_Standalone.cpp @@ -98,7 +98,7 @@ class AudioProcessorApplication window = std::make_unique (getApplicationName(), editor); window->centreWithSize (editor->getPreferredSize()); window->setVisible (true); - window->toFront(true); + window->toFront (true); } void shutdown() override From 5f3d85219d87bfe7660247dac12fce95b988225a Mon Sep 17 00:00:00 2001 From: kunitoki Date: Sun, 6 Apr 2025 18:36:37 +0200 Subject: [PATCH 15/22] Format in main --- .github/workflows/clang_format.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/clang_format.yml b/.github/workflows/clang_format.yml index 71214737a..d871a421c 100644 --- a/.github/workflows/clang_format.yml +++ b/.github/workflows/clang_format.yml @@ -9,7 +9,6 @@ on: - "**/tests/**" branches: - "**" - - "!main" jobs: format: From ac4f4e85e7ee5cbb1485bc88331459078d080d47 Mon Sep 17 00:00:00 2001 From: kunitoki Date: Sun, 6 Apr 2025 22:37:29 +0200 Subject: [PATCH 16/22] Make UndoManager a reference counted and weak referenceable object --- modules/yup_data_model/undo/yup_UndoManager.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/modules/yup_data_model/undo/yup_UndoManager.h b/modules/yup_data_model/undo/yup_UndoManager.h index 3c05f289a..dedeeb9a4 100644 --- a/modules/yup_data_model/undo/yup_UndoManager.h +++ b/modules/yup_data_model/undo/yup_UndoManager.h @@ -43,9 +43,13 @@ namespace yup @see UndoableAction */ -class UndoManager : private Timer +class UndoManager + : public ReferenceCountedObject + , private Timer { public: + using Ptr = ReferenceCountedObjectPtr; + //============================================================================== /** Creates a new UndoManager and starts the timer. @@ -323,6 +327,7 @@ class UndoManager : private Timer bool isUndoEnabled = false; + JUCE_DECLARE_WEAK_REFERENCEABLE (UndoManager) JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (UndoManager) }; From 00844a27ef6b409b0b92e7af6caf0f49c91a46e0 Mon Sep 17 00:00:00 2001 From: Yup Bot Date: Wed, 9 Apr 2025 07:24:27 +0000 Subject: [PATCH 17/22] Code formatting --- examples/render/source/main.cpp | 4 ++-- modules/yup_graphics/graphics/yup_Graphics.cpp | 2 +- .../primitives/yup_AffineTransform.h | 3 +-- modules/yup_graphics/primitives/yup_Path.cpp | 3 +-- modules/yup_gui/application/yup_Application.cpp | 2 +- .../native/yup_WindowingUtilities_sdl2.cpp | 2 +- modules/yup_gui/native/yup_Windowing_mac.mm | 17 ++++++++--------- 7 files changed, 15 insertions(+), 18 deletions(-) diff --git a/examples/render/source/main.cpp b/examples/render/source/main.cpp index 9851b5d91..844c9df99 100644 --- a/examples/render/source/main.cpp +++ b/examples/render/source/main.cpp @@ -38,7 +38,7 @@ class CustomWindow { public: CustomWindow() - : yup::DocumentWindow (yup::ComponentNative::Options{}.withRenderContinuous (true), {}) + : yup::DocumentWindow (yup::ComponentNative::Options {}.withRenderContinuous (true), {}) { // Set title setTitle ("main"); @@ -179,7 +179,7 @@ class CustomWindow2 { public: CustomWindow2() - : yup::DocumentWindow (yup::ComponentNative::Options{}.withRenderContinuous (true), {}) + : yup::DocumentWindow (yup::ComponentNative::Options {}.withRenderContinuous (true), {}) { setTitle ("secondary"); } diff --git a/modules/yup_graphics/graphics/yup_Graphics.cpp b/modules/yup_graphics/graphics/yup_Graphics.cpp index b9e03b8ae..0c1ca3927 100644 --- a/modules/yup_graphics/graphics/yup_Graphics.cpp +++ b/modules/yup_graphics/graphics/yup_Graphics.cpp @@ -109,7 +109,7 @@ void convertRawPathToRenderPath (const rive::RawPath& input, rive::RenderPath* o { if (transform.isIdentity()) { - convertRawPathToRenderPath(input, output); + convertRawPathToRenderPath (input, output); } else { diff --git a/modules/yup_graphics/primitives/yup_AffineTransform.h b/modules/yup_graphics/primitives/yup_AffineTransform.h index d11bdd9c3..8a4a7bffe 100644 --- a/modules/yup_graphics/primitives/yup_AffineTransform.h +++ b/modules/yup_graphics/primitives/yup_AffineTransform.h @@ -589,8 +589,7 @@ class JUCE_API AffineTransform /** @internal Conversion to Rive Mat2D class. */ rive::Mat2D toMat2D() const { - return - { + return { getScaleX(), // xx getShearX(), // xy getShearY(), // yx diff --git a/modules/yup_graphics/primitives/yup_Path.cpp b/modules/yup_graphics/primitives/yup_Path.cpp index 934ecf974..9057b8784 100644 --- a/modules/yup_graphics/primitives/yup_Path.cpp +++ b/modules/yup_graphics/primitives/yup_Path.cpp @@ -45,7 +45,6 @@ Path::Path (rive::rcp newPath) : path (newPath) { auto points = path->getRawPath().points(); - } //============================================================================== @@ -351,7 +350,7 @@ Path Path::transformed (const AffineTransform& t) const { auto newPath = rive::make_rcp(); newPath->addRenderPath (path.get(), t.toMat2D()); - return Path{ std::move (newPath) }; + return Path { std::move (newPath) }; } //============================================================================== diff --git a/modules/yup_gui/application/yup_Application.cpp b/modules/yup_gui/application/yup_Application.cpp index 81c9d5842..706f9d430 100644 --- a/modules/yup_gui/application/yup_Application.cpp +++ b/modules/yup_gui/application/yup_Application.cpp @@ -35,7 +35,7 @@ YUPApplication::YUPApplication() NSMenu* appMenu = [[NSMenu alloc] init]; NSMenuItem* quitMenuItem = [[NSMenuItem alloc] initWithTitle:@"Quit" - action:@selector(terminate:) + action:@selector (terminate:) keyEquivalent:@"q"]; [appMenu addItem:quitMenuItem]; [menuBarItem setSubmenu:appMenu]; diff --git a/modules/yup_gui/native/yup_WindowingUtilities_sdl2.cpp b/modules/yup_gui/native/yup_WindowingUtilities_sdl2.cpp index ef1c556ce..649799e5f 100644 --- a/modules/yup_gui/native/yup_WindowingUtilities_sdl2.cpp +++ b/modules/yup_gui/native/yup_WindowingUtilities_sdl2.cpp @@ -267,7 +267,7 @@ void* getNativeDisplayHandle (SDL_Window* window) //============================================================================== -#if !JUCE_WINDOWS && !JUCE_MAC && !JUCE_LINUX +#if ! JUCE_WINDOWS && ! JUCE_MAC && ! JUCE_LINUX Rectangle getNativeWindowPosition (void* nativeWindow) { return {}; diff --git a/modules/yup_gui/native/yup_Windowing_mac.mm b/modules/yup_gui/native/yup_Windowing_mac.mm index a2413e42a..9b02996e9 100644 --- a/modules/yup_gui/native/yup_Windowing_mac.mm +++ b/modules/yup_gui/native/yup_Windowing_mac.mm @@ -24,9 +24,9 @@ //============================================================================== -Rectangle getNativeWindowPosition (void* nativeWindow) +Rectangle getNativeWindowPosition(void* nativeWindow) { - NSView* view = reinterpret_cast (nativeWindow); + NSView* view = reinterpret_cast(nativeWindow); NSWindow* window = [view window]; // Convert view bounds to window coordinates @@ -40,17 +40,16 @@ NSScreen* screen = [window screen] ?: mainScreen; // Calculate vertical offset between current screen and main screen - CGFloat adjustedY = NSMaxY ([screen frame]) - NSMaxY ([mainScreen frame]); + CGFloat adjustedY = NSMaxY([screen frame]) - NSMaxY([mainScreen frame]); // Correctly flip Y coordinate relative to main screen's top-left origin - windowRect.origin.y = NSMaxY ([screen frame]) - NSMaxY (windowRect) - adjustedY; + windowRect.origin.y = NSMaxY([screen frame]) - NSMaxY(windowRect) - adjustedY; return { - static_cast (windowRect.origin.x), - static_cast (windowRect.origin.y), - static_cast (NSWidth (windowRect)), - static_cast (NSHeight (windowRect)) - }; + static_cast(windowRect.origin.x), + static_cast(windowRect.origin.y), + static_cast(NSWidth(windowRect)), + static_cast(NSHeight(windowRect))}; } } // namespace yup From 5e553b5f6ca19998703347037abfff2b1492f36e Mon Sep 17 00:00:00 2001 From: Yup Bot Date: Sun, 20 Apr 2025 14:23:49 +0000 Subject: [PATCH 18/22] Code formatting --- tests/juce_core/juce_ReferenceCountedObject.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/juce_core/juce_ReferenceCountedObject.cpp b/tests/juce_core/juce_ReferenceCountedObject.cpp index 6a3295200..7e397a52d 100644 --- a/tests/juce_core/juce_ReferenceCountedObject.cpp +++ b/tests/juce_core/juce_ReferenceCountedObject.cpp @@ -19,7 +19,6 @@ ============================================================================== */ - #include #include From 6218cf89e57e43fe773aedce985468c5fb090cdd Mon Sep 17 00:00:00 2001 From: Yup Bot Date: Fri, 13 Jun 2025 06:15:35 +0000 Subject: [PATCH 19/22] Code formatting --- examples/graphics/source/examples/Audio.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/graphics/source/examples/Audio.h b/examples/graphics/source/examples/Audio.h index fd776e656..c16073376 100644 --- a/examples/graphics/source/examples/Audio.h +++ b/examples/graphics/source/examples/Audio.h @@ -123,7 +123,7 @@ class Oscilloscope : public yup::Component for (std::size_t i = 1; i < renderData.size(); ++i) path.lineTo (i * xSize, (renderData[i] + 1.0f) * 0.5f * getHeight()); - filledPath = path.createStrokePolygon(4.0f); + filledPath = path.createStrokePolygon (4.0f); g.setFillColor (lineColor); g.setFeather (8.0f); From 538ae211b8403d6864fa94772e9eba683291bd2d Mon Sep 17 00:00:00 2001 From: kunitoki Date: Fri, 20 Jun 2025 15:14:41 +0200 Subject: [PATCH 20/22] Update rive.h --- thirdparty/rive/rive.h | 1 + 1 file changed, 1 insertion(+) diff --git a/thirdparty/rive/rive.h b/thirdparty/rive/rive.h index 6ef8814b6..d060c91ab 100644 --- a/thirdparty/rive/rive.h +++ b/thirdparty/rive/rive.h @@ -34,6 +34,7 @@ dependencies: harfbuzz sheenbidi yoga_library defines: WITH_RIVE_TEXT=1 WITH_RIVE_YOGA=1 WITH_RIVE_LAYOUT=1 + appleFrameworks: CoreText searchpaths: include END_YUP_MODULE_DECLARATION From 09148f096e83f3ad70e072152ac4d7622f4b2e8f Mon Sep 17 00:00:00 2001 From: kunitoki Date: Fri, 20 Jun 2025 15:26:39 +0200 Subject: [PATCH 21/22] More tweaks --- modules/yup_data_model/undo/yup_UndoManager.h | 6 +++--- modules/yup_data_model/yup_data_model.h | 9 ++++----- tests/yup_data_model/yup_UndoManager.cpp | 6 +++--- 3 files changed, 10 insertions(+), 11 deletions(-) diff --git a/modules/yup_data_model/undo/yup_UndoManager.h b/modules/yup_data_model/undo/yup_UndoManager.h index dedeeb9a4..c2d80d96a 100644 --- a/modules/yup_data_model/undo/yup_UndoManager.h +++ b/modules/yup_data_model/undo/yup_UndoManager.h @@ -43,7 +43,7 @@ namespace yup @see UndoableAction */ -class UndoManager +class YUP_API UndoManager : public ReferenceCountedObject , private Timer { @@ -327,8 +327,8 @@ class UndoManager bool isUndoEnabled = false; - JUCE_DECLARE_WEAK_REFERENCEABLE (UndoManager) - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (UndoManager) + YUP_DECLARE_WEAK_REFERENCEABLE (UndoManager) + YUP_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (UndoManager) }; } // namespace yup diff --git a/modules/yup_data_model/yup_data_model.h b/modules/yup_data_model/yup_data_model.h index 3b7a46f19..0d6c5fe7a 100644 --- a/modules/yup_data_model/yup_data_model.h +++ b/modules/yup_data_model/yup_data_model.h @@ -21,7 +21,7 @@ /******************************************************************************* - BEGIN_JUCE_MODULE_DECLARATION + BEGIN_YUP_MODULE_DECLARATION ID: yup_data_model vendor: yup @@ -30,19 +30,18 @@ description: The essential set of basic YUP data model classes. website: https://github.com/kunitoki/yup license: ISC - minimumCppStandard: 17 - dependencies: juce_events + dependencies: yup_events enableARC: 1 - END_JUCE_MODULE_DECLARATION + END_YUP_MODULE_DECLARATION *******************************************************************************/ #pragma once #define YUP_DATA_MODEL_H_INCLUDED -#include +#include //============================================================================== #include "undo/yup_UndoableAction.h" diff --git a/tests/yup_data_model/yup_UndoManager.cpp b/tests/yup_data_model/yup_UndoManager.cpp index 85ed049bd..2133832d1 100644 --- a/tests/yup_data_model/yup_UndoManager.cpp +++ b/tests/yup_data_model/yup_UndoManager.cpp @@ -176,8 +176,8 @@ TEST_F (UndoManagerTest, TransactionIteration) EXPECT_EQ (undoManager->getNumTransactions(), 2); } - EXPECT_EQ (juce::String ("1"), undoManager->getTransactionName (0)); - EXPECT_EQ (juce::String ("2"), undoManager->getTransactionName (1)); + EXPECT_EQ (String ("1"), undoManager->getTransactionName (0)); + EXPECT_EQ (String ("2"), undoManager->getTransactionName (1)); } TEST_F (UndoManagerTest, RedoAction) @@ -264,7 +264,7 @@ TEST_F (UndoManagerTest, PerformWithLambda) int counter = 0; private: - JUCE_DECLARE_WEAK_REFERENCEABLE (Object) + YUP_DECLARE_WEAK_REFERENCEABLE (Object) }; auto lambdaAction = [] (Object::Ptr x, UndoableActionState s) -> bool From 0666291752759f0259728b24f6885e81f6aa9f09 Mon Sep 17 00:00:00 2001 From: kunitoki Date: Fri, 20 Jun 2025 16:16:55 +0200 Subject: [PATCH 22/22] Fix formatting --- .github/workflows/clang_format.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/clang_format.yml b/.github/workflows/clang_format.yml index 481c94639..71214737a 100644 --- a/.github/workflows/clang_format.yml +++ b/.github/workflows/clang_format.yml @@ -9,6 +9,7 @@ on: - "**/tests/**" branches: - "**" + - "!main" jobs: format: @@ -29,6 +30,7 @@ jobs: uses: tj-actions/changed-files@v44 with: files: | + **/*.c **/*.cpp **/*.h **/*.hpp