Statistics
| Branch: | Tag: | Revision:

root / pithos-macos / PithosActivityFacility.m @ 1b1e6fa1

History | View | Annotate | Download (10.6 kB)

1
//
2
//  PithosActivityFacility.m
3
//  pithos-macos
4
//
5
// Copyright 2011 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

    
40
static PithosActivityFacility *defaultPithosActivityFacility = nil;
41

    
42
@implementation PithosActivityFacility
43
@synthesize delegate;
44

    
45
#pragma mark -
46
#pragma mark - Singleton
47

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

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

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

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

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

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

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

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

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

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

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

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

    
129
#pragma mark -
130
#pragma mark Timer
131

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

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

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

    
226
- (PithosActivity *)startActivityWithType:(PithosActivityType)type 
227
                                  message:(NSString *)message {
228
    return [self startActivityWithType:type message:message totalBytes:0 currentBytes:0];
229
}
230

    
231
- (void)updateActivity:(PithosActivity *)activity 
232
           withMessage:(NSString *)message 
233
            totalBytes:(NSUInteger)totalBytes 
234
          currentBytes:(NSUInteger)currentBytes {
235
    if (!activity)
236
        return;
237
    NSLog(@"PithosActivityFacility updatedActivity %@", activity);
238
    @synchronized(self) {
239
        activity.message = message;
240
        switch (activity.type) {
241
            case PithosActivityUpload:
242
                totalUploadBytes += totalBytes - activity.totalBytes;
243
                activity.totalBytes = totalBytes;
244
                currentUploadBytes += currentBytes - activity.currentBytes;
245
                activity.currentBytes = currentBytes;
246
                break;
247
            case PithosActivityDownload:
248
                totalDownloadBytes += totalBytes - activity.totalBytes;
249
                activity.totalBytes = totalBytes;
250
                currentDownloadBytes += currentBytes - activity.currentBytes;
251
                activity.currentBytes = currentBytes;
252
                break;
253
            default:
254
                break;
255
        }
256
    }
257
    NSLog(@"PithosActivityFacility %@", self);
258
}
259

    
260
- (void)updateActivity:(PithosActivity *)activity 
261
           withMessage:(NSString *)message {
262
    [self updateActivity:activity withMessage:message totalBytes:activity.totalBytes currentBytes:activity.currentBytes];
263
}
264

    
265
- (void)endActivity:(PithosActivity *)activity 
266
        withMessage:(NSString *)message 
267
         totalBytes:(NSUInteger)totalBytes 
268
       currentBytes:(NSUInteger)currentBytes {
269
    if (!activity)
270
        return;
271
    @synchronized(self) {
272
        [runningActivities removeObject:activity];
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
        [endingActivities addObject:activity];
291
    }
292
    NSLog(@"PithosActivityFacility endedActivity %@", activity);
293
    NSLog(@"PithosActivityFacility %@", self);
294
}
295

    
296
- (void)endActivity:(PithosActivity *)activity 
297
        withMessage:(NSString *)message {
298
    [self endActivity:activity withMessage:message totalBytes:activity.totalBytes currentBytes:activity.currentBytes];
299
}
300

    
301
@end