2009年2月23日 星期一

用C/C++加入/退出Multicast Group的方法

在VLC裡面找這部份,看了wikipedia就往IGMP的方向找,結果證實是浪費時間... orz

總而言之,參考這裡。簡單的講,加入Multicast Group是用setsockopt()搭配IP_ADD_MEMBERSHIP這個參數。範例請參考上述網頁。離開則是IP_DROP_MEMBERSHIP

其他還有IP_MULTICAST_IF, IP_MULTICAST_TTL, IP_MULTICAST_LOOP等。不過因為我只是要找出VLC哪部份在弄Multicast,所以就沒去詳細嘗試這些的功用是什麼了。

Blog顯示程式碼

貼了程式碼才發現上次改網誌主題,所以之前編的CSS跑掉了....
用"blog 程式碼"之類的關鍵字去找結果找到一堆沒處理好縮排的,
千辛萬苦才找回以前參考用的這個

現在的做法是,在CSS裡面加下面這段:
pre.code  {
display: block;
font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace;
color: #000000;
background-color: #eee;
font-size: 12px;
border: 1px dashed #999999;
line-height: 14px;
padding: 5px;
overflow: auto;
width: 100%
}

然後程式碼就前面加上<pre class=code><code>
後面加上
</pre></code>這樣。

C語言: 讀出";"結尾的字串

while( sscanf(pStr, "%[^;]", scan)==1 )
{
pStr += strlen(scan);
while(*pStr == ';')
pStr++;
printf("%s\n", scan);
}

sscanf(..., "%[^;]", ....)這個用法其實很多地方有寫是有寫,
可是寫的很隱密....。

從一件小事看iPod nano的歌曲星等實作機制

我平常在外聽音樂用的是iPod nano。用了四年以上的古董了。
(不過小小一台很方便,雖然偶爾有點秀抖,電池也開始衰退了)

平常聽歌都是編輯一個「某某歌手多少星等以上」的Smart playlist,
不過這樣就得歌曲要給星等。最近新增還沒給星等的歌曲又有點多,
就想說先來排序(用自己寫的簡單javascript),然後看哪個區間要給星等。

所以排序完。把原本有給星等的歌通通取消星等。
依照排序的結果一個一個給分。嗯,這邊五分....這裡開始四分....以下略。

今天早上要聽歌的時候打開同樣的Smart playlist發現,
咦,歌曲的列表怎麼是照我給分的順序?
##ReadMore##

理論上如果歌曲是以資料庫的方式,每首歌給一個row來存的話是不太可能會這樣的。
給五星就是五星,五星的歌曲間不會有任何區分,先給後給都一樣。
資料庫本身不會記憶被給星等的時間。

我最後的結論是,他們星等是另外維持一個列表,
表上列出哪些歌是五星,哪些歌是四星,依此類推。
由於這樣你把歌曲給星等時,不是像資料庫一樣分數被「改」動而是被「加」上去的,
所以會有加上去的先後順序。會依照加上去的順序列出歌曲。

至於為什麼會這樣我就不知道了。
也許因為給星等的歌通常不多,避免佔據空間?(可是一首挺多1Byte耶)
也許這樣比較快?或者只是因為這是四年多前的iPod了,現在已經改掉了。

不過這樣的排序方式對我來說也方便就是了 :p

2009年2月22日 星期日

Mysql的Truncate與Lock

只是小小附註。lock tables跟truncate table不能一起用...。
當你lock某個table,你就不能truncate他。

某些狀況下這有點麻煩....

2009年2月19日 星期四

PHP的小小抽象滲漏

關於什麼是抽象滲漏請看這裡

1.Firefox的自動reload


在未指定字碼而且實際字碼與Firefox的預設不同時,
Firefox會先讀入一次,判斷目前所使用的字碼不對,
然後再跟Server要一次資料。所以PHP之類的CGI會被執行兩次。
所以,網頁請寫好Content-Type的header。
(什麼,你說這不是理所當然的嗎?
嗯,的確是,不過我現在程式還在寫內部部分還沒要處理UI,
這部份隨便寫寫結果就中招了。)

順帶一提IE不會這樣。他會直接用亂碼印出來。


2.empty的抽象滲漏


##ReadMore##
PHP的empty()只能拿來判斷變數。
如果你拿它來判斷函數回傳,他會給你一個錯誤訊息。
到這邊都很正常。

不過PHP 5.x開始多了個類別的method,叫__set跟__get。
__get的功用是他會在找不到member時以這個method去找資料。
比如說如果變數實際上沒有$t->num,他就會去呼叫$t->__get('num')。

實際上來說,這兩個就只是語法上的甜頭就是了,
因為一般使用上可以自己寫兩個函式,比如說Set()跟Get()來做同樣事,效果一樣。
好處只是,你可以寫$t->num++而不是$t->Set('num', $t->Get('num')+1)。

問題出在於,當你empty($t->num)時。
假設$t->str會回傳字串,而你想要判斷這是不是個空字串,
他不會照你預期的回傳,也不會有錯誤訊息。
就算字串有東西,他會照樣回傳true。
而你就字面上看,empty($t->str)怎麼看都沒有問題。

順帶一提strcmp($t->str, "")===0也一樣會出錯。
我最後成功時是使用strlen($t->str)===0。

供參考。

2009年2月17日 星期二

iGoogle與Gadget

又是一個暫時不會用到的東西....

總而言之研究了一下Gadget。就iGoogle上那堆小工具。
大致上的結論是:
  1. 是XML、HTML跟JavaScript混成。另外有gadget特有的API。
  2. 起頭教學
  3. 原始檔要自己找Server存。沒有的話,上面頁面提供的Google Gadgets Editor可以讓你存在Google的空間。
  4. 可以加點developer tool來協助開發。雖然實際上裡面有用的只有一個,可以拿來看別人的Gadget的程式碼
  5. 完整API列表在
看起來這現在跟OpenSocial API整合了...。暫時不關我事就是了。
(除非哪天mixi、plurk或pixiv提供足夠的支援)

網頁的檔案上傳(以及php的處理與驗證)

因為這樣跟那樣所以去查了。暫時用不著,先記起來。

這裡的範例一有HTML的示範,範例二則是PHP的部份。
檢查$_FILES['userfile']['type']可以確認副檔名,
不過僅只是副檔名,沒有分析檔案內容,所以參考就好。
順帶一提,照範例程式的話,重複上傳同名檔案後面會蓋到前面的。

分析檔案內容的話,好像有個mime_content_type
不過官網不建議。建議使用的Fileinfo則是要PHP5.3.0版。
在更早的版本是算PECL的一部分的樣子。

2009年2月16日 星期一

Web Game: 該lock全部或是部份的table

*以下是個人寫Web Game中途產生的心得。
很有可能不適用於其他類型的應用程式,請注意。

話說從頭


包括Web Game在內的多人網路遊戲都需要對資料庫或檔案進行鎖定(lock)。
鎖定的目的我原本寫了個範例出來,不過這樣這篇文章會太長所以算了吧。
抽象一點的舉例,就像是在白板上留言,要一個人寫完才能輪別人,否則留言就會看不懂。
多人遊戲時大家也得排隊輪著讀寫資料庫(雖然這動作時間很短所以看起來像大家同時)。

今天要講的是,一次該鎖定多少?

##ReadMore##

資料庫通常會起碼提供你一次最低可鎖定到一個table。
假設現在有三個table分別代表角色(char),地區(area)跟組隊(team)。
你可以鎖定它們其中之一,其中兩個或全部。

直覺的想法是,需要幾個就鎖定幾個。
如果自己暫時不會用到,就給別人用啊。
假設A鎖定了char跟area,B鎖定了team。
A跟B就可以同時動作而不會互斥。
效率比雙方都一次全部鎖定,B要等A做完要來的好。

理論上如此,而且其他應用程式很可能是對的,但遊戲不是。

因為沒有漸進式鎖定


首先原因是,我不確定其他資料庫,不過Mysql的lock是一次性的。
你不能先lock char,然後跟資料庫講我要多lock area。
這樣做會把char解鎖才去鎖定area,而不是你所想的鎖定了兩個table。

事實上這是很合理的,想一想下面這個情況:
A鎖定了char跟area而B鎖定了team。
A想要多鎖定team,B想要多鎖定char。
要不就雙方都拿不到(因為在對方那邊,而且對方不會放手),
要不就資料庫提供更複雜的機制解決這問題。

所以你不能漸進式鎖定。你在發出lock指令時就得指定好所有的table。

可是寫遊戲,通常資料庫存取動作並沒有那麼單純。
要在開頭就完全確定這裡只會用到某些table是很困難的。
有可能今天你要加某個功能,所以這個角色動作就得多使用到一個table。

更糟一點的狀況是,那個功能隱藏在好幾層函式呼叫的下面。
你得一層一層爬上去,找到到底誰呼叫了那個函式。
如果你每次做這個動作就得往上爬個四層尋找會呼叫它的一百個地方,
改個幾次你大概就投降了。

效率問題?


更重要的一點是,全部一次鎖定其實也沒什麼效率問題。

這邊的重點是,這是遊戲,而且還是Web Game。
遊戲的重點是玩家的角色。Web Game的動作則都是由玩家觸發的。
也就是說,90%以上的鎖定都一定會包括角色(char)的table
既然大家都要用到同一個table,那部份鎖定跟全部鎖定是一樣的
-不管怎樣都要排隊。

而且一次全部鎖定,也可以讓你不用去思索什麼時候該開始鎖定-
每個指令執行期間全部鎖起來就對了。
不用去看哪些動作有用到資料庫哪些沒有,省掉coding時考慮這些的麻煩,
可以更直接而輕鬆的使用資料庫。

所以我的建議是,如果你是要寫遊戲的話,就全部鎖定吧。
coding會方便很多,又不會真的犧牲多少效率。