source: trunk/SapphireImportHelper.m @ 459

Last change on this file since 459 was 459, checked in by gbooker, 10 years ago

Switch to using nstask instead of fork for the child since the signal handler seems to break the "sleep" mode on the ATV

File size: 7.8 KB
Line 
1/*
2 * SapphireImportHelper.m
3 * Sapphire
4 *
5 * Created by Graham Booker on Dec. 8, 2007.
6 * Copyright 2007 Sapphire Development Team and/or www.nanopi.net
7 * All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify it under the terms of the GNU
10 * General Public License as published by the Free Software Foundation; either version 3 of the License,
11 * or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
14 * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
15 * Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along with this program; if not,
18 * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19 */
20
21#import "SapphireImportHelper.h"
22#import "SapphireMetaData.h"
23#import "SapphireAllImporter.h"
24#import "SapphireFileDataImporter.h"
25#import "SapphireTVShowImporter.h"
26#import "SapphireMovieImporter.h"
27
28#define CONNECTION_NAME @"Sapphire Server"
29
30@interface SapphireImportFile : NSObject <SapphireImportFileProtocol>{
31        id <SapphireFileMetaDataProtocol>               file;
32        id <SapphireImporterBackgroundProtocol> informer;
33        ImportType                                                              type;
34}
35- (id)initWithFile:(id <SapphireFileMetaDataProtocol>)aFile informer:(id <SapphireImporterBackgroundProtocol>)aInformer type:(ImportType)aType;
36@end
37
38@interface SapphireImportHelperServer (private)
39- (void)startClient;
40@end
41
42@implementation SapphireImportHelper
43
44static SapphireImportHelper *shared = nil;
45
46+ (SapphireImportHelper *)sharedHelper
47{
48        if(shared == nil)
49                shared = [[SapphireImportHelperServer alloc] init];
50
51        return shared;
52}
53
54+ (void)relinquishHelper
55{
56        if(shared != nil)
57                [shared relinquishHelper];
58}
59
60- (void)relinquishHelper
61{
62}
63
64- (void)importFileData:(id <SapphireFileMetaDataProtocol>)file inform:(id <SapphireImporterBackgroundProtocol>)inform;
65{
66}
67
68- (void)importAllData:(id <SapphireFileMetaDataProtocol>)file inform:(id <SapphireImporterBackgroundProtocol>)inform;
69{
70}
71
72- (void)removeObjectsWithInform:(id <SapphireImporterBackgroundProtocol>)inform
73{
74}
75
76@end
77
78@implementation SapphireImportHelperClient
79
80- (id)init
81{
82        self = [super init];
83        if(!self)
84                return nil;
85       
86        SapphireFileDataImporter *fileImp = [[SapphireFileDataImporter alloc] init];
87        SapphireTVShowImporter *tvImp = [[SapphireTVShowImporter alloc] initWithSavedSetting:[NSHomeDirectory() stringByAppendingPathComponent:@"Library/Application Support/Sapphire/tvdata.plist"]];
88        SapphireMovieImporter *movImp = [[SapphireMovieImporter alloc] initWithSavedSetting:[NSHomeDirectory() stringByAppendingPathComponent:@"Library/Application Support/Sapphire/movieData.plist"]];
89        allImporter = [[SapphireAllImporter alloc] initWithImporters:[NSArray arrayWithObjects:tvImp,movImp,fileImp,nil]];
90        [fileImp release];
91        [tvImp release];
92        [movImp release];
93        keepRunning = YES;
94       
95        return self;
96}
97- (void) dealloc
98{
99        [server release];
100        [allImporter release];
101        [super dealloc];
102}
103
104- (void)importFileData:(id <SapphireFileMetaDataProtocol>)file inform:(id <SapphireImporterBackgroundProtocol>)inform;
105{
106        updateMetaData(file);
107}
108
109- (void)startChild
110{
111        /*Child here*/
112        @try {
113                NSConnection *connection = [NSConnection connectionWithRegisteredName:CONNECTION_NAME host:nil];
114                id serverobj = [[connection rootProxy] retain];
115                [serverobj setProtocolForProxy:@protocol(SapphireImportServer)];
116                shared = self;
117                [serverobj setClient:(SapphireImportHelperClient *)shared];
118                server = serverobj;     
119                [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(connectionDidDie:) name:NSConnectionDidDieNotification object:nil];           
120        }
121        @catch (NSException * e) {
122                keepRunning = NO;
123        }
124}
125
126- (BOOL)keepRunning
127{
128        return keepRunning;
129}
130
131- (void)connectionDidDie:(NSNotification *)note
132{
133        [self exitChild];
134}
135
136- (oneway void)exitChild
137{
138        keepRunning = NO;
139}
140
141- (oneway void)startQueue
142{
143        id <SapphireImportFileProtocol> file = nil;
144        while((file = [server nextFile]) != nil)
145        {
146                ImportType type = [file importType];
147                BOOL ret;
148                if(type == IMPORT_TYPE_FILE_DATA)
149                        ret = updateMetaData([file file]);
150                else
151                        ret = ([allImporter importMetaData:[file file]] == IMPORT_STATE_UPDATED);
152                [server importComplete:ret];
153        }
154}
155@end
156
157@implementation SapphireImportHelperServer
158
159- (id) init
160{
161        self = [super init];
162        if (self == nil)
163                return nil;
164       
165        queue = [[NSMutableArray alloc] init];
166        queueSuspended = NO;
167       
168        serverConnection = [NSConnection defaultConnection];
169        [serverConnection setRootObject:self];
170        if([serverConnection registerName:CONNECTION_NAME] == NO)
171                NSLog(@"Register failed");
172       
173        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(connectionDidDie:) name:NSConnectionDidDieNotification object:nil];
174       
175        [self startClient];
176       
177        return self;
178}
179
180- (void) dealloc
181{
182        [[NSNotificationCenter defaultCenter] removeObserver:self];
183        [client release];
184        [queue release];
185        [currentImporting release];
186        [super dealloc];
187}
188
189- (void)relinquishHelper
190{
191        [client exitChild];
192        [serverConnection registerName:nil];
193        [serverConnection setRootObject:nil];
194        [shared autorelease];
195        shared = nil;
196}
197
198- (void)startClient
199{
200        NSString *path = [[NSBundle bundleForClass:[SapphireImportHelper class]] pathForResource:@"ImportHelper" ofType:@""];
201        [NSTask launchedTaskWithLaunchPath:path arguments:[NSArray array]];
202}
203
204- (void)connectionDidDie:(NSNotification *)note
205{
206        [client release];
207        client = nil;
208        /*Inform that import completed (since it crashed, no update done)*/
209        [self importComplete:NO];
210        if(shared != nil)
211                /* Don't start it again if we are shutting down*/
212                [self startClient];
213}
214
215- (void)itemAdded
216{
217        if(!queueSuspended)
218                return;
219        queueSuspended = NO;
220        [client startQueue];
221}
222
223- (void)importFileData:(id <SapphireFileMetaDataProtocol>)file inform:(id <SapphireImporterBackgroundProtocol>)inform;
224{
225        SapphireImportFile *item = [[SapphireImportFile alloc] initWithFile:file informer:inform  type:IMPORT_TYPE_FILE_DATA];
226        [queue addObject:item];
227        [item release];
228        [self itemAdded];
229}
230
231- (void)importAllData:(id <SapphireFileMetaDataProtocol>)file inform:(id <SapphireImporterBackgroundProtocol>)inform;
232{
233        SapphireImportFile *item = [[SapphireImportFile alloc] initWithFile:file informer:inform  type:IMPORT_TYPE_ALL_DATA];
234        [queue addObject:item];
235        [item release];
236        [self itemAdded];
237}
238
239- (void)removeObjectsWithInform:(id <SapphireImporterBackgroundProtocol>)inform
240{
241        if(inform == nil)
242                return;
243       
244        int i, count=[queue count];
245        for(i=0; i<count; i++)
246        {
247                id <SapphireImportFileProtocol> file = [queue objectAtIndex:i];
248                if([file informer] == inform)
249                {
250                        [queue removeObjectAtIndex:i];
251                        i--;
252                        count--;
253                }
254        }
255}
256
257- (id <SapphireImportFileProtocol>)nextFile
258{
259        if(![queue count])
260        {
261                queueSuspended = YES;
262                return nil;
263        }
264        [currentImporting release];
265        currentImporting = [[queue objectAtIndex:0] retain];
266        [queue removeObjectAtIndex:0];
267        return currentImporting;
268}
269
270- (oneway void)setClient:(id <SapphireImportClient>)aClient
271{
272        if(shared == nil)
273        {
274                [aClient exitChild];
275                return;
276        }
277        client = [aClient retain];
278        if([queue count])
279        {
280                queueSuspended = NO;
281                [client startQueue];
282        }
283}
284
285- (oneway void)importComplete:(BOOL)updated
286{
287        [[currentImporting informer] informComplete:updated];
288        [currentImporting release];
289        currentImporting = nil;
290}
291
292@end
293
294@implementation SapphireImportFile
295- (id)initWithFile:(id <SapphireFileMetaDataProtocol>)aFile informer:(id <SapphireImporterBackgroundProtocol>)aInformer type:(ImportType)aType
296{
297        self = [super init];
298        if(!self)
299                return nil;
300       
301        file = [aFile retain];
302        informer = [aInformer retain];
303        type = aType;
304       
305        return self;
306}
307- (void) dealloc
308{
309        [file release];
310        [informer release];
311        [super dealloc];
312}
313
314- (id <SapphireFileMetaDataProtocol>)file
315{
316        return file;
317}
318- (id <SapphireImporterBackgroundProtocol>)informer
319{
320        return informer;
321}
322
323- (ImportType)importType
324{
325        return type;
326}
327
328@end
Note: See TracBrowser for help on using the repository browser.