Merge branch 'devel/master (1.2.0)' into tizen
[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 namespace // unnamed namespace
32 {
33
34 // predicate for std::remove_if algorithm for compressing observer list
35 bool isNULL(void* ptr)
36 {
37   return ptr == NULL;
38 }
39
40 } // unnamed namespace
41
42 namespace Dali
43 {
44
45 namespace Internal
46 {
47
48 ResourceTicket::ResourceTicket( ResourceTicketLifetimeObserver& observer, unsigned int id, ResourceTypePath& typePath )
49 : mLifetimeObserver( &observer ),
50   mId( id ),
51   mTypePath( typePath ),
52   mLoadingState( ResourceLoading )
53 {
54 }
55
56 ResourceTicket::~ResourceTicket()
57 {
58   // Guard to allow handle destruction after Core has been destroyed
59   if ( Stage::IsInstalled() &&
60        mLifetimeObserver )
61   {
62     mLifetimeObserver->ResourceTicketDiscarded( *this );
63   }
64 }
65
66 void ResourceTicket::AddObserver(ResourceTicketObserver& observer)
67 {
68   mObservers.push_back(&observer);
69 }
70
71 void ResourceTicket::RemoveObserver(ResourceTicketObserver& observer)
72 {
73   ObserverIter iter = find(mObservers.begin(), mObservers.end(), &observer);
74   DALI_ASSERT_DEBUG( mObservers.end() != iter );
75   if( mObservers.end() != iter )
76   {
77     (*iter) = NULL;
78   }
79 }
80
81 void ResourceTicket::LoadingSucceeded()
82 {
83   DALI_ASSERT_DEBUG(mLoadingState == ResourceLoading);
84
85   mLoadingState = ResourceLoadingSucceeded;
86
87   // Using array operator as the call back out to application code might call back in
88   // and corrupt the mObservers list. Presumption is the operator gets the current address
89   // and adds an offset so a push_back() triggered reallocation should still work.
90   size_t count = mObservers.size();
91   for(size_t i = 0; i < count; i++)
92   {
93     if( mObservers[i] != NULL)
94     {
95       mObservers[i]->ResourceLoadingSucceeded(*this);
96     }
97   }
98
99   // Move NULL pointers to the end...
100   ObserverIter endIter = remove_if( mObservers.begin(), mObservers.end(), isNULL );
101
102   // ...and remove them
103   mObservers.erase( endIter, mObservers.end() );
104 }
105
106 void ResourceTicket::LoadingFailed()
107 {
108   DALI_ASSERT_DEBUG(mLoadingState == ResourceLoading);
109
110   mLoadingState = ResourceLoadingFailed;
111
112   // Using array operator as the call back out to application code might call back in
113   // and corrupt the mObservers list. Presumption is the operator gets the current address
114   // and adds an offset so a push_back() triggered reallocation should still work.
115   size_t count = mObservers.size();
116   for(size_t i = 0; i < count; i++)
117   {
118     if( mObservers[i] != NULL)
119     {
120       mObservers[i]->ResourceLoadingFailed(*this);
121     }
122   }
123
124   // Move NULL pointers to the end...
125   ObserverIter endIter = remove_if( mObservers.begin(), mObservers.end(), isNULL );
126
127   // ...and remove them
128   mObservers.erase( endIter, mObservers.end() );
129 }
130
131 void ResourceTicket::Loading()
132 {
133   mLoadingState = ResourceLoading;
134
135   // Move NULL pointers to the end...
136   ObserverIter endIter = remove_if( mObservers.begin(), mObservers.end(), isNULL );
137
138   // ...and remove them
139   mObservers.erase( endIter, mObservers.end() );
140 }
141
142 void ResourceTicket::Uploaded()
143 {
144   // Using array operator as the call back out to application code might call back in
145   // and corrupt the mObservers list. Presumption is the operator gets the current address
146   // and adds an offset so a push_back() triggered reallocation should still work.
147   size_t count = mObservers.size();
148   for(size_t i = 0; i < count; i++)
149   {
150     if( mObservers[i] != NULL)
151     {
152       mObservers[i]->ResourceUploaded(*this);
153     }
154   }
155
156   // Move NULL pointers to the end...
157   ObserverIter endIter = remove_if( mObservers.begin(), mObservers.end(), isNULL );
158
159   // ...and remove them
160   mObservers.erase( endIter, mObservers.end() );
161 }
162
163 void ResourceTicket::StopLifetimeObservation()
164 {
165   mLifetimeObserver = NULL;
166 }
167
168 } // namespace Internal
169
170 } // namespace Dali
171