Well, here is what I came up for. It's not a full manager, but it works
There's a single NSMutableDictionary in which I keep NSMutableDictionaries (dictionary of dictionaries). The "inner" dictionary holds another dictionary - that of the ParticleDesigner - and an NSMutableArray with particle systems
When the function is asked for a ParticleSystem for a file it first checks if it has ever encountered this file before. If so - it checks if there are any particle systems that are no longer active ( !psq.particleCount ), if there is an unused particle system - it gets returned (you need to restart it of course and possibly remove from it's current parent and add to a new one). In the opposite case - a new particle system is created for NSDictionary that is already stored in system RAM
If this file has not been used before it will only then be loaded from device's memory
Code follows - be aware that:
1) You need to add +(id) particleWithDictionary:(NSDictionary*) dict to the CCParticleSystem class
2) There are no safety checks whatsoever (might cause a SIGABRT if there is no file on the device)
3) You need to reset and add the system to the layer yourself. Also - since we reuse particles - you should check if it already has a parent to avoid crash caused by adding to multiple parents
4) No static preloading of particle systems (yet ?)
-(CCParticleSystemQuad *) getParticleSystemForPDFile:(NSString*) plistFile
{
if( NSMutableDictionary * dict = [particlesDict objectForKey:plistFile] )
{
NSMutableArray * arr = [dict objectForKey:@"particle_systems"];
for(CCParticleSystemQuad * psq in arr)
{
if(!psq.particleCount)
{
printf("---- returning reused particle system\n");
printf("array count : %d\n", [arr count]);
return psq;
}
}
NSMutableDictionary * PDDict = [dict objectForKey:@"pd_dict"];
printf("---- returning new particle system from existing dictionary\n");
printf("array count : %d\n", [arr count]);
return [CCParticleSystemQuad particleWithDictionary:PDDict];
}
printf("---- returning new particle system for a new dictionary\n");
NSMutableDictionary * newDict = [[NSMutableDictionary alloc] init];
NSString *path = [CCFileUtils fullPathFromRelativePath:plistFile];
NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:path];
[newDict setObject:dict forKey:@"pd_dict"];
NSMutableArray * emitterArray = [[NSMutableArray alloc] initWithCapacity:5];
CCParticleSystemQuad * emitter = [CCParticleSystemQuad particleWithDictionary:dict];
[emitterArray addObject:emitter];
[newDict setObject:emitterArray forKey:@"particle_systems"];
[emitterArray release];
[particlesDict setObject:newDict forKey:plistFile];
[newDict release];
return emitter;
}
I have not made performance checks, but it's clear this approach is much faster. As I have said earlier, on my test 3G loading a new particle system directly from device could take a total of almost 20 ms - way too much to keep 60 fps. This method removes a need to both load file from disk and initalize the whole particle system