From 035c82cc4f9aa9b4bdf9374d2f50039c07de1ee2 Mon Sep 17 00:00:00 2001 From: micio Date: Thu, 14 Jan 2010 00:06:35 +0000 Subject: [PATCH] WithFactory - PolyXML - Added documentation git-svn-id: svn://ultimatepp.org/upp/trunk@1888 f0d560ea-af0d-0410-9eb7-867de7ffcac7 --- bazaar/PolyXML/PolyXML.upp | 3 +- bazaar/PolyXML/init | 4 + bazaar/PolyXML/src.tpp/WithFactory$en-us.tpp | 153 +++++++++++++++++++ bazaar/PolyXML/src.tpp/WithPolyXML$en-us.tpp | 105 +++++++++++++ 4 files changed, 264 insertions(+), 1 deletion(-) create mode 100644 bazaar/PolyXML/init create mode 100644 bazaar/PolyXML/src.tpp/WithFactory$en-us.tpp create mode 100644 bazaar/PolyXML/src.tpp/WithPolyXML$en-us.tpp diff --git a/bazaar/PolyXML/PolyXML.upp b/bazaar/PolyXML/PolyXML.upp index 102c57548..004c1ee34 100644 --- a/bazaar/PolyXML/PolyXML.upp +++ b/bazaar/PolyXML/PolyXML.upp @@ -3,5 +3,6 @@ uses file ClassFactory.h, - PolyXML.h; + PolyXML.h, + src.tpp; diff --git a/bazaar/PolyXML/init b/bazaar/PolyXML/init new file mode 100644 index 000000000..ef1ddbad7 --- /dev/null +++ b/bazaar/PolyXML/init @@ -0,0 +1,4 @@ +#ifndef _PolyXML_icpp_init_stub +#define _PolyXML_icpp_init_stub +#include "Core/init" +#endif diff --git a/bazaar/PolyXML/src.tpp/WithFactory$en-us.tpp b/bazaar/PolyXML/src.tpp/WithFactory$en-us.tpp new file mode 100644 index 000000000..cd788b195 --- /dev/null +++ b/bazaar/PolyXML/src.tpp/WithFactory$en-us.tpp @@ -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]&] +[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 :&] +[s2; -|-|[* One ptr `= MyBaseClass`::Create(`"MyBaseClass`");]&] +[s2; [* -|-|One 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 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; ] \ No newline at end of file diff --git a/bazaar/PolyXML/src.tpp/WithPolyXML$en-us.tpp b/bazaar/PolyXML/src.tpp/WithPolyXML$en-us.tpp new file mode 100644 index 000000000..3561cd79a --- /dev/null +++ b/bazaar/PolyXML/src.tpp/WithPolyXML$en-us.tpp @@ -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]&] +[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]&] +[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; ] \ No newline at end of file