Hello everybody. I had a question.
I'm creating a simple class to auto free SelectionSet's name(acedSSFree) when my SSNameRel object goes out of its scope.
My code is below. It seems that the command ran without errors. But I'm not sure what I'm doing is correct?
Cause at the step「acedSSFree(_ssNameVector[i])」I'm transferring the int64_t* instead of the ads_name.
The reason for this is when I tried to use ads_name, It will generate error at the step Vector::push_back(ads_name ssName) so I decided to use int64_t* instead.
Thanks in advance!
/// <summary>
/// Help class to auto free multiple SelectionSet name
/// when its object goes out of scope.
/// </summary>
class SSNameRel
{
public:
SSNameRel();
~SSNameRel();
void AddAdsName(int64_t* ssName);
private:
std::vector<int64_t*> _ssNameVector;
};
SSNameRel::SSNameRel()
{
}
void SSNameRel::AddAdsName(int64_t* ssName)
{
_ssNameVector.push_back(ssName);
}
SSNameRel::~SSNameRel()
{
size_t vectorSize = _ssNameVector.size();
if (vectorSize > 0 )
{
for (size_t i = 0; i < vectorSize; i++)
{
if (acedSSFree(_ssNameVector[i]) != RTNORM)
{
acrx_abort(L"\nCannot free selection name!");
}
}
}
}
//Sample to illustrate the implementation of auto SelectionSet's name free:
void TestSS1()
{
SSNameRel mySSNameRel;
ads_name ssName;
int rc;
int MaxCount = 5; //Ask user select 5 times
for (int i = 0; i < MaxCount; i++)
{
rc = acedSSGet(NULL, NULL, NULL, NULL, ssName);
if (rc == RTCAN)
{
return;
}
else if (rc == RTERROR || rc == RTNONE)
{
acutPrintf(L"\nCannot get SelectionSet!");
return;
}
else
{
acutPrintf(L"\nYour Selection set %d", i + 1);
mySSNameRel.AddAdsName(ssName);
Adesk::Int32 ssLen;
acedSSLength(ssName, &ssLen);
acutPrintf(L"\nNumber of selected items: %d", ssLen);
}
}
}
Solved! Go to Solution.
Solved by tbrammer. Go to Solution.
Solved by tbrammer. Go to Solution.
What about using ArxDbgSelSet class from ObjectARX SDK sample ARXDBG ( samples\database\ARXDBG\AcadUtils\ArxDbgSelSet.cpp ) ?
Відповідь корисна? Клікніть на "ВПОДОБАЙКУ" цім повідомленням! | Do you find the posts helpful? "LIKE" these posts!
Находите сообщения полезными? Поставьте "НРАВИТСЯ" этим сообщениям!
На ваше запитання відповіли? Натисніть кнопку "ПРИЙНЯТИ РІШЕННЯ" | Have your question been answered successfully? Click "ACCEPT SOLUTION" button.
На ваш вопрос успешно ответили? Нажмите кнопку "УТВЕРДИТЬ РЕШЕНИЕ"
Alexander Rivilis / Александр Ривилис / Олександр Рівіліс
Programmer & Teacher & Helper / Программист - Учитель - Помощник / Програміст - вчитель - помічник
Facebook | Twitter | LinkedIn
@Alexander.Rivilis Thanks for your reply.
I saw the code of ArxDbgSelSet 's class. I think this class is very detailed for many cases of SelectionSet.
I will consider to use this when handling with multiple types of selection.
But now I want to know that when using acutSSFree(ads_name), if i pass the first element's address of ads_name array, so the function acutSSFree(int64_t *) will return RTNORM. So I think at this time my SelectionSet is released successfully, but am I wrong?
Thanks in advance!
Your code will not work in general. But it can be fixed easily.
void SSNameRel::AddAdsName(int64_t* ssName) {
_ssNameVector.push_back(ssName);
}
void TestSS1() {
ads_name ssName;
SSNameRel mySSNameRel; // same scope as ssName. OK.
acedSSGet(NULL, NULL, NULL, NULL, ssName);
mySSNameRel.AddAdsName(ssName);
}
void BadSelection(SSNameRel &mySSNameRel) {
ads_name ssName;
acedSSGet(NULL, NULL, NULL, NULL, ssName);
mySSNameRel.AddAdsName(ssName);
}
void BadSelSecUsage() {
SSNameRel mySSNameRel;
BadSelection(SSNameRel &mySSNameRel);
use(mySSNameRel); // NO! ads_name is out of scope.
// int64_t* in _ssNameVector points to released memory
...
}
class SelSetContainer
{
public:
SelSetContainer(ads_name ss) {
ads_name_set(ss, m_ss);
}
void free() {
acedSSFree(m_ss);
}
private:
ads_name m_ss;
};
class SSNameRel
{
public:
~SSNameRel() {
for (auto &ss : _ssNameVector)
ss.free();
}
void AddAdsName(ads_name ss) {
_ssNameVector.push_back(SelSetContainer(ss));
}
private:
std::vector<SelSetContainer> _ssNameVector;
};
@tbrammer Thanks for your reply. I understood your solution.
I think your instruction is very clear and understandable.
More over this also help me to understand more about bad usage when Release Object and ssname not in the same scope.
One more thing I want to ask related to using acedSSGetKwordCallbackPtr(). As I saw in this post,
https://adndevblog.typepad.com/autocad/2013/01/using-acedsssetkwordcallbackptr-on-selections.html
author store the old function pointer first, then set the new one, then set back to the old funtion pointer before going out of the method.
I tried to not store the old function pointer and set the new one directly, the sample command still run well.
After the sample command is finished I tried other Autocad's commands(Move/ copy ...vv) to test whether the KeyWordCallBack still remember the above new function pointer but it seems that when above sample command finished. KeyWordCallBack is auto set back to the original set up, but I don't know if I made any mistake?
Thanks in advance!
The ARX docs say that the old function pointer should be restored.
I don't know what happens if you don't do this. Maybe you run into problems if another 3rd party module changed the function pointer. I would just restore it after switching and using my own.
Can't find what you're looking for? Ask the community or share your knowledge.