2 // PithosActivityFacility.m
5 // Copyright 2011-2012 GRNET S.A. All rights reserved.
7 // Redistribution and use in source and binary forms, with or
8 // without modification, are permitted provided that the following
11 // 1. Redistributions of source code must retain the above
12 // copyright notice, this list of conditions and the following
15 // 2. Redistributions in binary form must reproduce the above
16 // copyright notice, this list of conditions and the following
17 // disclaimer in the documentation and/or other materials
18 // provided with the distribution.
20 // THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
21 // OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
24 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
27 // USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
28 // AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
30 // ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 // POSSIBILITY OF SUCH DAMAGE.
33 // The views and conclusions contained in the software and
34 // documentation are those of the authors and should not be
35 // interpreted as representing official policies, either expressed
36 // or implied, of GRNET S.A.
38 #import "PithosActivityFacility.h"
39 #import "PithosAccount.h"
40 #import "pithos_macosAppDelegate.h"
42 static PithosActivityFacility *defaultPithosActivityFacility = nil;
44 @implementation PithosActivityFacility
48 #pragma mark - Singleton
50 + (id)defaultPithosActivityFacility {
52 if (!defaultPithosActivityFacility)
53 [[self alloc] init]; // Assignment not done here
55 return defaultPithosActivityFacility;
58 + (id)allocWithZone:(NSZone *)zone {
60 if (!defaultPithosActivityFacility) {
61 defaultPithosActivityFacility = [super allocWithZone:zone];
62 return defaultPithosActivityFacility;
68 - (id)copyWithZone:(NSZone *)zone {
76 - (NSUInteger)retainCount {
77 return UINT_MAX; // Can not be released
89 #pragma mark Object Lifecycle
92 if ((self = [super init])) {
101 [runningActivities release];
102 [endingActivities release];
107 @synchronized(self) {
111 [runningActivities release];
112 runningActivities = [[NSMutableArray alloc] init];
113 [endingActivities release];
114 endingActivities = [[NSMutableArray alloc] init];
115 totalUploadBytes = 0;
116 currentUploadBytes = 0;
117 totalDownloadBytes = 0;
118 currentDownloadBytes = 0;
122 timer = [[NSTimer scheduledTimerWithTimeInterval:[(pithos_macosAppDelegate *)[[NSApplication sharedApplication] delegate] activityFacilityTimeInterval]
124 selector:@selector(update:)
126 repeats:YES] retain];
130 - (NSString *)description {
131 return [NSString stringWithFormat:@"running activities: %lu, ending activities: %lu, totalUploadBytes: %lu, currentUploadBytes: %lu, totalDownloadBytes: %lu, currentDownloadBytes: %lu",
132 [runningActivities count], [endingActivities count], totalUploadBytes, currentUploadBytes, totalDownloadBytes, currentDownloadBytes];
138 - (void)update:(NSTimer *)aTimer {
139 NSMutableDictionary *info = [NSMutableDictionary dictionary];
140 @synchronized(self) {
141 PithosActivity *activity = nil;
142 NSUInteger endingActivitiesCount = [endingActivities count];
143 NSUInteger runningActivitiesCount = [runningActivities count];
144 if ((pickedRunning || !runningActivitiesCount) && endingActivitiesCount) {
146 for (index = 0 ; index < endingActivitiesCount; index++) {
147 activity = [endingActivities objectAtIndex:index];
148 switch (activity.type) {
149 case PithosActivityUpload:
150 totalUploadBytes -= activity.totalBytes;
151 currentUploadBytes -= activity.currentBytes;
153 case PithosActivityDownload:
154 totalDownloadBytes -= activity.totalBytes;
155 currentDownloadBytes -= activity.currentBytes;
160 if (activity.message)
164 [endingActivities removeObjectsInRange:NSMakeRange(0, (index + 1))];
166 } else if (runningActivitiesCount) {
168 for (count = 0 ; count < runningActivitiesCount; count++) {
169 activity = [[runningActivities objectAtIndex:0] retain];
170 [runningActivities removeObjectAtIndex:0];
171 [runningActivities addObject:activity];
172 if (activity.message) {
181 if (activity && activity.message) {
182 if (activity.pithosAccount)
183 [info setObject:[NSString stringWithFormat:@"[%@] %@", activity.pithosAccount.name, activity.message] forKey:@"message"];
185 [info setObject:activity.message forKey:@"message"];
187 [info setObject:[NSNumber numberWithUnsignedInteger:[runningActivities count]] forKey:@"runningActivitiesCount"];
188 [info setObject:[NSNumber numberWithUnsignedInteger:[endingActivities count]] forKey:@"endingActivitiesCount"];
189 [info setObject:[NSNumber numberWithUnsignedInteger:totalUploadBytes] forKey:@"totalUploadBytes"];
190 [info setObject:[NSNumber numberWithUnsignedInteger:currentUploadBytes] forKey:@"currentUploadBytes"];
191 [info setObject:[NSNumber numberWithUnsignedInteger:totalDownloadBytes] forKey:@"totalDownloadBytes"];
192 [info setObject:[NSNumber numberWithUnsignedInteger:currentDownloadBytes] forKey:@"currentDownloadBytes"];
196 [delegate activityUpdate:info];
201 #pragma mark Activity Actions
203 - (PithosActivity *)startActivityWithType:(PithosActivityType)type
204 message:(NSString *)message
205 totalBytes:(NSUInteger)totalBytes
206 currentBytes:(NSUInteger)currentBytes
207 pithosAccount:(PithosAccount *)pithosAccount {
208 PithosActivity *activity = [[[PithosActivity alloc] initWithType:type pithosAccount:pithosAccount] autorelease];
209 activity.message = message;
210 activity.totalBytes = totalBytes;
211 activity.currentBytes = currentBytes;
212 NSLog(@"PithosActivityFacility startedActivity %@", activity);
215 case PithosActivityUpload:
216 @synchronized(self) {
217 totalUploadBytes += totalBytes;
218 currentUploadBytes += currentBytes;
221 case PithosActivityDownload:
222 @synchronized(self) {
223 totalDownloadBytes += totalBytes;
224 currentDownloadBytes += currentBytes;
231 @synchronized(self) {
232 [runningActivities addObject:activity];
234 NSLog(@"PithosActivityFacility %@", self);
239 - (PithosActivity *)startActivityWithType:(PithosActivityType)type
240 message:(NSString *)message
241 totalBytes:(NSUInteger)totalBytes
242 currentBytes:(NSUInteger)currentBytes {
243 return [self startActivityWithType:type message:message totalBytes:totalBytes currentBytes:currentBytes pithosAccount:nil];
246 - (PithosActivity *)startActivityWithType:(PithosActivityType)type
247 message:(NSString *)message
248 pithosAccount:(PithosAccount *)pithosAccount {
249 return [self startActivityWithType:type message:message totalBytes:0 currentBytes:0 pithosAccount:pithosAccount];
252 - (PithosActivity *)startActivityWithType:(PithosActivityType)type
253 message:(NSString *)message {
254 return [self startActivityWithType:type message:message pithosAccount:nil];
257 - (PithosActivity *)startAndEndActivityWithType:(PithosActivityType)type
258 message:(NSString *)message
259 pithosAccount:(PithosAccount *)pithosAccount {
260 PithosActivity *activity = [[[PithosActivity alloc] initWithType:type pithosAccount:pithosAccount] autorelease];
261 activity.message = message;
262 activity.totalBytes = 0;
263 activity.currentBytes = 0;
264 @synchronized(self) {
265 [endingActivities addObject:activity];
267 NSLog(@"PithosActivityFacility startedAndEndedActivity %@", activity);
272 - (PithosActivity *)startAndEndActivityWithType:(PithosActivityType)type message:(NSString *)message {
273 return [self startAndEndActivityWithType:type message:message pithosAccount:nil];
276 - (void)updateActivity:(PithosActivity *)activity
277 withMessage:(NSString *)message
278 totalBytes:(NSUInteger)totalBytes
279 currentBytes:(NSUInteger)currentBytes {
282 NSLog(@"PithosActivityFacility updatedActivity %@", activity);
283 @synchronized(self) {
284 activity.message = message;
285 switch (activity.type) {
286 case PithosActivityUpload:
287 totalUploadBytes += totalBytes - activity.totalBytes;
288 activity.totalBytes = totalBytes;
289 currentUploadBytes += currentBytes - activity.currentBytes;
290 activity.currentBytes = currentBytes;
292 case PithosActivityDownload:
293 totalDownloadBytes += totalBytes - activity.totalBytes;
294 activity.totalBytes = totalBytes;
295 currentDownloadBytes += currentBytes - activity.currentBytes;
296 activity.currentBytes = currentBytes;
302 NSLog(@"PithosActivityFacility %@", self);
305 - (void)updateActivity:(PithosActivity *)activity
306 withMessage:(NSString *)message {
307 [self updateActivity:activity withMessage:message totalBytes:activity.totalBytes currentBytes:activity.currentBytes];
310 - (void)endActivity:(PithosActivity *)activity
311 withMessage:(NSString *)message
312 totalBytes:(NSUInteger)totalBytes
313 currentBytes:(NSUInteger)currentBytes {
316 @synchronized(self) {
317 [runningActivities removeObject:activity];
318 activity.message = message;
319 switch (activity.type) {
320 case PithosActivityUpload:
321 totalUploadBytes += totalBytes - activity.totalBytes;
322 activity.totalBytes = totalBytes;
323 currentUploadBytes += currentBytes - activity.currentBytes;
324 activity.currentBytes = currentBytes;
326 case PithosActivityDownload:
327 totalDownloadBytes += totalBytes - activity.totalBytes;
328 activity.totalBytes = totalBytes;
329 currentDownloadBytes += currentBytes - activity.currentBytes;
330 activity.currentBytes = currentBytes;
335 [endingActivities addObject:activity];
337 NSLog(@"PithosActivityFacility endedActivity %@", activity);
338 NSLog(@"PithosActivityFacility %@", self);
341 - (void)endActivity:(PithosActivity *)activity
342 withMessage:(NSString *)message {
343 [self endActivity:activity withMessage:message totalBytes:activity.totalBytes currentBytes:activity.currentBytes];