23template <FinalArrangerObjectSub
class ChildT>
class ArrangerObjectOwner
26 using ArrangerObjectChildType = ChildT;
27 using ArrangerObjectListModel =
31 explicit ArrangerObjectOwner (
32 ArrangerObjectRegistry ®istry,
33 dsp::FileAudioSourceRegistry &file_audio_source_registry,
35 requires std::derived_from<T, QObject>
36 : registry_ (registry),
37 file_audio_source_registry_ (file_audio_source_registry)
39 if constexpr (std::derived_from<T, ArrangerObject>)
41 list_model_ = utils::make_qobject_unique<ArrangerObjectListModel> (
46 list_model_ = utils::make_qobject_unique<ArrangerObjectListModel> (
50 virtual ~ArrangerObjectOwner () =
default;
51 Z_DISABLE_COPY_MOVE (ArrangerObjectOwner)
53 auto &get_children_vector ()
const
58 auto get_children_view ()
const
62 | std::views::transform (
63 &ArrangerObjectUuidReference::get_object_as<ChildT>);
66 auto get_sorted_children_view ()
const
70 | std::views::transform (
71 &ArrangerObjectUuidReference::get_object_as<ChildT>);
74 void add_ticks_to_children (
double ticks)
76 for (
auto * child : get_children_view ())
78 child->position ()->setTicks (child->position ()->ticks () + ticks);
92 template <
typename SelfT>
93 ArrangerObjectUuidReference
94 remove_object (
this SelfT &self,
const ArrangerObject::Uuid &
id)
96 auto &container = self.ArrangerObjectOwner<ChildT>::children_;
97 auto &random_access_idx = container.template get<random_access_index> ();
98 auto it_to_remove = std::ranges::find (
99 random_access_idx,
id, &ArrangerObjectUuidReference::id);
100 if (it_to_remove == random_access_idx.end ())
102 throw std::runtime_error (
103 fmt::format (
"object to remove not found: {}",
id));
105 z_trace (
"removing object: {}",
id);
107 auto obj_ref = *it_to_remove;
108 const auto remove_idx =
109 std::distance (random_access_idx.begin (), it_to_remove);
112 self.ArrangerObjectOwner<ChildT>::list_model_->removeRows (
113 static_cast<int> (remove_idx), 1);
118 template <
typename SelfT>
121 const ArrangerObjectUuidReference &obj_ref,
124 self.ArrangerObjectOwner<ChildT>::list_model_->insertObject (obj_ref, idx);
127 template <
typename SelfT>
128 void add_object (
this SelfT &self,
const ArrangerObjectUuidReference &obj_ref)
130 self.ArrangerObjectOwner<ChildT>::insert_object (
132 static_cast<int> (self.ArrangerObjectOwner<ChildT>::children_.size ()));
135 void clear_objects () { list_model_->clear (); }
149 friend void init_from (
150 ArrangerObjectOwner &obj,
151 const ArrangerObjectOwner &other,
156 obj.children_.reserve (other.children_.size ());
157 for (
const auto &child : other.get_children_view ())
160 std::optional<ArrangerObjectUuidReference> clone_ref;
161 if constexpr (std::is_same_v<ChildT, AudioSourceObject>)
163 clone_ref = obj.registry_.clone_object (
164 *child, child->get_tempo_map (),
165 obj.file_audio_source_registry_, child->audio_source_ref ());
167 std::move (*clone_ref));
173 else if constexpr (std::is_same_v<ChildT, Marker>)
175 clone_ref = obj.registry_.clone_object (
176 *child, child->get_tempo_map (), child->markerType ());
178 std::move (*clone_ref));
183 obj.registry_.clone_object (*child, child->get_tempo_map ());
185 std::move (*clone_ref));
194 const auto children_field_name =
196 j[children_field_name] = obj.children_;
198 friend void from_json (
const nlohmann::json &j, ArrangerObjectOwner &obj)
200 const auto children_field_name =
201 obj.get_field_name_for_serialization (
static_cast<ChildT *
> (
nullptr));
202 for (
const auto &child_json : j.at (children_field_name))
205 child_json.at (ArrangerObjectUuidReference::kIdKey)
206 .template get<ArrangerObjectUuid> ();
207 ArrangerObjectUuidReference obj_ref{ uuid, obj.registry_ };
208 obj.children_.get<sequenced_index> ().emplace_back (std::move (obj_ref));
213 ArrangerObjectRegistry ®istry_;
214 dsp::FileAudioSourceRegistry &file_audio_source_registry_;
215 ArrangerObjectRefMultiIndexContainer children_;
216 utils::QObjectUniquePtr<ArrangerObjectListModel> list_model_;
218 BOOST_DESCRIBE_CLASS (ArrangerObjectOwner<ChildT>, (), (), (), (children_))