mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-07-11 22:03:01 -06:00
WithFactory - PolyXML - Added documentation
git-svn-id: svn://ultimatepp.org/upp/trunk@1888 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
parent
af9723b24b
commit
035c82cc4f
4 changed files with 264 additions and 1 deletions
|
|
@ -3,5 +3,6 @@ uses
|
|||
|
||||
file
|
||||
ClassFactory.h,
|
||||
PolyXML.h;
|
||||
PolyXML.h,
|
||||
src.tpp;
|
||||
|
||||
|
|
|
|||
4
bazaar/PolyXML/init
Normal file
4
bazaar/PolyXML/init
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
#ifndef _PolyXML_icpp_init_stub
|
||||
#define _PolyXML_icpp_init_stub
|
||||
#include "Core/init"
|
||||
#endif
|
||||
153
bazaar/PolyXML/src.tpp/WithFactory$en-us.tpp
Normal file
153
bazaar/PolyXML/src.tpp/WithFactory$en-us.tpp
Normal file
|
|
@ -0,0 +1,153 @@
|
|||
topic "WithFactory";
|
||||
[ $$0,0#00000000000000000000000000000000:Default]
|
||||
[i448;a25;kKO9; $$1,0#37138531426314131252341829483380:structitem]
|
||||
[l288;2 $$2,0#27521748481378242620020725143825:desc]
|
||||
[0 $$3,0#96390100711032703541132217272105:end]
|
||||
[i448;b42;O9;2 $$4,4#61672508125594000341940100500538:tparam]
|
||||
[b42;2 $$5,5#13035079074754324216151401829390:normal]
|
||||
[H6;0 $$6,0#05600065144404261032431302351956:begin]
|
||||
[i448;a25;kKO9;2 $$7,0#37138531426314131252341829483370:codeitem]
|
||||
[{_}%EN-US
|
||||
[ {{10000@(113.42.0) [s0; [*@7;4 WithFactory]]}}&]
|
||||
[s0;*@3;4 &]
|
||||
[s1;:noref:%- [@(0.0.255) template]_<[@(0.0.255) class]_[*@4 T]>&]
|
||||
[s1;:WithFactory`:`:class:%- [@(0.0.255) class]_[* WithFactory]&]
|
||||
[s4; [*C@4 T]-|Type of base class of polymorphic hyerarchy.&]
|
||||
[s5; This template class adds some RTTI (Run Time Type Identification)
|
||||
to your classes, and implements a so called `'class factory`',
|
||||
bringing the ability to register class hyerarchies, construct
|
||||
them by name, check their type at runtime, list all classes in
|
||||
hyerarchy and so on. &]
|
||||
[s5; It`'s a base behaviour for most polymorphic class usage.&]
|
||||
[s2; &]
|
||||
[s3;%- &]
|
||||
[s0;2 &]
|
||||
[ {{10000F(128)G(128)@1 [s0; [* Basic usage]]}}&]
|
||||
[s3;%- &]
|
||||
[s5; To implement the factory behaviour in your base class, just
|
||||
derive from WithFactory :&]
|
||||
[s0; &]
|
||||
[s2; [* class MyBaseClass : public WithFactory<MyBaseClass>]&]
|
||||
[s2; [* `{]&]
|
||||
[s2; [* -|-|.........]&]
|
||||
[s2; [* `};]&]
|
||||
[s5; Then you can derive your class hyerarchy from base, as usual
|
||||
:&]
|
||||
[s0; &]
|
||||
[s2; [* class MyDerivedClass : public MyBaseClass]&]
|
||||
[s2; [* `{]&]
|
||||
[s2; [* -|-|.........]&]
|
||||
[s2; [* `};]&]
|
||||
[s5; When you`'ve your class definition, you must register them;
|
||||
that`'s done inserting in a .cpp file (or in separate ones if
|
||||
you like, but NOT inside include files, the following statement
|
||||
:&]
|
||||
[s5; &]
|
||||
[s2; [* REGISTERCLASS(MyBaseClass `[, `"a class description`" `[, anIndex`]`])]&]
|
||||
[s2; [* REGISTERCLASS(MyDerivedClass `[, `"a class description`" `[,
|
||||
anIndex`]`])]&]
|
||||
[s5; &]
|
||||
[s5; where you can insert an optional class description string an
|
||||
an index; their usage will be clarified later on.&]
|
||||
[s5; Class creation can be done by following ways :&]
|
||||
[s5; &]
|
||||
[s2; As a pointer by classic new operator:&]
|
||||
[s2; -|-|[* MyBaseClass `*ptr `= new MyBaseClass;]&]
|
||||
[s2; [* -|-|MyBaseClass `*ptr `= new MyDerivedClass;]&]
|
||||
[s0; &]
|
||||
[s2; As a pointer, by ascii class name :&]
|
||||
[s2; -|-|[* MyBaseClass `*ptr `= MyBaseClass`::CreatePtr(`"MyBaseClass`");]&]
|
||||
[s2; [* -|-|MyBaseClass `*ptr `= MyBaseClass`::CreatePtr(`"MyDerivedClass`");]&]
|
||||
[s0; &]
|
||||
[s2; As One<MyBaseClass> :&]
|
||||
[s2; -|-|[* One<MyBaseClass> ptr `= MyBaseClass`::Create(`"MyBaseClass`");]&]
|
||||
[s2; [* -|-|One<MyBaseClass> ptr `= MyBaseClass`::Create(`"MyDerivedClass`");]&]
|
||||
[s0; &]
|
||||
[s5; You can inquire the type of an object at runtime with the [* IsA()]
|
||||
member function `::&]
|
||||
[s5; &]
|
||||
[s2; [* MyBaseClass `*ptr `= new MyDerivedClass;]&]
|
||||
[s2; [* String classType `= ptr`->IsA(); ]returns the string `"MyDerivedClass`"&]
|
||||
[s0; &]
|
||||
[s5; You can also list at runtime your class hyerarchy by mean of
|
||||
static member [* Classes()]:&]
|
||||
[s5; &]
|
||||
[s2; [* Vector<String> const `&classList `= MyBaseClass`::Classes();]&]
|
||||
[s0; &]
|
||||
[s5; or get descriptions by class name with [* GetClassDescription()]
|
||||
static member :&]
|
||||
[s5; &]
|
||||
[s2; [* String classDesc `= MyBaseClass`::GetClassDescription(`"MyBaseClass`");]&]
|
||||
[s2; [* String classDesc `= MyBaseClass`::GetClassDescription(`"MyDerivedClass`");]&]
|
||||
[s0; &]
|
||||
[s5; or get their integer `'index`' with [* GetClassIndex()] static
|
||||
member :&]
|
||||
[s5; &]
|
||||
[s2; [* int classIndex `= MyBaseClass`::GetClassIndex(`"MyBaseClass`");]&]
|
||||
[s2; [* int classIndex `= MyBaseClass`::GetClassIndex(`"MyDerivedClass`");]&]
|
||||
[s0;2 &]
|
||||
[ {{10000F(128)G(128)@1 [s0; [* Class registering]]}}&]
|
||||
[s3;%- &]
|
||||
[s7;:REGISTERCLASS`(type`, `.`.`.`):%- [* REGISTERCLASS]([*@3 type])&]
|
||||
[s2; Registers a class by its [%-*@3 type].&]
|
||||
[s3; &]
|
||||
[s6; &]
|
||||
[s7;:REGISTERCLASS`(type`, `.`.`.`):%- [* REGISTERCLASS]([*@3 type],
|
||||
[*@3 description])&]
|
||||
[s2; Registers a class by its [%-*@3 type] giving an optional [%-*@3 description
|
||||
]which can be queried later on. Main purpose of [%-*@3 description]
|
||||
is the presentation of class lists on menus and or dialogs when
|
||||
creating classes at runtime.&]
|
||||
[s3; &]
|
||||
[s6; &]
|
||||
[s7;:REGISTERCLASS`(type`, `.`.`.`):%- [* REGISTERCLASS]([*@3 type],
|
||||
[*@3 description, index])&]
|
||||
[s2; Registers a class by its [%-*@3 type] giving an optional [%-*@3 description
|
||||
]and an integer [%-*@3 index] which both can be queried later on.
|
||||
Main purpose of [%-*@3 index] is to give the ability to sort at
|
||||
runtime the class list by importance. [%-*@3 Index] can be any
|
||||
integer number &]
|
||||
[s3; &]
|
||||
[ {{10000F(128)G(128)@1 [s0; [* Detailed member list]]}}&]
|
||||
[s3;%- &]
|
||||
[s6;%- &]
|
||||
[s7;:WithFactory`:`:Create`(const String`&`):%- [@(0.0.255) static]
|
||||
[_^One^ One]<[*@4 T]>_[* Create]([@(0.0.255) const]_[_^String^ String]_`&[*@3 className])&]
|
||||
[s2; Creates a class derived from hyerarchy base T by its [%-*@3 className].&]
|
||||
[s2; Returns a smart pointer to the base class T&]
|
||||
[s3; &]
|
||||
[s6;%- &]
|
||||
[s7;:WithFactory`:`:CreatePtr`(String const`&`):%- [@(0.0.255) static]
|
||||
[*@4 T]_`*[* CreatePtr]([_^String^ String]_[@(0.0.255) const]_`&[*@3 className])&]
|
||||
[s2; Creates a class derived from hyerarchy base T by its [%-*@3 className].&]
|
||||
[s2; Returns a traditional pointer to the base class T&]
|
||||
[s3; &]
|
||||
[s6;%- &]
|
||||
[s7;:WithFactory`:`:Classes`(void`):%- [@(0.0.255) static] [_^Vector^ Vector]<[_^String^ St
|
||||
ring]>_[@(0.0.255) const]_`&[* Classes]([@(0.0.255) void])&]
|
||||
[s2; Returns Vector of strings containing all registered class names
|
||||
in hyerarchy.&]
|
||||
[s3;%- &]
|
||||
[s6;%- &]
|
||||
[s7;:WithFactory`:`:GetClassDescription`(const String`&`):%- [@(0.0.255) static]
|
||||
[_^String^ String]_[@(0.0.255) const]_`&[* GetClassDescription]([@(0.0.255) const]_[_^String^ S
|
||||
tring]_`&[*@3 className])&]
|
||||
[s2; Returns an ascii description of a class identified by [%-*@3 className].&]
|
||||
[s2; If no description was given when registering the class, returns
|
||||
an empty string.&]
|
||||
[s3; &]
|
||||
[s6;%- &]
|
||||
[s7;:WithFactory`:`:GetClassIndex`(const String`&`):%- [@(0.0.255) static]
|
||||
[@(0.0.255) int]_[@(0.0.255) const]_`&[* GetClassIndex]([@(0.0.255) const]_[_^String^ Strin
|
||||
g]_`&[*@3 className])&]
|
||||
[s2; Return an integer index assigned to class type identified by
|
||||
[%-*@3 className].&]
|
||||
[s2; If no index was given when registering the class, returns 0.&]
|
||||
[s3; &]
|
||||
[s6;%- &]
|
||||
[s7;:WithFactory`:`:IsA`(void`):%- [_^String^ String]_[@(0.0.255) const]_`&[* IsA]([@(0.0.255) v
|
||||
oid])&]
|
||||
[s2; Returns a string containing the class name.&]
|
||||
[s3;%- &]
|
||||
[s6;%- &]
|
||||
[s0; ]
|
||||
105
bazaar/PolyXML/src.tpp/WithPolyXML$en-us.tpp
Normal file
105
bazaar/PolyXML/src.tpp/WithPolyXML$en-us.tpp
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
topic "WithPolyXML";
|
||||
[2 $$0,0#00000000000000000000000000000000:Default]
|
||||
[i448;a25;kKO9;2 $$1,0#37138531426314131252341829483380:class]
|
||||
[l288;2 $$2,2#27521748481378242620020725143825:desc]
|
||||
[0 $$3,0#96390100711032703541132217272105:end]
|
||||
[H6;0 $$4,0#05600065144404261032431302351956:begin]
|
||||
[i448;a25;kKO9;2 $$5,0#37138531426314131252341829483370:item]
|
||||
[l288;a4;*@5;1 $$6,6#70004532496200323422659154056402:requirement]
|
||||
[l288;i1121;b17;O9;~~~.1408;2 $$7,0#10431211400427159095818037425705:param]
|
||||
[i448;b42;O9;2 $$8,8#61672508125594000341940100500538:tparam]
|
||||
[b42;2 $$9,9#13035079074754324216151401829390:normal]
|
||||
[{_}%EN-US
|
||||
[ {{10000@(113.42.0) [s0; [*@7;4 WithPolyXML]]}}&]
|
||||
[s1;@(0.0.255)3%- &]
|
||||
[s1;:noref:%- [@(0.0.255)3 template][3 _<][@(0.0.255)3 class][3 _][*@4;3 T][3 >]&]
|
||||
[s1;:WithPolyXML`:`:class:%- [@(0.0.255) class]_[* WithPolyXML]_:_[@(0.0.255) public]_[*@3 Wit
|
||||
hFactory]<[*@4 T]>_&]
|
||||
[s8; [*C@4 T]-|Type of base class of polymorphic hyerarchy.&]
|
||||
[s0; This template class implements the base behaviour of polymorphic
|
||||
classes that needs to be streamed in XML format.&]
|
||||
[s3; &]
|
||||
[s1;@(0.0.255)3%- &]
|
||||
[s1;:noref:%- [@(0.0.255)3 template][3 _<][@(0.0.255)3 class][3 _][*@4;3 T][3 >]&]
|
||||
[s1;:PolyXMLArray`:`:class:%- [@(0.0.255) class]_[* PolyXMLArray]_:_[@(0.0.255) public]_[*@3 A
|
||||
rray]<[_^WithPolyXML^ WithPolyXML]<[*@4 T]>_>_&]
|
||||
[s8; [*C@4 T]-|Type of base class of polymorphic hyerarchy.&]
|
||||
[s0; This template class implements the base behaviour of an XML`-streamable
|
||||
polymorphic container.&]
|
||||
[s2; &]
|
||||
[s3;%- &]
|
||||
[s0; &]
|
||||
[ {{10000F(128)G(128)@1 [s0; [* Basic usage]]}}&]
|
||||
[s3;%- &]
|
||||
[s9; To implement the polymorphic XML behaviour in your base class,
|
||||
just derive from [* WithPolyXML ]template :&]
|
||||
[s0; &]
|
||||
[s2; [* class MyBaseClass : public WithPolyXML<MyBaseClass>]&]
|
||||
[s2; [* `{]&]
|
||||
[s2; [* -|-|public:]&]
|
||||
[s2; [* -|-|-|virtual void Xmlize(XmlIO xml);]&]
|
||||
[s2; [* `};]&]
|
||||
[s9; Then you can derive your class hyerarchy from base, as usual
|
||||
:&]
|
||||
[s0; &]
|
||||
[s2; [* class MyDerivedClass : public MyBaseClass]&]
|
||||
[s2; [* `{]&]
|
||||
[s2; [* -|-|public:]&]
|
||||
[s2; [* -|-|-|virtual void Xmlize(XmlIO xml);]&]
|
||||
[s2; [* `};]&]
|
||||
[s9; &]
|
||||
[s9; The [* Xmlize()] virtual member function must be defined in each
|
||||
class in the hyerarchy; its purpose is to XML`-ize [* ONLY ]the
|
||||
direct members of the class. Because of that, in each derived
|
||||
class you must call [* AT FIRST] the parent`'s class [* Xmlize()]
|
||||
from inside it; here an example:&]
|
||||
[s0; &]
|
||||
[s2; [* void MyBaseClass`::Xmlize(XmlIO xml)]&]
|
||||
[s2; [* `{]&]
|
||||
[s2; [* -|-|xml]&]
|
||||
[s2; [* -|-|-|(`"FirstBaseMember`", FirstBaseMember),]&]
|
||||
[s2; [* -|-|-|(`"SecondBaseMember`", SecondBaseMember)]&]
|
||||
[s2; [* -|-|);]&]
|
||||
[s2; [* `}]&]
|
||||
[s2;* &]
|
||||
[s2; [* void MyDerivedClass`::Xmlize(XmlIO xml)]&]
|
||||
[s2; [* `{]&]
|
||||
[s2; [* -|-|MyBaseClass`::Xmlize(XmlIO xml);]&]
|
||||
[s2; [* -|-|xml]&]
|
||||
[s2; [* -|-|-|(`"FirstDerivedMember`", FirstDerivedMember),]&]
|
||||
[s2; [* -|-|-|(`"SecondDerivedMember`", SeconDeriveddMember)]&]
|
||||
[s2; [* -|-|);]&]
|
||||
[s2; [* `}]&]
|
||||
[s9; Don`'t forget to register your classes by [* REGISTERCLASS] macro,
|
||||
see [* WithFactory ]help topic about it.&]
|
||||
[s9; Then, you must declare the class container :&]
|
||||
[s0; &]
|
||||
[s2; [* class MyXMLContainer : public PolyXMLArray<MyXMLContainer>]&]
|
||||
[s2; [* `{]&]
|
||||
[s2; [* `}];&]
|
||||
[s0; &]
|
||||
[s0; That`'s all. Now you can construct your classes, add them to
|
||||
container which behaviour is identical to Array`'s one, and stream
|
||||
the container in XML format :&]
|
||||
[s0; &]
|
||||
[s0; Create classes and container :&]
|
||||
[s2; [* MyBaseClass `* baseClass `= new MyBaseClass;]&]
|
||||
[s2; [* MyBaseClass `* derivedClass `= MyBaseClass`::Create(`"MyDerivedClass`");]&]
|
||||
[s2; [* MyXMLContainer myContainer;]&]
|
||||
[s2; [* myContainer.Add(baseClass);]&]
|
||||
[s2; [* myContainer.Add(derivedClass);]&]
|
||||
[s0; &]
|
||||
[s0; Stream container into a string :&]
|
||||
[s2; [* String s `= StoreAsXML(myContainer, `"aTagName`");]&]
|
||||
[s0; &]
|
||||
[s0; Reload container from a string :&]
|
||||
[s2; [* myContainer.Clear();]&]
|
||||
[s2; [* bool res `= LoadFromXML(myContainer, s);]&]
|
||||
[s0; &]
|
||||
[s0; Store container into an xml file :&]
|
||||
[s2; [* bool res `= StoreAsXMLFile(myContainer, `"aTagName`", `"a/file/path.xml`");]&]
|
||||
[s0; &]
|
||||
[s0; Reload container from an xml file :&]
|
||||
[s2; [* myContainer.Clear();]&]
|
||||
[s2; [* bool res `= LoadFromXMLFile(myContainer, `"a/file/path.xml`")]&]
|
||||
[s0; ]
|
||||
Loading…
Add table
Add a link
Reference in a new issue