Game Development Community

SimObject and ConsoleMethod runtime CTD

by Todd Stafford · in Torque Game Engine · 07/04/2007 (12:23 pm) · 8 replies

Just started playing with Torque so I am still figuring some things out.

I made my own child class of SimObject (all based off of the wonderful example "Basic Scriptable SimObject" by John) and everthing works fine until I modify it.

OneSAFClient::OneSAFClient() {
	CommonEntityPtr theEntity;
	theEntity->name = "bob"; //this line kills it
	theMap.insert(make_pair("key",theEntity));
	
	mMemberVar = 0;
}

Here OneSAFClient is a SimObject and it currently has simple variables and the test methods from the tutorial (add, setvariable, etc...), these methods all work inside TorqueDemo. When I add the "theEntity->name="bob"" line it won't even run and windows wants to send an error report. Everything works fine if I comment that line out so does SimObject do wierd things with pointers or there some other subtleties that I am not picking up?

Btw, CommonEntityPtr is defined by ICE (a way to get Java and c++ to talk)
typedef ::IceInternal::Handle< ::Data::CommonEntity> CommonEntityPtr;

#1
07/04/2007 (1:26 pm)
Strings in Torque should normally be defined as type StringTableEntry, and initialized (and modified) with variations of StringTable->insert("bob");
#2
07/05/2007 (5:00 am)
Thanks for the reply Stephen, but I don't think that the fact that "bob" is a string is causing the runtime error.

OneSAFClient::OneSAFClient() {
	CommonEntityPtr theEntity;	
	theEntity->name = StringTable->insert("Hello World");	 //this line will kill it
	theEntity->location = new CommonTuple3d();		//and this line will kit it
	theMap.insert(make_pair("key",theEntity));
	mMemberVar = 0;
}

After taking your advice I still have the CTD even when I reference another field within theEntity, I experience the same error.

Is it something to do with how SimObjects are loaded up by Torque?

--Edit--

I created a test struct

struct TestMe {
	int x;
	int y;
	StringTableEntry name;
};

and it compiled and ran fine with torque:

OneSAFClient::OneSAFClient() {	
	test = new TestMe();
	test->name = StringTable->insert("Hello World");
}

So i guess the specific problem is Torque interfacing with Ice. Has anyone succesfully interfaced the two before? Or does anyone know what part of Ice Torque would most likely not like?
#3
07/05/2007 (8:10 am)
Hmm..you have me stumped. What does the call stack look like, and what's the specific error?
#4
07/05/2007 (12:39 pm)
My guess is that you are running into the fact that the class constructor of a SimObject is actually called multiple times before the engine is fully loaded so that the console system can populate various data it needs to start up. Doing more than basic value assignments can put you into a really bad state really quickly.

This sort of code should really be in OneSAFClient::onAdd() instead.
#5
07/05/2007 (4:10 pm)
Great catch Matt, and I agree--just hadn't thought about it :)
#6
07/10/2007 (7:43 am)
Sorry for the delay, I was pulled to a different project.

Adding the code to the onAdd method resulted in the same crash.

I added the following to the server code.

function GameConnection::onClientEnterGame(%this)
{
	<<snip>>
	$OneSAFClient = new OneSAFClient(foo); //breakpoint
	echo("OneSAFClient: " @ foo);
}

Right when that line is reached it crashes and the only call stack I could get (with the free Codeweaver IDE) was

GameConnection::onClientEnterGame		96	GameOne/server/game.cs
serverCmdMissionStartPhase3Ack		116	common/server/missionDownload.cs

Any ideas or any tips on how to get a more descriptive call stack?
#7
07/10/2007 (7:48 am)
Run the engine itself under Visual Studio in debug mode to find the c++ call stack for the crashes.

You are looking at the TorqueScript execution flow, which isn't quite as useful for debugging c++ crashes.
#8
07/10/2007 (11:23 am)
--Edit--

We figured it out :-). The problem was not in the Torque Engine or script but rather in the way we were using ICE. Once we fixed the ICE side everything works, thanks for the help.