Anklang-0.3.0.dev797+g4e3241f3 anklang-0.3.0.dev797+g4e3241f3
ASE — Anklang Sound Engine (C++)

« « « Anklang Documentation
Loading...
Searching...
No Matches
trkn-utils.cc
Go to the documentation of this file.
1 // This Source Code Form is licensed MPL-2.0: http://mozilla.org/MPL/2.0
2#include "trkn/tracktion.hh" // PCH include must come first
3
4#include "trkn-utils.hh"
5#include "platform.hh"
6#include "main.hh"
7#include "logging.hh"
8#include "internal.hh"
9
10namespace te = tracktion::engine;
11
12namespace Ase {
13
14// == SelectableBaseref ==
15using JuceWeakReference_Selectable = juce::WeakReference<tracktion::Selectable>;
16
17template<size_t N> static JuceWeakReference_Selectable&
18juce_weak_reference_selectable (const char (&mem)[N])
19{
20 static_assert (N == sizeof (JuceWeakReference_Selectable));
21 return *reinterpret_cast<JuceWeakReference_Selectable*> (const_cast<char*> (mem));
22}
23
24SelectableBaseref::SelectableBaseref()
25{
26 static_assert (sizeof (mem_) == sizeof (JuceWeakReference_Selectable));
27 JuceWeakReference_Selectable *const weakref = new (mem_) JuceWeakReference_Selectable (nullptr);
28 assert_return (weakref != nullptr);
29}
30
31SelectableBaseref::~SelectableBaseref()
32{
33 JuceWeakReference_Selectable &weakref = juce_weak_reference_selectable (mem_);
34 weakref.~JuceWeakReference_Selectable();
35}
36
37tracktion::Selectable*
38SelectableBaseref::get () const noexcept
39{
40 JuceWeakReference_Selectable &weakref = juce_weak_reference_selectable (mem_);
41 return weakref.get();
42}
43
44void
45SelectableBaseref::set (tracktion::Selectable *selectable) noexcept
46{
47 JuceWeakReference_Selectable &weakref = juce_weak_reference_selectable (mem_);
48 weakref = selectable;
49}
50
51void
52SelectableBaseref::set (const SelectableBaseref &other) noexcept
53{
54 JuceWeakReference_Selectable &weakref = juce_weak_reference_selectable (mem_);
55 const JuceWeakReference_Selectable &otherref = juce_weak_reference_selectable (other.mem_);
56 weakref = otherref;
57}
58
59// == SelectableHandle ==
61
62static SelectableHandleMap&
63selectable_handle_map()
64{
65 static SelectableHandleMap *map = [] { return new SelectableHandleMap(); } ();
66 return *map;
67}
68
69SelectableHandle*
70SelectableHandle::find_base_handle (tracktion::Selectable &selectable_obj)
71{
72 SelectableHandleMap &map = selectable_handle_map();
73 auto it = map.find (&selectable_obj);
74 return it != map.end() ? it->second : nullptr;
75}
76
77SelectableHandle::SelectableHandle (tracktion::Selectable &selectable_obj)
78{
79 SelectableHandleMap &map = selectable_handle_map();
80 if (tracktion::Selectable::isSelectableValid (&selectable_obj)) {
81 selectable_ = &selectable_obj;
82 selectable_obj.addListener (this);
83 map[&selectable_obj] = this;
84 }
85}
86
87SelectableHandle::~SelectableHandle()
88{
89 discard_selectable();
90}
91
92void
93SelectableHandle::discard_selectable()
94{
95 tracktion::Selectable *selectable = selectable_.get();
96 return_unless (selectable != nullptr);
97 SelectableHandleMap &map = selectable_handle_map();
98 auto it = map.find (selectable);
99 if (it != map.end()) {
100 map.erase (it);
101 if (tracktion::Selectable::isSelectableValid (selectable))
102 selectable->removeListener (this);
103 }
104 selectable_ = nullptr;
105}
106
107void
108SelectableHandle::selectableObjectAboutToBeDeleted (tracktion::Selectable *selectable)
109{
110 if (this_thread_is_main()) {
111 warning ("TODO: verify this branch is reached");
112 discard_selectable();
113 } else {
114 // not in main thread, `this` could be in dtor in main thread
115 const SelectableHandle *handle = this; // save to re-check association
116 main_jobs += [selectable, handle] {
117 warning ("TODO: verify this lambda is reached");
118 // main thread
119 SelectableHandleMap &map = selectable_handle_map();
120 auto it = map.find (selectable);
121 if (it != map.end() && // selectable_ still valid
122 it->second == handle) // prevent ABA
123 const_cast<SelectableHandle*> (handle)->discard_selectable();
124 };
125 }
126}
127
128void
129SelectableHandle::selectableObjectChanged (tracktion::Selectable *object)
130{}
131
132void
133SelectableHandle::discarded ()
134{}
135
136} // Ase
#define assert_return(expr,...)
Return from the current function if expr is unmet and issue an assertion warning.
Definition internal.hh:29
#define return_unless(cond,...)
Return silently if cond does not evaluate to true with return value ...
Definition internal.hh:73
The Anklang C++ API namespace.
Definition api.hh:9
JobQueue main_jobs(call_main_loop)
Execute a job callback in the event loop.
Definition main.hh:42