examples/Basics/MClasses2/MClasses2.cpp

00001 /*
00002 Copyright (c) 2000-2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.
00003 
00004 Redistribution and use in source and binary forms, with or without
00005 modification, are permitted provided that the following conditions are met:
00006 
00007 * Redistributions of source code must retain the above copyright notice, this
00008   list of conditions and the following disclaimer.
00009 * Redistributions in binary form must reproduce the above copyright notice,
00010   this list of conditions and the following disclaimer in the documentation
00011   and/or other materials provided with the distribution.
00012 * Neither the name of Nokia Corporation nor the names of its contributors
00013   may be used to endorse or promote products derived from this software
00014   without specific prior written permission.
00015 
00016 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00017 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00018 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00019 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
00020 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00021 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00022 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00023 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00024 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00025 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00026 
00027 Description: 
00028 Demonstrate use of M classes, or mixins - the
00029 only use of multiple inheritance that has been
00030 sanctioned by the E32 architecture team
00031 This example shows how mixins can be used to
00032 pass some protocol, and an associated object, from
00033 a protocol provider to an protocol user.  The user
00034 is not supposed to know everything about the provider,
00035 only about the protocol it's interested in.
00036 In this specific example, the provider contains a pointer 
00037 to the _real provider_: the provider is derived
00038 from the protocol base class, but the real provider is not.
00039 The real provider may thus honour many protocols. 
00040 */
00041 
00042 
00043 
00044 
00045 #include "CommonFramework.h"
00046 
00048 //
00049 // -----> CProtocol (definition)
00050 //
00051 // A protocol class for mixing in
00052 //
00054 class TProtocol
00055         {
00056 public:
00057         virtual void HandleEvent(TInt aEventCode)=0;
00058         };
00059 
00060 
00062 //
00063 // -----> CProtocolUser (definition)
00064 //
00065 // Define a protocol user which uses this protocol
00066 //
00068 class CProtocolUser : public CBase
00069         {
00070 public:
00071           // Construction
00072         static CProtocolUser* NewLC();
00073         static CProtocolUser* NewL();
00074 
00075           // Destruction
00076         ~CProtocolUser();
00077 
00078           // Some function which uses a protocol
00079         void DoSomething(TProtocol* aProtocol);
00080 
00081 protected:
00082           // Construction assistance
00083         void ConstructL();
00084         };
00085 
00086 
00088 //
00089 // -----> CProtocolProvider (definition)
00090 //
00091 // A simple class which uses the mixin
00092 //
00094 class TProtocolProvider;
00095 class CProtocolProvider : public CBase
00096         {
00097 public:
00098           // Construction
00099         static CProtocolProvider* NewLC();
00100 
00101           // Destruction
00102         ~CProtocolProvider();
00103 
00104           // Calls the protocol user
00105         void CallProtocolUser();
00106 
00107           // Implement the protocol (handles the protocol)
00108         void HandleEvent(TInt aEventCode);
00109 
00110 protected:
00111           // Construction assistance
00112         void ConstructL();
00113 
00114 private:
00115           // data members defined by this class
00116         CProtocolUser*     iProtocolUser;
00117         TProtocolProvider* iProviderProtocol;
00118         };
00119 
00120 
00122 //
00123 // -----> TProtocolProvider (definition)
00124 //
00125 // Define protocol implementation which passes on the implementation
00126 // to a real protocol provider
00127 //
00129 class TProtocolProvider : public TProtocol
00130         {
00131 public:
00132           // Construction
00133         TProtocolProvider(CProtocolProvider* aProvider);
00134 
00135           // The protocol itself
00136         void HandleEvent(TInt aEventCode);
00137 
00138 private:
00139           // The real provider
00140         CProtocolProvider* iProvider;
00141         };
00142 
00143 
00145 //
00146 // -----> CProtocolUser (implementation)
00147 //
00149 CProtocolUser* CProtocolUser::NewLC()
00150         {
00151         CProtocolUser* self=new(ELeave) CProtocolUser;
00152         CleanupStack::PushL(self);
00153         self->ConstructL();
00154         return self;
00155         }
00156 
00157 CProtocolUser* CProtocolUser::NewL()
00158         {
00159         CProtocolUser* self=NewLC();
00160         CleanupStack::Pop();
00161         return self;
00162         }
00163 
00164 CProtocolUser::~CProtocolUser()
00165         {
00166         }
00167 
00168 void CProtocolUser::ConstructL()
00169         {
00170         }
00171 
00172 void CProtocolUser::DoSomething(TProtocol* aProtocol)
00173         {
00174           // Do something that requires a protocol
00175         _LIT(KTxtExtSystemDoing,"External system doing something\n");
00176         console->Printf(KTxtExtSystemDoing);
00177         _LIT(KTxtInvokingProtocol,"invoking protocol - event 3\n");
00178         console->Printf(KTxtInvokingProtocol);
00179           // Handle an event
00180         aProtocol->HandleEvent(3);
00181         }
00182 
00183 
00185 //
00186 // -----> TProtocolProvider (implementation)
00187 //
00189 TProtocolProvider::TProtocolProvider(CProtocolProvider* aProvider)
00190                 : iProvider(aProvider)
00191         {
00192         }
00193 
00194 // see later for definition of HandleEvent()
00195 
00196 
00198 //
00199 // -----> CProtocolProvider (implementation)
00200 //
00202 CProtocolProvider* CProtocolProvider::NewLC()
00203         {
00204         CProtocolProvider* self=new(ELeave) CProtocolProvider;
00205         CleanupStack::PushL(self);
00206         self->ConstructL();
00207         return self;
00208         };
00209 
00210 CProtocolProvider::~CProtocolProvider()
00211         {
00212         delete iProtocolUser;
00213         delete iProviderProtocol;
00214         }
00215 
00216 void CProtocolProvider::ConstructL()
00217         {
00218         iProtocolUser=CProtocolUser::NewL();
00219         iProviderProtocol=new(ELeave) TProtocolProvider(this);
00220         }
00221 
00222 void CProtocolProvider::CallProtocolUser()
00223         { 
00224           // Call the protocol user to do some work
00225         _LIT(KTxtCallProtUser,"CProtocolProvider calling protocol user\n");
00226         console->Printf(KTxtCallProtUser);
00227         iProtocolUser->DoSomething(iProviderProtocol);
00228                         // pass the intermediary, which implements the
00229                         // protocol by passing it on to us,
00230                         // to the protocol user
00231         }
00232 
00233 void CProtocolProvider::HandleEvent(TInt aEventCode)
00234         { 
00235           // A concrete implementation of the abstract protocol.
00236           // Handle an event in the protocol user
00237         _LIT(KFormat1,"CProtocolProvider handling event %d\n");
00238         console->Printf(KFormat1,aEventCode);
00239         }
00240 
00241 void TProtocolProvider::HandleEvent(TInt aEventCode)
00242         {
00243           // A concrete definition of TProtocol::HandleEvent()
00244         _LIT(KTxtHandling,"Handling through intermediary\n");
00245         console->Printf(KTxtHandling);
00246         iProvider->HandleEvent(aEventCode);
00247         }
00248 
00249 
00251 //
00252 // Do the example
00253 //
00255 LOCAL_C void doExampleL()
00256     {
00257           // show use of mixin with simple class
00258         CProtocolProvider* simpleProvider=CProtocolProvider::NewLC();
00259           // call protocol user
00260         simpleProvider->CallProtocolUser();
00261           // Remove simpleProvider from cleanup stack and destroy
00262         CleanupStack::PopAndDestroy();
00263         }

Generated by  doxygen 1.6.2