Statistics
| Branch: | Tag: | Revision:

root / pithos-macos / PithosActivityFacility.m @ d8426ffb

History | View | Annotate | Download (12.4 kB)

1
//
2
//  PithosActivityFacility.m
3
//  pithos-macos
4
//
5
// Copyright 2011-2012 GRNET S.A. All rights reserved.
6
//
7
// Redistribution and use in source and binary forms, with or
8
// without modification, are permitted provided that the following
9
// conditions are met:
10
// 
11
//   1. Redistributions of source code must retain the above
12
//      copyright notice, this list of conditions and the following
13
//      disclaimer.
14
// 
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.
19
// 
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.
32
// 
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.
37

    
38
#import "PithosActivityFacility.h"
39
#import "PithosAccount.h"
40

    
41
static PithosActivityFacility *defaultPithosActivityFacility = nil;
42

    
43
@implementation PithosActivityFacility
44
@synthesize delegate;
45

    
46
#pragma mark -
47
#pragma mark - Singleton
48

    
49
+ (id)defaultPithosActivityFacility {
50
	@synchronized(self) {
51
		if (!defaultPithosActivityFacility)
52
			[[self alloc] init]; // Assignment not done here
53
	}
54
	return defaultPithosActivityFacility;
55
}
56

    
57
+ (id)allocWithZone:(NSZone *)zone {
58
    @synchronized(self) {
59
        if (!defaultPithosActivityFacility) {
60
            defaultPithosActivityFacility = [super allocWithZone:zone];
61
            return defaultPithosActivityFacility;
62
        }
63
    }
64
    return nil;
65
}
66

    
67
- (id)copyWithZone:(NSZone *)zone {
68
    return self;
69
}
70

    
71
- (id)retain {
72
    return self;
73
}
74

    
75
- (NSUInteger)retainCount {
76
    return UINT_MAX; // Can not be released
77
}
78

    
79
- (void)release {
80
    // Do nothing
81
}
82

    
83
- (id)autorelease {
84
    return self;
85
}
86

    
87
#pragma mark -
88
#pragma mark Object Lifecycle
89

    
90
- (id)init {
91
    if ((self = [super init])) {
92
        [self reset];
93
    }
94
    return self;
95
}
96

    
97
- (void)dealloc {
98
    [timer invalidate];
99
    [timer release];
100
    [runningActivities release];
101
    [endingActivities release];
102
    [super dealloc];
103
}
104

    
105
- (void)reset {
106
    @synchronized(self) {
107
        [timer invalidate];
108
        [timer release];
109
        
110
        [runningActivities release];
111
        runningActivities = [[NSMutableArray alloc] init];
112
        [endingActivities release];
113
        endingActivities = [[NSMutableArray alloc] init];
114
        totalUploadBytes = 0;
115
        currentUploadBytes = 0;
116
        totalDownloadBytes = 0;
117
        currentDownloadBytes = 0;
118
        
119
        pickedRunning = NO;
120
        
121
        timer = [[NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(update:) userInfo:nil repeats:YES] retain];
122
    }
123
}
124

    
125
- (NSString *)description {
126
    return [NSString stringWithFormat:@"running activities: %lu, ending activities: %lu, totalUploadBytes: %lu, currentUploadBytes: %lu, totalDownloadBytes: %lu, currentDownloadBytes: %lu", 
127
            [runningActivities count], [endingActivities count], totalUploadBytes, currentUploadBytes, totalDownloadBytes, currentDownloadBytes];
128
}
129

    
130
#pragma mark -
131
#pragma mark Timer
132

    
133
- (void)update:(NSTimer *)aTimer {
134
    NSMutableDictionary *info = [NSMutableDictionary dictionary];
135
    @synchronized(self) {
136
        PithosActivity *activity = nil;
137
        NSUInteger endingActivitiesCount = [endingActivities count];
138
        NSUInteger runningActivitiesCount = [runningActivities count];
139
        if ((pickedRunning || !runningActivitiesCount) && endingActivitiesCount) {
140
            NSUInteger index;
141
            for (index = 0 ; index < endingActivitiesCount; index++) {
142
                activity = [endingActivities objectAtIndex:index];
143
                switch (activity.type) {
144
                    case PithosActivityUpload:
145
                        totalUploadBytes -= activity.totalBytes;
146
                        currentUploadBytes -= activity.currentBytes;
147
                        break;
148
                    case PithosActivityDownload:
149
                        totalDownloadBytes -= activity.totalBytes;
150
                        currentDownloadBytes -= activity.currentBytes;
151
                        break;
152
                    default:
153
                        break;
154
                }
155
                if (activity.message)
156
                    break;
157
            }
158
            [activity retain];
159
            [endingActivities removeObjectsInRange:NSMakeRange(0, (index + 1))];
160
            pickedRunning = NO;
161
        } else if (runningActivitiesCount) {
162
            NSUInteger count;
163
            for (count = 0 ; count < runningActivitiesCount; count++) {
164
                activity = [[runningActivities objectAtIndex:0] retain];
165
                [runningActivities removeObjectAtIndex:0];
166
                [runningActivities addObject:activity];
167
                if (activity.message) {
168
                    break;
169
                } else {
170
                    [activity release];
171
                    activity = nil;
172
                }
173
            }
174
            pickedRunning = YES;
175
        }
176
        if (activity && activity.message) {
177
            if (activity.pithosAccount)
178
                [info setObject:[NSString stringWithFormat:@"[%@] %@", activity.pithosAccount.name, activity.message] forKey:@"message"];
179
            else
180
                [info setObject:activity.message forKey:@"message"];
181
        }
182
        [info setObject:[NSNumber numberWithUnsignedInteger:[runningActivities count]] forKey:@"runningActivitiesCount"];
183
        [info setObject:[NSNumber numberWithUnsignedInteger:[endingActivities count]] forKey:@"endingActivitiesCount"];
184
        [info setObject:[NSNumber numberWithUnsignedInteger:totalUploadBytes] forKey:@"totalUploadBytes"];
185
        [info setObject:[NSNumber numberWithUnsignedInteger:currentUploadBytes] forKey:@"currentUploadBytes"];
186
        [info setObject:[NSNumber numberWithUnsignedInteger:totalDownloadBytes] forKey:@"totalDownloadBytes"];
187
        [info setObject:[NSNumber numberWithUnsignedInteger:currentDownloadBytes] forKey:@"currentDownloadBytes"];
188
        [activity release];
189
    }
190
    if (delegate) {
191
        [delegate activityUpdate:info];
192
    }
193
}
194

    
195
#pragma mark -
196
#pragma mark Activity Actions
197

    
198
- (PithosActivity *)startActivityWithType:(PithosActivityType)type 
199
                                  message:(NSString *)message 
200
                               totalBytes:(NSUInteger)totalBytes 
201
                             currentBytes:(NSUInteger)currentBytes 
202
                            pithosAccount:(PithosAccount *)pithosAccount {
203
    PithosActivity *activity = [[[PithosActivity alloc] initWithType:type pithosAccount:pithosAccount] autorelease];
204
    activity.message = message;
205
    activity.totalBytes = totalBytes;
206
    activity.currentBytes = currentBytes;
207
    NSLog(@"PithosActivityFacility startedActivity %@", activity);
208
    
209
    switch (type) {
210
        case PithosActivityUpload:
211
            @synchronized(self) {
212
                totalUploadBytes += totalBytes;
213
                currentUploadBytes += currentBytes;
214
            }
215
            break;
216
        case PithosActivityDownload:
217
            @synchronized(self) {
218
                totalDownloadBytes += totalBytes;
219
                currentDownloadBytes += currentBytes;
220
            }
221
            break;
222
        default:
223
            break;
224
    }
225
    
226
    @synchronized(self) {
227
        [runningActivities addObject:activity];
228
    }
229
    NSLog(@"PithosActivityFacility %@", self);
230
    
231
    return activity;
232
}
233

    
234
- (PithosActivity *)startActivityWithType:(PithosActivityType)type 
235
                                  message:(NSString *)message 
236
                               totalBytes:(NSUInteger)totalBytes 
237
                             currentBytes:(NSUInteger)currentBytes {
238
    return [self startActivityWithType:type message:message totalBytes:totalBytes currentBytes:currentBytes pithosAccount:nil];
239
}
240

    
241
- (PithosActivity *)startActivityWithType:(PithosActivityType)type 
242
                                  message:(NSString *)message 
243
                            pithosAccount:(PithosAccount *)pithosAccount {
244
    return [self startActivityWithType:type message:message totalBytes:0 currentBytes:0 pithosAccount:pithosAccount];
245
}
246

    
247
- (PithosActivity *)startActivityWithType:(PithosActivityType)type 
248
                                  message:(NSString *)message {
249
    return [self startActivityWithType:type message:message pithosAccount:nil];
250
}
251

    
252
- (PithosActivity *)startAndEndActivityWithType:(PithosActivityType)type 
253
                                        message:(NSString *)message 
254
                                  pithosAccount:(PithosAccount *)pithosAccount {
255
    PithosActivity *activity = [[[PithosActivity alloc] initWithType:type pithosAccount:pithosAccount] autorelease];
256
    activity.message = message;
257
    activity.totalBytes = 0;
258
    activity.currentBytes = 0;
259
    @synchronized(self) {
260
        [endingActivities addObject:activity];
261
    }
262
    NSLog(@"PithosActivityFacility startedAndEndedActivity %@", activity);
263
    
264
    return activity;
265
}
266

    
267
- (PithosActivity *)startAndEndActivityWithType:(PithosActivityType)type message:(NSString *)message {
268
    return [self startAndEndActivityWithType:type message:message pithosAccount:nil];
269
}
270

    
271
- (void)updateActivity:(PithosActivity *)activity 
272
           withMessage:(NSString *)message 
273
            totalBytes:(NSUInteger)totalBytes 
274
          currentBytes:(NSUInteger)currentBytes {
275
    if (!activity)
276
        return;
277
    NSLog(@"PithosActivityFacility updatedActivity %@", activity);
278
    @synchronized(self) {
279
        activity.message = message;
280
        switch (activity.type) {
281
            case PithosActivityUpload:
282
                totalUploadBytes += totalBytes - activity.totalBytes;
283
                activity.totalBytes = totalBytes;
284
                currentUploadBytes += currentBytes - activity.currentBytes;
285
                activity.currentBytes = currentBytes;
286
                break;
287
            case PithosActivityDownload:
288
                totalDownloadBytes += totalBytes - activity.totalBytes;
289
                activity.totalBytes = totalBytes;
290
                currentDownloadBytes += currentBytes - activity.currentBytes;
291
                activity.currentBytes = currentBytes;
292
                break;
293
            default:
294
                break;
295
        }
296
    }
297
    NSLog(@"PithosActivityFacility %@", self);
298
}
299

    
300
- (void)updateActivity:(PithosActivity *)activity 
301
           withMessage:(NSString *)message {
302
    [self updateActivity:activity withMessage:message totalBytes:activity.totalBytes currentBytes:activity.currentBytes];
303
}
304

    
305
- (void)endActivity:(PithosActivity *)activity 
306
        withMessage:(NSString *)message 
307
         totalBytes:(NSUInteger)totalBytes 
308
       currentBytes:(NSUInteger)currentBytes {
309
    if (!activity)
310
        return;
311
    @synchronized(self) {
312
        [runningActivities removeObject:activity];
313
        activity.message = message;
314
        switch (activity.type) {
315
            case PithosActivityUpload:
316
                totalUploadBytes += totalBytes - activity.totalBytes;
317
                activity.totalBytes = totalBytes;
318
                currentUploadBytes += currentBytes - activity.currentBytes;
319
                activity.currentBytes = currentBytes;
320
                break;
321
            case PithosActivityDownload:
322
                totalDownloadBytes += totalBytes - activity.totalBytes;
323
                activity.totalBytes = totalBytes;
324
                currentDownloadBytes += currentBytes - activity.currentBytes;
325
                activity.currentBytes = currentBytes;
326
                break;
327
            default:
328
                break;
329
        }
330
        [endingActivities addObject:activity];
331
    }
332
    NSLog(@"PithosActivityFacility endedActivity %@", activity);
333
    NSLog(@"PithosActivityFacility %@", self);
334
}
335

    
336
- (void)endActivity:(PithosActivity *)activity 
337
        withMessage:(NSString *)message {
338
    [self endActivity:activity withMessage:message totalBytes:activity.totalBytes currentBytes:activity.currentBytes];
339
}
340

    
341
@end