SOLVED Add values for enum data type (node graph)

Hello,
I am trying to create an enum data type with some values (options) added but I can't get the options added to this data type.

When setting DESCRIPTION::DATA::BASE::ENUM it requires an maxon::Array<Tuple<Id, Data>> as a value type, but even if I create a variable of that type and add some values, its size does not change and stays 0.

I also tried using BlockToEnumArray() but that would return an BaseArray<Tuple<Id, Data>> which is not accepted in DESCRIPTION::DATA::BASE::ENUM although the comments in the function say it does.

//----------------------------------------------------------------------------------------
/// Converts a given Block<TYPE> to a enum list array to use with DESCRIPTION::DATA::BASE::ENUM.
/// @param[in] enumBlock					Block to convert into a array.
/// @return												BaseArray on success.
//----------------------------------------------------------------------------------------
template <typename TYPE> inline Result<BaseArray<Tuple<Id, Data>>> BlockToEnumArray(const Block<TYPE>& enumBlock)

Also converting BaseArray<Type> to Array<Type> did not work.
I'm not sure what I am doing wrong.

Thank you.

I solved this by having two typename in the template in the Set function.

template <typename ATTR, typename VAL> Result<void> Set(const Id& category, const ATTR& attr, const VAL& value)
 {
 // Retrieve the category"s and add an attribute.
 iferr_scope;
 DataDictionary& dict = GetPortDictionary(category) iferr_return;
 dict.Set(attr, value) iferr_return;
 return OK;
 }

Thanks for your time.

Hey @ogers,

Thank you for reaching out to us. I think I understand what you are talking about, but just to be sure, when you say:

I am trying to create an enum data type with some values (options) added but I can't get the options added to this data type.

Because the word create is ambiguous, this could be interpreted as you wanting to implement some form of maxon::DataType, i.e., what is more or less a struct in canonical C++. But you want to just instantiate some form of maxon::BaseCollection to be used in the field maxon::DESCRIPTION::DATA::BASE::ENUM of a maxon::DataDictionary, right?

maxon::Array is a type template of datadictionary.h, I never really understood myself why it is there or what it is good for since it does not really do anything. But it is used in many fields of data dictionaries and can be written with some common collection types we have, e.g., BaseArray.

The field maxon::DESCRIPTION::DATA::BASE::ENUM must be written as a maxon::BaseArray<maxon::Tuple<maxon::Id, maxon::Data>> instance. But it also requires that BaseArray to be built by the function maxon::BlockToEnumArray() as the function formats the BaseArray in a distinct way. Here is some obfuscated code how we write that field internally:

static const maxon::Block<maxon::Id> GetStuff()
{
    static maxon::Id stuff[] = {maxon::Id("A"), maxon::Id("B"), maxon::Id("C")};
    return maxon::ToBlock(stuff)
}

...

maxon::BaseArray<maxon::Tuple<maxon::Id, maxon::Data>> data = maxon::BlockToEnumArray(GetStuff()) iferr_return;
someDataDictionary.Set(maxon::DESCRIPTION::DATA::BASE::ENUM, std::move(data)) iferr_return;

I could go into details here, but I think we use this weird form with the function GetStuff() intentionally due to constness requirements of the block, as you are otherwise unable to define a const block with non const elements which is not empty.

If you run still into problems, I would ask you to provide more code and context for what you are doing and the exact compiler errors you run into.

Cheers,
Ferdinand

Hello @ferdinand
Thank you for your reply. Yes, your assumption is right, sorry to confuse you.
I forgot to mention that I am getting this error when setting the values when using Set function from documentation

template <typename ATTR> Result<void> Set(const Id& category, const ATTR& attr, const typename ATTR::ValueType& value)
 {
 // Retrieve the category"s and add an attribute.
 iferr_scope;
 DataDictionary& dict = GetPortDictionary(category) iferr_return;
 dict.Set(attr, value) iferr_return;
 return OK;
 }

For some reason, I can't even post my full reply here. I thought the system was down yesterday that's why I could not reply, but when making the message shorter today it was posted successfully.
reply error video.
I don't know if I should create another thread for this.
Thank you.

Hello @Ogers,

this is likely caused by the hype aggressive filtering mechanisms of NodeBB. You cannot write 'chr (' without the white space between the r and ( character for example. The issue is likely introduced by either one of your code listings or the console output.

Please use either Pastebin or a similar site, or reach out to us via mail.

Cheers,
Ferdinand

I have pasted the message here.
https://pastebin.com/mB3i8TTM

Thank you.

I solved this by having two typename in the template in the Set function.

template <typename ATTR, typename VAL> Result<void> Set(const Id& category, const ATTR& attr, const VAL& value)
 {
 // Retrieve the category"s and add an attribute.
 iferr_scope;
 DataDictionary& dict = GetPortDictionary(category) iferr_return;
 dict.Set(attr, value) iferr_return;
 return OK;
 }

Thanks for your time.

Hi,

you can also create your own blockToArray function like so

template <typename TYPE> inline Result<Array<Tuple<Id, Data>>> BlockToEnumArray(const Block<TYPE>& enumBlock)
{
	 iferr_scope;
	 Array<Tuple<Id, Data>> codecEnum;
	 for (const TYPE& val : enumBlock)
	 {
		 CString str = FormatCString("@", val);
		 Id id;
		 id.Init(str) iferr_return;
		 codecEnum.Append({ id, Data(val) }) iferr_return;
	 }
	 return std::move(codecEnum);
 }

Or directly create the array for the enum parameter like so.

maxon::Array<maxon::Tuple<maxon::Id, maxon::Data>> data;
data.Append({ maxon::Id("Test1") , maxon::Data("Test1")}) iferr_return;
data.Append({ maxon::Id("Test2") , maxon::Data("Test2")}) iferr_return;
data.Append({ maxon::Id("Test3") , maxon::Data("Test3")}) iferr_return;

Doing this, you can use the Setfunction provided.

Cheers,
Manuel

Hello,

Thanks for the code.
Regarding the second one, I have tried it and also mentioned in the first message that the data does not get added and the array size still stays 0.
I had forgotten to put iferr_return and now with your example, I am getting a critical error when trying to append those data.

RefMemberType<S> CritStop()
{
CriticalOutput(static_cast<const typename S::ReferenceClass*>(this)->ToString()); return this->PrivateGetRefMember();
}