00001 /* 00002 Copyright (c) 1997-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 is derived from 00037 an appropriate base class, and a mixin class representing 00038 the protocol. The benefits of the method shown in example EUTYPEM2 00039 are thus gained, without the inconvenience of intermediary 00040 classes. 00041 */ 00042 00043 00044 00045 00046 00047 #include "CommonFramework.h" 00048 00050 // 00051 // -----> CProtocol (definition) 00052 // 00053 // A protocol class for mixing in 00054 // 00056 class MProtocol 00057 { 00058 public: 00059 virtual void HandleEvent(TInt aEventCode)=0; 00060 }; 00061 00062 00064 // 00065 // -----> CProtocolUser (definition) 00066 // 00067 // Define a protocol user which uses this protocol 00068 // 00070 class CProtocolUser : public CBase 00071 { 00072 public: 00073 // Construction 00074 static CProtocolUser* NewLC(); 00075 static CProtocolUser* NewL(); 00076 00077 // Destruction 00078 ~CProtocolUser(); 00079 00080 // Some function which uses a protocol 00081 void DoSomething(MProtocol* aProtocol); 00082 00083 protected: 00084 // Construction assistance 00085 void ConstructL(); 00086 }; 00087 00088 00090 // 00091 // -----> CProtocolProvider (definition) 00092 // 00093 // A simple class which uses the mixin 00094 // 00096 class CProtocolProvider : public CBase, public MProtocol 00097 { 00098 public: 00099 // Construction 00100 static CProtocolProvider* NewLC(); 00101 00102 // Destruction 00103 ~CProtocolProvider(); 00104 00105 // Calls the protocol user 00106 void CallProtocolUser(); 00107 00108 // Implement the protocol (handles the protocol) 00109 void HandleEvent(TInt aEventCode); 00110 00111 protected: 00112 // Construction assistance 00113 void ConstructL(); 00114 00115 private: 00116 // data members defined by this class 00117 CProtocolUser* iProtocolUser; 00118 }; 00119 00120 00122 // 00123 // -----> CProtocolUser (implementation) 00124 // 00126 CProtocolUser* CProtocolUser::NewLC() 00127 { 00128 CProtocolUser* self=new(ELeave) CProtocolUser; 00129 CleanupStack::PushL(self); 00130 self->ConstructL(); 00131 return self; 00132 } 00133 00134 CProtocolUser* CProtocolUser::NewL() 00135 { 00136 CProtocolUser* self=NewLC(); 00137 CleanupStack::Pop(); 00138 return self; 00139 } 00140 00141 CProtocolUser::~CProtocolUser() 00142 { 00143 } 00144 00145 void CProtocolUser::ConstructL() 00146 { 00147 } 00148 00149 void CProtocolUser::DoSomething(MProtocol* aProtocol) 00150 { 00151 // Do something that requires a protocol 00152 _LIT(KTxtExtSystemDoing,"External system doing something\n"); 00153 console->Printf(KTxtExtSystemDoing); 00154 _LIT(KTxtInvokingProtocol,"invoking protocol - event 3\n"); 00155 console->Printf(KTxtInvokingProtocol); 00156 // Handle an event 00157 aProtocol->HandleEvent(3); 00158 } 00159 00160 00162 // 00163 // -----> CProtocolProvider (implementation) 00164 // 00166 CProtocolProvider* CProtocolProvider::NewLC() 00167 { 00168 CProtocolProvider* self=new(ELeave) CProtocolProvider; 00169 CleanupStack::PushL(self); 00170 self->ConstructL(); 00171 return self; 00172 }; 00173 00174 CProtocolProvider::~CProtocolProvider() 00175 { 00176 delete iProtocolUser; 00177 } 00178 00179 void CProtocolProvider::ConstructL() 00180 { 00181 iProtocolUser=CProtocolUser::NewL(); 00182 } 00183 00184 void CProtocolProvider::CallProtocolUser() 00185 { 00186 // Call the protocol user to do some work 00187 _LIT(KTxtCallProtUser,"CProtocolProvider calling protocol user\n"); 00188 console->Printf(KTxtCallProtUser); 00189 iProtocolUser->DoSomething(this); 00190 // pass ourselves, disguised as our mixin 00191 // protocol base, to the protocol user 00192 } 00193 00194 void CProtocolProvider::HandleEvent(TInt aEventCode) 00195 { 00196 // A concrete implementation of the abstract protocol. 00197 // Handle an event in the protocol user 00198 _LIT(KFormat1,"CProtocolProvider handling event %d\n"); 00199 console->Printf(KFormat1,aEventCode); 00200 } 00201 00202 00204 // 00205 // Do the example 00206 // 00208 LOCAL_C void doExampleL() 00209 { 00210 // show use of mixin with simple class 00211 CProtocolProvider* simpleProvider=CProtocolProvider::NewLC(); 00212 // call protocol user 00213 simpleProvider->CallProtocolUser(); 00214 // Remove simpleProvider from cleanup stack and destroy 00215 CleanupStack::PopAndDestroy(); 00216 }