2009年10月31日 星期六

rhino-debugger

目前我的網路遊戲是以 plt-scheme 寫成,有以下兩個原因使得 plt-scheme 難以被取代:
  1. 它的 at-exp 容易讓我描述遊戲的劇本。
  2. 它的 continuation based web server 使得我容易撰寫遊戲的流程。
但未來遊戲若要做成 GUI 的形式,我會期待用 javascript 完成。此時,我會選擇以下的工具:
  1. rhino, 以 JAVA 實現的 javascript interpreter。
  2. JAVA 的 Swing。因為它的無所不在,因為 Java Web Start。我不選擇 Eclipse 的 SWT,並不是有 JAVA 的地方就有 SWT。
 為未來做準備,我因此必須多瞭解一點 rhino,以及 JAVA。以下是我今日拜訪的連結:
Rhino + Javascript + Swing, Look Ma no Java ,很好,這樣短短的一篇,就給了我一個好開頭。

依據這篇文章,我寫了以下小小的 GUI 程式於 launch.js 中,以 rhino launch.js 成功地執行。

importPackage(Packages.javax.swing);
importPackage(Packages.javax.swing.border);
importPackage(Packages.java.awt.event);
importPackage(Packages.java.awt);
importPackage(Packages.java.util);

importClass(Packages.java.beans.EventHandler);

function runApp() {
        var lframe = new JFrame("MapaView");
        lframe.setSize(500, 400);
        lframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        var panel = new JPanel();
        panel.border = BorderFactory.createEmptyBorder(30, 30, 10, 30);
        panel.setLayout(new java.awt.GridLayout(0, 2, 10, 10));
        var exitButton = new JButton("Done");
        exitButton.addActionListener( function() {
                java.lang.System.exit(0);
        });

        panel.add(new JLabel("done yet?"));
        panel.add(exitButton);

        lframe.add(panel);
        lframe.pack();
        lframe.show();

}
runApp();

此外,我也瞭解了一下 rhino-debugger。rhino-debugger 這命令在 Debian Linux 下是一個 script 檔。閱讀後多多少少讓我知道要如何呼叫 Java。呼叫 Java?唉,是啊,我完全不懂 Java,我不屬於新生代的軟體工程師了。

2009年10月23日 星期五

Functional Programming

使用 PLT Scheme 撰寫遊戲至今,我完完全全體會到 functional programming 的表達力。在我的程式中,現在到處是 map 及 lambda。而且,setter 的使用也減少許多。
不過,我寫遊戲的方式是有點瞎子摸象方式的,沒什麼事先的設計規劃。完全是玩玩改改。目前這樣做的進展很快。但能持續到何時,可維護性如何,我還沒有把握。

2009年10月20日 星期二

Chat and Wiki for Scheme.

台灣很少有和 Scheme 這種語言有關的資訊。既然我目前使用 Scheme 做為我開發遊戲的語言,我就將這部落格做為我提供 Scheme 相關資訊的平台。

由於需要,我搜尋是否有以Scheme實現的 wiki ,發現了以下網頁。

http://practical-scheme.net/

在網頁中有個 WiLiKi 從開發的歷史來看,這 Wiki 從 2001 年到 2009 都有開發的活動。因此我粗淺地斷定這作者不會放棄這個 Wiki 軟體的開發,因此值得信賴。

在這網頁中還有個 chat room 的軟體,這也讓我頗感興趣。

2009年10月18日 星期日

Continuation Web Server works great!

將原本以 javascript 及 Helma NG 寫成的遊戲程式以 PLT Scheme 改寫,使用 PLT Scheme 的 Web server,我發覺 Scheme 的 continuation 真的是撰寫動態網頁的利器。使用 javascript 時,點選遊戲中某個容器的物件,必須將這物件的 id 變成網頁上連結的參數,這樣點選物件時才能將這 id 回傳給 server,server 才知道點選的是哪一個物件。這也使得網頁的設計和 model 密不可分。但是使用 continuation 時這件工作就省下來了。在網頁上的連結對應的就是處理那物件的 continuation。我在撰寫這部分程式時根本就很少關心網頁要傳什麼資料給 server 的問題。

Continuation 實在太神奇了!

2009年10月16日 星期五

Continuation or not continuation

在瞭解了 Continutaion 在 Web development 的應用後,我以為 continuation 只適用於部份的Web程式。這時,就不得不覺得 PLT Scheme 的文件中對不使用 continuation 的 Web development 方法討論太少了。

以下的文章反應了我的想法,也提供了另一種以 PLT Scheme 撰寫 Web applications 的 tutorial:

2009年10月15日 星期四

Model-View-Controller 及 Continuation II

重新思考 WEB 程式開發中使用 Continuation 和 Model-View-Controller 之間的關係。我決定回到物件導向設計的基礎,Robustness,不再勉強套用 MVC 這隻鞋子。為了 Robustness,Model/View/Controller 的區分還是有價值的。但是使用 Callback 及 Event-loop 實現 View 這個概念就不一定有價值。

Model-View-Controller 及 Continuation

PLT Scheme Web Server 是一種 Continuation based Web Server。HTTP 的 stateless 特性使得某類網路應用程式難以撰寫。而 Continuation 可以解決這類的問題。

但是初次接觸 Continuation based Web Server 的我對這種程式的寫法不無疑問。在當初以 javascript 及 Helma NG 撰寫我的遊戲軟體時,我採用的是 page oriented 的撰寫方式,這樣的撰寫方式很自然地和 Model-View-Controller 的理念對應。但是當我以 Continuation 來撰寫時,還摸索不出如何做到 Model-View-Controller 的方法。

以我游戲中的一個場景為例。這場景秀出一段文字,之後給玩家三個選項,玩家點了選項後會跑到另一個場景,因此網頁上和這選項對應的連結必須指出將要到哪一個場景。如果使用 Continuation,產生 html 的 function (View) 必須知道這連結要執行哪一個 function (Controller),以產生那個 function 的 continutaion。但這使得 View 必須知道 Controller。再者,如果那個被連結的 function 會使用到產生 html 的 function 的 local 資料或引數,則那被連結的 function 還必須在產生 html 的 function 的 local 中定義。結果 View 和 Controller 無法分開放在兩個不同的 modules。

在 GUI 還不盛行的時代,撰寫交談式程式的概念十分簡單,就是先印出問題等待使用者回答,使用者回答後再根據使用者的回答進行處理。GUI 的複雜度使得我們必須使用 MVC 這樣的概念。程式流程的控制權轉到了使用者的手裡。但至少 VIEW 和 Controller 都還在同一台電腦上,資料得以互通。到了網路時代,WEB 程式的撰寫更為困難,因為人機界面落在另一台電腦,在伺服端的程式並不知道使用者正在觀看哪一個畫面。當使用者下命令時,伺服端程式只能從 request 來猜出使用者的要求,沒有 continuation 的設計時,request 內只有這次要求的資料,看不出過去要求的歷史,無法處理複雜的,必須依據使用者過去瀏覽的歷史處理的運算。

這樣說來,如果 Continuation 能把事情簡化到最早期的程式撰寫方法,則 MVC 的概念並不是一定必要的。

2009年10月11日 星期日

Macro 的不可或缺

原本我的遊戲是以 javascript 寫成。在研讀過 PLT Scheme手冊後,我開始以 scheme 改寫我的遊戲軟體。 這樣做的原因主要是我欣賞 PLT scheme 中提供的 @-exp 語法。這語法類似 XML,適合用來描述遊戲的劇本,又和 scheme 完美整合。

將劇本以 @-exp 改寫後,我發現 macro 的重要性。以下是我劇本的一個片段:

@novel["家變"]{
  @room["書房"]{
    @scene["牆壁"]{
      你面對一面白色牆壁。牆壁上有條裂縫。向上直達天花板。
      @next["檢查裂縫" #:scene "裂縫"]
      @next["檢查天花板" #:scene "天花板"]
    }
    @scene["天花板"]
      天花板有點潮溼。
    }
    @scene["裂縫"]{
      裂縫中有隻螞蟻。
    }
  }
}

面對這樣的劇本,有兩種作法:
  1. novel 是 scheme function。此時,因為 room 會比 novel 早執行,因此,在執行 novel 前必須先建造一個名為 current-novel 的物件,或是使用一個 global 的物件,以存放 room 產生的資料。這使得劇本必須做小修改,而撰寫劇本的人,很可能不是一位程式設計師,必須操心這些小修改。
  2. novel 是 scheme macro。由於使用 macro,可以將建造 current-novel 的工作包括在 macro 的設計中,因此,撰寫劇本的人就不必操心這些問題。
我沒想到的是,單單劇本撰寫這樣原本以為簡單的工作,竟然也涉及到 macro 的撰寫,也因此體會了 macro 強大的能力。

在設計劇本的描述語言時,我也感受到 scheme 的 keyword 帶來的好處,以以上的劇本為例,在 next 中我使用了 #:scene 這個 keyword,它使得劇本更容易閱讀。

一個讓我驚訝的事是,我目前感受不到 PLT-Scheme 的 define-struct 的好處。原本我使用 (define-struct novel (name)) 來建立 novel 這結構,但最後我改成如同我原本使用 javascript 的作法,使用 hashtable,同時參考 SICP 的作法 來解決。