Statistics
| Branch: | Tag: | Revision:

root / pithos-macos / PithosActivityFacility.m @ 0224a49f

History | View | Annotate | Download (11 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
- (PithosActivity *)startAndEndActivityWithType:(PithosActivityType)type message:(NSString *)message {
232
    PithosActivity *activity = [[[PithosActivity alloc] initWithType:type] autorelease];
233
    activity.message = message;
234
    activity.totalBytes = 0;
235
    activity.currentBytes = 0;
236
    @synchronized(self) {
237
        [endingActivities addObject:activity];
238
    }
239
    NSLog(@"PithosActivityFacility startedAndEndedActivity %@", activity);
240
    
241
    return activity;
242
}
243

    
244
- (void)updateActivity:(PithosActivity *)activity 
245
           withMessage:(NSString *)message 
246
            totalBytes:(NSUInteger)totalBytes 
247
          currentBytes:(NSUInteger)currentBytes {
248
    if (!activity)
249
        return;
250
    NSLog(@"PithosActivityFacility updatedActivity %@", activity);
251
    @synchronized(self) {
252
        activity.message = message;
253
        switch (activity.type) {
254
            case PithosActivityUpload:
255
                totalUploadBytes += totalBytes - activity.totalBytes;
256
                activity.totalBytes = totalBytes;
257
                currentUploadBytes += currentBytes - activity.currentBytes;
258
                activity.currentBytes = currentBytes;
259
                break;
260
            case PithosActivityDownload:
261
                totalDownloadBytes += totalBytes - activity.totalBytes;
262
                activity.totalBytes = totalBytes;
263
                currentDownloadBytes += currentBytes - activity.currentBytes;
264
                activity.currentBytes = currentBytes;
265
                break;
266
            default:
267
                break;
268
        }
269
    }
270
    NSLog(@"PithosActivityFacility %@", self);
271
}
272

    
273
- (void)updateActivity:(PithosActivity *)activity 
274
           withMessage:(NSString *)message {
275
    [self updateActivity:activity withMessage:message totalBytes:activity.totalBytes currentBytes:activity.currentBytes];
276
}
277

    
278
- (void)endActivity:(PithosActivity *)activity 
279
        withMessage:(NSString *)message 
280
         totalBytes:(NSUInteger)totalBytes 
281
       currentBytes:(NSUInteger)currentBytes {
282
    if (!activity)
283
        return;
284
    @synchronized(self) {
285
        [runningActivities removeObject:activity];
286
        activity.message = message;
287
        switch (activity.type) {
288
            case PithosActivityUpload:
289
                totalUploadBytes += totalBytes - activity.totalBytes;
290
                activity.totalBytes = totalBytes;
291
                currentUploadBytes += currentBytes - activity.currentBytes;
292
                activity.currentBytes = currentBytes;
293
                break;
294
            case PithosActivityDownload:
295
                totalDownloadBytes += totalBytes - activity.totalBytes;
296
                activity.totalBytes = totalBytes;
297
                currentDownloadBytes += currentBytes - activity.currentBytes;
298
                activity.currentBytes = currentBytes;
299
                break;
300
            default:
301
                break;
302
        }
303
        [endingActivities addObject:activity];
304
    }
305
    NSLog(@"PithosActivityFacility endedActivity %@", activity);
306
    NSLog(@"PithosActivityFacility %@", self);
307
}
308

    
309
- (void)endActivity:(PithosActivity *)activity 
310
        withMessage:(NSString *)message {
311
    [self endActivity:activity withMessage:message totalBytes:activity.totalBytes currentBytes:activity.currentBytes];
312
}
313

    
314
@end