1 /* |
|
2 * Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: This class handles the event list & process the events |
|
15 * while progressive rendering |
|
16 * |
|
17 */ |
|
18 |
|
19 |
|
20 #include "SvgtEventHandlerAO.h" |
|
21 #include <SVGTAppObserverUtil.h> |
|
22 #include <imcvcodc.h> |
|
23 #include "SvgtEvent.h" |
|
24 |
|
25 const TInt KTimerIntervalInMiliSeconds = 1000; |
|
26 |
|
27 const TInt KInitialTimeInterval = 100; |
|
28 const TInt KMaxTimeInterval = 2000; |
|
29 // ----------------------------------------------------------------------------- |
|
30 // CSvgtEventHandlerAO::NewL |
|
31 // Two phase construction |
|
32 // ----------------------------------------------------------------------------- |
|
33 // |
|
34 CSvgtEventHandlerAO* CSvgtEventHandlerAO::NewL(MSvgtAppObserver* aAppObserverUtil, |
|
35 CSVGTCustControl* aCustControl , |
|
36 const TThreadId aMainThreadId ) |
|
37 { |
|
38 CSvgtEventHandlerAO* self = new ( ELeave ) CSvgtEventHandlerAO( aAppObserverUtil , |
|
39 aCustControl, |
|
40 aMainThreadId); |
|
41 CleanupStack::PushL( self ); |
|
42 self->ConstructL(); |
|
43 CleanupStack::Pop(self); |
|
44 return self; |
|
45 } |
|
46 |
|
47 // ----------------------------------------------------------------------------- |
|
48 // CSvgtEventHandlerAO::CSvgtEventHandlerAO |
|
49 // Constructor |
|
50 // ----------------------------------------------------------------------------- |
|
51 // |
|
52 CSvgtEventHandlerAO::CSvgtEventHandlerAO(MSvgtAppObserver* aAppObserverUtil, |
|
53 CSVGTCustControl* aCustControl, |
|
54 const TThreadId aMainThreadId): |
|
55 CActive( CActive::EPriorityStandard ), |
|
56 iCustControl(aCustControl), |
|
57 iMainThreadId( aMainThreadId ), |
|
58 iIsDocumentComplete( EFalse ), |
|
59 iStepCount( 1 ), |
|
60 iSvgTimeBetweenRedraw( KInitialTimeInterval ) |
|
61 { |
|
62 iAppObserverUtil = static_cast<CSVGTAppObserverUtil*>(aAppObserverUtil); |
|
63 } |
|
64 |
|
65 // ----------------------------------------------------------------------------- |
|
66 // CSvgtEventHandlerAO::ConstructL |
|
67 // 2nd phase constructor |
|
68 // ----------------------------------------------------------------------------- |
|
69 // |
|
70 void CSvgtEventHandlerAO::ConstructL() |
|
71 { |
|
72 iPreviousRedrawClock.HomeTime(); |
|
73 // Add to active scheduler |
|
74 CActiveScheduler::Add( this ); |
|
75 // Set the status as pending |
|
76 iStatus = KRequestPending; |
|
77 // Set the active object as Active |
|
78 SetActive(); |
|
79 // Create the critical section IPC for sync. the RequestComplete Calls |
|
80 iCritSection.CreateLocal(); |
|
81 } |
|
82 |
|
83 // ----------------------------------------------------------------------------- |
|
84 // CSvgtEventHandlerAO::~CSvgtEventHandlerAO |
|
85 // Destructor |
|
86 // ----------------------------------------------------------------------------- |
|
87 // |
|
88 CSvgtEventHandlerAO::~CSvgtEventHandlerAO() |
|
89 { |
|
90 Cancel(); |
|
91 iEventList.ResetAndDestroy(); |
|
92 iEventList.Close(); |
|
93 iCritSection.Close(); |
|
94 } |
|
95 |
|
96 // ----------------------------------------------------------------------------- |
|
97 // CSvgtEventHandlerAO::AddEventToList |
|
98 // It adds the event (except redraw event) to the event queue. |
|
99 // ----------------------------------------------------------------------------- |
|
100 // |
|
101 TBool CSvgtEventHandlerAO::AddEventToList( CSvgtEvent* aEvent) |
|
102 { |
|
103 iEventList.Append( aEvent ); |
|
104 return ETrue; |
|
105 } |
|
106 |
|
107 // ----------------------------------------------------------------------------- |
|
108 // CSvgtEventHandlerAO::AddRedrawEventToList |
|
109 // It adds the redraw event to the event queue. |
|
110 // ----------------------------------------------------------------------------- |
|
111 // |
|
112 TBool CSvgtEventHandlerAO::AddRedrawEventToList( const TBool aForceAdd ) |
|
113 { |
|
114 TBool isEventAdded = EFalse; |
|
115 if(aForceAdd || IsRedrawTimeElapsed()) |
|
116 { |
|
117 CSvgtEvent* redrawEvent = new CSvgtEventRedraw; |
|
118 iEventList.Append( redrawEvent ); |
|
119 isEventAdded = ETrue; |
|
120 } |
|
121 |
|
122 return isEventAdded; |
|
123 } |
|
124 |
|
125 // ----------------------------------------------------------------------------- |
|
126 // CSvgtEventHandlerAO::MakeRequestComplete |
|
127 // It make the request complete. |
|
128 // ----------------------------------------------------------------------------- |
|
129 // |
|
130 void CSvgtEventHandlerAO::MakeRequestComplete( TInt aError ) |
|
131 { |
|
132 // The Asynchronouse service provider must only call the RequestComplete() |
|
133 // once for each request. Multiple completion events on a single active |
|
134 // object result in a stray signal panic. |
|
135 // Hence use a critical section to synchronize access to RequestComplete() |
|
136 iCritSection.Wait(); |
|
137 if( ( IsActive() ) && ( iStatus == KRequestPending ) ) |
|
138 { |
|
139 // The asynchronous service provider is the loading thread and since |
|
140 // this is called from both loading thread as well as main thread |
|
141 // use the RThread object to complete the request for active |
|
142 // object present in the main thread's active scheduler |
|
143 TRequestStatus* status = &iStatus; |
|
144 RThread mainThread; |
|
145 |
|
146 if( mainThread.Open( iMainThreadId) ) |
|
147 { |
|
148 // Problem opening thread, ignore error and return : Should not happen. |
|
149 return; |
|
150 } |
|
151 |
|
152 mainThread.RequestComplete( status, aError ); |
|
153 mainThread.Close(); |
|
154 } |
|
155 iCritSection.Signal(); |
|
156 } |
|
157 |
|
158 // ----------------------------------------------------------------------------- |
|
159 // CSvgtEventHandlerAO::AddEventToList |
|
160 // It indicates that document is document loading completed. |
|
161 // ----------------------------------------------------------------------------- |
|
162 // |
|
163 void CSvgtEventHandlerAO::SetDocumentComplete() |
|
164 { |
|
165 iIsDocumentComplete = ETrue; |
|
166 } |
|
167 |
|
168 // ----------------------------------------------------------------------------- |
|
169 // CSvgtEventHandlerAO::RunL |
|
170 // Handles an active object's request completion event. |
|
171 // ----------------------------------------------------------------------------- |
|
172 // |
|
173 void CSvgtEventHandlerAO::RunL() |
|
174 { |
|
175 // Set the Active Object Active always |
|
176 if( !IsActive() ) |
|
177 { |
|
178 iStatus = KRequestPending; |
|
179 SetActive(); |
|
180 } |
|
181 |
|
182 if(iEventList.Count()) |
|
183 { |
|
184 CSvgtEvent* event = iEventList[0]; |
|
185 iEventList.Remove( 0 ); |
|
186 switch(event->EventType()) |
|
187 { |
|
188 case CSvgtEvent::ESvgtEventEmbededImage: |
|
189 { |
|
190 CSvgtEventEmbededImage* svgEvent = |
|
191 static_cast<CSvgtEventEmbededImage*>(event); |
|
192 iAppObserverUtil->AssignEmbededDataL( svgEvent->ImageUri() ); |
|
193 } |
|
194 break; |
|
195 |
|
196 case CSvgtEvent::ESvgtEventFetchImage: |
|
197 { |
|
198 CSvgtEventFetchImage* fetchEvent = |
|
199 static_cast<CSvgtEventFetchImage*>(event); |
|
200 iAppObserverUtil->NewFetchImageData(fetchEvent->ImageUri()); |
|
201 } |
|
202 break; |
|
203 case CSvgtEvent::ESvgtEventLinkActivated: |
|
204 { |
|
205 CSvgtEventLinkActivated* linkEvent = |
|
206 static_cast<CSvgtEventLinkActivated*>(event); |
|
207 iAppObserverUtil->LinkActivated(linkEvent->ImageUri()); |
|
208 } |
|
209 break; |
|
210 case CSvgtEvent::ESvgtEventLinkActivatedWithShow: |
|
211 { |
|
212 CSvgtEventLinkActivatedWithShow* linkShowEvent = |
|
213 static_cast<CSvgtEventLinkActivatedWithShow*>(event); |
|
214 iAppObserverUtil->LinkActivatedWithShow(linkShowEvent->ImageUri(), |
|
215 linkShowEvent->Show()); |
|
216 } |
|
217 break; |
|
218 case CSvgtEvent::ESvgtEventRedraw: |
|
219 { |
|
220 //DO REDRAW |
|
221 iCustControl->PerformEngineRedraw(); |
|
222 iCustControl->DrawNow(); |
|
223 } |
|
224 break; |
|
225 |
|
226 default: |
|
227 break; |
|
228 } |
|
229 |
|
230 delete event; |
|
231 } |
|
232 |
|
233 |
|
234 if( iEventList.Count() ) |
|
235 { |
|
236 // Pending events in the list, reschedule active |
|
237 // object |
|
238 MakeRequestComplete( KErrNone ); |
|
239 } |
|
240 } |
|
241 |
|
242 // ----------------------------------------------------------------------------- |
|
243 // CSvgtEventHandlerAO::DoCancel |
|
244 // Cancels all the pending request |
|
245 // ----------------------------------------------------------------------------- |
|
246 // |
|
247 void CSvgtEventHandlerAO::DoCancel() |
|
248 { |
|
249 // The service provided for this active object is the |
|
250 // loading thread. Since the loading thread is already indicated to stop |
|
251 // generating requests, need to terminate the request |
|
252 // pending in the main thread |
|
253 DoTerminate(); |
|
254 } |
|
255 |
|
256 // ----------------------------------------------------------------------------- |
|
257 // CSvgtEventHandlerAO::RunError |
|
258 // Handles a leave occurring in the request completion event handler RunL(). |
|
259 // ----------------------------------------------------------------------------- |
|
260 // |
|
261 TInt CSvgtEventHandlerAO::RunError( TInt aError ) |
|
262 { |
|
263 // When an error occurs, call base class error handler |
|
264 // Note that active object should not be Cancel() here |
|
265 // as Loading thread could still be alive and do a |
|
266 // MakeRequestComplete. This would generate a stray |
|
267 // signal. |
|
268 return ( CActive::RunError( aError ) ); |
|
269 } |
|
270 |
|
271 // ----------------------------------------------------------------------------- |
|
272 // CSvgtEventHandlerAO::IsRedrawTimeElapsed |
|
273 // It determines whether the time elapsed or not. |
|
274 // ----------------------------------------------------------------------------- |
|
275 // |
|
276 TBool CSvgtEventHandlerAO::IsRedrawTimeElapsed() |
|
277 { |
|
278 TBool isTimeElapsed = EFalse; |
|
279 TTime currentClock; |
|
280 currentClock.HomeTime(); |
|
281 |
|
282 TTimeIntervalMicroSeconds time64; |
|
283 time64 = currentClock.MicroSecondsFrom( iPreviousRedrawClock ); |
|
284 |
|
285 TUint32 timeDelta = I64INT( time64.Int64() ) / KTimerIntervalInMiliSeconds; |
|
286 // milliseconds |
|
287 |
|
288 if ( timeDelta > iSvgTimeBetweenRedraw )//KSvgTimeBetweenRedraw=500 |
|
289 { |
|
290 if( iSvgTimeBetweenRedraw < KMaxTimeInterval ) |
|
291 { |
|
292 iSvgTimeBetweenRedraw *= ++iStepCount; |
|
293 } |
|
294 isTimeElapsed = ETrue; |
|
295 // Save the current time to calculate interframe delay |
|
296 iPreviousRedrawClock.HomeTime(); |
|
297 } |
|
298 |
|
299 return isTimeElapsed; |
|
300 } |
|
301 |
|
302 // ----------------------------------------------------------------------------- |
|
303 // CSvgtEventHandlerAO::DoTerminate |
|
304 // Cancels the pending async request |
|
305 // ----------------------------------------------------------------------------- |
|
306 // |
|
307 void CSvgtEventHandlerAO::DoTerminate() |
|
308 { |
|
309 // Post a pseudo complete, so that Cancel() is done |
|
310 // successfully. The Loading thread which is the actual service |
|
311 // provider is by now already stopped. |
|
312 // The Asynchronous service provider should complete the |
|
313 // request with KErrCancel as quickly as possible, because CActive::Cancel |
|
314 // blocks until completion occurs. |
|
315 MakeRequestComplete( KErrCancel ); |
|
316 } |
|
317 |
|
318 |
|
319 //End of file |
|