修改 cocosbuilder 源码,在编辑完ccb文件之后 publish ,直接生成 .h , .cpp 文件

时间:2021-11-26 12:40:53

最烦每次都要代码去绑定 ccb 里面的属性和方法了,有时候因为大小写的错误很烦。

所以找了 cocosbuilder 的源码,在它基础上生成 .h , .cpp 代码文件。


- (BOOL) publishDirectory:(NSString*) dir subPath:(NSString*) subPath
{
    CocosBuilderAppDelegate* ad = [CocosBuilderAppDelegate appDelegate];
    ResourceManager* resManager = [ResourceManager sharedManager];
    NSArray* resIndependentDirs = [resManager resIndependentDirs];
    
    NSFileManager* fm = [NSFileManager defaultManager];
    
    // Path to output directory for the currently exported path
    NSString* outDir = NULL;
    if (projectSettings.flattenPaths && projectSettings.publishToZipFile)
    {
        outDir = outputDir;
    }
    else
    {
        outDir = [outputDir stringByAppendingPathComponent:subPath];
    }
    
    // Check for generated sprite sheets
    BOOL isGeneratedSpriteSheet = NO;
    NSDate* srcSpriteSheetDate = NULL;
    
    if ([projectSettings.generatedSpriteSheets objectForKey:subPath])
    {
        isGeneratedSpriteSheet = YES;
        srcSpriteSheetDate = [self latestModifiedDateForDirectory:dir];
        
        // Clear temporary sprite sheet directory
        [fm removeItemAtPath:[projectSettings tempSpriteSheetCacheDirectory] error:NULL];
    }
    
    // Create the directory if it doesn't exist
    if (!isGeneratedSpriteSheet)
    {
        BOOL createdDirs = [fm createDirectoryAtPath:outDir withIntermediateDirectories:YES attributes:NULL error:NULL];
        if (!createdDirs)
        {
            [warnings addWarningWithDescription:@"Failed to create output directory %@" isFatal:YES];
            return NO;
        }
    }
    
    // Add files from main directory
    NSMutableSet* files = [NSMutableSet setWithArray:[fm contentsOfDirectoryAtPath:dir error:NULL]];
    
    // Add files from resolution depentant directories
    for (NSString* publishExt in publishForResolutions)
    {
        NSString* resolutionDir = [dir stringByAppendingPathComponent:publishExt];
        BOOL isDirectory;
        if ([fm fileExistsAtPath:resolutionDir isDirectory:&isDirectory] && isDirectory)
        {
            [files addObjectsFromArray:[fm contentsOfDirectoryAtPath:resolutionDir error:NULL]];
        }
    }
    
    // Add files from the -auto directory
    NSString* autoDir = [dir stringByAppendingPathComponent:@"resources-auto"];
    BOOL isDirAuto;
    if ([fm fileExistsAtPath:autoDir isDirectory:&isDirAuto] && isDirAuto)
    {
        [files addObjectsFromArray:[fm contentsOfDirectoryAtPath:autoDir error:NULL]];
    }
    
    // Iterate through all files
    for (NSString* fileName in files)
    {
        if ([fileName hasPrefix:@"."]) continue;
        
        NSString* filePath = [dir stringByAppendingPathComponent:fileName];
        
        BOOL isDirectory;
        BOOL fileExists = [fm fileExistsAtPath:filePath isDirectory:&isDirectory];
        if (fileExists && isDirectory)
        {
            NSString* childPath = NULL;
            if (subPath) childPath = [NSString stringWithFormat:@"%@/%@", subPath, fileName];
            else childPath = fileName;
            
            // Skip resource independent directories
            if ([resIndependentDirs containsObject:fileName]) continue;
            
            // Skip generated sprite sheets
            if (isGeneratedSpriteSheet) continue;
            
            // Skip the empty folder
            if ([[fm contentsOfDirectoryAtPath:filePath error:NULL] count] == 0)  continue;
            
            // Skip the fold no .ccb files when onlyPublishCCBs is true
            if(projectSettings.onlyPublishCCBs && ![self containsCCBFile:filePath]) continue;
            
            [self publishDirectory:filePath subPath:childPath];
        }
        else
        {
            // Publish file
            
            // Copy files
            for (NSString* ext in copyExtensions)
            {
                // Skip non png files for generated sprite sheets
                if (isGeneratedSpriteSheet && ![ext isEqualToString:@"png"]) continue;
                
                if ([[fileName lowercaseString] hasSuffix:ext] && !projectSettings.onlyPublishCCBs)
                {
                    // This file should be copied
                    NSString* dstFile = [outDir stringByAppendingPathComponent:fileName];
                    
                    // Use temp cache directory for generated sprite sheets
                    if (isGeneratedSpriteSheet)
                    {
                        dstFile = [[projectSettings tempSpriteSheetCacheDirectory] stringByAppendingPathComponent:fileName];
                    }
                    
                    // Make conversion rules for audio
                    NSString* newFormat = NULL;
                    
                    if ([ext isEqualToString:@"wav"])
                    {
                        if (targetType == kCCBPublisherTargetTypeIPhone)
                        {
                            newFormat = @"caf";
                        }
                        else if (targetType == kCCBPublisherTargetTypeHTML5)
                        {
                            newFormat = @"mp3";
                        }
                        else if (targetType == kCCBPublisherTargetTypeAndroid)
                        {
                            newFormat = @"ogg";
                        }
                    }
                    /*
                    else if ([ext isEqualToString:@"mp3"])
                    {
                        if (targetType == kCCBPublisherTargetTypeAndroid)
                        {
                            newFormat = @"ogg";
                        }
                    }
                     */
                
                    if (newFormat)
                    {
                        // Set new name
                        dstFile = [[dstFile stringByDeletingPathExtension] stringByAppendingPathExtension:newFormat];
                        
                        // Add to conversion table
                        NSString* localName = fileName;
                        if (subPath) localName = [subPath stringByAppendingPathComponent:fileName];
                        
                        [self addRenamingRuleFrom:localName to:[[localName stringByDeletingPathExtension] stringByAppendingPathExtension:newFormat]];
                    }
                
                    // Copy file (and possibly convert)
                    if (![self copyFileIfChanged:filePath to:dstFile forResolution:NULL isSpriteSheet:isGeneratedSpriteSheet outDir:outDir srcDate: srcSpriteSheetDate]) return NO;
                    
                    if (publishForResolutions)
                    {
                        for (NSString* res in publishForResolutions)
                        {
                            if (![self copyFileIfChanged:filePath to:dstFile forResolution:res isSpriteSheet:isGeneratedSpriteSheet outDir:outDir srcDate: srcSpriteSheetDate]) return NO;
                        }
                    }
                }
            }
            
            // Publish ccb files
            if ([[fileName lowercaseString] hasSuffix:@"ccb"] && !isGeneratedSpriteSheet)
            {
                NSString* strippedFileName = [fileName stringByDeletingPathExtension];
                
                NSString* dstFile = [[outDir stringByAppendingPathComponent:strippedFileName] stringByAppendingPathExtension:publishFormat];
                
                //处理 g_pTempOutPutPath
                {
                    NSString* strPath = [NSString stringWithFormat:@"%@",dstFile];
                    NSArray* ary = [dir componentsSeparatedByString:@"/"];
                    NSMutableString* outPutPath = [NSMutableString stringWithString:@""];
                    for (int iii=0;iii<[ary count]-1 ;iii++ )
                    {
                        NSString* str = [ary objectAtIndex:iii ];
                        [outPutPath appendFormat:@"/%@",str];
                    }
                    g_pTempRootPath = outPutPath;//root path
                    
                    NSString* strOutPathDirect = [NSString stringWithFormat:@"%@/codeOutPut/",outPutPath];
                    outPutPath = [NSMutableString stringWithFormat:@"%@/%@" , strOutPathDirect ,strippedFileName];
                    
                    if(1 )
                    {
                        NSError* error = nil;
                        [[NSFileManager defaultManager] createDirectoryAtPath:strOutPathDirect withIntermediateDirectories:NO attributes:nil error:&error];
                        if (error != nil) {
                            NSLog(@"error = %@",error);
                        }
                    }
                    

                    g_pTempOutPutClassName = strippedFileName;
                    g_pTempOutPutPath = [NSString stringWithString:outPutPath];
                }
                
                
                // Add file to list of published files
                NSString* localFileName = [dstFile relativePathFromBaseDirPath:outputDir];
                [publishedResources addObject:localFileName];
                
                if ([dstFile isEqualToString:filePath])
                {
                    [warnings addWarningWithDescription:@"Publish will overwrite files in resource directory." isFatal:YES];
                    return NO;
                }
                
                NSDate* srcDate = [CCBFileUtil modificationDateForFile:filePath];
                NSDate* dstDate = [CCBFileUtil modificationDateForFile:dstFile];
                
                //if (![fm fileExistsAtPath:dstFile] || [self srcFile:filePath isNewerThanDstFile:dstFile])
                if (![srcDate isEqualToDate:dstDate])
                {
                    [ad modalStatusWindowUpdateStatusText:[NSString stringWithFormat:@"Publishing %@...", fileName]];
                    
                    // Remove old file
                    [fm removeItemAtPath:dstFile error:NULL];
                    
                    
                    
                    // Copy the file
                    BOOL sucess = [self publishCCBFile:filePath to:dstFile];
                    if (!sucess) return NO;
                    
                    [CCBFileUtil setModificationDate:srcDate forFile:dstFile];
                }
                
                g_pTempOutPutPath = nil;
            }
        }
    }
    
    if (isGeneratedSpriteSheet)
    {
        // Sprite files should have been saved to the temp cache directory, now actually generate the sprite sheets
        NSString* spriteSheetDir = [outDir stringByDeletingLastPathComponent];
        NSString* spriteSheetName = [outDir lastPathComponent];
        ProjectSettingsGeneratedSpriteSheet* ssSettings = [projectSettings smartSpriteSheetForSubPath:subPath];

        // Check if sprite sheet needs to be re-published
        for (NSString* res in publishForResolutions)
        {
            NSArray* srcDirs = [NSArray arrayWithObjects:
                                [projectSettings.tempSpriteSheetCacheDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@"resources-%@", res]],
                                projectSettings.tempSpriteSheetCacheDirectory,
                                nil];
            
            NSString* spriteSheetFile = NULL;
            if (publishToSingleResolution) spriteSheetFile = outDir;
            else spriteSheetFile = [[spriteSheetDir stringByAppendingPathComponent:[NSString stringWithFormat:@"resources-%@", res]] stringByAppendingPathComponent:spriteSheetName];
            
            // Skip publish if sprite sheet exists and is up to date
            NSDate* dstDate = [CCBFileUtil modificationDateForFile:[spriteSheetFile stringByAppendingPathExtension:@"plist"]];
            if (dstDate && [dstDate isEqualToDate:srcSpriteSheetDate] && !ssSettings.isDirty)
            {
                continue;
            }
                        
            Tupac* packer = [Tupac tupac];
            packer.outputName = spriteSheetFile;
            packer.outputFormat = TupacOutputFormatCocos2D;
            
            if (targetType == kCCBPublisherTargetTypeIPhone)
            {
                packer.imageFormat = ssSettings.textureFileFormat;
                packer.compress = ssSettings.compress;
                packer.dither = ssSettings.dither;
            }
            else if (targetType == kCCBPublisherTargetTypeAndroid)
            {
                packer.imageFormat = ssSettings.textureFileFormatAndroid;
                packer.compress = NO;
                packer.dither = ssSettings.ditherAndroid;
            }
            else if (targetType == kCCBPublisherTargetTypeHTML5)
            {
                packer.imageFormat = ssSettings.textureFileFormatHTML5;
                packer.compress = NO;
                packer.dither = ssSettings.ditherHTML5;
            }
            
            // Update progress
            [ad modalStatusWindowUpdateStatusText:[NSString stringWithFormat:@"Generating sprite sheet %@...", [[subPath stringByAppendingPathExtension:@"plist"] lastPathComponent]]];
            
            // Pack texture
            packer.directoryPrefix = subPath;
            packer.border = YES;
            [packer createTextureAtlasFromDirectoryPaths:srcDirs];
            
            // Set correct modification date
            [CCBFileUtil setModificationDate:srcSpriteSheetDate forFile:[spriteSheetFile stringByAppendingPathExtension:@"plist"]];
        }
        
        [publishedResources addObject:[subPath stringByAppendingPathExtension:@"plist"]];
        [publishedResources addObject:[subPath stringByAppendingPathExtension:@"png"]];
        
        if (ssSettings.isDirty) {
            ssSettings.isDirty = NO;
            [projectSettings store];
        }
    }
    
    return YES;
}


//

- (void) writeDocument:(NSDictionary*)doc
{
    NSDictionary* nodeGraph = [doc objectForKey:@"nodeGraph"];
    jsControlled = [[doc objectForKey:@"jsControlled"] boolValue];
    
    [self outputAssginedMemberAndSelector:nodeGraph];//输出绑定的变量和函数
    
    [self cacheStringsForNode:nodeGraph];
    [self cacheStringsForSequences:doc];
    [self transformStringCache];
    
    [self writeHeader];
    [self writeStringCache];
    [self writeSequences:doc];
    [self writeNodeGraph:nodeGraph];
}

NSString* g_pTempOutSuperClassName;//父类头文件的类名字
NSString* g_pTempOutSubClassName;//子类头文件的类名字
NSString* g_pWantSaveCodeFilePath = nil;//希望存储代码的位置

-(void)searchMemberAndAppend:(NSDictionary*)node saveInMemberString:(NSMutableString*)strMembers saveInMemberInitString:(NSMutableString*)strMembersInit strMembersBind:(NSMutableString*)strMembersBind saveMenuBind:(NSMutableString*)strMenuBinds saveMenuHead:(NSMutableString*)strMenuHead saveMenuCPP:(NSMutableString*)strMenuCpp saveMenuCallBackFun_SuperHead:(NSMutableString*)strMenuCallBackFun_SuperHead
{
    NSString* baseClass = [node objectForKey:@"baseClass"];
    NSString* customClass = [node objectForKey:@"customClass"];
    NSArray* aryChildren = [node objectForKey:@"children" ];
    NSString* displayName = [node objectForKey:@"displayName"];
    NSString* memberVarAssignmentName = [node objectForKey:@"memberVarAssignmentName"];
    NSNumber* memberVarAssignmentType = [node objectForKey:@"memberVarAssignmentType"];
    
    //检查生成代码的目录
    if ([displayName isEqualToString:@"code_save_path"])
    {
        g_pWantSaveCodeFilePath = memberVarAssignmentName;
        return;
    }
    
    //成员
    if ([memberVarAssignmentType intValue] == 2 && [memberVarAssignmentName length] > 0)
    {
        NSString* classnames = [customClass length] == 0 ? baseClass : customClass;
        NSString* comentStr = [displayName isEqualToString:baseClass] ? @"" : displayName;
        //owner
        //  类型* 成员名;//注释
        NSString* oneMember = [NSString stringWithFormat:@"\t%@* %@;//%@\r\n",classnames,memberVarAssignmentName ,comentStr];
        [strMembers appendString:oneMember];
        
        //初始化代码
        NSString* strInit = [NSString stringWithFormat:@"\t\t%@ = NULL;\r\n",memberVarAssignmentName];
        [strMembersInit appendString:strInit];
        
        //绑定成员
        NSString* strBind = [NSString stringWithFormat:@"\t\tCCB_MEMBERVARIABLEASSIGNER_GLUE(this, \"%@\", %@*, this->%@);\r\n",memberVarAssignmentName,classnames,memberVarAssignmentName];
        [strMembersBind appendString:strBind];
        
    }
    
    //绑定菜单项
    if ([baseClass rangeOfString:@"CCMenuItem"].length > 0)
    {
        //菜单项的绑定
        NSArray* aryProperties = [node objectForKey:@"properties"];
        for (NSDictionary* dic in aryProperties)
        {
            NSString* proname = [dic objectForKey:@"name"];
            NSString* protype = [dic objectForKey:@"type"];
            if ([proname rangeOfString:@"block"].length > 0 && [protype rangeOfString:@"Block"].length > 0 )
            {
                NSArray* aryTheValue = [dic objectForKey:@"value"];
                if ([aryTheValue count] == 1) {
                    continue;
                }
                NSString* funName = [aryTheValue objectAtIndex:0];
                if ([funName isKindOfClass:[NSString class]] == NO || [funName length] == 0) {
                    break;
                }
                
                //绑定
                NSString* newBind = [NSString stringWithFormat:@"\t\tCCB_SELECTORRESOLVER_CCMENUITEM_GLUE(this, \"%@\", %@::%@);\r\n", funName ,g_pTempOutSuperClassName, funName ];
                if ([strMenuBinds rangeOfString:newBind].length == 0)
                {
                    [strMenuBinds appendString:newBind];
                    //头文件函数
                    [strMenuHead appendFormat:@"\tvirtual void %@(cocos2d::CCObject* pSender);\r\n",funName];
                    //cpp 文件
                    [strMenuCpp appendFormat:@"void %@::%@(cocos2d::CCObject* pSender)\r\n{\r\n\r\n}\r\n",g_pTempOutSubClassName,funName];
                    //父类头文件里面的函数声明 必须给子类来实现
                    [strMenuCallBackFun_SuperHead appendFormat:@"\tvirtual void %@(cocos2d::CCObject* pSender)=0;\r\n",funName];
                }                
                
                break;
            }
        }
    
    }
    
    //检查 child
    for (NSDictionary* subNode in aryChildren)
    {
        if ([subNode isKindOfClass:[NSDictionary class]]) {
            [self searchMemberAndAppend:subNode saveInMemberString:strMembers saveInMemberInitString:(NSMutableString*)strMembersInit strMembersBind:strMembersBind saveMenuBind:strMenuBinds saveMenuHead:strMenuHead saveMenuCPP:strMenuCpp saveMenuCallBackFun_SuperHead:strMenuCallBackFun_SuperHead];
        }
    }
    
}

extern NSString* g_pTempOutPutPath;
extern NSString* g_pTempOutPutClassName;
extern NSString* g_pTempRootPath;



-(void)outputAssginedMemberAndSelector:(NSDictionary*)nodeGraph
{
    //输出方式是 父类一个头文件,子类一个头文件+一个CPP文件.每次publish都重新生成父类的头文件,然后判断子类的头文件和cpp文件是否存在,如果已经存在,则不再做生成操作
    g_pTempOutSuperClassName = [NSString stringWithFormat:@"%@_ccbHead",g_pTempOutPutClassName];
    g_pTempOutSubClassName = g_pTempOutPutClassName;
    g_pWantSaveCodeFilePath = nil;
    
    //存储成员
    NSMutableString* strMembers = [NSMutableString stringWithString:@"\r\n"];//成员定义
    NSMutableString* strMembersInit = [NSMutableString stringWithString:@"\r\n"];//成员初始化
    NSMutableString* strMembersBind = [NSMutableString stringWithString:@"\r\n"];//成员绑定
    NSMutableString* strMenuBinds = [NSMutableString stringWithString:@"\r\n"];//菜单事件绑定
    NSMutableString* strMenuHead = [NSMutableString stringWithString:@"\r\n"];//菜单函数头
    NSMutableString* strMenuCpp = [NSMutableString stringWithString:@"\r\n"];//菜单函数 cpp
    NSMutableString* strMenuCallBackFun_SuperHead = [NSMutableString stringWithString:@"\r\n"];
    
    [self searchMemberAndAppend:nodeGraph saveInMemberString:strMembers saveInMemberInitString:(NSMutableString*)strMembersInit strMembersBind:strMembersBind saveMenuBind:strMenuBinds saveMenuHead:strMenuHead saveMenuCPP:strMenuCpp saveMenuCallBackFun_SuperHead:strMenuCallBackFun_SuperHead];
    
//    NSLog(@"%@",strMembers);
//    NSLog(@"%@",strMenuBinds);
//    NSLog(@"%@",strMenuHead);
//    NSLog(@"%@",strMenuCpp);
    
    //写文件存储
    if (g_pTempOutPutPath != nil)
    {
        NSError* error = nil;
        [strMembers writeToFile:[NSString stringWithFormat:@"%@__member.txt",g_pTempOutPutPath] atomically:NO encoding:4 error:&error];
        if (error != nil) {
            NSLog(@"error = %@",error);
            error = nil;
        }
        [strMenuBinds writeToFile:[NSString stringWithFormat:@"%@__menuBind.txt",g_pTempOutPutPath] atomically:NO encoding:4 error:&error];
        if (error != nil) {
            NSLog(@"error = %@",error);
            error = nil;
        }
        
        [strMenuHead writeToFile:[NSString stringWithFormat:@"%@__menuH.txt",g_pTempOutPutPath] atomically:NO encoding:4 error:&error];
        if (error != nil) {
            NSLog(@"error = %@",error);
            error = nil;
        }
        
        [strMenuCpp writeToFile:[NSString stringWithFormat:@"%@__menuCPP.txt",g_pTempOutPutPath] atomically:NO encoding:4 error:&error];
        if (error != nil) {
            NSLog(@"error = %@",error);
            error = nil;
        }

    }

    //自动生成 .h 文件 和子类的 .h .cpp文件

    

    if (g_pWantSaveCodeFilePath.length > 0)
    {
        NSString* templatePath1 = [[NSBundle mainBundle] pathForResource:@"TemplateCCB_CodeFile_Head_h" ofType:@"txt"];
        
        //得到写父类头文件的路径
        NSString* pathHeadSuper = [NSString stringWithFormat:@"%@/%@/%@.h",g_pTempRootPath,g_pWantSaveCodeFilePath , g_pTempOutSuperClassName ];
        NSLog(@"Head file path = %@",pathHeadSuper);
        
        //首先替换父类模板的内容
        NSStringEncoding enc = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingGB_18030_2000);
        NSError* error = nil;
        NSString* strContenTemplateH = [NSString stringWithContentsOfFile:templatePath1 encoding:enc error:&error];//父类模板本地读取
        if (error) {
            NSLog(@"error = %@",error);
        }
        
        strContenTemplateH = [strContenTemplateH stringByReplacingOccurrencesOfString:@"TemplateCCB_CodeFile_Head" withString:g_pTempOutSuperClassName];
        
        strContenTemplateH = [strContenTemplateH stringByReplacingOccurrencesOfString:@"//input properties here." withString:strMembers];//成员定义
        strContenTemplateH = [strContenTemplateH stringByReplacingOccurrencesOfString:@"//input init here." withString:strMembersInit];//变量初始化
        strContenTemplateH = [strContenTemplateH stringByReplacingOccurrencesOfString:@"//input memberBind here." withString:strMembersBind];//成员绑定
        strContenTemplateH = [strContenTemplateH stringByReplacingOccurrencesOfString:@"//input menuItemSelector shengming here." withString:strMenuCallBackFun_SuperHead];//函数声明绑定
        strContenTemplateH = [strContenTemplateH stringByReplacingOccurrencesOfString:@"//input menuItemSelector here." withString:strMenuBinds];//函数绑定
        strContenTemplateH = [strContenTemplateH stringByReplacingOccurrencesOfString:@"//input ccb file name here." withString:[NSString stringWithFormat:@"strCCBFileName = \"%@.ccbi\";",g_pTempOutSubClassName ]];//ccb文件
        
        
        
        error = nil;
        [strContenTemplateH writeToFile:pathHeadSuper atomically:NO encoding:enc error:&error];
        if (error) {
            NSLog(@"error = %@",error);
        }
    }
    
    //替换子类的头文件的内容
    if (g_pWantSaveCodeFilePath.length > 0)
    {
        NSString* pathHeadSub = [NSString stringWithFormat:@"%@/%@/%@.h",g_pTempRootPath,g_pWantSaveCodeFilePath , g_pTempOutSubClassName ];
        NSLog(@"Head file path = %@",pathHeadSub);
        bool isAllReadyExist = [[NSFileManager defaultManager] fileExistsAtPath:pathHeadSub];
        if (!isAllReadyExist)
        {
            NSString* templatePath2 = [[NSBundle mainBundle] pathForResource:@"TemplateCCB_CodeFile_h" ofType:@"txt"];
            
            //首先替换父类模板的内容
            NSStringEncoding enc = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingGB_18030_2000);
            NSError* error = nil;
            NSString* strContenTemplateH_sub = [NSString stringWithContentsOfFile:templatePath2 encoding:enc error:&error];//子类 .h 模板
            if (error) {
                NSLog(@"error = %@",error);
            }
            
            strContenTemplateH_sub = [strContenTemplateH_sub stringByReplacingOccurrencesOfString:@"TemplateCCB_CodeFile_Head" withString:g_pTempOutSuperClassName];
            strContenTemplateH_sub = [strContenTemplateH_sub stringByReplacingOccurrencesOfString:@"TemplateCCB_CodeFile" withString:g_pTempOutSubClassName];
            strContenTemplateH_sub = [strContenTemplateH_sub stringByReplacingOccurrencesOfString:@"//input subclass menu shengming here." withString:strMenuHead];

            
            error = nil;
            [strContenTemplateH_sub writeToFile:pathHeadSub atomically:NO encoding:enc error:&error];
            if (error) {
                NSLog(@"error = %@",error);
            }
            
            
        }
    }

    //替换子类的cpp 文件的内容
    if (g_pWantSaveCodeFilePath.length > 0)
    {
        NSString* pathCppSub = [NSString stringWithFormat:@"%@/%@/%@.cpp",g_pTempRootPath,g_pWantSaveCodeFilePath , g_pTempOutSubClassName ];
        NSLog(@"Cpp file path = %@",pathCppSub);
        bool isAllReadyExist = [[NSFileManager defaultManager] fileExistsAtPath:pathCppSub];
        if (!isAllReadyExist)
        {
            NSString* templatePath3 =[[NSBundle mainBundle] pathForResource:@"TemplateCCB_CodeFile_cpp" ofType:@"txt"];
            
            //首先替换父类模板的内容
            NSStringEncoding enc = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingGB_18030_2000);
            NSError* error = nil;
            NSString* strContenTemplateCPP_sub = [NSString stringWithContentsOfFile:templatePath3 encoding:enc error:&error];//子类 .cpp 模板
            if (error) {
                NSLog(@"error = %@",error);
            }
            
            strContenTemplateCPP_sub = [strContenTemplateCPP_sub stringByReplacingOccurrencesOfString:@"TemplateCCB_CodeFile_Head" withString:g_pTempOutSuperClassName];
            strContenTemplateCPP_sub = [strContenTemplateCPP_sub stringByReplacingOccurrencesOfString:@"TemplateCCB_CodeFile" withString:g_pTempOutSubClassName];
            strContenTemplateCPP_sub = [strContenTemplateCPP_sub stringByReplacingOccurrencesOfString:@"//input menuItemSelector dingyi here." withString:strMenuCpp];
            
            
            error = nil;
            [strContenTemplateCPP_sub writeToFile:pathCppSub atomically:NO encoding:enc error:&error];
            if (error) {
                NSLog(@"error = %@",error);
            }
            
            
        }
    }
    
    
}



模板文件暂不提供