simplify attribute mapping v_0
authorFrantišek Kučera <franta-hg@frantovo.cz>
Sun, 04 Oct 2020 12:40:00 +0200
branchv_0
changeset 16 d17d70731446
parent 15 b3239e4ad328
child 17 0fcd9944016a
simplify attribute mapping
src/JackHandler.h
--- a/src/JackHandler.h	Sun Oct 04 00:04:28 2020 +0200
+++ b/src/JackHandler.h	Sun Oct 04 12:40:00 2020 +0200
@@ -111,16 +111,12 @@
 	public:
 		bool skip = false;
 
-		size_t indexOfEvent = -1;
-		size_t indexOfChannel = -1;
-		size_t indexOfNoteOn = -1;
-		size_t indexOfNotePitch = -1;
-		size_t indexOfNoteVelocity = -1;
-		size_t indexOfControllerId = -1;
-		size_t indexOfControllerValue = -1;
-		size_t indexOfRaw = -1;
+		std::vector<relpipe::reader::handlers::AttributeMetadata> attributes;
 
-		size_t attributeCount = 0;
+		bool hasAttribute(const relpipe::common::type::StringX& name) {
+			for (auto a : attributes) if (a.getAttributeName() == name) return true;
+			return false;
+		}
 
 		class RecordContext {
 		public:
@@ -132,7 +128,7 @@
 				UNKNOWN
 			};
 
-			static Event parseEventType(const relpipe::common::type::StringX name) {
+			static Event parseEventType(const relpipe::common::type::StringX& name) {
 				if (name == L"note") return Event::NOTE;
 				else if (name == L"control") return Event::CONTROL;
 				else if (name == L"sysex") return Event::SYSEX;
@@ -201,24 +197,12 @@
 		// TODO: validate metadata and prepare attribute mappings (names and types are important, order does not matter)
 
 		relationContext = RelationContext();
-		relationContext.attributeCount = attributes.size();
-
-		for (int i = 0; i < relationContext.attributeCount; i++) {
-			const relpipe::common::type::StringX attributeName = attributes[i].getAttributeName();
-			if (attributeName == L"event") relationContext.indexOfEvent = i;
-			else if (attributeName == L"channel") relationContext.indexOfChannel = i;
-			else if (attributeName == L"controller_id") relationContext.indexOfControllerId = i;
-			else if (attributeName == L"controller_value") relationContext.indexOfControllerValue = i;
-			else if (attributeName == L"note_on") relationContext.indexOfNoteOn = i;
-			else if (attributeName == L"note_pitch") relationContext.indexOfNotePitch = i;
-			else if (attributeName == L"note_velocity") relationContext.indexOfNoteVelocity = i;
-			else if (attributeName == L"raw") relationContext.indexOfRaw = i;
-		}
+		relationContext.attributes = attributes;
 
 		// TODO: check also data types and skipt relation if important attributes are missing
 		// TODO: configurable relation name
 
-		if (relationContext.indexOfRaw == -1) {
+		if (!relationContext.hasAttribute(L"raw")) {
 			relationContext.skip = true;
 			fwprintf(stderr, L"Relation „%ls“ will be ignored because mandatory attribute „raw“ is missing.\n", name.c_str());
 		}
@@ -233,18 +217,20 @@
 		RelationContext& rel = relationContext;
 		RelationContext::RecordContext& rec = rel.recordContext;
 
-		if (rel.indexOfEvent == rec.attributeIndex) rec.event = rec.parseEventType(value);
-		else if (rel.indexOfChannel == rec.attributeIndex) rec.channel = std::stoi(value);
-		else if (rel.indexOfControllerId == rec.attributeIndex) rec.controllerId = std::stoi(value);
-		else if (rel.indexOfControllerValue == rec.attributeIndex) rec.controllerValue = std::stoi(value);
-		else if (rel.indexOfNoteOn == rec.attributeIndex) rec.noteOn = value == L"true";
-		else if (rel.indexOfNotePitch == rec.attributeIndex) rec.notePitch = std::stoi(value);
-		else if (rel.indexOfNoteVelocity == rec.attributeIndex) rec.noteVelocity = std::stoi(value);
-		else if (rel.indexOfRaw == rec.attributeIndex) rec.raw = value;
+		const auto attributeName = rel.attributes[rec.attributeIndex].getAttributeName();
+
+		if (attributeName == L"event") rec.event = rec.parseEventType(value);
+		else if (attributeName == L"channel") rec.channel = std::stoi(value);
+		else if (attributeName == L"controller_id") rec.controllerId = std::stoi(value);
+		else if (attributeName == L"controller_value") rec.controllerValue = std::stoi(value);
+		else if (attributeName == L"note_on") rec.noteOn = value == L"true";
+		else if (attributeName == L"note_pitch") rec.notePitch = std::stoi(value);
+		else if (attributeName == L"note_velocity") rec.noteVelocity = std::stoi(value);
+		else if (attributeName == L"raw") rec.raw = value;
 
 		rec.attributeIndex++;
 
-		if (rec.attributeIndex == rel.attributeCount) {
+		if (rec.attributeIndex == rel.attributes.size()) {
 
 			while (jack_ringbuffer_write_space(realTimeContext.ringBuffer) < sizeof (MidiMessage)) usleep(1000); // should not happen, the real-time thread should be faster