reflection.bmx 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831
  1. Strict
  2. Rem
  3. bbdoc: BASIC/Reflection
  4. End Rem
  5. Module BRL.Reflection
  6. ModuleInfo "Version: 1.02"
  7. ModuleInfo "Author: Mark Sibly"
  8. ModuleInfo "License: zlib/libpng"
  9. ModuleInfo "Copyright: Blitz Research Ltd"
  10. ModuleInfo "Modserver: BRL"
  11. ModuleInfo "History: 1.02 Release"
  12. ModuleInfo "History: Added Brucey's size fix to GetArrayElement()/SetArrayElement()."
  13. ModuleInfo "History: 1.01 Release"
  14. ModuleInfo "History: Fixed NewArray using temp type name"
  15. Import BRL.LinkedList
  16. Import BRL.Map
  17. Import "reflection.cpp"
  18. Private
  19. Extern
  20. Function bbObjectNew:Object( class )
  21. Function bbObjectRegisteredTypes:Int Ptr( count Var )
  22. Function bbArrayNew1D:Object( typeTag:Byte Ptr,length )
  23. Function bbRefArrayClass()
  24. Function bbRefStringClass()
  25. Function bbRefObjectClass()
  26. Function bbRefArrayLength( array:Object, dim:Int = 0 )
  27. Function bbRefArrayTypeTag$( array:Object )
  28. Function bbRefArrayDimensions:Int( array:Object )
  29. Function bbRefArrayCreate:Object( typeTag:Byte Ptr,dims:Int[] )
  30. Function bbRefFieldPtr:Byte Ptr( obj:Object,index )
  31. Function bbRefMethodPtr:Byte Ptr( obj:Object,index )
  32. Function bbRefArrayElementPtr:Byte Ptr( sz,array:Object,index )
  33. Function bbRefGetObject:Object( p:Byte Ptr )
  34. Function bbRefPushObject( p:Byte Ptr,obj:Object )
  35. Function bbRefInitObject( p:Byte Ptr,obj:Object )
  36. Function bbRefAssignObject( p:Byte Ptr,obj:Object )
  37. Function bbRefGetObjectClass( obj:Object )
  38. Function bbRefGetSuperClass( class )
  39. End Extern
  40. Type TClass
  41. Method Compare( with:Object )
  42. Return _class-TClass( with )._class
  43. End Method
  44. Method SetClass:TClass( class )
  45. _class=class
  46. Return Self
  47. End Method
  48. Field _class
  49. End Type
  50. Function _Get:Object( p:Byte Ptr,typeId:TTypeId )
  51. Select typeId
  52. Case ByteTypeId
  53. Return String.FromInt( (Byte Ptr p)[0] )
  54. Case ShortTypeId
  55. Return String.FromInt( (Short Ptr p)[0] )
  56. Case IntTypeId
  57. Return String.FromInt( (Int Ptr p)[0] )
  58. Case LongTypeId
  59. Return String.FromLong( (Long Ptr p)[0] )
  60. Case FloatTypeId
  61. Return String.FromFloat( (Float Ptr p)[0] )
  62. Case DoubleTypeId
  63. Return String.FromDouble( (Double Ptr p)[0] )
  64. Default
  65. Return bbRefGetObject( p )
  66. End Select
  67. End Function
  68. Function _Push:Byte Ptr( sp:Byte Ptr,typeId:TTypeId,value:Object )
  69. Select typeId
  70. Case ByteTypeId,ShortTypeId,IntTypeId
  71. (Int Ptr sp)[0]=value.ToString().ToInt()
  72. Return sp+4
  73. Case LongTypeId
  74. (Long Ptr sp)[0]=value.ToString().ToLong()
  75. Return sp+8
  76. Case FloatTypeId
  77. (Float Ptr sp)[0]=value.ToString().ToFloat()
  78. Return sp+4
  79. Case DoubleTypeId
  80. (Double Ptr sp)[0]=value.ToString().ToDouble()
  81. Return sp+8
  82. Case StringTypeId
  83. If Not value value=""
  84. bbRefPushObject sp,value
  85. Return sp+4
  86. Default
  87. If value
  88. Local c=typeId._class
  89. Local t=bbRefGetObjectClass( value )
  90. While t And t<>c
  91. t=bbRefGetSuperClass( t )
  92. Wend
  93. If Not t Throw "ERROR"
  94. EndIf
  95. bbRefPushObject sp,value
  96. Return sp+4
  97. End Select
  98. End Function
  99. Function _Assign( p:Byte Ptr,typeId:TTypeId,value:Object )
  100. Select typeId
  101. Case ByteTypeId
  102. (Byte Ptr p)[0]=value.ToString().ToInt()
  103. Case ShortTypeId
  104. (Short Ptr p)[0]=value.ToString().ToInt()
  105. Case IntTypeId
  106. (Int Ptr p)[0]=value.ToString().ToInt()
  107. Case LongTypeId
  108. (Long Ptr p)[0]=value.ToString().ToLong()
  109. Case FloatTypeId
  110. (Float Ptr p)[0]=value.ToString().ToFloat()
  111. Case DoubleTypeId
  112. (Double Ptr p)[0]=value.ToString().ToDouble()
  113. Case StringTypeId
  114. If Not value value=""
  115. bbRefAssignObject p,value
  116. Default
  117. If value
  118. Local c=typeId._class
  119. Local t=bbRefGetObjectClass( value )
  120. While t And t<>c
  121. t=bbRefGetSuperClass( t )
  122. Wend
  123. If Not t Throw "ERROR"
  124. EndIf
  125. bbRefAssignObject p,value
  126. End Select
  127. End Function
  128. Function _Call:Object( p:Byte Ptr,typeId:TTypeId,obj:Object,args:Object[],argTypes:TTypeId[] )
  129. Local q[10],sp:Byte Ptr=q
  130. bbRefPushObject sp,obj
  131. sp:+4
  132. If typeId=LongTypeId sp:+8
  133. For Local i=0 Until args.length
  134. If Int Ptr(sp)>=Int Ptr(q)+8 Throw "ERROR"
  135. sp=_Push( sp,argTypes[i],args[i] )
  136. Next
  137. If Int Ptr(sp)>Int Ptr(q)+8 Throw "ERROR"
  138. Select typeId
  139. Case ByteTypeId,ShortTypeId,IntTypeId
  140. Local f(p0,p1,p2,p3,p4,p5,p6,p7)=p
  141. Return String.FromInt( f( q[0],q[1],q[2],q[3],q[4],q[5],q[6],q[7] ) )
  142. Case LongTypeId
  143. Throw "TODO"
  144. Case FloatTypeId
  145. Local f:Float(p0,p1,p2,p3,p4,p5,p6,p7)=p
  146. Return String.FromFloat( f( q[0],q[1],q[2],q[3],q[4],q[5],q[6],q[7] ) )
  147. Case DoubleTypeId
  148. Local f:Double(p0,p1,p2,p3,p4,p5,p6,p7)=p
  149. Return String.FromDouble( f( q[0],q[1],q[2],q[3],q[4],q[5],q[6],q[7] ) )
  150. Default
  151. Local f:Object(p0,p1,p2,p3,p4,p5,p6,p7)=p
  152. Return f( q[0],q[1],q[2],q[3],q[4],q[5],q[6],q[7] )
  153. End Select
  154. End Function
  155. Function TypeTagForId$( id:TTypeId )
  156. If id.ExtendsType( ArrayTypeId )
  157. Return "[]"+TypeTagForId( id.ElementType() )
  158. EndIf
  159. If id.ExtendsType( ObjectTypeId )
  160. Return ":"+id.Name()
  161. EndIf
  162. Select id
  163. Case ByteTypeId Return "b"
  164. Case ShortTypeId Return "s"
  165. Case IntTypeId Return "i"
  166. Case LongTypeId Return "l"
  167. Case FloatTypeId Return "f"
  168. Case DoubleTypeId Return "d"
  169. Case StringTypeId Return "$"
  170. End Select
  171. Throw "ERROR"
  172. End Function
  173. Function TypeIdForTag:TTypeId( ty$ )
  174. If ty.StartsWith( "[" )
  175. Local dims:Int = ty.split(",").length
  176. ty=ty[ty.Find("]")+1..]
  177. Local id:TTypeId = TypeIdForTag( ty )
  178. If id Then
  179. id._arrayType = Null
  180. id=id.ArrayType(dims)
  181. End If
  182. Return id
  183. EndIf
  184. If ty.StartsWith( ":" )
  185. ty=ty[1..]
  186. Local i=ty.FindLast( "." )
  187. If i<>-1 ty=ty[i+1..]
  188. Return TTypeId.ForName( ty )
  189. EndIf
  190. Select ty
  191. Case "b" Return ByteTypeId
  192. Case "s" Return ShortTypeId
  193. Case "i" Return IntTypeId
  194. Case "l" Return LongTypeId
  195. Case "f" Return FloatTypeId
  196. Case "d" Return DoubleTypeId
  197. Case "$" Return StringTypeId
  198. End Select
  199. End Function
  200. Function ExtractMetaData$( meta$,key$ )
  201. If Not key Return meta
  202. Local i=0
  203. While i<meta.length
  204. Local e=meta.Find( "=",i )
  205. If e=-1 Throw "Malformed meta data"
  206. Local k$=meta[i..e],v$
  207. i=e+1
  208. If i<meta.length And meta[i]=Asc("~q")
  209. i:+1
  210. Local e=meta.Find( "~q",i )
  211. If e=-1 Throw "Malformed meta data"
  212. v=meta[i..e]
  213. i=e+1
  214. Else
  215. Local e=meta.Find( " ",i )
  216. If e=-1 e=meta.length
  217. v=meta[i..e]
  218. i=e
  219. EndIf
  220. If k=key Return v
  221. If i<meta.length And meta[i]=Asc(" ") i:+1
  222. Wend
  223. End Function
  224. Public
  225. Rem
  226. bbdoc: Primitive byte type
  227. End Rem
  228. Global ByteTypeId:TTypeId=New TTypeId.Init( "Byte",1 )
  229. Rem
  230. bbdoc: Primitive short type
  231. End Rem
  232. Global ShortTypeId:TTypeId=New TTypeId.Init( "Short",2 )
  233. Rem
  234. bbdoc: Primitive int type
  235. End Rem
  236. Global IntTypeId:TTypeId=New TTypeId.Init( "Int",4 )
  237. Rem
  238. bbdoc: Primitive long type
  239. End Rem
  240. Global LongTypeId:TTypeId=New TTypeId.Init( "Long",8 )
  241. Rem
  242. bbdoc: Primitive float type
  243. End Rem
  244. Global FloatTypeId:TTypeId=New TTypeId.Init( "Float",4 )
  245. Rem
  246. bbdoc: Primitive double type
  247. End Rem
  248. Global DoubleTypeId:TTypeId=New TTypeId.Init( "Double",8 )
  249. Rem
  250. bbdoc: Primitive object type
  251. End Rem
  252. Global ObjectTypeId:TTypeId=New TTypeId.Init( "Object",4,bbRefObjectClass() )
  253. Rem
  254. bbdoc: Primitive string type
  255. End Rem
  256. Global StringTypeId:TTypeId=New TTypeId.Init( "String",4,bbRefStringClass(),ObjectTypeId )
  257. Rem
  258. bbdoc: Primitive array type
  259. End Rem
  260. Global ArrayTypeId:TTypeId=New TTypeId.Init( "Null[]",4,bbRefArrayClass(),ObjectTypeId )
  261. Rem
  262. bbdoc: Type member - field or method.
  263. End Rem
  264. Type TMember
  265. Rem
  266. bbdoc: Get member name
  267. End Rem
  268. Method Name$()
  269. Return _name
  270. End Method
  271. Rem
  272. bbdoc: Get member type
  273. End Rem
  274. Method TypeId:TTypeId()
  275. Return _typeId
  276. End Method
  277. Rem
  278. bbdoc: Get member meta data
  279. End Rem
  280. Method MetaData$( key$="" )
  281. Return ExtractMetaData( _meta,key )
  282. End Method
  283. Field _name$,_typeId:TTypeId,_meta$
  284. End Type
  285. Rem
  286. bbdoc: Type field
  287. End Rem
  288. Type TField Extends TMember
  289. Method Init:TField( name$,typeId:TTypeId,meta$,index )
  290. _name=name
  291. _typeId=typeId
  292. _meta=meta
  293. _index=index
  294. Return Self
  295. End Method
  296. Rem
  297. bbdoc: Get field value
  298. End Rem
  299. Method Get:Object( obj:Object )
  300. Return _Get( bbRefFieldPtr( obj,_index ),_typeId )
  301. End Method
  302. Rem
  303. bbdoc: Get int field value
  304. End Rem
  305. Method GetInt:Int( obj:Object )
  306. Return GetString( obj ).ToInt()
  307. End Method
  308. Rem
  309. bbdoc: Get long field value
  310. End Rem
  311. Method GetLong:Long( obj:Object )
  312. Return GetString( obj ).ToLong()
  313. End Method
  314. Rem
  315. bbdoc: Get float field value
  316. End Rem
  317. Method GetFloat:Float( obj:Object )
  318. Return GetString( obj ).ToFloat()
  319. End Method
  320. Rem
  321. bbdoc: Get double field value
  322. End Rem
  323. Method GetDouble:Double( obj:Object )
  324. Return GetString( obj ).ToDouble()
  325. End Method
  326. Rem
  327. bbdoc: Get string field value
  328. End Rem
  329. Method GetString$( obj:Object )
  330. Return String( Get( obj ) )
  331. End Method
  332. Rem
  333. bbdoc: Set field value
  334. End Rem
  335. Method Set( obj:Object,value:Object )
  336. _Assign bbRefFieldPtr( obj,_index ),_typeId,value
  337. End Method
  338. Rem
  339. bbdoc: Set int field value
  340. End Rem
  341. Method SetInt( obj:Object,value:Int )
  342. SetString obj,String.FromInt( value )
  343. End Method
  344. Rem
  345. bbdoc: Set long field value
  346. End Rem
  347. Method SetLong( obj:Object,value:Long )
  348. SetString obj,String.FromLong( value )
  349. End Method
  350. Rem
  351. bbdoc: Set float field value
  352. End Rem
  353. Method SetFloat( obj:Object,value:Float )
  354. SetString obj,String.FromFloat( value )
  355. End Method
  356. Rem
  357. bbdoc: Set double field value
  358. End Rem
  359. Method SetDouble( obj:Object,value:Double )
  360. SetString obj,String.FromDouble( value )
  361. End Method
  362. Rem
  363. bbdoc: Set string field value
  364. End Rem
  365. Method SetString( obj:Object,value$ )
  366. Set obj,value
  367. End Method
  368. Field _index
  369. End Type
  370. Rem
  371. bbdoc: Type method
  372. End Rem
  373. Type TMethod Extends TMember
  374. Method Init:TMethod( name$,typeId:TTypeId,meta$,selfTypeId:TTypeId,index,argTypes:TTypeId[] )
  375. _name=name
  376. _typeId=typeId
  377. _meta=meta
  378. _selfTypeId=selfTypeId
  379. _index=index
  380. _argTypes=argTypes
  381. Return Self
  382. End Method
  383. Rem
  384. bbdoc: Get method arg types
  385. End Rem
  386. Method ArgTypes:TTypeId[]()
  387. Return _argTypes
  388. End Method
  389. Rem
  390. bbdoc: Invoke method
  391. End Rem
  392. Method Invoke:Object( obj:Object,args:Object[] )
  393. If _index<4096
  394. Return _Call( bbRefMethodPtr( obj,_index ),_typeId,obj,args,_argTypes )
  395. EndIf
  396. Return _Call( Byte Ptr(_index),_typeId,obj,args,_argTypes )
  397. End Method
  398. Field _selfTypeId:TTypeId,_index,_argTypes:TTypeId[]
  399. End Type
  400. Rem
  401. bbdoc: Type id
  402. End Rem
  403. Type TTypeId
  404. Rem
  405. bbdoc: Get name of type
  406. End Rem
  407. Method Name$()
  408. Return _name
  409. End Method
  410. Rem
  411. bbdoc: Get type meta data
  412. End Rem
  413. Method MetaData$( key$="" )
  414. Return ExtractMetaData( _meta,key )
  415. End Method
  416. Rem
  417. bbdoc: Get super type
  418. End Rem
  419. Method SuperType:TTypeId()
  420. Return _super
  421. End Method
  422. Rem
  423. bbdoc: Get array type
  424. End Rem
  425. Method ArrayType:TTypeId(dims:Int = 1)
  426. If Not _arrayType
  427. Local dim:String
  428. If dims > 1 Then
  429. For Local i:Int = 1 Until dims
  430. dim :+ ","
  431. Next
  432. End If
  433. _arrayType=New TTypeId.Init( _name+"[" + dim + "]",4,bbRefArrayClass() )
  434. _arrayType._elementType=Self
  435. If _super
  436. _arrayType._super=_super.ArrayType()
  437. Else
  438. _arrayType._super=ArrayTypeId
  439. EndIf
  440. EndIf
  441. Return _arrayType
  442. End Method
  443. Rem
  444. bbdoc: Get element type
  445. End Rem
  446. Method ElementType:TTypeId()
  447. Return _elementType
  448. End Method
  449. Rem
  450. bbdoc: Determine if type extends a type
  451. End Rem
  452. Method ExtendsType( typeId:TTypeId )
  453. If Self=typeId Return True
  454. If _super Return _super.ExtendsType( typeId )
  455. End Method
  456. Rem
  457. bbdoc: Get list of derived types
  458. End Rem
  459. Method DerivedTypes:TList()
  460. If Not _derived _derived=New TList
  461. Return _derived
  462. End Method
  463. Rem
  464. bbdoc: Create a new object
  465. End Rem
  466. Method NewObject:Object()
  467. If Not _class Throw "Unable to create new object"
  468. Return bbObjectNew( _class )
  469. End Method
  470. Rem
  471. bbdoc: Get list of fields
  472. about: Only returns fields declared in this type, not in super types.
  473. End Rem
  474. Method Fields:TList()
  475. Return _fields
  476. End Method
  477. Rem
  478. bbdoc: Get list of methods
  479. about: Only returns methods declared in this type, not in super types.
  480. End Rem
  481. Method Methods:TList()
  482. Return _methods
  483. End Method
  484. Rem
  485. bbdoc: Find a field by name
  486. about: Searchs type hierarchy for field called @name.
  487. End Rem
  488. Method FindField:TField( name$ )
  489. name=name.ToLower()
  490. For Local t:TField=EachIn _fields
  491. If t.Name().ToLower()=name Return t
  492. Next
  493. If _super Return _super.FindField( name )
  494. End Method
  495. Rem
  496. bbdoc: Find a method by name
  497. about: Searchs type hierarchy for method called @name.
  498. End Rem
  499. Method FindMethod:TMethod( name$ )
  500. name=name.ToLower()
  501. For Local t:TMethod=EachIn _methods
  502. If t.Name().ToLower()=name Return t
  503. Next
  504. If _super Return _super.FindMethod( name )
  505. End Method
  506. Rem
  507. bbdoc: Enumerate all fields
  508. about: Returns a list of all fields in type hierarchy
  509. End Rem
  510. Method EnumFields:TList( list:TList=Null )
  511. If Not list list=New TList
  512. If _super _super.EnumFields list
  513. For Local t:TField=EachIn _fields
  514. list.AddLast t
  515. Next
  516. Return list
  517. End Method
  518. Rem
  519. bbdoc: Enumerate all methods
  520. about: Returns a list of all methods in type hierarchy - TO DO: handle overrides!
  521. End Rem
  522. Method EnumMethods:TList( list:TList=Null )
  523. If Not list list=New TList
  524. If _super _super.EnumMethods list
  525. For Local t:TMethod=EachIn _methods
  526. list.AddLast t
  527. Next
  528. Return list
  529. End Method
  530. Rem
  531. bbdoc: Create a new array
  532. End Rem
  533. Method NewArray:Object( length, dims:Int[] = Null )
  534. If Not _elementType Throw "TypeID is not an array type"
  535. Local tag:Byte Ptr=_elementType._typeTag
  536. If Not tag
  537. tag=TypeTagForId( _elementType ).ToCString()
  538. _elementType._typeTag=tag
  539. EndIf
  540. If Not dims Then
  541. Return bbArrayNew1D( tag,length )
  542. Else
  543. Return bbRefArrayCreate( tag, dims )
  544. End If
  545. End Method
  546. Rem
  547. bbdoc: Get array length
  548. End Rem
  549. Method ArrayLength( array:Object, dim:Int = 0 )
  550. If Not _elementType Throw "TypeID is not an array type"
  551. Return bbRefArrayLength( array, dim )
  552. End Method
  553. Rem
  554. bbdoc: Get the number of dimensions
  555. End Rem
  556. Method ArrayDimensions:Int( array:Object )
  557. If Not _elementType Throw "TypeID is not an array type"
  558. Return bbRefArrayDimensions( array )
  559. End Method
  560. Rem
  561. bbdoc: Get an array element
  562. End Rem
  563. Method GetArrayElement:Object( array:Object,index )
  564. If Not _elementType Throw "TypeID is not an array type"
  565. Local p:Byte Ptr=bbRefArrayElementPtr( _elementType._size,array,index )
  566. Return _Get( p,_elementType )
  567. End Method
  568. Rem
  569. bbdoc: Set an array element
  570. End Rem
  571. Method SetArrayElement( array:Object,index,value:Object )
  572. If Not _elementType Throw "TypeID is not an array type"
  573. Local p:Byte Ptr=bbRefArrayElementPtr( _elementType._size,array,index )
  574. _Assign p,_elementType,value
  575. End Method
  576. Rem
  577. bbdoc: Get Type by name
  578. End Rem
  579. Function ForName:TTypeId( name$ )
  580. _Update
  581. If name.EndsWith( "]" )
  582. ' TODO
  583. name=name[..name.length-2]
  584. Return TTypeId( _nameMap.ValueForKey( name.ToLower() ) ).ArrayType()
  585. Else
  586. Return TTypeId( _nameMap.ValueForKey( name.ToLower() ) )
  587. EndIf
  588. End Function
  589. Rem
  590. bbdoc: Get Type by object
  591. End Rem
  592. Function ForObject:TTypeId( obj:Object )
  593. _Update
  594. Local class=bbRefGetObjectClass( obj )
  595. If class=ArrayTypeId._class
  596. If Not bbRefArrayLength( obj ) Return ArrayTypeId
  597. Return TypeIdForTag( bbRefArrayTypeTag( obj ) ).ArrayType()
  598. Else
  599. Return TTypeId( _classMap.ValueForKey( New TClass.SetClass( class ) ) )
  600. EndIf
  601. End Function
  602. Rem
  603. bbdoc: Get list of all types
  604. End Rem
  605. Function EnumTypes:TList()
  606. _Update
  607. Local list:TList=New TList
  608. For Local t:TTypeId=EachIn _nameMap.Values()
  609. list.AddLast t
  610. Next
  611. Return list
  612. End Function
  613. '***** PRIVATE *****
  614. Method Init:TTypeId( name$,size,class=0,supor:TTypeId=Null )
  615. _name=name
  616. _size=size
  617. _class=class
  618. _super=supor
  619. _fields=New TList
  620. _methods=New TList
  621. _nameMap.Insert _name.ToLower(),Self
  622. If class _classMap.Insert New TClass.SetClass( class ),Self
  623. Return Self
  624. End Method
  625. Method SetClass:TTypeId( class )
  626. Local debug=(Int Ptr class)[2]
  627. Local name$=String.FromCString( Byte Ptr( (Int Ptr debug)[1] ) ),meta$
  628. Local i=name.Find( "{" )
  629. If i<>-1
  630. meta=name[i+1..name.length-1]
  631. name=name[..i]
  632. EndIf
  633. _name=name
  634. _meta=meta
  635. _class=class
  636. _nameMap.Insert _name.ToLower(),Self
  637. _classMap.Insert New TClass.SetClass( class ),Self
  638. Return Self
  639. End Method
  640. Function _Update()
  641. Local count,p:Int Ptr=bbObjectRegisteredTypes( count )
  642. If count=_count Return
  643. Local list:TList=New TList
  644. For Local i=_count Until count
  645. Local ty:TTypeId=New TTypeId.SetClass( p[i] )
  646. list.AddLast ty
  647. Next
  648. _count=count
  649. For Local t:TTypeId=EachIn list
  650. t._Resolve
  651. Next
  652. End Function
  653. Method _Resolve()
  654. If _fields Or Not _class Return
  655. _fields=New TList
  656. _methods=New TList
  657. _super=TTypeId( _classMap.ValueForKey( New TClass.SetClass( (Int Ptr _class)[0] ) ) )
  658. If Not _super _super=ObjectTypeId
  659. If Not _super._derived _super._derived=New TList
  660. _super._derived.AddLast Self
  661. Local debug=(Int Ptr _class)[2]
  662. Local p:Int Ptr=(Int Ptr debug)+2
  663. While p[0]
  664. Local id$=String.FromCString( Byte Ptr p[1] )
  665. Local ty$=String.FromCString( Byte Ptr p[2] )
  666. Local meta$
  667. Local i=ty.Find( "{" )
  668. If i<>-1
  669. meta=ty[i+1..ty.length-1]
  670. ty=ty[..i]
  671. EndIf
  672. Select p[0]
  673. Case 3 'field
  674. Local typeId:TTypeId=TypeIdForTag( ty )
  675. If typeId _fields.AddLast New TField.Init( id,typeId,meta,p[3] )
  676. Case 6 'method
  677. Local t$[]=ty.Split( ")" )
  678. Local retType:TTypeId=TypeIdForTag( t[1] )
  679. If retType
  680. Local argTypes:TTypeId[]
  681. If t[0].length>1
  682. Local i,b,q$=t[0][1..],args:TList=New TList
  683. While i<q.length
  684. Select q[i]
  685. Case Asc( "," )
  686. args.AddLast q[b..i]
  687. i:+1
  688. b=i
  689. Case Asc( "[" )
  690. i:+1
  691. While i<q.length And q[i]=Asc(",")
  692. i:+1
  693. Wend
  694. Default
  695. i:+1
  696. End Select
  697. Wend
  698. If b<q.length args.AddLast q[b..q.length]
  699. argTypes=New TTypeId[args.Count()]
  700. i=0
  701. For Local arg$=EachIn args
  702. argTypes[i]=TypeIdForTag( arg )
  703. If Not argTypes[i] retType=Null
  704. i:+1
  705. Next
  706. EndIf
  707. If retType
  708. _methods.AddLast New TMethod.Init( id,retType,meta,Self,p[3],argTypes )
  709. EndIf
  710. EndIf
  711. End Select
  712. p:+4
  713. Wend
  714. End Method
  715. Field _name$
  716. Field _meta$
  717. Field _class
  718. Field _size=4
  719. Field _fields:TList
  720. Field _methods:TList
  721. Field _super:TTypeId
  722. Field _derived:TList
  723. Field _arrayType:TTypeId
  724. Field _elementType:TTypeId
  725. Field _typeTag:Byte Ptr
  726. Global _count,_nameMap:TMap=New TMap,_classMap:TMap=New TMap
  727. End Type