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