slang_rs_reflection.cpp revision 462aefd62cc646d2ff753c1d003ef3cd7bbea262
1#include "slang_rs_context.hpp" 2#include "slang_rs_export_var.hpp" 3#include "slang_rs_reflection.hpp" 4#include "slang_rs_export_func.hpp" 5 6#include <ctype.h> 7 8#include <utility> 9#include <cstdarg> 10 11using std::make_pair; 12using std::endl; 13 14 15#define RS_SCRIPT_CLASS_NAME_PREFIX "ScriptC_" 16#define RS_SCRIPT_CLASS_SUPER_CLASS_NAME "ScriptC" 17 18#define RS_TYPE_CLASS_NAME_PREFIX "ScriptField_" 19#define RS_TYPE_CLASS_SUPER_CLASS_NAME "android.renderscript.Script.FieldBase" 20 21#define RS_TYPE_ITEM_CLASS_NAME "Item" 22 23#define RS_TYPE_ITEM_BUFFER_NAME "mItemArray" 24#define RS_TYPE_ITEM_BUFFER_PACKER_NAME "mIOBuffer" 25 26#define RS_EXPORT_VAR_INDEX_PREFIX "mExportVarIdx_" 27#define RS_EXPORT_VAR_PREFIX "mExportVar_" 28 29#define RS_EXPORT_FUNC_INDEX_PREFIX "mExportFuncIdx_" 30 31#define RS_EXPORT_VAR_ALLOCATION_PREFIX "mAlloction_" 32#define RS_EXPORT_VAR_DATA_STORAGE_PREFIX "mData_" 33 34namespace slang { 35 36/* Some utility function using internal in RSReflection */ 37static bool GetFileNameWithoutExtension(const std::string& FileName, std::string& OutFileName) { 38 OutFileName.clear(); 39 40 if(FileName.empty() || (FileName == "-")) 41 return true; 42 43 /* find last component in given path */ 44 size_t SlashPos = FileName.find_last_of("/\\"); 45 46 if((SlashPos != std::string::npos) && ((SlashPos + 1) < FileName.length())) 47 OutFileName = FileName.substr(SlashPos + 1); 48 else 49 OutFileName = FileName; 50 51 size_t DotPos = OutFileName.find_first_of('.'); 52 if(DotPos != std::string::npos) 53 OutFileName.erase(DotPos); 54 55 return true; 56} 57 58static const char* GetPrimitiveTypeName(const RSExportPrimitiveType* EPT) { 59 static const char* PrimitiveTypeJavaNameMap[] = { 60 "", 61 "", 62 "float", /* RSExportPrimitiveType::DataTypeFloat32 */ 63 "double", /* RSExportPrimitiveType::DataTypeFloat64 */ 64 "byte", /* RSExportPrimitiveType::DataTypeSigned8 */ 65 "short", /* RSExportPrimitiveType::DataTypeSigned16 */ 66 "int", /* RSExportPrimitiveType::DataTypeSigned32 */ 67 "long", /* RSExportPrimitiveType::DataTypeSigned64 */ 68 "byte", /* RSExportPrimitiveType::DataTypeUnsigned8 */ 69 "short", /* RSExportPrimitiveType::DataTypeUnsigned16 */ 70 "int", /* RSExportPrimitiveType::DataTypeUnsigned32 */ 71 "long", /* RSExportPrimitiveType::DataTypeUnsigned64 */ 72 73 "short", /* RSExportPrimitiveType::DataTypeUnsigned565 */ 74 "short", /* RSExportPrimitiveType::DataTypeUnsigned5551 */ 75 "short", /* RSExportPrimitiveType::DataTypeUnsigned4444 */ 76 77 "Element", /* RSExportPrimitiveType::DataTypeRSElement */ 78 "Type", /* RSExportPrimitiveType::DataTypeRSType */ 79 "Allocation", /* RSExportPrimitiveType::DataTypeRSAllocation */ 80 "Sampler", /* RSExportPrimitiveType::DataTypeRSSampler */ 81 "Script", /* RSExportPrimitiveType::DataTypeRSScript */ 82 "SimpleMesh", /* RSExportPrimitiveType::DataTypeRSSimpleMesh */ 83 "ProgramFragment", /* RSExportPrimitiveType::DataTypeRSProgramFragment */ 84 "ProgramVertex", /* RSExportPrimitiveType::DataTypeRSProgramVertex */ 85 "ProgramRaster", /* RSExportPrimitiveType::DataTypeRSProgramRaster */ 86 "ProgramStore", /* RSExportPrimitiveType::DataTypeRSProgramStore */ 87 }; 88 89 if((EPT->getType() >= 0) && (EPT->getType() < (sizeof(PrimitiveTypeJavaNameMap) / sizeof(const char*)))) 90 return PrimitiveTypeJavaNameMap[ EPT->getType() ]; 91 92 assert(false && "GetPrimitiveTypeName : Unknown primitive data type"); 93 return NULL; 94} 95 96static const char* GetVectorTypeName(const RSExportVectorType* EVT) { 97 static const char* VectorTypeJavaNameMap[][3] = { 98 /* 0 */ { "Byte2", "Byte3", "Byte4" }, 99 /* 1 */ { "Short2", "Short3", "Short4" }, 100 /* 2 */ { "Int2", "Int3", "Int4" }, 101 /* 3 */ { "Float2", "Float3", "Float4" }, 102 }; 103 104 const char** BaseElement; 105 106 switch(EVT->getType()) { 107 case RSExportPrimitiveType::DataTypeSigned8: 108 case RSExportPrimitiveType::DataTypeUnsigned8: 109 BaseElement = VectorTypeJavaNameMap[0]; 110 break; 111 112 case RSExportPrimitiveType::DataTypeSigned16: 113 case RSExportPrimitiveType::DataTypeUnsigned16: 114 BaseElement = VectorTypeJavaNameMap[1]; 115 break; 116 117 case RSExportPrimitiveType::DataTypeSigned32: 118 case RSExportPrimitiveType::DataTypeUnsigned32: 119 BaseElement = VectorTypeJavaNameMap[2]; 120 break; 121 122 case RSExportPrimitiveType::DataTypeFloat32: 123 BaseElement = VectorTypeJavaNameMap[3]; 124 break; 125 126 default: 127 assert(false && "RSReflection::genElementTypeName : Unsupported vector element data type"); 128 break; 129 } 130 131 assert((EVT->getNumElement() > 1) && (EVT->getNumElement() <= 4) && "Number of element in vector type is invalid"); 132 133 return BaseElement[EVT->getNumElement() - 2]; 134} 135 136static const char* GetPackerAPIName(const RSExportPrimitiveType* EPT) { 137 static const char* PrimitiveTypePackerAPINameMap[] = { 138 "", 139 "", 140 "addF32", /* RSExportPrimitiveType::DataTypeFloat32 */ 141 "addF64", /* RSExportPrimitiveType::DataTypeFloat64 */ 142 "addI8", /* RSExportPrimitiveType::DataTypeSigned8 */ 143 "addI16", /* RSExportPrimitiveType::DataTypeSigned16 */ 144 "addI32", /* RSExportPrimitiveType::DataTypeSigned32 */ 145 "addI64", /* RSExportPrimitiveType::DataTypeSigned64 */ 146 "addU8", /* RSExportPrimitiveType::DataTypeUnsigned8 */ 147 "addU16", /* RSExportPrimitiveType::DataTypeUnsigned16 */ 148 "addU32", /* RSExportPrimitiveType::DataTypeUnsigned32 */ 149 "addU64", /* RSExportPrimitiveType::DataTypeUnsigned64 */ 150 151 "addU16", /* RSExportPrimitiveType::DataTypeUnsigned565 */ 152 "addU16", /* RSExportPrimitiveType::DataTypeUnsigned5551 */ 153 "addU16", /* RSExportPrimitiveType::DataTypeUnsigned4444 */ 154 155 "addObj", /* RSExportPrimitiveType::DataTypeRSElement */ 156 "addObj", /* RSExportPrimitiveType::DataTypeRSType */ 157 "addObj", /* RSExportPrimitiveType::DataTypeRSAllocation */ 158 "addObj", /* RSExportPrimitiveType::DataTypeRSSampler */ 159 "addObj", /* RSExportPrimitiveType::DataTypeRSScript */ 160 "addObj", /* RSExportPrimitiveType::DataTypeRSSimpleMesh */ 161 "addObj", /* RSExportPrimitiveType::DataTypeRSProgramFragment */ 162 "addObj", /* RSExportPrimitiveType::DataTypeRSProgramVertex */ 163 "addObj", /* RSExportPrimitiveType::DataTypeRSProgramRaster */ 164 "addObj", /* RSExportPrimitiveType::DataTypeRSProgramStore */ 165 }; 166 167 if((EPT->getType() >= 0) && (EPT->getType() < (sizeof(PrimitiveTypePackerAPINameMap) / sizeof(const char*)))) 168 return PrimitiveTypePackerAPINameMap[ EPT->getType() ]; 169 170 assert(false && "GetPackerAPIName : Unknown primitive data type"); 171 return NULL; 172} 173 174static std::string GetTypeName(const RSExportType* ET) { 175 switch(ET->getClass()) { 176 case RSExportType::ExportClassPrimitive: 177 return GetPrimitiveTypeName(static_cast<const RSExportPrimitiveType*>(ET)); 178 break; 179 180 case RSExportType::ExportClassPointer: 181 { 182 const RSExportType* PointeeType = static_cast<const RSExportPointerType*>(ET)->getPointeeType(); 183 184 if(PointeeType->getClass() != RSExportType::ExportClassRecord) 185 return "Allocation"; 186 else 187 return RS_TYPE_CLASS_NAME_PREFIX + PointeeType->getName(); 188 } 189 break; 190 191 case RSExportType::ExportClassVector: 192 return GetVectorTypeName(static_cast<const RSExportVectorType*>(ET)); 193 break; 194 195 case RSExportType::ExportClassRecord: 196 return RS_TYPE_CLASS_NAME_PREFIX + ET->getName() + "."RS_TYPE_ITEM_CLASS_NAME; 197 break; 198 199 default: 200 assert(false && "Unknown class of type"); 201 break; 202 } 203 204 return ""; 205} 206 207static const char* GetBuiltinElementConstruct(const RSExportType* ET) { 208 if(ET->getClass() == RSExportType::ExportClassPrimitive) { 209 const RSExportPrimitiveType* EPT = static_cast<const RSExportPrimitiveType*>(ET); 210 if(EPT->getKind() == RSExportPrimitiveType::DataKindUser) { 211 static const char* PrimitiveBuiltinElementConstructMap[] = { 212 NULL, 213 NULL, 214 "USER_F32", /* RSExportPrimitiveType::DataTypeFloat32 */ 215 NULL, /* RSExportPrimitiveType::DataTypeFloat64 */ 216 "USER_I8", /* RSExportPrimitiveType::DataTypeSigned8 */ 217 NULL, /* RSExportPrimitiveType::DataTypeSigned16 */ 218 "USER_I32", /* RSExportPrimitiveType::DataTypeSigned32 */ 219 NULL, /* RSExportPrimitiveType::DataTypeSigned64 */ 220 "USER_U8", /* RSExportPrimitiveType::DataTypeUnsigned8 */ 221 NULL, /* RSExportPrimitiveType::DataTypeUnsigned16 */ 222 "USER_U32", /* RSExportPrimitiveType::DataTypeUnsigned32 */ 223 NULL, /* RSExportPrimitiveType::DataTypeUnsigned64 */ 224 225 NULL, /* RSExportPrimitiveType::DataTypeUnsigned565 */ 226 NULL, /* RSExportPrimitiveType::DataTypeUnsigned5551 */ 227 NULL, /* RSExportPrimitiveType::DataTypeUnsigned4444 */ 228 229 "USER_ELEMENT", /* RSExportPrimitiveType::DataTypeRSElement */ 230 "USER_TYPE", /* RSExportPrimitiveType::DataTypeRSType */ 231 "USER_ALLOCATION", /* RSExportPrimitiveType::DataTypeRSAllocation */ 232 "USER_SAMPLER", /* RSExportPrimitiveType::DataTypeRSSampler */ 233 "USER_SCRIPT", /* RSExportPrimitiveType::DataTypeRSScript */ 234 "USER_MESH", /* RSExportPrimitiveType::DataTypeRSSimpleMesh */ 235 "USER_PROGRAM_FRAGMENT", /* RSExportPrimitiveType::DataTypeRSProgramFragment */ 236 "USER_PROGRAM_VERTEX", /* RSExportPrimitiveType::DataTypeRSProgramVertex */ 237 "USER_PROGRAM_RASTER", /* RSExportPrimitiveType::DataTypeRSProgramRaster */ 238 "USER_PROGRAM_STORE", /* RSExportPrimitiveType::DataTypeRSProgramStore */ 239 }; 240 241 if((EPT->getType() >= 0) && (EPT->getType() < (sizeof(PrimitiveBuiltinElementConstructMap) / sizeof(const char*)))) 242 return PrimitiveBuiltinElementConstructMap[ EPT->getType() ]; 243 } else if(EPT->getKind() == RSExportPrimitiveType::DataKindPixelA) { 244 if(EPT->getType() == RSExportPrimitiveType::DataTypeUnsigned8) 245 return "A_8"; 246 } else if(EPT->getKind() == RSExportPrimitiveType::DataKindPixelRGB) { 247 if(EPT->getType() == RSExportPrimitiveType::DataTypeUnsigned565) 248 return "RGB_565"; 249 else if(EPT->getType() == RSExportPrimitiveType::DataTypeUnsigned8) 250 return "RGB_888"; 251 } else if(EPT->getKind() == RSExportPrimitiveType::DataKindPixelRGBA) { 252 if(EPT->getType() == RSExportPrimitiveType::DataTypeUnsigned5551) 253 return "RGB_5551"; 254 else if(EPT->getType() == RSExportPrimitiveType::DataTypeUnsigned4444) 255 return "RGB_4444"; 256 else if(EPT->getType() == RSExportPrimitiveType::DataTypeUnsigned8) 257 return "RGB_8888"; 258 } else if(EPT->getKind() == RSExportPrimitiveType::DataKindIndex) { 259 if(EPT->getType() == RSExportPrimitiveType::DataTypeUnsigned16) 260 return "INDEX_16"; 261 } 262 } else if(ET->getClass() == RSExportType::ExportClassVector) { 263 const RSExportVectorType* EVT = static_cast<const RSExportVectorType*>(ET); 264 if(EVT->getKind() == RSExportPrimitiveType::DataKindPosition) { 265 if(EVT->getType() == RSExportPrimitiveType::DataTypeFloat32) { 266 if(EVT->getNumElement() == 2) 267 return "ATTRIB_POSITION_2"; 268 else if(EVT->getNumElement() == 3) 269 return "ATTRIB_POSITION_3"; 270 } 271 } else if(EVT->getKind() == RSExportPrimitiveType::DataKindTexture) { 272 if(EVT->getType() == RSExportPrimitiveType::DataTypeFloat32) { 273 if(EVT->getNumElement() == 2) 274 return "ATTRIB_TEXTURE_2"; 275 } 276 } else if(EVT->getKind() == RSExportPrimitiveType::DataKindNormal) { 277 if(EVT->getType() == RSExportPrimitiveType::DataTypeFloat32) { 278 if(EVT->getNumElement() == 3) 279 return "ATTRIB_NORMAL_3"; 280 } 281 } else if(EVT->getKind() == RSExportPrimitiveType::DataKindColor) { 282 if(EVT->getType() == RSExportPrimitiveType::DataTypeFloat32) { 283 if(EVT->getNumElement() == 4) 284 return "ATTRIB_COLOR_F32_4"; 285 } else if(EVT->getType() == RSExportPrimitiveType::DataTypeUnsigned8) { 286 if(EVT->getNumElement() == 4) 287 return "ATTRIB_COLOR_U8_4"; 288 } 289 } 290 } else if(ET->getClass() == RSExportType::ExportClassPointer) { 291 return "USER_U32"; /* tread pointer type variable as unsigned int (TODO: this is target dependent) */ 292 } 293 294 return NULL; 295} 296 297static const char* GetElementDataKindName(RSExportPrimitiveType::DataKind DK) { 298 static const char* ElementDataKindNameMap[] = { 299 "Element.DataKind.USER", /* RSExportPrimitiveType::DataKindUser */ 300 "Element.DataKind.COLOR", /* RSExportPrimitiveType::DataKindColor */ 301 "Element.DataKind.POSITION", /* RSExportPrimitiveType::DataKindPosition */ 302 "Element.DataKind.TEXTURE", /* RSExportPrimitiveType::DataKindTexture */ 303 "Element.DataKind.NORMAL", /* RSExportPrimitiveType::DataKindNormal */ 304 "Element.DataKind.INDEX", /* RSExportPrimitiveType::DataKindIndex */ 305 "Element.DataKind.POINT_SIZE", /* RSExportPrimitiveType::DataKindPointSize */ 306 "Element.DataKind.PIXEL_L", /* RSExportPrimitiveType::DataKindPixelL */ 307 "Element.DataKind.PIXEL_A", /* RSExportPrimitiveType::DataKindPixelA */ 308 "Element.DataKind.PIXEL_LA", /* RSExportPrimitiveType::DataKindPixelLA */ 309 "Element.DataKind.PIXEL_RGB", /* RSExportPrimitiveType::DataKindPixelRGB */ 310 "Element.DataKind.PIXEL_RGBA", /* RSExportPrimitiveType::DataKindPixelRGBA */ 311 }; 312 313 if((DK >= 0) && (DK < (sizeof(ElementDataKindNameMap) / sizeof(const char*)))) 314 return ElementDataKindNameMap[ DK ]; 315 else 316 return NULL; 317} 318 319static const char* GetElementDataTypeName(RSExportPrimitiveType::DataType DT) { 320 static const char* ElementDataTypeNameMap[] = { 321 NULL, 322 NULL, 323 "Element.DataType.FLOAT_32", /* RSExportPrimitiveType::DataTypeFloat32 */ 324 NULL, /* RSExportPrimitiveType::DataTypeFloat64 */ 325 "Element.DataType.SIGNED_8", /* RSExportPrimitiveType::DataTypeSigned8 */ 326 "Element.DataType.SIGNED_16", /* RSExportPrimitiveType::DataTypeSigned16 */ 327 "Element.DataType.SIGNED_32", /* RSExportPrimitiveType::DataTypeSigned32 */ 328 NULL, /* RSExportPrimitiveType::DataTypeSigned64 */ 329 "Element.DataType.UNSIGNED_8", /* RSExportPrimitiveType::DataTypeUnsigned8 */ 330 "Element.DataType.UNSIGNED_16", /* RSExportPrimitiveType::DataTypeUnsigned16 */ 331 "Element.DataType.UNSIGNED_32", /* RSExportPrimitiveType::DataTypeUnsigned32 */ 332 NULL, /* RSExportPrimitiveType::DataTypeUnsigned64 */ 333 334 "Element.DataType.UNSIGNED_5_6_5", /* RSExportPrimitiveType::DataTypeUnsigned565 */ 335 "Element.DataType.UNSIGNED_5_5_5_1", /* RSExportPrimitiveType::DataTypeUnsigned5551 */ 336 "Element.DataType.UNSIGNED_4_4_4_4", /* RSExportPrimitiveType::DataTypeUnsigned4444 */ 337 338 "Element.DataType.RS_ELEMENT", /* RSExportPrimitiveType::DataTypeRSElement */ 339 "Element.DataType.RS_TYPE", /* RSExportPrimitiveType::DataTypeRSType */ 340 "Element.DataType.RS_ALLOCATION", /* RSExportPrimitiveType::DataTypeRSAllocation */ 341 "Element.DataType.RS_SAMPLER", /* RSExportPrimitiveType::DataTypeRSSampler */ 342 "Element.DataType.RS_SCRIPT", /* RSExportPrimitiveType::DataTypeRSScript */ 343 "Element.DataType.RS_MESH", /* RSExportPrimitiveType::DataTypeRSSimpleMesh */ 344 "Element.DataType.RS_PROGRAM_FRAGMENT", /* RSExportPrimitiveType::DataTypeRSProgramFragment */ 345 "Element.DataType.RS_PROGRAM_VERTEX", /* RSExportPrimitiveType::DataTypeRSProgramVertex */ 346 "Element.DataType.RS_PROGRAM_RASTER", /* RSExportPrimitiveType::DataTypeRSProgramRaster */ 347 "Element.DataType.RS_PROGRAM_STORE", /* RSExportPrimitiveType::DataTypeRSProgramStore */ 348 }; 349 350 if((DT >= 0) && (DT < (sizeof(ElementDataTypeNameMap) / sizeof(const char*)))) 351 return ElementDataTypeNameMap[ DT ]; 352 else 353 return NULL; 354} 355 356/****************************** Methods to generate script class ******************************/ 357bool RSReflection::genScriptClass(Context& C, const std::string& ClassName, std::string& ErrorMsg) { 358 if(!C.startClass(Context::AM_Public, false, ClassName, RS_SCRIPT_CLASS_SUPER_CLASS_NAME, ErrorMsg)) 359 return false; 360 361 genScriptClassConstructor(C); 362 363 /* Reflect export variable */ 364 for(RSContext::const_export_var_iterator I = mRSContext->export_vars_begin(); 365 I != mRSContext->export_vars_end(); 366 I++) 367 genExportVariable(C, *I); 368 369 /* Reflect export function */ 370 for(RSContext::const_export_func_iterator I = mRSContext->export_funcs_begin(); 371 I != mRSContext->export_funcs_end(); 372 I++) 373 genExportFunction(C, *I); 374 375 C.endClass(); 376 377 return true; 378} 379 380void RSReflection::genScriptClassConstructor(Context& C) { 381 C.indent() << "// Constructor" << endl; 382 C.startFunction(Context::AM_Public, false, NULL, C.getClassName(), 3, "RenderScript", "rs", 383 "Resources", "resources", 384 "boolean", "isRoot"); 385 /* Call constructor of super class */ 386 C.indent() << "super(rs, resources, R.raw." << C.getResourceId() << ", isRoot);" << endl; 387 C.endFunction(); 388 return; 389} 390 391void RSReflection::genExportVariable(Context& C, const RSExportVar* EV) { 392 const RSExportType* ET = EV->getType(); 393 394 C.indent() << "private final static int "RS_EXPORT_VAR_INDEX_PREFIX << EV->getName() << " = " << C.getNextExportVarSlot() << ";" << endl; 395 396 switch(ET->getClass()) { 397 case RSExportType::ExportClassPrimitive: 398 genPrimitiveTypeExportVariable(C, EV); 399 break; 400 401 case RSExportType::ExportClassPointer: 402 genPointerTypeExportVariable(C, EV); 403 break; 404 405 case RSExportType::ExportClassVector: 406 genVectorTypeExportVariable(C, EV); 407 break; 408 409 case RSExportType::ExportClassRecord: 410 genRecordTypeExportVariable(C, EV); 411 break; 412 413 default: 414 assert(false && "Unknown class of type"); 415 break; 416 } 417 418 return; 419} 420 421void RSReflection::genExportFunction(Context& C, const RSExportFunc* EF) { 422 C.indent() << "private final static int "RS_EXPORT_FUNC_INDEX_PREFIX << EF->getName() << " = " << C.getNextExportFuncSlot() << ";" << endl; 423 424 /* invoke_*() */ 425 Context::ArgTy Args; 426 427 for(RSExportFunc::const_param_iterator I = EF->params_begin(); 428 I != EF->params_end(); 429 I++) 430 { 431 const RSExportFunc::Parameter* P = *I; 432 Args.push_back( make_pair(GetTypeName(P->getType()), P->getName()) ); 433 } 434 435 C.startFunction(Context::AM_Public, false, "void", "invoke_" + EF->getName(), Args); 436 437 if(!EF->hasParam()) { 438 C.indent() << "invoke("RS_EXPORT_FUNC_INDEX_PREFIX << EF->getName() << ");" << endl; 439 } else { 440 const RSExportRecordType* ERT = EF->getParamPacketType(); 441 std::string FieldPackerName = EF->getName() + "_fp"; 442 443 if(genCreateFieldPacker(C, ERT, FieldPackerName.c_str())) 444 genPackVarOfType(C, ERT, NULL, FieldPackerName.c_str()); 445 446 C.indent() << "invokeData("RS_EXPORT_FUNC_INDEX_PREFIX << EF->getName() << ", " << FieldPackerName << ");" << endl; 447 } 448 449 C.endFunction(); 450 return; 451} 452 453void RSReflection::genPrimitiveTypeExportVariable(Context& C, const RSExportVar* EV) { 454 assert((EV->getType()->getClass() == RSExportType::ExportClassPrimitive) && "Variable should be type of primitive here"); 455 456 const RSExportPrimitiveType* EPT = static_cast<const RSExportPrimitiveType*>(EV->getType()); 457 const char* TypeName = GetPrimitiveTypeName(EPT); 458 459 C.indent() << "private " << TypeName << " "RS_EXPORT_VAR_PREFIX << EV->getName() << ";" << endl; 460 461 /* set_*() */ 462 C.startFunction(Context::AM_Public, false, "void", "set_" + EV->getName(), 1, TypeName, "v"); 463 C.indent() << RS_EXPORT_VAR_PREFIX << EV->getName() << " = v;" << endl; 464 465 if(EPT->isRSObjectType()) 466 C.indent() << "setVar("RS_EXPORT_VAR_INDEX_PREFIX << EV->getName() << ", v.getID());" << endl; 467 else 468 C.indent() << "setVar("RS_EXPORT_VAR_INDEX_PREFIX << EV->getName() << ", v);" << endl; 469 470 C.endFunction(); 471 472 genGetExportVariable(C, TypeName, EV->getName()); 473 474 return; 475} 476 477void RSReflection::genPointerTypeExportVariable(Context& C, const RSExportVar* EV) { 478 const RSExportType* ET = EV->getType(); 479 const RSExportType* PointeeType; 480 std::string TypeName; 481 482 assert((ET->getClass() == RSExportType::ExportClassPointer) && "Variable should be type of pointer here"); 483 484 PointeeType = static_cast<const RSExportPointerType*>(ET)->getPointeeType(); 485 TypeName = GetTypeName(ET); 486 487 /* bind_*() */ 488 C.indent() << "private " << TypeName << " "RS_EXPORT_VAR_PREFIX << EV->getName() << ";" << endl; 489 490 C.startFunction(Context::AM_Public, false, "void", "bind_" + EV->getName(), 1, TypeName.c_str(), "v"); 491 492 C.indent() << RS_EXPORT_VAR_PREFIX << EV->getName() << " = v;" << endl; 493 C.indent() << "if(v == null) bindAllocation(null, "RS_EXPORT_VAR_INDEX_PREFIX << EV->getName() << ");" << endl; 494 495 if(PointeeType->getClass() == RSExportType::ExportClassRecord) 496 C.indent() << "else bindAllocation(v.getAllocation(), "RS_EXPORT_VAR_INDEX_PREFIX << EV->getName() << ");" << endl; 497 else 498 C.indent() << "else bindAllocation(v, "RS_EXPORT_VAR_INDEX_PREFIX << EV->getName() << ");" << endl; 499 500 C.endFunction(); 501 502 genGetExportVariable(C, TypeName, EV->getName()); 503 504 return; 505} 506 507void RSReflection::genVectorTypeExportVariable(Context& C, const RSExportVar* EV) { 508 assert((EV->getType()->getClass() == RSExportType::ExportClassVector) && "Variable should be type of vector here"); 509 510 const RSExportVectorType* EVT = static_cast<const RSExportVectorType*>(EV->getType()); 511 const char* TypeName = GetVectorTypeName(EVT); 512 const char* FieldPackerName = "fp"; 513 514 C.indent() << "private " << TypeName << " "RS_EXPORT_VAR_PREFIX << EV->getName() << ";" << endl; 515 516 /* set_*() */ 517 C.startFunction(Context::AM_Public, false, "void", "set_" + EV->getName(), 1, TypeName, "v"); 518 C.indent() << RS_EXPORT_VAR_PREFIX << EV->getName() << " = v;" << endl; 519 520 if(genCreateFieldPacker(C, EVT, FieldPackerName)) 521 genPackVarOfType(C, EVT, "v", FieldPackerName); 522 C.indent() << "setVar("RS_EXPORT_VAR_INDEX_PREFIX << EV->getName() << ", " << FieldPackerName << ");" << endl; 523 524 C.endFunction(); 525 526 genGetExportVariable(C, TypeName, EV->getName()); 527 return; 528} 529 530void RSReflection::genRecordTypeExportVariable(Context& C, const RSExportVar* EV) { 531 assert((EV->getType()->getClass() == RSExportType::ExportClassRecord) && "Variable should be type of struct here"); 532 533 const RSExportRecordType* ERT = static_cast<const RSExportRecordType*>(EV->getType()); 534 std::string TypeName = RS_TYPE_CLASS_NAME_PREFIX + ERT->getName() + "."RS_TYPE_ITEM_CLASS_NAME; 535 const char* FieldPackerName = "fp"; 536 537 C.indent() << "private " << TypeName << " "RS_EXPORT_VAR_PREFIX << EV->getName() << ";" << endl; 538 539 /* set_*() */ 540 C.startFunction(Context::AM_Public, false, "void", "set_" + EV->getName(), 1, TypeName.c_str(), "v"); 541 C.indent() << RS_EXPORT_VAR_PREFIX << EV->getName() << " = v;" << endl; 542 543 if(genCreateFieldPacker(C, ERT, FieldPackerName)) 544 genPackVarOfType(C, ERT, "v", FieldPackerName); 545 C.indent() << "setVar("RS_EXPORT_VAR_INDEX_PREFIX << EV->getName() << ", " << FieldPackerName << ");" << endl; 546 547 C.endFunction(); 548 549 genGetExportVariable(C, TypeName.c_str(), EV->getName()); 550 return; 551} 552 553void RSReflection::genGetExportVariable(Context& C, const std::string& TypeName, const std::string& VarName) { 554 C.startFunction(Context::AM_Public, false, TypeName.c_str(), "get_" + VarName, 0); 555 556 C.indent() << "return "RS_EXPORT_VAR_PREFIX << VarName << ";" << endl; 557 558 C.endFunction(); 559 return; 560} 561 562/****************************** Methods to generate script class /end ******************************/ 563 564bool RSReflection::genCreateFieldPacker(Context& C, const RSExportType* ET, const char* FieldPackerName) { 565 size_t AllocSize = RSExportType::GetTypeAllocSize(ET); 566 if(AllocSize > 0) 567 C.indent() << "FieldPacker " << FieldPackerName << " = new FieldPacker(" << AllocSize << ");" << endl; 568 else 569 return false; 570 return true; 571} 572 573void RSReflection::genPackVarOfType(Context& C, const RSExportType* ET, const char* VarName, const char* FieldPackerName) { 574 switch(ET->getClass()) { 575 case RSExportType::ExportClassPrimitive: 576 case RSExportType::ExportClassVector: 577 C.indent() << FieldPackerName << "." << GetPackerAPIName(static_cast<const RSExportPrimitiveType*>(ET)) << "(" << VarName << ");" << endl; 578 break; 579 580 case RSExportType::ExportClassPointer: 581 { 582 /* Must reflect as type Allocation in Java */ 583 const RSExportType* PointeeType = static_cast<const RSExportPointerType*>(ET)->getPointeeType(); 584 585 if(PointeeType->getClass() != RSExportType::ExportClassRecord) 586 C.indent() << FieldPackerName << ".addU32(" << VarName << ".getPtr());" << endl; 587 else 588 C.indent() << FieldPackerName << ".addU32(" << VarName << ".getAllocation().getPtr());" << endl; 589 } 590 break; 591 592 case RSExportType::ExportClassRecord: 593 { 594 const RSExportRecordType* ERT = static_cast<const RSExportRecordType*>(ET); 595 int Pos = 0; /* relative pos from now on in field packer */ 596 597 for(RSExportRecordType::const_field_iterator I = ERT->fields_begin(); 598 I != ERT->fields_end(); 599 I++) 600 { 601 const RSExportRecordType::Field* F = *I; 602 std::string FieldName; 603 size_t FieldOffset = F->getOffsetInParent(); 604 size_t FieldStoreSize = RSExportType::GetTypeStoreSize(F->getType()); 605 size_t FieldAllocSize = RSExportType::GetTypeAllocSize(F->getType()); 606 607 if(VarName != NULL) 608 FieldName = VarName + ("." + F->getName()); 609 else 610 FieldName = F->getName(); 611 612 if(FieldOffset > Pos) 613 C.indent() << FieldPackerName << ".skip(" << (FieldOffset - Pos) << ");" << endl; 614 615 genPackVarOfType(C, F->getType(), FieldName.c_str(), FieldPackerName); 616 617 if(FieldAllocSize > FieldStoreSize) /* there's padding in the field type */ 618 C.indent() << FieldPackerName << ".skip(" << (FieldAllocSize - FieldStoreSize) << ");" << endl; 619 620 Pos = FieldOffset + FieldAllocSize; 621 } 622 623 /* There maybe some padding after the struct */ 624 size_t Padding = RSExportType::GetTypeAllocSize(ERT) - Pos; 625 if(Padding > 0) 626 C.indent() << FieldPackerName << ".skip(" << Padding << ");" << endl; 627 } 628 break; 629 630 default: 631 assert(false && "Unknown class of type"); 632 break; 633 } 634 635 return; 636} 637 638/****************************** Methods to generate type class ******************************/ 639bool RSReflection::genTypeClass(Context& C, const RSExportRecordType* ERT, std::string& ErrorMsg) { 640 std::string ClassName = RS_TYPE_CLASS_NAME_PREFIX + ERT->getName(); 641 642 if(!C.startClass(Context::AM_Public, false, ClassName, RS_TYPE_CLASS_SUPER_CLASS_NAME, ErrorMsg)) 643 return false; 644 645 if(!genTypeItemClass(C, ERT, ErrorMsg)) 646 return false; 647 648 /* Declare item buffer and item buffer packer */ 649 C.indent() << "private "RS_TYPE_ITEM_CLASS_NAME" "RS_TYPE_ITEM_BUFFER_NAME"[];" << endl; 650 C.indent() << "private FieldPacker "RS_TYPE_ITEM_BUFFER_PACKER_NAME";" << endl; 651 652 genTypeClassConstructor(C, ERT); 653 genTypeClassCopyToArray(C, ERT); 654 genTypeClasSet(C, ERT); 655 genTypeClasCopyAll(C, ERT); 656 657 C.endClass(); 658 659 return true; 660} 661 662bool RSReflection::genTypeItemClass(Context& C, const RSExportRecordType* ERT, std::string& ErrorMsg) { 663 C.indent() << "static public class "RS_TYPE_ITEM_CLASS_NAME; 664 C.startBlock(); 665 666 C.indent() << "public static final int sizeof = " << RSExportType::GetTypeAllocSize(ERT) << ";" << endl; 667 668 /* Member elements */ 669 C.out() << endl; 670 for(RSExportRecordType::const_field_iterator FI = ERT->fields_begin(); 671 FI != ERT->fields_end(); 672 FI++) 673 C.indent() << GetTypeName((*FI)->getType()) << " " << (*FI)->getName() << ";" << endl; 674 675 /* Constructor */ 676 C.out() << endl; 677 C.indent() << RS_TYPE_ITEM_CLASS_NAME"()"; 678 C.startBlock(); 679 680 for(RSExportRecordType::const_field_iterator FI = ERT->fields_begin(); 681 FI != ERT->fields_end(); 682 FI++) 683 { 684 const RSExportRecordType::Field* F = *FI; 685 if((F->getType()->getClass() == RSExportType::ExportClassVector) || (F->getType()->getClass() == RSExportType::ExportClassRecord)) 686 C.indent() << F->getName() << " = new " << GetTypeName(F->getType()) << "();" << endl; 687 } 688 689 C.endBlock(); /* end Constructor */ 690 691 C.endBlock(); /* end Item class */ 692 693 694 return true; 695} 696 697void RSReflection::genTypeClassConstructor(Context& C, const RSExportRecordType* ERT) { 698 const char* RenderScriptVar = "rs"; 699 700 C.startFunction(Context::AM_Public, false, NULL, C.getClassName(), 2, "RenderScript", RenderScriptVar, 701 "int", "count"); 702 703 C.indent() << RS_TYPE_ITEM_BUFFER_NAME" = null;" << endl; 704 C.indent() << RS_TYPE_ITEM_BUFFER_PACKER_NAME" = null;" << endl; 705 706 genBuildElement(C, ERT, "mElement", RenderScriptVar); 707 /* Call init() in super class */ 708 C.indent() << "init(" << RenderScriptVar << ", count);" << endl; 709 C.endFunction(); 710 711 return; 712} 713 714void RSReflection::genTypeClassCopyToArray(Context& C, const RSExportRecordType* ERT) { 715 C.startFunction(Context::AM_Private, false, "void", "copyToArray", 2, RS_TYPE_ITEM_CLASS_NAME, "i", 716 "int", "index"); 717 718 C.indent() << "if ("RS_TYPE_ITEM_BUFFER_PACKER_NAME" == null) "RS_TYPE_ITEM_BUFFER_PACKER_NAME" = new FieldPacker("RS_TYPE_ITEM_CLASS_NAME".sizeof * mType.getX() /* count */);" << endl; 719 C.indent() << RS_TYPE_ITEM_BUFFER_PACKER_NAME".reset(index * "RS_TYPE_ITEM_CLASS_NAME".sizeof);" << endl; 720 721 genPackVarOfType(C, ERT, "i", RS_TYPE_ITEM_BUFFER_PACKER_NAME); 722 723 C.endFunction(); 724 return; 725} 726 727void RSReflection::genTypeClasSet(Context& C, const RSExportRecordType* ERT) { 728 C.startFunction(Context::AM_Public, false, "void", "set", 3, RS_TYPE_ITEM_CLASS_NAME, "i", 729 "int", "index", 730 "boolean", "copyNow"); 731 C.indent() << "if ("RS_TYPE_ITEM_BUFFER_NAME" == null) "RS_TYPE_ITEM_BUFFER_NAME" = new "RS_TYPE_ITEM_CLASS_NAME"[mType.getX() /* count */];" << endl; 732 C.indent() << RS_TYPE_ITEM_BUFFER_NAME"[index] = i;" << endl; 733 734 C.indent() << "if (copyNow) "; 735 C.startBlock(); 736 737 C.indent() << "copyToArray(i, index);" << endl; 738 C.indent() << "mAllocation.subData1D(index * "RS_TYPE_ITEM_CLASS_NAME".sizeof, "RS_TYPE_ITEM_CLASS_NAME".sizeof, "RS_TYPE_ITEM_BUFFER_PACKER_NAME".getData());" << endl; 739 740 C.endBlock(); /* end if (copyNow) */ 741 742 C.endFunction(); 743 return; 744} 745 746void RSReflection::genTypeClasCopyAll(Context& C, const RSExportRecordType* ERT) { 747 C.startFunction(Context::AM_Public, false, "void", "copyAll", 0); 748 749 C.indent() << "for (int ct=0; ct < "RS_TYPE_ITEM_BUFFER_NAME".length; ct++) copyToArray("RS_TYPE_ITEM_BUFFER_NAME"[ct], ct);" << endl; 750 C.indent() << "mAllocation.data("RS_TYPE_ITEM_BUFFER_PACKER_NAME".getData());" << endl; 751 752 C.endFunction(); 753 return; 754} 755 756/****************************** Methods to generate type class /end ******************************/ 757 758/******************** Methods to create Element in Java of given record type ********************/ 759void RSReflection::genBuildElement(Context& C, const RSExportRecordType* ERT, const char* ElementName, const char* RenderScriptVar) { 760 const char* ElementBuilderName = "eb"; 761 762 /* Create element builder */ 763 C.startBlock(true); 764 765 C.indent() << "Element.Builder " << ElementBuilderName << " = new Element.Builder(" << RenderScriptVar << ");" << endl; 766 767 /* eb.add(...) */ 768 genAddElementToElementBuilder(C, ERT, "", ElementBuilderName, RenderScriptVar); 769 770 C.indent() << ElementName << " = " << ElementBuilderName << ".create();" << endl; 771 772 C.endBlock(); 773 return; 774} 775 776#define EB_ADD(x, ...) \ 777 C.indent() << ElementBuilderName << ".add(Element." << x ##__VA_ARGS__ ", \"" << VarName << "\");" << endl 778void RSReflection::genAddElementToElementBuilder(Context& C, const RSExportType* ET, const std::string& VarName, const char* ElementBuilderName, const char* RenderScriptVar) { 779 const char* ElementConstruct = GetBuiltinElementConstruct(ET); 780 if(ElementConstruct != NULL) { 781 EB_ADD(ElementConstruct << "(" << RenderScriptVar << ")"); 782 } else { 783 if((ET->getClass() == RSExportType::ExportClassPrimitive) || (ET->getClass() == RSExportType::ExportClassVector)) { 784 const RSExportPrimitiveType* EPT = static_cast<const RSExportPrimitiveType*>(ET); 785 const char* DataKindName = GetElementDataKindName(EPT->getKind()); 786 const char* DataTypeName = GetElementDataTypeName(EPT->getType()); 787 int Size = (ET->getClass() == RSExportType::ExportClassVector) ? static_cast<const RSExportVectorType*>(ET)->getNumElement() : 1; 788 789 switch(EPT->getKind()) { 790 case RSExportPrimitiveType::DataKindColor: 791 case RSExportPrimitiveType::DataKindPosition: 792 case RSExportPrimitiveType::DataKindTexture: 793 case RSExportPrimitiveType::DataKindNormal: 794 case RSExportPrimitiveType::DataKindPointSize: 795 /* Element.createAttrib() */ 796 EB_ADD("createAttrib(" << RenderScriptVar << ", " << DataTypeName << ", " << DataKindName << ", " << Size << ")"); 797 break; 798 799 case RSExportPrimitiveType::DataKindIndex: 800 /* Element.createIndex() */ 801 EB_ADD("createAttrib(" << RenderScriptVar << ")"); 802 break; 803 804 case RSExportPrimitiveType::DataKindPixelL: 805 case RSExportPrimitiveType::DataKindPixelA: 806 case RSExportPrimitiveType::DataKindPixelLA: 807 case RSExportPrimitiveType::DataKindPixelRGB: 808 case RSExportPrimitiveType::DataKindPixelRGBA: 809 /* Element.createPixel() */ 810 EB_ADD("createVector(" << RenderScriptVar << ", " << DataTypeName << ", " << DataKindName << ")"); 811 break; 812 813 case RSExportPrimitiveType::DataKindUser: 814 default: 815 if(EPT->getClass() == RSExportType::ExportClassPrimitive) 816 /* Element.createUser() */ 817 EB_ADD("createUser(" << RenderScriptVar << ", " << DataTypeName << ")"); 818 else /* (ET->getClass() == RSExportType::ExportClassVector) must hold here */ 819 /* Element.createVector() */ 820 EB_ADD("createVector(" << RenderScriptVar << ", " << DataTypeName << ", " << Size << ")"); 821 break; 822 } 823 } else if(ET->getClass() == RSExportType::ExportClassPointer) { 824 /* Pointer type variable should be resolved in GetBuiltinElementConstruct() */ 825 assert(false && "??"); 826 } else if(ET->getClass() == RSExportType::ExportClassRecord) { 827 /* 828 * Simalar to genPackVarOfType. 829 * 830 * TODO: Generalize these two function such that there's no duplicated codes. 831 */ 832 const RSExportRecordType* ERT = static_cast<const RSExportRecordType*>(ET); 833 int Pos = 0; /* relative pos from now on */ 834 835 for(RSExportRecordType::const_field_iterator I = ERT->fields_begin(); 836 I != ERT->fields_end(); 837 I++) 838 { 839 const RSExportRecordType::Field* F = *I; 840 std::string FieldName; 841 size_t FieldOffset = F->getOffsetInParent(); 842 size_t FieldStoreSize = RSExportType::GetTypeStoreSize(F->getType()); 843 size_t FieldAllocSize = RSExportType::GetTypeAllocSize(F->getType()); 844 845 if(!VarName.empty()) 846 FieldName = VarName + "." + F->getName(); 847 else 848 FieldName = F->getName(); 849 850 /* alignment */ 851 genAddPaddingToElementBuiler(C, (FieldOffset - Pos), ElementBuilderName, RenderScriptVar); 852 853 /* eb.add(...) */ 854 genAddElementToElementBuilder(C, (*I)->getType(), FieldName, ElementBuilderName, RenderScriptVar); 855 856 /* there's padding within the field type */ 857 genAddPaddingToElementBuiler(C, (FieldAllocSize - FieldStoreSize), ElementBuilderName, RenderScriptVar); 858 859 Pos = FieldOffset + FieldAllocSize; 860 } 861 862 /* There maybe some padding after the struct */ 863 genAddPaddingToElementBuiler(C, (RSExportType::GetTypeAllocSize(ERT) - Pos), ElementBuilderName, RenderScriptVar); 864 } else { 865 assert(false && "Unknown class of type"); 866 } 867 } 868} 869 870void RSReflection::genAddPaddingToElementBuiler(Context& C, size_t PaddingSize, const char* ElementBuilderName, const char* RenderScriptVar) { 871 while(PaddingSize > 0) { 872 const std::string& VarName = C.createPaddingField(); 873 if(PaddingSize >= 4) { 874 EB_ADD("USER_U32(" << RenderScriptVar << ")"); 875 PaddingSize -= 4; 876 } else if(PaddingSize >= 2) { 877 EB_ADD("USER_U16(" << RenderScriptVar << ")"); 878 PaddingSize -= 2; 879 } else if(PaddingSize >= 1) { 880 EB_ADD("USER_U8(" << RenderScriptVar << ")"); 881 PaddingSize -= 1; 882 } 883 } 884 return; 885} 886 887#undef EB_ADD 888/******************** Methods to create Element in Java of given record type /end ********************/ 889 890bool RSReflection::reflect(const char* OutputPackageName, const std::string& InputFileName, const std::string& OutputBCFileName) { 891 Context *C = NULL; 892 std::string ResourceId = ""; 893 894 if(!GetFileNameWithoutExtension(OutputBCFileName, ResourceId)) 895 return false; 896 897 if(ResourceId.empty()) 898 ResourceId = "<Resource ID>"; 899 900 if((OutputPackageName == NULL) || (*OutputPackageName == '\0') || strcmp(OutputPackageName, "-") == 0) 901 C = new Context("<Package Name>", ResourceId, true); 902 else 903 C = new Context(OutputPackageName, ResourceId, false); 904 905 if(C != NULL) { 906 std::string ErrorMsg, ScriptClassName; 907 /* class ScriptC_<ScriptName> */ 908 if(!GetFileNameWithoutExtension(InputFileName, ScriptClassName)) 909 return false; 910 911 if(ScriptClassName.empty()) 912 ScriptClassName = "<Input Script Name>"; 913 914 ScriptClassName.at(0) = toupper(ScriptClassName.at(0)); 915 ScriptClassName.insert(0, RS_SCRIPT_CLASS_NAME_PREFIX); 916 917 if(!genScriptClass(*C, ScriptClassName, ErrorMsg)) { 918 std::cerr << "Failed to generate class " << ScriptClassName << " (" << ErrorMsg << ")" << endl; 919 return false; 920 } 921 922 /* class ScriptField_<TypeName> */ 923 for(RSContext::const_export_type_iterator TI = mRSContext->export_types_begin(); 924 TI != mRSContext->export_types_end(); 925 TI++) 926 { 927 const RSExportType* ET = TI->getValue(); 928 929 if(ET->getClass() == RSExportType::ExportClassRecord) { 930 const RSExportRecordType* ERT = static_cast<const RSExportRecordType*>(ET); 931 932 if(!ERT->isArtificial() && !genTypeClass(*C, ERT, ErrorMsg)) { 933 std::cerr << "Failed to generate type class for struct '" << ERT->getName() << "' (" << ErrorMsg << ")" << endl; 934 return false; 935 } 936 } 937 } 938 } 939 940 return true; 941} 942 943/****************************** RSReflection::Context ******************************/ 944const char* const RSReflection::Context::LicenseNote = 945 "/*\n" 946 " * Copyright (C) 2010 The Android Open Source Project\n" 947 " *\n" 948 " * Licensed under the Apache License, Version 2.0 (the \"License\");\n" 949 " * you may not use this file except in compliance with the License.\n" 950 " * You may obtain a copy of the License at\n" 951 " *\n" 952 " * http://www.apache.org/licenses/LICENSE-2.0\n" 953 " *\n" 954 " * Unless required by applicable law or agreed to in writing, software\n" 955 " * distributed under the License is distributed on an \"AS IS\" BASIS,\n" 956 " * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n" 957 " * See the License for the specific language governing permissions and\n" 958 " * limitations under the License.\n" 959 " */\n"; 960 961const char* const RSReflection::Context::Import[] = { 962 /* RenderScript java class */ 963 "android.renderscript.*", 964 /* Import R */ 965 "android.content.res.Resources", 966 /* Import for debugging */ 967 "android.util.Log", 968}; 969 970const char* RSReflection::Context::AccessModifierStr(AccessModifier AM) { 971 switch(AM) { 972 case AM_Public: return "public"; break; 973 case AM_Protected: return "protected"; break; 974 case AM_Private: return "private"; break; 975 default: return ""; break; 976 } 977} 978 979bool RSReflection::Context::startClass(AccessModifier AM, bool IsStatic, const std::string& ClassName, const char* SuperClassName, std::string& ErrorMsg) { 980 if(mVerbose) 981 std::cout << "Generating " << ClassName << ".java ..." << endl; 982 983 /* Open the file */ 984 if(!mUseStdout) { 985 mOF.clear(); 986 mOF.open((ClassName + ".java").c_str()); 987 if(!mOF.good()) { 988 ErrorMsg = "failed to open file '" + ClassName + ".java' for write"; 989 return false; 990 } 991 } 992 993 /* License */ 994 out() << LicenseNote << endl; 995 996 /* Package */ 997 if(!mPackageName.empty()) 998 out() << "package " << mPackageName << ";" << endl; 999 out() << endl; 1000 1001 /* Imports */ 1002 for(int i=0;i<(sizeof(Import)/sizeof(const char*));i++) 1003 out() << "import " << Import[i] << ";" << endl; 1004 out() << endl; 1005 1006 out() << AccessModifierStr(AM) << ((IsStatic) ? " static" : "") << " class " << ClassName; 1007 if(SuperClassName != NULL) 1008 out() << " extends " << SuperClassName; 1009 1010 startBlock(); 1011 1012 mClassName = ClassName; 1013 1014 return true; 1015} 1016 1017void RSReflection::Context::endClass() { 1018 endBlock(); 1019 if(!mUseStdout) 1020 mOF.close(); 1021 clear(); 1022 return; 1023} 1024 1025void RSReflection::Context::startBlock(bool ShouldIndent) { 1026 if(ShouldIndent) 1027 indent() << "{" << endl; 1028 else 1029 out() << " {" << endl; 1030 incIndentLevel(); 1031 return; 1032} 1033 1034void RSReflection::Context::endBlock() { 1035 decIndentLevel(); 1036 indent() << "}" << endl << endl; 1037 return; 1038} 1039 1040void RSReflection::Context::startTypeClass(const std::string& ClassName) { 1041 indent() << "public static class " << ClassName; 1042 startBlock(); 1043 return; 1044} 1045 1046void RSReflection::Context::endTypeClass() { 1047 endBlock(); 1048 return; 1049} 1050 1051void RSReflection::Context::startFunction(AccessModifier AM, bool IsStatic, const char* ReturnType, const std::string& FunctionName, int Argc, ...) { 1052 ArgTy Args; 1053 va_list vl; 1054 va_start(vl, Argc); 1055 1056 for(int i=0;i<Argc;i++) { 1057 const char* ArgType = va_arg(vl, const char*); 1058 const char* ArgName = va_arg(vl, const char*); 1059 1060 Args.push_back( make_pair(ArgType, ArgName) ); 1061 } 1062 va_end(vl); 1063 1064 startFunction(AM, IsStatic, ReturnType, FunctionName, Args); 1065 1066 return; 1067} 1068 1069void RSReflection::Context::startFunction(AccessModifier AM, 1070 bool IsStatic, 1071 const char* ReturnType, 1072 const std::string& FunctionName, 1073 const ArgTy& Args) 1074{ 1075 indent() << AccessModifierStr(AM) << ((IsStatic) ? " static " : " ") << ((ReturnType) ? ReturnType : "") << " " << FunctionName << "("; 1076 1077 bool FirstArg = true; 1078 for(ArgTy::const_iterator I = Args.begin(); 1079 I != Args.end(); 1080 I++) 1081 { 1082 if(!FirstArg) 1083 out() << ", "; 1084 else 1085 FirstArg = false; 1086 1087 out() << I->first << " " << I->second; 1088 } 1089 1090 out() << ")"; 1091 startBlock(); 1092 1093 return; 1094} 1095 1096void RSReflection::Context::endFunction() { 1097 endBlock(); 1098 return; 1099} 1100 1101} /* namespace slang */ 1102