More Related Content Similar to 코드 생성을 사용해 개발 속도 높이기 NDC2011 Similar to 코드 생성을 사용해 개발 속도 높이기 NDC2011 (20) 코드 생성을 사용해 개발 속도 높이기 NDC20111. 코드 생성을 사용해
개발 속도 높이기
김이선 (veblush at neople | gmail)
네오플 던파개발실
2. 버블파이터
BNB 카트라이더 프로토타입 에버플래닛 던전엔파이터
프로그래머 리드 프로그래머 리드 프로그래머 리드 프로그래머 테크니컬 디렉터
게임 프로그래밍 10년차
8. const WChar* Fruit_strs[] =
{
L"apple",
L"banana",
L"grape"
};
void fillValue(CComboBox* cb)
{
cb->Clear();
for (int i=0; i<_countof(Fruit_str); i++)
cb->AddString(Fruit_strs[i]);
}
17. 코드 생성
C++ 헤더 코드
기술 코드
C++ 소스 코드
<Enum name="Fruit"> struct Fruit {
<C n="apple"/> enum T {
<C n="banana"/> apple, banana, grape };
<C n="grape"/> };
</Enum>
String toString(Fruit::T v)
{ … }
void fromString(WChar* str,
Fruit::T* v) { … }
23. 소스 작성 중
CodeGen
코드 작성
CodeGen
플러그인 실행
C++ 코드 생성
소스 작업 계속
33. 빠르게 원하는 기능 구현
구현 코드는 CodeGen 이 생성!
프로그래머는 내용에 집중!
36. 라이브러리 형태 지원
<Enum name="Fruit" dllDecl="LibDecl">
<Const name="apple" value="1"/>
<Const name="banana"/>
<Const name="grape"/>
struct LibDecl Fruit // LibDecl=__declspec(dllexport) …
{
enum T
{
apple = 1,
banana,
grape,
37. doxygen 주석 붙이기
<!--! 과일을 나타냅니다 -->
<Enum name="Fruit">
<Const name="apple" value="1" comment="사과"/>
<Const name="banana" comment="바나나는 맛있어"/>
//! 과일을 나타냅니다
struct Fruit
{
enum T
{
apple = 1, //!< 사과
banana, //!< 바나나는 맛있어
38. 생성된 코드에 유저 코드 삽입
<Enum name="Fruit">
<Const name="apple" value="1"/>
…
<HText><![CDATA[
Bool isMyFavorate(Fruit::T v);
]]></HText>
struct Fruit
{
enum T
…
Bool isMyFavorate(Fruit::T v);
};
47. Enum : CodeGen
<Enum name="Fruit">
<Const name="apple" value="1"/>
<Const name="banana"/>
<Const name="grape"/>
</Enum>
48. Enum : Generated
struct Fruit {
enum T {
apple=1,
banana,
grape
};
…
};
String toString(…);
fromString(…);
50. template <class EnumType>
void fillValue(CComboBox* cb)
{
cb->Clear();
for (size_t i=0; i<EnumType::enumCount; i++)
cb->AddString(EnumType::enumStr[i]);
};
51. Packet : 패킷 Serialization
패킷 내용을 구조체로 구성
Byte Serialization 코드 작성
53. Packet : CodeGen
<Packet name="TestPacket">
<Field name="code" type="Int4"/>
<Field name="name" type="String"/>
</Packet>
54. Packet : Generated
struct TestPacket : public Packet
{
TestPacket(Int4 code, String name);
virtual Int4 getStreamSize() const;
virtual void readFrom(Stream& is);
virtual void writeTo(Stream& os);
public:
Int4 code;
String name;
};
55. Packet : Usage
send() {
TestPacketPtr p = new TestPacket;
p->code = 1;
p->name = L"Test";
sendPacket(p);
// or
sendPacket(new TestPacket(1, L"Test"));
}
recv(TestPacket* p) {
p->code;
p->name;
}
56. 코드 생성이라 최적화 전략 가능
패킷 멤버 모두가 단순 타입이면
read/write 를 단순 memcpy로
57. Packet : Optimized
// Read
// Member is >> userId;
Int4 userId; is >> itemId;
Int4 itemId; is >> presetId;
Int4 presetId; is >> pos;
Vector2 pos;
// Read (Optimized)
is.read(this,
sizeof(TestPacket));
58. Data : POD 확장
멤버 변수를
XML | 바이트 스트림으로
Serialization
60. Data: CodeGen
<Data name="Item">
<Field name="id" type="Int4"/>
<Field name="name" type="String"/>
<Field name="desc" type="String"/>
<Field name="level" type="Int4" init="0"/>
<Field name="itemClass" type="ItemClass::T"
init="ItemClass::kMisc"/>
</Data>
61. Data : Generated
struct Item
{
Item();
void readFrom(Stream& is);
void writeTo(Stream& os) const;
void readFrom(XmlElement* xel);
void writeTo(XmlElement* xel) const;
Int4 id;
String name;
…
};
62. Data : Usage
<Item
Item item; id="100"
item.readFrom(xml); name="무쇠 갑옷"
item.id; desc="무척강하다"
item.name; itemClass="armor"
/>
65. <Pet 07 0a 00 00 00 06
id="10" 00 00 00 6d 00 6f
name="monkey" 00 6e 00 6b 00 65
food="banana" 00 79 00 02 00 00
> 00 02 00 00 00 00
<Items> 64 00 00 00 01 c8
<ItemSpawn 00 00 00 05 00 00
itemId="100" 00
/>
<ItemSpawn
itemId="200"
count="5"
용량 16%
/>
</Items>
속도 x3
</Pet>
66. 개발 때는 XML 사용
포맷 개방, 공동 작업!
배포 때는 Binary 사용
포맷 고정, 빠른 속도, 보안!
68. DbCall : CodeGen
<DbCall name="DcLogin" spName="spLogin">
<Param name="id" type="String" maxLen="24"/>
<Param name="ret" type="Int4" io="out"/>
</DbCall>
CREATE PROCEDURE spLogin
@id as nvarchar(24), @ret as int OUTPUT
69. DbCall : Generated
struct DcLogin
{
static HRESULT exec(DbSession* s,
const String& id, Int4* ret);
struct Param : public DbCallParam
{
String id;
Int4 ret;
virtual HRESULT exec(DbSession* s);
};
};
70. DbCall : Usage
hr = DcLogin::exec(s, "userid", &ret);
// or
p = new DcLogin::Param;
p->id = "userid";
p->exec(s);
p->ret;
CREATE PROCEDURE spLogin
@id as nvarchar(24), @ret as int OUTPUT
72. DbRowset : CodeGen
<DbRowset name="DrInven">
<Field name="id" type="Int4"/>
<Field name="count" type="Int4"/>
<Field name="expireTime" type="DateTime4"/>
</DbRowset>
SELECT id, count, expireTime
FROM tblInven WHERE charId=1
73. DbRowset : Generated
struct DrInven : public DbRowset
{
Int4 id;
Int4 count;
DateTime4 expireTime;
protected:
virtual HRESULT onInit(...);
virtual void onNext();
};
74. DbRowset : Usage
DrInvenPtr rs;
hr = DcInvenGet::exec(dbSession, &rs);
while (rs->next()) {
rs->id;
rs->count;
rs->expireTime;
}
SELECT id, count, expireTime
FROM tblInven WHERE charId=1
76. 사용한 CodeGen 개수
0 200 400 600 800 1000
Enum
Packet
Data
DbCall
DbRowset
78. 생성코드의 비중
생성코드
69,391
11%
그외코드
559,517