Statistics
| Branch: | Tag: | Revision:

root / pithos-macos / PithosActivityFacility.m @ 9990166e

History | View | Annotate | Download (12.8 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 -
48
#pragma mark - Singleton
49

    
50
+ (id)defaultPithosActivityFacility {
51
	@synchronized(self) {
52
		if (!defaultPithosActivityFacility)
53
			[[self alloc] init]; // Assignment not done here
54
	}
55
	return defaultPithosActivityFacility;
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 -
89
#pragma mark Object Lifecycle
90

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

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

    
106
- (void)reset {
107
    @synchronized(self) {
108
        [timer invalidate];
109
        [timer release];
110
        
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;
119
        
120
        pickedRunning = NO;
121
        
122
        timer = [[NSTimer scheduledTimerWithTimeInterval:[(pithos_macosAppDelegate *)[[NSApplication sharedApplication] delegate] activityFacilityTimeInterval] 
123
                                                  target:self 
124
                                                selector:@selector(update:) 
125
                                                userInfo:nil 
126
                                                 repeats:YES] retain];
127
    }
128
}
129

    
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];
133
}
134

    
135
#pragma mark -
136
#pragma mark Timer
137

    
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) {
145
            NSUInteger index;
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;
152
                        break;
153
                    case PithosActivityDownload:
154
                        totalDownloadBytes -= activity.totalBytes;
155
                        currentDownloadBytes -= activity.currentBytes;
156
                        break;
157
                    default:
158
                        break;
159
                }
160
                if (activity.message)
161
                    break;
162
            }
163
            [activity retain];
164
            [endingActivities removeObjectsInRange:NSMakeRange(0, (index + 1))];
165
            pickedRunning = NO;
166
        } else if (runningActivitiesCount) {
167
            NSUInteger count;
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) {
173
                    break;
174
                } else {
175
                    [activity release];
176
                    activity = nil;
177
                }
178
            }
179
            pickedRunning = YES;
180
        }
181
        if (activity && activity.message) {
182
            if (activity.pithosAccount)
183
                [info setObject:[NSString stringWithFormat:@"[%@] %@", activity.pithosAccount.name, activity.message] forKey:@"message"];
184
            else
185
                [info setObject:activity.message forKey:@"message"];
186
        }
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"];
193
        [activity release];
194
    }
195
    if (delegate) {
196
        [delegate activityUpdate:info];
197
    }
198
}
199

    
200
#pragma mark -
201
#pragma mark Activity Actions
202

    
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
    DLog(@"PithosActivityFacility startedActivity %@", activity);
213
    
214
    switch (type) {
215
        case PithosActivityUpload:
216
            @synchronized(self) {
217
                totalUploadBytes += totalBytes;
218
                currentUploadBytes += currentBytes;
219
            }
220
            break;
221
        case PithosActivityDownload:
222
            @synchronized(self) {
223
                totalDownloadBytes += totalBytes;
224
                currentDownloadBytes += currentBytes;
225
            }
226
            break;
227
        default:
228
            break;
229
    }
230
    
231
    @synchronized(self) {
232
        [runningActivities addObject:activity];
233
    }
234
    DLog(@"PithosActivityFacility %@", self);
235
    
236
    return activity;
237
}
238

    
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];
244
}
245

    
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];
250
}
251

    
252
- (PithosActivity *)startActivityWithType:(PithosActivityType)type 
253
                                  message:(NSString *)message {
254
    return [self startActivityWithType:type message:message pithosAccount:nil];
255
}
256

    
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];
266
    }
267
    DLog(@"PithosActivityFacility startedAndEndedActivity %@", activity);
268
    
269
    return activity;
270
}
271

    
272
- (PithosActivity *)startAndEndActivityWithType:(PithosActivityType)type message:(NSString *)message {
273
    return [self startAndEndActivityWithType:type message:message pithosAccount:nil];
274
}
275

    
276
- (void)updateActivity:(PithosActivity *)activity 
277
           withMessage:(NSString *)message 
278
            totalBytes:(NSUInteger)totalBytes 
279
          currentBytes:(NSUInteger)currentBytes {
280
    if (!activity)
281
        return;
282
    DLog(@"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;
291
                break;
292
            case PithosActivityDownload:
293
                totalDownloadBytes += totalBytes - activity.totalBytes;
294
                activity.totalBytes = totalBytes;
295
                currentDownloadBytes += currentBytes - activity.currentBytes;
296
                activity.currentBytes = currentBytes;
297
                break;
298
            default:
299
                break;
300
        }
301
    }
302
    DLog(@"PithosActivityFacility %@", self);
303
}
304

    
305
- (void)updateActivity:(PithosActivity *)activity 
306
           withMessage:(NSString *)message {
307
    [self updateActivity:activity withMessage:message totalBytes:activity.totalBytes currentBytes:activity.currentBytes];
308
}
309

    
310
- (void)endActivity:(PithosActivity *)activity 
311
        withMessage:(NSString *)message 
312
         totalBytes:(NSUInteger)totalBytes 
313
       currentBytes:(NSUInteger)currentBytes {
314
    if (!activity)
315
        return;
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;
325
                break;
326
            case PithosActivityDownload:
327
                totalDownloadBytes += totalBytes - activity.totalBytes;
328
                activity.totalBytes = totalBytes;
329
                currentDownloadBytes += currentBytes - activity.currentBytes;
330
                activity.currentBytes = currentBytes;
331
                break;
332
            default:
333
                break;
334
        }
335
        [endingActivities addObject:activity];
336
    }
337
    DLog(@"PithosActivityFacility endedActivity %@", activity);
338
    DLog(@"PithosActivityFacility %@", self);
339
}
340

    
341
- (void)endActivity:(PithosActivity *)activity 
342
        withMessage:(NSString *)message {
343
    [self endActivity:activity withMessage:message totalBytes:activity.totalBytes currentBytes:activity.currentBytes];
344
}
345

    
346
@end