Merge "Convert the Underline and Shadow deprecated APIs to the new ones." into devel...
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / image-loader / image-load-thread.cpp
1 /*
2  * Copyright (c) 2015 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 // CLASS HEADER
19 #include "image-load-thread.h"
20
21 namespace Dali
22 {
23
24 namespace Toolkit
25 {
26
27 namespace Internal
28 {
29
30 LoadingTask::LoadingTask(uint32_t id, BitmapLoader loader )
31 : loader( loader ),
32   id( id )
33 {
34 }
35
36 ImageLoadThread::ImageLoadThread( EventThreadCallback* trigger )
37 : mTrigger( trigger )
38 {
39 }
40
41 ImageLoadThread::~ImageLoadThread()
42 {
43   // add an empty task would stop the thread from conditional wait.
44   AddTask( NULL );
45   // stop the thread
46   Join();
47
48   delete mTrigger;
49 }
50
51 void ImageLoadThread::Run()
52 {
53   while( LoadingTask* task =  NextTaskToProcess())
54   {
55     task->loader.Load();
56     AddCompletedTask( task );
57   }
58 }
59
60 void ImageLoadThread::AddTask( LoadingTask* task )
61 {
62   bool wasEmpty = false;
63
64   {
65     // Lock while adding task to the queue
66     ConditionalWait::ScopedLock lock( mConditionalWait );
67     wasEmpty = mLoadQueue.Empty();
68     mLoadQueue.PushBack( task );
69   }
70
71   if( wasEmpty)
72   {
73     // wake up the image loading thread
74     mConditionalWait.Notify();
75   }
76 }
77
78 LoadingTask* ImageLoadThread::NextCompletedTask()
79 {
80   // Lock while popping task out from the queue
81   Mutex::ScopedLock lock( mMutex );
82
83   if( mCompleteQueue.Empty() )
84   {
85     return NULL;
86   }
87
88   Vector< LoadingTask* >::Iterator next = mCompleteQueue.Begin();
89   LoadingTask* nextTask = *next;
90   mCompleteQueue.Erase( next );
91
92   return nextTask;
93 }
94
95 bool ImageLoadThread::CancelTask( uint32_t loadingTaskId )
96 {
97   // Lock while remove task from the queue
98   ConditionalWait::ScopedLock lock( mConditionalWait );
99
100   for( Vector< LoadingTask* >::Iterator iter = mLoadQueue.Begin(); iter != mLoadQueue.End(); iter++ )
101   {
102     if( (*iter)->id == loadingTaskId )
103     {
104       delete (*iter);
105       mLoadQueue.Erase( iter );
106       return true;
107     }
108   }
109
110   return false;
111 }
112
113
114 void ImageLoadThread::CancelAll()
115 {
116   // Lock while remove task from the queue
117   ConditionalWait::ScopedLock lock( mConditionalWait );
118
119   for( Vector< LoadingTask* >::Iterator iter = mLoadQueue.Begin(); iter != mLoadQueue.End(); iter++ )
120   {
121     delete (*iter);
122   }
123   mLoadQueue.Clear();
124 }
125
126 LoadingTask* ImageLoadThread::NextTaskToProcess()
127 {
128   // Lock while popping task out from the queue
129   ConditionalWait::ScopedLock lock( mConditionalWait );
130
131   while( mLoadQueue.Empty() )
132   {
133     mConditionalWait.Wait( lock );
134   }
135
136   Vector< LoadingTask* >::Iterator next = mLoadQueue.Begin();
137   LoadingTask* nextTask = *next;
138   mLoadQueue.Erase( next );
139
140   return nextTask;
141 }
142
143 void ImageLoadThread::AddCompletedTask( LoadingTask* task )
144 {
145   // Lock while adding task to the queue
146   Mutex::ScopedLock lock( mMutex );
147   mCompleteQueue.PushBack( task );
148
149   // wake up the main thread
150   mTrigger->Trigger();
151 }
152
153
154
155 } // namespace Internal
156
157 } // namespace Toolkit
158
159 } // namespace Dali