摘要: 代碼如下:
Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->class lmmsStyle : public QPlastiqueStyle{public: lmm...
閱讀全文
終于把SmartGUi庫(kù)寫了一半,基本的架子算是搭起來了
現(xiàn)在我打算編寫博客邊做開發(fā)
雖然說之前也做過GUI,但是這次還是想把這個(gè)做好點(diǎn)(要是一不小心和CEGUI或者M(jìn)YGUI起名那就不錯(cuò)了哈哈)
先說GUI字體接口吧
需要說在的 這個(gè)庫(kù)的定位是與具體渲染機(jī)器無(wú)關(guān)
那么我們就需要一個(gè)與具體渲染有關(guān)的插件了
很顯然,對(duì)于GUI來說主要有3個(gè)部分
1.紋理/位圖
2.字體
3.基本圖元的繪制
當(dāng)然還有其他...
下面這是基本字體的抽象基類
CORE_BEGIN_NAMESPACE
class GUI_EXPORT GFont : public Object
{
public:
const static int LEFT = -1;
const static int TOP = -1;
const static int CENTER = 0;
const static int RIGHT = 1;
const static int BOTTOM = 1;
public:
virtual ~GFont();
virtual gstring GetFileName()const = 0;
virtual int GetFontSize() = 0;
virtual int GetLineHeight() const = 0;
virtual int GetWidth(const gstring& text) const = 0;
virtual int GetHitCharIndex(const gstring& text,float offset)const = 0;
virtual void Render(const gstring& text,const Recti& area,\
int halignment = CENTER,\
int valignment = CENTER,\
bool oneline = true) = 0;
DECLARE_OBJECT(GFont)
};
CORE_END_NAMESPACE
函數(shù)功能基本都看的懂
需要說明的是
1.GetHitCharIndex是本文給定偏移對(duì)于的字符標(biāo)號(hào)
2.這里并沒有提供一個(gè)渲染給定文本在給定位置的功能,反而提供了一個(gè)更為貼心的Render渲染文本于給定矩形-可以指定對(duì)其方式和是否為多行渲染
3.這里還沒有提供一些更為復(fù)雜的字體性質(zhì),比如斜體,下劃線,粗體等等
一個(gè)相關(guān)的字體工廠對(duì)象如下:
CORE_BEGIN_NAMESPACE
class GUI_EXPORT GFontFactory : public Object
{
public:
virtual ~GFontFactory();
virtual boost::shared_ptr<GFont> CreateFont(const gstring& font,int size) = 0;
DECLARE_OBJECT(GFontFactory)
};
CORE_END_NAMESPACE
這個(gè)沒什么說的,根據(jù)字體文件和字體大小生成字體指針一枚
還有一個(gè)相關(guān)對(duì)象是FontManager
接口如下:
CORE_BEGIN_NAMESPACE
class GUI_EXPORT GFontManager:
public Manager<boost::shared_ptr<GFont> >,
public GSerializer
{
public:
bool AddFont(const gstring& name,const gstring& font,int size,bool del = false);
gstring GetSerializerTag(){return "fontlist";}
bool Load(boost::shared_ptr<XMLNode> node);
bool Save(boost::shared_ptr<XMLDocument> doc,boost::shared_ptr<XMLNode>& node);
apiuse
void SetFontFactory(boost::shared_ptr<GFontFactory> factory);
private:
boost::shared_ptr<GFontFactory> factory;
DEFINE_SINGLETON(GFontManager)
};
CORE_END_NAMESPACE
1.顯然字體管理器是一個(gè)單件
2.函數(shù)SetFontFactory()是提供給插件設(shè)置具體的字體工廠的,所以這里有一個(gè)標(biāo)記apiuse
3.函數(shù)GetSerializerTag,Load,Save是從對(duì)那象GSerializer繼承來的,目的就是提供字體的序列化和反序列化動(dòng)作-我們的GUI是要盡可能做到自動(dòng)化的
在SmartGUI中,字體系統(tǒng)基本上就由這三個(gè)對(duì)象,以后樣子改動(dòng)不會(huì)太大了,也許只會(huì)增加函數(shù)接口而已
另外這個(gè)字體系統(tǒng)從設(shè)計(jì)模式的角度看是很容易理解的
----------------------------------------------------------標(biāo)記
接口總比實(shí)現(xiàn)重要些.
源于lmms
代碼如下:
#include <QtCore/QSemaphore>
template<typename T>
class fifoBuffer
{
public:
fifoBuffer( int _size ) :
m_reader_sem( _size ),
m_writer_sem( _size ),
m_reader_index( 0 ),
m_writer_index( 0 ),
m_size( _size )
{
m_buffer = new T[_size];
m_reader_sem.acquire( _size );
}
~fifoBuffer()
{
delete[] m_buffer;
m_reader_sem.release( m_size );
}
void write( T _element )
{
m_writer_sem.acquire();
m_buffer[m_writer_index++] = _element;
m_writer_index %= m_size;
m_reader_sem.release();
}
T read()
{
m_reader_sem.acquire();
T element = m_buffer[m_reader_index++];
m_reader_index %= m_size;
m_writer_sem.release();
return( element );
}
bool available()
{
return( m_reader_sem.available() );
}
private:
QSemaphore m_reader_sem;
QSemaphore m_writer_sem;
int m_reader_index;
int m_writer_index;
int m_size;
T * m_buffer;
} ;
先解釋下啥是SmartGUI?
SmartGUI是我打算做,也做了一周多的一個(gè)Game GUI LIB
其基本的特點(diǎn)包括,但不限于以下幾項(xiàng)
1.跨平臺(tái)
2.支持DX,GL
以上2項(xiàng)似乎不大能引起別人的注意
3.全腳本化支持
載入配置即可自動(dòng)生成控件,外觀并顯示出來
你所要做的只是設(shè)置必要的邏輯關(guān)系即可(至少現(xiàn)在我還沒有合適的方案來支持腳本配置UI邏輯關(guān)系,不過未來未必)
這點(diǎn)貌似比較吸引人吧
不過還有一點(diǎn)
4.開源
這將是我第一個(gè)開源項(xiàng)目,在動(dòng)手之前我吸收了大量android,QT編程的養(yǎng)分
SmartGUI最大的特點(diǎn)只要2個(gè)
1為易用
2為界面配置協(xié)調(diào)
--------------------------------------------------------------------
當(dāng)然性能不會(huì)差到哪里去
附注:幾天前才開始,爭(zhēng)取端午截止前放上第一份源碼
各位同學(xué)給一個(gè)好的開源站點(diǎn)吧
Android中的ListActivity涉及2類點(diǎn)擊事件
1個(gè)是短按點(diǎn)擊
1個(gè)是長(zhǎng)按點(diǎn)擊
對(duì)于短按點(diǎn)擊
只需要重載下面的函數(shù)即可
void onListItemClick(ListView arg0, View arg1, int pos, long id)對(duì)于長(zhǎng)按
則需要繼承接口OnItemLongClickListener并實(shí)現(xiàn)
getListView().setOnItemLongClickListener(new OnItemLongCLickListener(){
public boolean onItemLongClick(AdapterView parent, View view, int position,
long id)
{
return true;
}
}); 其方法即可
Echo是聲音的反射,是指人直接聽到聲音之后,其反射音又被聽到。
一個(gè)真正意義上的Echo是單反射的。其時(shí)間間隔就是聲音的速率
很顯然一般的Echo具有2個(gè)參數(shù)
一個(gè)是延遲,一個(gè)是衰減
在某一時(shí)刻,人聽到的聲音是此時(shí)音源聲音和延遲前音源聲音的混合音。
顯然一個(gè)簡(jiǎn)單的表達(dá)式是:
data+=data_prev*decay
這就是Echo音效基本的函數(shù)表達(dá)式
這是第四篇關(guān)于音效處理的文檔
其他類似音效不打算再寫了
需要說的就是 實(shí)際編程并沒有想象中的那么復(fù)雜!
在音頻這塊喔已經(jīng)做完了
1.acc格式編解碼
2.wma編解碼
3.fadein,fadeout,echo,reverb等音效算法
4.音頻頻譜分析
5.EQ設(shè)置
有空整理下哈
這是音效系列編程之三:FadeOut和FadeIn音效
二者都分別控制音樂的淡出和淡入
解釋下淡出效果的含義:就在是音樂播放即將結(jié)束之前通過一定的手法控制音樂響度-直至結(jié)束。
很顯然,使用線性關(guān)系基本可以達(dá)到目的
假定數(shù)據(jù)關(guān)系為y = kx + b;
另外需要控制淡出的坡度,或者直接說需要知道從結(jié)束之前多少個(gè)數(shù)據(jù)開始需要使用FadeOut音效。所以我們需要一個(gè)參數(shù)len。
假定我們使用下列的一句話算法來說明問題:
for(int i = 0; i != len ;i++)
bufer[i]*= (a-i)*b;
其中a,b為待定參數(shù)
因?yàn)橛幸粋€(gè)前提:當(dāng)i = len-1的時(shí)候buffer[len-1] = 0;
所以有a=len-1
另外當(dāng)fadeout發(fā)揮作用之前buffer數(shù)據(jù)并未變化,故有
b=(len-1)
故基本的Fadeout核心算法就是一句:
y=y*(1-t/k)
簡(jiǎn)單吧。
理所當(dāng)然
基本的FadeIn核心算法就是
y*=(t/k-1)
雖然在具體場(chǎng)合,算法有所變形,但是基本的原理就是這個(gè)樣子
PS:基本的函數(shù)關(guān)系雖然簡(jiǎn)單,但是比較實(shí)用
以后有空還會(huì)講Echo,Reverb,Treble Booster,Compressor,High Filter等音效原理
。只是研究音效的同志們不多。沒的討論
啥是門面模式?
按照我的理解就是:給一系列子對(duì)象或者系統(tǒng)提高一個(gè)統(tǒng)一的接口
在使用過程中該接口把客戶端發(fā)送來的要求傳遞到各個(gè)可能的子系統(tǒng)中去。
一句話:門面模式是為了簡(jiǎn)化客戶端操作而產(chǎn)生的
一個(gè)簡(jiǎn)單的例子是:
之前我要看電視,只需要打開電視機(jī)即可
但是現(xiàn)在有了機(jī)頂盒這個(gè)東西,要看電視需要2個(gè)步驟:打開電視機(jī),打開機(jī)頂盒,反而繁瑣了。
做個(gè)夢(mèng),如果一天我想看電視我只要說一句-我要看電視,然后自動(dòng)打開電視機(jī)和機(jī)頂盒。那該多好。
可以看出,在實(shí)際開發(fā)過程中,對(duì)于那些沒有學(xué)過設(shè)計(jì)模式滴淫,他們也可能使用過該模式,只不過不知道名字罷了
門面模式的一個(gè)例子:
很簡(jiǎn)單滴:
class A;
class B;
class C;
class Op
{
A* a;
B* b;
C* c;
void Call()
{
a->Call();
b->Call();
c->Call();
}
}
注意這里A,B,C不具有共同基類
不管什么模式,都是為了應(yīng)用服務(wù)的,如果但是將復(fù)雜化,高深化,那是不可取的。想想當(dāng)時(shí)買了設(shè)計(jì)模式一書,看的稀里糊涂的。
PS:門面模式=簡(jiǎn)化客戶端操作(統(tǒng)一包裝)
本文給出當(dāng)前我使用過的Android 調(diào)試橋方法
要使用調(diào)試橋首先需要 切換目錄到Android SDK下的tools目錄或者設(shè)置下路徑
常見的使用方法如下:
1.把本地apk文件推入真機(jī)
adb push name.apk system/app
2.卸載真機(jī)apk程序
adb uninstall packagename
比如
adb uninstall cm.android.game
3.如果adb push 失敗
則需要執(zhí)行
adb remount
4.如果執(zhí)行
adb uninstall .
失敗
則可以嘗試
adb shell
切換到app目錄 cd system/app
執(zhí)行l(wèi)s查看當(dāng)前所有應(yīng)用列表
然后使用rm 名字移除apk包
比如rm game.apk
不過這樣做有一個(gè)壞處就是
只是簡(jiǎn)單刪除了應(yīng)用程序并沒有刪除程序數(shù)據(jù)
嗯 GUI庫(kù)應(yīng)該分為幾個(gè)大的模塊呢? :)我想
這次的GUI庫(kù)我會(huì)采用類似GUICHAN的方式,具體的GUI并不依賴于特定的圖形接口,而是采取插件的方式動(dòng)態(tài)加載,這樣有助于提高其使用的廣度
應(yīng)該包含一個(gè)GUIRender
另外GUI庫(kù)涉及面比較廣,需要有大量附加的數(shù)據(jù)結(jié)構(gòu)比如XML,圖形處理,向量,插件,基本對(duì)象,日志等。我們應(yīng)該再加一個(gè)輔助庫(kù)
于是有一個(gè)叫做Util的東西
其次我們主要的GUI庫(kù)類
這個(gè)是核心
我暫時(shí)給他起個(gè)名字叫coregui吧
這個(gè)是這個(gè)GUi的核心
其功能除了一般的GUI控件對(duì)象之后還應(yīng)該有控件工廠,控件池(管理器),控件數(shù)據(jù)串行化,控件布局,控件編輯,控件動(dòng)態(tài)加載,腳本處理等功能(想想功能還比較多-不過總比之前做的游戲引擎量要小很多)
分塊就這么幾個(gè)了
在開發(fā)過程中,我會(huì)一個(gè)一個(gè)GUI對(duì)象都貼上來,然后說明為什么要這樣做,并附上可能對(duì)應(yīng)的設(shè)計(jì)模式(要活學(xué)活用(⊙v⊙)?)
PS:其實(shí)一個(gè)比較好的辦法是借助于UML,可是我現(xiàn)在忘了這幾個(gè)字母如何寫,有空學(xué)學(xué)吧