bonusblock is a sprite and not a tile in the new design. Renamend messagebox.png...
[supertux.git] / src / scripting / wrapper_util.cpp
1 #include <config.h>
2
3 #include <stdexcept>
4 #include <sstream>
5 #include "wrapper_util.h"
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     sq_createslot(v, -3);
12 }
13
14 static void register_class(HSQUIRRELVM v, WrappedClass* wclass)
15 {
16     sq_pushstring(v, wclass->name, -1);
17     sq_newclass(v, false);
18     for(WrappedFunction* func = wclass->functions; func->name != 0; ++func) {
19         register_function(v, func->f, func->name);
20     }
21     sq_createslot(v, -3);
22 }
23
24 void register_functions(HSQUIRRELVM v, WrappedFunction* functions)
25 {
26     sq_pushroottable(v);
27     for(WrappedFunction* func = functions; func->name != 0; ++func) {
28         register_function(v, func->f, func->name);
29     }
30     sq_pop(v, 1);
31 }
32
33 void register_classes(HSQUIRRELVM v, WrappedClass* classes)
34 {
35     sq_pushroottable(v);
36     for(WrappedClass* wclass = classes; wclass->name != 0; ++wclass) {
37         register_class(v, wclass);
38     }
39     sq_pop(v, 1);
40 }
41
42 void print_squirrel_stack(HSQUIRRELVM v)
43 {
44     printf("--------------------------------------------------------------\n");
45     int count = sq_gettop(v);
46     for(int i = 1; i <= count; ++i) {
47         printf("%d: ",i);
48         switch(sq_gettype(v, i))
49         {
50             case OT_NULL:
51                 printf("null");        
52                 break;
53             case OT_INTEGER: {
54                 int val;
55                 sq_getinteger(v, i, &val);
56                 printf("integer (%d)", val);
57                 break;
58             }
59             case OT_FLOAT: {
60                 float val;
61                 sq_getfloat(v, i, &val);
62                 printf("float (%f)", val);
63                 break;
64             }
65             case OT_STRING: {
66                 const char* val;
67                 sq_getstring(v, i, &val);
68                 printf("string (%s)", val);
69                 break;    
70             }
71             case OT_TABLE:
72                 printf("table");
73                 break;
74             case OT_ARRAY:
75                 printf("array");
76                 break;
77             case OT_USERDATA:
78                 printf("userdata");
79                 break;
80             case OT_CLOSURE:        
81                 printf("closure(function)");    
82                 break;
83             case OT_NATIVECLOSURE:
84                 printf("native closure(C function)");
85                 break;
86             case OT_GENERATOR:
87                 printf("generator");
88                 break;
89             case OT_USERPOINTER:
90                 printf("userpointer");
91                 break;
92             case OT_CLASS:
93                 printf("class");
94                 break;
95             case OT_INSTANCE:
96                 printf("instance");
97                 break;
98             default:
99                 printf("unknown?!?");
100                 break;
101         }
102         printf("\n");
103     }
104     printf("--------------------------------------------------------------\n");
105 }
106
107 void expose_object(HSQUIRRELVM v, void* object, const char* type,
108         const char* name)
109 {
110     // part1 of registration of the instance in the root table
111     sq_pushroottable(v);
112     sq_pushstring(v, name, -1);
113
114     // resolve class name
115     sq_pushroottable(v);
116     sq_pushstring(v, type, -1);
117     if(sq_get(v, -2) < 0) {
118         std::ostringstream msg;
119         msg << "Couldn't resolve squirrel type '" << type << "'.";
120         throw std::runtime_error(msg.str());
121     }
122     sq_remove(v, -2); // remove roottable
123
124     // create an instance and set pointer to c++ object
125     if(sq_createinstance(v, -1) < 0 || sq_setinstanceup(v, -1, object)) {
126       std::ostringstream msg;
127       msg << "Couldn't setup squirrel instance for object '"
128           << name << "' of type '" << type << "'.";
129       throw SquirrelError(v, msg.str());
130     }
131     
132     sq_remove(v, -2); // remove class from stack
133
134     // part2 of registration of the instance in the root table
135     if(sq_createslot(v, -3) < 0)
136       throw SquirrelError(v, "Couldn't register object in squirrel root table");
137     sq_pop(v, 2);
138 }
139
140 //----------------------------------------------------------------------------
141
142 SquirrelError::SquirrelError(HSQUIRRELVM v, const std::string& message) throw()
143 {
144   std::ostringstream msg;
145   msg << "SQuirrel error: " << message << " (";
146   const char* lasterr;
147   sq_getlasterror(v);
148   sq_getstring(v, -1, &lasterr);
149   sq_pop(v, 1);
150   msg << lasterr << ")";
151   this->message = msg.str();
152 }
153
154 SquirrelError::~SquirrelError() throw()
155 {}
156
157 const char*
158 SquirrelError::what() const throw()
159 {
160   return message.c_str();
161 }