Mercurial > hg > orthanc-stone
comparison Framework/SmartLoader.cpp @ 322:a902a07769d4 am-2
wip: preload slice
author | am@osimis.io |
---|---|
date | Mon, 15 Oct 2018 22:43:02 +0200 |
parents | 3a4ca166fafa |
children | 7a364e44fbb4 |
comparison
equal
deleted
inserted
replaced
321:56b2e47d3c0c | 322:a902a07769d4 |
---|---|
29 | 29 |
30 namespace OrthancStone | 30 namespace OrthancStone |
31 { | 31 { |
32 enum CachedSliceStatus | 32 enum CachedSliceStatus |
33 { | 33 { |
34 CachedSliceStatus_Loading, | 34 CachedSliceStatus_ScheduledToLoad, |
35 CachedSliceStatus_Loaded | 35 CachedSliceStatus_GeometryLoaded, |
36 CachedSliceStatus_ImageLoaded | |
36 }; | 37 }; |
37 | 38 |
38 class SmartLoader::CachedSlice : public LayerSourceBase | 39 class SmartLoader::CachedSlice : public LayerSourceBase |
39 { | 40 { |
40 public: | 41 public: |
101 // - if currently loading, we need to return an object that will observe the existing LayerSource and forward | 102 // - if currently loading, we need to return an object that will observe the existing LayerSource and forward |
102 // the messages to its observables | 103 // the messages to its observables |
103 // in both cases, we must be carefull about objects lifecycle !!! | 104 // in both cases, we must be carefull about objects lifecycle !!! |
104 | 105 |
105 std::auto_ptr<ILayerSource> layerSource; | 106 std::auto_ptr<ILayerSource> layerSource; |
106 | 107 std::string sliceKeyId = instanceId + ":" + std::to_string(frame); |
107 if (cachedSlices_.find(instanceId) != cachedSlices_.end() && cachedSlices_[instanceId]->status_ == CachedSliceStatus_Loaded) | 108 |
108 { | 109 if (cachedSlices_.find(sliceKeyId) != cachedSlices_.end()) // && cachedSlices_[sliceKeyId]->status_ == CachedSliceStatus_Loaded) |
109 layerSource.reset(cachedSlices_[instanceId]->Clone()); | 110 { |
111 layerSource.reset(cachedSlices_[sliceKeyId]->Clone()); | |
110 } | 112 } |
111 else | 113 else |
112 { | 114 { |
113 layerSource.reset(new OrthancFrameLayerSource(IObserver::broker_, orthancApiClient_)); | 115 layerSource.reset(new OrthancFrameLayerSource(IObserver::broker_, orthancApiClient_)); |
114 dynamic_cast<OrthancFrameLayerSource*>(layerSource.get())->SetImageQuality(imageQuality_); | 116 dynamic_cast<OrthancFrameLayerSource*>(layerSource.get())->SetImageQuality(imageQuality_); |
138 cachedSlice->NotifyGeometryReady(); | 140 cachedSlice->NotifyGeometryReady(); |
139 } | 141 } |
140 | 142 |
141 } | 143 } |
142 | 144 |
143 | 145 void SmartLoader::PreloadSlice(const std::string instanceId, unsigned int frame) |
144 void SmartLoader::LoadStudyList() | 146 { |
145 { | 147 // TODO: check if it is already in the cache |
146 // orthancApiClient_.ScheduleGetJsonRequest("/studies"); | 148 |
147 } | 149 // create the slice in the cache with "empty" data |
148 | 150 boost::shared_ptr<CachedSlice> cachedSlice(new CachedSlice(IObserver::broker_)); |
149 void PreloadStudy(const std::string studyId) | 151 cachedSlice->slice_.reset(new Slice(instanceId, frame)); |
150 { | 152 cachedSlice->status_ = CachedSliceStatus_ScheduledToLoad; |
151 /* TODO */ | 153 std::string sliceKeyId = instanceId + ":" + std::to_string(frame); |
152 } | 154 |
153 | 155 cachedSlices_[sliceKeyId] = boost::shared_ptr<CachedSlice>(cachedSlice); |
154 void PreloadSeries(const std::string seriesId) | 156 |
155 { | 157 std::auto_ptr<ILayerSource> layerSource(new OrthancFrameLayerSource(IObserver::broker_, orthancApiClient_)); |
156 /* TODO */ | 158 |
157 } | 159 dynamic_cast<OrthancFrameLayerSource*>(layerSource.get())->SetImageQuality(imageQuality_); |
160 layerSource->RegisterObserverCallback(new Callable<SmartLoader, ILayerSource::GeometryReadyMessage>(*this, &SmartLoader::OnLayerGeometryReady)); | |
161 layerSource->RegisterObserverCallback(new Callable<SmartLoader, ILayerSource::ImageReadyMessage>(*this, &SmartLoader::OnImageReady)); | |
162 layerSource->RegisterObserverCallback(new Callable<SmartLoader, ILayerSource::LayerReadyMessage>(*this, &SmartLoader::OnLayerReady)); | |
163 dynamic_cast<OrthancFrameLayerSource*>(layerSource.get())->LoadFrame(instanceId, frame); | |
164 | |
165 // keep a ref to the LayerSource until the slice is fully loaded and saved to cache | |
166 preloadingInstances_[sliceKeyId] = boost::shared_ptr<ILayerSource>(layerSource.release()); | |
167 } | |
168 | |
169 | |
170 // void PreloadStudy(const std::string studyId) | |
171 // { | |
172 // /* TODO */ | |
173 // } | |
174 | |
175 // void PreloadSeries(const std::string seriesId) | |
176 // { | |
177 // /* TODO */ | |
178 // } | |
158 | 179 |
159 | 180 |
160 void SmartLoader::OnLayerGeometryReady(const ILayerSource::GeometryReadyMessage& message) | 181 void SmartLoader::OnLayerGeometryReady(const ILayerSource::GeometryReadyMessage& message) |
161 { | 182 { |
162 OrthancFrameLayerSource& source = dynamic_cast<OrthancFrameLayerSource&>(message.origin_); | 183 OrthancFrameLayerSource& source = dynamic_cast<OrthancFrameLayerSource&>(message.origin_); |
163 // save the slice | 184 |
185 // save/replace the slice in cache | |
164 const Slice& slice = source.GetSlice(0); // TODO handle GetSliceCount() | 186 const Slice& slice = source.GetSlice(0); // TODO handle GetSliceCount() |
165 std::string instanceId = slice.GetOrthancInstanceId(); | 187 std::string sliceKeyId = slice.GetOrthancInstanceId() + ":" + std::to_string(slice.GetFrame()); |
166 | 188 |
167 CachedSlice* cachedSlice = new CachedSlice(IObserver::broker_); | 189 boost::shared_ptr<CachedSlice> cachedSlice(new CachedSlice(IObserver::broker_)); |
168 cachedSlice->slice_.reset(slice.Clone()); | 190 cachedSlice->slice_.reset(slice.Clone()); |
169 cachedSlice->effectiveQuality_ = source.GetImageQuality(); | 191 cachedSlice->effectiveQuality_ = source.GetImageQuality(); |
170 cachedSlice->status_ = CachedSliceStatus_Loading; | 192 cachedSlice->status_ = CachedSliceStatus_GeometryLoaded; |
171 | 193 |
172 cachedSlices_[instanceId] = boost::shared_ptr<CachedSlice>(cachedSlice); | 194 cachedSlices_[sliceKeyId] = boost::shared_ptr<CachedSlice>(cachedSlice); |
173 | 195 |
174 // re-emit original Layer message to observers | 196 // re-emit original Layer message to observers |
175 EmitMessage(message); | 197 EmitMessage(message); |
176 } | 198 } |
177 | 199 |
178 void SmartLoader::OnImageReady(const ILayerSource::ImageReadyMessage& message) | 200 void SmartLoader::OnImageReady(const ILayerSource::ImageReadyMessage& message) |
179 { | 201 { |
180 OrthancFrameLayerSource& source = dynamic_cast<OrthancFrameLayerSource&>(message.origin_); | 202 OrthancFrameLayerSource& source = dynamic_cast<OrthancFrameLayerSource&>(message.origin_); |
181 | 203 |
182 // save the slice | 204 // save/replace the slice in cache |
183 const Slice& slice = source.GetSlice(0); // TODO handle GetSliceCount() ? | 205 const Slice& slice = source.GetSlice(0); // TODO handle GetSliceCount() ? |
184 std::string instanceId = slice.GetOrthancInstanceId(); | 206 std::string sliceKeyId = slice.GetOrthancInstanceId() + ":" + std::to_string(slice.GetFrame()); |
185 | 207 |
186 boost::shared_ptr<CachedSlice> cachedSlice(new CachedSlice(IObserver::broker_)); | 208 boost::shared_ptr<CachedSlice> cachedSlice(new CachedSlice(IObserver::broker_)); |
187 cachedSlice->image_ = message.image_; | 209 cachedSlice->image_ = message.image_; |
188 cachedSlice->effectiveQuality_ = message.imageQuality_; | 210 cachedSlice->effectiveQuality_ = message.imageQuality_; |
189 cachedSlice->slice_.reset(message.slice_.Clone()); | 211 cachedSlice->slice_.reset(message.slice_.Clone()); |
190 cachedSlice->status_ = CachedSliceStatus_Loaded; | 212 cachedSlice->status_ = CachedSliceStatus_ImageLoaded; |
191 | 213 |
192 cachedSlices_[instanceId] = cachedSlice; | 214 cachedSlices_[sliceKeyId] = cachedSlice; |
193 | 215 |
194 // re-emit original Layer message to observers | 216 // re-emit original Layer message to observers |
195 EmitMessage(message); | 217 EmitMessage(message); |
196 } | 218 } |
197 | 219 |
198 void SmartLoader::OnLayerReady(const ILayerSource::LayerReadyMessage& message) | 220 void SmartLoader::OnLayerReady(const ILayerSource::LayerReadyMessage& message) |
199 { | 221 { |
222 OrthancFrameLayerSource& source = dynamic_cast<OrthancFrameLayerSource&>(message.origin_); | |
223 const Slice& slice = source.GetSlice(0); // TODO handle GetSliceCount() ? | |
224 std::string sliceKeyId = slice.GetOrthancInstanceId() + ":" + std::to_string(slice.GetFrame()); | |
225 | |
226 // remove the slice from the preloading slices now that it has been fully loaded and it is referenced in the cache | |
227 if (preloadingInstances_.find(sliceKeyId) != preloadingInstances_.end()) | |
228 { | |
229 preloadingInstances_.erase(sliceKeyId); | |
230 } | |
231 | |
200 // re-emit original Layer message to observers | 232 // re-emit original Layer message to observers |
201 EmitMessage(message); | 233 EmitMessage(message); |
202 } | 234 } |
203 | 235 |
204 } | 236 } |