爲什麼需要自動生成代碼
在遊戲公司我發現一個問題,存在大量相似的代碼,而公司主程處理這些相似代碼的辦法則是編寫自己的代碼生成工具來自動生成這些代碼,因爲編寫相似的代碼不僅耗時,還不能保證每個人編寫的代碼格式是否標準,所以在這裏使用代碼生成工具能提升效率的同時,讓程序員更加的專注與邏輯部分的編輯。
那選擇什麼方式來生成代碼呢
我公司裏的兩位主程分別採用了不同的方法,首先項目老大使用的時正則表達式來進行代碼替換,但是我在使用這個的時候發現,正則確實不好用,對於一些程序員編寫代碼不規範,正則在這裏就無法識別了(當然除非你使用正則特別牛逼),提示替換就會出錯,對於替換出錯我是深有體會的(改的蛋疼)。後來另一個主程大佬說用個這方法不是很好,採用模板的方法來處理這些比較好。之後大佬真的採用模板方法來做了個自動生成讀取xml配置文件的工具,當時我是一萬個敬佩。所以我到網上查閱了下模板方法替換的方式生成代碼。
編寫模板
下面我來編寫一個簡單的模板,自己創建一個文件,並修改文件名及後綴,文件名爲:“default.tmpl”,其中使用${}的方式來獲取外部傳進來的數據。
#ifndef __${CLASSNAME}_H__
#define __${CLASSNAME}_H__
#include <map>
class C${Class_Name}
{
public:
C${Class_Name}() {}
~C${Class_Name}() {}
public:
struct ${En_name}_struct
{
public:
${En_name}_struct() : m_${Name}(0) {}
${Type} m_${Name};
};
private:
std::map<${Type}, ${En_name}_struct> m_${En_name}_cfg;
};
#endif
編寫python代碼
我問了下大佬,他是用go語言編寫的exe,但是我對go不大瞭解,想着採用python來編寫。
文件名:”build.py”
#! /usr/bin/env python
#coding=utf-8
from string import Template
class BuildData:
def Init(self):
filePath = './default.h'
class_file = open(filePath, 'w')
mycode = []
# 加載模板文件
template_file = open('default.tmpl', 'r')
tmpl = Template(template_file.read())
# 模板替換
mycode.append(tmpl.substitute(
CLASSNAME = 'DEFAULT',
Class_Name = 'Default',
En_name = 'mystruct',
Type = 'int',
Name = 'value'))
# 將代碼寫入文件
class_file.writelines(mycode)
class_file.close()
print('ok')
if __name__ == '__main__':
build = BuildData()
build.Init()
結語
執行上面的python文件,會在本路徑下生成一個”default.h”的頭文件,我們來看看我這裏生成的代碼
#ifndef __DEFAULT_H__
#define __DEFAULT_H__
#include <map>
class CDefault
{
public:
CDefault() {}
~CDefault() {}
public:
struct mystruct_struct
{
public:
mystruct_struct() : m_value(0) {}
int m_value;
};
private:
std::map<int, mystruct_struct> m_mystruct_cfg;
};
#endif
到這裏我的簡單的代碼生成器就實現了,可以根據這類方法編寫自己的生成器,像大佬那樣自動生成讀取xml的配置文件的話,則可以在python裏先讀取xml裏面的數據(當然少不了的是對每一個xml表都非常瞭解),在賦值到裏面去,我這裏爲了方便起見直接用了靜態數據。一點多了該睡覺了!