# HG changeset patch # User truebrain # Date 1204061722 0 # Node ID e8d8d8894f23ad2f074444d8c87c369909a779c7 # Parent d583b3eb60e0e28c2c7755b6b28b0bf02c806dd8 (svn r12277) [NoAI] -Change: overlay GlobalPointer with local instance access and create sub-node to contain data [NoAI] -Change: relay PrintFunc to redirect via overlay and supply AIController with Print, in order to establish bypass of the log created by the AI [/STARTREK VOYAGER] diff -r d583b3eb60e0 -r e8d8d8894f23 src/ai/ai_squirrel.cpp --- a/src/ai/ai_squirrel.cpp Tue Feb 26 18:39:33 2008 +0000 +++ b/src/ai/ai_squirrel.cpp Tue Feb 26 21:35:22 2008 +0000 @@ -302,6 +302,7 @@ AIControllerSquirrel::AIControllerSquirrel(const char *script, const char *class_name) { this->engine = new Squirrel(); + this->engine->SetPrintFunction(&AIControllerSquirrel::PrintFunc); this->RegisterClasses(); this->engine->LoadScript(script); /* Create the main-class */ diff -r d583b3eb60e0 -r e8d8d8894f23 src/ai/ai_squirrel.hpp --- a/src/ai/ai_squirrel.hpp Tue Feb 26 18:39:33 2008 +0000 +++ b/src/ai/ai_squirrel.hpp Tue Feb 26 21:35:22 2008 +0000 @@ -26,6 +26,7 @@ uint GetTick() { return AIController::GetTick(); } void Sleep(uint ticks) { return AIController::Sleep(ticks); } + static void PrintFunc(bool error_msg, const char *message) { AIController::Print(error_msg, message); } }; class FSquirrel: public AIFactory { diff -r d583b3eb60e0 -r e8d8d8894f23 src/ai/api/ai_controller.cpp --- a/src/ai/api/ai_controller.cpp Tue Feb 26 18:39:33 2008 +0000 +++ b/src/ai/api/ai_controller.cpp Tue Feb 26 21:35:22 2008 +0000 @@ -8,7 +8,13 @@ #include "../../player_func.h" #include "../ai_threads.h" -void AIController::Sleep(uint ticks) +/* static */ void AIController::Sleep(uint ticks) { AI_SuspendPlayer(_current_player, ticks); } + +/* static */ void AIController::Print(bool error_msg, const char *message) +{ + if (error_msg) fprintf(stderr, "%s", message); + else printf("%s", message); +} diff -r d583b3eb60e0 -r e8d8d8894f23 src/ai/api/ai_controller.hpp --- a/src/ai/api/ai_controller.hpp Tue Feb 26 18:39:33 2008 +0000 +++ b/src/ai/api/ai_controller.hpp Tue Feb 26 21:35:22 2008 +0000 @@ -69,7 +69,14 @@ * @post the value of GetTick() will be changed exactly 'ticks' in value after * calling this. */ - void Sleep(uint ticks); + static void Sleep(uint ticks); + + /** + * Print a message to the AI log. + * @param error_msg If true, it is marked as error message. + * @param message The message you want to log. + */ + static void Print(bool error_msg, const char *message); }; #endif /* AI_CONTROLLER_HPP */ diff -r d583b3eb60e0 -r e8d8d8894f23 src/ai/api/ai_controller.hpp.sq --- a/src/ai/api/ai_controller.hpp.sq Tue Feb 26 18:39:33 2008 +0000 +++ b/src/ai/api/ai_controller.hpp.sq Tue Feb 26 21:35:22 2008 +0000 @@ -3,7 +3,8 @@ void SQAIController_Register(Squirrel *engine) { DefSQClass SQAIController("AIController"); SQAIController.PreRegister(engine); - SQAIController.DefSQMethod(engine, &AIControllerSquirrel::GetTick, "GetTick"); - SQAIController.DefSQMethod(engine, &AIControllerSquirrel::Sleep, "Sleep"); + SQAIController.DefSQMethod(engine, &AIControllerSquirrel::GetTick, "GetTick", 1, "x"); + SQAIController.DefSQStaticMethod(engine, &AIControllerSquirrel::Sleep, "Sleep", 2, "xi"); + SQAIController.DefSQStaticMethod(engine, &AIControllerSquirrel::Print, "Print", 3, "xbs"); SQAIController.PostRegister(engine); } diff -r d583b3eb60e0 -r e8d8d8894f23 src/squirrel.cpp --- a/src/squirrel.cpp Tue Feb 26 18:39:33 2008 +0000 +++ b/src/squirrel.cpp Tue Feb 26 21:35:22 2008 +0000 @@ -27,9 +27,16 @@ void Squirrel::ErrorPrintFunc(HSQUIRRELVM vm, const SQChar *s, ...) { va_list arglist; + char buf[1024]; + va_start(arglist, s); - scvfprintf(stderr, s, arglist); + vsnprintf(buf, lengthof(buf), s, arglist); va_end(arglist); + + /* Check if we have a custom print function */ + SQPrintFunc *func = ((Squirrel *)sq_getforeignptr(vm))->print_func; + if (func == NULL) fprintf(stderr, "%s", buf); + else (*func)(true, buf); } void Squirrel::RunError(HSQUIRRELVM vm, const char *error) @@ -37,7 +44,14 @@ /* Set the print function to something that prints to stderr */ SQPRINTFUNCTION pf = sq_getprintfunc(vm); sq_setprintfunc(vm, &Squirrel::ErrorPrintFunc); - DEBUG(misc, 0, "Your script made an error: %s", error); + + /* Check if we have a custom print function */ + char buf[1024]; + snprintf(buf, lengthof(buf), "Your script made an error: %s\n", error); + SQPrintFunc *func = ((Squirrel *)sq_getforeignptr(vm))->print_func; + if (func == NULL) fprintf(stderr, "%s", buf); + else (*func)(true, buf); + /* Print below the error the stack, so the users knows what is happening */ sqstd_printcallstack(vm); /* Reset the old print function */ @@ -62,10 +76,17 @@ void Squirrel::PrintFunc(HSQUIRRELVM vm, const SQChar *s, ...) { va_list arglist; + char buf[1024]; + va_start(arglist, s); - scvprintf(s, arglist); + vsnprintf(buf, lengthof(buf) - 2, s, arglist); va_end(arglist); - printf("\n"); + strcat(buf, "\n"); + + /* Check if we have a custom print function */ + SQPrintFunc *func = ((Squirrel *)sq_getforeignptr(vm))->print_func; + if (func == NULL) printf("%s", buf); + else (*func)(false, buf); } void Squirrel::AddMethod(const char *method_name, SQFUNCTION proc, uint nparam, const char *params, void *userdata, int size) @@ -198,6 +219,8 @@ Squirrel::Squirrel() { this->vm = sq_open(1024); + this->print_func = NULL; + this->global_pointer = NULL; /* Handle compile-errors ourself, so we can display it nicely */ sq_setcompilererrorhandler(this->vm, &Squirrel::CompileError); @@ -208,6 +231,9 @@ sq_newclosure(this->vm, &Squirrel::_RunError, 0); sq_seterrorhandler(this->vm); + /* Set the foreigh pointer, so we can always find this instance from within the VM */ + sq_setforeignptr(this->vm, this); + sq_pushroottable(this->vm); squirrel_register_global_std(this); } diff -r d583b3eb60e0 -r e8d8d8894f23 src/squirrel.hpp --- a/src/squirrel.hpp Tue Feb 26 18:39:33 2008 +0000 +++ b/src/squirrel.hpp Tue Feb 26 21:35:22 2008 +0000 @@ -7,7 +7,11 @@ class Squirrel { private: - HSQUIRRELVM vm; ///< The VirtualMachine instnace for squirrel + typedef void (SQPrintFunc)(bool error_msg, const char *message); + + HSQUIRRELVM vm; ///< The VirtualMachine instnace for squirrel + void *global_pointer; ///< Can be set by who ever initializes Squirrel + SQPrintFunc *print_func; ///< Points to either NULL, or a custom print handler /** * The internal RunError handler. It looks up the real error and calls RunError with it. @@ -129,15 +133,20 @@ static int ObjectToInteger(HSQOBJECT *ptr) { return sq_objtointeger(ptr); } /** - * Sets a pointer in the VM that is reasable from where ever you are, what - * ever your state is. Useful to keep track of the main instance. + * Sets a pointer in the VM that is reachable from where ever you are in SQ. + * Useful to keep track of the main instance. */ - void SetGlobalPointer(void *ptr) { sq_setforeignptr(this->vm, ptr); } + void SetGlobalPointer(void *ptr) { this->global_pointer = ptr; } /** * Get the pointer as set by SetGlobalPointer. */ - static void *GetGlobalPointer(HSQUIRRELVM vm) { return sq_getforeignptr(vm); } + static void *GetGlobalPointer(HSQUIRRELVM vm) { return ((Squirrel *)sq_getforeignptr(vm))->global_pointer; } + + /** + * Set a custom print function, so you can handle outputs from SQ yourself. + */ + void SetPrintFunction(SQPrintFunc *func) { this->print_func = func; } /** * Throw a Squirrel error that will be nicely displayed to the user.