为WebWorker设置正确的路径

WebWorker的路径通常是写在代码源文件中,而且这个路径并非其相对父js文件的相对路径,而似乎是相对页面的路径。所以指定一个正确的可随处部署的路径变得有些麻烦。昨天有人给HeatCanvas提了这个问题我才想到上网搜索了一下,有一个还算挺不错的办法。

写一个getPath函数,从document里找到父js的路径,拼到Worker的名字上。对heatcanvas.js这个文件来说就是:

HeatCanvas.getPath = function() {
    var scriptTags = document.getElementsByTagName("script");
    for (var i=0; i<scriptTags.length; i++) {
        var src = scriptTags[i].src;
        var pos = src.indexOf("heatcanvas.js");
        if (pos > 0) {
            return src.substring(0, pos);
        }
    }
    return "";
};

因此现在HeatCanvas已经解决了这个路径问题,现在这个库应该更好用了。当然如果你改了我的文件名我就无话可说了。

My favorite feature in leiningen 2

Recently, the leiningen team has released a preview version for leiningen 2. It brings new features to the clojure build tool. But my favorite one is not listed in any document. So I would like to share with you here.

As you know, leiningen is a project oriented tool. It manages dependencies for a particular project. In Java world, Maven and Gradle are also working in this manner.

In contrast, there are tools which manages dependencies in a system scope. For instance, pip(python), npm(nodejs) and gems(ruby). One advantage of these tools is easy for evaluating a library. Concretely, when you want to test pyclj, just run “pip install pyclj” to install it. Then open a REPL and type “import pyclj”. That’s pretty easy.

But in clojure/leiningen, to take a tutorial of “core.logic”, we have following steps:

  1. Find a right directory and type “lein new logic-abc” to create a project.
  2. cd into it, edit project.clj, add core.logic as a dependency
  3. Run `lein deps`
  4. Start a REPL and follow the tutorial

So I guest you must have a lot of empty projects created for such purpose.

Now we could say goodbye to this situation. Leiningen 2 has move its dependency management core to a new library, called pomegranate. Pomegranate wraps aether, which is a maven library created by sonatype. With pomegranate, we can add a maven artifact from repository to REPL classpath. Still on the core.logic example, it becomes much easier:

$ lein2 repl
Welcome to REPL-y!
Clojure 1.3.0
    Exit: Control+D or (exit) or (quit)
Commands: (help)
    Docs: (doc function-name-here)
          (find-doc "part-of-name-here")
  Source: (source function-name-here)
          (sourcery function-name-here)
 Javadoc: (javadoc java-object-or-class-here)
Examples from clojuredocs.org:
          (clojuredocs name-here)
          (clojuredocs "ns-here" "name-here")
nil
user=> (use '[cemerick.pomegranate :only (add-dependencies)])
nil
user=> (add-dependencies :coordinates '[[org.clojure/core.logic "0.6.8"]])
{[org.clojure/clojure "1.3.0"] nil, [org.clojure/core.logic "0.6.8"] #{[org.clojure/clojure "1.3.0"]}}
user=> (use  '[clojure.core.logic])
nilWARNING: == already refers to: #'clojure.core/== in namespace: user, being replaced by: #'clojure.core.logic/==
user=> (run* [q] (== q 1))
(1)

Now core.logic is right on you classpath and you are ready to use any functions under the namespace. There’s no need to create project, no need to care about where the jars stored. Just start a REPL at anywhere you want. When you finished, send EOF to the REPL. Nothing to clean up.

My jython dependency manager jip has similar feature as I described above. It does great help to me. So I have been waiting for this feature in leiningen for a long time. Thanks to leiningen guys, it finally comes.

Edit 20120323 21:39

If you want to load libraries from clojars, you should explicitly add clojars in add-dependencies:

(add-dependencies :coordinates '[[incanter "1.2.3"]]
                  :repositories (merge cemerick.pomegranate.aether/maven-central
                                       {"clojars" "http://clojars.org/repo"}))

(The example is copied from Pomegranate document.)

刷HTC EVO 3D GSM

去年买的水货Desire Z在服役了刚刚一年之后就坏了,看来肯定是上了奸商的当。鉴于最近的新手机也没有什么像当时Desire Z那样一见倾心的,这次保守起见买了个行货EVO 3D。买行货的问题不仅是贵(贵很多),而且默认的ROM实在是没法用。几大国产流氓软件堂而皇之地强制安装后台运行,系统连google账户,官方market都没有。

那么只能刷一下了。所有的步骤开始之前都是解锁,按照官方的解锁方式(http://www.htcdev.com)基本上没有什么难度。在我的archlinux上,不需要安装HTC Sync(也没得装),只需要从aur安装android-sdk和android-sdk-platform-tools就有adb和fastboot在PATH里。唯一值得一提的是,在我的系统上fastboot oem get_identifier_token需要sudo,否则会一直wait device。除了这个小插曲以外,按照官方的步骤就可以解锁HBOOT。

接下来就可以刷recovery了,HTC EVO 3D GSM版的codename叫做shootru,比较可靠的一个版本是4.0.1.4-shooteru,可以在网上搜索 cwm-4.0.1.4-shooteru.img 这个文件,比较好找。继续通过 sudo fastboot flash recovery cwm-4.0.1.4-shooteru.img把recovery刷进手机。

接下来就是ROM的选择了。最好的选择是cyanogenmod,EVO 3D分为GSM和CDMA版,cmod 7只支持CDMA版,似乎还没有稳定的正式版。对GSM似乎有正在开发7.2,不过按照他们的说法,自从4.0发布之后,所有人的注意力都转移到基于4.0的cmod9上,所以7.2这个版本希望也比较渺茫。9.0已经有开发版本,但是都有一些还未解决的严重bug。说了这么多就是说我暂时放弃cmod了。

除了cmod,EVO 3D GSM上一个比较被认可的ROM叫做LeeDrOiD.从网站上下载5.3.0的发布版,拷贝到sd卡上,通过recovery就可以安装。安装之前先要清除旧的数据。剩下这一步也没有什么悬念。但是安装之后5.3.0上,WIFI无法启动。必须继续更新kernel,从网站上下载。安装kernel的方法和之前不太一样,不能通过recovery安装。需要用一个叫做FlashImageGUI的工具,可以在网上直接搜索这个名字找到下载。剩下就很简单了。

折腾这么一圈,手机基本上能用了。不过我还是非常期待早日能用上cmod 9.

Kliment Voroshilov tank 2

业余时间,我除了写括号以外,也会做点模型,不过是入门水平。用淘宝店家的话说,你随便涂涂就行了。这个KV-2坦克是去年秋天买的,后来周末学车加上天冷坐不住就搁置下来。现在稍微暖和一点,就赶紧把开工。

KV-2坦克,是二战时期苏联的重型坦克。最早参加了苏芬战争,后来投入到早期的苏德战争。但是绝大多数被德军在巴巴罗萨行动中摧毁、俘虏。被俘虏的KV-2坦克被刷上德军的标志也为德军服役,这在二战早期的东线战场倒是很常见。我的这个KV-2附带的水贴纸也分两个版本,分别是苏军和德军的涂装。

花了一天时间素组。
DSC_0016

DSC_0013

DSC_0023

DSC_0019

DSC_0029

今天又花了一上午时间上漆。第一次上漆,也没看什么教程,就是这个结果了。

DSC_0003

DSC_0009

DSC_0015

下一个目标就是T34。

What’s new in slacker 0.7.0 ?

I just released [slacker "0.7.0"] to clojars. This is the first release after my presentation on the Clojure China Meetup. lbt05 contributed an ACL module to slacker, which is the most significant feature in this release.

The ACL module provides a simple DSL to define access rules.

(use 'slacker.acl)
(use 'slacker.server)

(defrules myrule
  (allow ["10.60.15.*"]))

(start-slacker-server ...
                      :acl myrule)

“myrule” defines a limited access control list. Only clients from IP segment 10.60.15.* could access the slacker service.

And there are also minor enhancements in this release:

  • Content compression, new content type :deflate-carb :deflate-json and :deflate-clj
  • In debug mode, server side stacktraces are printed on client
  • Zookeeper node path refined
  • New options in use-remote, :o nly and :exclude
  • Cheshire used as json library

slacker 0.7.0 will be the last version on clojure 1.2 . As aleph 0.2.1 is coming near, we will migrate to clojure 1.3 as soon as possible. If you like to taste slacker on your 1.3 application now, there is a 0.7.1-SNAPSHOT available.