From e5a5000beac5275e89ab272a92075dc4466b2d9e Mon Sep 17 00:00:00 2001
From: Aaron Cuevas Lopez <aacuelo@teleco.upv.es>
Date: Fri, 7 Jul 2017 02:13:23 +0200
Subject: [PATCH] Add some needed methods to channel and event structures

---
 Source/Processors/Channel/InfoObjects.cpp     | 20 +++++++-
 Source/Processors/Channel/InfoObjects.h       | 14 +++++-
 Source/Processors/Channel/MetaData.cpp        | 46 +++++++++++++++++--
 Source/Processors/Channel/MetaData.h          | 13 +++++-
 .../GenericProcessor/GenericProcessor.cpp     | 12 +++++
 5 files changed, 95 insertions(+), 10 deletions(-)

diff --git a/Source/Processors/Channel/InfoObjects.cpp b/Source/Processors/Channel/InfoObjects.cpp
index 4e33c8e2e..7c0151dd2 100644
--- a/Source/Processors/Channel/InfoObjects.cpp
+++ b/Source/Processors/Channel/InfoObjects.cpp
@@ -39,6 +39,16 @@ unsigned int NodeInfoBase::getCurrentNodeID() const
 	return m_nodeID;
 }
 
+String NodeInfoBase::getCurrentNodeType() const
+{
+	return m_currentNodeType;
+}
+
+String NodeInfoBase::getCurrentNodeName() const
+{
+	return m_currentNodeName;
+}
+
 //History Object
 String HistoryObject::getHistoricString()
 {
@@ -58,7 +68,8 @@ SourceProcessorInfo::SourceProcessorInfo(const GenericProcessor* source, uint16
 	:	m_sourceNodeID(source->getNodeId()),
 		m_sourceSubNodeIndex(subproc), 
 		m_sourceType(source->getName()),
-		m_sourceName(source->getName()) //TODO: fix those two when we have the ability to rename processors
+		m_sourceName(source->getName()), //TODO: fix those two when we have the ability to rename processors
+		m_sourceSubProcessorCount(source->getNumSubProcessors())
 {
 }
 
@@ -82,6 +93,11 @@ String SourceProcessorInfo::getSourceName() const
 	return m_sourceName;
 }
 
+uint16 SourceProcessorInfo::getSourceSubprocessorCount() const
+{
+	return m_sourceSubProcessorCount;
+}
+
 //NamedInfoObject
 void NamedInfoObject::setName(String name)
 {
@@ -98,7 +114,7 @@ void NamedInfoObject::setIdentifier(String identifier)
 	m_identifier = identifier;
 }
 
-String NamedInfoObject::getDescriptor() const
+String NamedInfoObject::getIdentifier() const
 {
 	return m_identifier;
 }
diff --git a/Source/Processors/Channel/InfoObjects.h b/Source/Processors/Channel/InfoObjects.h
index c16e3d117..c69b92905 100644
--- a/Source/Processors/Channel/InfoObjects.h
+++ b/Source/Processors/Channel/InfoObjects.h
@@ -49,10 +49,16 @@ class PLUGIN_API NodeInfoBase
 public:
 	/** Gets the ID of the processor which currently owns this copy of the info object */
 	unsigned int getCurrentNodeID() const;
+	/** Gets the type of the processor which currently owns this copy of the info object */
+	String getCurrentNodeType() const;
+	/** Gets the name of the processor which currently owns this copy of the info object */
+	String getCurrentNodeName() const;
 protected:
 	NodeInfoBase() = delete;
 	NodeInfoBase(uint16 id);
 	uint16 m_nodeID{ 0 };
+	String m_currentNodeType;
+	String m_currentNodeName;
 };
 
 /** This class allows creating a string with an historic of all the data a node has gone through */
@@ -89,13 +95,17 @@ public:
 	/** Gets the name of the processor which created this object */
 	String getSourceName() const;
 
+	/** Gets the number of subprocessors the source processor has.
+	Useful to determine if a processor has multiple subprocessors and label things accordingly*/
+	uint16 getSourceSubprocessorCount() const;
+ 
 private:
 	SourceProcessorInfo() = delete;
 	const uint16 m_sourceNodeID;
 	const uint16 m_sourceSubNodeIndex;
 	const String m_sourceType;
 	const String m_sourceName;
-
+	const uint16 m_sourceSubProcessorCount;
 };
 
 class PLUGIN_API NamedInfoObject
@@ -116,7 +126,7 @@ public:
 	/** Sets a machine-readable data identifier (eg.: sourcedata.continuous ) */
 	void setIdentifier(String identifier);
 
-	String getDescriptor() const;
+	String getIdentifier() const;
 protected:
 	NamedInfoObject();
 	virtual void setDefaultNameAndDescription() = 0;
diff --git a/Source/Processors/Channel/MetaData.cpp b/Source/Processors/Channel/MetaData.cpp
index c2d297959..b1303c710 100644
--- a/Source/Processors/Channel/MetaData.cpp
+++ b/Source/Processors/Channel/MetaData.cpp
@@ -162,7 +162,7 @@ size_t MetaDataValue::getDataSize() const
 
 void MetaDataValue::allocSpace()
 {
-	m_data.malloc(m_size);
+	m_data.calloc(m_size);
 }
 
 MetaDataValue::MetaDataValue(const MetaDataValue& v)
@@ -239,6 +239,19 @@ void MetaDataValue::getValue(T* data) const
 	memcpy(data, m_data.getData(), m_size);
 }
 
+//Using this version of the method in normal processor operation is not recommended
+//However it is useful for format-agnostic processes.
+template<>
+void MetaDataValue::getValue<void>(void* data) const
+{
+	memcpy(data, m_data.getData(), m_size);
+}
+
+const void* MetaDataValue::getRawValuePointer() const
+{
+	return m_data.getData();
+}
+
 template <typename T>
 void MetaDataValue::setValue(const Array<T>& data)
 {
@@ -331,7 +344,10 @@ void MetaDataEventObject::addEventMetaData(MetaDataDescriptor* desc)
 		return;
 	}
 	m_eventMetaDataDescriptorArray.add(desc);
-	m_totalSize += desc->getDataSize();
+	size_t size = desc->getDataSize();
+	m_totalSize += size;
+	if (m_maxSize < size)
+		m_maxSize = size;
 }
 
 void MetaDataEventObject::addEventMetaData(const MetaDataDescriptor& desc)
@@ -343,7 +359,10 @@ void MetaDataEventObject::addEventMetaData(const MetaDataDescriptor& desc)
 		return;
 	}
 	m_eventMetaDataDescriptorArray.add(new MetaDataDescriptor(desc));
-	m_totalSize += desc.getDataSize();
+	size_t size = desc.getDataSize();
+	m_totalSize += size;
+	if (m_maxSize < size)
+		m_maxSize = size;
 }
 
 size_t MetaDataEventObject::getTotalEventMetaDataSize() const
@@ -356,7 +375,7 @@ const MetaDataDescriptor* MetaDataEventObject::getEventMetaDataDescriptor(int in
 	return m_eventMetaDataDescriptorArray[index];
 }
 
-const int MetaDataEventObject::getEventMetaDataCount() const
+int MetaDataEventObject::getEventMetaDataCount() const
 {
 	return m_eventMetaDataDescriptorArray.size();
 }
@@ -373,14 +392,29 @@ int MetaDataEventObject::findEventMetaData(MetaDataDescriptor::MetaDataTypes typ
 	return -1;
 }
 
+size_t MetaDataEventObject::getMaxEventMetaDataSize() const
+{
+	return m_maxSize;
+}
+
 //MetaDataEvent
 MetaDataEvent::MetaDataEvent() {}
 
+int MetaDataEvent::getMetadataValueCount() const
+{
+	return m_metaDataValues.size();
+}
+
+const MetaDataValue* MetaDataEvent::getMetaDataValue(int index) const
+{
+	return m_metaDataValues[index];
+}
+
 void MetaDataEvent::serializeMetaData(void* dstBuffer) const
 {
 	int metaDataSize = m_metaDataValues.size();
 	char* buffer = static_cast<char*>(dstBuffer);
-	int ptrIndex = 0;
+	size_t ptrIndex = 0;
 
 	for (int i = 0; i < metaDataSize; i++)
 	{
@@ -489,6 +523,8 @@ template PLUGIN_API void MetaDataValue::getValue<uint64>(Array<uint64>&) const;
 template PLUGIN_API void MetaDataValue::getValue<float>(Array<float>&) const;
 template PLUGIN_API void MetaDataValue::getValue<double>(Array<double>&) const;
 
+template PLUGIN_API void MetaDataValue::getValue<void>(void*) const;
+
 //Helper function to compare identifier strings
 bool compareIdentifierStrings(const String& identifier, const String& compareWith)
 {
diff --git a/Source/Processors/Channel/MetaData.h b/Source/Processors/Channel/MetaData.h
index b3677b5ce..a106e730e 100644
--- a/Source/Processors/Channel/MetaData.h
+++ b/Source/Processors/Channel/MetaData.h
@@ -149,6 +149,11 @@ public:
 	template <typename T>
 	void getValue(Array<T>& data) const;
 
+	/** It is generally not advised to use this method, which can, however, be of use in performance critical modules.
+	It is usually preferable to use the strongly typed copy getter methods, when speed is not an issue.
+	Keep in mind that any pointer returned by this will become invalid after the block execution.*/
+	const void* getRawValuePointer() const;
+
 private:
 	MetaDataValue() = delete;
 	void setValue(const void* data);
@@ -205,16 +210,22 @@ public:
 	const MetaDataDescriptor* getEventMetaDataDescriptor(int index) const;
 	int findEventMetaData(MetaDataDescriptor::MetaDataTypes type, unsigned int length, String identifier = String::empty) const;
 	size_t getTotalEventMetaDataSize() const;
-	const int getEventMetaDataCount() const;
+	int getEventMetaDataCount() const;
+	//gets the largest metadata size, which can be useful to reserve buffers in advance
+	size_t getMaxEventMetaDataSize() const;
 protected:
 	MetaDataDescriptorArray m_eventMetaDataDescriptorArray;
 	MetaDataEventObject();
 	size_t m_totalSize{ 0 };
+	size_t m_maxSize{ 0 };
 };
 
 //And the base from which event objects can hold their metadata before serializing
 class PLUGIN_API MetaDataEvent
 {
+public:
+	int getMetadataValueCount() const;
+	const MetaDataValue* getMetaDataValue(int index) const;
 protected:
 	void serializeMetaData(void* dstBuffer) const;
 	bool deserializeMetaData(const MetaDataEventObject* info, const void* srcBuffer, int size);
diff --git a/Source/Processors/GenericProcessor/GenericProcessor.cpp b/Source/Processors/GenericProcessor/GenericProcessor.cpp
index e1b6864a8..65a960441 100755
--- a/Source/Processors/GenericProcessor/GenericProcessor.cpp
+++ b/Source/Processors/GenericProcessor/GenericProcessor.cpp
@@ -409,7 +409,11 @@ void GenericProcessor::updateChannelIndexes(bool updateNodeID)
 	{
 		DataChannel* channel = dataChannelArray[i];
 		if (updateNodeID)
+		{
 			channel->m_nodeID = nodeId;
+			channel->m_currentNodeName = getName();
+			channel->m_currentNodeType = getName(); //Fix when the ability to name individual processors is implemented
+		}
 		uint32 sourceID = getProcessorFullId(channel->getSourceNodeID(), channel->getSubProcessorIdx());
 		dataChannelMap[sourceID][channel->getSourceIndex()] = i;
 	}
@@ -417,7 +421,11 @@ void GenericProcessor::updateChannelIndexes(bool updateNodeID)
 	{
 		EventChannel* channel = eventChannelArray[i];
 		if (updateNodeID)
+		{
 			channel->m_nodeID = nodeId;
+			channel->m_currentNodeName = getName();
+			channel->m_currentNodeType = getName(); //Fix when the ability to name individual processors is implemented
+		}
 		uint32 sourceID = getProcessorFullId(channel->getSourceNodeID(), channel->getSubProcessorIdx());
 		eventChannelMap[sourceID][channel->getSourceIndex()] = i;
 	}
@@ -425,7 +433,11 @@ void GenericProcessor::updateChannelIndexes(bool updateNodeID)
 	{
 		SpikeChannel* channel = spikeChannelArray[i];
 		if (updateNodeID)
+		{
 			channel->m_nodeID = nodeId;
+			channel->m_currentNodeName = getName();
+			channel->m_currentNodeType = getName(); //Fix when the ability to name individual processors is implemented
+		}
 		uint32 sourceID = getProcessorFullId(channel->getSourceNodeID(), channel->getSubProcessorIdx());
 		spikeChannelMap[sourceID][channel->getSourceIndex()] = i;
 	}
-- 
GitLab