summaryrefslogtreecommitdiffstats
path: root/squirrel_3_0_1_stable/sqplus/SquirrelBindingsUtils.cpp
blob: cd337961c2bda9007a1342a1b5ebb1dd22e9afb3 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
#include "sqplus.h"

BOOL CreateStaticNamespace(HSQUIRRELVM v,ScriptNamespaceDecl *sn)
{
	int n = 0;
	sq_pushroottable(v);
	sq_pushstring(v,sn->name,-1);
	sq_newtable(v);
	const ScriptClassMemberDecl *members = sn->members;
	const ScriptClassMemberDecl *m = NULL;
	while(members[n].name) {
		m = &members[n];
		sq_pushstring(v,m->name,-1);
		sq_newclosure(v,m->func,0);
		sq_setparamscheck(v,m->params,m->typemask);
		sq_setnativeclosurename(v,-1,m->name);
		sq_createslot(v,-3);
		n++;
	}
	const ScriptConstantDecl *consts = sn->constants;
	const ScriptConstantDecl *c = NULL;
	n = 0;
	while(consts[n].name) {
		c = &consts[n];
		sq_pushstring(v,c->name,-1);
		switch(c->type) {
		case OT_STRING: sq_pushstring(v,c->val.s,-1);break;
		case OT_INTEGER: sq_pushinteger(v,c->val.i);break;
		case OT_FLOAT: sq_pushfloat(v,c->val.f);break;
		}
		sq_createslot(v,-3);
		n++;
	}
	if(sn->delegate) {
		const ScriptClassMemberDecl *members = sn->delegate;
		const ScriptClassMemberDecl *m = NULL;
		sq_newtable(v);
		while(members[n].name) {
			m = &members[n];
			sq_pushstring(v,m->name,-1);
			sq_newclosure(v,m->func,0);
			sq_setparamscheck(v,m->params,m->typemask);
			sq_setnativeclosurename(v,-1,m->name);
			sq_createslot(v,-3);
			n++;
		}
		sq_setdelegate(v,-2);
	}
	sq_createslot(v,-3);
	sq_pop(v,1);
	
	return TRUE;
}

BOOL CreateClass(HSQUIRRELVM v,SquirrelClassDecl *cd)
{
	int n = 0;
	int oldtop = sq_gettop(v);
	sq_pushroottable(v);
	sq_pushstring(v,cd->name,-1);
	if(cd->base) {
		sq_pushstring(v,cd->base,-1);
		if(SQ_FAILED(sq_get(v,-3))) { // Make sure the base exists if specified by cd->base name.
			sq_settop(v,oldtop);
			return FALSE;
		}
	}
	if(SQ_FAILED(sq_newclass(v,cd->base?1:0))) { // Will inherit from base class on stack from sq_get() above.
		sq_settop(v,oldtop);
		return FALSE;
	}
//  sq_settypetag(v,-1,(unsigned int)cd);
#ifdef _WIN32
#pragma warning(disable : 4311)
#endif
	sq_settypetag(v,-1,reinterpret_cast<SQUserPointer>(cd));
	const ScriptClassMemberDecl *members = cd->members;
	const ScriptClassMemberDecl *m = NULL;
  if (members) {
    while(members[n].name) {
      m = &members[n];
      sq_pushstring(v,m->name,-1);
      sq_newclosure(v,m->func,0);
      sq_setparamscheck(v,m->params,m->typemask);
      sq_setnativeclosurename(v,-1,m->name);
      sq_createslot(v,-3);
      n++;
    }
  } // if
	sq_createslot(v,-3);
	sq_pop(v,1);
	return TRUE;
}

BOOL CreateNativeClassInstance(HSQUIRRELVM v,
                               const SQChar *classname,
                               SQUserPointer ud,
                               SQRELEASEHOOK hook)
{
  // If we don't do this, SquirrelVM keeps an old pointer around and this 
  // will be used by SquirrelObject. That crashes when using several VMs.
  SquirrelVM::Init( v );
  
  int oldtop = sq_gettop(v);
  sq_pushroottable(v);
  sq_pushstring(v,classname,-1);
  if(SQ_FAILED(sq_rawget(v,-2))){ //Get the class (created with sq_newclass()).
    sq_settop(v,oldtop);
    return FALSE;
  }
  //sq_pushroottable(v);
  if(SQ_FAILED(sq_createinstance(v,-1))) {
    sq_settop(v,oldtop);
    return FALSE;
  }

#ifdef SQ_USE_CLASS_INHERITANCE
  HSQOBJECT ho;
  sq_getstackobj(v, -1, &ho); // OT_INSTANCE
  SquirrelObject instance(ho);
  SqPlus::PopulateAncestry(v, instance, ud);
#endif
    
  sq_remove(v,-3); //removes the root table
  sq_remove(v,-2); //removes the class
  if(SQ_FAILED(sq_setinstanceup(v,-1,ud))) {
    sq_settop(v,oldtop);
    return FALSE;
  }
  sq_setreleasehook(v,-1,hook);
  return TRUE;
}



// Create native class instance and leave on stack.
BOOL CreateConstructNativeClassInstance(HSQUIRRELVM v,const SQChar * className) {
  int oldtop = sq_gettop(v);
  sq_pushroottable(v);
  sq_pushstring(v,className,-1);
  if (SQ_FAILED(sq_rawget(v,-2))) { // Get the class (created with sq_newclass()).
    sq_settop(v,oldtop);
    return FALSE;
  } // if
#if 0
  sq_remove(v,-3); // Remove the root table.
  sq_push(v,1);    // Push the 'this'.
#else // Kamaitati's change. 5/28/06 jcs.
  sq_remove(v,-2); // Remove the root table.
  sq_pushroottable(v); // Push the 'this'.
#endif
  if (SQ_FAILED(sq_call(v,1,SQTrue,SQ_CALL_RAISE_ERROR))) { // Call ClassName(): creates new instance and calls constructor (instead of sq_createinstance() where constructor is not called).
    sq_settop(v,oldtop);
    return FALSE;
  } // if
  sq_remove(v,-2); // Remove the class.
  //  int newtop = sq_gettop(v);
  return TRUE;
} // CreateConstructNativeClassInstance