(svn r12277) [NoAI] -Change: overlay GlobalPointer with local instance access and create sub-node to contain data noai
authortruebrain
Tue, 26 Feb 2008 21:35:22 +0000
branchnoai
changeset 9782 e8d8d8894f23
parent 9781 d583b3eb60e0
child 9783 771250d9488a
(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]
src/ai/ai_squirrel.cpp
src/ai/ai_squirrel.hpp
src/ai/api/ai_controller.cpp
src/ai/api/ai_controller.hpp
src/ai/api/ai_controller.hpp.sq
src/squirrel.cpp
src/squirrel.hpp
--- 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 */
--- 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<FSquirrel> {
--- 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);
+}
--- 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 */
--- 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 <AIControllerSquirrel> 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);
 }
--- 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);
 }
--- 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.