Merge remote-tracking branch 'refs/remotes/origin/development' into pr/1153

This commit is contained in:
Anis A. Hireche 2016-02-26 14:39:38 +01:00
commit 10cb6ab9c4
893 changed files with 44063 additions and 6437 deletions

View file

@ -302,7 +302,7 @@ static void yy_fatal_error YY_PROTO(( yyconst char msg[] ));
#define YY_NUM_RULES 94
#define YY_END_OF_BUFFER 95
static yyconst short int yy_accept[233] =
static yyconst short int yy_accept[224] =
{ 0,
0, 0, 95, 93, 1, 5, 4, 51, 93, 93,
58, 57, 93, 41, 42, 45, 43, 56, 44, 50,
@ -320,16 +320,15 @@ static yyconst short int yy_accept[233] =
92, 87, 0, 32, 3, 3, 91, 0, 91, 89,
29, 30, 35, 34, 88, 88, 88, 88, 88, 88,
88, 88, 73, 88, 88, 76, 88, 88, 88, 88,
88, 88, 92, 0, 2, 2, 88, 88, 79, 88,
88, 88, 92, 0, 3, 2, 88, 88, 79, 88,
88, 88, 66, 88, 88, 88, 88, 88, 88, 88,
88, 85, 88, 2, 2, 2, 2, 2, 88, 64,
88, 88, 88, 86, 88, 88, 88, 88, 88, 88,
88, 68, 0, 2, 2, 67, 88, 88, 88, 88,
88, 85, 88, 3, 0, 88, 64, 88, 88, 88,
86, 88, 88, 88, 88, 88, 88, 88, 68, 0,
67, 88, 88, 88, 88, 88, 88, 88, 65, 88,
88, 88, 88, 65, 88, 81, 0, 2, 2, 88,
88, 82, 72, 88, 88, 83, 88, 80, 0, 2,
2, 2, 74, 88, 71, 75, 88, 88, 78, 84,
77, 0
81, 0, 88, 88, 82, 72, 88, 88, 83, 88,
80, 0, 74, 88, 71, 75, 88, 88, 0, 78,
84, 77, 0
} ;
static yyconst int yy_ec[256] =
@ -375,69 +374,67 @@ static yyconst int yy_meta[68] =
7, 7, 7, 1, 1, 1, 1
} ;
static yyconst short int yy_base[248] =
static yyconst short int yy_base[237] =
{ 0,
0, 0, 380, 381, 377, 381, 381, 61, 63, 51,
53, 65, 66, 381, 381, 354, 64, 381, 66, 60,
68, 76, 80, 356, 381, 60, 352, 77, 381, 381,
0, 341, 338, 345, 381, 381, 348, 311, 311, 54,
61, 315, 59, 38, 62, 309, 323, 318, 62, 306,
313, 381, 89, 381, 381, 361, 338, 381, 111, 381,
357, 100, 381, 339, 381, 381, 381, 112, 381, 355,
381, 381, 381, 333, 381, 381, 107, 381, 339, 381,
110, 114, 121, 0, 381, 332, 381, 381, 381, 331,
0, 0, 324, 324, 381, 292, 303, 290, 293, 287,
0, 0, 337, 338, 334, 338, 338, 61, 63, 51,
53, 65, 66, 338, 338, 311, 64, 338, 66, 60,
68, 76, 80, 313, 338, 60, 309, 77, 338, 338,
0, 298, 295, 302, 338, 338, 305, 268, 268, 54,
61, 272, 59, 38, 62, 266, 280, 275, 62, 263,
270, 338, 89, 338, 338, 318, 295, 338, 111, 338,
314, 100, 338, 296, 338, 338, 338, 112, 338, 312,
338, 338, 338, 290, 338, 338, 107, 338, 296, 338,
110, 114, 121, 0, 338, 289, 338, 338, 338, 288,
0, 0, 281, 281, 338, 249, 260, 247, 250, 244,
298, 0, 286, 291, 285, 287, 0, 0, 287, 278,
0, 294, 278, 282, 285, 274, 283, 381, 381, 381,
313, 312, 311, 381, 0, 139, 119, 125, 128, 0,
381, 381, 0, 0, 283, 286, 281, 267, 283, 282,
277, 264, 275, 276, 273, 0, 267, 257, 268, 256,
268, 261, 293, 292, 146, 152, 253, 258, 0, 258,
264, 246, 0, 259, 262, 244, 244, 259, 243, 247,
254, 0, 251, 155, 157, 162, 165, 168, 237, 0,
241, 242, 241, 0, 248, 241, 230, 199, 185, 190,
183, 0, 215, 173, 175, 0, 168, 172, 161, 167,
255, 0, 243, 248, 242, 244, 0, 0, 244, 235,
0, 251, 235, 239, 242, 231, 240, 338, 338, 338,
270, 269, 268, 338, 0, 139, 119, 125, 128, 0,
338, 338, 0, 0, 240, 243, 238, 224, 240, 239,
234, 221, 232, 233, 230, 0, 224, 214, 225, 213,
225, 218, 250, 249, 146, 152, 210, 215, 0, 215,
221, 203, 0, 216, 219, 201, 201, 216, 200, 204,
211, 0, 208, 155, 237, 193, 0, 197, 198, 197,
0, 204, 197, 190, 197, 190, 197, 193, 0, 225,
0, 180, 184, 179, 177, 153, 158, 151, 0, 134,
154, 164, 159, 0, 145, 198, 185, 178, 181, 153,
154, 0, 191, 141, 146, 0, 117, 381, 0, 184,
186, 191, 0, 110, 381, 0, 88, 76, 0, 0,
0, 381, 209, 213, 220, 224, 228, 232, 239, 119,
243, 250, 257, 264, 271, 278, 285
187, 157, 143, 144, 0, 176, 123, 126, 0, 112,
338, 160, 0, 115, 338, 0, 88, 76, 162, 0,
0, 0, 338, 170, 174, 181, 185, 189, 193, 200,
119, 204, 211, 218, 225, 232
} ;
static yyconst short int yy_def[248] =
static yyconst short int yy_def[237] =
{ 0,
232, 1, 232, 232, 232, 232, 232, 232, 233, 234,
234, 232, 235, 232, 232, 232, 232, 232, 232, 232,
232, 232, 232, 232, 232, 232, 232, 232, 232, 232,
236, 236, 236, 236, 232, 232, 232, 236, 236, 236,
236, 236, 236, 236, 236, 236, 236, 236, 236, 236,
236, 232, 232, 232, 232, 232, 232, 232, 233, 232,
233, 237, 232, 238, 232, 232, 232, 235, 232, 235,
232, 232, 232, 232, 232, 232, 232, 232, 239, 232,
232, 232, 232, 240, 232, 232, 232, 232, 232, 232,
236, 236, 236, 236, 232, 236, 236, 236, 236, 236,
223, 1, 223, 223, 223, 223, 223, 223, 224, 225,
225, 223, 226, 223, 223, 223, 223, 223, 223, 223,
223, 223, 223, 223, 223, 223, 223, 223, 223, 223,
227, 227, 227, 227, 223, 223, 223, 227, 227, 227,
227, 227, 227, 227, 227, 227, 227, 227, 227, 227,
227, 223, 223, 223, 223, 223, 223, 223, 224, 223,
224, 228, 223, 229, 223, 223, 223, 226, 223, 226,
223, 223, 223, 223, 223, 223, 223, 223, 230, 223,
223, 223, 223, 231, 223, 223, 223, 223, 223, 223,
227, 227, 227, 227, 223, 227, 227, 227, 227, 227,
236, 236, 236, 236, 236, 236, 236, 236, 236, 236,
236, 236, 236, 236, 236, 236, 236, 232, 232, 232,
241, 238, 238, 232, 239, 242, 232, 232, 232, 240,
232, 232, 236, 236, 236, 236, 236, 236, 236, 236,
236, 236, 236, 236, 236, 236, 236, 236, 236, 236,
236, 236, 241, 241, 243, 244, 236, 236, 236, 236,
236, 236, 236, 236, 236, 236, 236, 236, 236, 236,
236, 236, 236, 243, 232, 243, 244, 244, 236, 236,
236, 236, 236, 236, 236, 236, 236, 236, 236, 236,
236, 236, 232, 243, 244, 236, 236, 236, 236, 236,
227, 227, 227, 227, 227, 227, 227, 227, 227, 227,
227, 227, 227, 227, 227, 227, 227, 223, 223, 223,
232, 229, 229, 223, 230, 233, 223, 223, 223, 231,
223, 223, 227, 227, 227, 227, 227, 227, 227, 227,
227, 227, 227, 227, 227, 227, 227, 227, 227, 227,
227, 227, 232, 232, 234, 223, 227, 227, 227, 227,
227, 227, 227, 227, 227, 227, 227, 227, 227, 227,
227, 227, 227, 234, 223, 227, 227, 227, 227, 227,
227, 227, 227, 227, 227, 227, 227, 227, 227, 223,
227, 227, 227, 227, 227, 227, 227, 227, 227, 227,
236, 236, 236, 236, 236, 236, 232, 245, 246, 236,
236, 236, 236, 236, 236, 236, 236, 232, 247, 243,
244, 244, 236, 236, 232, 236, 236, 236, 236, 236,
236, 0, 232, 232, 232, 232, 232, 232, 232, 232,
232, 232, 232, 232, 232, 232, 232
227, 235, 227, 227, 227, 227, 227, 227, 227, 227,
223, 236, 227, 227, 223, 227, 227, 227, 236, 227,
227, 227, 0, 223, 223, 223, 223, 223, 223, 223,
223, 223, 223, 223, 223, 223
} ;
static yyconst short int yy_nxt[449] =
static yyconst short int yy_nxt[406] =
{ 0,
4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
@ -453,44 +450,40 @@ static yyconst short int yy_nxt[449] =
89, 90, 104, 61, 100, 109, 70, 83, 101, 110,
99, 83, 118, 114, 84, 105, 60, 102, 62, 62,
106, 69, 130, 83, 115, 77, 77, 83, 127, 127,
81, 231, 82, 82, 128, 230, 128, 127, 127, 129,
129, 156, 156, 129, 129, 83, 129, 129, 175, 175,
83, 61, 70, 119, 175, 175, 125, 175, 175, 175,
175, 83, 229, 176, 175, 175, 83, 175, 175, 178,
175, 175, 176, 228, 193, 175, 175, 175, 175, 194,
221, 221, 178, 221, 221, 195, 175, 175, 175, 175,
208, 227, 209, 175, 175, 208, 226, 225, 209, 224,
81, 222, 82, 82, 128, 221, 128, 127, 127, 129,
129, 156, 156, 129, 129, 83, 129, 129, 156, 156,
83, 61, 70, 119, 156, 156, 125, 156, 156, 156,
156, 83, 156, 156, 156, 156, 83, 220, 218, 175,
59, 217, 59, 59, 59, 59, 59, 64, 216, 64,
64, 68, 215, 68, 68, 68, 68, 68, 91, 214,
213, 91, 121, 211, 210, 121, 122, 122, 209, 122,
223, 176, 219, 178, 218, 217, 216, 215, 178, 59,
214, 59, 59, 59, 59, 59, 64, 213, 64, 64,
68, 212, 68, 68, 68, 68, 68, 91, 211, 210,
91, 121, 207, 206, 121, 122, 122, 205, 122, 125,
204, 125, 125, 125, 125, 125, 153, 153, 203, 153,
155, 155, 155, 155, 155, 155, 155, 174, 174, 174,
174, 174, 174, 174, 177, 177, 177, 177, 177, 177,
177, 220, 220, 220, 220, 220, 220, 220, 222, 222,
222, 222, 222, 222, 222, 156, 156, 202, 156, 156,
156, 156, 201, 200, 199, 198, 197, 196, 192, 191,
125, 208, 125, 125, 125, 125, 125, 153, 153, 207,
153, 155, 155, 155, 155, 155, 155, 155, 174, 174,
174, 174, 174, 174, 174, 212, 212, 206, 212, 212,
212, 212, 219, 219, 219, 219, 219, 219, 219, 205,
204, 203, 202, 201, 200, 199, 198, 197, 196, 195,
194, 193, 192, 191, 190, 189, 188, 187, 186, 185,
184, 183, 182, 181, 180, 179, 178, 177, 176, 154,
154, 173, 172, 171, 170, 169, 168, 167, 166, 165,
164, 163, 162, 161, 160, 159, 158, 157, 123, 123,
154, 152, 151, 150, 149, 148, 147, 146, 145, 144,
190, 189, 188, 187, 186, 185, 184, 183, 182, 181,
180, 179, 154, 154, 173, 172, 171, 170, 169, 168,
167, 166, 165, 164, 163, 162, 161, 160, 159, 158,
157, 123, 123, 154, 152, 151, 150, 149, 148, 147,
146, 145, 144, 143, 142, 141, 140, 139, 138, 137,
136, 135, 134, 133, 132, 131, 126, 124, 68, 123,
59, 120, 56, 117, 116, 113, 112, 111, 103, 97,
96, 95, 94, 93, 92, 88, 85, 71, 56, 232,
3, 232, 232, 232, 232, 232, 232, 232, 232, 232,
232, 232, 232, 232, 232, 232, 232, 232, 232, 232,
143, 142, 141, 140, 139, 138, 137, 136, 135, 134,
133, 132, 131, 126, 124, 68, 123, 59, 120, 56,
117, 116, 113, 112, 111, 103, 97, 96, 95, 94,
93, 92, 88, 85, 71, 56, 223, 3, 223, 223,
223, 223, 223, 223, 223, 223, 223, 223, 223, 223,
223, 223, 223, 223, 223, 223, 223, 223, 223, 223,
223, 223, 223, 223, 223, 223, 223, 223, 223, 223,
223, 223, 223, 223, 223, 223, 223, 223, 223, 223,
223, 223, 223, 223, 223, 223, 223, 223, 223, 223,
223, 223, 223, 223, 223, 223, 223, 223, 223, 223,
232, 232, 232, 232, 232, 232, 232, 232, 232, 232,
232, 232, 232, 232, 232, 232, 232, 232, 232, 232,
232, 232, 232, 232, 232, 232, 232, 232, 232, 232,
232, 232, 232, 232, 232, 232, 232, 232, 232, 232,
232, 232, 232, 232, 232, 232, 232, 232
223, 223, 223, 223, 223
} ;
static yyconst short int yy_chk[449] =
static yyconst short int yy_chk[406] =
{ 0,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
@ -505,42 +498,38 @@ static yyconst short int yy_chk[449] =
28, 28, 43, 9, 41, 45, 13, 22, 41, 45,
40, 23, 53, 49, 22, 43, 59, 41, 62, 62,
43, 68, 240, 22, 49, 77, 77, 23, 81, 81,
82, 228, 82, 82, 83, 227, 83, 127, 127, 83,
43, 68, 231, 22, 49, 77, 77, 23, 81, 81,
82, 218, 82, 82, 83, 217, 83, 127, 127, 83,
83, 126, 126, 128, 128, 82, 129, 129, 155, 155,
127, 59, 68, 53, 156, 156, 126, 174, 174, 175,
175, 82, 224, 155, 176, 176, 127, 177, 177, 156,
178, 178, 174, 217, 175, 194, 194, 195, 195, 176,
208, 208, 177, 209, 209, 178, 220, 220, 221, 221,
194, 215, 195, 222, 222, 208, 214, 213, 209, 211,
127, 59, 68, 53, 156, 156, 126, 174, 174, 202,
202, 82, 212, 212, 219, 219, 127, 214, 210, 156,
224, 208, 224, 224, 224, 224, 224, 225, 207, 225,
225, 226, 206, 226, 226, 226, 226, 226, 227, 204,
203, 227, 228, 201, 200, 228, 229, 229, 198, 229,
210, 220, 207, 221, 206, 205, 203, 202, 222, 233,
201, 233, 233, 233, 233, 233, 234, 200, 234, 234,
235, 199, 235, 235, 235, 235, 235, 236, 198, 197,
236, 237, 193, 191, 237, 238, 238, 190, 238, 239,
189, 239, 239, 239, 239, 239, 241, 241, 188, 241,
242, 242, 242, 242, 242, 242, 242, 243, 243, 243,
243, 243, 243, 243, 244, 244, 244, 244, 244, 244,
244, 245, 245, 245, 245, 245, 245, 245, 246, 246,
246, 246, 246, 246, 246, 247, 247, 187, 247, 247,
247, 247, 186, 185, 183, 182, 181, 179, 173, 171,
230, 197, 230, 230, 230, 230, 230, 232, 232, 196,
232, 233, 233, 233, 233, 233, 233, 233, 234, 234,
234, 234, 234, 234, 234, 235, 235, 195, 235, 235,
235, 235, 236, 236, 236, 236, 236, 236, 236, 194,
193, 192, 190, 188, 187, 186, 185, 184, 183, 182,
180, 179, 178, 176, 175, 173, 171, 170, 169, 168,
167, 166, 165, 164, 162, 161, 160, 158, 157, 154,
153, 152, 151, 150, 149, 148, 147, 145, 144, 143,
142, 141, 140, 139, 138, 137, 136, 135, 123, 122,
121, 117, 116, 115, 114, 113, 112, 110, 109, 106,
170, 169, 168, 167, 166, 165, 164, 162, 161, 160,
158, 157, 154, 153, 152, 151, 150, 149, 148, 147,
145, 144, 143, 142, 141, 140, 139, 138, 137, 136,
135, 123, 122, 121, 117, 116, 115, 114, 113, 112,
110, 109, 106, 105, 104, 103, 101, 100, 99, 98,
97, 96, 94, 93, 90, 86, 79, 74, 70, 64,
61, 57, 56, 51, 50, 48, 47, 46, 42, 39,
38, 37, 34, 33, 32, 27, 24, 16, 5, 3,
232, 232, 232, 232, 232, 232, 232, 232, 232, 232,
232, 232, 232, 232, 232, 232, 232, 232, 232, 232,
105, 104, 103, 101, 100, 99, 98, 97, 96, 94,
93, 90, 86, 79, 74, 70, 64, 61, 57, 56,
51, 50, 48, 47, 46, 42, 39, 38, 37, 34,
33, 32, 27, 24, 16, 5, 3, 223, 223, 223,
223, 223, 223, 223, 223, 223, 223, 223, 223, 223,
223, 223, 223, 223, 223, 223, 223, 223, 223, 223,
223, 223, 223, 223, 223, 223, 223, 223, 223, 223,
223, 223, 223, 223, 223, 223, 223, 223, 223, 223,
223, 223, 223, 223, 223, 223, 223, 223, 223, 223,
223, 223, 223, 223, 223, 223, 223, 223, 223, 223,
232, 232, 232, 232, 232, 232, 232, 232, 232, 232,
232, 232, 232, 232, 232, 232, 232, 232, 232, 232,
232, 232, 232, 232, 232, 232, 232, 232, 232, 232,
232, 232, 232, 232, 232, 232, 232, 232, 232, 232,
232, 232, 232, 232, 232, 232, 232, 232
223, 223, 223, 223, 223
} ;
static yy_state_type yy_last_accepting_state;
@ -642,7 +631,7 @@ void CMDerror(char * s, ...);
// Reset the parser.
void CMDrestart(FILE *in);
#line 646 "CMDscan.cpp"
#line 635 "CMDscan.cpp"
/* Macros after this point can all be overridden by user definitions in
* section 1.
@ -792,7 +781,7 @@ YY_DECL
#line 105 "CMDscan.l"
;
#line 796 "CMDscan.cpp"
#line 785 "CMDscan.cpp"
if ( yy_init )
{
@ -843,13 +832,13 @@ yy_match:
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
{
yy_current_state = (int) yy_def[yy_current_state];
if ( yy_current_state >= 233 )
if ( yy_current_state >= 224 )
yy_c = yy_meta[(unsigned int) yy_c];
}
yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
++yy_cp;
}
while ( yy_base[yy_current_state] != 381 );
while ( yy_base[yy_current_state] != 338 );
yy_find_action:
yy_act = yy_accept[yy_current_state];
@ -1298,7 +1287,7 @@ YY_RULE_SETUP
#line 222 "CMDscan.l"
ECHO;
YY_BREAK
#line 1302 "CMDscan.cpp"
#line 1291 "CMDscan.cpp"
case YY_STATE_EOF(INITIAL):
yyterminate();
@ -1587,7 +1576,7 @@ static yy_state_type yy_get_previous_state()
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
{
yy_current_state = (int) yy_def[yy_current_state];
if ( yy_current_state >= 233 )
if ( yy_current_state >= 224 )
yy_c = yy_meta[(unsigned int) yy_c];
}
yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
@ -1622,11 +1611,11 @@ yy_state_type yy_current_state;
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
{
yy_current_state = (int) yy_def[yy_current_state];
if ( yy_current_state >= 233 )
if ( yy_current_state >= 224 )
yy_c = yy_meta[(unsigned int) yy_c];
}
yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
yy_is_jam = (yy_current_state == 232);
yy_is_jam = (yy_current_state == 223);
return yy_is_jam ? 0 : yy_current_state;
}
@ -2190,6 +2179,7 @@ void CMDerror(char *format, ...)
#else
vsnprintf( tempBuf, BUFMAX, format, args );
#endif
va_end(args);
if(fileName)
{

View file

@ -105,7 +105,7 @@ HEXDIGIT [a-fA-F0-9]
%%
;
{SPACE}+ { }
("///"[^/][^\n\r]*[\n\r]*)+ { return(Sc_ScanDocBlock()); }
("///"([^/\n\r][^\n\r]*)?[\n\r]+)+ { return(Sc_ScanDocBlock()); }
"//"[^\n\r]* ;
[\r] ;
[\n] {lineIndex++;}
@ -250,6 +250,7 @@ void CMDerror(char *format, ...)
#else
vsnprintf( tempBuf, BUFMAX, format, args );
#endif
va_end(args);
if(fileName)
{

View file

@ -103,9 +103,7 @@ S32 QSORT_CALLBACK ArrayObject::_keyFunctionCompare( const void* a, const void*
ArrayObject::Element* ea = ( ArrayObject::Element* )( a );
ArrayObject::Element* eb = ( ArrayObject::Element* )( b );
ConsoleValueRef argv[] = { smCompareFunction, ea->key, eb->key };
S32 result = dAtoi( Con::execute( 3, argv ) );
S32 result = dAtoi(Con::executef((const char*)smCompareFunction, ea->key, eb->key));
S32 res = result < 0 ? -1 : ( result > 0 ? 1 : 0 );
return ( smDecreasing ? -res : res );
}
@ -115,9 +113,7 @@ S32 QSORT_CALLBACK ArrayObject::_valueFunctionCompare( const void* a, const void
ArrayObject::Element* ea = ( ArrayObject::Element* )( a );
ArrayObject::Element* eb = ( ArrayObject::Element* )( b );
ConsoleValueRef argv[] = { smCompareFunction, ea->value, eb->value };
S32 result = dAtoi( Con::execute( 3, argv ) );
S32 result = dAtoi( Con::executef( (const char*)smCompareFunction, ea->value, eb->value ) );
S32 res = result < 0 ? -1 : ( result > 0 ? 1 : 0 );
return ( smDecreasing ? -res : res );
}

View file

@ -258,7 +258,6 @@ void IfStmtNode::propagateSwitchExpr(ExprNode *left, bool string)
U32 IfStmtNode::compileStmt(CodeStream &codeStream, U32 ip)
{
U32 start = ip;
U32 endifIp, elseIp;
addBreakLine(codeStream);
@ -340,7 +339,6 @@ U32 LoopStmtNode::compileStmt(CodeStream &codeStream, U32 ip)
addBreakLine(codeStream);
codeStream.pushFixScope(true);
U32 start = ip;
if(initExpr)
ip = initExpr->compile(codeStream, ip, TypeReqNone);
@ -1565,8 +1563,6 @@ U32 FunctionDeclStmtNode::compileStmt(CodeStream &codeStream, U32 ip)
CodeBlock::smInFunction = false;
U32 start = ip;
codeStream.emit(OP_FUNC_DECL);
codeStream.emitSTE(fnName);
codeStream.emitSTE(nameSpace);

View file

@ -570,7 +570,7 @@ bool CodeBlock::compile(const char *codeFileName, StringTableEntry fileName, con
}
const char *CodeBlock::compileExec(StringTableEntry fileName, const char *inString, bool noCalls, S32 setFrame)
ConsoleValueRef CodeBlock::compileExec(StringTableEntry fileName, const char *inString, bool noCalls, S32 setFrame)
{
AssertFatal(Con::isMainThread(), "Compiling code on a secondary thread");
@ -635,7 +635,7 @@ const char *CodeBlock::compileExec(StringTableEntry fileName, const char *inStri
if(!gStatementList)
{
delete this;
return "";
return ConsoleValueRef();
}
resetTables();

View file

@ -129,7 +129,7 @@ public:
/// with, zero being the top of the stack. If the the index is
/// -1 a new frame is created. If the index is out of range the
/// top stack frame is used.
const char *compileExec(StringTableEntry fileName, const char *script,
ConsoleValueRef compileExec(StringTableEntry fileName, const char *script,
bool noCalls, S32 setFrame = -1 );
/// Executes the existing code in the CodeBlock. The return string is any

View file

@ -87,7 +87,7 @@ struct IterStackRecord
struct StringPos
{
/// The raw string data on the string stack.
const char* mString;
StringStackPtr mString;
/// Current parsing position.
U32 mIndex;
@ -195,18 +195,27 @@ namespace Con
return STR.getArgBuffer(bufferSize);
}
ConsoleValueRef getFloatArg(F64 arg)
char *getFloatArg(F64 arg)
{
ConsoleValueRef ref = arg;
return ref;
char *ret = STR.getArgBuffer(32);
dSprintf(ret, 32, "%g", arg);
return ret;
}
ConsoleValueRef getIntArg(S32 arg)
char *getIntArg(S32 arg)
{
ConsoleValueRef ref = arg;
return ref;
char *ret = STR.getArgBuffer(32);
dSprintf(ret, 32, "%d", arg);
return ret;
}
char* getBoolArg(bool arg)
{
char *ret = STR.getArgBuffer(32);
dSprintf(ret, 32, "%d", arg);
return ret;
}
char *getStringArg( const char *arg )
{
U32 len = dStrlen( arg ) + 1;
@ -286,6 +295,12 @@ inline void ExprEvalState::setStringVariable(const char *val)
currentVariable->setStringValue(val);
}
inline void ExprEvalState::setStringStackPtrVariable(StringStackPtr str)
{
AssertFatal(currentVariable != NULL, "Invalid evaluator state - trying to set null variable!");
currentVariable->setStringStackPtrValue(str);
}
inline void ExprEvalState::setCopyVariable()
{
if (copyVariable)
@ -427,11 +442,14 @@ static void setFieldComponent( SimObject* object, StringTableEntry field, const
ConsoleValueRef CodeBlock::exec(U32 ip, const char *functionName, Namespace *thisNamespace, U32 argc, ConsoleValueRef *argv, bool noCalls, StringTableEntry packageName, S32 setFrame)
{
#ifdef TORQUE_DEBUG
#ifdef TORQUE_VALIDATE_STACK
U32 stackStart = STR.mStartStackSize;
U32 consoleStackStart = CSTK.mStackPos;
#endif
//Con::printf("CodeBlock::exec(%s,%u)", functionName ? functionName : "??", ip);
static char traceBuffer[1024];
S32 i;
@ -441,7 +459,7 @@ ConsoleValueRef CodeBlock::exec(U32 ip, const char *functionName, Namespace *thi
F64 *curFloatTable;
char *curStringTable;
S32 curStringTableLen = 0; //clint to ensure we dont overwrite it
STR.clearFunctionOffset();
STR.clearFunctionOffset(); // ensures arg buffer offset is back to 0
StringTableEntry thisFunctionName = NULL;
bool popFrame = false;
if(argv)
@ -489,15 +507,25 @@ ConsoleValueRef CodeBlock::exec(U32 ip, const char *functionName, Namespace *thi
ConsoleValueRef ref = argv[i+1];
if (argv[i+1].isString())
gEvalState.setStringVariable(argv[i+1]);
else if (argv[i+1].isInt())
switch(argv[i+1].getType())
{
case ConsoleValue::TypeInternalInt:
gEvalState.setIntVariable(argv[i+1]);
else if (argv[i+1].isFloat())
break;
case ConsoleValue::TypeInternalFloat:
gEvalState.setFloatVariable(argv[i+1]);
else
break;
case ConsoleValue::TypeInternalStringStackPtr:
gEvalState.setStringStackPtrVariable(argv[i+1].getStringStackPtrValue());
break;
case ConsoleValue::TypeInternalStackString:
case ConsoleValue::TypeInternalString:
default:
gEvalState.setStringVariable(argv[i+1]);
break;
}
}
ip = ip + (fnArgc * 2) + (2 + 6 + 1);
curFloatTable = functionFloats;
curStringTable = functionStrings;
@ -533,17 +561,6 @@ ConsoleValueRef CodeBlock::exec(U32 ip, const char *functionName, Namespace *thi
}
}
bool doResetValueStack = !gEvalState.mResetLocked;
gEvalState.mResetLocked = true;
if (gEvalState.mShouldReset)
{
// Ensure all stacks are clean in case anything became unbalanced during the previous execution
STR.clearFrames();
CSTK.clearFrames();
gEvalState.mShouldReset = false;
}
// Grab the state of the telenet debugger here once
// so that the push and pop frames are always balanced.
const bool telDebuggerOn = TelDebugger && TelDebugger->isConnected();
@ -590,7 +607,7 @@ ConsoleValueRef CodeBlock::exec(U32 ip, const char *functionName, Namespace *thi
Con::gCurrentRoot = this->modPath;
}
const char * val;
const char *retValue;
StringStackPtr retValue;
// note: anything returned is pushed to CSTK and will be invalidated on the next exec()
ConsoleValueRef returnValue;
@ -1144,7 +1161,7 @@ breakContinue:
// We're falling thru here on purpose.
case OP_RETURN:
retValue = STR.getStringValue();
retValue = STR.getStringValuePtr();
if( iterDepth > 0 )
{
@ -1156,13 +1173,13 @@ breakContinue:
}
STR.rewind();
STR.setStringValue( retValue ); // Not nice but works.
retValue = STR.getStringValue();
STR.setStringValue( StringStackPtrRef(retValue).getPtr(&STR) ); // Not nice but works.
retValue = STR.getStringValuePtr();
}
// Previously the return value was on the stack and would be returned using STR.getStringValue().
// Now though we need to wrap it in a ConsoleValueRef
returnValue.value = CSTK.pushStackString(retValue);
returnValue.value = CSTK.pushStringStackPtr(retValue);
goto execFinished;
@ -1847,7 +1864,7 @@ breakContinue:
// This will clear everything including returnValue
CSTK.popFrame();
STR.clearFunctionOffset();
//STR.clearFunctionOffset();
}
else
{
@ -1999,7 +2016,7 @@ breakContinue:
break;
case OP_PUSH:
STR.push();
CSTK.pushString(STR.getPreviousStringValue());
CSTK.pushStringStackPtr(STR.getPreviousStringValuePtr());
break;
case OP_PUSH_UINT:
CSTK.pushUINT(intStack[_UINT]);
@ -2080,7 +2097,7 @@ breakContinue:
if( iter.mIsStringIter )
{
iter.mData.mStr.mString = STR.getStringValue();
iter.mData.mStr.mString = STR.getStringValuePtr();
iter.mData.mStr.mIndex = 0;
}
else
@ -2118,7 +2135,7 @@ breakContinue:
if( iter.mIsStringIter )
{
const char* str = iter.mData.mStr.mString;
const char* str = StringStackPtrRef(iter.mData.mStr.mString).getPtr(&STR);
U32 startIndex = iter.mData.mStr.mIndex;
U32 endIndex = startIndex;
@ -2234,16 +2251,9 @@ execFinished:
Con::gCurrentRoot = saveCodeBlock->modPath;
}
// Mark the reset flag for the next run if we've finished execution
if (doResetValueStack)
{
gEvalState.mShouldReset = true;
gEvalState.mResetLocked = false;
}
decRefCount();
#ifdef TORQUE_DEBUG
#ifdef TORQUE_VALIDATE_STACK
AssertFatal(!(STR.mStartStackSize > stackStart), "String stack not popped enough in script exec");
AssertFatal(!(STR.mStartStackSize < stackStart), "String stack popped too much in script exec");
#endif

View file

@ -310,7 +310,7 @@ protected:
U8 *data; ///< Allocated data (size is BlockSize)
U32 size; ///< Bytes used in data
CodeData *next; ///< Next block
};
} CodeData;
/// @name Emitted code
/// {

File diff suppressed because it is too large Load diff

View file

@ -44,6 +44,8 @@ struct ConsoleFunctionHeader;
class EngineEnumTable;
typedef EngineEnumTable EnumTable;
typedef U32 StringStackPtr;
template< typename T > S32 TYPEID();
@ -121,8 +123,9 @@ public:
enum
{
TypeInternalInt = -4,
TypeInternalFloat = -3,
TypeInternalInt = -5,
TypeInternalFloat = -4,
TypeInternalStringStackPtr = -3,
TypeInternalStackString = -2,
TypeInternalString = -1,
};
@ -166,6 +169,7 @@ public:
S32 getSignedIntValue();
F32 getFloatValue();
const char *getStringValue();
StringStackPtr getStringStackPtr();
bool getBoolValue();
void setIntValue(U32 val);
@ -173,6 +177,7 @@ public:
void setFloatValue(F32 val);
void setStringValue(const char *value);
void setStackStringValue(const char *value);
void setStringStackPtrValue(StringStackPtr ptr);
void setBoolValue(bool val);
void init()
@ -181,19 +186,23 @@ public:
fval = 0;
sval = typeValueEmpty;
bufferLen = 0;
type = TypeInternalString;
}
void cleanup()
{
if (type <= TypeInternalString &&
sval != typeValueEmpty && type != TypeInternalStackString )
if ((type <= TypeInternalString) && (bufferLen > 0))
{
dFree(sval);
bufferLen = 0;
}
sval = typeValueEmpty;
type = ConsoleValue::TypeInternalString;
ival = 0;
fval = 0;
bufferLen = 0;
}
ConsoleValue(){ init(); };
~ConsoleValue(){ cleanup(); };
};
// Proxy class for console variables
@ -203,21 +212,16 @@ class ConsoleValueRef
{
public:
ConsoleValue *value;
const char *stringStackValue;
ConsoleValueRef() : value(0), stringStackValue(0) { ; }
ConsoleValueRef() : value(0) { ; }
~ConsoleValueRef() { ; }
ConsoleValueRef(const ConsoleValueRef &ref);
ConsoleValueRef(const char *value);
ConsoleValueRef(const String &ref);
ConsoleValueRef(U32 value);
ConsoleValueRef(S32 value);
ConsoleValueRef(F32 value);
ConsoleValueRef(F64 value);
static ConsoleValueRef fromValue(ConsoleValue *value) { ConsoleValueRef ref; ref.value = value; return ref; }
const char *getStringValue() { return value ? value->getStringValue() : ""; }
const char *getStringArgValue();
StringStackPtr getStringStackPtrValue() { return value ? value->getStringStackPtr() : 0; }
inline U32 getIntValue() { return value ? value->getIntValue() : 0; }
inline S32 getSignedIntValue() { return value ? value->getSignedIntValue() : 0; }
@ -229,10 +233,13 @@ public:
inline operator U32() { return getIntValue(); }
inline operator S32() { return getSignedIntValue(); }
inline operator F32() { return getFloatValue(); }
inline bool isString() { return value ? value->type >= ConsoleValue::TypeInternalStackString : true; }
inline operator bool() { return getBoolValue(); }
inline bool isStringStackPtr() { return value ? value->type == ConsoleValue::TypeInternalStringStackPtr : false; }
inline bool isString() { return value ? value->type >= ConsoleValue::TypeInternalStringStackPtr : true; }
inline bool isInt() { return value ? value->type == ConsoleValue::TypeInternalInt : false; }
inline bool isFloat() { return value ? value->type == ConsoleValue::TypeInternalFloat : false; }
inline S32 getType() { return value ? value->type : -1; }
// Note: operators replace value
ConsoleValueRef& operator=(const ConsoleValueRef &other);
@ -281,6 +288,7 @@ public:
class StringStackConsoleWrapper
{
public:
ConsoleValue *argvValue;
ConsoleValueRef *argv;
int argc;
@ -478,6 +486,20 @@ namespace Con
bool expandToolScriptFilename(char *filename, U32 size, const char *src);
bool collapseScriptFilename(char *filename, U32 size, const char *src);
bool expandPath(char* pDstPath, U32 size, const char* pSrcPath, const char* pWorkingDirectoryHint = NULL, const bool ensureTrailingSlash = false);
void collapsePath(char* pDstPath, U32 size, const char* pSrcPath, const char* pWorkingDirectoryHint = NULL);
bool isBasePath(const char* SrcPath, const char* pBasePath);
void ensureTrailingSlash(char* pDstPath, const char* pSrcPath);
bool stripRepeatSlashes(char* pDstPath, const char* pSrcPath, S32 dstSize);
void addPathExpando(const char* pExpandoName, const char* pPath);
void removePathExpando(const char* pExpandoName);
bool isPathExpando(const char* pExpandoName);
StringTableEntry getPathExpando(const char* pExpandoName);
U32 getPathExpandoCount(void);
StringTableEntry getPathExpandoKey(U32 expandoIndex);
StringTableEntry getPathExpandoValue(U32 expandoIndex);
bool isCurrentScriptToolScript();
StringTableEntry getModNameFromPath(const char *path);
@ -731,6 +753,13 @@ namespace Con
/// @see Con::errorf()
void errorf(ConsoleLogEntry::Type type, const char *_format, ...);
//some additions from t2d
/// Prints a separator to the console.
inline void printSeparator(void) { printf("--------------------------------------------------------------------------------"); }
/// Prints a separator to the console.
inline void printBlankLine(void) { printf(""); }
/// @}
/// Returns true when called from the main thread, false otherwise
@ -753,23 +782,9 @@ namespace Con
/// char* argv[] = {"abs", "-9"};
/// char* result = execute(2, argv);
/// @endcode
const char *execute(S32 argc, const char* argv[]);
const char *execute(S32 argc, ConsoleValueRef argv[]);
/// @see execute(S32 argc, const char* argv[])
// Note: this can't be ConsoleValueRef& since the compiler will confuse it with SimObject*
#define ARG ConsoleValueRef
const char *executef( ARG);
const char *executef( ARG, ARG);
const char *executef( ARG, ARG, ARG);
const char *executef( ARG, ARG, ARG, ARG);
const char *executef( ARG, ARG, ARG, ARG, ARG);
const char *executef( ARG, ARG, ARG, ARG, ARG, ARG);
const char *executef( ARG, ARG, ARG, ARG, ARG, ARG, ARG);
const char *executef( ARG, ARG, ARG, ARG, ARG, ARG, ARG, ARG);
const char *executef( ARG, ARG, ARG, ARG, ARG, ARG, ARG, ARG, ARG);
const char *executef( ARG, ARG, ARG, ARG, ARG, ARG, ARG, ARG, ARG, ARG);
#undef ARG
/// NOTE: this function restores the console stack on return.
ConsoleValueRef execute(S32 argc, const char* argv[]);
ConsoleValueRef execute(S32 argc, ConsoleValueRef argv[]);
/// Call a Torque Script member function of a SimObject from C/C++ code.
/// @param object Object on which to execute the method call.
@ -783,35 +798,23 @@ namespace Con
/// char* argv[] = {"setMode", "", "2"};
/// char* result = execute(mysimobject, 3, argv);
/// @endcode
const char *execute(SimObject *object, S32 argc, const char *argv[], bool thisCallOnly = false);
const char *execute(SimObject *object, S32 argc, ConsoleValueRef argv[], bool thisCallOnly = false);
/// @see execute(SimObject *, S32 argc, ConsoleValueRef argv[])
#define ARG ConsoleValueRef
const char *executef(SimObject *, ARG);
const char *executef(SimObject *, ARG, ARG);
const char *executef(SimObject *, ARG, ARG, ARG);
const char *executef(SimObject *, ARG, ARG, ARG, ARG);
const char *executef(SimObject *, ARG, ARG, ARG, ARG, ARG);
const char *executef(SimObject *, ARG, ARG, ARG, ARG, ARG, ARG);
const char *executef(SimObject *, ARG, ARG, ARG, ARG, ARG, ARG, ARG);
const char *executef(SimObject *, ARG, ARG, ARG, ARG, ARG, ARG, ARG, ARG);
const char *executef(SimObject *, ARG, ARG, ARG, ARG, ARG, ARG, ARG, ARG, ARG);
const char *executef(SimObject *, ARG, ARG, ARG, ARG, ARG, ARG, ARG, ARG, ARG, ARG);
const char *executef(SimObject *, ARG, ARG, ARG, ARG, ARG, ARG, ARG, ARG, ARG, ARG, ARG);
#undef ARG
/// NOTE: this function restores the console stack on return.
ConsoleValueRef execute(SimObject *object, S32 argc, const char* argv[], bool thisCallOnly = false);
ConsoleValueRef execute(SimObject *object, S32 argc, ConsoleValueRef argv[], bool thisCallOnly = false);
/// Evaluate an arbitrary chunk of code.
///
/// @param string Buffer containing code to execute.
/// @param echo Should we echo the string to the console?
/// @param fileName Indicate what file this code is coming from; used in error reporting and such.
const char *evaluate(const char* string, bool echo = false, const char *fileName = NULL);
/// NOTE: This function restores the console stack on return.
ConsoleValueRef evaluate(const char* string, bool echo = false, const char *fileName = NULL);
/// Evaluate an arbitrary line of script.
///
/// This wraps dVsprintf(), so you can substitute parameters into the code being executed.
const char *evaluatef(const char* string, ...);
/// NOTE: This function restores the console stack on return.
ConsoleValueRef evaluatef(const char* string, ...);
/// @}
@ -831,14 +834,13 @@ namespace Con
char* getReturnBuffer( const StringBuilder& str );
char* getArgBuffer(U32 bufferSize);
ConsoleValueRef getFloatArg(F64 arg);
ConsoleValueRef getIntArg (S32 arg);
char* getStringArg( const char *arg );
char* getFloatArg(F64 arg);
char* getIntArg (S32 arg);
char* getBoolArg(bool arg);
char* getStringArg( const char* arg );
char* getStringArg( const String& arg );
/// @}
void resetStackFrame();
/// @name Namespaces
/// @{
@ -872,21 +874,48 @@ namespace Con
/// @name Dynamic Type System
/// @{
///
/* void registerType( const char *typeName, S32 type, S32 size, GetDataFunction gdf, SetDataFunction sdf, bool isDatablockType = false );
void registerType( const char* typeName, S32 type, S32 size, bool isDatablockType = false );
void registerTypeGet( S32 type, GetDataFunction gdf );
void registerTypeSet( S32 type, SetDataFunction sdf );
const char *getTypeName(S32 type);
bool isDatablockType( S32 type ); */
void setData(S32 type, void *dptr, S32 index, S32 argc, const char **argv, const EnumTable *tbl = NULL, BitSet32 flag = 0);
const char *getData(S32 type, void *dptr, S32 index, const EnumTable *tbl = NULL, BitSet32 flag = 0);
const char *getFormattedData(S32 type, const char *data, const EnumTable *tbl = NULL, BitSet32 flag = 0);
/// @}
};
struct _EngineConsoleCallbackHelper;
template<typename P1> struct _EngineConsoleExecCallbackHelper;
namespace Con
{
/// @name Console Execution - executef
/// {
///
/// Implements a script function thunk which automatically converts parameters to relevant console types.
/// Can be used as follows:
/// - Con::executef("functionName", ...);
/// - Con::executef(mySimObject, "functionName", ...);
///
/// NOTE: if you get a rather cryptic template error coming through here, most likely you are trying to
/// convert a parameter which EngineMarshallType does not have a specialization for.
/// Another problem can occur if you do not include "console/simBase.h" and "console/engineAPI.h"
/// since _EngineConsoleExecCallbackHelper and SimConsoleThreadExecCallback are required.
///
/// @see _EngineConsoleExecCallbackHelper
///
template<typename A> ConsoleValueRef executef(A a) { _EngineConsoleExecCallbackHelper<A> callback( a ); return callback.template call<ConsoleValueRef>(); }
template<typename A, typename B> ConsoleValueRef executef(A a, B b) { _EngineConsoleExecCallbackHelper<A> callback( a ); return callback.template call<ConsoleValueRef>(b); }
template<typename A, typename B, typename C> ConsoleValueRef executef(A a, B b, C c) { _EngineConsoleExecCallbackHelper<A> callback( a ); return callback.template call<ConsoleValueRef>(b, c); }
template<typename A, typename B, typename C, typename D> ConsoleValueRef executef(A a, B b, C c, D d) { _EngineConsoleExecCallbackHelper<A> callback( a ); return callback.template call<ConsoleValueRef>(b, c, d); }
template<typename A, typename B, typename C, typename D, typename E> ConsoleValueRef executef(A a, B b, C c, D d, E e) { _EngineConsoleExecCallbackHelper<A> callback( a ); return callback.template call<ConsoleValueRef>(b, c, d, e); }
template<typename A, typename B, typename C, typename D, typename E, typename F> ConsoleValueRef executef(A a, B b, C c, D d, E e, F f) { _EngineConsoleExecCallbackHelper<A> callback( a ); return callback.template call<ConsoleValueRef>(b, c, d, e, f); }
template<typename A, typename B, typename C, typename D, typename E, typename F, typename G> ConsoleValueRef executef(A a, B b, C c, D d, E e, F f, G g) { _EngineConsoleExecCallbackHelper<A> callback( a ); return callback.template call<ConsoleValueRef>(b, c, d, e, f, g); }
template<typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H> ConsoleValueRef executef(A a, B b, C c, D d, E e, F f, G g, H h) { _EngineConsoleExecCallbackHelper<A> callback( a ); return callback.template call<ConsoleValueRef>(b, c, d, e, f, g, h); }
template<typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I> ConsoleValueRef executef(A a, B b, C c, D d, E e, F f, G g, H h, I i) { _EngineConsoleExecCallbackHelper<A> callback( a ); return callback.template call<ConsoleValueRef>(b, c, d, e, f, g, h, i); }
template<typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I, typename J> ConsoleValueRef executef(A a, B b, C c, D d, E e, F f, G g, H h, I i, J j) { _EngineConsoleExecCallbackHelper<A> callback( a ); return callback.template call<ConsoleValueRef>(b, c, d, e, f, g, h, i, j); }
template<typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I, typename J, typename K> ConsoleValueRef executef(A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k) { _EngineConsoleExecCallbackHelper<A> callback( a ); return callback.template call<ConsoleValueRef>(b, c, d, e, f, g, h, i, j, k); }
template<typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I, typename J, typename K, typename L> ConsoleValueRef executef(A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k, L l) { _EngineConsoleExecCallbackHelper<A> callback( a ); return callback.template call<ConsoleValueRef>(b, c, d, e, f, g, h, i, j, k, l); }
/// }
};
extern void expandEscape(char *dest, const char *src);
extern bool collapseEscape(char *buf);
extern U32 HashPointer(StringTableEntry ptr);
@ -1093,9 +1122,9 @@ struct ConsoleDocFragment
static ConsoleDocFragment* smFirst;
ConsoleDocFragment( const char* text, const char* inClass = NULL, const char* definition = NULL )
: mText( text ),
mClass( inClass ),
: mClass( inClass ),
mDefinition( definition ),
mText( text ),
mNext( smFirst )
{
smFirst = this;
@ -1103,6 +1132,28 @@ struct ConsoleDocFragment
};
/// Utility class to save and restore the current console stack frame
///
class ConsoleStackFrameSaver
{
public:
bool mSaved;
ConsoleStackFrameSaver() : mSaved(false)
{
}
~ConsoleStackFrameSaver()
{
restore();
}
void save();
void restore();
};
/// @name Global Console Definition Macros
///
/// @note If TORQUE_DEBUG is defined, then we gather documentation information, and

View file

@ -34,10 +34,6 @@
#include "core/util/journal/journal.h"
#include "core/util/uuid.h"
#ifdef TORQUE_DEMO_PURCHASE
#include "gui/core/guiCanvas.h"
#endif
// This is a temporary hack to get tools using the library to
// link in this module which contains no other references.
bool LinkConsoleFunctions = false;
@ -480,7 +476,7 @@ DefineConsoleFunction( strreplace, const char*, ( const char* source, const char
if(!scan)
{
dStrcpy(ret + dstp, source + scanp);
break;
return ret;
}
U32 len = scan - (source + scanp);
dStrncpy(ret + dstp, source + scanp, len);
@ -1598,6 +1594,7 @@ DefineEngineFunction( gotoWebPage, void, ( const char* address ),,
DefineEngineFunction( displaySplashWindow, bool, (const char* path), ("art/gui/splash.bmp"),
"Display a startup splash window suitable for showing while the engine still starts up.\n\n"
"@note This is currently only implemented on Windows.\n\n"
"@param path relative path to splash screen image to display.\n"
"@return True if the splash window could be successfully initialized.\n\n"
"@ingroup Platform" )
{
@ -2269,7 +2266,7 @@ DefineConsoleFunction( isDefined, bool, ( const char* varName, const char* varVa
"@endtsexample\n\n"
"@ingroup Scripting")
{
if(dStrIsEmpty(varName))
if(String::isEmpty(varName))
{
Con::errorf("isDefined() - did you forget to put quotes around the variable name?");
return false;
@ -2345,7 +2342,7 @@ DefineConsoleFunction( isDefined, bool, ( const char* varName, const char* varVa
{
if (dStrlen(value) > 0)
return true;
else if (!dStrIsEmpty(varValue))
else if (!String::isEmpty(varValue))
{
obj->setDataField(valName, 0, varValue);
}
@ -2362,7 +2359,7 @@ DefineConsoleFunction( isDefined, bool, ( const char* varName, const char* varVa
if (ent)
return true;
else if (!dStrIsEmpty(varValue))
else if (!String::isEmpty(varValue))
{
gEvalState.getCurrentFrame().setVariable(name, varValue);
}
@ -2377,7 +2374,7 @@ DefineConsoleFunction( isDefined, bool, ( const char* varName, const char* varVa
if (ent)
return true;
else if (!dStrIsEmpty(varValue))
else if (!String::isEmpty(varValue))
{
gEvalState.globalVars.setVariable(name, varValue);
}
@ -2387,7 +2384,7 @@ DefineConsoleFunction( isDefined, bool, ( const char* varName, const char* varVa
// Is it an object?
if (dStrcmp(varName, "0") && dStrcmp(varName, "") && (Sim::findObject(varName) != NULL))
return true;
else if (!dStrIsEmpty(varValue))
else if (!String::isEmpty(varValue))
{
Con::errorf("%s() - can't assign a value to a variable of the form \"%s\"", __FUNCTION__, varValue);
}

View file

@ -512,13 +512,17 @@ void ConsoleValue::setStringValue(const char * value)
*/
if (value == typeValueEmpty)
{
if (sval && sval != typeValueEmpty && type != TypeInternalStackString) dFree(sval);
sval = typeValueEmpty;
if (bufferLen > 0)
{
dFree(sval);
bufferLen = 0;
fval = 0.f;
ival = 0;
type = TypeInternalString;
return;
}
sval = typeValueEmpty;
fval = 0.f;
ival = 0;
type = TypeInternalString;
return;
}
U32 stringLen = dStrlen(value);
@ -541,7 +545,7 @@ void ConsoleValue::setStringValue(const char * value)
// may as well pad to the next cache line
U32 newLen = ((stringLen + 1) + 15) & ~15;
if(sval == typeValueEmpty || type == TypeInternalStackString)
if(bufferLen == 0)
sval = (char *) dMalloc(newLen);
else if(newLen > bufferLen)
sval = (char *) dRealloc(sval, newLen);
@ -556,17 +560,22 @@ void ConsoleValue::setStringValue(const char * value)
}
void ConsoleValue::setStackStringValue(const char * value)
void ConsoleValue::setStackStringValue(const char *value)
{
if (value == NULL) value = typeValueEmpty;
if(type <= ConsoleValue::TypeInternalString)
{
// sval might still be temporarily present so we need to check and free it
if (bufferLen > 0)
{
dFree(sval);
bufferLen = 0;
}
if (value == typeValueEmpty)
{
if (sval && sval != typeValueEmpty && type != ConsoleValue::TypeInternalStackString) dFree(sval);
sval = typeValueEmpty;
bufferLen = 0;
fval = 0.f;
ival = 0;
type = TypeInternalString;
@ -586,13 +595,46 @@ void ConsoleValue::setStackStringValue(const char * value)
}
type = TypeInternalStackString;
sval = (char*)value;
bufferLen = stringLen;
sval = (char*)value;
bufferLen = 0;
}
else
Con::setData(type, dataPtr, 0, 1, &value, enumTable);
}
void ConsoleValue::setStringStackPtrValue(StringStackPtr ptrValue)
{
if(type <= ConsoleValue::TypeInternalString)
{
const char *value = StringStackPtrRef(ptrValue).getPtr(&STR);
if (bufferLen > 0)
{
dFree(sval);
bufferLen = 0;
}
U32 stringLen = dStrlen(value);
if(stringLen < 256)
{
fval = dAtof(value);
ival = dAtoi(value);
}
else
{
fval = 0.f;
ival = 0;
}
type = TypeInternalStringStackPtr;
sval = (char*)(value - STR.mBuffer);
bufferLen = 0;
}
else
{
const char *value = StringStackPtrRef(ptrValue).getPtr(&STR);
Con::setData(type, dataPtr, 0, 1, &value, enumTable);
}
}
S32 Dictionary::getIntVariable(StringTableEntry name, bool *entValid)
{
@ -651,7 +693,7 @@ Dictionary::Entry* Dictionary::addVariable( const char *name,
Entry *ent = add(StringTable->insert(name));
if ( ent->value.type <= ConsoleValue::TypeInternalString &&
ent->value.sval != typeValueEmpty && ent->value.type != ConsoleValue::TypeInternalStackString )
ent->value.bufferLen > 0 )
dFree(ent->value.sval);
ent->value.type = type;
@ -1338,14 +1380,20 @@ void Namespace::markGroup(const char* name, const char* usage)
extern S32 executeBlock(StmtNode *block, ExprEvalState *state);
const char *Namespace::Entry::execute(S32 argc, ConsoleValueRef *argv, ExprEvalState *state)
ConsoleValueRef Namespace::Entry::execute(S32 argc, ConsoleValueRef *argv, ExprEvalState *state)
{
STR.clearFunctionOffset();
if(mType == ConsoleFunctionType)
{
if(mFunctionOffset)
{
return mCode->exec(mFunctionOffset, argv[0], mNamespace, argc, argv, false, mPackage);
}
else
return "";
{
return ConsoleValueRef();
}
}
#ifndef TORQUE_DEBUG
@ -1354,7 +1402,7 @@ const char *Namespace::Entry::execute(S32 argc, ConsoleValueRef *argv, ExprEvalS
if(mToolOnly && ! Con::isCurrentScriptToolScript())
{
Con::errorf(ConsoleLogEntry::Script, "%s::%s - attempting to call tools only function from outside of tools", mNamespace->mName, mFunctionName);
return "";
return ConsoleValueRef();
}
#endif
@ -1362,32 +1410,26 @@ const char *Namespace::Entry::execute(S32 argc, ConsoleValueRef *argv, ExprEvalS
{
Con::warnf(ConsoleLogEntry::Script, "%s::%s - wrong number of arguments.", mNamespace->mName, mFunctionName);
Con::warnf(ConsoleLogEntry::Script, "usage: %s", mUsage);
return "";
return ConsoleValueRef();
}
static char returnBuffer[32];
switch(mType)
{
case StringCallbackType:
return cb.mStringCallbackFunc(state->thisObject, argc, argv);
return ConsoleValueRef::fromValue(CSTK.pushStackString(cb.mStringCallbackFunc(state->thisObject, argc, argv)));
case IntCallbackType:
dSprintf(returnBuffer, sizeof(returnBuffer), "%d",
cb.mIntCallbackFunc(state->thisObject, argc, argv));
return returnBuffer;
return ConsoleValueRef::fromValue(CSTK.pushUINT((U32)cb.mBoolCallbackFunc(state->thisObject, argc, argv)));
case FloatCallbackType:
dSprintf(returnBuffer, sizeof(returnBuffer), "%g",
cb.mFloatCallbackFunc(state->thisObject, argc, argv));
return returnBuffer;
return ConsoleValueRef::fromValue(CSTK.pushFLT((U32)cb.mBoolCallbackFunc(state->thisObject, argc, argv)));
case VoidCallbackType:
cb.mVoidCallbackFunc(state->thisObject, argc, argv);
return "";
return ConsoleValueRef();
case BoolCallbackType:
dSprintf(returnBuffer, sizeof(returnBuffer), "%d",
(U32)cb.mBoolCallbackFunc(state->thisObject, argc, argv));
return returnBuffer;
return ConsoleValueRef::fromValue(CSTK.pushUINT((U32)cb.mBoolCallbackFunc(state->thisObject, argc, argv)));
}
return "";
return ConsoleValueRef();
}
//-----------------------------------------------------------------------------

View file

@ -151,7 +151,7 @@ class Namespace
void clear();
///
const char *execute( S32 argc, ConsoleValueRef* argv, ExprEvalState* state );
ConsoleValueRef execute( S32 argc, ConsoleValueRef* argv, ExprEvalState* state );
/// Return a one-line documentation text string for the function.
String getBriefDescription( String* outRemainingDocText = NULL ) const;
@ -367,6 +367,22 @@ public:
notify->trigger();
}
void setStringStackPtrValue(StringStackPtr newValue)
{
if( mIsConstant )
{
Con::errorf( "Cannot assign value to constant '%s'.", name );
return;
}
value.setStringStackPtrValue(newValue);
// Fire off the notification if we have one.
if ( notify )
notify->trigger();
}
void setStringValue(const char *newValue)
{
if( mIsConstant )
@ -495,6 +511,7 @@ public:
void setIntVariable(S32 val);
void setFloatVariable(F64 val);
void setStringVariable(const char *str);
void setStringStackPtrVariable(StringStackPtr str);
void setCopyVariable();
void pushFrame(StringTableEntry frameName, Namespace *ns);

View file

@ -55,7 +55,25 @@ bool AbstractClassRep::initialized = false;
//-----------------------------------------------------------------------------
AbstractClassRep* AbstractClassRep::findFieldRoot(StringTableEntry fieldName)
{
// Find the field.
const Field* pField = findField(fieldName);
// Finish if not found.
if (pField == NULL)
return NULL;
// We're the root if we have no parent.
if (getParentClass() == NULL)
return this;
// Find the field root via the parent.
AbstractClassRep* pFieldRoot = getParentClass()->findFieldRoot(fieldName);
// We're the root if the parent does not have it else return the field root.
return pFieldRoot == NULL ? this : pFieldRoot;
}
void AbstractClassRep::init()
{
@ -349,6 +367,7 @@ void ConsoleObject::addGroup(const char* in_pGroupname, const char* in_pGroupDoc
f.validator = NULL;
f.setDataFn = &defaultProtectedSetFn;
f.getDataFn = &defaultProtectedGetFn;
f.writeDataFn = &defaultProtectedWriteFn;
// Add to field list.
sg_tempFieldList.push_back(f);
@ -371,6 +390,7 @@ void ConsoleObject::endGroup(const char* in_pGroupname)
f.validator = NULL;
f.setDataFn = &defaultProtectedSetFn;
f.getDataFn = &defaultProtectedGetFn;
f.writeDataFn = &defaultProtectedWriteFn;
f.elementCount = 0;
// Add to field list.
@ -393,6 +413,7 @@ void ConsoleObject::addArray( const char *arrayName, S32 count )
f.validator = NULL;
f.setDataFn = &defaultProtectedSetFn;
f.getDataFn = &defaultProtectedGetFn;
f.writeDataFn = &defaultProtectedWriteFn;
// Add to field list.
sg_tempFieldList.push_back(f);
@ -412,6 +433,7 @@ void ConsoleObject::endArray( const char *arrayName )
f.validator = NULL;
f.setDataFn = &defaultProtectedSetFn;
f.getDataFn = &defaultProtectedGetFn;
f.writeDataFn = &defaultProtectedWriteFn;
f.elementCount = 0;
// Add to field list.
@ -433,13 +455,77 @@ void ConsoleObject::addField(const char* in_pFieldname,
flags );
}
void ConsoleObject::addField(const char* in_pFieldname,
const U32 in_fieldType,
const dsize_t in_fieldOffset,
AbstractClassRep::WriteDataNotify in_writeDataFn,
const char* in_pFieldDocs,
U32 flags)
{
addField(
in_pFieldname,
in_fieldType,
in_fieldOffset,
in_writeDataFn,
1,
in_pFieldDocs,
flags);
}
void ConsoleObject::addField(const char* in_pFieldname,
const U32 in_fieldType,
const dsize_t in_fieldOffset,
const U32 in_elementCount,
const char* in_pFieldDocs,
U32 flags)
{
addField(in_pFieldname,
in_fieldType,
in_fieldOffset,
&defaultProtectedWriteFn,
in_elementCount,
in_pFieldDocs,
flags);
}
void ConsoleObject::addField(const char* in_pFieldname,
const U32 in_fieldType,
const dsize_t in_fieldOffset,
AbstractClassRep::WriteDataNotify in_writeDataFn,
const U32 in_elementCount,
const char* in_pFieldDocs,
U32 flags)
{
AbstractClassRep::Field f;
f.pFieldname = StringTable->insert(in_pFieldname);
if (in_pFieldDocs)
f.pFieldDocs = in_pFieldDocs;
f.type = in_fieldType;
f.offset = in_fieldOffset;
f.elementCount = in_elementCount;
f.validator = NULL;
f.flag = flags;
f.setDataFn = &defaultProtectedSetFn;
f.getDataFn = &defaultProtectedGetFn;
f.writeDataFn = in_writeDataFn;
ConsoleBaseType* conType = ConsoleBaseType::getType(in_fieldType);
AssertFatal(conType, "ConsoleObject::addField - invalid console type");
f.table = conType->getEnumTable();
sg_tempFieldList.push_back(f);
}
void ConsoleObject::addProtectedField(const char* in_pFieldname,
const U32 in_fieldType,
const dsize_t in_fieldOffset,
AbstractClassRep::SetDataNotify in_setDataFn,
AbstractClassRep::GetDataNotify in_getDataFn,
const char* in_pFieldDocs,
U32 flags )
const U32 in_fieldType,
const dsize_t in_fieldOffset,
AbstractClassRep::SetDataNotify in_setDataFn,
AbstractClassRep::GetDataNotify in_getDataFn,
const char* in_pFieldDocs,
U32 flags)
{
addProtectedField(
in_pFieldname,
@ -447,67 +533,81 @@ void ConsoleObject::addProtectedField(const char* in_pFieldname,
in_fieldOffset,
in_setDataFn,
in_getDataFn,
&defaultProtectedWriteFn,
1,
in_pFieldDocs,
flags );
}
void ConsoleObject::addField(const char* in_pFieldname,
const U32 in_fieldType,
const dsize_t in_fieldOffset,
const U32 in_elementCount,
const char* in_pFieldDocs,
U32 flags )
{
AbstractClassRep::Field f;
f.pFieldname = StringTable->insert(in_pFieldname);
if(in_pFieldDocs)
f.pFieldDocs = in_pFieldDocs;
f.type = in_fieldType;
f.offset = in_fieldOffset;
f.elementCount = in_elementCount;
f.validator = NULL;
f.flag = flags;
f.setDataFn = &defaultProtectedSetFn;
f.getDataFn = &defaultProtectedGetFn;
ConsoleBaseType* conType = ConsoleBaseType::getType( in_fieldType );
AssertFatal( conType, "ConsoleObject::addField - invalid console type" );
f.table = conType->getEnumTable();
sg_tempFieldList.push_back(f);
flags);
}
void ConsoleObject::addProtectedField(const char* in_pFieldname,
const U32 in_fieldType,
const dsize_t in_fieldOffset,
AbstractClassRep::SetDataNotify in_setDataFn,
AbstractClassRep::GetDataNotify in_getDataFn,
const U32 in_elementCount,
const char* in_pFieldDocs,
U32 flags )
const U32 in_fieldType,
const dsize_t in_fieldOffset,
AbstractClassRep::SetDataNotify in_setDataFn,
AbstractClassRep::GetDataNotify in_getDataFn,
AbstractClassRep::WriteDataNotify in_writeDataFn,
const char* in_pFieldDocs,
U32 flags)
{
addProtectedField(
in_pFieldname,
in_fieldType,
in_fieldOffset,
in_setDataFn,
in_getDataFn,
in_writeDataFn,
1,
in_pFieldDocs,
flags);
}
void ConsoleObject::addProtectedField(const char* in_pFieldname,
const U32 in_fieldType,
const dsize_t in_fieldOffset,
AbstractClassRep::SetDataNotify in_setDataFn,
AbstractClassRep::GetDataNotify in_getDataFn,
const U32 in_elementCount,
const char* in_pFieldDocs,
U32 flags)
{
addProtectedField(
in_pFieldname,
in_fieldType,
in_fieldOffset,
in_setDataFn,
in_getDataFn,
&defaultProtectedWriteFn,
in_elementCount,
in_pFieldDocs,
flags);
}
void ConsoleObject::addProtectedField(const char* in_pFieldname,
const U32 in_fieldType,
const dsize_t in_fieldOffset,
AbstractClassRep::SetDataNotify in_setDataFn,
AbstractClassRep::GetDataNotify in_getDataFn,
AbstractClassRep::WriteDataNotify in_writeDataFn,
const U32 in_elementCount,
const char* in_pFieldDocs,
U32 flags)
{
AbstractClassRep::Field f;
f.pFieldname = StringTable->insert(in_pFieldname);
f.pFieldname = StringTable->insert(in_pFieldname);
if(in_pFieldDocs)
f.pFieldDocs = in_pFieldDocs;
if (in_pFieldDocs)
f.pFieldDocs = in_pFieldDocs;
f.type = in_fieldType;
f.offset = in_fieldOffset;
f.type = in_fieldType;
f.offset = in_fieldOffset;
f.elementCount = in_elementCount;
f.validator = NULL;
f.flag = flags;
f.validator = NULL;
f.flag = flags;
f.setDataFn = in_setDataFn;
f.getDataFn = in_getDataFn;
f.writeDataFn = in_writeDataFn;
ConsoleBaseType* conType = ConsoleBaseType::getType( in_fieldType );
AssertFatal( conType, "ConsoleObject::addProtectedField - invalid console type" );
ConsoleBaseType* conType = ConsoleBaseType::getType(in_fieldType);
AssertFatal(conType, "ConsoleObject::addProtectedField - invalid console type");
f.table = conType->getEnumTable();
sg_tempFieldList.push_back(f);
@ -529,6 +629,7 @@ void ConsoleObject::addFieldV(const char* in_pFieldname,
f.table = NULL;
f.setDataFn = &defaultProtectedSetFn;
f.getDataFn = &defaultProtectedGetFn;
f.writeDataFn = &defaultProtectedWriteFn;
f.validator = v;
v->fieldIndex = sg_tempFieldList.size();
@ -546,6 +647,7 @@ void ConsoleObject::addDeprecatedField(const char *fieldName)
f.validator = NULL;
f.setDataFn = &defaultProtectedSetFn;
f.getDataFn = &defaultProtectedGetFn;
f.writeDataFn = &defaultProtectedWriteFn;
sg_tempFieldList.push_back(f);
}
@ -847,12 +949,13 @@ DefineEngineFunction(linkNamespaces, bool, ( String childNSName, String parentNS
Namespace *childNS = Namespace::find(childNSSTE);
Namespace *parentNS = Namespace::find(parentNSSTE);
Namespace *currentParent = childNS->getParent();
if (!childNS)
{
return false;
}
Namespace *currentParent = childNS->getParent();
// Link to new NS if applicable

View file

@ -47,7 +47,9 @@
#ifndef _SIMOBJECTREF_H_
#include "console/simObjectRef.h"
#endif
#ifndef TINYXML_INCLUDED
#include "tinyxml.h"
#endif
/// @file
/// Legacy console object system.
@ -201,13 +203,16 @@ public:
typedef ConsoleBaseType Parent;
/// Allows the writing of a custom TAML schema.
typedef void(*WriteCustomTamlSchema)(const AbstractClassRep* pClassRep, TiXmlElement* pParentElement);
/// @name 'Tructors
/// @{
///
/// @param conIdPtr Pointer to the static S32 console ID.
/// @param conTypeName Console type name.
AbstractClassRep( S32* conIdPtr, const char* typeName )
AbstractClassRep( S32* conIdPtr, const char* typeName )
: Parent( sizeof( void* ), conIdPtr, typeName )
{
VECTOR_SET_ASSOCIATION( mFieldList );
@ -318,10 +323,13 @@ public:
/// Return the namespace that contains the methods of this class.
Namespace* getNameSpace() const { return mNamespace; }
/// Return the AbstractClassRep of the class that this class is derived from.
AbstractClassRep* getParentClass() const { return parentClass; }
virtual AbstractClassRep* getContainerChildClass(const bool recurse) = 0;
virtual WriteCustomTamlSchema getCustomTamlSchema(void) = 0;
/// Return the size of instances of this class in bytes.
S32 getSizeof() const { return mClassSizeof; }
@ -376,6 +384,8 @@ public:
virtual ConsoleObject* create () const = 0;
AbstractClassRep* findFieldRoot(StringTableEntry fieldName);
protected:
virtual void init();
@ -386,7 +396,7 @@ protected:
Namespace * mNamespace;
/// @}
public:
bool mIsRenderEnabled;
@ -394,23 +404,23 @@ public:
bool isRenderEnabled() const { return mIsRenderEnabled; }
bool isSelectionEnabled() const { return mIsSelectionEnabled; }
/// @name Categories
/// @{
protected:
const char* mCategory;
const char* mDescription;
public:
/// Return the space separated category path for the class.
const char* getCategory() const { return mCategory; }
/// Return a short description string suitable for displaying in tooltips.
const char* getDescription() const { return mDescription; }
/// @}
/// @name Fields
@ -421,12 +431,15 @@ public:
typedef bool (*SetDataNotify)( void *obj, const char *array, const char *data );
typedef const char *(*GetDataNotify)( void *obj, const char *data );
/// This is a function pointer typedef to support optional writing for fields.
typedef bool(*WriteDataNotify)(void* obj, StringTableEntry pFieldName);
/// These are special field type values used to mark
/// groups and arrays in the field list.
/// @see Field::type
/// @see addArray, endArray
/// @see addGroup, endGroup
/// @see addGroup, endGroup
/// @see addGroup, endGroup
/// @see addGroup, endGroup
/// @see addDeprecatedField
enum ACRFieldTypes
{
@ -434,35 +447,35 @@ public:
/// types greater or equal to this one are not
/// console data types.
ARCFirstCustomField = 0xFFFFFFFB,
/// Marks the start of a fixed size array of fields.
/// @see addArray
StartArrayFieldType = 0xFFFFFFFB,
/// Marks the end of a fixed size array of fields.
/// @see endArray
EndArrayFieldType = 0xFFFFFFFC,
/// Marks the beginning of a group of fields.
/// @see addGroup
StartGroupFieldType = 0xFFFFFFFD,
/// Marks the beginning of a group of fields.
/// @see endGroup
EndGroupFieldType = 0xFFFFFFFE,
/// Marks a field that is depreciated and no
/// Marks a field that is depreciated and no
/// longer stores a value.
/// @see addDeprecatedField
DeprecatedFieldType = 0xFFFFFFFF
};
enum FieldFlags
{
FIELD_HideInInspectors = BIT( 0 ), ///< Do not show the field in inspectors.
};
struct Field
struct Field
{
Field()
: pFieldname( NULL ),
@ -494,6 +507,7 @@ public:
TypeValidator *validator; ///< Validator, if any.
SetDataNotify setDataFn; ///< Set data notify Fn
GetDataNotify getDataFn; ///< Get data notify Fn
WriteDataNotify writeDataFn; ///< Function to determine whether data should be written or not.
};
typedef Vector<Field> FieldList;
@ -507,10 +521,10 @@ public:
/// @name Console Type Interface
/// @{
virtual void* getNativeVariable() { return new ( AbstractClassRep* ); } // Any pointer-sized allocation will do.
virtual void deleteNativeVariable( void* var ) { delete reinterpret_cast< AbstractClassRep** >( var ); }
/// @}
/// @name Abstract Class Database
@ -556,10 +570,10 @@ template< class T >
class ConcreteClassRep : public AbstractClassRep
{
public:
static EnginePropertyTable _smPropertyTable;
static EnginePropertyTable& smPropertyTable;
ConcreteClassRep( const char* name,
const char* conTypeName,
S32* conTypeIdPtr,
@ -573,10 +587,10 @@ class ConcreteClassRep : public AbstractClassRep
mClassName = StringTable->insert( name );
mCategory = T::__category();
mTypeInfo = _MAPTYPE< T >();
if( mTypeInfo )
const_cast< EngineTypeInfo* >( mTypeInfo )->mPropertyTable = &smPropertyTable;
if( &T::__description != parentDesc )
mDescription = T::__description();
@ -595,6 +609,27 @@ class ConcreteClassRep : public AbstractClassRep
registerClassRep(this);
};
virtual AbstractClassRep* getContainerChildClass(const bool recurse)
{
// Fetch container children type.
AbstractClassRep* pChildren = T::getContainerChildStaticClassRep();
if (!recurse || pChildren != NULL)
return pChildren;
// Fetch parent type.
AbstractClassRep* pParent = T::getParentStaticClassRep();
if (pParent == NULL)
return NULL;
// Get parent container children.
return pParent->getContainerChildClass(recurse);
}
virtual WriteCustomTamlSchema getCustomTamlSchema(void)
{
return T::getStaticWriteCustomTamlSchema();
}
/// Perform class specific initialization tasks.
///
/// Link namespaces, call initPersistFields() and consoleInit().
@ -603,7 +638,7 @@ class ConcreteClassRep : public AbstractClassRep
// Get handle to our parent class, if any, and ourselves (we are our parent's child).
AbstractClassRep *parent = T::getParentStaticClassRep();
AbstractClassRep *child = T::getStaticClassRep();
// If we got reps, then link those namespaces! (To get proper inheritance.)
if(parent && child)
Con::classLinkNamespaces(parent->getNameSpace(), child->getNameSpace());
@ -618,7 +653,7 @@ class ConcreteClassRep : public AbstractClassRep
/// Wrap constructor.
ConsoleObject* create() const { return new T; }
/// @name Console Type Interface
/// @{
@ -632,16 +667,16 @@ class ConcreteClassRep : public AbstractClassRep
else
Con::errorf( "Cannot set multiple args to a single ConsoleObject*.");
}
virtual const char* getData( void* dptr, const EnumTable* tbl, BitSet32 flag )
{
T** obj = ( T** ) dptr;
return Con::getReturnBuffer( T::__getObjectId( *obj ) );
}
virtual const char* getTypeClassName() { return mClassName; }
virtual const bool isDatablock() { return T::__smIsDatablock; };
/// @}
};
@ -652,7 +687,7 @@ template< typename T > EnginePropertyTable& ConcreteClassRep< T >::smPropertyTab
//------------------------------------------------------------------------------
// Forward declaration of this function so it can be used in the class
const char *defaultProtectedGetFn( void *obj, const char *data );
bool defaultProtectedWriteFn(void* obj, StringTableEntry pFieldName);
//=============================================================================
// ConsoleObject.
@ -712,7 +747,7 @@ const char *defaultProtectedGetFn( void *obj, const char *data );
class ConsoleObject : public EngineObject
{
DECLARE_ABSTRACT_CLASS( ConsoleObject, EngineObject );
protected:
/// @deprecated This is disallowed.
@ -721,7 +756,7 @@ protected:
public:
ConsoleObject() {}
/// Get a reference to a field by name.
const AbstractClassRep::Field *findField(StringTableEntry fieldName) const;
@ -730,7 +765,7 @@ public:
/// Set the value of a field.
bool setField(const char *fieldName, const char *value);
public:
/// @name Object Creation
@ -760,11 +795,11 @@ public:
static void endGroup(const char* in_pGroupname);
/// Marks the start of a fixed size array of fields.
/// @see console_autodoc
/// @see console_autodoc
static void addArray( const char *arrayName, S32 count );
/// Marks the end of an array of fields.
/// @see console_autodoc
/// @see console_autodoc
static void endArray( const char *arrayName );
/// Register a complex field.
@ -781,6 +816,14 @@ public:
const char* in_pFieldDocs = NULL,
U32 flags = 0 );
static void addField(const char* in_pFieldname,
const U32 in_fieldType,
const dsize_t in_fieldOffset,
AbstractClassRep::WriteDataNotify in_writeDataFn,
const U32 in_elementCount = 1,
const char* in_pFieldDocs = NULL,
U32 flags = 0);
/// Register a simple field.
///
/// @param in_pFieldname Name of the field.
@ -793,6 +836,13 @@ public:
const char* in_pFieldDocs,
U32 flags = 0 );
static void addField(const char* in_pFieldname,
const U32 in_fieldType,
const dsize_t in_fieldOffset,
AbstractClassRep::WriteDataNotify in_writeDataFn,
const char* in_pFieldDocs,
U32 flags = 0);
/// Register a validated field.
///
/// A validated field is just like a normal field except that you can't
@ -821,10 +871,20 @@ public:
const U32 in_fieldType,
const dsize_t in_fieldOffset,
AbstractClassRep::SetDataNotify in_setDataFn,
AbstractClassRep::GetDataNotify in_getDataFn,
const U32 in_elementCount,
const char* in_pFieldDocs = NULL,
U32 flags = 0 );
AbstractClassRep::GetDataNotify in_getDataFn = &defaultProtectedGetFn,
AbstractClassRep::WriteDataNotify in_writeDataFn = &defaultProtectedWriteFn,
const U32 in_elementCount = 1,
const char* in_pFieldDocs = NULL,
U32 flags = 0);
static void addProtectedField(const char* in_pFieldname,
const U32 in_fieldType,
const dsize_t in_fieldOffset,
AbstractClassRep::SetDataNotify in_setDataFn,
AbstractClassRep::GetDataNotify in_getDataFn = &defaultProtectedGetFn,
const U32 in_elementCount = 1,
const char* in_pFieldDocs = NULL,
U32 flags = 0);
/// Register a simple protected field.
///
@ -839,8 +899,17 @@ public:
const dsize_t in_fieldOffset,
AbstractClassRep::SetDataNotify in_setDataFn,
AbstractClassRep::GetDataNotify in_getDataFn = &defaultProtectedGetFn,
AbstractClassRep::WriteDataNotify in_writeDataFn = &defaultProtectedWriteFn,
const char* in_pFieldDocs = NULL,
U32 flags = 0 );
U32 flags = 0);
static void addProtectedField(const char* in_pFieldname,
const U32 in_fieldType,
const dsize_t in_fieldOffset,
AbstractClassRep::SetDataNotify in_setDataFn,
AbstractClassRep::GetDataNotify in_getDataFn = &defaultProtectedGetFn,
const char* in_pFieldDocs = NULL,
U32 flags = 0);
/// Add a deprecated field.
///
@ -855,16 +924,16 @@ public:
static bool removeField(const char* in_pFieldname);
/// @}
/// @name Logging
/// @{
/// Overload this in subclasses to change the message formatting.
/// @param fmt A printf style format string.
/// @param args A va_list containing the args passed ot a log function.
/// @note It is suggested that you use String::VToString.
virtual String _getLogMessage(const char* fmt, va_list args) const;
/// @}
public:
@ -873,16 +942,16 @@ public:
/// These functions will try to print out a message along the lines
/// of "ObjectClass - ObjectName(ObjectId) - formatted message"
/// @{
/// Logs with Con::printf.
void logMessage(const char* fmt, ...) const;
/// Logs with Con::warnf.
void logWarning(const char* fmt, ...) const;
/// Logs with Con::errorf.
void logError(const char* fmt, ...) const;
/// @}
/// Register dynamic fields in a subclass of ConsoleObject.
@ -943,16 +1012,16 @@ public:
static const char* __category() { return ""; }
static const char* __description() { return ""; }
/// Subclasses of ConsoleObjects that are datablocks should redefine this static member variable
/// and set it to true.
static const bool __smIsDatablock = false;
/// @name Object IDs and lookup.
/// For a subclass hierarchy based on ConsoleObject to become functional for use as a console object type,
/// the hierarchy must implement a naming scheme and indexing function for looking up objects by name.
/// @{
static ConsoleObject* __findObject( const char* ) { return NULL; }
static const char* __getObjectId( ConsoleObject* ) { return ""; }
};
@ -1045,11 +1114,13 @@ inline bool& ConsoleObject::getDynamicGroupExpand()
static AbstractClassRep* getParentStaticClassRep(); \
static AbstractClassRep* getStaticClassRep(); \
static SimObjectRefConsoleBaseType< className > ptrRefType; \
virtual AbstractClassRep* getClassRep() const
static AbstractClassRep::WriteCustomTamlSchema getStaticWriteCustomTamlSchema(); \
static AbstractClassRep* getContainerChildStaticClassRep(); \
virtual AbstractClassRep* getClassRep() const
#define DECLARE_CATEGORY( string ) \
static const char* __category() { return string; }
#define DECLARE_DESCRIPTION( string ) \
static const char* __description() { return string; }
@ -1061,6 +1132,44 @@ inline bool& ConsoleObject::getDynamicGroupExpand()
AbstractClassRep* className::getClassRep() const { return &className::dynClassRep; } \
AbstractClassRep* className::getStaticClassRep() { return &dynClassRep; } \
AbstractClassRep* className::getParentStaticClassRep() { return Parent::getStaticClassRep(); } \
AbstractClassRep* className::getContainerChildStaticClassRep() { return NULL; } \
AbstractClassRep::WriteCustomTamlSchema className::getStaticWriteCustomTamlSchema() { return NULL; } \
ConcreteClassRep<className> className::dynClassRep( #className, "Type" #className, &_smTypeId, 0, -1, 0, className::getParentStaticClassRep(), &Parent::__description )
#define IMPLEMENT_CONOBJECT_CHILDREN( className ) \
IMPLEMENT_CLASS( className, NULL ) \
END_IMPLEMENT_CLASS; \
S32 className::_smTypeId; \
SimObjectRefConsoleBaseType< className > className::ptrRefType( "Type" #className "Ref" ); \
AbstractClassRep* className::getClassRep() const { return &className::dynClassRep; } \
AbstractClassRep* className::getStaticClassRep() { return &dynClassRep; } \
AbstractClassRep* className::getParentStaticClassRep() { return Parent::getStaticClassRep(); } \
AbstractClassRep* className::getContainerChildStaticClassRep() { return Children::getStaticClassRep(); } \
AbstractClassRep::WriteCustomTamlSchema className::getStaticWriteCustomTamlSchema() { return NULL; } \
ConcreteClassRep<className> className::dynClassRep( #className, "Type" #className, &_smTypeId, 0, -1, 0, className::getParentStaticClassRep(), &Parent::__description )
#define IMPLEMENT_CONOBJECT_SCHEMA( className, schema ) \
IMPLEMENT_CLASS( className, NULL ) \
END_IMPLEMENT_CLASS; \
S32 className::_smTypeId; \
SimObjectRefConsoleBaseType< className > className::ptrRefType( "Type" #className "Ref" ); \
AbstractClassRep* className::getClassRep() const { return &className::dynClassRep; } \
AbstractClassRep* className::getStaticClassRep() { return &dynClassRep; } \
AbstractClassRep* className::getParentStaticClassRep() { return Parent::getStaticClassRep(); } \
AbstractClassRep* className::getContainerChildStaticClassRep() { return NULL; } \
AbstractClassRep::WriteCustomTamlSchema className::getStaticWriteCustomTamlSchema() { return schema; } \
ConcreteClassRep<className> className::dynClassRep( #className, "Type" #className, &_smTypeId, 0, -1, 0, className::getParentStaticClassRep(), &Parent::__description )
#define IMPLEMENT_CONOBJECT_CHILDREN_SCHEMA( className, schema ) \
IMPLEMENT_CLASS( className, NULL ) \
END_IMPLEMENT_CLASS; \
S32 className::_smTypeId; \
SimObjectRefConsoleBaseType< className > className::ptrRefType( "Type" #className "Ref" ); \
AbstractClassRep* className::getClassRep() const { return &className::dynClassRep; } \
AbstractClassRep* className::getStaticClassRep() { return &dynClassRep; } \
AbstractClassRep* className::getParentStaticClassRep() { return Parent::getStaticClassRep(); } \
AbstractClassRep* className::getContainerChildStaticClassRep() { return Children::getStaticClassRep(); } \
AbstractClassRep::WriteCustomTamlSchema className::getStaticWriteCustomTamlSchema() { return schema; } \
ConcreteClassRep<className> className::dynClassRep( #className, "Type" #className, &_smTypeId, 0, -1, 0, className::getParentStaticClassRep(), &Parent::__description )
#define IMPLEMENT_CO_NETOBJECT_V1( className ) \
@ -1071,6 +1180,8 @@ inline bool& ConsoleObject::getDynamicGroupExpand()
AbstractClassRep* className::getClassRep() const { return &className::dynClassRep; } \
AbstractClassRep* className::getStaticClassRep() { return &dynClassRep; } \
AbstractClassRep* className::getParentStaticClassRep() { return Parent::getStaticClassRep(); } \
AbstractClassRep* className::getContainerChildStaticClassRep() { return NULL; } \
AbstractClassRep::WriteCustomTamlSchema className::getStaticWriteCustomTamlSchema() { return NULL; } \
ConcreteClassRep<className> className::dynClassRep( #className, "Type" #className, &_smTypeId, NetClassGroupGameMask, NetClassTypeObject, 0, className::getParentStaticClassRep(), &Parent::__description )
#define IMPLEMENT_CO_DATABLOCK_V1( className ) \
@ -1081,8 +1192,10 @@ inline bool& ConsoleObject::getDynamicGroupExpand()
AbstractClassRep* className::getClassRep() const { return &className::dynClassRep; } \
AbstractClassRep* className::getStaticClassRep() { return &dynClassRep; } \
AbstractClassRep* className::getParentStaticClassRep() { return Parent::getStaticClassRep(); } \
AbstractClassRep* className::getContainerChildStaticClassRep() { return NULL; } \
AbstractClassRep::WriteCustomTamlSchema className::getStaticWriteCustomTamlSchema() { return NULL; } \
ConcreteClassRep<className> className::dynClassRep(#className, "Type" #className, &_smTypeId, NetClassGroupGameMask, NetClassTypeDataBlock, 0, className::getParentStaticClassRep(), &Parent::__description )
// Support for adding properties to classes CONOBJECT style.
#define PROPERTY_TABLE( className ) \
namespace { namespace _ ## className { \
@ -1092,13 +1205,13 @@ inline bool& ConsoleObject::getDynamicGroupExpand()
ConcreteClassRep< className >::smPropertyTable = _ ## className::_propTable; \
namespace { namespace _ ## className { \
EnginePropertyTable::Property _props[] = {
#define END_PROPERTY_TABLE \
{ NULL } \
}; \
EnginePropertyTable _propTable( sizeof( _props ) / sizeof( _props[ 0 ] ) - 1, _props ); \
} }
/// Add an auto-doc for a class.
#define ConsoleDocClass( className, docString ) \
CLASSDOC( className, docString )
@ -1108,7 +1221,7 @@ inline bool& ConsoleObject::getDynamicGroupExpand()
//------------------------------------------------------------------------------
// Protected field default get/set functions
//
// The reason for these functions is that it will save one branch per console
// The reason for these functions is that it will save one branch per console
// data request and script functions will still execute at the same speed as
// before the modifications to allow protected static fields. These will just
// inline and the code should be roughly the same size, and just as fast as
@ -1133,6 +1246,21 @@ inline const char *emptyStringProtectedGetFn( void *obj, const char *data )
return "";
}
inline bool defaultProtectedWriteFn(void* obj, StringTableEntry pFieldName)
{
return true;
}
inline bool defaultProtectedNotSetFn(void* obj, const char *array, const char* data)
{
return false;
}
inline bool defaultProtectedNotWriteFn(void* obj, StringTableEntry pFieldName)
{
return false;
}
/// @}
#endif //_CONSOLEOBJECT_H_

View file

@ -50,24 +50,21 @@ bool addConsoleParser(char *ext, fnGetCurrentFile gcf, fnGetCurrentLine gcl, fnP
AssertFatal(ext && gcf && gcl && p && r, "AddConsoleParser called with one or more NULL arguments");
ConsoleParser * pParser = new ConsoleParser;
if(pParser != NULL)
{
pParser->ext = ext;
pParser->getCurrentFile = gcf;
pParser->getCurrentLine = gcl;
pParser->parse = p;
pParser->restart = r;
pParser->setScanBuffer = ssb;
if(def)
gDefaultParser = pParser;
pParser->ext = ext;
pParser->getCurrentFile = gcf;
pParser->getCurrentLine = gcl;
pParser->parse = p;
pParser->restart = r;
pParser->setScanBuffer = ssb;
pParser->next = gParserList;
gParserList = pParser;
if (def)
gDefaultParser = pParser;
return true;
}
return false;
pParser->next = gParserList;
gParserList = pParser;
return true;
}
ConsoleParser * getParserForFile(const char *filename)

View file

@ -34,7 +34,7 @@
//-----------------------------------------------------------------------------
// TypeString
//-----------------------------------------------------------------------------
ConsoleType( string, TypeString, const char* )
ConsoleType( string, TypeString, const char*, "" )
ImplementConsoleTypeCasters( TypeString, const char* );
ConsoleGetType( TypeString )
@ -53,7 +53,7 @@ ConsoleSetType( TypeString )
//-----------------------------------------------------------------------------
// TypeCaseString
//-----------------------------------------------------------------------------
ConsoleType( caseString, TypeCaseString, const char* )
ConsoleType(caseString, TypeCaseString, const char*, "")
ConsoleSetType( TypeCaseString )
{
@ -71,7 +71,7 @@ ConsoleGetType( TypeCaseString )
//-----------------------------------------------------------------------------
// TypeRealString
//-----------------------------------------------------------------------------
ConsoleType( string, TypeRealString, String )
ConsoleType(string, TypeRealString, String, "")
ImplementConsoleTypeCasters( TypeRealString, String )
ConsoleGetType( TypeRealString )
@ -94,7 +94,7 @@ ConsoleSetType( TypeRealString )
//-----------------------------------------------------------------------------
// TypeCommand
//-----------------------------------------------------------------------------
ConsoleType( string, TypeCommand, String )
ConsoleType(string, TypeCommand, String, "")
ConsoleGetType( TypeCommand )
{
@ -284,7 +284,7 @@ ConsoleProcessData( TypeShapeFilename )
//-----------------------------------------------------------------------------
// TypeS8
//-----------------------------------------------------------------------------
ConsoleType( char, TypeS8, S8 )
ConsoleType(char, TypeS8, S8, "")
ImplementConsoleTypeCasters( TypeS8, S8 )
ConsoleGetType( TypeS8 )
@ -306,7 +306,7 @@ ConsoleSetType( TypeS8 )
//-----------------------------------------------------------------------------
// TypeS32
//-----------------------------------------------------------------------------
ConsoleType( int, TypeS32, S32 )
ConsoleType(int, TypeS32, S32, "")
ImplementConsoleTypeCasters(TypeS32, S32)
ConsoleGetType( TypeS32 )
@ -329,7 +329,7 @@ ConsoleSetType( TypeS32 )
//-----------------------------------------------------------------------------
// TypeS32Vector
//-----------------------------------------------------------------------------
ConsoleType( intList, TypeS32Vector, Vector<S32> )
ConsoleType(intList, TypeS32Vector, Vector<S32>, "")
ImplementConsoleTypeCasters( TypeS32Vector, Vector< S32 > )
ConsoleGetType( TypeS32Vector )
@ -386,7 +386,7 @@ ConsoleSetType( TypeS32Vector )
//-----------------------------------------------------------------------------
// TypeF32
//-----------------------------------------------------------------------------
ConsoleType( float, TypeF32, F32 )
ConsoleType(float, TypeF32, F32, "")
ImplementConsoleTypeCasters(TypeF32, F32)
ConsoleGetType( TypeF32 )
@ -407,7 +407,7 @@ ConsoleSetType( TypeF32 )
//-----------------------------------------------------------------------------
// TypeF32Vector
//-----------------------------------------------------------------------------
ConsoleType( floatList, TypeF32Vector, Vector<F32> )
ConsoleType(floatList, TypeF32Vector, Vector<F32>, "")
ImplementConsoleTypeCasters( TypeF32Vector, Vector< F32 > )
ConsoleGetType( TypeF32Vector )
@ -464,7 +464,7 @@ ConsoleSetType( TypeF32Vector )
//-----------------------------------------------------------------------------
// TypeBool
//-----------------------------------------------------------------------------
ConsoleType( bool, TypeBool, bool )
ConsoleType(bool, TypeBool, bool, "")
ImplementConsoleTypeCasters( TypeBool, bool )
ConsoleGetType( TypeBool )
@ -484,7 +484,7 @@ ConsoleSetType( TypeBool )
//-----------------------------------------------------------------------------
// TypeBoolVector
//-----------------------------------------------------------------------------
ConsoleType( boolList, TypeBoolVector, Vector<bool> )
ConsoleType(boolList, TypeBoolVector, Vector<bool>, "")
ImplementConsoleTypeCasters( TypeBoolVector, Vector< bool > )
ConsoleGetType( TypeBoolVector )
@ -541,7 +541,7 @@ ConsoleSetType( TypeBoolVector )
//-----------------------------------------------------------------------------
// TypeFlag
//-----------------------------------------------------------------------------
ConsoleType( flag, TypeFlag, S32 )
ConsoleType(flag, TypeFlag, S32, "")
ConsoleGetType( TypeFlag )
{
@ -567,7 +567,7 @@ ConsoleSetType( TypeFlag )
//-----------------------------------------------------------------------------
// TypeColorF
//-----------------------------------------------------------------------------
ConsoleType( ColorF, TypeColorF, ColorF )
ConsoleType(ColorF, TypeColorF, ColorF, "")
ImplementConsoleTypeCasters( TypeColorF, ColorF )
ConsoleGetType( TypeColorF )
@ -640,7 +640,7 @@ ConsoleSetType( TypeColorF )
//-----------------------------------------------------------------------------
// TypeColorI
//-----------------------------------------------------------------------------
ConsoleType( ColorI, TypeColorI, ColorI )
ConsoleType(ColorI, TypeColorI, ColorI, "")
ImplementConsoleTypeCasters( TypeColorI, ColorI )
ConsoleGetType( TypeColorI )
@ -713,7 +713,7 @@ ConsoleSetType( TypeColorI )
//-----------------------------------------------------------------------------
// TypeSimObjectName
//-----------------------------------------------------------------------------
ConsoleType( SimObject, TypeSimObjectName, SimObject* )
ConsoleType(SimObject, TypeSimObjectName, SimObject*, "")
ConsoleSetType( TypeSimObjectName )
{
@ -738,7 +738,7 @@ ConsoleGetType( TypeSimObjectName )
//-----------------------------------------------------------------------------
// TypeName
//-----------------------------------------------------------------------------
ConsoleType( string, TypeName, const char* )
ConsoleType(string, TypeName, const char*, "")
ConsoleGetType( TypeName )
{
@ -753,7 +753,7 @@ ConsoleSetType( TypeName )
//------------------------------------------------------------------------------
// TypeParticleParameterString
//------------------------------------------------------------------------------
ConsoleType( string, TypeParticleParameterString, const char* )
ConsoleType(string, TypeParticleParameterString, const char*, "")
ConsoleGetType( TypeParticleParameterString )
{
@ -772,7 +772,7 @@ ConsoleSetType( TypeParticleParameterString )
// TypeMaterialName
//-----------------------------------------------------------------------------
ConsoleType( string, TypeMaterialName, String )
ConsoleType(string, TypeMaterialName, String, "")
ConsoleGetType( TypeMaterialName )
{
@ -794,7 +794,7 @@ ConsoleSetType( TypeMaterialName )
// TypeTerrainMaterialIndex
//-----------------------------------------------------------------------------
ConsoleType( int, TypeTerrainMaterialIndex, S32 )
ConsoleType(int, TypeTerrainMaterialIndex, S32, "")
ConsoleGetType( TypeTerrainMaterialIndex )
{
@ -816,7 +816,7 @@ ConsoleSetType( TypeTerrainMaterialIndex )
// TypeTerrainMaterialName
//-----------------------------------------------------------------------------
ConsoleType( string, TypeTerrainMaterialName, const char* )
ConsoleType(string, TypeTerrainMaterialName, const char*, "")
ConsoleGetType( TypeTerrainMaterialName )
{
@ -835,7 +835,7 @@ ConsoleSetType( TypeTerrainMaterialName )
// TypeCubemapName
//-----------------------------------------------------------------------------
ConsoleType( string, TypeCubemapName, String )
ConsoleType(string, TypeCubemapName, String, "")
ConsoleGetType( TypeCubemapName )
{
@ -856,7 +856,7 @@ ConsoleSetType( TypeCubemapName )
//-----------------------------------------------------------------------------
// TypeRectUV
//-----------------------------------------------------------------------------
ConsoleType( RectF, TypeRectUV, RectF )
ConsoleType(RectF, TypeRectUV, RectF, "")
ConsoleGetType( TypeRectUV )
{
@ -882,7 +882,7 @@ ConsoleSetType( TypeRectUV )
//-----------------------------------------------------------------------------
// TypeUUID
//-----------------------------------------------------------------------------
ConsoleType( uuid, TypeUUID, Torque::UUID )
ConsoleType(uuid, TypeUUID, Torque::UUID, "")
ImplementConsoleTypeCasters( TypeUUID, Torque::UUID )
ConsoleGetType( TypeUUID )
@ -906,7 +906,7 @@ ConsoleSetType( TypeUUID )
//-----------------------------------------------------------------------------
// TypePID
//-----------------------------------------------------------------------------
ConsoleType( pid, TypePID, SimPersistID* )
ConsoleType(pid, TypePID, SimPersistID*, "")
ImplementConsoleTypeCasters( TypePID, SimPersistID* )
ConsoleGetType( TypePID )
@ -945,7 +945,7 @@ ConsoleSetType( TypePID )
//-----------------------------------------------------------------------------
// TypeSimPersistId
//-----------------------------------------------------------------------------
ConsoleType( SimPersistId, TypeSimPersistId, SimPersistID* )
ConsoleType(SimPersistId, TypeSimPersistId, SimPersistID*, "")
ConsoleGetType( TypeSimPersistId )
{

View file

@ -48,11 +48,7 @@
/// @{
#ifndef Offset
#if defined(TORQUE_COMPILER_GCC) && (__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1))
#define Offset(m,T) ((int)(&((T *)1)->m) - 1)
#else
#define Offset(x, cls) ((dsize_t)((const char *)&(((cls *)0)->x)-(const char *)0))
#endif
#define Offset(x, cls) offsetof(cls, x)
#endif
class GFXShader;

View file

@ -35,6 +35,9 @@
#include "console/engineTypeInfo.h"
#endif
#ifndef _STRINGTABLE_H_
#include "core/stringTable.h"
#endif
/// @file
/// Support for legacy TorqueScript console types.
@ -151,6 +154,8 @@ class ConsoleBaseType
virtual const bool isDatablock() { return false; };
virtual const char* prepData( const char* data, char* buffer, U32 bufferLen ) { return data; };
virtual StringTableEntry getTypePrefix(void) const { return StringTable->EmptyString(); }
/// @}
};
@ -259,7 +264,7 @@ const EngineTypeInfo* _MAPTYPE() { return TYPE< T >(); }
DefineConsoleType( type, nativeType ) \
template<> inline const EngineTypeInfo* _MAPTYPE< nativeType >() { return NULL; }
#define ConsoleType( typeName, type, nativeType ) \
#define ConsoleType( typeName, type, nativeType, typePrefix ) \
S32 type; \
class ConsoleType##type : public ConsoleBaseType \
{ \
@ -275,6 +280,7 @@ const EngineTypeInfo* _MAPTYPE() { return TYPE< T >(); }
virtual const char *getTypeClassName() { return #typeName ; } \
virtual void *getNativeVariable() { T* var = new T; return (void*)var; } \
virtual void deleteNativeVariable(void* var) { T* nativeVar = reinterpret_cast<T*>(var); delete nativeVar; } \
virtual StringTableEntry getTypePrefix( void ) const { return StringTable->insert( typePrefix ); } \
}; \
ConsoleType ## type gConsoleType ## type ## Instance;
@ -304,6 +310,9 @@ const EngineTypeInfo* _MAPTYPE() { return TYPE< T >(); }
}; \
ConsoleType ## type gConsoleType ## type ## Instance;
#define ConsoleTypeFieldPrefix( type, typePrefix ) \
StringTableEntry ConsoleType##type::getTypePrefix( void ) const { return StringTable->insert( typePrefix ); }
#define ConsoleSetType( type ) \
void ConsoleType##type::setData(void *dptr, S32 argc, const char **argv, const EnumTable *tbl, BitSet32 flag)
@ -318,6 +327,10 @@ const EngineTypeInfo* _MAPTYPE() { return TYPE< T >(); }
DECLARE_ENUM( type ); \
DefineConsoleType( Type ## type, type );
#define DefineEnumType_R( type ) \
DECLARE_ENUM_R( type ); \
DefineConsoleType( Type ## type, type );
#define _ConsoleEnumType( typeName, type, nativeType ) \
S32 type; \
ImplementConsoleTypeCasters( type, nativeType ) \
@ -347,6 +360,10 @@ const EngineTypeInfo* _MAPTYPE() { return TYPE< T >(); }
DECLARE_BITFIELD( type ); \
DefineConsoleType( Type ## type, type );
#define DefineBitfieldType_R( type ) \
DECLARE_BITFIELD_R( type ); \
DefineConsoleType( Type ## type, type );
#define _ConsoleBitfieldType( typeName, type, nativeType ) \
S32 type; \
ImplementConsoleTypeCasters( type, nativeType ) \

File diff suppressed because it is too large Load diff

View file

@ -706,7 +706,7 @@ static bool dumpEngineDocs( const char *outputFile )
// Dump pre-declarations for any groups we encountered
// so that we don't have to explicitly define them.
HashTable<String,U32>::Iterator iter = smDocGroups.begin();
for ( ; iter != smDocGroups.end(); iter++ )
for (; iter != smDocGroups.end(); ++iter)
stream.writeText( String::ToString( "/*! @addtogroup %s */\r\n\r\n", iter->key.c_str() ) );
return true;

View file

@ -77,7 +77,11 @@ struct EngineFunctionDefaultArguments
// Need byte-aligned packing for the default argument structures.
#ifdef _WIN64
#pragma pack( push, 4 )
#else
#pragma pack( push, 1 )
#endif
// Structure encapsulating default arguments to an engine API function.

View file

@ -34,14 +34,14 @@
DECLARE_PRIMITIVE( bool );
DECLARE_PRIMITIVE( S8 );
DECLARE_PRIMITIVE( U8 );
DECLARE_PRIMITIVE( S32 );
DECLARE_PRIMITIVE( U32 );
DECLARE_PRIMITIVE( F32 );
DECLARE_PRIMITIVE( F64 );
DECLARE_PRIMITIVE( void* );
DECLARE_PRIMITIVE_R( bool );
DECLARE_PRIMITIVE_R(S8);
DECLARE_PRIMITIVE_R(U8);
DECLARE_PRIMITIVE_R(S32);
DECLARE_PRIMITIVE_R(U32);
DECLARE_PRIMITIVE_R(F32);
DECLARE_PRIMITIVE_R(F64);
DECLARE_PRIMITIVE_R(void*);
//FIXME: this allows String to be used as a struct field type
@ -52,7 +52,7 @@ DECLARE_PRIMITIVE( void* );
// are considered to be owned by the API layer itself. The rule here is that such
// a string is only valid until the next API call is made. Usually, control layers
// will immediately copy and convert strings to their own string type.
_DECLARE_TYPE( String );
_DECLARE_TYPE_R(String);
template<>
struct EngineTypeTraits< String > : public _EnginePrimitiveTypeTraits< String >
{

View file

@ -41,11 +41,11 @@ class ColorI;
class ColorF;
DECLARE_STRUCT( Vector< bool > );
DECLARE_STRUCT( Vector< S32 > );
DECLARE_STRUCT( Vector< F32 > );
DECLARE_STRUCT( Torque::UUID );
DECLARE_STRUCT( ColorI );
DECLARE_STRUCT( ColorF );
DECLARE_STRUCT_R(Vector< bool >);
DECLARE_STRUCT_R(Vector< S32 >);
DECLARE_STRUCT_R(Vector< F32 >);
DECLARE_STRUCT_R(Torque::UUID);
DECLARE_STRUCT_R(ColorI);
DECLARE_STRUCT_R(ColorF);
#endif // !_ENGINESTRUCTS_H_

View file

@ -44,7 +44,7 @@ enum EngineTypeKind
EngineTypeKindClass ///< Pointer to opaque EngineObject.
};
DECLARE_ENUM( EngineTypeKind );
DECLARE_ENUM_R( EngineTypeKind );
/// Flags for an EngineTypeInfo.
enum EngineTypeFlags
@ -173,8 +173,8 @@ class EngineFieldTable
/// Construct a field table from a NULL-terminated array of Field
/// records.
EngineFieldTable( const Field* fields )
: mFields( fields ),
mNumFields( 0 )
: mNumFields( 0 ),
mFields( fields )
{
while( fields[ mNumFields ].getName() )
mNumFields ++;

View file

@ -416,6 +416,16 @@ namespace _Private {
#define _DECLARE_TYPE( type ) \
template<> const EngineTypeInfo* TYPE< type >(); \
template<> struct _SCOPE< type > { \
EngineExportScope& operator()() const { \
return *static_cast< EngineExportScope* >( \
const_cast< EngineTypeInfo* >( ( TYPE< type >() ) ) \
); \
} \
};
#define _DECLARE_TYPE_R( type ) \
template<> const EngineTypeInfo* TYPE< type >(); \
template<> struct _SCOPE< type > { \
EngineExportScope& operator()() const { \
@ -432,22 +442,42 @@ namespace _Private {
_DECLARE_TYPE( type ) \
template<> \
struct EngineTypeTraits< type > : public _EnginePrimitiveTypeTraits< type > {};
#define _DECLARE_PRIMITIVE_R( type ) \
_DECLARE_TYPE_R( type ) \
template<> \
struct EngineTypeTraits< type > : public _EnginePrimitiveTypeTraits< type > {};
#define _DECLARE_ENUM( type ) \
_DECLARE_TYPE( type ) \
template<> \
struct _EngineTypeTraits< type > : public _EngineEnumTypeTraits< type > {};
#define _DECLARE_ENUM_R( type ) \
_DECLARE_TYPE_R( type ) \
template<> \
struct _EngineTypeTraits< type > : public _EngineEnumTypeTraits< type > {};
#define _DECLARE_BITFIELD( type ) \
_DECLARE_TYPE( type ) \
template<> \
struct _EngineTypeTraits< type > : public _EngineBitfieldTypeTraits< type > {};
#define _DECLARE_BITFIELD_R( type ) \
_DECLARE_TYPE_R( type ) \
template<> \
struct _EngineTypeTraits< type > : public _EngineBitfieldTypeTraits< type > {};
#define _DECLARE_STRUCT( type ) \
_DECLARE_TYPE( type ) \
template<> \
struct _EngineTypeTraits< type > : public _EngineStructTypeTraits< type > {};
#define _DECLARE_STRUCT_R( type ) \
_DECLARE_TYPE_R( type ) \
template<> \
struct _EngineTypeTraits< type > : public _EngineStructTypeTraits< type > {};
#define _IMPLEMENT_TYPE( type, exportName ) \
template<> \
@ -524,6 +554,10 @@ namespace _Private {
#define DECLARE_PRIMITIVE( type ) \
_DECLARE_PRIMITIVE( type )
///
#define DECLARE_PRIMITIVE_R( type ) \
_DECLARE_PRIMITIVE_R( type )
///
#define IMPLEMENT_PRIMITIVE( type, exportName, scope, doc ) \
_IMPLEMENT_PRIMITIVE( type, exportName, scope, doc )
@ -531,11 +565,19 @@ namespace _Private {
///
#define DECLARE_ENUM( type ) \
_DECLARE_ENUM( type )
///
#define DECLARE_ENUM_R( type ) \
_DECLARE_ENUM_R( type )
///
#define DECLARE_BITFIELD( type ) \
_DECLARE_BITFIELD( type )
///
#define DECLARE_BITFIELD_R( type ) \
_DECLARE_BITFIELD_R( type )
///
#define IMPLEMENT_ENUM( type, exportName, scope, doc ) \
_IMPLEMENT_ENUM( type, exportName, scope, doc )
@ -556,6 +598,10 @@ namespace _Private {
#define DECLARE_STRUCT( type ) \
_DECLARE_STRUCT( type )
///
#define DECLARE_STRUCT_R( type ) \
_DECLARE_STRUCT_R( type )
///
#define IMPLEMENT_STRUCT( type, exportName, scope, doc ) \
_IMPLEMENT_STRUCT( type, exportName, scope, doc )
@ -571,7 +617,7 @@ namespace _Private {
///
#define FIELD_AS( type, fieldName, exportName, numElements, doc ) \
{ #exportName, doc, numElements, TYPE( *( ( type* ) &( ( ThisType* ) 16 )->fieldName ) ), FIELDOFFSET( fieldName ) }, // Artificial offset to avoid compiler warnings.
{ #exportName, doc, numElements, TYPE( *( ( type* ) &( ( ThisType* ) 16 )->fieldName ) ), (U32)FIELDOFFSET( fieldName ) }, // Artificial offset to avoid compiler warnings.
///
#define FIELDOFFSET( fieldName ) \

View file

@ -216,7 +216,7 @@ DefineConsoleMethod(FieldBrushObject, queryFields, const char*, (const char* sim
const AbstractClassRep::FieldList& staticFields = pSimObject->getFieldList();
// Did we specify a groups list?
if ( dStrIsEmpty(groupList) )
if ( String::isEmpty(groupList) )
{
// No, so return all fields...

View file

@ -137,7 +137,7 @@ static S32 buildFileList(const char* pattern, bool recurse, bool multiMatch)
//-----------------------------------------------------------------------------
DefineEngineFunction( findFirstFile, String, ( const char* pattern, bool recurse ), ( true ),
DefineEngineFunction( findFirstFile, String, ( const char* pattern, bool recurse ), ( "", true ),
"@brief Returns the first file in the directory system matching the given pattern.\n\n"
"Use the corresponding findNextFile() to step through "
@ -209,7 +209,7 @@ DefineEngineFunction( findNextFile, String, ( const char* pattern ), ( "" ),
//-----------------------------------------------------------------------------
DefineEngineFunction( getFileCount, S32, ( const char* pattern, bool recurse ), ( true ),
DefineEngineFunction( getFileCount, S32, ( const char* pattern, bool recurse ), ( "", true ),
"@brief Returns the number of files in the directory tree that match the given patterns\n\n"
"This function differs from getFileCountMultiExpr() in that it supports a single search "
@ -245,7 +245,7 @@ DefineEngineFunction( getFileCount, S32, ( const char* pattern, bool recurse ),
//-----------------------------------------------------------------------------
DefineEngineFunction(findFirstFileMultiExpr, String, ( const char* pattern, bool recurse ), (true),
DefineEngineFunction(findFirstFileMultiExpr, String, ( const char* pattern, bool recurse ), ( "", true),
"@brief Returns the first file in the directory system matching the given patterns.\n\n"
"Use the corresponding findNextFileMultiExpr() to step through "
@ -327,7 +327,7 @@ DefineEngineFunction(findNextFileMultiExpr, String, ( const char* pattern ), (""
return sgFindFilesResults[sgFindFilesPos++];
}
DefineEngineFunction(getFileCountMultiExpr, S32, ( const char* pattern, bool recurse ), (true),
DefineEngineFunction(getFileCountMultiExpr, S32, ( const char* pattern, bool recurse ), ( "", true),
"@brief Returns the number of files in the directory tree that match the given patterns\n\n"
"If you're interested in a list of files that match the given patterns and not just "
@ -452,7 +452,7 @@ DefineEngineFunction(stopFileChangeNotifications, void, (),,
}
DefineEngineFunction(getDirectoryList, String, ( const char* path, S32 depth ), ( 0 ),
DefineEngineFunction(getDirectoryList, String, ( const char* path, S32 depth ), ( "", 0 ),
"@brief Gathers a list of directories starting at the given path.\n\n"
"@param path String containing the path of the directory\n"
@ -511,7 +511,7 @@ DefineEngineFunction(fileSize, S32, ( const char* fileName ),,
"@brief Determines the size of a file on disk\n\n"
"@param fileName Name and path of the file to check\n"
"@return Returns filesize in KB, or -1 if no file\n"
"@return Returns filesize in bytes, or -1 if no file\n"
"@ingroup FileSystem")
{
@ -686,7 +686,7 @@ DefineEngineFunction(getWorkingDirectory, String, (),,
// are just string processing functions. They are needed by the 3D tools which
// are not currently built with TORQUE_TOOLS defined.
DefineEngineFunction(makeFullPath, String, ( const char* path, const char* cwd ), (""),
DefineEngineFunction(makeFullPath, String, ( const char* path, const char* cwd ), ( "", ""),
"@brief Converts a relative file path to a full path\n\n"
"For example, \"./console.log\" becomes \"C:/Torque/t3d/examples/FPS Example/game/console.log\"\n"
@ -701,7 +701,7 @@ DefineEngineFunction(makeFullPath, String, ( const char* path, const char* cwd )
return buf;
}
DefineEngineFunction(makeRelativePath, String, ( const char* path, const char* to ), (""),
DefineEngineFunction(makeRelativePath, String, ( const char* path, const char* to ), ( "", ""),
"@brief Turns a full or local path to a relative one\n\n"
"For example, \"./game/art\" becomes \"game/art\"\n"
@ -714,7 +714,7 @@ DefineEngineFunction(makeRelativePath, String, ( const char* path, const char* t
return Platform::makeRelativePathName( path, dStrlen(to) > 1 ? to : NULL );
}
DefineEngineFunction(pathConcat, String, ( const char* path, const char* file),,
DefineEngineFunction(pathConcat, String, ( const char* path, const char* file), ( "", ""),
"@brief Combines two separate strings containing a file path and file name together into a single string\n\n"
"@param path String containing file path\n"
@ -783,7 +783,7 @@ DefineEngineFunction( openFile, void, ( const char* file ),,
//-----------------------------------------------------------------------------
DefineEngineFunction( pathCopy, bool, ( const char* fromFile, const char* toFile, bool noOverwrite ), ( true ),
DefineEngineFunction( pathCopy, bool, ( const char* fromFile, const char* toFile, bool noOverwrite ), ( "", "", true ),
"@brief Copy a file to a new location.\n"
"@param fromFile %Path of the file to copy.\n"
"@param toFile %Path where to copy @a fromFile to.\n"

View file

@ -60,6 +60,27 @@ public:
parentClass = parent;
};
virtual AbstractClassRep* getContainerChildClass(const bool recurse)
{
// Fetch container children type.
AbstractClassRep* pChildren = T::getContainerChildStaticClassRep();
if (!recurse || pChildren != NULL)
return pChildren;
// Fetch parent type.
AbstractClassRep* pParent = T::getParentStaticClassRep();
if (pParent == NULL)
return NULL;
// Get parent container children.
return pParent->getContainerChildClass(recurse);
}
virtual WriteCustomTamlSchema getCustomTamlSchema(void)
{
return T::getStaticWriteCustomTamlSchema();
}
/// Perform class specific initialization tasks.
///
/// Link namespaces, call initPersistFields() and consoleInit().

View file

@ -230,6 +230,11 @@ bool expandOldScriptFilename(char *filename, U32 size, const char *src)
else if (dStrncmp(src, "./", 2) == 0)
// dot path means load from current codeblock/mod path
slash = dStrrchr(cbName, '/');
else if (dStrncmp(src, "^", 1) == 0)
{
Platform::makeFullPathName(src + 1, filename, size);
return true;
}
else
{
// otherwise path must be fully specified

View file

@ -64,7 +64,7 @@ typedef U32 SimObjectId;
enum SimObjectsConstants
{
DataBlockObjectIdFirst = 3,
DataBlockObjectIdBitSize = 10,
DataBlockObjectIdBitSize = 14,
DataBlockObjectIdLast = DataBlockObjectIdFirst + (1 << DataBlockObjectIdBitSize) - 1,
MessageObjectIdFirst = DataBlockObjectIdLast + 1,
@ -157,13 +157,13 @@ namespace Sim
SimTime getTargetTime();
/// a target time of 0 on an event means current event
U32 postEvent(SimObject*, SimEvent*, U32 targetTime);
U32 postEvent(SimObject*, SimEvent*, SimTime targetTime);
inline U32 postEvent(SimObjectId iD,SimEvent*evt, U32 targetTime)
inline U32 postEvent(SimObjectId iD,SimEvent*evt, SimTime targetTime)
{
return postEvent(findObject(iD), evt, targetTime);
}
inline U32 postEvent(const char *objectName,SimEvent*evt, U32 targetTime)
inline U32 postEvent(const char *objectName,SimEvent*evt, SimTime targetTime)
{
return postEvent(findObject(objectName), evt, targetTime);
}

View file

@ -39,7 +39,10 @@ SimConsoleEvent::SimConsoleEvent(S32 argc, ConsoleValueRef *argv, bool onObject)
mArgv[i].value = new ConsoleValue();
mArgv[i].value->type = ConsoleValue::TypeInternalString;
mArgv[i].value->init();
mArgv[i].value->setStringValue((const char*)argv[i]);
if (argv)
{
mArgv[i].value->setStringValue((const char*)argv[i]);
}
}
}
@ -92,10 +95,19 @@ void SimConsoleEvent::process(SimObject* object)
}
}
void SimConsoleEvent::populateArgs(ConsoleValueRef *argv)
{
for (U32 i=0; i<mArgc; i++)
{
argv[i].value = mArgv[i].value;
}
}
//-----------------------------------------------------------------------------
SimConsoleThreadExecCallback::SimConsoleThreadExecCallback() : retVal(NULL)
SimConsoleThreadExecCallback::SimConsoleThreadExecCallback()
{
retVal.value = NULL;
sem = new Semaphore(0);
}
@ -104,20 +116,20 @@ SimConsoleThreadExecCallback::~SimConsoleThreadExecCallback()
delete sem;
}
void SimConsoleThreadExecCallback::handleCallback(const char *ret)
void SimConsoleThreadExecCallback::handleCallback(ConsoleValueRef ret)
{
retVal = ret;
sem->release();
}
const char *SimConsoleThreadExecCallback::waitForResult()
ConsoleValueRef SimConsoleThreadExecCallback::waitForResult()
{
if(sem->acquire(true))
{
return retVal;
}
return NULL;
return ConsoleValueRef();
}
//-----------------------------------------------------------------------------
@ -129,7 +141,7 @@ SimConsoleThreadExecEvent::SimConsoleThreadExecEvent(S32 argc, ConsoleValueRef *
void SimConsoleThreadExecEvent::process(SimObject* object)
{
const char *retVal;
ConsoleValueRef retVal;
if(mOnObject)
retVal = Con::execute(object, mArgc, mArgv);
else

View file

@ -114,19 +114,24 @@ public:
~SimConsoleEvent();
virtual void process(SimObject *object);
/// Creates a reference to our internal args list in argv
void populateArgs(ConsoleValueRef *argv);
};
// NOTE: SimConsoleThreadExecCallback & SimConsoleThreadExecEvent moved to engineAPI.h
/// Used by Con::threadSafeExecute()
struct SimConsoleThreadExecCallback
{
Semaphore *sem;
const char *retVal;
ConsoleValueRef retVal;
SimConsoleThreadExecCallback();
~SimConsoleThreadExecCallback();
void handleCallback(const char *ret);
const char *waitForResult();
void handleCallback(ConsoleValueRef ret);
ConsoleValueRef waitForResult();
};
class SimConsoleThreadExecEvent : public SimConsoleEvent
@ -136,6 +141,7 @@ class SimConsoleThreadExecEvent : public SimConsoleEvent
public:
SimConsoleThreadExecEvent(S32 argc, ConsoleValueRef *argv, bool onObject, SimConsoleThreadExecCallback *callback);
SimConsoleThreadExecCallback& getCB() { return *cb; }
virtual void process(SimObject *object);
};

View file

@ -49,13 +49,13 @@ public:
Entry *next;
ConsoleBaseType *type;
};
private:
enum
{
HashTableSize = 19
};
Entry *mHashTable[HashTableSize];
private:
static Entry *smFreeList;
void freeEntry(Entry *entry);

View file

@ -34,7 +34,7 @@
#include "core/frameAllocator.h"
#include "core/stream/fileStream.h"
#include "core/fileObject.h"
#include "persistence/taml/tamlCustom.h"
IMPLEMENT_CONOBJECT( SimObject );
@ -437,6 +437,97 @@ SimPersistID* SimObject::getOrCreatePersistentId()
return mPersistentId;
}
void SimObject::onTamlCustomRead(TamlCustomNodes const& customNodes)
{
// Debug Profiling.
//PROFILE_SCOPE(SimObject_OnTamlCustomRead);
// Fetch field list.
const AbstractClassRep::FieldList& fieldList = getFieldList();
const U32 fieldCount = fieldList.size();
for (U32 index = 0; index < fieldCount; ++index)
{
// Fetch field.
const AbstractClassRep::Field* pField = &fieldList[index];
// Ignore if field not appropriate.
if (pField->type == AbstractClassRep::StartArrayFieldType || pField->elementCount > 1)
{
// Find cell custom node.
const TamlCustomNode* pCustomCellNodes = NULL;
if (pField->pGroupname != NULL)
pCustomCellNodes = customNodes.findNode(pField->pGroupname);
if (!pCustomCellNodes)
{
char* niceFieldName = const_cast<char *>(pField->pFieldname);
niceFieldName[0] = dToupper(niceFieldName[0]);
String str_niceFieldName = String(niceFieldName);
pCustomCellNodes = customNodes.findNode(str_niceFieldName + "s");
}
// Continue if we have explicit cells.
if (pCustomCellNodes != NULL)
{
// Fetch children cell nodes.
const TamlCustomNodeVector& cellNodes = pCustomCellNodes->getChildren();
U8 idx = 0;
// Iterate cells.
for (TamlCustomNodeVector::const_iterator cellNodeItr = cellNodes.begin(); cellNodeItr != cellNodes.end(); ++cellNodeItr)
{
char buf[5];
dSprintf(buf, 5, "%d", idx);
// Fetch cell node.
TamlCustomNode* pCellNode = *cellNodeItr;
// Fetch node name.
StringTableEntry nodeName = pCellNode->getNodeName();
// Is this a valid alias?
if (nodeName != pField->pFieldname)
{
// No, so warn.
Con::warnf("SimObject::onTamlCustomRead() - Encountered an unknown custom name of '%s'. Only '%s' is valid.", nodeName, pField->pFieldname);
continue;
}
// Fetch fields.
const TamlCustomFieldVector& fields = pCellNode->getFields();
// Iterate property fields.
for (TamlCustomFieldVector::const_iterator fieldItr = fields.begin(); fieldItr != fields.end(); ++fieldItr)
{
// Fetch field.
const TamlCustomField* pField = *fieldItr;
// Fetch field name.
StringTableEntry fieldName = pField->getFieldName();
const AbstractClassRep::Field* field = findField(fieldName);
// Check common fields.
if (field)
{
setDataField(fieldName, buf, pField->getFieldValue());
}
else
{
// Unknown name so warn.
Con::warnf("SimObject::onTamlCustomRead() - Encountered an unknown custom field name of '%s'.", fieldName);
continue;
}
}
idx++;
}
}
}
}
}
//-----------------------------------------------------------------------------
bool SimObject::_setPersistentID( void* object, const char* index, const char* data )
@ -925,6 +1016,220 @@ const char *SimObject::getDataField(StringTableEntry slotName, const char *array
return "";
}
const char *SimObject::getPrefixedDataField(StringTableEntry fieldName, const char *array)
{
// Sanity!
AssertFatal(fieldName != NULL, "Cannot get field value with NULL field name.");
// Fetch field value.
const char* pFieldValue = getDataField(fieldName, array);
// Sanity.
//AssertFatal(pFieldValue != NULL, "Field value cannot be NULL.");
if (!pFieldValue)
return NULL;
// Return without the prefix if there's no value.
if (*pFieldValue == 0)
return StringTable->EmptyString();
// Fetch the field prefix.
StringTableEntry fieldPrefix = getDataFieldPrefix(fieldName);
// Sanity!
AssertFatal(fieldPrefix != NULL, "Field prefix cannot be NULL.");
// Calculate a buffer size including prefix.
const U32 valueBufferSize = dStrlen(fieldPrefix) + dStrlen(pFieldValue) + 1;
// Fetch a buffer.
char* pValueBuffer = Con::getReturnBuffer(valueBufferSize);
// Format the value buffer.
dSprintf(pValueBuffer, valueBufferSize, "%s%s", fieldPrefix, pFieldValue);
return pValueBuffer;
}
//-----------------------------------------------------------------------------
void SimObject::setPrefixedDataField(StringTableEntry fieldName, const char *array, const char *value)
{
// Sanity!
AssertFatal(fieldName != NULL, "Cannot set object field value with NULL field name.");
AssertFatal(value != NULL, "Field value cannot be NULL.");
// Set value without prefix if there's no value.
if (*value == 0)
{
setDataField(fieldName, NULL, value);
return;
}
// Fetch the field prefix.
StringTableEntry fieldPrefix = getDataFieldPrefix(fieldName);
// Sanity.
AssertFatal(fieldPrefix != NULL, "Field prefix cannot be NULL.");
// Do we have a field prefix?
if (fieldPrefix == StringTable->EmptyString())
{
// No, so set the data field in the usual way.
setDataField(fieldName, NULL, value);
return;
}
// Yes, so fetch the length of the field prefix.
const U32 fieldPrefixLength = dStrlen(fieldPrefix);
// Yes, so does it start with the object field prefix?
if (dStrnicmp(value, fieldPrefix, fieldPrefixLength) != 0)
{
// No, so set the data field in the usual way.
setDataField(fieldName, NULL, value);
return;
}
// Yes, so set the data excluding the prefix.
setDataField(fieldName, NULL, value + fieldPrefixLength);
}
//-----------------------------------------------------------------------------
const char *SimObject::getPrefixedDynamicDataField(StringTableEntry fieldName, const char *array, const S32 fieldType)
{
// Sanity!
AssertFatal(fieldName != NULL, "Cannot get field value with NULL field name.");
// Fetch field value.
const char* pFieldValue = getDataField(fieldName, array);
// Sanity.
AssertFatal(pFieldValue != NULL, "Field value cannot be NULL.");
// Return the field if no field type is specified.
if (fieldType == -1)
return pFieldValue;
// Return without the prefix if there's no value.
if (*pFieldValue == 0)
return StringTable->EmptyString();
// Fetch the console base type.
ConsoleBaseType* pConsoleBaseType = ConsoleBaseType::getType(fieldType);
// Did we find the console base type?
if (pConsoleBaseType == NULL)
{
// No, so warn.
Con::warnf("getPrefixedDynamicDataField() - Invalid field type '%d' specified for field '%s' with value '%s'.",
fieldType, fieldName, pFieldValue);
}
// Fetch the field prefix.
StringTableEntry fieldPrefix = pConsoleBaseType->getTypePrefix();
// Sanity!
AssertFatal(fieldPrefix != NULL, "Field prefix cannot be NULL.");
// Calculate a buffer size including prefix.
const U32 valueBufferSize = dStrlen(fieldPrefix) + dStrlen(pFieldValue) + 1;
// Fetch a buffer.
char* pValueBuffer = Con::getReturnBuffer(valueBufferSize);
// Format the value buffer.
dSprintf(pValueBuffer, valueBufferSize, "%s%s", fieldPrefix, pFieldValue);
return pValueBuffer;
}
//-----------------------------------------------------------------------------
void SimObject::setPrefixedDynamicDataField(StringTableEntry fieldName, const char *array, const char *value, const S32 fieldType)
{
// Sanity!
AssertFatal(fieldName != NULL, "Cannot set object field value with NULL field name.");
AssertFatal(value != NULL, "Field value cannot be NULL.");
// Set value without prefix if no field type was specified.
if (fieldType == -1)
{
setDataField(fieldName, NULL, value);
return;
}
// Fetch the console base type.
ConsoleBaseType* pConsoleBaseType = ConsoleBaseType::getType(fieldType);
// Did we find the console base type?
if (pConsoleBaseType == NULL)
{
// No, so warn.
Con::warnf("setPrefixedDynamicDataField() - Invalid field type '%d' specified for field '%s' with value '%s'.",
fieldType, fieldName, value);
}
// Set value without prefix if there's no value or we didn't find the console base type.
if (*value == 0 || pConsoleBaseType == NULL)
{
setDataField(fieldName, NULL, value);
return;
}
// Fetch the field prefix.
StringTableEntry fieldPrefix = pConsoleBaseType->getTypePrefix();
// Sanity.
AssertFatal(fieldPrefix != NULL, "Field prefix cannot be NULL.");
// Do we have a field prefix?
if (fieldPrefix == StringTable->EmptyString())
{
// No, so set the data field in the usual way.
setDataField(fieldName, NULL, value);
return;
}
// Yes, so fetch the length of the field prefix.
const U32 fieldPrefixLength = dStrlen(fieldPrefix);
// Yes, so does it start with the object field prefix?
if (dStrnicmp(value, fieldPrefix, fieldPrefixLength) != 0)
{
// No, so set the data field in the usual way.
setDataField(fieldName, NULL, value);
return;
}
// Yes, so set the data excluding the prefix.
setDataField(fieldName, NULL, value + fieldPrefixLength);
}
//-----------------------------------------------------------------------------
StringTableEntry SimObject::getDataFieldPrefix(StringTableEntry fieldName)
{
// Sanity!
AssertFatal(fieldName != NULL, "Cannot get field prefix with NULL field name.");
// Find the field.
const AbstractClassRep::Field* pField = findField(fieldName);
// Return nothing if field was not found.
if (pField == NULL)
return StringTable->EmptyString();
// Yes, so fetch the console base type.
ConsoleBaseType* pConsoleBaseType = ConsoleBaseType::getType(pField->type);
// Fetch the type prefix.
return pConsoleBaseType->getTypePrefix();
}
//-----------------------------------------------------------------------------
U32 SimObject::getDataFieldType( StringTableEntry slotName, const char* array )
@ -1407,10 +1712,11 @@ void SimObject::linkNamespaces()
// while still having the class namespace fields matching the current
// setup.
AssertWarn( mNameSpace == NULL, "SimObject::linkNamespaces -- Namespace linkage already in place" );
if( mNameSpace )
if (mNameSpace)
{
Con::warnf("SimObject::linkNamespaces -- Namespace linkage already in place %s", mNameSpace->getName());
return;
}
// Get the namespace for the C++ class.
Namespace* cppNamespace = getClassRep()->getNameSpace();
@ -1599,7 +1905,8 @@ void SimObject::unlinkNamespaces()
// Handle object name.
if (mNameSpace && mNameSpace->mClassRep == NULL)
StringTableEntry objectName = getName();
if( objectName && objectName[ 0 ] )
mNameSpace->decRefCountToParent();
mNameSpace = NULL;

View file

@ -33,6 +33,9 @@
#include "core/bitSet.h"
#endif
#ifndef _TAML_CALLBACKS_H_
#include "persistence/taml/tamlCallbacks.h"
#endif
class Stream;
class LightManager;
@ -226,7 +229,7 @@ class SimPersistID;
/// set automatically by the console constructor code.
///
/// @nosubgrouping
class SimObject: public ConsoleObject
class SimObject: public ConsoleObject, public TamlCallbacks
{
public:
@ -298,6 +301,8 @@ class SimObject: public ConsoleObject
/// Flags internal to the object management system.
BitSet32 mFlags;
StringTableEntry mProgenitorFile;
/// Object we are copying fields from.
SimObject* mCopySource;
@ -348,13 +353,42 @@ class SimObject: public ConsoleObject
static bool setSuperClass(void *object, const char *index, const char *data)
{ static_cast<SimObject*>(object)->setSuperClassNamespace(data); return false; };
static bool writeObjectName(void* obj, StringTableEntry pFieldName)
{ SimObject* simObject = static_cast<SimObject*>(obj); return simObject->objectName != NULL && simObject->objectName != StringTable->EmptyString(); }
static bool writeCanSaveDynamicFields(void* obj, StringTableEntry pFieldName)
{ return static_cast<SimObject*>(obj)->mCanSaveFieldDictionary == false; }
static bool writeInternalName(void* obj, StringTableEntry pFieldName)
{ SimObject* simObject = static_cast<SimObject*>(obj); return simObject->mInternalName != NULL && simObject->mInternalName != StringTable->EmptyString(); }
static bool setParentGroup(void* obj, const char* data);
static bool writeParentGroup(void* obj, StringTableEntry pFieldName)
{ return static_cast<SimObject*>(obj)->mGroup != NULL; }
static bool writeSuperclass(void* obj, StringTableEntry pFieldName)
{ SimObject* simObject = static_cast<SimObject*>(obj); return simObject->mSuperClassName != NULL && simObject->mSuperClassName != StringTable->EmptyString(); }
static bool writeClass(void* obj, StringTableEntry pFieldName)
{ SimObject* simObject = static_cast<SimObject*>(obj); return simObject->mClassName != NULL && simObject->mClassName != StringTable->EmptyString(); }
static bool writeClassName(void* obj, StringTableEntry pFieldName)
{ SimObject* simObject = static_cast<SimObject*>(obj); return simObject->mClassName != NULL && simObject->mClassName != StringTable->EmptyString(); }
// Group hierarchy protected set method
static bool setProtectedParent(void *object, const char *index, const char *data);
// Object name protected set method
static bool setProtectedName(void *object, const char *index, const char *data);
public:
inline void setProgenitorFile(const char* pFile) { mProgenitorFile = StringTable->insert(pFile); }
inline StringTableEntry getProgenitorFile(void) const { return mProgenitorFile; }
protected:
/// Taml callbacks.
virtual void onTamlPreWrite(void) {}
virtual void onTamlPostWrite(void) {}
virtual void onTamlPreRead(void) {}
virtual void onTamlPostRead(const TamlCustomNodes& customNodes) {}
virtual void onTamlAddParent(SimObject* pParentObject) {}
virtual void onTamlCustomWrite(TamlCustomNodes& customNodes) {}
virtual void onTamlCustomRead(const TamlCustomNodes& customNodes);
/// Id number for this object.
SimObjectId mId;
@ -461,6 +495,16 @@ class SimObject: public ConsoleObject
/// @param value Value to store.
void setDataField(StringTableEntry slotName, const char *array, const char *value);
const char *getPrefixedDataField(StringTableEntry fieldName, const char *array);
void setPrefixedDataField(StringTableEntry fieldName, const char *array, const char *value);
const char *getPrefixedDynamicDataField(StringTableEntry fieldName, const char *array, const S32 fieldType = -1);
void setPrefixedDynamicDataField(StringTableEntry fieldName, const char *array, const char *value, const S32 fieldType = -1);
StringTableEntry getDataFieldPrefix(StringTableEntry fieldName);
/// Get the type of a field on the object.
///
/// @param slotName Field to access.

View file

@ -23,7 +23,8 @@
#include "platform/platform.h"
#include "console/simObjectList.h"
#include "console/console.h"
#include "console/simBase.h"
#include "console/engineAPI.h"
#include "console/sim.h"
#include "console/simObject.h"

View file

@ -44,9 +44,9 @@ public:
static S32 _smTypeId;
SimObjectRef()
: mId( 0 ),
mObject( NULL ),
mName( "" )
: mName( "" ),
mId( 0 ),
mObject( NULL )
{
}
@ -178,4 +178,4 @@ public:
};
#endif // _SIMOBJECTREF_H_
#endif // _SIMOBJECTREF_H_

View file

@ -39,6 +39,7 @@
#include "core/util/tSignal.h"
#endif
#include "persistence/taml/tamlChildren.h"
//---------------------------------------------------------------------------
/// A set of SimObjects.
@ -89,7 +90,7 @@
/// }
/// @endcode
///
class SimSet: public SimObject
class SimSet : public SimObject, public TamlChildren
{
public:
@ -152,8 +153,10 @@ class SimSet: public SimObject
iterator end() { return objectList.end(); }
value operator[] (S32 index) { return objectList[U32(index)]; }
iterator find( iterator first, iterator last, SimObject *obj)
inline iterator find( iterator first, iterator last, SimObject *obj)
{ return ::find(first, last, obj); }
inline iterator find(SimObject *obj)
{ return ::find(begin(), end(), obj); }
/// Reorder the position of "obj" to either be the last object in the list or, if
/// "target" is given, to come before "target" in the list of children.
@ -222,7 +225,7 @@ class SimSet: public SimObject
/// @note The child sets themselves count towards the total too.
U32 sizeRecursive();
SimObject* findObjectByInternalName(StringTableEntry internalName, bool searchChildren = false);
virtual SimObject* findObjectByInternalName(StringTableEntry internalName, bool searchChildren = false);
SimObject* findObjectByLineNumber(const char* fileName, S32 declarationLine, bool searchChildren = false);
/// Find the given object in this set. Returns NULL if the object
@ -277,6 +280,32 @@ class SimSet: public SimObject
virtual bool readObject(Stream *stream);
virtual SimSet* clone();
// TamlChildren
virtual U32 getTamlChildCount(void) const
{
return (U32)size();
}
virtual SimObject* getTamlChild(const U32 childIndex) const
{
// Sanity!
AssertFatal(childIndex < (U32)size(), "SimSet::getTamlChild() - Child index is out of range.");
// For when the assert is not used.
if (childIndex >= (U32)size())
return NULL;
return at(childIndex);
}
virtual void addTamlChild(SimObject* pSimObject)
{
// Sanity!
AssertFatal(pSimObject != NULL, "SimSet::addTamlChild() - Cannot add a NULL child object.");
addObject(pSimObject);
}
};
#ifdef TORQUE_DEBUG_GUARD

View file

@ -31,12 +31,11 @@ void ConsoleValueStack::getArgcArgv(StringTableEntry name, U32 *argc, ConsoleVal
U32 argCount = getMin(mStackPos - startStack, (U32)MaxArgs - 1);
*in_argv = mArgv;
mArgv[0] = name;
mArgv[0].value = CSTK.pushStackString(name);
for(U32 i = 0; i < argCount; i++) {
ConsoleValueRef *ref = &mArgv[i+1];
ref->value = &mStack[startStack + i];
ref->stringStackValue = NULL;
}
argCount++;
@ -91,11 +90,43 @@ void ConsoleValueStack::pushValue(ConsoleValue &variable)
mStack[mStackPos++].setIntValue((S32)variable.getIntValue());
case ConsoleValue::TypeInternalFloat:
mStack[mStackPos++].setFloatValue((F32)variable.getFloatValue());
case ConsoleValue::TypeInternalStringStackPtr:
mStack[mStackPos++].setStringStackPtrValue(variable.getStringStackPtr());
default:
mStack[mStackPos++].setStringValue(variable.getStringValue());
}
}
ConsoleValue* ConsoleValueStack::reserveValues(U32 count)
{
U32 startPos = mStackPos;
if (startPos+count >= ConsoleValueStack::MaxStackDepth) {
AssertFatal(false, "Console Value Stack is empty");
return NULL;
}
//Con::printf("[%i]CSTK reserveValues %i", mStackPos, count);
mStackPos += count;
return &mStack[startPos];
}
bool ConsoleValueStack::reserveValues(U32 count, ConsoleValueRef *outValues)
{
U32 startPos = mStackPos;
if (startPos+count >= ConsoleValueStack::MaxStackDepth) {
AssertFatal(false, "Console Value Stack is empty");
return false;
}
//Con::printf("[%i]CSTK reserveValues %i", mStackPos, count);
for (U32 i=0; i<count; i++)
{
outValues[i].value = &mStack[mStackPos+i];
}
mStackPos += count;
return true;
}
ConsoleValue *ConsoleValueStack::pushString(const char *value)
{
if (mStackPos == ConsoleValueStack::MaxStackDepth) {
@ -122,6 +153,19 @@ ConsoleValue *ConsoleValueStack::pushStackString(const char *value)
return &mStack[mStackPos-1];
}
ConsoleValue *ConsoleValueStack::pushStringStackPtr(StringStackPtr value)
{
if (mStackPos == ConsoleValueStack::MaxStackDepth) {
AssertFatal(false, "Console Value Stack is empty");
return NULL;
}
//Con::printf("[%i]CSTK pushStringStackPtr %s", mStackPos, StringStackPtrRef(value).getPtr(&STR));
mStack[mStackPos++].setStringStackPtrValue(value);
return &mStack[mStackPos-1];
}
ConsoleValue *ConsoleValueStack::pushUINT(U32 value)
{
if (mStackPos == ConsoleValueStack::MaxStackDepth) {

View file

@ -35,8 +35,21 @@
#include "console/console.h"
#endif
typedef U32 StringStackPtr;
struct StringStack;
/// Helper class which stores a relative pointer in the StringStack buffer
class StringStackPtrRef
{
public:
StringStackPtrRef() : mOffset(0) {;}
StringStackPtrRef(StringStackPtr offset) : mOffset(offset) {;}
StringStackPtr mOffset;
/// Get pointer to string in stack stk
inline char *getPtr(StringStack *stk);
};
/// Core stack for interpreter operations.
///
@ -127,6 +140,7 @@ struct StringStack
/// Return a temporary buffer we can use to return data.
char* getReturnBuffer(U32 size)
{
AssertFatal(Con::isMainThread(), "Manipulating return buffer from a secondary thread!");
validateArgBufferSize(size);
return mArgBuffer;
}
@ -136,6 +150,7 @@ struct StringStack
/// This updates the function offset.
char *getArgBuffer(U32 size)
{
AssertFatal(Con::isMainThread(), "Manipulating console arg buffer from a secondary thread!");
validateBufferSize(mStart + mFunctionOffset + size);
char *ret = mBuffer + mStart + mFunctionOffset;
mFunctionOffset += size;
@ -197,6 +212,16 @@ struct StringStack
return mBuffer + mStartOffsets[mStartStackSize-1];
}
inline StringStackPtr getStringValuePtr()
{
return (getStringValue() - mBuffer);
}
inline StringStackPtr getPreviousStringValuePtr()
{
return (getPreviousStringValue() - mBuffer);
}
/// Advance the start stack, placing a zero length string on the top.
///
/// @note You should use StringStack::push, not this, if you want to
@ -314,10 +339,13 @@ public:
void pushVar(ConsoleValue *variable);
void pushValue(ConsoleValue &value);
ConsoleValue* reserveValues(U32 numValues);
bool reserveValues(U32 numValues, ConsoleValueRef *values);
ConsoleValue* pop();
ConsoleValue *pushString(const char *value);
ConsoleValue *pushStackString(const char *value);
ConsoleValue *pushStringStackPtr(StringStackPtr ptr);
ConsoleValue *pushUINT(U32 value);
ConsoleValue *pushFLT(float value);
@ -338,4 +366,9 @@ public:
ConsoleValueRef mArgv[MaxArgs];
};
extern StringStack STR;
extern ConsoleValueStack CSTK;
inline char* StringStackPtrRef::getPtr(StringStack *stk) { return stk->mBuffer + mOffset; }
#endif

View file

@ -21,9 +21,11 @@
//-----------------------------------------------------------------------------
#include "platform/platform.h"
#include "console/simBase.h"
#include "console/engineAPI.h"
#include "console/telnetConsole.h"
#include "console/engineAPI.h"
#include "core/strings/stringFunctions.h"
#include "core/util/journal/process.h"
#include "core/module.h"

View file

@ -0,0 +1,287 @@
#ifdef TORQUE_TESTS_ENABLED
#include "testing/unitTesting.h"
#include "platform/platform.h"
#include "console/simBase.h"
#include "console/consoleTypes.h"
#include "console/simBase.h"
#include "console/engineAPI.h"
#include "math/mMath.h"
#include "console/stringStack.h"
TEST(Con, executef)
{
char buffer[128];
Con::evaluate("if (isObject(TestConExec)) {\r\nTestConExec.delete();\r\n}\r\nfunction testExecutef(%a,%b,%c,%d,%e,%f,%g,%h,%i,%j,%k){return %a SPC %b SPC %c SPC %d SPC %e SPC %f SPC %g SPC %h SPC %i SPC %j SPC %k;}\r\nfunction TestConExec::testThisFunction(%this,%a,%b,%c,%d,%e,%f,%g,%h,%i,%j){ return %a SPC %b SPC %c SPC %d SPC %e SPC %f SPC %g SPC %h SPC %i SPC %j;}\r\nnew ScriptObject(TestConExec);\r\n", false, "test");
SimObject *testObject = NULL;
Sim::findObject("TestConExec", testObject);
EXPECT_TRUE(testObject != NULL)
<< "TestConExec object should exist";
// Check basic calls with SimObject. We'll do this for every single possible call just to make sure.
const char *returnValue = NULL;
returnValue = Con::executef(testObject, "testThisFunction");
EXPECT_TRUE(dStricmp(returnValue, " ") == 0) <<
"All values should be printed in the correct order";
returnValue = Con::executef(testObject, "testThisFunction", "a");
EXPECT_TRUE(dStricmp(returnValue, "a ") == 0) <<
"All values should be printed in the correct order";
returnValue = Con::executef(testObject, "testThisFunction", "a", "b");
EXPECT_TRUE(dStricmp(returnValue, "a b ") == 0) <<
"All values should be printed in the correct order";
returnValue = Con::executef(testObject, "testThisFunction", "a", "b", "c");
EXPECT_TRUE(dStricmp(returnValue, "a b c ") == 0) <<
"All values should be printed in the correct order";
returnValue = Con::executef(testObject, "testThisFunction", "a", "b", "c", "d");
EXPECT_TRUE(dStricmp(returnValue, "a b c d ") == 0) <<
"All values should be printed in the correct order";
returnValue = Con::executef(testObject, "testThisFunction", "a", "b", "c", "d", "e");
EXPECT_TRUE(dStricmp(returnValue, "a b c d e ") == 0) <<
"All values should be printed in the correct order";
returnValue = Con::executef(testObject, "testThisFunction", "a", "b", "c", "d", "e", "f");
EXPECT_TRUE(dStricmp(returnValue, "a b c d e f ") == 0) <<
"All values should be printed in the correct order";
returnValue = Con::executef(testObject, "testThisFunction", "a", "b", "c", "d", "e", "f", "g");
EXPECT_TRUE(dStricmp(returnValue, "a b c d e f g ") == 0) <<
"All values should be printed in the correct order";
returnValue = Con::executef(testObject, "testThisFunction", "a", "b", "c", "d", "e", "f", "g", "h");
EXPECT_TRUE(dStricmp(returnValue, "a b c d e f g h ") == 0) <<
"All values should be printed in the correct order";
returnValue = Con::executef(testObject, "testThisFunction", "a", "b", "c", "d", "e", "f", "g", "h", "i");
EXPECT_TRUE(dStricmp(returnValue, "a b c d e f g h i ") == 0) <<
"All values should be printed in the correct order";
// Now test without the object
returnValue = Con::executef("testExecutef");
EXPECT_TRUE(dStricmp(returnValue, " ") == 0) <<
"All values should be printed in the correct order";
returnValue = Con::executef("testExecutef", "a");
EXPECT_TRUE(dStricmp(returnValue, "a ") == 0) <<
"All values should be printed in the correct order";
returnValue = Con::executef("testExecutef", "a", "b");
EXPECT_TRUE(dStricmp(returnValue, "a b ") == 0) <<
"All values should be printed in the correct order";
returnValue = Con::executef("testExecutef", "a", "b", "c");
EXPECT_TRUE(dStricmp(returnValue, "a b c ") == 0) <<
"All values should be printed in the correct order";
returnValue = Con::executef("testExecutef", "a", "b", "c", "d");
EXPECT_TRUE(dStricmp(returnValue, "a b c d ") == 0) <<
"All values should be printed in the correct order";
returnValue = Con::executef("testExecutef", "a", "b", "c", "d", "e");
EXPECT_TRUE(dStricmp(returnValue, "a b c d e ") == 0) <<
"All values should be printed in the correct order";
returnValue = Con::executef("testExecutef", "a", "b", "c", "d", "e", "f");
EXPECT_TRUE(dStricmp(returnValue, "a b c d e f ") == 0) <<
"All values should be printed in the correct order";
returnValue = Con::executef("testExecutef", "a", "b", "c", "d", "e", "f", "g");
EXPECT_TRUE(dStricmp(returnValue, "a b c d e f g ") == 0) <<
"All values should be printed in the correct order";
returnValue = Con::executef("testExecutef", "a", "b", "c", "d", "e", "f", "g", "h");
EXPECT_TRUE(dStricmp(returnValue, "a b c d e f g h ") == 0) <<
"All values should be printed in the correct order";
returnValue = Con::executef("testExecutef", "a", "b", "c", "d", "e", "f", "g", "h", "i");
EXPECT_TRUE(dStricmp(returnValue, "a b c d e f g h i ") == 0) <<
"All values should be printed in the correct order";
returnValue = Con::executef("testExecutef", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j");
EXPECT_TRUE(dStricmp(returnValue, "a b c d e f g h i j ") == 0) <<
"All values should be printed in the correct order";
// Test type conversions with and without SimObject...
// Integer
returnValue = Con::executef(testObject, "testThisFunction", 123);
EXPECT_TRUE(dStricmp(returnValue, "123 ") == 0) <<
"Integer should be converted";
returnValue = Con::executef("testExecutef", 123);
EXPECT_TRUE(dStricmp(returnValue, "123 ") == 0) <<
"Integer should be converted";
// Float
returnValue = Con::executef(testObject, "testThisFunction", (F32)123.4);
EXPECT_TRUE(dStricmp(returnValue, "123.4 ") == 0) <<
"Float should be converted";
returnValue = Con::executef("testExecutef", (F32)123.4);
EXPECT_TRUE(dStricmp(returnValue, "123.4 ") == 0) <<
"Float should be converted";
// SimObject
dSprintf(buffer, sizeof(buffer), "%i ", testObject->getId());
returnValue = Con::executef(testObject, "testThisFunction", testObject);
EXPECT_TRUE(dStricmp(returnValue, buffer) == 0) <<
"SimObject should be converted";
dSprintf(buffer, sizeof(buffer), "%i ", testObject->getId());
returnValue = Con::executef("testExecutef", testObject);
EXPECT_TRUE(dStricmp(returnValue, buffer) == 0) <<
"SimObject should be converted";
// Point3F
Point3F point(1,2,3);
returnValue = Con::executef(testObject, "testThisFunction", point);
EXPECT_TRUE(dStricmp(returnValue, "1 2 3 ") == 0) <<
"Point3F should be converted";
returnValue = Con::executef("testExecutef", point);
EXPECT_TRUE(dStricmp(returnValue, "1 2 3 ") == 0) <<
"Point3F should be converted";
// Finally test the function arg offset. This should be consistently 0 after each call
EXPECT_TRUE(STR.mFunctionOffset == 0) <<
"Function offset should be 0";
const char *floatArg = Con::getFloatArg(1.23);
EXPECT_TRUE(STR.mFunctionOffset > 0) <<
"Function offset should not be 0";
Con::executef("testExecutef", floatArg);
EXPECT_TRUE(STR.mFunctionOffset == 0) <<
"Function offset should be 0";
floatArg = Con::getFloatArg(1.23);
EXPECT_TRUE(STR.mFunctionOffset > 0) <<
"Function offset should not be 0";
Con::executef("testImaginaryFunction_", floatArg);
EXPECT_TRUE(STR.mFunctionOffset == 0) <<
"Function offset should be 0";
}
TEST(Con, execute)
{
Con::evaluate("if (isObject(TestConExec)) {\r\nTestConExec.delete();\r\n}\r\nfunction testScriptExecuteFunction(%a,%b) {return %a SPC %b;}\nfunction TestConExec::testScriptExecuteFunction(%this, %a,%b) {return %a SPC %b;}new ScriptObject(TestConExec);\r\n", false, "testExecute");
U32 startStackPos = CSTK.mStackPos;
U32 startStringStackPos = STR.mStart;
U32 startStackFrame = CSTK.mFrame;
SimObject *testObject = NULL;
Sim::findObject("TestConExec", testObject);
EXPECT_TRUE(testObject != NULL)
<< "TestConExec object should exist";
// const char* versions of execute should maintain stack
const char *argv[] = {"testScriptExecuteFunction", "1", "2"};
const char *argvObject[] = {"testScriptExecuteFunction", "", "1", "2"};
const char *returnValue = Con::execute(3, argv);
EXPECT_TRUE(dStricmp(returnValue, "1 2") == 0) <<
"execute should return 1 2";
EXPECT_TRUE(CSTK.mStackPos == startStackPos) <<
"execute should restore stack";
returnValue = Con::execute(testObject, 4, argvObject);
EXPECT_TRUE(dStricmp(returnValue, "1 2") == 0) <<
"execute should return 1 2";
EXPECT_TRUE(CSTK.mStackPos == startStackPos) <<
"execute should restore stack";
// ConsoleValueRef versions of execute should not restore stack
CSTK.pushFrame();
STR.pushFrame();
ConsoleValue valueArg[4];
ConsoleValueRef refArg[4];
ConsoleValue valueArgObject[4];
ConsoleValueRef refArgObject[4];
for (U32 i=0; i<4; i++)
{
refArg[i].value = &valueArg[i];
refArgObject[i].value = &valueArgObject[i];
valueArgObject[i].init();
valueArg[i].init();
}
refArg[0] = "testScriptExecuteFunction";
refArg[1] = "1";
refArg[2] = "2";
refArgObject[0] = "testScriptExecuteFunction";
refArgObject[2] = "1";
refArgObject[3] = "2";
returnValue = Con::execute(3, refArg);
EXPECT_TRUE(dStricmp(returnValue, "1 2") == 0) <<
"execute should return 1 2";
EXPECT_TRUE(CSTK.mStackPos == startStackPos) <<
"execute should restore stack";
CSTK.popFrame();
STR.popFrame();
CSTK.pushFrame();
STR.pushFrame();
returnValue = Con::execute(testObject, 4, refArgObject);
EXPECT_TRUE(dStricmp(returnValue, "1 2") == 0) <<
"execute should return 1 2";
EXPECT_TRUE(CSTK.mStackPos == startStackPos) <<
"execute should restore stack";
CSTK.popFrame();
STR.popFrame();
}
static U32 gConsoleStackFrame = 0;
ConsoleFunction(testConsoleStackFrame, S32, 1, 1, "")
{
gConsoleStackFrame = CSTK.mFrame;
return (U32)Con::executef("testScriptEvalFunction"); // execute a sub function which manipulates the stack
}
TEST(Con, evaluate)
{
U32 startStackPos = CSTK.mStackPos;
U32 startStringStackPos = STR.mStart;
S32 returnValue = Con::evaluate("function testScriptEvalFunction() {return \"1\"@\"2\"@\"3\";}\nreturn testConsoleStackFrame();", false, "testEvaluate");
U32 frame = CSTK.mFrame;
EXPECT_TRUE(returnValue == 123) <<
"Evaluate should return 123";
EXPECT_TRUE(gConsoleStackFrame == (frame+2)) <<
"Console stack frame inside function should be +2";
EXPECT_TRUE(CSTK.mFrame == frame) <<
"Console stack frame outside function should be the same as before";
EXPECT_TRUE(STR.mStart == startStringStackPos) <<
"Console string stack should not be changed";
EXPECT_TRUE(CSTK.mStackPos == startStackPos) <<
"Console stack should not be changed";
}
#endif

View file

@ -0,0 +1,150 @@
#ifdef TORQUE_TESTS_ENABLED
#include "testing/unitTesting.h"
#include "platform/platform.h"
#include "console/simBase.h"
#include "console/consoleTypes.h"
#include "console/simBase.h"
#include "console/engineAPI.h"
#include "math/mMath.h"
TEST(EngineAPI, EngineMarshallData)
{
// Reserve some values
ConsoleValue values[16];
ConsoleValueRef refValues[16];
for (U32 i=0; i<16; i++)
{
values[i].init();
refValues[i].value = &values[i];
}
// Basic string casting...
SimObject *foo = new SimObject();
foo->registerObject();
const char *value = EngineMarshallData(foo);
EXPECT_TRUE(dStricmp(value, foo->getIdString()) == 0)
<< "SimObject should be casted to its ID";
U32 unsignedNumber = 123;
S32 signedNumber = -123;
value = EngineMarshallData(unsignedNumber);
EXPECT_TRUE(dStricmp(value, "123") == 0)
<< "Integer should be converted to 123";
value = EngineMarshallData(signedNumber);
EXPECT_TRUE(dStricmp(value, "-123") == 0)
<< "Integer should be converted to -123";
bool boolValue = true;
value = EngineMarshallData(boolValue);
EXPECT_TRUE(dStricmp(value, "1") == 0)
<< "Bool should be converted to 1";
Point3F point(1,2,3);
value = EngineMarshallData(point);
EXPECT_TRUE(dStricmp(value, "1 2 3") == 0)
<< "Point3F should be converted to 1 2 3";
F32 floatValue = 1.23f;
value = EngineMarshallData(floatValue);
EXPECT_TRUE(dStricmp(value, "1.23") == 0)
<< "F32 should be converted to 1.23";
// Argv based casting
S32 argc = 0;
EngineMarshallData(foo, argc, refValues);
EngineMarshallData((const SimObject*)foo, argc, refValues);
EngineMarshallData(point, argc, refValues);
EngineMarshallData(unsignedNumber, argc, refValues);
EngineMarshallData(signedNumber, argc, refValues);
EngineMarshallData(boolValue, argc, refValues);
EngineMarshallData(floatValue, argc, refValues);
EXPECT_TRUE(argc == 7)
<< "7 args should have been set";
EXPECT_TRUE(values[0].type == ConsoleValue::TypeInternalInt && values[0].getSignedIntValue() == foo->getId())
<< "1st arg should be foo's id";
EXPECT_TRUE(values[1].type == ConsoleValue::TypeInternalInt && values[1].getSignedIntValue() == foo->getId())
<< "2nd arg should be foo's id";
EXPECT_TRUE(values[2].type == ConsoleValue::TypeInternalString && dStricmp(values[2].getStringValue(), "1 2 3") == 0)
<< "3rd arg should be 1 2 3";
EXPECT_TRUE(values[3].type == ConsoleValue::TypeInternalFloat && values[3].getSignedIntValue() == 123)
<< "4th arg should be 123";
EXPECT_TRUE(values[4].type == ConsoleValue::TypeInternalFloat && values[4].getSignedIntValue() == -123)
<< "5th arg should be -123";
EXPECT_TRUE(values[5].type == ConsoleValue::TypeInternalFloat && values[5].getBoolValue() == true)
<< "6th arg should be -123";
EXPECT_TRUE(values[6].type == ConsoleValue::TypeInternalFloat && mRound(values[6].getFloatValue() * 100) == 123)
<< "7th arg should be 1.23";
foo->deleteObject();
}
TEST(EngineAPI, EngineUnMarshallData)
{
SimObject *foo = new SimObject();
foo->registerObject();
SimObject *testFoo = EngineUnmarshallData<SimObject*>()(foo->getIdString());
EXPECT_TRUE(foo == testFoo)
<< "Unmarshalling foo's id should return foo";
testFoo = EngineUnmarshallData<SimObject*>()("ShouldNotExist_Really123");
EXPECT_TRUE(testFoo == NULL)
<< "Unmarshalling a bad object should return NULL";
foo->deleteObject();
}
TEST(EngineAPI, _EngineConsoleCallbackHelper)
{
Con::evaluate("if (isObject(TestConExec)) {\r\nTestConExec.delete();\r\n}\r\nfunction testExecutef(%a,%b,%c,%d,%e,%f,%g,%h,%i,%j,%k){return %a SPC %b SPC %c SPC %d SPC %e SPC %f SPC %g SPC %h SPC %i SPC %j SPC %k;}\r\nfunction TestConExec::testThisFunction(%this,%a,%b,%c,%d,%e,%f,%g,%h,%i,%j){ return %a SPC %b SPC %c SPC %d SPC %e SPC %f SPC %g SPC %h SPC %i SPC %j;}\r\nnew ScriptObject(TestConExec);\r\n", false, "test");
SimObject *testObject = NULL;
Sim::findObject("TestConExec", testObject);
_EngineConsoleCallbackHelper helper("testExecutef", NULL);
const char *returnValue = helper.call<const char*>("a", "b", "c");
EXPECT_TRUE(dStricmp(returnValue, "a b c ") == 0) <<
"All values should be printed in the correct order";
_EngineConsoleCallbackHelper objectHelper("testThisFunction", testObject);
returnValue = helper.call<const char*>("a", "b", "c");
EXPECT_TRUE(dStricmp(returnValue, "a b c ") == 0) <<
"All values should be printed in the correct order";
}
// NOTE: this is also indirectly tested by the executef tests
TEST(EngineAPI, _EngineConsoleExecCallbackHelper)
{
Con::evaluate("if (isObject(TestConExec)) {\r\nTestConExec.delete();\r\n}\r\nfunction testExecutef(%a,%b,%c,%d,%e,%f,%g,%h,%i,%j,%k){return %a SPC %b SPC %c SPC %d SPC %e SPC %f SPC %g SPC %h SPC %i SPC %j SPC %k;}\r\nfunction TestConExec::testThisFunction(%this,%a,%b,%c,%d,%e,%f,%g,%h,%i,%j){ return %a SPC %b SPC %c SPC %d SPC %e SPC %f SPC %g SPC %h SPC %i SPC %j;}\r\nnew ScriptObject(TestConExec);\r\n", false, "test");
SimObject *testObject = NULL;
Sim::findObject("TestConExec", testObject);
_EngineConsoleExecCallbackHelper<const char*> helper("testExecutef");
const char *returnValue = helper.call<const char*>("a", "b", "c");
EXPECT_TRUE(dStricmp(returnValue, "a b c ") == 0) <<
"All values should be printed in the correct order";
_EngineConsoleExecCallbackHelper<SimObject*> objectHelper(testObject);
returnValue = objectHelper.call<const char*>("testThisFunction", "a", "b", "c");
EXPECT_TRUE(dStricmp(returnValue, "a b c ") == 0) <<
"All values should be printed in the correct order";
}
#endif

View file

@ -101,7 +101,7 @@ void Point3NormalizeValidator::validateType(SimObject *object, void *typePtr)
namespace CommonValidators
{
FRangeValidator PositiveFloat(0.0f, F32_MAX);
FRangeValidator PositiveNonZeroFloat(F32( POINT_EPSILON ) , F32_MAX);
FRangeValidator PositiveNonZeroFloat((F32)POINT_EPSILON, F32_MAX);
FRangeValidator NormalizedFloat(0.0f, 1.0f);
Point3NormalizeValidator NormalizedPoint3(1.0f);
};