2018-09-27 04:03 PM - last edited on 2022-10-06 01:04 PM by Daniel Kassai
Solved! Go to Solution.
2018-10-02 07:17 PM
#include "MemoryIChannel.hpp" #include "MemoryOChannel.hpp" #include "SetPlatformProtocol.hpp" class MyUserData { Int32 id; char string[128]; GSErrCode LoadFromUserData (const API_ElementUserData& userData); GSErrCode SaveToUserData (API_ElementUserData& userData) const; public: MyUserData () : id (-1) {} MyUserData (Int32 id, const char* cstr) : id (id) { CHTruncate (cstr, string, sizeof (string)); } GSErrCode GetFromElement (const API_Guid& elemGuid); GSErrCode SetToElement (const API_Guid& elemGuid) const; }; // ----------------------------------------------------------------------------- // How to set: MyUserData userData (1234, "My own ID"); userData.SetToElement (elemGuid); // How to get: MyUserData userData2; if (userData2.GetFromElement (elemGuid2) != APIERR_NOUSERDATA) { // } // ----------------------------------------------------------------------------- GSErrCode MyUserData::LoadFromUserData (const API_ElementUserData& userData) { IO::MemoryIChannel memChannel (*(userData.dataHdl), BMGetHandleSize (userData.dataHdl)); IO::SetPlatformIProtocol (memChannel, static_cast<GS::PlatformSign> (userData.platformSign)); GSErrCode err = NoError; err = memChannel.Read (id); if (err != NoError) return err; err = memChannel.Read (string); if (err != NoError) return err; return NoError; } GSErrCode MyUserData::SaveToUserData (API_ElementUserData& userData) const { userData.dataVersion = 1; userData.platformSign = GS::Act_Platform_Sign; userData.flags = APIUserDataFlag_FillWith | APIUserDataFlag_Pickup; IO::MemoryOChannel memChannel; memChannel.Write (id); memChannel.Write (string); const USize nBytes = memChannel.GetDataSize (); const char* pData = memChannel.GetDestination (); userData.dataHdl = BMAllocateHandle (nBytes, ALLOCATE_CLEAR, 0); if (userData.dataHdl == nullptr) return APIERR_MEMFULL; BNCopyMemory (*(userData.dataHdl), pData, nBytes); return NoError; } GSErrCode MyUserData::GetFromElement (const API_Guid& elemGuid) { API_ElementUserData userData = {}; API_Elem_Head elemHead = {}; elemHead.guid = elemGuid; GSErrCode err = ACAPI_Element_GetUserData (&elemHead, &userData); if (err != NoError) return err; err = LoadFromUserData (userData); BMKillHandle (&userData.dataHdl); return err; } GSErrCode MyUserData::SetToElement (const API_Guid& elemGuid) const { API_ElementUserData userData = {}; GSErrCode err = SaveToUserData (userData); if (err != NoError) return err; API_Elem_Head elemHead = {}; elemHead.guid = elemGuid; err = ACAPI_Element_SetUserData (&elemHead, &userData); BMKillHandle (&userData.dataHdl); return err; }
2018-09-27 04:55 PM
2018-09-27 05:44 PM
2018-09-28 10:35 AM
int savedData = 234; int* savedDataPtr = &savedData; int** sDataPtrPtr = &savedDataPtr; API_AttributeUserData MyUserData; userData.dataVersion = 1234; userData.platformSign = GS::Win_Platform_Sign; userData.dataHdl = BMAllocateHandle(sizeof(int), ALLOCATE_CLEAR,0); GSErr ud_err = BMPtrAndHandle(&sDataPtrPtr, userData.dataHdl, sizeof(int)); GS::ErrCode err = ACAPI_Attribute_SetUserData(&attr.header, &userData);
2018-10-02 05:09 PM
2018-10-02 07:17 PM
#include "MemoryIChannel.hpp" #include "MemoryOChannel.hpp" #include "SetPlatformProtocol.hpp" class MyUserData { Int32 id; char string[128]; GSErrCode LoadFromUserData (const API_ElementUserData& userData); GSErrCode SaveToUserData (API_ElementUserData& userData) const; public: MyUserData () : id (-1) {} MyUserData (Int32 id, const char* cstr) : id (id) { CHTruncate (cstr, string, sizeof (string)); } GSErrCode GetFromElement (const API_Guid& elemGuid); GSErrCode SetToElement (const API_Guid& elemGuid) const; }; // ----------------------------------------------------------------------------- // How to set: MyUserData userData (1234, "My own ID"); userData.SetToElement (elemGuid); // How to get: MyUserData userData2; if (userData2.GetFromElement (elemGuid2) != APIERR_NOUSERDATA) { // } // ----------------------------------------------------------------------------- GSErrCode MyUserData::LoadFromUserData (const API_ElementUserData& userData) { IO::MemoryIChannel memChannel (*(userData.dataHdl), BMGetHandleSize (userData.dataHdl)); IO::SetPlatformIProtocol (memChannel, static_cast<GS::PlatformSign> (userData.platformSign)); GSErrCode err = NoError; err = memChannel.Read (id); if (err != NoError) return err; err = memChannel.Read (string); if (err != NoError) return err; return NoError; } GSErrCode MyUserData::SaveToUserData (API_ElementUserData& userData) const { userData.dataVersion = 1; userData.platformSign = GS::Act_Platform_Sign; userData.flags = APIUserDataFlag_FillWith | APIUserDataFlag_Pickup; IO::MemoryOChannel memChannel; memChannel.Write (id); memChannel.Write (string); const USize nBytes = memChannel.GetDataSize (); const char* pData = memChannel.GetDestination (); userData.dataHdl = BMAllocateHandle (nBytes, ALLOCATE_CLEAR, 0); if (userData.dataHdl == nullptr) return APIERR_MEMFULL; BNCopyMemory (*(userData.dataHdl), pData, nBytes); return NoError; } GSErrCode MyUserData::GetFromElement (const API_Guid& elemGuid) { API_ElementUserData userData = {}; API_Elem_Head elemHead = {}; elemHead.guid = elemGuid; GSErrCode err = ACAPI_Element_GetUserData (&elemHead, &userData); if (err != NoError) return err; err = LoadFromUserData (userData); BMKillHandle (&userData.dataHdl); return err; } GSErrCode MyUserData::SetToElement (const API_Guid& elemGuid) const { API_ElementUserData userData = {}; GSErrCode err = SaveToUserData (userData); if (err != NoError) return err; API_Elem_Head elemHead = {}; elemHead.guid = elemGuid; err = ACAPI_Element_SetUserData (&elemHead, &userData); BMKillHandle (&userData.dataHdl); return err; }
2018-10-02 10:30 PM
2018-10-07 04:01 PM
GS::ErrCode MyUserData::SetToAttrib(const API_Attribute& attrib) const { API_AttributeUserData userData = {}; GSErrCode err = SaveToUserDataAtt(userData); if (err != NoError) return err; API_Attr_Head attHead = {}; attHead.index = attrib.header.index; attHead.typeID = attrib.header.typeID; err = ACAPI_Attribute_SetUserData(&attHead, &userData); BMKillHandle(&userData.dataHdl); return err; }
GS::ErrCode MyUserData::GetFromAttribute(const API_Attribute& attrib) { API_AttributeUserData userData = {}; API_Attr_Head attHead = {}; attHead.index = attrib.header.index; attHead.typeID = attrib.header.typeID; GSErrCode err = ACAPI_Attribute_GetUserData(&attHead, &userData); if (err != NoError) return err; err = LoadFromUserDataAtt(userData); BMKillHandle(&userData.dataHdl); return err; }
2018-10-07 05:02 PM
kzaremba wrote:Nice, I'm glad you succeed!
It's working perfectly. I added Attributes as well there is a slight adjustment since ACAPI_Attribute_Set_UserData takes only type and Idx instead of GUID. So I'm passing API_Attribute instead of GUID.
kzaremba wrote:It has historical reasons. The first ARCHICAD version was released more than 30 years ago and the first API version is also more than 20 years old. Back then C++ was still just a baby...
I was recently wondering why the whole API is not structured as classes?? But with structs and all methods as separate functions. It would be much easier to have API_Element as a class with all parameters and methods warped up in one class.
2018-10-08 08:14 PM
Tibor wrote:Thx to you
Nice, I'm glad you succeed!
Tibor wrote:So if it's only historical... Do you think there is a possibility to start GitRepository (or similar solution) to create the library of classes working with actual API (like the example above)? So if someone is interested in developing such an approach could collaborate and build upon some examples like this? This might be an even better way to share this knowledge than the forum where some topics are covered by the others.
it would be much more easier that way