2008-10-13 16:34 UTC+0200 Przemyslaw Czerpak (druzus/at/priv.onet.pl)

* harbour/include/hbclass.ch
  * harbour/source/vm/classes.c
  * harbour/source/rtl/tobject.prg
  * harbour/source/rtl/tclass.prg
    ! fixed race condition when class function is called 1-st time
      and new class is created. It was possible that more then one
      thread execute this function simultaneously and two classes
      identical classes but with different handles were created
      and registered in HVM

  * harbour/contrib/xhb/xhbcomp.prg
    * updated hack with optional inheritance for new class code
This commit is contained in:
Przemyslaw Czerpak
2008-10-13 14:35:07 +00:00
parent d43cc93d44
commit b3ee472fee
6 changed files with 232 additions and 142 deletions

View File

@@ -8,6 +8,20 @@
2008-12-31 13:59 UTC+0100 Foo Bar (foo.bar foobar.org)
*/
2008-10-13 16:34 UTC+0200 Przemyslaw Czerpak (druzus/at/priv.onet.pl)
* harbour/include/hbclass.ch
* harbour/source/vm/classes.c
* harbour/source/rtl/tobject.prg
* harbour/source/rtl/tclass.prg
! fixed race condition when class function is called 1-st time
and new class is created. It was possible that more then one
thread execute this function simultaneously and two classes
identical classes but with different handles were created
and registered in HVM
* harbour/contrib/xhb/xhbcomp.prg
* updated hack with optional inheritance for new class code
2008-10-13 13:51 UTC+0200 Viktor Szakats (harbour.01 syenar hu)
* make_b32.mak
* make_gcc.mak

View File

@@ -61,7 +61,7 @@ ANNOUNCE XHB_LIB
*/
#xcommand OPTIONAL INHERIT <!className!> => ;
if type( <"className">+"()" ) == "UI" ;;
aadd( s_oClass:asSuper, @__<className>() ) ;;
aadd( oClass:asSuper, @__<className>() ) ;;
end

View File

@@ -269,10 +269,11 @@ DECLARE HBClass ;
_HB_CLASS <ClassName> <FuncName> ;;
<static> function __HB_CLS_OPT([<FuncName>,] <ClassName>) ( HB_CLS_PARAM_LIST ) ;;
static s_oClass ;;
local nScope, oInstance ;;
if s_oClass == NIL ;;
nScope := HB_OO_CLSTP_EXPORTED ;;
s_oClass := IIF(<.metaClass.>, <(metaClass)>, HBClass():new( <(ClassName)> , __HB_CLS_PAR( [ @<SuperClass1>() ] [ , @<SuperClassN>() ] ), @__HB_CLS_OPT([__HB_CLS_ASID(<FuncName>),] <ClassName>)() [, <.modulfriend.> ] ) ) ;;
local nScope, oClass, oInstance ;;
if s_oClass == NIL .and. __clsLockDef( @s_oClass ) ;;
begin sequence ;;
nScope := HB_OO_CLSTP_EXPORTED ;;
oClass := IIF(<.metaClass.>, <(metaClass)>, HBClass():new( <(ClassName)> , __HB_CLS_PAR( [ @<SuperClass1>() ] [ , @<SuperClassN>() ] ), @__HB_CLS_OPT([__HB_CLS_ASID(<FuncName>),] <ClassName>)() [, <.modulfriend.> ] ) ) ;;
#undef _CLASS_NAME_ ; #define _CLASS_NAME_ <ClassName> ;;
#undef _CLASS_MODE_ ; #define _CLASS_MODE_ _CLASS_DECLARATION_ ;
[ ; #translate Super( <SuperClassN> ): => ::<SuperClassN>: ] ;
@@ -282,11 +283,14 @@ DECLARE HBClass ;
[ ; #translate ::Super : => ::<SuperClass1>: ]
#xcommand ENDCLASS [<lck: LOCK, LOCKED>] => ;
s_oClass:Create() ; [<-lck-> __clsLock( s_oClass:hClass ) ] ;;
oInstance := s_oClass:Instance() ;;
if __ObjHasMsg( oInstance, "InitClass" ) ;;
oInstance:InitClass( HB_CLS_PARAM_LIST ) ;;
end ;;
oClass:Create() ; [<-lck-> __clsLock( oClass:hClass ) ] ;;
oInstance := oClass:Instance() ;;
if __ObjHasMsg( oInstance, "InitClass" ) ;;
oInstance:InitClass( HB_CLS_PARAM_LIST ) ;;
end ;;
always ;;
__clsUnlockDef( @s_oClass, oClass ) ;;
end sequence ;;
return oInstance ;;
end ;;
return s_oClass:Instance() AS CLASS _CLASS_NAME_ ;;
@@ -308,7 +312,7 @@ DECLARE HBClass ;
#xcommand METHOD <MethodName> [ <ctor: CONSTRUCTOR> ] [ AS <type> ] [ <export: EXPORTED, VISIBLE>] [<protect: PROTECTED>] [<hidde: HIDDEN>] [<persistent: PERSISTENT, PROPERTY>] [<sync: SYNC>] [_CLASS_DECLARATION_] => ;
_HB_MEMBER __HB_CLS_ASFUNC(<MethodName>) [<-ctor-> AS CLASS _CLASS_NAME_] [ AS <type> ];;
__HB_CLS_DECLARE_METHOD __HB_CLS_PARAMS(<MethodName>) _CLASS_NAME_ ;;
s_oClass:AddMethod( __HB_CLS_ASSTRING(<MethodName>), @__HB_CLS_ASID( __HB_CLS_MTHNAME _CLASS_NAME_ <MethodName> )(), __HB_CLS_SCOPE( <.export.>, <.protect.>, <.hidde.> ) + iif( <.ctor.>, HB_OO_CLSTP_CTOR, 0 ) + iif( <.persistent.>, HB_OO_CLSTP_PERSIST, 0 ) + iif( <.sync.>, HB_OO_CLSTP_SYNC, 0 ) )
oClass:AddMethod( __HB_CLS_ASSTRING(<MethodName>), @__HB_CLS_ASID( __HB_CLS_MTHNAME _CLASS_NAME_ <MethodName> )(), __HB_CLS_SCOPE( <.export.>, <.protect.>, <.hidde.> ) + iif( <.ctor.>, HB_OO_CLSTP_CTOR, 0 ) + iif( <.persistent.>, HB_OO_CLSTP_PERSIST, 0 ) + iif( <.sync.>, HB_OO_CLSTP_SYNC, 0 ) )
#xcommand ACCESS <AccessName> [ AS <type> ] [ <export: EXPORTED, VISIBLE>] [<protect: PROTECTED>] [<hidde: HIDDEN>] [<persistent: PERSISTENT, PROPERTY>] [<sync: SYNC>] [_CLASS_DECLARATION_] => ;
METHOD <AccessName> [ AS <type> ] <export> <protect> <hidde> <persistent> <sync> _CLASS_DECLARATION_
@@ -335,49 +339,49 @@ DECLARE HBClass ;
#xcommand DESTRUCTOR <MethodName> => ;
_HB_MEMBER __HB_CLS_ASFUNC(<MethodName>);;
__HB_CLS_DECLARE_METHOD __HB_CLS_PARAMS(<MethodName>) _CLASS_NAME_ ;;
s_oClass:SetDestructor( @__HB_CLS_ASID( __HB_CLS_MTHNAME _CLASS_NAME_ <MethodName> )() )
oClass:SetDestructor( @__HB_CLS_ASID( __HB_CLS_MTHNAME _CLASS_NAME_ <MethodName> )() )
#xcommand ON ERROR <MethodName> => ERROR HANDLER <MethodName>
#xcommand ERROR HANDLER <MethodName> => ;
_HB_MEMBER __HB_CLS_ASFUNC(<MethodName>);;
__HB_CLS_DECLARE_METHOD __HB_CLS_PARAMS(<MethodName>) _CLASS_NAME_ ;;
s_oClass:SetOnError( @__HB_CLS_ASID( __HB_CLS_MTHNAME _CLASS_NAME_ <MethodName> )() )
oClass:SetOnError( @__HB_CLS_ASID( __HB_CLS_MTHNAME _CLASS_NAME_ <MethodName> )() )
#xcommand ON ERROR FUNCTION <FuncName> => ;
s_oClass:SetOnError( @__HB_CLS_ASID( <FuncName> )() )
oClass:SetOnError( @__HB_CLS_ASID( <FuncName> )() )
/* Friend function/class definitions */
#xcommand FRIEND CLASS <ClassName1> [, <ClassNameN> ] => ;
s_oClass:AddFriendClass( @__HB_CLS_ASID(<ClassName1>)() [, @__HB_CLS_ASID(<ClassNameN>)() ] )
oClass:AddFriendClass( @__HB_CLS_ASID(<ClassName1>)() [, @__HB_CLS_ASID(<ClassNameN>)() ] )
#xcommand FRIEND FUNCTION <FuncName1> [, <FuncNameN> ] => ;
s_oClass:AddFriendFunc( @__HB_CLS_ASID(<FuncName1>)() [, @__HB_CLS_ASID(<FuncNameN>)() ] )
oClass:AddFriendFunc( @__HB_CLS_ASID(<FuncName1>)() [, @__HB_CLS_ASID(<FuncNameN>)() ] )
/* Operator overloading */
#xcommand OPERATOR <op> [<arg: ARG, ARGS> <Args,...>] [LOCAL <Locals,...>] INLINE <Code,...> [ <export: EXPORTED, VISIBLE>] [<protect: PROTECTED>] [<hidde: HIDDEN>] [<sync: SYNC>] => ;
s_oClass:AddInline( <(op)>, {|Self [,<Args>] [,<Locals>]| __HB_CLS_SYMBOL_UNUSED(Self), <Code>}, __HB_CLS_SCOPE( <.export.>, <.protect.>, <.hidde.> ) + iif( <.sync.>, HB_OO_CLSTP_SYNC, 0 ) )
oClass:AddInline( <(op)>, {|Self [,<Args>] [,<Locals>]| __HB_CLS_SYMBOL_UNUSED(Self), <Code>}, __HB_CLS_SCOPE( <.export.>, <.protect.>, <.hidde.> ) + iif( <.sync.>, HB_OO_CLSTP_SYNC, 0 ) )
#xcommand METHOD <MethodName> [ AS <type> ] OPERATOR <op> [ <export: EXPORTED, VISIBLE>] [<protect: PROTECTED>] [<hidde: HIDDEN>] [<sync: SYNC>] => ;
_HB_MEMBER __HB_CLS_ASFUNC(<MethodName>) [ AS <type> ];;
__HB_CLS_DECLARE_METHOD __HB_CLS_PARAMS(<MethodName>) _CLASS_NAME_ ;;
s_oClass:AddMethod( <(op)>, @__HB_CLS_ASID( __HB_CLS_MTHNAME _CLASS_NAME_ <MethodName> )(), __HB_CLS_SCOPE( <.export.>, <.protect.>, <.hidde.> ) + iif( <.sync.>, HB_OO_CLSTP_SYNC, 0 ) )
oClass:AddMethod( <(op)>, @__HB_CLS_ASID( __HB_CLS_MTHNAME _CLASS_NAME_ <MethodName> )(), __HB_CLS_SCOPE( <.export.>, <.protect.>, <.hidde.> ) + iif( <.sync.>, HB_OO_CLSTP_SYNC, 0 ) )
#xcommand OPERATOR <op> FUNCTION <FuncName> [ <export: EXPORTED, VISIBLE>] [<protect: PROTECTED>] [<hidde: HIDDEN>] [<sync: SYNC>] => ;
s_oClass:AddMethod( <(op)>, @__HB_CLS_ASID( <FuncName> )(), __HB_CLS_SCOPE( <.export.>, <.protect.>, <.hidde.> ) + iif( <.sync.>, HB_OO_CLSTP_SYNC, 0 ) )
oClass:AddMethod( <(op)>, @__HB_CLS_ASID( <FuncName> )(), __HB_CLS_SCOPE( <.export.>, <.protect.>, <.hidde.> ) + iif( <.sync.>, HB_OO_CLSTP_SYNC, 0 ) )
/* Set/Get Method */
#xcommand METHOD <MethodName> [ AS <type> ] SETGET [ <export: EXPORTED, VISIBLE>] [<protect: PROTECTED>] [<hidde: HIDDEN>] [<ro: READONLY, RO>] [<persistent: PERSISTENT, PROPERTY>] [<sync: SYNC>] => ;
_HB_MEMBER __HB_CLS_ASFUNC(<MethodName>) [ AS <type> ];;
_HB_MEMBER __HB_CLS_ASFUNC(_<MethodName>) [ AS <type> ];;
__HB_CLS_DECLARE_METHOD __HB_CLS_PARAMS(<MethodName>) _CLASS_NAME_ ;;
s_oClass:AddMethod( __HB_CLS_ASSTRING(<MethodName>), @__HB_CLS_ASID( __HB_CLS_MTHNAME _CLASS_NAME_ <MethodName> )(), __HB_CLS_SCOPE( <.export.>, <.protect.>, <.hidde.> ) + iif( <.persistent.>, HB_OO_CLSTP_PERSIST, 0 ) + iif( <.sync.>, HB_OO_CLSTP_SYNC, 0 ) ) ;;
s_oClass:AddMethod( __HB_CLS_ASSTRING(_<MethodName>), @__HB_CLS_ASID( __HB_CLS_MTHNAME _CLASS_NAME_ <MethodName> )(), __HB_CLS_SCOPE( <.export.>, <.protect.>, <.hidde.> ) + iif( <.ro.>, HB_OO_CLSTP_READONLY, 0 ) + iif( <.persistent.>, HB_OO_CLSTP_PERSIST, 0 ) + iif( <.sync.>, HB_OO_CLSTP_SYNC, 0 ) )
oClass:AddMethod( __HB_CLS_ASSTRING(<MethodName>), @__HB_CLS_ASID( __HB_CLS_MTHNAME _CLASS_NAME_ <MethodName> )(), __HB_CLS_SCOPE( <.export.>, <.protect.>, <.hidde.> ) + iif( <.persistent.>, HB_OO_CLSTP_PERSIST, 0 ) + iif( <.sync.>, HB_OO_CLSTP_SYNC, 0 ) ) ;;
oClass:AddMethod( __HB_CLS_ASSTRING(_<MethodName>), @__HB_CLS_ASID( __HB_CLS_MTHNAME _CLASS_NAME_ <MethodName> )(), __HB_CLS_SCOPE( <.export.>, <.protect.>, <.hidde.> ) + iif( <.ro.>, HB_OO_CLSTP_READONLY, 0 ) + iif( <.persistent.>, HB_OO_CLSTP_PERSIST, 0 ) + iif( <.sync.>, HB_OO_CLSTP_SYNC, 0 ) )
/* Message definitions */
/* Virtual / Deferred Methods */
#xcommand MESSAGE <MessageName> [ AS <type> ] VIRTUAL => ;
_HB_MEMBER __HB_CLS_ASFUNC(<MessageName>) ;;
s_oClass:AddVirtual( __HB_CLS_ASSTRING(<MessageName>) )
oClass:AddVirtual( __HB_CLS_ASSTRING(<MessageName>) )
#xcommand MESSAGE <MessageName> [ AS <type> ] DEFERRED => ;
MESSAGE <MessageName> [ AS <type> ] VIRTUAL
@@ -385,15 +389,15 @@ DECLARE HBClass ;
#xcommand MESSAGE <MessageName> [ AS <type> ] METHOD <MethodName> [<ctor: CONSTRUCTOR>] [<export: EXPORTED, VISIBLE>] [<protect: PROTECTED>] [<hidde: HIDDEN>] [<persistent: PERSISTENT, PROPERTY>] [<sync: SYNC>] => ;
_HB_MEMBER __HB_CLS_ASFUNC(<MessageName>) [<-ctor-> AS CLASS _CLASS_NAME_] [ AS <type> ];;
__HB_CLS_DECLARE_METHOD __HB_CLS_PARAMS(<MethodName>) _CLASS_NAME_ ;;
s_oClass:AddMethod( __HB_CLS_ASSTRING(<MessageName>), @__HB_CLS_ASID( __HB_CLS_MTHNAME _CLASS_NAME_ <MethodName> )(), __HB_CLS_SCOPE( <.export.>, <.protect.>, <.hidde.> ) + iif( <.ctor.>, HB_OO_CLSTP_CTOR, 0 ) + iif( <.persistent.>, HB_OO_CLSTP_PERSIST, 0 ) + iif( <.sync.>, HB_OO_CLSTP_SYNC, 0 ) )
oClass:AddMethod( __HB_CLS_ASSTRING(<MessageName>), @__HB_CLS_ASID( __HB_CLS_MTHNAME _CLASS_NAME_ <MethodName> )(), __HB_CLS_SCOPE( <.export.>, <.protect.>, <.hidde.> ) + iif( <.ctor.>, HB_OO_CLSTP_CTOR, 0 ) + iif( <.persistent.>, HB_OO_CLSTP_PERSIST, 0 ) + iif( <.sync.>, HB_OO_CLSTP_SYNC, 0 ) )
#xcommand MESSAGE <MessageName> [ AS <type> ] EXTERN <FuncName> [<ctor: CONSTRUCTOR>] [<export: EXPORTED, VISIBLE>] [<protect: PROTECTED>] [<hidde: HIDDEN>] [<persistent: PERSISTENT, PROPERTY>] [<sync: SYNC>] => ;
_HB_MEMBER __HB_CLS_ASFUNC(<MessageName>) [<-ctor-> AS CLASS _CLASS_NAME_] [ AS <type> ];;
s_oClass:AddMethod( __HB_CLS_ASSTRING(<MessageName>), @__HB_CLS_ASID( <FuncName> )(), __HB_CLS_SCOPE( <.export.>, <.protect.>, <.hidde.> ) + iif( <.ctor.>, HB_OO_CLSTP_CTOR, 0 ) + iif( <.persistent.>, HB_OO_CLSTP_PERSIST, 0 ) + iif( <.sync.>, HB_OO_CLSTP_SYNC, 0 ) )
oClass:AddMethod( __HB_CLS_ASSTRING(<MessageName>), @__HB_CLS_ASID( <FuncName> )(), __HB_CLS_SCOPE( <.export.>, <.protect.>, <.hidde.> ) + iif( <.ctor.>, HB_OO_CLSTP_CTOR, 0 ) + iif( <.persistent.>, HB_OO_CLSTP_PERSIST, 0 ) + iif( <.sync.>, HB_OO_CLSTP_SYNC, 0 ) )
#xcommand MESSAGE <MessageName> [ AS <type> ] BLOCK <CodeBlock> [<ctor: CONSTRUCTOR>] [<export: EXPORTED, VISIBLE>] [<protect: PROTECTED>] [<hidde: HIDDEN>] [<persistent: PERSISTENT, PROPERTY>] [<sync: SYNC>] => ;
_HB_MEMBER __HB_CLS_ASFUNC(<MessageName>) [<-ctor-> AS CLASS _CLASS_NAME_] [ AS <type> ];;
s_oClass:AddInline( __HB_CLS_ASSTRING(<MessageName>), <CodeBlock>, __HB_CLS_SCOPE( <.export.>, <.protect.>, <.hidde.> ) + iif( <.ctor.>, HB_OO_CLSTP_CTOR, 0 ) + iif( <.persistent.>, HB_OO_CLSTP_PERSIST, 0 ) + iif( <.sync.>, HB_OO_CLSTP_SYNC, 0 ) )
oClass:AddInline( __HB_CLS_ASSTRING(<MessageName>), <CodeBlock>, __HB_CLS_SCOPE( <.export.>, <.protect.>, <.hidde.> ) + iif( <.ctor.>, HB_OO_CLSTP_CTOR, 0 ) + iif( <.persistent.>, HB_OO_CLSTP_PERSIST, 0 ) + iif( <.sync.>, HB_OO_CLSTP_SYNC, 0 ) )
#xcommand MESSAGE <MessageName> [ AS <type> ] [LOCAL <Locals,...>] INLINE <Code,...> [<ctor: CONSTRUCTOR>] [<export: EXPORTED, VISIBLE>] [<protect: PROTECTED>] [<hidde: HIDDEN>] [<persistent: PERSISTENT, PROPERTY>] [<sync: SYNC>] => ;
MESSAGE <MessageName> [ AS <type> ] BLOCK {|Self __HB_CLS_ASARGSOPT(<MessageName>) [,<Locals>]| __HB_CLS_SYMBOL_UNUSED(Self), <Code>} <ctor> <export> <protect> <hidde> <persistent> <sync>
@@ -498,31 +502,31 @@ DECLARE HBClass ;
#xcommand VAR <DataNames,...> [ <tp: TYPE, AS> <type> ] [ <as: ASSIGN, INIT> <uValue> ] [<export: EXPORTED, VISIBLE>] [<protect: PROTECTED>] [<hidde: HIDDEN>] [<ro: READONLY, RO>] [<persistent: PERSISTENT, PROPERTY>] [<sync: SYNC>] => ;
__HB_CLS_CHECKVAR(<DataNames>);;
_HB_MEMBER {[ AS <type>] <DataNames> } ;;
s_oClass:AddMultiData( <(type)>, <uValue>, __HB_CLS_SCOPE( <.export.>, <.protect.>, <.hidde.> ) + iif( <.ro.>, HB_OO_CLSTP_READONLY, 0 ) + iif( <.persistent.>, HB_OO_CLSTP_PERSIST, 0 ) + iif( <.sync.>, HB_OO_CLSTP_SYNC, 0 ), {<(DataNames)>}, __HB_CLS_NOINI )
oClass:AddMultiData( <(type)>, <uValue>, __HB_CLS_SCOPE( <.export.>, <.protect.>, <.hidde.> ) + iif( <.ro.>, HB_OO_CLSTP_READONLY, 0 ) + iif( <.persistent.>, HB_OO_CLSTP_PERSIST, 0 ) + iif( <.sync.>, HB_OO_CLSTP_SYNC, 0 ), {<(DataNames)>}, __HB_CLS_NOINI )
#xcommand VAR <DataName> [ AS <type> ] IN <SuperClass> => ;
__HB_CLS_CHECKVAR(<DataName>);;
_HB_MEMBER {[ AS <type>] <DataName> } ;;
s_oClass:AddInline( <(DataName)>, {|Self| Self:<SuperClass>:<DataName> }, HB_OO_CLSTP_EXPORTED + HB_OO_CLSTP_READONLY ) ;;
s_oClass:AddInline( "_" + <(DataName)>, {|Self, param| Self:<SuperClass>:<DataName> := param }, HB_OO_CLSTP_EXPORTED )
oClass:AddInline( <(DataName)>, {|Self| Self:<SuperClass>:<DataName> }, HB_OO_CLSTP_EXPORTED + HB_OO_CLSTP_READONLY ) ;;
oClass:AddInline( "_" + <(DataName)>, {|Self, param| Self:<SuperClass>:<DataName> := param }, HB_OO_CLSTP_EXPORTED )
#xcommand VAR <DataName> [ AS <type> ] IS <SprDataName> IN <SuperClass> => ;
__HB_CLS_CHECKVAR(<DataName>);;
_HB_MEMBER {[ AS <type>] <DataName> } ;;
s_oClass:AddInline( <(DataName)>, {|Self| Self:<SuperClass>:<SprDataName> }, HB_OO_CLSTP_EXPORTED + HB_OO_CLSTP_READONLY ) ;;
s_oClass:AddInline( "_" + <(DataName)>, {|Self, param| Self:<SuperClass>:<SprDataName> := param }, HB_OO_CLSTP_EXPORTED )
oClass:AddInline( <(DataName)>, {|Self| Self:<SuperClass>:<SprDataName> }, HB_OO_CLSTP_EXPORTED + HB_OO_CLSTP_READONLY ) ;;
oClass:AddInline( "_" + <(DataName)>, {|Self, param| Self:<SuperClass>:<SprDataName> := param }, HB_OO_CLSTP_EXPORTED )
#xcommand VAR <DataName1> [ AS <type> ] IS <DataName2> => ;
__HB_CLS_CHECKVAR(<DataName1>);;
_HB_MEMBER {[ AS <type>] <DataName1> } ;;
s_oClass:AddInline( <(DataName1)>, {|Self| Self:<DataName2> }, HB_OO_CLSTP_EXPORTED + HB_OO_CLSTP_READONLY ) ;;
s_oClass:AddInline( "_" + <(DataName1)>, {|Self, param| Self:<DataName2> := param }, HB_OO_CLSTP_EXPORTED )
oClass:AddInline( <(DataName1)>, {|Self| Self:<DataName2> }, HB_OO_CLSTP_EXPORTED + HB_OO_CLSTP_READONLY ) ;;
oClass:AddInline( "_" + <(DataName1)>, {|Self, param| Self:<DataName2> := param }, HB_OO_CLSTP_EXPORTED )
#xcommand VAR <DataName1> [ AS <type> ] IS <DataName2> TO <oObject> => ;
__HB_CLS_CHECKVAR(<DataName1>);;
_HB_MEMBER {[ AS <type>] <DataName1> } ;;
s_oClass:AddInline( <(DataName1)>, {|Self| Self:<oObject>:<DataName2> }, HB_OO_CLSTP_EXPORTED + HB_OO_CLSTP_READONLY ) ;;
s_oClass:AddInline( "_" + <(DataName1)>, {|Self, param| Self:<oObject>:<DataName2> := param }, HB_OO_CLSTP_EXPORTED )
oClass:AddInline( <(DataName1)>, {|Self| Self:<oObject>:<DataName2> }, HB_OO_CLSTP_EXPORTED + HB_OO_CLSTP_READONLY ) ;;
oClass:AddInline( "_" + <(DataName1)>, {|Self, param| Self:<oObject>:<DataName2> := param }, HB_OO_CLSTP_EXPORTED )
#endif /* HB_CLS_CSY */
@@ -532,13 +536,13 @@ DECLARE HBClass ;
#xcommand DATA <DataNames,...> [ AS <type> ] [ INIT <uValue> ] [ <export: EXPORTED, VISIBLE>] [<protect: PROTECTED>] [<hidde: HIDDEN>] [<ro: READONLY, RO>] [<persistent: PERSISTENT, PROPERTY>] [<sync: SYNC>] => ;
__HB_CLS_CHECKVAR(<DataNames>);;
_HB_MEMBER {[ AS <type>] <DataNames> } ;;
s_oClass:AddMultiData( <(type)>, <uValue>, __HB_CLS_SCOPE( <.export.>, <.protect.>, <.hidde.> ) + iif( <.ro.>, HB_OO_CLSTP_READONLY, 0 ) + iif( <.persistent.>, HB_OO_CLSTP_PERSIST, 0 ) + iif( <.sync.>, HB_OO_CLSTP_SYNC, 0 ), {<(DataNames)>}, __HB_CLS_NOINI )
oClass:AddMultiData( <(type)>, <uValue>, __HB_CLS_SCOPE( <.export.>, <.protect.>, <.hidde.> ) + iif( <.ro.>, HB_OO_CLSTP_READONLY, 0 ) + iif( <.persistent.>, HB_OO_CLSTP_PERSIST, 0 ) + iif( <.sync.>, HB_OO_CLSTP_SYNC, 0 ), {<(DataNames)>}, __HB_CLS_NOINI )
/* Warning! For backward compatibility this CLASSDATA ignores the
SHARED clause and always create shared class variables */
#xcommand CLASSDATA <DataNames,...> [ AS <type> ] [ INIT <uValue> ] [<export: EXPORTED, VISIBLE>] [<protect: PROTECTED>] [<hidde: HIDDEN>] [<ro: READONLY, RO>] [<share: SHARED>] [<persistent: PERSISTENT, PROPERTY>] [<sync: SYNC>] => ;
_HB_MEMBER {[ AS <type>] <DataNames> } ;;
s_oClass:AddMultiClsData( <(type)>, <uValue>, __HB_CLS_SCOPE( <.export.>, <.protect.>, <.hidde.> ) + iif( <.ro.>, HB_OO_CLSTP_READONLY, 0 ) + iif( /* <.share.> */ .T., HB_OO_CLSTP_SHARED, 0 ) + iif( <.persistent.>, HB_OO_CLSTP_PERSIST, 0 ) + iif( <.sync.>, HB_OO_CLSTP_SYNC, 0 ), {<(DataNames)>}, __HB_CLS_NOINI )
oClass:AddMultiClsData( <(type)>, <uValue>, __HB_CLS_SCOPE( <.export.>, <.protect.>, <.hidde.> ) + iif( <.ro.>, HB_OO_CLSTP_READONLY, 0 ) + iif( /* <.share.> */ .T., HB_OO_CLSTP_SHARED, 0 ) + iif( <.persistent.>, HB_OO_CLSTP_PERSIST, 0 ) + iif( <.sync.>, HB_OO_CLSTP_SYNC, 0 ), {<(DataNames)>}, __HB_CLS_NOINI )
#endif /* HB_CLS_FWO */
@@ -552,15 +556,15 @@ DECLARE HBClass ;
#xcommand EXPORT <!DataName1!> [, <!DataNameN!>] [ <tp: TYPE, AS> <type> ] [ <as: ASSIGN, INIT> <uValue> ] [<ro: READONLY, RO>] [<persistent: PERSISTENT, PROPERTY>] => ;
_HB_MEMBER {[ AS <type>] <DataName1> [, <DataNameN>] } ;;
s_oClass:AddMultiData( <(type)>, <uValue>, HB_OO_CLSTP_EXPORTED + iif( <.ro.>, HB_OO_CLSTP_READONLY, 0 ) + iif( <.persistent.>, HB_OO_CLSTP_PERSIST, 0 ), {<(DataName1)> [, <(DataNameN)>]}, __HB_CLS_NOINI )
oClass:AddMultiData( <(type)>, <uValue>, HB_OO_CLSTP_EXPORTED + iif( <.ro.>, HB_OO_CLSTP_READONLY, 0 ) + iif( <.persistent.>, HB_OO_CLSTP_PERSIST, 0 ), {<(DataName1)> [, <(DataNameN)>]}, __HB_CLS_NOINI )
#xcommand PROTECT <!DataName1!> [, <!DataNameN!>] [ <tp: TYPE, AS> <type> ] [ <as: ASSIGN, INIT> <uValue> ] [<ro: READONLY, RO>] [<persistent: PERSISTENT, PROPERTY>] => ;
_HB_MEMBER {[ AS <type>] <DataName1> [, <DataNameN>] } ;;
s_oClass:AddMultiData( <(type)>, <uValue>, HB_OO_CLSTP_PROTECTED + iif( <.ro.>, HB_OO_CLSTP_READONLY, 0 ) + iif( <.persistent.>, HB_OO_CLSTP_PERSIST, 0 ), {<(DataName1)> [, <(DataNameN)>]}, __HB_CLS_NOINI )
oClass:AddMultiData( <(type)>, <uValue>, HB_OO_CLSTP_PROTECTED + iif( <.ro.>, HB_OO_CLSTP_READONLY, 0 ) + iif( <.persistent.>, HB_OO_CLSTP_PERSIST, 0 ), {<(DataName1)> [, <(DataNameN)>]}, __HB_CLS_NOINI )
#xcommand HIDDE <!DataName1!> [, <!DataNameN!>] [ <tp: TYPE, AS> <type> ] [ <as: ASSIGN, INIT> <uValue> ] [<ro: READONLY, RO>] [<persistent: PERSISTENT, PROPERTY>] => ;
_HB_MEMBER {[ AS <type>] <DataName1> [, <DataNameN>] } ;;
s_oClass:AddMultiData( <(type)>, <uValue>, HB_OO_CLSTP_HIDDEN + iif( <.ro.>, HB_OO_CLSTP_READONLY, 0 ) + iif( <.persistent.>, HB_OO_CLSTP_PERSIST, 0 ), {<(DataName1)> [, <(DataNameN)>]}, __HB_CLS_NOINI )
oClass:AddMultiData( <(type)>, <uValue>, HB_OO_CLSTP_HIDDEN + iif( <.ro.>, HB_OO_CLSTP_READONLY, 0 ) + iif( <.persistent.>, HB_OO_CLSTP_PERSIST, 0 ), {<(DataName1)> [, <(DataNameN)>]}, __HB_CLS_NOINI )
#endif /* HB_CLS_VO */
@@ -576,11 +580,11 @@ DECLARE HBClass ;
#xcommand CLASSMETHOD <MethodName> [ AS <type> ] [<export: EXPORTED, VISIBLE>] [<protect: PROTECTED>] [<hidde: HIDDEN>] [<share: SHARED>] [<persistent: PERSISTENT, PROPERTY>] [<sync: SYNC>] => ;
_HB_MEMBER __HB_CLS_ASFUNC(<MethodName>) [ AS <type> ];;
__HB_CLS_DECLARE_METHOD __HB_CLS_PARAMS(<MethodName>) _CLASS_NAME_ ;;
s_oClass:AddClsMethod( __HB_CLS_ASSTRING(<MethodName>), @__HB_CLS_ASID( __HB_CLS_MTHNAME _CLASS_NAME_ <MethodName> )(), __HB_CLS_SCOPE( <.export.>, <.protect.>, <.hidde.> ) + iif( <.share.>, HB_OO_CLSTP_SHARED, 0 ) + iif( <.persistent.>, HB_OO_CLSTP_PERSIST, 0 ) + iif( <.sync.>, HB_OO_CLSTP_SYNC, 0 ) )
oClass:AddClsMethod( __HB_CLS_ASSTRING(<MethodName>), @__HB_CLS_ASID( __HB_CLS_MTHNAME _CLASS_NAME_ <MethodName> )(), __HB_CLS_SCOPE( <.export.>, <.protect.>, <.hidde.> ) + iif( <.share.>, HB_OO_CLSTP_SHARED, 0 ) + iif( <.persistent.>, HB_OO_CLSTP_PERSIST, 0 ) + iif( <.sync.>, HB_OO_CLSTP_SYNC, 0 ) )
#xcommand CLASSVAR <!DataName1!> [, <!DataNameN!>] [ <tp: TYPE, AS> <type> ] [ <as: ASSIGN, INIT> <uValue> ] [<export: EXPORTED, VISIBLE>] [<protect: PROTECTED>] [<hidde: HIDDEN>] [<ro: READONLY, RO>] [<share: SHARED>] [<persistent: PERSISTENT, PROPERTY>] [<sync: SYNC>] => ;
_HB_MEMBER {[ AS <type>] <DataName1> [, <DataNameN>] } ;;
s_oClass:AddMultiClsData( <(type)>, <uValue>, __HB_CLS_SCOPE( <.export.>, <.protect.>, <.hidde.> ) + iif( <.ro.>, HB_OO_CLSTP_READONLY, 0 ) + iif( <.share.>, HB_OO_CLSTP_SHARED, 0 ) + iif( <.persistent.>, HB_OO_CLSTP_PERSIST, 0 ) + iif( <.sync.>, HB_OO_CLSTP_SYNC, 0 ), {<(DataName1)> [, <(DataNameN)>]}, __HB_CLS_NOINI )
oClass:AddMultiClsData( <(type)>, <uValue>, __HB_CLS_SCOPE( <.export.>, <.protect.>, <.hidde.> ) + iif( <.ro.>, HB_OO_CLSTP_READONLY, 0 ) + iif( <.share.>, HB_OO_CLSTP_SHARED, 0 ) + iif( <.persistent.>, HB_OO_CLSTP_PERSIST, 0 ) + iif( <.sync.>, HB_OO_CLSTP_SYNC, 0 ), {<(DataName1)> [, <(DataNameN)>]}, __HB_CLS_NOINI )
/* Scalar classes support */

View File

@@ -81,64 +81,74 @@ REQUEST HBObject
FUNCTION HBClass()
STATIC s_hClass /* NOTE: Automatically default to NIL */
LOCAL hClass
IF s_hClass == NIL
s_hClass := __clsNew( "HBCLASS", 16,, @HBClass() )
/* s_hClass := __clsNew( "HBCLASS", 17,, @HBClass()) */
IF s_hClass == NIL .AND. __clsLockDef( @s_hClass )
__clsAddMsg( s_hClass, "New" , @New() , HB_OO_MSG_METHOD )
__clsAddMsg( s_hClass, "Create" , @Create() , HB_OO_MSG_METHOD )
__clsAddMsg( s_hClass, "AddData" , @AddData() , HB_OO_MSG_METHOD )
__clsAddMsg( s_hClass, "AddMultiData" , @AddMultiData() , HB_OO_MSG_METHOD )
__clsAddMsg( s_hClass, "AddClassData" , @AddClassData() , HB_OO_MSG_METHOD )
__clsAddMsg( s_hClass, "AddMultiClsData", @AddMultiClsData(), HB_OO_MSG_METHOD )
__clsAddMsg( s_hClass, "AddInline" , @AddInline() , HB_OO_MSG_METHOD )
__clsAddMsg( s_hClass, "AddMethod" , @AddMethod() , HB_OO_MSG_METHOD )
__clsAddMsg( s_hClass, "AddClsMethod" , @AddClsMethod() , HB_OO_MSG_METHOD )
__clsAddMsg( s_hClass, "AddVirtual" , @AddVirtual() , HB_OO_MSG_METHOD )
__clsAddMsg( s_hClass, "AddDelegate" , @AddDelegate() , HB_OO_MSG_METHOD )
__clsAddMsg( s_hClass, "AddFriendFunc" , @AddFriendFunc() , HB_OO_MSG_METHOD )
__clsAddMsg( s_hClass, "AddFriendClass" , @AddFriendClass() , HB_OO_MSG_METHOD )
__clsAddMsg( s_hClass, "Instance" , @Instance() , HB_OO_MSG_METHOD )
__clsAddMsg( s_hClass, "SetOnError" , @SetOnError() , HB_OO_MSG_METHOD )
__clsAddMsg( s_hClass, "SetDestructor" , @SetDestructor() , HB_OO_MSG_METHOD )
__clsAddMsg( s_hClass, "InitClass" , @InitClass() , HB_OO_MSG_METHOD )
__clsAddMsg( s_hClass, "cSuper" , {| Self | iif( Empty( ::asSuper ), NIL, ::asSuper[ 1 ]:name ) }, HB_OO_MSG_INLINE )
__clsAddMsg( s_hClass, "hClass" , 1, HB_OO_MSG_ACCESS )
__clsAddMsg( s_hClass, "_hClass" , 1, HB_OO_MSG_ASSIGN )
__clsAddMsg( s_hClass, "cName" , 2, HB_OO_MSG_ACCESS )
__clsAddMsg( s_hClass, "_cName" , 2, HB_OO_MSG_ASSIGN )
__clsAddMsg( s_hClass, "aDatas" , 3, HB_OO_MSG_ACCESS )
__clsAddMsg( s_hClass, "_aDatas" , 3, HB_OO_MSG_ASSIGN )
__clsAddMsg( s_hClass, "aMethods" , 4, HB_OO_MSG_ACCESS )
__clsAddMsg( s_hClass, "_aMethods" , 4, HB_OO_MSG_ASSIGN )
__clsAddMsg( s_hClass, "aClsDatas" , 5, HB_OO_MSG_ACCESS )
__clsAddMsg( s_hClass, "_aClsDatas" , 5, HB_OO_MSG_ASSIGN )
__clsAddMsg( s_hClass, "aClsMethods" , 6, HB_OO_MSG_ACCESS )
__clsAddMsg( s_hClass, "_aClsMethods" , 6, HB_OO_MSG_ASSIGN )
__clsAddMsg( s_hClass, "aInlines" , 7, HB_OO_MSG_ACCESS )
__clsAddMsg( s_hClass, "_aInlines" , 7, HB_OO_MSG_ASSIGN )
__clsAddMsg( s_hClass, "aVirtuals" , 8, HB_OO_MSG_ACCESS )
__clsAddMsg( s_hClass, "_aVirtuals" , 8, HB_OO_MSG_ASSIGN )
BEGIN SEQUENCE
__clsAddMsg( s_hClass, "aDelegates" , 9, HB_OO_MSG_ACCESS )
__clsAddMsg( s_hClass, "_aDelegates" , 9, HB_OO_MSG_ASSIGN )
__clsAddMsg( s_hClass, "asSuper" , 10, HB_OO_MSG_ACCESS )
__clsAddMsg( s_hClass, "_asSuper" , 10, HB_OO_MSG_ASSIGN )
__clsAddMsg( s_hClass, "sOnError" , 11, HB_OO_MSG_ACCESS )
__clsAddMsg( s_hClass, "_sOnError" , 11, HB_OO_MSG_ASSIGN )
__clsAddMsg( s_hClass, "sDestructor" , 12, HB_OO_MSG_ACCESS )
__clsAddMsg( s_hClass, "_sDestructor" , 12, HB_OO_MSG_ASSIGN )
__clsAddMsg( s_hClass, "lModFriendly" , 13, HB_OO_MSG_ACCESS )
__clsAddMsg( s_hClass, "_lModFriendly" , 13, HB_OO_MSG_ASSIGN )
__clsAddMsg( s_hClass, "asFriendClass" , 14, HB_OO_MSG_ACCESS )
__clsAddMsg( s_hClass, "_asFriendClass" , 14, HB_OO_MSG_ASSIGN )
__clsAddMsg( s_hClass, "asFriendFunc" , 15, HB_OO_MSG_ACCESS )
__clsAddMsg( s_hClass, "_asFriendFunc" , 15, HB_OO_MSG_ASSIGN )
__clsAddMsg( s_hClass, "sClassFunc" , 16, HB_OO_MSG_ACCESS )
__clsAddMsg( s_hClass, "_sClassFunc" , 16, HB_OO_MSG_ASSIGN )
/* __clsAddMsg( s_hClass, "class" , 17, HB_OO_MSG_ACCESS )
__clsAddMsg( s_hClass, "_class" , 17, HB_OO_MSG_ASSIGN ) */
hClass := __clsNew( "HBCLASS", 16,, @HBClass() )
/* hClass := __clsNew( "HBCLASS", 17,, @HBClass()) */
__clsAddMsg( hClass, "New" , @New() , HB_OO_MSG_METHOD )
__clsAddMsg( hClass, "Create" , @Create() , HB_OO_MSG_METHOD )
__clsAddMsg( hClass, "AddData" , @AddData() , HB_OO_MSG_METHOD )
__clsAddMsg( hClass, "AddMultiData" , @AddMultiData() , HB_OO_MSG_METHOD )
__clsAddMsg( hClass, "AddClassData" , @AddClassData() , HB_OO_MSG_METHOD )
__clsAddMsg( hClass, "AddMultiClsData", @AddMultiClsData(), HB_OO_MSG_METHOD )
__clsAddMsg( hClass, "AddInline" , @AddInline() , HB_OO_MSG_METHOD )
__clsAddMsg( hClass, "AddMethod" , @AddMethod() , HB_OO_MSG_METHOD )
__clsAddMsg( hClass, "AddClsMethod" , @AddClsMethod() , HB_OO_MSG_METHOD )
__clsAddMsg( hClass, "AddVirtual" , @AddVirtual() , HB_OO_MSG_METHOD )
__clsAddMsg( hClass, "AddDelegate" , @AddDelegate() , HB_OO_MSG_METHOD )
__clsAddMsg( hClass, "AddFriendFunc" , @AddFriendFunc() , HB_OO_MSG_METHOD )
__clsAddMsg( hClass, "AddFriendClass" , @AddFriendClass() , HB_OO_MSG_METHOD )
__clsAddMsg( hClass, "Instance" , @Instance() , HB_OO_MSG_METHOD )
__clsAddMsg( hClass, "SetOnError" , @SetOnError() , HB_OO_MSG_METHOD )
__clsAddMsg( hClass, "SetDestructor" , @SetDestructor() , HB_OO_MSG_METHOD )
__clsAddMsg( hClass, "InitClass" , @InitClass() , HB_OO_MSG_METHOD )
__clsAddMsg( hClass, "cSuper" , {| Self | iif( Empty( ::asSuper ), NIL, ::asSuper[ 1 ]:name ) }, HB_OO_MSG_INLINE )
__clsAddMsg( hClass, "hClass" , 1, HB_OO_MSG_ACCESS )
__clsAddMsg( hClass, "_hClass" , 1, HB_OO_MSG_ASSIGN )
__clsAddMsg( hClass, "cName" , 2, HB_OO_MSG_ACCESS )
__clsAddMsg( hClass, "_cName" , 2, HB_OO_MSG_ASSIGN )
__clsAddMsg( hClass, "aDatas" , 3, HB_OO_MSG_ACCESS )
__clsAddMsg( hClass, "_aDatas" , 3, HB_OO_MSG_ASSIGN )
__clsAddMsg( hClass, "aMethods" , 4, HB_OO_MSG_ACCESS )
__clsAddMsg( hClass, "_aMethods" , 4, HB_OO_MSG_ASSIGN )
__clsAddMsg( hClass, "aClsDatas" , 5, HB_OO_MSG_ACCESS )
__clsAddMsg( hClass, "_aClsDatas" , 5, HB_OO_MSG_ASSIGN )
__clsAddMsg( hClass, "aClsMethods" , 6, HB_OO_MSG_ACCESS )
__clsAddMsg( hClass, "_aClsMethods" , 6, HB_OO_MSG_ASSIGN )
__clsAddMsg( hClass, "aInlines" , 7, HB_OO_MSG_ACCESS )
__clsAddMsg( hClass, "_aInlines" , 7, HB_OO_MSG_ASSIGN )
__clsAddMsg( hClass, "aVirtuals" , 8, HB_OO_MSG_ACCESS )
__clsAddMsg( hClass, "_aVirtuals" , 8, HB_OO_MSG_ASSIGN )
__clsAddMsg( hClass, "aDelegates" , 9, HB_OO_MSG_ACCESS )
__clsAddMsg( hClass, "_aDelegates" , 9, HB_OO_MSG_ASSIGN )
__clsAddMsg( hClass, "asSuper" , 10, HB_OO_MSG_ACCESS )
__clsAddMsg( hClass, "_asSuper" , 10, HB_OO_MSG_ASSIGN )
__clsAddMsg( hClass, "sOnError" , 11, HB_OO_MSG_ACCESS )
__clsAddMsg( hClass, "_sOnError" , 11, HB_OO_MSG_ASSIGN )
__clsAddMsg( hClass, "sDestructor" , 12, HB_OO_MSG_ACCESS )
__clsAddMsg( hClass, "_sDestructor" , 12, HB_OO_MSG_ASSIGN )
__clsAddMsg( hClass, "lModFriendly" , 13, HB_OO_MSG_ACCESS )
__clsAddMsg( hClass, "_lModFriendly" , 13, HB_OO_MSG_ASSIGN )
__clsAddMsg( hClass, "asFriendClass" , 14, HB_OO_MSG_ACCESS )
__clsAddMsg( hClass, "_asFriendClass" , 14, HB_OO_MSG_ASSIGN )
__clsAddMsg( hClass, "asFriendFunc" , 15, HB_OO_MSG_ACCESS )
__clsAddMsg( hClass, "_asFriendFunc" , 15, HB_OO_MSG_ASSIGN )
__clsAddMsg( hClass, "sClassFunc" , 16, HB_OO_MSG_ACCESS )
__clsAddMsg( hClass, "_sClassFunc" , 16, HB_OO_MSG_ASSIGN )
/* __clsAddMsg( hClass, "class" , 17, HB_OO_MSG_ACCESS )
__clsAddMsg( hClass, "_class" , 17, HB_OO_MSG_ASSIGN ) */
ALWAYS
__clsUnlockDef( @s_hClass, hClass )
END SEQUENCE
ENDIF

View File

@@ -77,71 +77,80 @@
FUNCTION HBObject()
STATIC s_oClass
LOCAL oClass
IF s_oClass == NIL
IF s_oClass == NIL .and. __clsLockDef( @s_oClass )
s_oClass := HBClass():New( "HBObject",, @HBObject() )
BEGIN SEQUENCE
/* Those Five worked fine but their C version from classes.c are probably better in term of speed */
/*s_oClass:AddInline( "CLASSNAME" , {| Self | __OBJGETCLSNAME( Self ) }, HB_OO_CLSTP_EXPORTED ) */
/*s_oClass:AddInline( "CLASSH" , {| Self | __CLASSH( Self ) }, HB_OO_CLSTP_EXPORTED ) */
/*s_oClass:AddInline( "CLASSSEL" , {| Self | __CLASSSEL( Self:CLASSH() ) }, HB_OO_CLSTP_EXPORTED ) */
/*s_oClass:AddInline( "EVAL" , {| Self | __EVAL( Self ) }, HB_OO_CLSTP_EXPORTED ) */
oClass := HBClass():New( "HBObject",, @HBObject() )
/* xBase++ */
/* Those Five worked fine but their C version from classes.c are probably better in term of speed */
/*oClass:AddInline( "CLASSNAME" , {| Self | __OBJGETCLSNAME( Self ) }, HB_OO_CLSTP_EXPORTED ) */
/*oClass:AddInline( "CLASSH" , {| Self | __CLASSH( Self ) }, HB_OO_CLSTP_EXPORTED ) */
/*oClass:AddInline( "CLASSSEL" , {| Self | __CLASSSEL( Self:CLASSH() ) }, HB_OO_CLSTP_EXPORTED ) */
/*oClass:AddInline( "EVAL" , {| Self | __EVAL( Self ) }, HB_OO_CLSTP_EXPORTED ) */
/* xBase++ */
#ifdef HB_COMPAT_XPP
s_oClass:AddInline( "ISDERIVEDFROM" , {| Self, xPar1 | __ObjDerivedFrom( Self, xPar1 ) }, HB_OO_CLSTP_EXPORTED )
oClass:AddInline( "ISDERIVEDFROM" , {| Self, xPar1 | __ObjDerivedFrom( Self, xPar1 ) }, HB_OO_CLSTP_EXPORTED )
#endif
/* Class(y) */
s_oClass:AddInline( "ISKINDOF" , {| Self, xPar1 | __ObjDerivedFrom( Self, xPar1 ) }, HB_OO_CLSTP_EXPORTED )
s_oClass:AddMethod( "NEW" , @HBObject_New() , HB_OO_CLSTP_EXPORTED )
s_oClass:AddMethod( "INIT" , @HBObject_Init() , HB_OO_CLSTP_EXPORTED )
/* Class(y) */
oClass:AddInline( "ISKINDOF" , {| Self, xPar1 | __ObjDerivedFrom( Self, xPar1 ) }, HB_OO_CLSTP_EXPORTED )
s_oClass:AddMethod( "ERROR", @HBObject_Error() , HB_OO_CLSTP_EXPORTED )
oClass:AddMethod( "NEW" , @HBObject_New() , HB_OO_CLSTP_EXPORTED )
oClass:AddMethod( "INIT" , @HBObject_Init() , HB_OO_CLSTP_EXPORTED )
s_oClass:SetOnError( @HBObject_DftonError() )
oClass:AddMethod( "ERROR", @HBObject_Error() , HB_OO_CLSTP_EXPORTED )
s_oClass:AddInline( "MSGNOTFOUND" , {| Self, cMsg | ::Error( "Message not found", Self:className, cMsg, iif( Left( cMsg, 1 ) == "_", 1005, 1004 ) ) }, HB_OO_CLSTP_EXPORTED )
oClass:SetOnError( @HBObject_DftonError() )
/*s_oClass:AddMultiData( , , HB_OO_CLSTP_EXPORTED, { "CLASS" }, .F. ) */
oClass:AddInline( "MSGNOTFOUND" , {| Self, cMsg | ::Error( "Message not found", Self:className, cMsg, iif( Left( cMsg, 1 ) == "_", 1005, 1004 ) ) }, HB_OO_CLSTP_EXPORTED )
/*s_oClass:AddInline( "ADDMETHOD" , { | Self, cMeth, pFunc, nScopeMeth | __clsAddMsg( __CLASSH( Self ) , cMeth , pFunc ,HB_OO_MSG_METHOD , NIL, iif( nScopeMeth == NIL, 1, nScopeMeth ) ) }, HB_OO_CLSTP_EXPORTED ) */
/*s_oClass:AddInline( "ADDVAR" , { | Self, cVAR, nScopeMeth, uiData, hClass | __clsAddMsg( hClass:=__CLASSH( Self ) , cVar , uidata := __CLS_INCDATA( hClass ), HB_OO_MSG_ACCESS, NIL, iif( nScopeMeth == NIL, 1, nScopeMeth ) ) , ; */
/* __clsAddMsg( hClass , "_"+cVar , uiData , HB_OO_MSG_ASSIGN, NIL, iif( nScopeMeth == NIL, 1, nScopeMeth ) ) }, HB_OO_CLSTP_EXPORTED ) */
/*oClass:AddMultiData( , , HB_OO_CLSTP_EXPORTED, { "CLASS" }, .F. ) */
/* Those one exist within Class(y), so we will probably try to implement it */
/*oClass:AddInline( "ADDMETHOD" , { | Self, cMeth, pFunc, nScopeMeth | __clsAddMsg( __CLASSH( Self ) , cMeth , pFunc ,HB_OO_MSG_METHOD , NIL, iif( nScopeMeth == NIL, 1, nScopeMeth ) ) }, HB_OO_CLSTP_EXPORTED ) */
/*oClass:AddInline( "ADDVAR" , { | Self, cVAR, nScopeMeth, uiData, hClass | __clsAddMsg( hClass:=__CLASSH( Self ) , cVar , uidata := __CLS_INCDATA( hClass ), HB_OO_MSG_ACCESS, NIL, iif( nScopeMeth == NIL, 1, nScopeMeth ) ) , ; */
/* __clsAddMsg( hClass , "_"+cVar , uiData , HB_OO_MSG_ASSIGN, NIL, iif( nScopeMeth == NIL, 1, nScopeMeth ) ) }, HB_OO_CLSTP_EXPORTED ) */
/*s_oClass:AddInline( "asString" , {| Self | ::class:name + " object" }, HB_OO_CLSTP_EXPORTED ) */
/*s_oClass:AddInline( "asExpStr" , {| Self | }, HB_OO_CLSTP_EXPORTED ) */
/*s_oClass:AddInline( "basicSize" , {| Self | Len( Self ) }, HB_OO_CLSTP_EXPORTED ) */
/*s_oClass:AddInline( "become" , {| Self | }, HB_OO_CLSTP_EXPORTED ) */
/*s_oClass:AddInline( "isEqual" , {| Self | }, HB_OO_CLSTP_EXPORTED ) */
/*s_oClass:AddInline( "isScalar" , {| Self | }, HB_OO_CLSTP_EXPORTED ) */
/*s_oClass:AddInline( "copy" , {| Self | }, HB_OO_CLSTP_EXPORTED ) */
/*s_oClass:AddInline( "deepCopy" , {| Self | }, HB_OO_CLSTP_EXPORTED ) */
/* Those one exist within Class(y), so we will probably try to implement it */
/*s_oClass:AddInline( "deferred" , {| Self | }, HB_OO_CLSTP_EXPORTED ) */
/*oClass:AddInline( "asString" , {| Self | ::class:name + " object" }, HB_OO_CLSTP_EXPORTED ) */
/*oClass:AddInline( "asExpStr" , {| Self | }, HB_OO_CLSTP_EXPORTED ) */
/*oClass:AddInline( "basicSize" , {| Self | Len( Self ) }, HB_OO_CLSTP_EXPORTED ) */
/*oClass:AddInline( "become" , {| Self | }, HB_OO_CLSTP_EXPORTED ) */
/*oClass:AddInline( "isEqual" , {| Self | }, HB_OO_CLSTP_EXPORTED ) */
/*oClass:AddInline( "isScalar" , {| Self | }, HB_OO_CLSTP_EXPORTED ) */
/*oClass:AddInline( "copy" , {| Self | }, HB_OO_CLSTP_EXPORTED ) */
/*oClass:AddInline( "deepCopy" , {| Self | }, HB_OO_CLSTP_EXPORTED ) */
/*s_oClass:AddInline( "exec" , {| Self | }, HB_OO_CLSTP_EXPORTED ) */
/*s_oClass:AddInline( "error , {| Self | }, HB_OO_CLSTP_EXPORTED ) */
/*s_oClass:AddInline( "hash" , {| Self | }, HB_OO_CLSTP_EXPORTED ) */
/*s_oClass:AddInline( "null" , {| Self | }, HB_OO_CLSTP_EXPORTED ) */
/*s_oClass:AddInline( "size" , {| Self | Len( Self ) }, HB_OO_CLSTP_EXPORTED ) */
/*oClass:AddInline( "deferred" , {| Self | }, HB_OO_CLSTP_EXPORTED ) */
/* Those three are already treated within Classes.c */
/*s_oClass:AddInline( "protectErr" , {| Self | }, HB_OO_CLSTP_EXPORTED ) */
/*s_oClass:AddInline( "hiddenErr" , {| Self | }, HB_OO_CLSTP_EXPORTED ) */
/*s_oClass:AddInline( "readOnlyErr" , {| Self | }, HB_OO_CLSTP_EXPORTED ) */
/*oClass:AddInline( "exec" , {| Self | }, HB_OO_CLSTP_EXPORTED ) */
/*oClass:AddInline( "error , {| Self | }, HB_OO_CLSTP_EXPORTED ) */
/*oClass:AddInline( "hash" , {| Self | }, HB_OO_CLSTP_EXPORTED ) */
/*oClass:AddInline( "null" , {| Self | }, HB_OO_CLSTP_EXPORTED ) */
/*oClass:AddInline( "size" , {| Self | Len( Self ) }, HB_OO_CLSTP_EXPORTED ) */
/* No idea when those two could occur !!? */
/*s_oClass:AddInline( "wrongClass" , {| Self | }, HB_OO_CLSTP_EXPORTED ) */
/*s_oClass:AddInline( "badMethod" , {| Self | }, HB_OO_CLSTP_EXPORTED ) */
/* Those three are already treated within Classes.c */
/*oClass:AddInline( "protectErr" , {| Self | }, HB_OO_CLSTP_EXPORTED ) */
/*oClass:AddInline( "hiddenErr" , {| Self | }, HB_OO_CLSTP_EXPORTED ) */
/*oClass:AddInline( "readOnlyErr" , {| Self | }, HB_OO_CLSTP_EXPORTED ) */
/* this one exist within VO and seem to be Auto Called when object ran out of scope */
/*s_oClass:AddInline( "Axit" , {| Self | }, HB_OO_CLSTP_EXPORTED ) */
/* No idea when those two could occur !!? */
/*oClass:AddInline( "wrongClass" , {| Self | }, HB_OO_CLSTP_EXPORTED ) */
/*oClass:AddInline( "badMethod" , {| Self | }, HB_OO_CLSTP_EXPORTED ) */
s_oClass:Create()
/* this one exist within VO and seem to be Auto Called when object ran out of scope */
/*oClass:AddInline( "Axit" , {| Self | }, HB_OO_CLSTP_EXPORTED ) */
oClass:Create()
ALWAYS
__clsUnlockDef( @s_oClass, oClass ) ;;
END SEQUENCE
ENDIF

View File

@@ -405,6 +405,8 @@ static PCLASS * s_pClasses = NULL;
static USHORT s_uiClsSize = 0;
static USHORT s_uiClasses = 0;
static PHB_ITEM s_pClassMtx = NULL;
/* ================================================ */
#if 0
@@ -1056,6 +1058,10 @@ void hb_clsInit( void )
s_uiClasses = 0;
s_pClasses = ( PCLASS * ) hb_xgrab( sizeof( PCLASS ) * ( ( ULONG ) s_uiClsSize + 1 ) );
s_pClasses[ 0 ] = NULL;
#if defined( HB_MT_VM )
s_pClassMtx = hb_threadMutexCreate( FALSE );
#endif
}
/*
@@ -1165,6 +1171,12 @@ void hb_clsReleaseAll( void )
s_pClasses = NULL;
s_uiClsSize = 0;
}
if( s_pClassMtx )
{
hb_itemRelease( s_pClassMtx );
s_pClassMtx = NULL;
}
}
/* Mark all internal data as used so it will not be released by the
@@ -4661,6 +4673,47 @@ HB_FUNC( __CLSPREALLOCATE )
hb_retnl( s_uiClsSize );
}
HB_FUNC( __CLSLOCKDEF )
{
PHB_ITEM pClsItm = hb_param( 1, HB_IT_BYREF );
BOOL fLocked = FALSE;
if( pClsItm && HB_IS_NIL( pClsItm ) )
{
if( !s_pClassMtx || hb_threadMutexLock( s_pClassMtx ) )
{
if( HB_IS_NIL( pClsItm ) )
fLocked = TRUE;
else if( s_pClassMtx )
hb_threadMutexUnlock( s_pClassMtx );
}
}
hb_retl( fLocked );
}
HB_FUNC( __CLSUNLOCKDEF )
{
PHB_ITEM pClsDst = hb_param( 1, HB_IT_BYREF ),
pClsSrc = hb_param( 2, HB_IT_ANY );
if( pClsDst && pClsSrc && HB_IS_NIL( pClsDst ) && !ISBYREF( 2 ) )
{
/* intentional low level hack to eliminate race condition in
* unprotected readonly access.
* hb_itemMove() uses memcpy() for whole HB_ITEM structure first
* coping 'type' and then 'item' parts of HB_ITEM so it cannot be
* used by us. [druzus]
*/
memcpy( &pClsDst->item, &pClsSrc->item, sizeof( pClsDst->item ) );
/* pClsDst->item.asArray.value = pClsSrc->item.asArray.value; */
pClsDst->type = pClsSrc->type;
pClsSrc->type = HB_IT_NIL;
}
if( s_pClassMtx )
hb_threadMutexUnlock( s_pClassMtx );
}
/* Real dirty function, though very usefull under certain circunstances:
* It allows to change the class handle of an object into another class handle,
* so the object behaves like a different Class of object.