Hi, I'm new to angelcode and have a nooby question. I have a class called "DebugConsole" which simply prints debug messages to the screen when you call its public "println" method. That works perfectly fine in C++, but is causing issues when I try to do it from angelscript.
The way it works is that DebugConsole owns an std::vector of pointers to TextNodes (which are nodes in my engine that render strings in the render loop). This means that the DebugConsole only works if it has a valid array of those textnodes. However, when I call "println" on the DebugConsole handle, which I've registered as a global property, I know that the println function is successfully called because I'm printing logs to stdout, but when it tries to access the array of textnodes, it seems to find garbage data. This makes me suspect that the pointer Angelscript has is invalid.
Here is how I'm initializing everything:
//Register type
engine->RegisterObjectType("DebugConsole", 0, asOBJ_REF|asOBJ_NOCOUNT);
//Register method
engine->RegisterObjectMethod("DebugConsole","void println(string)", asMETHOD(DebugConsole, println), asCALL_THISCALL);
...
//This works, confirming that 'dbg' points to a valid DebugConsole instance
dbg->println("Hello from C++!");
//Register handle as global property
game->angel->getScriptEngine()->RegisterGlobalProperty("DebugConsole@ Console", dbg);
//Compilation; works. (see below for createModuleFromSource impl.)
int ret = game->angel->createModuleFromSource("testscr",src,true);
if(ret!=0){
Log::i("playscene", "compilation failed!");
}else{
game->angel->addContextByDecl(0, "testscr", "void main()");
//above just calls CContextMgr::AddContext(engine, engine->GetModule("testscr")->GetFunctionByDecl("void main()"), false);
}
//Angelscript source:
void main(){
string msg = "Hello from script!";
Console.println(msg);
}
Now here is the implementation of the println method in DebugConsole:
void DebugConsole::println(std::string ln){
//Print stuff to stdout for debugging
Log::I() << "DebugConsole::println('" << str << "');" << std::endl;
Log::I() << "numLines: " << numLines << std::endl;
Log::I() << "lines.size: " << lines.size() << std::endl;
lines[cline]->setText(str);
cline++;
if(cline>=lines.size())
cline = 0;
}
Finally, when I run the program, this is what the output looks like:
First, the "Hello from C++" line is called, and it works as expected:
QuoteDebugConsole::println: 'Hello from C++!'
numLines: 5
lines.size: 5
Then, the Angelscript is compiled and executed, and this is printed before the program crashes:
QuoteDebugConsole::println: 'Hello from script!'
numLines: 1414866944
lines.size: 18446744073709545184
As you can see, numLines/lines.size are just a bunch of random values, yet the function is successfully printing the debug stuff.
So what could be the issue here? DebugConsole is supposed to be a singleton that will outlast any script, which is why I disabled reference counting and didn't implement any ctors/dtors. The pointer I'm passing to RegisterGlobalProperty is a valid one that has been tested to work (it was also initialized on the heap, so it's not getting deleted automatically or anything like that, at least afaik). The object method registration is seemingly fine since it is being called successfully and even printing debug logs to stdout.
I appreciate any help!
createModuleFromSource implementation:
int createModuleFromSource(const char *mname, const char *src, bool compile){
int r;
CScriptBuilder builder;
r = builder.StartNewModule(engine, mname);
if(r<0){
Log::e("angel", "Failed to create module");
return 1;
}
r = builder.AddSectionFromMemory(mname, src, strlen(src), 0);
if(r<0){
Log::e("angel", "Failed to add section");
return 2;
}
if(compile){
r = builder.BuildModule();
if(r<0){
Log::e("angel", "Failed to compile module");
return 3;
}
}
return 0;
}