Conversion to Apache 2.0 license
[platform/core/uifw/dali-core.git] / dali / internal / event / resources / resource-ticket.cpp
1 /*
2  * Copyright (c) 2014 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 <dali/internal/event/resources/resource-ticket.h>
20
21 // EXTERNAL INCLUDES
22 #include <algorithm>
23
24 // INTERNAL INCLUDES
25 #include <dali/public-api/common/dali-common.h>
26 #include <dali/public-api/images/image.h>
27 #include <dali/internal/event/common/stage-impl.h>
28 #include <dali/internal/event/resources/resource-ticket-observer.h>
29 #include <dali/internal/event/resources/resource-ticket-lifetime-observer.h>
30
31 using namespace std;
32
33 namespace // unnamed namespace
34 {
35
36 // predicate for std::remove_if algorithm for compressing observer list
37 bool isNULL(void* ptr)
38 {
39   return ptr == NULL;
40 }
41
42 } // unnamed namespace
43
44 namespace Dali
45 {
46
47 namespace Internal
48 {
49
50 ResourceTicket::ResourceTicket( ResourceTicketLifetimeObserver& observer, unsigned int id, ResourceTypePath& typePath )
51 : mLifetimeObserver( &observer ),
52   mId( id ),
53   mTypePath( typePath ),
54   mLoadingState( ResourceLoading )
55 {
56 }
57
58 ResourceTicket::~ResourceTicket()
59 {
60   // Guard to allow handle destruction after Core has been destroyed
61   if ( Stage::IsInstalled() &&
62        mLifetimeObserver )
63   {
64     mLifetimeObserver->ResourceTicketDiscarded( *this );
65   }
66 }
67
68 void ResourceTicket::AddObserver(ResourceTicketObserver& observer)
69 {
70   mObservers.push_back(&observer);
71 }
72
73 void ResourceTicket::RemoveObserver(ResourceTicketObserver& observer)
74 {
75   ObserverIter iter = find(mObservers.begin(), mObservers.end(), &observer);
76   DALI_ASSERT_DEBUG( mObservers.end() != iter );
77   if( mObservers.end() != iter )
78   {
79     (*iter) = NULL;
80   }
81 }
82
83 void ResourceTicket::LoadingSucceeded()
84 {
85   DALI_ASSERT_DEBUG(mLoadingState == ResourceLoading);
86
87   mLoadingState = ResourceLoadingSucceeded;
88
89   // Using array operator as the call back out to application code might call back in
90   // and corrupt the mObservers list. Presumption is the operator gets the current address
91   // and adds an offset so a push_back() triggered reallocation should still work.
92   size_t count = mObservers.size();
93   for(size_t i = 0; i < count; i++)
94   {
95     if( mObservers[i] != NULL)
96     {
97       mObservers[i]->ResourceLoadingSucceeded(*this);
98     }
99   }
100
101   // Move NULL pointers to the end...
102   ObserverIter endIter = remove_if( mObservers.begin(), mObservers.end(), isNULL );
103
104   // ...and remove them
105   mObservers.erase( endIter, mObservers.end() );
106 }
107
108 void ResourceTicket::LoadingFailed()
109 {
110   DALI_ASSERT_DEBUG(mLoadingState == ResourceLoading);
111
112   mLoadingState = ResourceLoadingFailed;
113
114   // Using array operator as the call back out to application code might call back in
115   // and corrupt the mObservers list. Presumption is the operator gets the current address
116   // and adds an offset so a push_back() triggered reallocation should still work.
117   size_t count = mObservers.size();
118   for(size_t i = 0; i < count; i++)
119   {
120     if( mObservers[i] != NULL)
121     {
122       mObservers[i]->ResourceLoadingFailed(*this);
123     }
124   }
125
126   // Move NULL pointers to the end...
127   ObserverIter endIter = remove_if( mObservers.begin(), mObservers.end(), isNULL );
128
129   // ...and remove them
130   mObservers.erase( endIter, mObservers.end() );
131 }
132
133 void ResourceTicket::Loading()
134 {
135   mLoadingState = ResourceLoading;
136
137   // Move NULL pointers to the end...
138   ObserverIter endIter = remove_if( mObservers.begin(), mObservers.end(), isNULL );
139
140   // ...and remove them
141   mObservers.erase( endIter, mObservers.end() );
142 }
143
144 void ResourceTicket::Uploaded()
145 {
146   // Using array operator as the call back out to application code might call back in
147   // and corrupt the mObservers list. Presumption is the operator gets the current address
148   // and adds an offset so a push_back() triggered reallocation should still work.
149   size_t count = mObservers.size();
150   for(size_t i = 0; i < count; i++)
151   {
152     if( mObservers[i] != NULL)
153     {
154       mObservers[i]->ResourceUploaded(*this);
155     }
156   }
157
158   // Move NULL pointers to the end...
159   ObserverIter endIter = remove_if( mObservers.begin(), mObservers.end(), isNULL );
160
161   // ...and remove them
162   mObservers.erase( endIter, mObservers.end() );
163 }
164
165 void ResourceTicket::SavingSucceeded()
166 {
167   // Using array operator as the call back out to application code might call back in
168   // and corrupt the mObservers list. Presumption is the operator gets the current address
169   // and adds an offset so a push_back() triggered reallocation should still work.
170   size_t count = mObservers.size();
171   for(size_t i = 0; i < count; i++)
172   {
173     if( mObservers[i] != NULL)
174     {
175       mObservers[i]->ResourceSavingSucceeded(*this);
176     }
177   }
178
179   // Move NULL pointers to the end...
180   ObserverIter endIter = remove_if( mObservers.begin(), mObservers.end(), isNULL );
181
182   // ...and remove them
183   mObservers.erase( endIter, mObservers.end() );
184 }
185
186 void ResourceTicket::SavingFailed()
187 {
188   // Using array operator as the call back out to application code might call back in
189   // and corrupt the mObservers list. Presumption is the operator gets the current address
190   // and adds an offset so a push_back() triggered reallocation should still work.
191   size_t count = mObservers.size();
192   for(size_t i = 0; i < count; i++)
193   {
194     if( mObservers[i] != NULL)
195     {
196       mObservers[i]->ResourceSavingFailed(*this);
197     }
198   }
199
200   // Move NULL pointers to the end...
201   ObserverIter endIter = remove_if( mObservers.begin(), mObservers.end(), isNULL );
202
203   // ...and remove them
204   mObservers.erase( endIter, mObservers.end() );
205 }
206
207 void ResourceTicket::StopLifetimeObservation()
208 {
209   mLifetimeObserver = NULL;
210 }
211
212 } // namespace Internal
213
214 } // namespace Dali
215