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 ArrangerObjectUuidReference remove_object (
const ArrangerObject::Uuid &
id)
94 auto &container = ArrangerObjectOwner<ChildT>::children_;
95 auto &random_access_idx = container.template get<random_access_index> ();
96 auto it_to_remove = std::ranges::find (
97 random_access_idx,
id, &ArrangerObjectUuidReference::id);
98 if (it_to_remove == random_access_idx.end ())
100 throw std::runtime_error (
101 fmt::format (
"object to remove not found: {}",
id));
103 z_trace (
"removing object: {}",
id);
105 auto obj_ref = *it_to_remove;
106 const auto remove_idx =
107 std::distance (random_access_idx.begin (), it_to_remove);
110 ArrangerObjectOwner<ChildT>::list_model_->removeRows (
111 static_cast<int> (remove_idx), 1);
116 void insert_object (
const ArrangerObjectUuidReference &obj_ref,
int idx)
118 ArrangerObjectOwner<ChildT>::list_model_->insertObject (obj_ref, idx);
121 void add_object (
const ArrangerObjectUuidReference &obj_ref)
123 ArrangerObjectOwner<ChildT>::insert_object (
125 static_cast<int> (ArrangerObjectOwner<ChildT>::children_.size ()));
128 void clear_objects () { list_model_->clear (); }
142 friend void init_from (
143 ArrangerObjectOwner &obj,
144 const ArrangerObjectOwner &other,
149 obj.children_.reserve (other.children_.size ());
150 for (
const auto &child : other.get_children_view ())
153 std::optional<ArrangerObjectUuidReference> clone_ref;
154 if constexpr (std::is_same_v<ChildT, AudioSourceObject>)
156 clone_ref = obj.registry_.clone_object (
157 *child, child->get_tempo_map (),
158 obj.file_audio_source_registry_, child->audio_source_ref ());
165 else if constexpr (std::is_same_v<ChildT, Marker>)
167 clone_ref = obj.registry_.clone_object (
168 *child, child->get_tempo_map (), child->markerType ());
173 obj.registry_.clone_object (*child, child->get_tempo_map ());
178 obj.add_object (*clone_ref);
187 const auto children_field_name =
189 j[children_field_name] = obj.children_;
191 friend void from_json (
const nlohmann::json &j, ArrangerObjectOwner &obj)
193 const auto children_field_name =
194 obj.get_field_name_for_serialization (
static_cast<ChildT *
> (
nullptr));
195 for (
const auto &child_json : j.at (children_field_name))
197 const auto uuid = child_json.template get<ArrangerObjectUuid> ();
198 ArrangerObjectUuidReference obj_ref{ uuid, obj.registry_ };
199 obj.add_object (obj_ref);
204 ArrangerObjectRegistry ®istry_;
205 dsp::FileAudioSourceRegistry &file_audio_source_registry_;
206 ArrangerObjectRefMultiIndexContainer children_;
207 utils::QObjectUniquePtr<ArrangerObjectListModel> list_model_;
209 BOOST_DESCRIBE_CLASS (ArrangerObjectOwner<ChildT>, (), (), (), (children_))