TAG

首都機能移轉 (2) 歌詞 (2) 靠北文 (40) 戲言 (30) 糟糕 (7) ACG (23) Assembly (2) Boost (2) C (31) C++ (69) CMake (4) CSIE (67) Debian (34) Design_Pattern (2) Django (1) Eclipse (1) en_US (13) FFmpeg (3) FoolproofProject (26) FreeBSD (2) Git (4) GNU_Linux (65) IDE (5) Java (11) JavaScript (19) KDE (15) Khopper (16) KomiX (3) Kubuntu (18) Life (1) Lighttpd (2) Mac_OS_X (2) Opera (1) PHP (2) PicKing (2) Programing (21) Prolog (1) Python (7) QSnapshot (2) Qt (30) Qt_Jambi (1) Regular_Expression (1) Shell_Script (7) Talk (98) VirtualBox (7) Visual_Studio (13) Windows (18) zh_TW (36)

2009年8月27日 星期四

Enable frame buffer in grub2

With legacy grub, if you want to enable frame buffer built in kernel, the option "vga=xxx" is needed in boot command.
However, grub2 provides a newer way to enable the feature. You should set gfxpayload=1280x1024x32, and insmod vbe manually if needed. So where to add? I write it to /etc/grub.d/40_custom, as it is an user custom hook script.
cat <<EOF
insmod vbe
set gfxpayload=1280x1024x32
EOF
You can use vbeinfo in grub2 shell to look up which modes are available.
By the way, DO NOT FORGET to run:
# update-grub
to make newer grub.cfg generated.

2009年8月20日 星期四

Overview of Observer Pattern

如果想要讓某物件在「發生某事」時通知另一個物件「做某事」,那麼我們會使用 Observer Pattern 來實現。簡單的做法是:
class Sender {
    +__new__() {
        this.listener = []
    }
    +somethingHappend() {
        this.listener.each( lambda( l ) {
            l.refresh( arguments )
        } )
    }
    +addListener( that ) {
        this.listener.append( that )
    }
    -trigger() {
        this.somethingHappend()
    }
}
class Receiver {
    +__new__() {
        sender = Sender()
        sender.addListener( this )
    }
    +refresh() {
        // blah blah
    }
}
當 Sender 的 somethingHappend 執行時,它會通知所有已被 addListener 加入的物件執行 refresh 動作。
這個做法很單純,但是不夠泛化,Sender 可能不只有一個事件,該事件也不一定只會呼叫 refresh。
class Observer {
    +connect( slot ) {
        this.listeners.append( slot )
    }
    +__call__() {
        this.listeners.each( lambda( args, l ) {
            l( args )
        }.bind( arguments ) )
    }
    -listeners = []
}
為此我們需要一個統一的介面來操作,class Observer 就此應運而生。
就 connect 而言,我們關心的是事件發出者是誰,它發生什麼事件,事件接收者是誰,它做了什麼事。
稍後我們會處理好事件發出者以及發生什麼事件的辨別方式,因此在這個 Observer 裡只儲存事件接收者和對應的處理函式。slot 即代表被註冊進來的處理函式,儲存起來以備以後使用。
__call__ 這個函式會在事件發生時被呼叫,它做的事很單純,就是呼叫每一個註冊起來的處理函式,並把自己接收到的參數傳給那些處理函式。
當然在這裡最麻煩的就是參數型態及個數,這裡端看各種語言的特性會有不同的實作。基本上動態語言都不會有什麼大問題,但那些靜態語言就需要一些特殊的手法。
使用時就像這樣:
class Sender() {
    +somethingHappend = Observer()
    -trigger() {
        this.somethingHappend( arguments )
    }
}
class Receiver() {
    +__new__() {
        sender = Sender()
        sender.somethingHappend.connect( this.refresh )
    }
    +refresh() {
        // blah blah
    }
}
可以看到 Sender 本身可以持有數個不同的 Observer,而且不同的 Sender 實體可以各自綁定不同的事件。當 Sender 的 trigger 發出事件通知,Receiver 相對應的處理函式就會被喚起。
這裡並沒有討論細節,比方說 mutex lock,解除監聽,還有 receiver 反查 sender 的機制。

2009年8月13日 星期四

Resolve the BADSIG problem when updating apt list

I recently encounter an update problem during updating sources list:
W: GPG error: SOURCE Release: The following signatures were invalid: BADSIG KEY SENDER
I have no idea how this happened, but have fixed this. First I tried this:
# apt-get clean
# cd /var/lib/apt
# mv lists lists.old
# mkdir -p lists/partial
# apt-get clean
# apt-get update
Well, but no use. So I tried another way:
# apt-get update -o Acquire::http::No-Cache=True
Then it works.

2009年8月2日 星期日

PicKing 0.1.0 released

下載 jar
原始碼
Licinse: LGPLv3 or later
System require: JRE 6.0
用來挑選能夠塞進指定大小的最多檔案或資料夾。我主要在大量備份時使用。
如上圖,左邊是檔案系統,中間是該資料夾底下的內容,選好之後點 start 就會開始作業,花的時間要看選擇的數量,50 個項目大約會花好幾秒;結果會顯示在右邊。
左下角是設定檔案大小上限,預設是 4483MB,也就是一片 DVD 的容量。
按 F5 可以重新整理檔案系統,比方說你可能多新增一個資料夾或插上新硬碟,可以用來更新。
Ctrl+S 可以儲存跑出來的結果。
備註:
十六個項目以內會使用暴力演算法,跑得出全域最佳解,但是時間和空間複雜度皆是O(2^N)。超過十六個項目則會使用基因演算法,會收斂在局部最佳解,不保證是全域最佳解,但是速度很快。因此有時會看到同樣的樣本空間跑出不同結果,乃是正常現象,如不滿意可以再跑一次。
本項目的原型是 PycKer,一個使用 PyQt4 的作品,作者當然也是我,不要告我抄襲自己去年的專案。
由於原本只是想強迫自己練習一下 Java,一開始(半個月前)是放在垃圾碼的沙箱裡,沒想到現在做成這個樣子。

2009年8月1日 星期六

C++ 的多緒安全性

簡單的說,因為標準給編譯器優化的限度太寬鬆,導致編譯器可以很大程度地調換指令的順序,因此 critical section 也有可能無法完全包好。不少人以為 volatile 可以禁止優化,從而確保正確順序,但其實它只保證單緒的順序,多緒的狀況還是無法保證;連鬼才 Andrei Alexandrescu 都在他的神作 Morden C++ Design 裡犯了這個錯誤(我也不認為他示範的 Singleton 真的有 thread-safe)。
也許等 C++0x(呃,可能會變成 C++1X) 釋出之後,可以帶給我們更複雜的 C++ 吧。XD

Demogorgon 還真的滿強的

剛剛心血來潮查了一下 Bordur's Gate II 裡 Demogorgon 的資料,發現還真是超出規格的強:
Level25
Class惡魔
Party叛逆邪惡
力量25
敏捷20
體質22
智力22
智慧22
魅力18
HP290
防禦等級-17
THAC0-19
攻擊次數5
抗魔90
物理10
100
100
50
特殊能力攻擊附疾病和等級吸取效果
特殊能力免疫盲目以外的不利狀態
特殊能力會不停地招喚惡魔助陣
特殊能力HP的回復速度很快
對沒什麼概念的朋友解釋一下好了。在 TOB 釋出的當時,傳奇的大法師伊爾明斯特的等級也才 29 ,25 級算是相當高的等級,一般傭兵隊有個七到八級就很強了,崔斯特也才十二到十四級。
六個屬性最大值是 25,普通人約在 10 左右,18 可以說是強者中的強者,也算是天生的極限,可是這傢伙竟然只有魅力是在 20 以下。
生命值 ... 290 大約比龍再強壯一點,人類大概超過 40 就算是打不死的小強了。
防禦等級在二版的算法是越低越好,什麼都沒穿就是 10,穿上最好的盔甲大約是 0,再加上魔法可以到負的,像 BG2 這種滿地貨的遊戲,正常玩法可以到 -14 左右,拿 BGS 可以到 -23,而這傢伙只有 -17 算是比較人性化的,還不到打不中的地步。
THAC0 是 -19 就太超過了。THAC0 的全名是 To Hit Armor Class 0,也就是如果你要打中一個 AC 為 0 的敵人,需要擲出多少才會命中,骰子是二十面骰,換句話說,THAC0 也是越低越好。-19 就代表只要你的 AC 沒有撐到 -19,只要他沒 BG 就一定打得中你。
一回合攻擊次數五次(最多也就五次) ... 就算是超強戰士,沒打針吃藥或是魔法加持是沒辦法做這種快速攻擊的。 抗性是 100 最高,代表百分百扺抗。對了,這傢伙我記憶中沒錯的話,魔法武器無效= =
等級吸取的意思是每命中一次就會降低等級,法術和能力都會因降低而消失,降到零角色就會死亡。
盲目以外免疫就代表他不會受到牽制,定身、石化、催眠、混亂、弱智等。
然後他召喚惡魔是不用施法的,反正就一直冒出來就對了。
最扯的來了,他似乎是半神還什麼的,所以時間停止對他無效orz,用了之後會發現靜止的世界裡只有他和你的人生是彩色的。噢,不對,因為他是彩色的,你當然就是黑白的。
而且他還會放一些十級法術,像是內爆術之類的(20d6)。
如果你問我是怎麼幹掉他的 ... 在他出現以前在他腳下放三顆尖刺陷阱(3*20d6),他一出現敵意就會瞬間被遺返回外層界 ...