source: trunk/SapphireImportHelper.m @ 459

Revision 459, 7.8 KB checked in by gbooker, 6 years ago (diff)

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

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.