PIXNET Logo登入

太陽系後援會

跳到主文

部落格全站分類:職場甘苦

  • 相簿
  • 部落格
  • 留言
  • 名片
  • 8月 08 週五 200820:26
  • 噹噹噹~~噹!! 各位鄉民,這裡是彼得哥的生平事蹟紀錄簿!

8/7
       今天是中國七夕情人節,彼得哥對外發表了想法 : [ 不知怎麼著總有種淡淡(蛋蛋)的哀愁 ! ]
       鄉民齊稱 : [ 彼得哥萬歲萬歲萬萬歲 .......]
8/8
       今天是父親節,彼得哥在克里斯的循循善誘下,講出了今日佳句 : [ 來打炮吧 ! ]
(繼續閱讀...)
文章標籤

kgsprogrammer 發表在 痞客邦 留言(1) 人氣(88)

  • 個人分類:名言錦句篇
▲top
  • 8月 08 週五 200801:38
  • VGL 電玩交響音樂會週日隆重登場


VGL 電玩交響音樂會主辦單位於今(7)日在台北圓山飯店舉辦抵台記者會,會中除了安排 VGL 製作人 Tommy、指揮 Jack 與金獎音樂大師史擷詠進行對談之外,並邀請華裔鋼琴家 Martin Leung 現場演奏多首經典電玩樂曲,以及表演當年在網路上一炮而紅的「蒙眼彈奏瑪俐歐」。
VGL 電玩交響音樂會即將於週日與週一(8 月 10、11 日)在板橋體育館演出,由於本次是在數千名熱情玩家的連署之下首度來台演出,因此也格外受到台灣玩家的注目。
共同創辦 VGL,同時兼任製作主持的 Tommy 與製作指揮的 Jack,特別在演出前夕出席記者會,向台灣玩家分享對本次活動的期許與感想,並透露了部分演出曲目的資訊。
記者會中 Tommy 也展示了 VGL 最新出版的音樂 CD「Video Games Live Volume 1」,收錄《最後一戰》、《俄羅斯方塊》、《王國之心》、《魔獸爭霸》、《惡魔城》等經典電玩樂曲。Tommy 表示該 CD 將於活動現場販賣,希望喜愛電玩樂曲的玩家多支持。
超期待VGL的啦
(繼續閱讀...)
文章標籤

kgsprogrammer 發表在 痞客邦 留言(0) 人氣(63)

  • 個人分類:閒聊八卦
▲top
  • 8月 07 週四 200823:43
  • RTTI 二部曲


上一篇提到如何去使用C++函式庫所內建的RTTI操作方式,
但是怎麼自己設計一個還是有點霧煞煞是吧。
沒關係,奉彼德哥之命,我又看了一些書,爬了一些文章。
現在就來跟各位娓娓道來這些心路歷程。
要怎麼設計RTTI?
想想看,如果你要查字典,是不是要先知道部首,部首不知道,你還可以查注音,不會唸的話查筆畫總可以吧。
部首,注音,筆畫你可以想像成索引,索引到的地方就是字詞的解釋(好久沒查字典了,老實說,都快忘記怎麼查了)。
如此,當我們要建立RTTI的資料庫的時候,當類別被建構起來的時候紀錄必要的資訊。
怎麼樣,聽起來很簡單吧。
如果就這樣結束,我應該會被彼得哥的大鎖打死。
來,首先我們需要一個資料結構來儲存類別型錄。
其中至少要有char *來表示類別名稱,一個Next指向下一個,一個First指向第一個,由於First只需要有一個,所以用static來修飾。
class CRTTIClass
{
public:
    char * m_pcClassName;
    int        m_iObjectSize;
    UINT  m_uiSchema;
    CObject * (PASCAL * m_pfnCreateObject) ();
    CRTTIClass * m_pBaseClass;
    static CRTTIClass * ms_pFirstClass;
    CRTTIClass * m_pNextClass;
}
記得要對ms_pFirstClass做初始化
CRTTIClass * CRTTIClass::ms_pFirstClass = NULL;
再來
為了要讓每一個class都能夠有這個CRTTIClass,間單的方式就是在每個class都有這個CRTTIClass的instance,但是這樣每個class都要再寫對每個CRTTIClass設定的動作。想一想,這真的是一件麻煩的事。
因此,我們使用巨集來完成這項工作
定義以下巨集
#define DECLARE_DYNAMIC(class_name) \
public:
    static CRTTIClass class##class_name;  \
    virtual CRTTIClass * GetRTTIClass() const;
如此你只要使用此巨集
    DECLARE_DYNAMIC(CA);
編譯器會幫你展開為
    public:
        static CRTTIClass classCA;
        virtual CRTTIClass * GetRTTIClass() const;
這樣還沒完
我們只完成宣告而已,設定與連結的動作當然也要神不知鬼不覺的做完才可以
再來定義一個巨集
#define IMPLEMENT_DYNAMIC(class_name, base_class_name) \
    _IMPLEMENT_RTTICLASS(class_name, base_class_name, 0xFFFF, NULL)
#define _IMPLEMENT_RTTICLASS(class_name, base_class_name, wSchema, pfnNew) \
    static char _lpsz##class_name[] = #class_name; \
    CRTTIClass class_name::class##class_name = {\
        _lpsz##class_name, sizeof(class_name), wSchema, pfnNew, \
        RUNTIME_CLASS(base_class_name), NULL }; \
    static AFX_CLASSINT _int_##class_name(&class_name::class##class_name); \
    CRTTIClass * class_name::GetRTTIClass() const \
     { return &class_name::class##class_name; } \
在這裡又有一個RUNTIME_CLASS巨集,定義如下
#define RUNTIME_CLASS(class_name) \
    (&class_name::class##class_name)
其中更有一個重要的東西存在,就是AFX_CLASSINT這個struct,它負責linked list的串接工作
所以還必須宣告並定義AFX_CLASSINT
struct AFX_CLASSINT
{
    AFX_CLASSINT(CRTTIClass * pNewClass);
}
C++的struct可以有建構子與解構子
AFX_CLASSINT::AFX_CLASSINT(CRTTIClass * pNewClass)
{
    pNewClass->m_pNextClass = CRTTIClass::ms_pFirstClass;
    CRTTIClass::ms_pFirstClass = pNewClass;
}
接下來看一下範例
class CChild : public CBase
{
    //在類別內宣告
    DECLARE_DYNAMIC(CChild)
};
//在類別外宣告
IMPLEMENT_DYNAMIC(CChild, CBase)
上面的程式就會展開為
class CChild : public CBase
{
public:
    static CRTTIClass classCChild;
    virtual CRTTIClass * GetRTTIClass() const;
};
static char _lpszCChild[] = "CChild";
CRTTIClass CChild::classCChild = {
    _lpszCChild, sizeof(CChild), OxFFFF, NULL,
    &CBase::classCBase, NULL };
static AFX_CLASSINT _int_CChild(&CChild::classCChild);
CRTTIClass * CChild::GetRTTIClass() const
{ return &CChild::classCChild; }
如此複雜的工作就讓巨集給做完了,如此就不需要每個class都打一堆Code了
但是,串列的頭總是需要特別的處理。
class CBase
{
public:
    static CRTTIClass classCBase;
    virtual CRTTIClass * GetRTTIClass() const;
}
static char lpszCChild[] = "CBase";
struct CRTTIClass CBase::classCBase = 
{ lpszCChild, sizeof(CBase), 0xFFFF, NULL, NULL };
static AFX_CLASSINT _int_CBase(&CBase::classCBase);
CRTTIClass * CBase::GetRTTIClass() const
{
    return &CBase::classCBase;
}
聰明的你一定也看出來這些落落長的程式碼也可以用巨集來完成,如果你只有一個Root的class那你是可以不必設計一個專為root宣告RTTI的巨集,但是你如果想要很多種類別型錄,那麼設計一個給root使用的巨集是在所難免的,這就交給你們設計啦,希望彼得哥不會打我。
如此類別型錄已經都設計好了,但總覺得少了什麼
對了!!!!!!
就是IsKindOf
有類別型錄但是沒有查表的方式,這要叫別人怎麼查阿
奉彼得哥之命,馬上補上IsKindOf
IsKindOf要怎麼設計呢?左思右想之下,想到一個偷懶的方法
請看以下範例
CBase
{
public:
    .....................
    .....................
    bool IsKindOf(const CRTTIClass * pClass) const;
};
bool CBase::IsKindOf(const CRTTIClass * pClass) const
{
    CRTTIClass * pClassThis = GetRTTIClass();
    while (pClassThis != NULL)
    {
        if (pClassThis = pClass)
            return true;
        pClassThis = pClassThis->m_pBaseClass;
    }
    return false;
}
IsKindOf就是再檢查某個物件是不是某一個物件的延伸,所以他追查的方式是同宗查詢
聰明的你一定也看出來它可以設計為巨集,並且設計在宣告root的RTTI巨集裡。
有些人會覺得這些使用的方式很眼熟,沒錯它就是MFC裡的RTTI
但這不是我們的主要探討所在,最重要的是讓一般人能夠理解RTTI的設計原理
有什麼問題記得要問彼得哥喔
讓我們一起大喊
彼得哥萬歲~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
(繼續閱讀...)
文章標籤

kgsprogrammer 發表在 痞客邦 留言(0) 人氣(287)

  • 個人分類:C++
▲top
  • 8月 05 週二 200811:20
  • 各位後援會的會員,AVBODY注意一下!!

鑑於彼得哥的高人氣,讓本部落格一鳴驚人,
要求加入會員的聲浪不斷升高,
面對這樣的情形,一則以喜,一則以憂,
喜的是本後援會的壯大指日可待,
憂的是面對未來幾十萬會員的加入,
(繼續閱讀...)
文章標籤

kgsprogrammer 發表在 痞客邦 留言(2) 人氣(116)

  • 個人分類:後援會公告
▲top
  • 8月 04 週一 200800:30
  • RTTI

RTTI是什麼?做這些有什麼意義?
呜
~~我想,很多programmer對這個既熟悉又充滿陌生的辭彙感到一知半解。
熟悉的地方是,每天都要用它。引擎裡有用到,就算引擎沒有,對於一個專業的物件導向程式設計師來說,
RTTI是不可或缺的,畢竟設計一個class就是在宣告一個型別(Type)。陌生的地方是,很多人都會用(因為有人已經寫好了,只要call function就好),但是卻不了解怎麼做,一個programmer怎麼可以對技術一知半解,這要怎麼生存。寫這邊文章的最主要目標就是分享我對RTTI研究的心得,希望也能夠帶給大家許多幫助,我會用連小學五年級都懂的話來告訴大家。
RTTI(Run-Time Type Information, or Run-Time Type Identification)
執行時期型態資訊(辨識),C++可以將基礎類別指向衍生類別,這通常發生在程式執行時,因此你並不知道這個基礎類別指向的物件型態是什麼,如此就必須在執行時期才可以做到取得物件資訊的,瞭解物件的資訊之後才能做正確的操作。那要怎麼做呢?

最簡單的方法就是使用
typeid和dynamic_cast
這裡先簡單說明一下dynamic_cast。

dynamic_cast是C++的動態型別轉換機制,簡單來說就是在執行時期安全的將指標(pointer)或是參考(reference)轉換到衍生類別。首先會確認轉換目標與來源是否屬同一個類別階層,當轉換的是指標時,成功時回傳記憶體位址,失敗則回傳NULL,如果轉換的是參考,失敗則會丟出一個bad_cast。
if (A * pA = dynamic_cast<A *>(pBase))
{
    //轉型成功
    pA->OK();
}
try
{
    A & rA = dynamic_cast<A &>(rBase);
    rA.OK();
}
catch(std::bad_cast)
{
    //轉型失敗
}
typeid就是產生指標或是參考所實際指向的物件的資訊結構
type_info
typeid表示式:
    typeid(exp);
exp的意思是類別的指標或是參考,或是其類別名稱。typeid傳回的是一個type_info的物件參考。
type_info:

class type_info {
public:
    virtual ~type_info();
    bool operator==(const type_info& rhs) const;
    bool operator!=(const type_info& rhs) const;
    int before(const type_info& rhs) const;
    const char* name() const;
    const char* raw_name() const;
};
你無法直接instance type_info這個類別,因為此類別只有一個私有的複製建構子,你也無法用assignment來建立,因為assignment operator也是私有的。你只能透過typeid這個function來建立。
==, !=運算子顧名思義就是判斷該type_info是否和其他的type_info相同。
name這個member function回傳一個人類可以看的懂的字串來顯示該指標指向之類別名稱。
raw_name說的就是一個原始的名字,也就是在記憶體裡存放的資料,這表示我們一般人是看不懂的(因該只有受過專業的訓練才看的懂吧)。但是它比name快,因為name就是把這些資料轉換成我們看的懂的文字。不過一般人是不會用raw_name的。
用法很簡單,請看下面。
if (typeid(pBase) == typeid(A))
{
    //pBase指向的是A
    A * pA = dynamic_cast<A *>(pBase);
    pA->OK();
}
if (typeid(pA) == typeid(pB))
{
    //兩個pointer是相同的class
}
cout << typeid(pA).name();
以上就是RTTI的基本知識,另外一點要提的就是
要使用RTTI,你必須inlcude <typeinfo>這個header file
在VC++的專案設定裡C/C++ --> Language --> Enable Run-Time Type Info設定為
Yes (/GR)
就先寫到這裡吧
下一回在跟大家更深入的談RTTI

(繼續閱讀...)
文章標籤

kgsprogrammer 發表在 痞客邦 留言(0) 人氣(722)

  • 個人分類:C++
▲top
  • 8月 03 週日 200823:06
  • 電玩音樂會 Video Games Live 即將登場!!


  
  VGL 2008 in Taipei 8/10、8/11 19:30 在板橋體育館,台北愛樂共演,門票熱賣中! 售票訊息、演出曲目請參考Video Games Live 台灣樂迷情報站
重要訊息:
。[情報]今日起將介紹VGL的廣播電台!
(繼續閱讀...)
文章標籤

kgsprogrammer 發表在 痞客邦 留言(3) 人氣(56)

  • 個人分類:閒聊八卦
▲top
  • 8月 02 週六 200815:45
  • inline function是做什麼的

inline function是C++程式碼在編譯時嵌入呼叫者所在之處的函數。就像巨集一樣,inline function免除了函數呼叫時的而外負擔,增加效率,並且可以讓編譯器對其最佳化(procedural integration)。與macro不同的地方是,inline function只會對所有引數求一次的值,避免某些當在寫macro所不易察覺的錯誤。次外,inline function還會檢測引數的型態,做必要的型別轉換。
注意:過度使用inline function會讓程式碼過於肥胖,於分頁(paging)環境下反而有負面的效能影響。
宣告
1.
    inline void function(int i, float f);
    
2.
    class C
    {
    public:
        inline void functionA(int i);
        void functionB(int i);
    };
    
    inline void functionB(int i) //實做函式時加上inline也是可以的
    {
    }
此外,在debug版本的編譯器是不會將inline function展開的,我想應該是為了能夠在除錯時trace程式碼。
在以下網址有談到很多關於inline function的知識,給大家參考
http://miloyip.seezone.net/?p=47
(繼續閱讀...)
文章標籤

kgsprogrammer 發表在 痞客邦 留言(0) 人氣(8,508)

  • 個人分類:C++
▲top
  • 7月 31 週四 200814:08
  • Refactoring to Patterns~Introduction

最近在書上看到的,關於設計過頭與設計不足的一些現象,給大家做參考
 

設計過頭:
學完了DesignPattern就一昧的想要使用
結果原本短短幾行或一個Function就可以解決的問題
卻使用了複雜的架構(當然是從DesignPattern學來的)來完成,白白多寫了幾十行,甚至幾百行的Code


設計不足:
最常見的就是設計完的架構裡面,含有雜亂的資料結構(或甚至沒有!)
每一個Class之間的變數或function都可以互相使用,沒有切割好溝通的Interface
造成取得各種資料的管道千奇百怪,沒有任何安全性
變數及function名稱本身無意義,且會讓人誤解!
Function內容冗長且缺乏邏輯,執行好幾個不相干的內容,且有大量重複的程式碼
最重要的是,程式碼難以閱讀,難以理解!


撰寫程式碼一定要注意的事情:
@移除重複的程式碼:將可重複利用的部分蒐集起來,寫成function
@簡化程式碼:一開始寫的時候一定會有雜亂的演算法或步驟

     但是只要仔細再看過一次,通常都可以找到更精簡的方式來撰寫
@讓程式碼的目的更明確:看不懂在做什麼的程式碼最令人頭痛

     除了Debug會讓人摸不著頭緒外,想要修改的人也會看的一頭霧水;
    另外變數與function的命名也很重要,之所以會有匈牙利命名法這類的東西

     就是為了讓人有更加習慣且統一的規則,增加程式碼的可讀性與理解
@不斷提醒自己要時常去做以上三件事情:程式寫久了難免會有忽略或是寫壞掉的地方

     定期去做檢查,或甚至是Refactory可以讓整個架構爛掉之前做些補救

(繼續閱讀...)
文章標籤

kgsprogrammer 發表在 痞客邦 留言(0) 人氣(48)

  • 個人分類:Refactory
▲top
  • 7月 31 週四 200813:52
  • 常用的除錯方式

1.當你發現有一個東西應該要啟動而沒啟動時,先去找看看當初的啟動條件,
  如果啟動條件是一個函式如IsEnable();則trace進去這個函式,一直追下去。
 2.善用OutputDebugString(),尤其是當你要對付一大堆的AI或事件。例如當你
  要找出某個莫名奇妙快速位移的AI時,就先用下列的方式print出來所有的AI
  位移量:
(繼續閱讀...)
文章標籤

kgsprogrammer 發表在 痞客邦 留言(1) 人氣(147)

  • 個人分類:程式設計
▲top
«1...56

自訂側欄

個人頭像

kgsprogrammer
暱稱:
kgsprogrammer
分類:
職場甘苦
好友:
累積中
地區:

近期文章

  • 輕鬆愜意,沁涼消暑----轉吧!流麵
  • Hook 4 Fun ---- 終極派對遊戲
  • Design Pattern -- Observer
  • Design Pattern -- Strategy
  • Template
  • Shaders for Game Programmers and Artists--Chap1_welcome to the world of shaders (閱讀心得)
  • 基本演算法分析
  • 『The Making of God of War III』讀後雜談
  • 求整數以2為底的Log運算
  • 很有台灣味的國產元創iPhone, iPod Touch遊戲----Sliding War

文章彙整

文章分類

toggle 程式研究 (6)
  • Design Pattern (2)
  • Refactory (8)
  • AI (2)
  • 3D圖學 (4)
  • 程式設計 (7)
  • C++ (8)
toggle 遊戲研究 (3)
  • 遊戲設計 (5)
  • 遊戲新聞 (7)
  • 遊戲開發 (4)
toggle 閒聊八卦 (1)
  • 閒聊八卦 (4)
toggle 後援會 (1)
  • 後援會公告 (1)
toggle 彼得哥的生平事蹟 (1)
  • 名言錦句篇 (1)
  • Game Develepment (2)
  • C++ (3)
  • 未分類文章 (1)

部落格文章搜尋

誰來我家

參觀人氣

  • 本日人氣:
  • 累積人氣: