Creating SimObject from C++: Crashes when accessed by name
by Demolishun · in Torque 3D Professional · 10/07/2012 (12:46 am) · 7 replies
This is a very strange problem. I have a custom ScriptObject class. It has some very minor changes to it to facilitate it acting as a container class for external scripting objects. However, the problem I am having I believe to be a pure Torque Script issue.
Here is what happens:
Here is what happens:
- I create the object using Sim::spawnObject. That might be part of the issue.
- I then process the external object I want to contain this object. As part of that process I rename the object using assignName.
- The object gets created from C++ code at some point.
- If I go into the console and type in the object ID everything works fine. If I first go in and type in the assigned name with a function like dump then it crashes. If I had previously used the object id only: 4170.dump(); and then used the by name method py4170.dump(); then it works fine. There is something about accessing the object by id the first time that makes it work fine to access the object by name or id.
extScriptObject *tmpsobj = (extScriptObject*)Sim::spawnObject(String("extScriptObject"),String(""),String(name),String(properties));
...
dSprintf(buffer,512,"py%d",extsobject->getId());
extsobject->assignName(buffer);
...
// in the console after object creation and not accessing the object beforehand
py4170.dump(); //crash
...
// in the console after object creation and not accessing the object beforehand
4170 //fine, here it accesses the object, but does nothing with it
py4170.dump(); //fine
...
// in the console after object creation and not accessing the object beforehand
py4170 //fine, here it accesses the object, but does nothing with it
py4170.dump(); //fineAbout the author
I love programming, I love programming things that go click, whirr, boom. For organized T3D Links visit: http://demolishun.com/?page_id=67
#2
10/07/2012 (11:54 am)
You can try creating from C++ instead of using the spawnobject function that goes through the script console.extScriptObject *tmpObj = new extScripObject();
tmpObj->registerObject("someobjectnamehere");
#3
I will have to see if I can duplicate this with a regular object that is not related to my code. Like through an evaluate or something to see if this still does this.
10/07/2012 (1:10 pm)
It is crashing inside the dump function:> _scriptT3D.pyd!dIsalnum(const char c='Ì') Line 146 + 0xa bytes C++ _scriptT3D.pyd!`anonymous namespace'::sFindArgumentListSubstring(const char * usage=0x0027f7b0, const char * & start=0x0c56b0b8, const char * & end=0x0c56b0b8) Line 1343 + 0xc bytes C++ _scriptT3D.pyd!Namespace::Entry::getDocString() Line 1516 + 0x14 bytes C++ _scriptT3D.pyd!Namespace::Entry::getBriefDescription(String * outRemainingDocText=0x00000000) Line 1494 + 0xc bytes C++ _scriptT3D.pyd!`anonymous namespace'::DocString::DocString(Namespace::Entry * entry=0x0c49996c) Line 2187 C++ _scriptT3D.pyd!_SimObjectdumpframe::_exec(bool detailed=false) Line 2319 + 0x12 bytes C++The weird thing is that if I wait for a bit before doing anything it does not crash. It acts like it is a startup/object-init issue of some sort.
I will have to see if I can duplicate this with a regular object that is not related to my code. Like through an evaluate or something to see if this still does this.
#4
10/07/2012 (1:12 pm)
Look at the character on line 1 of the traceback. It is another & issue. That was a tilde I. I may have to update my wonky text fixer resource.
#5
Edit:
Why does this fix this issue? Because assignName calls unlinkNamespaces and linkNamespaces on the object. Since you cannot call those directly I am using the fact that they are called indirectly by calling assignName.
10/07/2012 (1:35 pm)
Okay, I am so lame. I am modifying the namespace when I add functions to the object and am wondering why it is having issues. I changed my code so it assigns the new name after I add a bunch of functions to the object. This seems to have made the crashes disappear.Namespace *ns = extsobject->getNamespace();
// get list of attributes
PyObject *tmpList = PyObject_Dir((PyObject *)cbObject);
if (PyList_Check(tmpList)){
int size = PyList_Size(tmpList);
for (int i = 0; i < size; i++) {
PyObject *ostr = PyList_GetItem(tmpList,i);
if (PyString_Check(ostr)){
PyObject *o = PyObject_GetAttr((PyObject *)cbObject, ostr);
if(PyCallable_Check(o)){
//Con::printf("%s.%s()",extsobject->getName(),PyString_AsString(ostr));
//Con::printf("%s.%s()",extsobject->getName(),PyString_AsString(ostr));
//Con::addScriptCommand(ns, name, pyScriptCallback, usage, minargs+2, maxargs+2);
dSprintf(buffer,512,"%s()",PyString_AsString(ostr)); // get function name for usage
ns->addScriptCommand( StringTable->insert(PyString_AsString(ostr)), pyScriptCallback, buffer, 0, 0, false, NULL );
pyExtCallBackObject *newcbobj = new pyExtCallBackObject((void *)o);
if(!newcbobj){
Con::errorf("pyExtCallBackObject::exportFunctions - error creating pyExtCallBackObject");
break;
}
struct MarshalNativeEntry *nEntry = script_get_namespace_entry(ns->getName(), PyString_AsString(ostr));
gScriptCallbackLookup.insertEqual(nEntry->entry,(void*)(newcbobj));
// remember ref
Py_XINCREF(o);
}
else{
//Con::printf("%s.%s",extsobject->getName(),PyString_AsString(ostr));
}
}
}
}else{
Con::errorf("pyExtCallBackObject::exportFunctions : non list object returned");
}
// create unique namespace for object
dSprintf(buffer,512,"py%d",extsobject->getId());
extsobject->assignName(buffer);Edit:
Why does this fix this issue? Because assignName calls unlinkNamespaces and linkNamespaces on the object. Since you cannot call those directly I am using the fact that they are called indirectly by calling assignName.
#6
@Alex,
I may have to explore that other avenue to see if it is something to do with creating an object and modifying it afterward.
10/07/2012 (1:58 pm)
Ahh crud. It still crashes. It just is a race for me to try and test this to get the crash. So I still have the same problem.@Alex,
I may have to explore that other avenue to see if it is something to do with creating an object and modifying it afterward.
#7
Edit:
I should also note that when I do an evaluate from my Python interface and do the "py4170.dump();" it does not crash. This seems to be related to the console interface in the engine only. That makes this really weird. However, since the problem goes away after a few seconds it is not something I am really concerned about anymore. Making the source change above has helped, I think. It made it harder to reproduce the crash. So I think this might be related to namespaces.
10/08/2012 (1:28 am)
This is the strangest bug I have ever seen. If I quickly open the console and quickly type in "py4170.dump();" I can get it to crash. If I wait for 5 seconds and then open the console and type in the same thing it does not crash. So what on earth could the console be doing in that time? There are no new logs being created. Weird, strange, I have no idea.Edit:
I should also note that when I do an evaluate from my Python interface and do the "py4170.dump();" it does not crash. This seems to be related to the console interface in the engine only. That makes this really weird. However, since the problem goes away after a few seconds it is not something I am really concerned about anymore. Making the source change above has helped, I think. It made it harder to reproduce the crash. So I think this might be related to namespaces.
Associate James Urquhart