Statistics
| Branch: | Tag: | Revision:

root / pithos-macos / PithosActivityFacility.m @ cb6abe72

History | View | Annotate | Download (12.5 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
#import "pithos_macosAppDelegate.h"
41

    
42
//static PithosActivityFacility *defaultPithosActivityFacility = nil;
43

    
44
@implementation PithosActivityFacility
45
@synthesize delegate;
46

    
47
#pragma mark - Singleton
48

    
49
+ (id)defaultPithosActivityFacility {
50
    static dispatch_once_t pred = 0;
51
    __strong static id _sharedObject = nil;
52
    dispatch_once(&pred, ^{
53
        _sharedObject = [[self alloc] init];
54
    });
55
    return _sharedObject;
56
}
57

    
58
//+ (id)allocWithZone:(NSZone *)zone {
59
//    @synchronized(self) {
60
//        if (!defaultPithosActivityFacility) {
61
//            defaultPithosActivityFacility = [super allocWithZone:zone];
62
//            return defaultPithosActivityFacility;
63
//        }
64
//    }
65
//    return nil;
66
//}
67
//
68
//- (id)copyWithZone:(NSZone *)zone {
69
//    return self;
70
//}
71
//
72
//- (id)retain {
73
//    return self;
74
//}
75
//
76
//- (NSUInteger)retainCount {
77
//    return UINT_MAX; // Can not be released
78
//}
79
//
80
//- (void)release {
81
//    // Do nothing
82
//}
83
//
84
//- (id)autorelease {
85
//    return self;
86
//}
87

    
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
}
100

    
101
- (void)reset {
102
    @synchronized(self) {
103
        [timer invalidate];
104
        
105
        runningActivities = [[NSMutableArray alloc] init];
106
        endingActivities = [[NSMutableArray alloc] init];
107
        totalUploadBytes = 0;
108
        currentUploadBytes = 0;
109
        totalDownloadBytes = 0;
110
        currentDownloadBytes = 0;
111
        
112
        pickedRunning = NO;
113
        
114
        timer = [NSTimer scheduledTimerWithTimeInterval:[(pithos_macosAppDelegate *)[[NSApplication sharedApplication] delegate] activityFacilityTimeInterval] 
115
                                                  target:self 
116
                                                selector:@selector(update:) 
117
                                                userInfo:nil 
118
                                                 repeats:YES];
119
    }
120
}
121

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

    
127
#pragma mark -
128
#pragma mark Timer
129

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

    
189
#pragma mark -
190
#pragma mark Activity Actions
191

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

    
228
- (PithosActivity *)startActivityWithType:(PithosActivityType)type 
229
                                  message:(NSString *)message 
230
                               totalBytes:(NSUInteger)totalBytes 
231
                             currentBytes:(NSUInteger)currentBytes {
232
    return [self startActivityWithType:type message:message totalBytes:totalBytes currentBytes:currentBytes pithosAccount:nil];
233
}
234

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

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

    
246
- (PithosActivity *)startAndEndActivityWithType:(PithosActivityType)type 
247
                                        message:(NSString *)message 
248
                                  pithosAccount:(PithosAccount *)pithosAccount {
249
    PithosActivity *activity = [[PithosActivity alloc] initWithType:type pithosAccount:pithosAccount];
250
    activity.message = message;
251
    activity.totalBytes = 0;
252
    activity.currentBytes = 0;
253
    @synchronized(self) {
254
        [endingActivities addObject:activity];
255
    }
256
    DLog(@"PithosActivityFacility startedAndEndedActivity %@", activity);
257
    
258
    return activity;
259
}
260

    
261
- (PithosActivity *)startAndEndActivityWithType:(PithosActivityType)type message:(NSString *)message {
262
    return [self startAndEndActivityWithType:type message:message pithosAccount:nil];
263
}
264

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

    
294
- (void)updateActivity:(PithosActivity *)activity 
295
           withMessage:(NSString *)message {
296
    [self updateActivity:activity withMessage:message totalBytes:activity.totalBytes currentBytes:activity.currentBytes];
297
}
298

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

    
330
- (void)endActivity:(PithosActivity *)activity 
331
        withMessage:(NSString *)message {
332
    [self endActivity:activity withMessage:message totalBytes:activity.totalBytes currentBytes:activity.currentBytes];
333
}
334

    
335
@end