From fb992677cf62b6aa982476538faae43e5bbbd87f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Nusser?= Date: Sun, 12 Jan 2020 15:41:39 +0100 Subject: Introduce EventsDS to handle all the events and enable new features. Also: * Added an id.h class to make IDs with type * Added a range class to easily use range based for loops --- src/events_ds.h | 135 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 135 insertions(+) create mode 100644 src/events_ds.h (limited to 'src/events_ds.h') diff --git a/src/events_ds.h b/src/events_ds.h new file mode 100644 index 0000000..4a31f47 --- /dev/null +++ b/src/events_ds.h @@ -0,0 +1,135 @@ +/* -*- Mode: c++ -*- */ +/*************************************************************************** + * events_ds.h + * + * Sun Jan 12 00:17:31 CET 2020 + * Copyright 2020 André Nusser + * andre.nusser@googlemail.com + ****************************************************************************/ + +/* + * This file is part of DrumGizmo. + * + * DrumGizmo is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * DrumGizmo is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with DrumGizmo; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ +#pragma once + +#include + +#include +#include +#include + +#include "events.h" +#include "id.h" +#include "memory_heap.h" +#include "range.h" +#include "instrument.h" + +// TODO: make it possible to choose sizes + +struct EventsDS +{ + // + // member functions + // + EventsDS() = default; + + template + T& emplace(int ch, Args&&... args); + + void remove(EventID event_id); + + std::size_t numberOfEvents(int ch) const; + + template + ContainerRange> iterateOver(int ch); + + EventGroupIDs const& getSampleEventGroupIDsOf(InstrumentID instrument_id) const; + EventIDs const& getEventIDsOf(EventGroupID event_group_id) const; + + void startAddingNewGroup(InstrumentID instrument_id = InstrumentID()); + +private: + struct ChannelData { + std::vector sample_events; + }; + + using ChannelEventIndex = std::size_t; + + struct EventInfo { + Event::Type type; + int ch; + ChannelEventIndex channel_event_index; + + EventInfo(Event::Type type, int ch, ChannelEventIndex channel_event_index) + : type(type), ch(ch), channel_event_index(channel_event_index) {} + }; + struct GroupData { + EventIDs event_ids; + Event::Type type; + + // SampleEvent specific data + std::size_t instrument_index; + }; + + // general data + std::array channel_data_array; + MemoryHeap id_to_info; + MemoryHeap id_to_group_data; + + // SampleEvent specific data + // TODO: maybe use something that actually has the size of the number of instruments + // Also, can we guarantee that there are at most 128 instrument ids? + std::array instruments_sample_event_group_ids; + + EventGroupID current_group_id; + InstrumentID current_groups_instrument_id; + + void removeGroup(EventGroupID group_id, InstrumentID instrument_id = InstrumentID()); +}; + +template +T& EventsDS::emplace(int ch, Args&&... args) +{ + if (std::is_same::value) + { + auto& sample_events = channel_data_array[ch].sample_events; + auto channel_event_index = sample_events.size(); + sample_events.emplace_back(std::forward(args)...); + + auto event_id = id_to_info.emplace(Event::Type::SampleEvent, ch, channel_event_index); + id_to_group_data.get(current_group_id).event_ids.push_back(event_id); + + auto& sample_event = sample_events.back(); + sample_event.id = event_id; + sample_event.group_id = current_group_id; + assert(sample_event.instrument_id == current_groups_instrument_id); + + return sample_event; + } + + assert(false); +} + +template +ContainerRange> EventsDS::iterateOver(int ch) +{ + if (std::is_same::value) + { + auto& sample_events = channel_data_array[ch].sample_events; + return ContainerRange>(sample_events.begin(), sample_events.end()); + } +} -- cgit v1.2.3