|
1 // Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 // All rights reserved. |
|
3 // This component and the accompanying materials are made available |
|
4 // under the terms of "Eclipse Public License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // |
|
15 |
|
16 // User includes |
|
17 #include "SchTimer.h" |
|
18 #include "SCHMAN.H" |
|
19 #include "SCHEDULE.H" |
|
20 |
|
21 // system includes |
|
22 #include <e32property.h> |
|
23 |
|
24 /** |
|
25 An instance of this class is used for each different time that a |
|
26 schedule needs to be run. It is created solely in the |
|
27 CScheduleCriteriaManager class. The timer is updated via the |
|
28 SetNext method. When the time has been reached it notifies the schedule |
|
29 manager via the CScheduleCriteriaManager::DueSchedule() method. |
|
30 |
|
31 @internalComponent |
|
32 */ |
|
33 NONSHARABLE_CLASS(CScheduleTimer) : public CTimer |
|
34 { |
|
35 public: |
|
36 ~CScheduleTimer(); |
|
37 static CScheduleTimer* NewL(TInt aSchedule, CScheduleCriteriaManager& aManager); |
|
38 |
|
39 void SetNext(const TTsTime& aNextTime); |
|
40 TInt Id(); |
|
41 |
|
42 //list capability |
|
43 static TInt Offset(); |
|
44 private: |
|
45 // From CTimer |
|
46 void RunL(); |
|
47 |
|
48 CScheduleTimer(TInt aSchedule, CScheduleCriteriaManager& aManager); |
|
49 void ConstructL(); |
|
50 |
|
51 private: |
|
52 TTsTime iDueTime; |
|
53 TInt iScheduleHandle; |
|
54 TSglQueLink iLink; |
|
55 CScheduleCriteriaManager& iConditonManager; |
|
56 }; |
|
57 |
|
58 CScheduleTimer* CScheduleTimer::NewL(TInt aSchedule, CScheduleCriteriaManager& aManager) |
|
59 { |
|
60 CScheduleTimer* self = new(ELeave) CScheduleTimer(aSchedule, aManager); |
|
61 CleanupStack::PushL(self); |
|
62 self->ConstructL(); |
|
63 CleanupStack::Pop(self); |
|
64 return self; |
|
65 } |
|
66 |
|
67 CScheduleTimer::CScheduleTimer(TInt aSchedule, CScheduleCriteriaManager& aManager) |
|
68 : CTimer(EPriorityStandard), |
|
69 iScheduleHandle(aSchedule), |
|
70 iConditonManager(aManager) |
|
71 { |
|
72 } |
|
73 |
|
74 CScheduleTimer::~CScheduleTimer() |
|
75 { |
|
76 Cancel(); |
|
77 } |
|
78 |
|
79 void CScheduleTimer::ConstructL() |
|
80 { |
|
81 CTimer::ConstructL(); |
|
82 CActiveScheduler::Add(this); |
|
83 } |
|
84 |
|
85 void CScheduleTimer::SetNext(const TTsTime& aNewTime) |
|
86 { |
|
87 // Can't handle (unlikely but theoretical) situation when year is BC (not AD) |
|
88 __ASSERT_ALWAYS(aNewTime.GetUtcTime().DateTime().Year()>0,User::Invariant()); |
|
89 if (IsActive()) |
|
90 Cancel(); |
|
91 |
|
92 iDueTime=aNewTime; |
|
93 TTime currentTime; |
|
94 currentTime.UniversalTime(); |
|
95 |
|
96 if (aNewTime.GetUtcTime()>currentTime) |
|
97 AtUTC(aNewTime.GetUtcTime()); |
|
98 else |
|
99 AtUTC(currentTime); |
|
100 } |
|
101 |
|
102 // Respond to an task being due. RunL is only called once! |
|
103 void CScheduleTimer::RunL() |
|
104 { |
|
105 if(iStatus != KErrAbort) |
|
106 iConditonManager.DueSchedule(iScheduleHandle); |
|
107 |
|
108 // RunL() will also be triggered if the system time is changed, with iStatus |
|
109 // set to KErrAbort. In this case DueSchedule() should not be called. |
|
110 // If the system time has been changed, the schedule needs to be requeued. |
|
111 // This has already been done automatically by CTaskScheduler::HandleEnvironmentChange() |
|
112 // [called by the AO CEnvironmentChangeNotifier], |
|
113 // as the active object CEnvironmentChangeNotifier has a higher priority than CScheduleTimer. |
|
114 } |
|
115 |
|
116 TInt CScheduleTimer::Offset() |
|
117 { |
|
118 return (_FOFF(CScheduleTimer, iLink)); |
|
119 } |
|
120 |
|
121 TInt CScheduleTimer::Id() |
|
122 { |
|
123 return iScheduleHandle; |
|
124 } |
|
125 |
|
126 // |
|
127 // class CPropertyNotifier |
|
128 // This class handles changes to P&S variables and notifies the |
|
129 // CConditionManager class when a condition is satisfied. |
|
130 NONSHARABLE_CLASS(CPropertyNotifier) : public CActive |
|
131 { |
|
132 public: |
|
133 ~CPropertyNotifier(); |
|
134 static CPropertyNotifier* NewL(CConditionManager& aManager); |
|
135 |
|
136 private: |
|
137 CPropertyNotifier(CConditionManager& aManager); |
|
138 void AttachL(); |
|
139 // From CActive |
|
140 void RunL(); |
|
141 void DoCancel(); |
|
142 |
|
143 public: |
|
144 void SetPropertyL(const TUid& aCategory, TUint aKey); |
|
145 |
|
146 private: |
|
147 TUid iCategory; |
|
148 TUint iKey; |
|
149 RProperty iProperty; |
|
150 CConditionManager& iConditionManager; |
|
151 }; |
|
152 |
|
153 // |
|
154 // class CConditionManager |
|
155 // This class manages a set of conditions for each schedule. It is used |
|
156 // solely by the CScheduleCriteriaManager class. When the set of conditions |
|
157 // is met, a the schedule manager is notified. |
|
158 NONSHARABLE_CLASS(CConditionManager) : public CActive |
|
159 { |
|
160 public: |
|
161 ~CConditionManager(); |
|
162 static CConditionManager* NewL(TInt aSchedule, CScheduleCriteriaManager& aManager); |
|
163 |
|
164 private: |
|
165 CConditionManager(TInt aSchedule, CScheduleCriteriaManager& aManager); |
|
166 TBool MatchAllConditionsL() const; |
|
167 TBool HasVariable(const TUid& aCategory, TUint aKey) const; |
|
168 void CompleteRequest(); |
|
169 // From CActive |
|
170 void RunL(); |
|
171 void DoCancel(); |
|
172 |
|
173 public: |
|
174 void ReplaceL(const RArray<TTaskSchedulerCondition>& aConditions); |
|
175 TInt Id(); |
|
176 void VariableChangedL(const TUid& aCategory, TUint aKey); |
|
177 //list capability |
|
178 static TInt Offset(); |
|
179 |
|
180 private: |
|
181 RArray<TTaskSchedulerCondition> iConditions; |
|
182 RPointerArray<CPropertyNotifier> iPropertyNotifiers; |
|
183 TInt iScheduleHandle; |
|
184 TSglQueLink iLink; |
|
185 CScheduleCriteriaManager& iManager; |
|
186 }; |
|
187 |
|
188 CConditionManager* CConditionManager::NewL(TInt aSchedule, CScheduleCriteriaManager& aManager) |
|
189 { |
|
190 CConditionManager* self = new(ELeave) CConditionManager(aSchedule, aManager); |
|
191 return self; |
|
192 } |
|
193 |
|
194 CConditionManager::CConditionManager(TInt aSchedule, CScheduleCriteriaManager& aManager) |
|
195 : CActive(EPriorityStandard+1), //make priority higher that propertynotifier AO |
|
196 iScheduleHandle(aSchedule), |
|
197 iManager(aManager) |
|
198 { |
|
199 CActiveScheduler::Add(this); |
|
200 } |
|
201 |
|
202 CConditionManager::~CConditionManager() |
|
203 { |
|
204 Cancel(); |
|
205 iPropertyNotifiers.ResetAndDestroy(); |
|
206 iConditions.Reset(); |
|
207 } |
|
208 |
|
209 //This function evaluates (aValue <op> aState) expression, where "op" could be |
|
210 //"==", "!=", ">", "<", depending on aType value, and returns the result of expression. |
|
211 static TBool DoMatchCondition(TTaskSchedulerCondition::TConditionType aType, |
|
212 TInt aValue, |
|
213 TInt aState) |
|
214 { |
|
215 if(aType == TTaskSchedulerCondition::EEquals) |
|
216 { |
|
217 if(aValue == aState) |
|
218 { |
|
219 return ETrue; |
|
220 } |
|
221 } |
|
222 else if(aType == TTaskSchedulerCondition::ENotEquals) |
|
223 { |
|
224 if(aValue != aState) |
|
225 { |
|
226 return ETrue; |
|
227 } |
|
228 } |
|
229 else if(aType == TTaskSchedulerCondition::EGreaterThan) |
|
230 { |
|
231 if(aValue > aState) |
|
232 { |
|
233 return ETrue; |
|
234 } |
|
235 } |
|
236 else if(aType == TTaskSchedulerCondition::ELessThan) |
|
237 { |
|
238 if(aValue < aState) |
|
239 { |
|
240 return ETrue; |
|
241 } |
|
242 } |
|
243 else |
|
244 { |
|
245 __ASSERT_ALWAYS(0, User::Invariant()); |
|
246 } |
|
247 return EFalse; |
|
248 } |
|
249 |
|
250 void CConditionManager::ReplaceL(const RArray<TTaskSchedulerCondition>& aConditions) |
|
251 { |
|
252 // Ensure any active requests are cancelled |
|
253 if(IsActive()) |
|
254 { |
|
255 Cancel(); |
|
256 } |
|
257 |
|
258 //destroying existing ones will cancel outstanding requests |
|
259 iPropertyNotifiers.ResetAndDestroy(); |
|
260 iConditions.Reset(); |
|
261 const TInt count = aConditions.Count(); |
|
262 TInt i; |
|
263 //Check that the properties already exist |
|
264 for(i=0;i<count;++i) |
|
265 { |
|
266 TInt value; |
|
267 TInt err = RProperty::Get(aConditions[i].iCategory, aConditions[i].iKey, value); |
|
268 if(err != KErrNone) |
|
269 { |
|
270 if(err == KErrNotFound) |
|
271 { |
|
272 err = KErrArgument; //use KErrArgument error code to signify bad conditions. |
|
273 } |
|
274 User::Leave(err); |
|
275 } |
|
276 } |
|
277 //Add the new conditions and notifiers. |
|
278 for(i=0;i<count;++i) |
|
279 { |
|
280 //Create local CPropertyNotifier object |
|
281 CPropertyNotifier* notifier = CPropertyNotifier::NewL(*this); |
|
282 CleanupStack::PushL(notifier); |
|
283 const TTaskSchedulerCondition& condition = aConditions[i]; |
|
284 notifier->SetPropertyL(condition.iCategory, condition.iKey); |
|
285 //Add condition |
|
286 User::LeaveIfError(iConditions.Append(condition)); |
|
287 //Add notifier |
|
288 TInt err = iPropertyNotifiers.Append(notifier); |
|
289 if(err != KErrNone) |
|
290 { |
|
291 iConditions.Remove(iConditions.Count() - 1);//Remove the condition we've just added |
|
292 User::Leave(err); |
|
293 } |
|
294 CleanupStack::Pop(notifier); |
|
295 } |
|
296 //Check to see that conditions are not already satisfied. |
|
297 if(MatchAllConditionsL()) |
|
298 { |
|
299 SetActive(); //we need to set AO active here, otherwise RunL wont be called. |
|
300 CompleteRequest(); |
|
301 } |
|
302 } |
|
303 |
|
304 void CConditionManager::CompleteRequest() |
|
305 { |
|
306 TRequestStatus *status = &iStatus; |
|
307 User::RequestComplete(status, KErrNone); // now compete request so RunL is triggered |
|
308 } |
|
309 |
|
310 //Respond to a condition changing. |
|
311 //Called from CPropertyNotifier::RunL(). |
|
312 void CConditionManager::VariableChangedL(const TUid& aCategory, TUint aKey) |
|
313 { |
|
314 //We have been notified that the value of one of the variables has been changed. |
|
315 //It is not enough to check that the variable's value satisfies its condition! |
|
316 //We have to check that all CConditionManager::iPropertyNotifiers satisfy their conditions. |
|
317 //---------------- |
|
318 //If this is a variable, which is a part of the variables, monitored by the |
|
319 //current CConditionManager object, only then do check variables values against |
|
320 //requested conditions |
|
321 if(HasVariable(aCategory, aKey)) |
|
322 { |
|
323 if(MatchAllConditionsL()) |
|
324 { |
|
325 SetActive(); //we need to set AO active here, otherwise RunL wont be called. |
|
326 CompleteRequest(); |
|
327 } |
|
328 } |
|
329 } |
|
330 |
|
331 void CConditionManager::RunL() |
|
332 { |
|
333 // cancel outstanding notification requests by destroying AO's |
|
334 iPropertyNotifiers.ResetAndDestroy(); |
|
335 iManager.DueSchedule(iScheduleHandle); |
|
336 } |
|
337 |
|
338 void CConditionManager::DoCancel() |
|
339 { |
|
340 CompleteRequest(); |
|
341 } |
|
342 |
|
343 //The method returns ETrue, if all monitored variables (aConditions array) |
|
344 //satisfy their conditions, EFalse otherwise. |
|
345 TBool CConditionManager::MatchAllConditionsL() const |
|
346 { |
|
347 TInt satisfiedConditionsCnt = 0; |
|
348 TInt count = iConditions.Count(); |
|
349 for(TInt i=0;i<count;++i) |
|
350 { |
|
351 const TTaskSchedulerCondition& condition = iConditions[i]; |
|
352 TInt value; |
|
353 // errors here typically indicate that the P&S variables is not of |
|
354 // integer type (ie its changed) or its been deleted |
|
355 User::LeaveIfError(RProperty::Get(condition.iCategory, condition.iKey, value)); |
|
356 if(::DoMatchCondition(condition.iType, value, condition.iState)) |
|
357 { |
|
358 ++satisfiedConditionsCnt; |
|
359 } |
|
360 } |
|
361 return satisfiedConditionsCnt == count; |
|
362 } |
|
363 |
|
364 //This method checks if the variable, identified by (aCategory, aKey) pair, is a part |
|
365 //of CConditionManager::iPropertyNotifiers array and returns ETrue, if that's true. |
|
366 //EFalse otherwise. |
|
367 TBool CConditionManager::HasVariable(const TUid& aCategory, TUint aKey) const |
|
368 { |
|
369 for(TInt i=iConditions.Count()-1;i>-1;--i) |
|
370 { |
|
371 if(iConditions[i].iCategory == aCategory && iConditions[i].iKey == aKey) |
|
372 { |
|
373 return ETrue; |
|
374 } |
|
375 } |
|
376 return EFalse; |
|
377 } |
|
378 |
|
379 TInt CConditionManager::Offset() |
|
380 { |
|
381 return (_FOFF(CConditionManager, iLink)); |
|
382 } |
|
383 |
|
384 TInt CConditionManager::Id() |
|
385 { |
|
386 return iScheduleHandle; |
|
387 } |
|
388 |
|
389 // |
|
390 |
|
391 CPropertyNotifier* CPropertyNotifier::NewL(CConditionManager& aManager) |
|
392 { |
|
393 CPropertyNotifier* self = new(ELeave) CPropertyNotifier(aManager); |
|
394 return self; |
|
395 } |
|
396 |
|
397 CPropertyNotifier::CPropertyNotifier(CConditionManager& aManager) |
|
398 : CActive(EPriorityStandard), |
|
399 iConditionManager(aManager) |
|
400 { |
|
401 CActiveScheduler::Add(this); |
|
402 } |
|
403 |
|
404 CPropertyNotifier::~CPropertyNotifier() |
|
405 { |
|
406 Cancel(); |
|
407 } |
|
408 |
|
409 void CPropertyNotifier::AttachL() |
|
410 { |
|
411 User::LeaveIfError(iProperty.Attach(iCategory, iKey)); |
|
412 iProperty.Subscribe(iStatus); |
|
413 SetActive(); |
|
414 } |
|
415 |
|
416 void CPropertyNotifier::SetPropertyL(const TUid& aCategory, TUint aKey) |
|
417 { |
|
418 if (IsActive()) |
|
419 Cancel(); |
|
420 iCategory = aCategory; |
|
421 iKey = aKey; |
|
422 AttachL(); |
|
423 } |
|
424 |
|
425 // Respond to a condition changing |
|
426 void CPropertyNotifier::RunL() |
|
427 { |
|
428 if (iStatus.Int() >= KErrNone) |
|
429 { |
|
430 iConditionManager.VariableChangedL(iCategory, iKey); |
|
431 AttachL(); |
|
432 } |
|
433 // if status is KErrNotFound then P&S variable has been deleted! By |
|
434 // resubscribing we wait for it to be created. If it never gets |
|
435 // created then TRequestStatus never completes so this condition |
|
436 // never gets met and iConditionManager.VariableChanged which |
|
437 // makes sense. |
|
438 else if (iStatus.Int() == KErrNotFound) |
|
439 AttachL(); |
|
440 // If status is another error we have a problem!!! Whatever the case |
|
441 // we should just ignore this condition from now on by doing nothing. |
|
442 } |
|
443 |
|
444 void CPropertyNotifier::DoCancel() |
|
445 { |
|
446 iProperty.Cancel(); |
|
447 } |
|
448 |
|
449 |
|
450 |
|
451 // |
|
452 |
|
453 CScheduleCriteriaManager* CScheduleCriteriaManager::NewL(CTaskScheduler& aOwner) |
|
454 { |
|
455 CScheduleCriteriaManager* self = new(ELeave) CScheduleCriteriaManager(aOwner); |
|
456 return self; |
|
457 } |
|
458 |
|
459 CScheduleCriteriaManager::~CScheduleCriteriaManager() |
|
460 { |
|
461 Cancel(); |
|
462 RemoveTimers(); |
|
463 RemoveConditions(); |
|
464 } |
|
465 |
|
466 CScheduleCriteriaManager::CScheduleCriteriaManager(CTaskScheduler& aOwner) |
|
467 : CActive(EPriorityStandard+2), //make priority higher than condition AO |
|
468 iTaskScheduler(aOwner), |
|
469 iTimers(CScheduleTimer::Offset()), |
|
470 iConditions(CConditionManager::Offset()) |
|
471 { |
|
472 CActiveScheduler::Add(this); |
|
473 } |
|
474 |
|
475 void CScheduleCriteriaManager::CompleteRequest() |
|
476 { |
|
477 TRequestStatus *status = &iStatus; |
|
478 User::RequestComplete(status, KErrNone); // now compete request so RunL is triggered |
|
479 } |
|
480 |
|
481 void CScheduleCriteriaManager::DueSchedule(TInt aScheduleHandle) |
|
482 { |
|
483 iDueScheduleHandle = aScheduleHandle; |
|
484 SetActive(); // need to set AO active so RunL will subsequently be called. |
|
485 CompleteRequest(); |
|
486 } |
|
487 |
|
488 void CScheduleCriteriaManager::RunL() |
|
489 { |
|
490 // remove schedule and then notify task scheduler manager |
|
491 RemoveSchedule(iDueScheduleHandle); |
|
492 iTaskScheduler.DueTaskNotifyL(iDueScheduleHandle); |
|
493 } |
|
494 |
|
495 void CScheduleCriteriaManager::DoCancel() |
|
496 { |
|
497 CompleteRequest(); |
|
498 } |
|
499 |
|
500 // If schedule timer for this ID doesnt exist then create and add new timer. If schedule |
|
501 // timer does exist then just amend existing timer. |
|
502 //When one of the schedule entries in this schedule has become due, |
|
503 //this function will be called with aNotFirstTime = ETrue |
|
504 //If this function is called because of environment changes then aSchChange = EOnlyTime and only update time based schedule |
|
505 void CScheduleCriteriaManager::ReplaceScheduleL(CSchedule& aSchedule, TSchChangeType aSchChange , TBool aNotFirstTime) |
|
506 { |
|
507 aSchedule.CalculateDueTime(aNotFirstTime); |
|
508 |
|
509 TInt scheduleId = aSchedule.Id(); |
|
510 const TTsTime nextTime = aSchedule.DueTime(); |
|
511 ReplaceScheduleL(nextTime,scheduleId); |
|
512 |
|
513 //If this function is called because of environment changes then |
|
514 //leave conditions unchanged |
|
515 if(aSchChange == EOnlyTime) |
|
516 return; |
|
517 CConditionManager* condition = FindCondition(scheduleId); |
|
518 // no point in doing work for |
|
519 if(aSchedule.Conditions().Count() > 0) |
|
520 { |
|
521 if(!condition) |
|
522 { |
|
523 condition = CConditionManager::NewL(scheduleId, *this); |
|
524 iConditions.AddLast(*condition); |
|
525 } |
|
526 condition->ReplaceL(aSchedule.Conditions()); |
|
527 } |
|
528 else if(condition) |
|
529 RemoveCondition(condition); |
|
530 } |
|
531 |
|
532 // If schedule timer for this ID doesnt exist then create and add new timer. If schedule |
|
533 // timer does exist then just amend existing timer. |
|
534 void CScheduleCriteriaManager::ReplaceScheduleL(const TTsTime& aNextTime, |
|
535 TInt aSchedule) |
|
536 { |
|
537 CScheduleTimer* timer = Find(aSchedule); |
|
538 // if time is set to MaxTTime then we don't want to set a timer |
|
539 // off as it will complete straight away. |
|
540 if((aNextTime.GetUtcTime() != Time::MaxTTime()) |
|
541 && (aNextTime.GetLocalTime() != Time::MaxTTime())) |
|
542 { |
|
543 if(!timer) |
|
544 { |
|
545 timer = CScheduleTimer::NewL(aSchedule, *this); |
|
546 iTimers.AddLast(*timer); |
|
547 } |
|
548 timer->SetNext(aNextTime); |
|
549 } |
|
550 else if(timer) |
|
551 { |
|
552 RemoveTimer(timer); // make sure we remove the old one! |
|
553 } |
|
554 } |
|
555 |
|
556 void CScheduleCriteriaManager::RemoveSchedule(TInt aSchedule) |
|
557 { |
|
558 CScheduleTimer* timer = Find(aSchedule); |
|
559 if(timer) |
|
560 RemoveTimer(timer); // remove timer also terminates AO |
|
561 |
|
562 CConditionManager* condition = FindCondition(aSchedule); |
|
563 if(condition) |
|
564 RemoveCondition(condition); // remove condition also terminates AO |
|
565 |
|
566 } |
|
567 |
|
568 //Timer methods |
|
569 void CScheduleCriteriaManager::RemoveTimers() |
|
570 { |
|
571 CScheduleTimer* timer; |
|
572 TSglQueIter<CScheduleTimer> timerIter(iTimers); |
|
573 timerIter.SetToFirst(); |
|
574 while ((timer = timerIter++) != NULL) |
|
575 { |
|
576 RemoveTimer(timer); |
|
577 } |
|
578 } |
|
579 |
|
580 void CScheduleCriteriaManager::RemoveTimer(CScheduleTimer* aTimer) |
|
581 { |
|
582 iTimers.Remove(*aTimer); |
|
583 delete aTimer; |
|
584 } |
|
585 |
|
586 CScheduleTimer* CScheduleCriteriaManager::Find(TInt aSchedule) |
|
587 { |
|
588 CScheduleTimer* timer = NULL; |
|
589 TSglQueIter<CScheduleTimer> timerIter(iTimers); |
|
590 timerIter.SetToFirst(); |
|
591 while ((timer = timerIter++) != NULL) |
|
592 { |
|
593 if (timer->Id() == aSchedule) |
|
594 break; |
|
595 } |
|
596 return timer; |
|
597 } |
|
598 |
|
599 // condition methods |
|
600 void CScheduleCriteriaManager::RemoveConditions() |
|
601 { |
|
602 CConditionManager* condition; |
|
603 TSglQueIter<CConditionManager> conditionIter(iConditions); |
|
604 conditionIter.SetToFirst(); |
|
605 while ((condition = conditionIter++) != NULL) |
|
606 { |
|
607 RemoveCondition(condition); |
|
608 } |
|
609 } |
|
610 |
|
611 void CScheduleCriteriaManager::RemoveCondition(CConditionManager* aCondition) |
|
612 { |
|
613 iConditions.Remove(*aCondition); |
|
614 delete aCondition; |
|
615 } |
|
616 |
|
617 CConditionManager* CScheduleCriteriaManager::FindCondition(TInt aSchedule) |
|
618 { |
|
619 CConditionManager* condition = NULL; |
|
620 TSglQueIter<CConditionManager> conditionIter(iConditions); |
|
621 conditionIter.SetToFirst(); |
|
622 while ((condition = conditionIter++) != NULL) |
|
623 { |
|
624 if (condition->Id() == aSchedule) |
|
625 break; |
|
626 } |
|
627 return condition; |
|
628 } |
|
629 |
|
630 |