b25930f7b6fde6c25fba09fb94c578d5b5d60708
[supertux.git] / src / scripting / wrapper_util.cpp
1 #include <config.h>
2
3 #include <stdexcept>
4 #include <sstream>
5 #include "wrapper_util.hpp"
6
7 static void register_function(HSQUIRRELVM v, SQFUNCTION func, const char* name)
8 {
9     sq_pushstring(v, name, -1);
10     sq_newclosure(v, func, 0); //create a new function
11     if(sq_createslot(v, -3) < 0) {
12         std::stringstream msg;
13         msg << "Couldn't register function '" << name << "'";
14         throw SquirrelError(v, msg.str());
15     }
16 }
17
18 static void register_class(HSQUIRRELVM v, WrappedClass* wclass)
19 {
20     sq_pushstring(v, wclass->name, -1);
21     sq_newclass(v, false);
22     register_functions(v, wclass->functions);
23     register_constants(v, wclass->int_consts);
24     register_constants(v, wclass->float_consts);
25     register_constants(v, wclass->string_consts);
26
27     if(sq_createslot(v, -3) < 0) {
28         std::stringstream msg;
29         msg << "Couldn't register function '" << wclass->name << "'";
30         throw SquirrelError(v, msg.str());
31     }
32 }
33
34 void register_functions(HSQUIRRELVM v, WrappedFunction* functions)
35 {
36     sq_pushroottable(v);
37     for(WrappedFunction* func = functions; func->name != 0; ++func) {
38         register_function(v, func->f, func->name);
39     }
40     sq_pop(v, 1);
41 }
42
43 void register_classes(HSQUIRRELVM v, WrappedClass* classes)
44 {
45     sq_pushroottable(v);
46     for(WrappedClass* wclass = classes; wclass->name != 0; ++wclass) {
47         register_class(v, wclass);
48     }
49     sq_pop(v, 1);
50 }
51
52
53 void print_squirrel_stack(HSQUIRRELVM v)
54 {
55     printf("--------------------------------------------------------------\n");
56     int count = sq_gettop(v);
57     for(int i = 1; i <= count; ++i) {
58         printf("%d: ",i);
59         switch(sq_gettype(v, i))
60         {
61             case OT_NULL:
62                 printf("null");        
63                 break;
64             case OT_INTEGER: {
65                 int val;
66                 sq_getinteger(v, i, &val);
67                 printf("integer (%d)", val);
68                 break;
69             }
70             case OT_FLOAT: {
71                 float val;
72                 sq_getfloat(v, i, &val);
73                 printf("float (%f)", val);
74                 break;
75             }
76             case OT_STRING: {
77                 const char* val;
78                 sq_getstring(v, i, &val);
79                 printf("string (%s)", val);
80                 break;    
81             }
82             case OT_TABLE:
83                 printf("table");
84                 break;
85             case OT_ARRAY:
86                 printf("array");
87                 break;
88             case OT_USERDATA:
89                 printf("userdata");
90                 break;
91             case OT_CLOSURE:        
92                 printf("closure(function)");    
93                 break;
94             case OT_NATIVECLOSURE:
95                 printf("native closure(C function)");
96                 break;
97             case OT_GENERATOR:
98                 printf("generator");
99                 break;
100             case OT_USERPOINTER:
101                 printf("userpointer");
102                 break;
103             case OT_THREAD:
104                 printf("thread");
105                 break;
106             case OT_CLASS:
107                 printf("class");
108                 break;
109             case OT_INSTANCE:
110                 printf("instance");
111                 break;
112             default:
113                 printf("unknown?!?");
114                 break;
115         }
116         printf("\n");
117     }
118     printf("--------------------------------------------------------------\n");
119 }
120
121 //----------------------------------------------------------------------------
122
123 SquirrelError::SquirrelError(HSQUIRRELVM v, const std::string& message) throw()
124 {
125   std::ostringstream msg;
126   msg << "SQuirrel error: " << message << " (";
127   const char* lasterr;
128   sq_getlasterror(v);
129   if(sq_gettype(v, -1) != OT_STRING) {
130     lasterr = "no error info";
131   } else {
132     sq_getstring(v, -1, &lasterr);
133   }
134   sq_pop(v, 1);
135   msg << lasterr << ")";
136   this->message = msg.str();
137 }
138
139 SquirrelError::~SquirrelError() throw()
140 {}
141
142 const char*
143 SquirrelError::what() const throw()
144 {
145   return message.c_str();
146 }