Sunday, May 20, 2012

Epicurean


其實我對很多美食主義者有意見。或者說,自稱是美食主義者的人有意見。

我尤其難以理解為什麼某些自稱美食主義者的會說「因為吃過了XXX店的OOO,所以其他的OOO我再也難以下嚥了」,這種跟許多壓根不懂咖啡的人硬說「市面上大多數咖啡簡直是黑苦的液體,根本不能喝」在自稱是咖啡鑑賞大師的人一樣等級。

先不談這些老兄大姐到底懂不懂咖啡,舌頭夠不夠天賦靈敏。事實上,假設真的是一個好的美食主義者,擁有如此有天賦的味蕾,那為什麼僅能嚐得出別人的缺點,卻無法分辨出它口中「不入流的貨色」有哪些特點,有哪些是別人沒有的味道呢?我不否認,你要我說屎有什麼別人沒有的香氣,我真的說不出口,不過要是有人覺得世界上如此多的廚坊(請注意,還沒夠格到稱為廚房),都只能作出這些人口中的屎,只有最高級的米其林餐廳做出來的鵝肝醬,這些人才能描述他有多香氣澎湃多美味...

我覺得這些人還是不要自稱美食家比較好,這種人我一般稱之為滿口屎味。

咖啡也是。我曾經喝過初學者手沖出過熱焦氣滿口的單品,也喝過真正的高手火候十足,賽風下水剛剛好時間的醇品。每滴咖啡,都有一定的特殊香氣,都有其他人做不出來的神奇口感。

噢我還不敢自稱咖啡達人,只是味覺靈敏了點。

Epicurean還有一個意思,就是享樂主義者。有篇很有趣的文章,我曾經分享給大家過。看看,是不是跟美食主義果然是該共用同一個單字呢? :)

同學,你其實可以不用周遊世界

可以不用去追求別人描述的所有人性解脫,再回來說台北空氣多汙濁,生活多繁忙,多世俗。當連路邊小店的特殊風味都沒辦法品味,當連附近的小山小水都沒有仔細觀察,那,你有什麼自信那麼可以自稱一個Epicurean? 還是只是一種自以為Epicurean的自High以及自以為的超脫感?

Tuesday, May 15, 2012

Roxette - She doesn't live here anymore

http://www.youtube.com/watch?v=LNcEQOVumYA


She Doesn't Live Here Anymore

Lyrics:Per Gessle Music:Per Gessle&Mats M.P.Persson

We grew up together, we've been here forever.
Barefoot in the summer, cold in stormy weather.
She taught me all there is, like magic and love,
lots of forgotten words.

But now, she doesn't live here anymore.
She's off and she's gone, she doesn't live here anymore.
I'm sorry that's all there is to it,
I'm sorry that's all.

She dressed just like a painter,
a female street Picasso and I,
I will remember the heaven in her laughter.

And the scent of her sweet perfume
when we made love under an August moon

But now, she doesn't live here anymore.
She's off and she's gone, she doesn't live here anymore.
I'm sorry that's all there is to it,
I'm sorry that's all.

But now, she doesn't live here anymore.
She's off and she's gone, she doesn't live here anymore
She's gone since long, so long, she doesn't live here anymore.
She took off and left home, she doesn't live here anymore.
I'm sorry that's all there is to it, I'm sorry that's all.
That's all.









我們曾經在一起成長,我們曾經決定永遠在這裡

夏天赤腳踩在沙灘上,冬天擁抱在暴風雪中

她教會了我一切,如魔幻般的愛情,無法用言語表達的感覺
但是,她再也不在這裡了
她就這樣像是消失在大氣一班,再也不在這裡了
我覺得很抱歉,真的,我非常的遺憾

她曾經穿得像個油漆工,跟我像是街頭藝人般的手拉著手
我永遠會記得她有如天堂般的笑容
我似乎想起了她熟悉的香氣 想起了我們在八月的滿月下纏綿

但是,她再也不在這裡了
她就如同大氣一樣的消失了,再也不存在於這裡
我感到很抱歉,我真的很遺憾。

她再也不在這裡了
她如同熄滅的燭火一樣消失在這裡
她已經好久,好久,再也沒有回到這裡
她就這樣捲起了衣衫,如同出遠門一樣,離開了這裡
我對她很抱歉,我很遺憾,就這樣吧。

Thursday, March 15, 2012

Java socket程式 -- 絕對避免println() / PrintStream!

我先簡要的說一下原因,internet protocol用來分隔的是CRLF(\r\n) 以及CRLFCRLF(後者用以區隔header跟content)。PrintWriter的println(以及所有stream family的println, 比方說PrintStream)所傳出的分隔都是依系統而變(也就是,很不幸,這個函數並不是跨平台)

珍惜生命 遠離println / printstream(全文完)

--------
基本上Client來說,看到這裡應該就夠了,下面是比較詳細的說明。換行(也就是println會幫你做的事情)會幫你插入一個換行符號,而這個換行符號在各個系統都不一樣,所以基本上各個系統輸出都不同。比方說Windows就是CRLF(難得反而windows是正統的) 而unix系的含OSX絕大多數都是CR。

這是java少數幾個無法跨平台的地方,你可以想像一下同樣一串碼

out.println("This is SPARTA!");

其實在Windows底下是輸出
This is SPARTA!\r\n
而Unix系卻是
This is SPARTA!\r

這個println如果是輸出到螢幕上的話,沒差,大家看起來都一樣
阿輸出到socket就有差了,後者readline會根本讀不到

那當然照慣例就要問了:那要怎麼辦?
簡單,out.print("This is SPARTA!\r\n");

當然,也別忘了out.flush();

請銘記在心,寫Java Socket程式絕對要遠離任何println/printstream,看到他請當瘟神一樣離開他

ok,接下來談談server對應的部分。事實上當你寫server的時候,很多時候你是沒得選擇的。根據我自己的經驗,會犯下這種錯誤的coder其實比率是相當高的,只是絕大多數都是在windows下作業跟跑server,有時候是一些3rd party,server來講你很難做些什麼。畢竟code不是你寫的,你也沒source code,你更沒辦法把寫client的人抓過來狗幹一頓(我個人是稱為「友善的爭論」XD)

既然改不了client,那我們只好改server,讓server吃得下這些錯誤的東西

在談讓server怎麼吃這些東西而不至於拉肚子以前,我先講個瘟腥小故事。

IE7以前的世界,事實上browser是非常「友善」的,友善到一些明明是錯的東西他照樣吃。比方說有<p>沒</p>,或者<body><p> ....... </body></p>照吃不誤。這樣其實大家寫code都很開心,問題是每個browser都用不一樣的方法去解譯它,所以造成了同一組code的效果不見得一樣。

這造成了html界的大混亂,也間接導致了嚴格規範的xhtml誕生。(不過這東西始終沒有來的及正式長大,就被html 5.0取代了)

請注意,我們現在做的事情就跟以前「友善的」server一樣,是不對的,但是這是一種沒辦法中的辦法

說穿了很簡單,我們改用一個字元一個字元的去讀它(沒buffer想必這會很耗力)。我們讀取到\r的時候,我們會打開一個flag, 然後將\r後面多寫一個\n,下一個如果是\n的時候我們就把flag關閉並且跳過這個\n,不是的話關閉flag繼續。

具體的code大約是這樣(我個人是用filterinputstream處理這種東西)

boolean LRFlag = false;
while(char input = in.read()) {
if(input == '\r') {
LRFlag = true;
out.write(input);
out.write('\n');
continue;
}

if(input == '\n' && flag == true) {
flag = false;
continue;
}

flag = false;
out.write(input);
}


繼承fliterinputstream在read裡面插入這一段(也有一種寫法是override skip(),方法大同小異,我是比較喜歡override skip()就是,不過這比較少為人知)

hope it helps

Thursday, December 22, 2011

淺談OAuth in Android -- 以Plurk為例子

OAuth是目前比較熱門的認證機制之一,他有個最大的好處就在於完全不需要在client端輸入賬號密碼,這部分完全會由web端完成。不過,他機制非常的複雜,有些地方做的讓人覺得很龜毛,所以我們在這篇只要淺談就好,其他的部分我會介紹一個函式庫來把它完成。

這邊有一篇非常不錯的OAuth機制介紹,有興趣的朋友可以看看。太細節部分的工作原理我們就不涉足了,我們專心看看最基本的認證步驟

  1. app開發者跟網站註冊取得API Key跟API Secret
  2. 開始認證的時候,用這組key/secret/callback(*1)跟網站要一個Request Token(*2)
  3. 用這組Request Token, callback組合成一個網址,讓使用者進入該網址認證
  4. 認證成功以後會傳回一個oauth_verifier,通常是一個很好閱讀的字串或者數字
  5. app端把這組verifier,以及request key跟網站取得半永久性的Access Token(*2)
  6. 往後對這個網站任何要求(比方說,plurk來講,取得時間軸)使用這個Token即可,app把它存起來備用,就不需要重新跟網站申請認證了。

這幾個步驟其實相當的繁瑣,尤其是對網站要求每次都要做一個全面性的Parameter Sign的動作,裡面牽涉的東西對一個初學者來講真是煩人到爆炸。當然,就會有人會寫一組library來解決這問題:我們今天介紹的就是oauth-signpost library。

基本的取得jar,放進project,設定buildpath這些基礎到爆的東西我們就不討論了。首先,我們要先去Plurk申請一組API Key來作為我們的開發用途。所以我們就有了API Key/Secret了。接下來,回到Plurk API介紹的頁面,他提供了幾個網址供OAuth使用。基本上這些分別是幹嘛的我們就不予深究了,我們只要知道她是要怎麼用。

signpost我們會用到根OAuth有關的一共有兩個部分:OAuthConsumer代表的是我們APP端的所有資料,包含Access Token等等(不過她好像沒幫你存,你要自己存),而OAuthProvider則是代表網站的OAuth認證部分。

static final String PLURK_REQUEST_URL = "http://www.plurk.com/OAuth/request_token";

static final String PLURK_AUTHORIZATION_URL = "http://www.plurk.com/m/authorize";

static final String PLURK_ACCESS_URL = "http://www.plurk.com/OAuth/access_token";

static final String PLURK_CALLBACK_URL = "myplurk:///";

static final String PLURK_CONSUMER_KEY = "你的API Key";

static final String PLURK_CONSUMER_SECRET = "你的API Secret";


我們先把這些東西設定變數,等等會用到。接下來我們設定Provider跟Consumer

mainConsumer = new DefaultOAuthConsumer(PLURK_CONSUMER_KEY, PLURK_CONSUMER_SECRET);

mainProvider = new DefaultOAuthProvider(PLURK_REQUEST_URL, PLURK_ACCESS_URL, PLURK_AUTHORIZATION_URL);

ok,那所有東西差不多就完成了。我們要讓使用者認證的時候,只要開一個url,載入provider提供的url :

String url = mainProvider.retrieveRequestToken(mainConsumer, PLURK_CALLBACK_URL);

利用webview打開這個以後,把webview設定一個WebViewClient,然後override它的link click

private class AuthClient extends WebViewClient {

@Override

public void onPageStarted(WebView view, String url, Bitmap favicon) {

super.onPageStarted(view, url, favicon);

}

@Override

public void onPageFinished(WebView view, String url) {

super.onPageFinished(view, url);

}

@Override

public boolean shouldOverrideUrlLoading(WebView view, String urlString) {

Log.d("SubPlurkV2", "url : " + urlString);

if(urlString.contains("subplurkv2")) {

Uri url = Uri.parse(urlString);

String verifier = url.getQueryParameter("oauth_verifier");

try {

SystemManager.getInst().getAuthManager().aquireAccessToken(verifier);

} catch (Exception e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

finish();

}

return super.shouldOverrideUrlLoading(view, urlString);

}

然後我們可以取得verifier,利用這個取得Access Token

mainProvider.retrieveAccessToken(mainConsumer, verifier);

Log.d("SubPlurkV2", "Token = " + mainConsumer.getToken() + " and secret = " + mainConsumer.getTokenSecret());


把這祖Token記錄起來,以後會用到。最後,我們來試試看最簡單地拿取時間軸吧

mainConsumer.setAccessToken("U5GNYyH6wVGS", "aCtJ9XVgNTeIpigq3qxsLi70Sv0HbA6h");


 

URL url = new URL("http://www.plurk.com/APP/Timeline/getPlurks");

HttpURLConnection request = (HttpURLConnection) url.openConnection();

request.setDoOutput(true);

request.setRequestMethod("POST");

mainConsumer.sign(request);

request.connect();

String context = StreamUtil.InputStreamToString(request.getInputStream());

Log.d("SubPlurkV2", "" + context);


have fun! 參考plunk api list繼續實做其他的api吧!

Monday, December 19, 2011

幾個Android裡面Dependency的設定差異 (1)

 

Android裡面,設定Dependency有幾種方法,不過都各自有一些問題。

官方的做法是把其中一個設定成Lib Project,然後我們就能在Host專案裡面選取這個Lib Project,剩下的ADT會自動幫你搞定。

Select

Select

Check

 

然後,在要使用這個Library的專案,同樣的地方,下面的checkbox應該就會出現可以選擇的lib名稱,選Add加入就好

Screen Shot 2011 12 19 at 11 07 10 AM

 

這個方法是Android內建的方法,他有些問題跟限制。1. 他會被「Close not related project」關掉,這個簡單,大不了在打開 2. 他在clean build會出錯,要重復clean個幾次。3 被設定成lib的project就不能跑了,所以不能相依於另外一個完整地執行模組(手動開開關關lib開關是可以啦,只是麻煩)。

 

Wednesday, December 14, 2011

解決static library(.a)在IB以及某些category的靈異狀況。

Interface Builder是個很神奇的東西,裡面很多神秘的機制。其中最為讓人難以裡解的就是他跟dependency的恩怨情仇。對,android的java有更嚴重的問題(在UI上,android甚至沒辦法access到dependency的resource),不過這個Bug完全是因為Interface的linking機制是等到obj編譯完以後才開始找的關係(所以這個bug基本上只會出現在自定的widget class)。

這個bug大概會以這種形式發作:我們的.a(static靜態函示庫)裡面有某個widget class,而引用端的Interface Builder會引用這個class, 於是在某種情況下就出錯了

2011-12-14 13:58:50.999 TestPlatform[294:707] Unknown class MyClassBtn in Interface Builder file.

2011-12-14 13:58:51.010 TestPlatform[294:707] Unknown class MyClass2Btn in Interface Builder file.


這出錯的原因很簡單。因為Interface Builder是從.obj(compile from .a)裡面去獲得class的名字以及資訊,但是他找不到(廢話)。為什麼找不到?因為.obj裡面真的沒有這個symbol。所以IB只好很哀怨地把他設定回預設的class,比方說UIButton。當然,當你真的invoke起這個button又用了只有MyClassBtn才有的method,他就會理所當然地吐一個unregconized selector的runtime exception給你。

所以問題出在linker,自作主張地把這個.a裡面的symbol沖倒馬桶去沒有編譯進去.obj了。linker在編譯.a編譯成.obj的時候,為了一些效能以及檔案大小上的理由,會主動地去尋找其他的.obj裡面到底有沒有真的用到某個symbol,要是他在其他obj裡面找不到,那自然就會理所當然地把它扔了。

然後IB自然就沒辦法在編譯出來的.a找到symbol,一切合情合理。

解決的方法有兩個,我先聊聊第一個比較簡單的方法。為了防止linker愚蠢的(這樣將不太公平,天曉得這東西IB會用到?)把不該丟掉的symbol給沖到馬桶去,所以我們必須要呼叫他的static method來欺騙linker,這東西是有用的,不准丟掉。link show了一個比較hack的方法,你做一個static method,但是什麼都不做,然後在host呼叫他,linker就會被欺騙而不會把.a裡面的symbol丟掉才編成.obj。

其實下面也提到一個更簡單的方法,事實上你呼叫class靜態方法也可以,比方說[MyClassBtn class]。

後面會提到第二種方法,同樣可以解決這問題。不過再看第二種方法以前,我們先看看另外一個靈異現象。

Category也有類似的問題,不過起因不太一樣。當你去Categorize一個Native class(最常見的,恩,NSString)在編譯的時候會被錯誤的當作沒用到的丟棄了--這起因應該主要是因為linker的objc旗標buggy,我猜的--所以同樣的在使用static library時,library裡面native class的category都會無作用(很妙的是,自動完成使用的資料庫是.h,所以自動完成會自動地幫你找到method,但是runtime會因為找不到這個selector炸掉,真悲)。

解決的方法就是前面提過的第二種方法 -- 強制linker「你什麼symbol都不准丟掉」。在宿主的build setting裡面,找到other linker flags,加上-all_load或者-force_load(老實講前後兩者不太一樣,但是我沒有去追究他們到底有什麼細微的不同)。這同樣也可以解決IB找不到symbol的問題。

所以我們可以替這兩種方法做一個總結。第一種方法是藉由對linker額外的提示(但是code會混亂不堪),明確地告訴linker那些東西要額外地放進來。所以.a->.obj並不會include過多的symbol,不會造成.obj又肥又大的問題。當然缺點就是code要用一些非常莫名的東西來提示linker--當然IBOutlet/IBAction都用了,不在乎再多個幾行莫名其妙的code。我們其實可以藉由#define來稍為美化他一下,至少讓他[MyClass class];這行看起來不會那麼奇怪。另外,他對於category造成的問題其實是無解的。

第二種方法則沒有以上的所有缺點,但是會造成.a->.obj非常大--尤其當你的.a包山包海無所不包的時候(比方說我個人非常愛的Utility classes)--然後大通常伴隨的就是慢。不過,在普通的輕量級class裡面,這算是一個可以接受的效能損失。當然,category造成的問題,這是唯一解的樣子。聽說-force_load效能會比-all_load效能好,不過我沒比過。

static library問題多,還是用source code編譯最好(遠目)

Tuesday, December 13, 2011

iOS底下幾個NS Debug用的旗標

Screen Shot 2011 12 13 at 11 06 16 AM

首先,先Edit Scheme叫出下面這個畫面

Debug Arguments

 

這些Enviroment Varibles分別代表這些意思 :

 

NSZombieEnabled : 除錯BAD_ACCESS_ERROR用的,可以追蹤過度retain的時候的一些多於資訊

 

MallocStackLogging : 可以enable一些unhandled exception的call stack資訊。

 

NSDebugEnabled :設定除錯旗標,可以讓你在程式裡面判斷,比方說

#include <unistd.h>

int main (int argc, char ** argv, char ** envp)
{
#ifdef DEBUGENVIRON
 
if (!getenv("NSDebugEnabled"))
 
{
    setenv
("NSDebugEnabled","1",1);
   
... set the other variables ...
   
// Maybe this will complain about an autorelease pool.
   
char * executablePath = [[[NSBundle mainBundle] executablePath] filesystemRepresentation];
    execve
(executablePath, argv, environ); abort();
 
}
#endif
 
... do what you normally do in main() ...
}

但是老實講除此之外我也不知道他能幹嗎
Ref : 

http://stackoverflow.com/questions/3816136/condtional-environment-varialbes-in-xcode

http://www.yifeiyang.net/iphone-development-skills-of-debugging-articles-3-crash-after-debugging-skills-program/

Monday, December 12, 2011

iOS底下啓動Code Trace Stack的方法

XCode4以後,以往的Code Stack變成了一堆address map,所以當Unhandled exception被Throw, 就會出現象如下圖一般的悲慘畫面

Origin

 

這些Trace顯然對追bug幾乎一點幫助都沒有,inspect crashed thread又只能看到一堆assembly,以前那些親切的Exception Stack跑哪去了呢?

其實Stack trace在exception裡面一直都是存在的,我們要做的只是讓unhandled exception被印出來而已。為了達到這個目的,所以我們必須做個小小的手腳。

首先先介紹一個基本的觀念,在C裡面,所有的unhandled exception都有一個最終處理函數,這個函數是可以經由指標切換的。原始預設的函數就是印出一堆有的沒有的以後,執行exit()。我們要做的就是寫一個函數取代掉它

 

void uncaughtExceptionHandler(NSException *exception) {

NSLog(@"CRASH: %@", exception);

NSLog(@"Stack Trace: %@", [exception callStackSymbols]);

// Internal error reporting

}

 

接下來我們必須要告訴系統,預設的處理unhandled exception handler函數更改為這個函數

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

{

// Override point for customization after application launch.

NSSetUncaughtExceptionHandler(&uncaughtExceptionHandler);

 

return YES;

}

 

當然,我們有很多地方可以放NSSetUncaughtExceptionHandler,不過我們選擇放在application:didFinishLaunchWithOptions:裡面

 

然後我們就可以得到下面的結果 :

XCode4_ST_Fixed

 

看,是不是好除錯多了嗎? 至少可以知道exception是從哪裡丟出來的了

Thursday, July 28, 2011

Pure electronic music fits me.

As far as early 1999, pure electronic stepped down from main stage in Asia. From that time, Techno category in muzie(http://www.muzie.co.jp, it's almost largest free-musician sharing hub even in nowadays) were slowly "infested" by Trance, and even mixed in Euro style.

What's T-E-C-H-N-O?

It represents a music excluding any emotional elements, similar to Heavy Trance. It doesn't exclude vocal, but it only used/served as a sound resource, or, more exactly, an instrument. All elements in Techno represents a pure electronic, pure digital, and HEAVY BEAT in this music in category.

If you are appreciating in more emotional ones, you will more likely find your sound in Euro or Rave.

Time is changing, since pure electronic techno fades in west Asia.

Sunday, July 03, 2011

Suppression on Depression

I just post a term in some social network, and I deleted in 30 sec. What I have posted is not quite important.

I can never deny that I put it in my heart.

Since the departure continues, I remembered somebody just said to me : "don't you wanna change? change the situation that you always keep your relationship with your friend so thin and far". Commission is my only way to keep it, and it will be gone since communicated is gone or broken.

Quite fit the situation I have met, I must say I have put somebody in my mind.

But enough murmuring, I have my own way to pave. Such one is no doubt a significant loss to me, but I have my own way to go, my won thing to do. Things will be much simpler since I keep distance with her, all keeps in line, and transfer to my team to handle this.

Way to go.

Sunday, June 12, 2011

Demolished

冷氣壞了,躺在床上聽著Speed of the Flow發呆

說真的,這個鬼地方還真的不比監獄隔間大多少,唯一值得慶幸的似乎只有我不用在這個白色的監獄中多劃一塊出來塞個馬桶進去...雖然在外面跟人共用的雅房盥洗室好像好不到哪裡去就是。

還有13個小時...

上次遠行似乎已經是好擠個世紀以前的事情了。對著不算小的行李拖行箱裡面巨大的空間,我努力的回想著其他人到底是怎樣把他填滿的,尤其當我看著床上整理出來的belongings... 恩,扣掉那三本該死的書的話,一個中型小背包就全部搞定了阿。

該死,還是得帶上那三本書 orz..

而且在填滿著行李箱的時候,我還要努力的讓自己的大腦,不被過往的回憶填滿...

Saturday, April 23, 2011

解決Android in Eclipse下,在.xml下按下run卻亂編出.out.xml的方法

這方法起因是因為一個元件衝突:XSL Editor.
解決方法其實很簡單,就把它關掉就可以了



從此王子跟公主...真的能因為這種事情過著幸福快樂的日子嗎(抱頭)

Friday, April 08, 2011

How to set automatic debug flag in Android for Logging

In my old method, I prefer to copy/paste follow code into each module.

static public boolean DEBUG_MODE = true; static public String DEBUG_MODEL_NAME = "your_module_name"; static public String DEBUG_TAG = "your_debug_tag"; static public void logD(String message){ if(DEBUG_MODE == false) return; Log.d(DEBUG_TAG, DEBUG_MODEL_NAME + " : " + message); } static public void logI(String message) { if(DEBUG_MODE == false) return; Log.i(DEBUG_TAG, DEBUG_MODEL_NAME + " : " + message); } static public void logE(String message) { if(DEBUG_MODE == false) return; Log.e(DEBUG_TAG, DEBUG_MODEL_NAME + " : " + message); }

This method is sharp, and you can debug each method. When you want to release, simply replace all "static public boolean DEBUG_MODE = true" to "static public boolean DEBUG_MODE = false" by Eclipse.



However, if your logging message is not so much, you can control logger flag in this way, more conveniently and efficiently.







PackageInfo packageInfo = ... // get package info for your context

int flags = packageInfo.applicationInfo.flags;

boolean DEBUG_MODE = (flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;




now you can control debug flag in AndroidManifest.xml's "Debuggable" flag, automatically.


Sunday, January 02, 2011

How To : 利用Time Capsule/Airport Extreme Base Station以及MobileMe在網 路 上使用AirDisk









AirPlay_Shared



Apple的Time Capsule/Airport Extreme Base Station(分別簡稱TC/AEBS)有一項主打的功能,是讓你能夠在遠端利用MobileMe的帳號存取你連接在TC/AEBS上面的儲存裝置。奇怪的是,這項功能雖然被寫在網頁上,可是說明書上並沒有詳細的使用方法(好歹我買AEBS跟MobileMe有一半的理由是為了他阿 orz)。這篇文章就來談談怎麼讓這個功能「啓動」。

MobileMe有一個功能稱為「Back To My Mac」,這是一個遠端remote自家產品的方法(包含iMac, MB系列....事實上也包含TC/AEBS)。首先,我們必須先讓這個功能啓動一下。







201101020224.jpg

這功能位置在System Preference->MobileMe->Back to My Mac。如果你還沒啓動過這個功能的話,把他給啓動一次。成功的啓動完畢以後,看你要關掉他還是怎樣都可以。啓動一次的目的在於讓他跟MobileMe的Server溝通,取得密碼。















接下來我們啓動Keychain Access。







Screen shot 2011-01-02 at 2.27.17 AM.png











先在畫面左邊點選System,然後在Name裡面找出.mac.com(某些人的MobileMe賬號產生的會是.me.com,這些以下同,不再贅述)。然後請右鍵(或者雙指壓觸控板)後選擇「Copy password to clipboard」,把密碼拷貝起來吧!(他會跟你要管理者權限),等等會用到。











到這邊,目前準備工作已經就緒了。現在讓我們打開我們的AirPort Utility。







讓我們開始設定AEBS吧(TC其實以下同)!先進入Advanced->MobileMe加入你的MobileMe帳號(這應該不用附圖吧冏)







再進入AirPort->Base Station 按下Edit











Screen shot 2011-01-02 at 2.49.11 AM.png











Screen shot 2011-01-02 at 2.49.52 AM.png











最重要的一點就是Password不是你的MobileMe賬號,很多人都搞錯了再跟我哀 冏...











然後進去AirDisk把裡面分享打開Screen shot 2011-01-02 at 2.49.32 AM.png











請先確定一下你區網內可以正常Access AirDisk!AirDisk只能是HPS+(MacOS的檔案格式)/FAT32/exFAT而已,他無法讀取NTFS,如果你在區網下都讀取不到AirDisk了,那怎麼可能在Internet下就可以了呢?請務必先確認這個(按下Disks標簽進去看一下吧)











最後,不能免俗的,update我們的AEBS吧,AEBS重開機以後應該就沒問題了。











OK,接下來我們來談談測試的方法跟Back to My Mac的原理。事實上MobileMe有一組隱藏的(使用者也不知道)的動態DNS服務,他的DNS Host在(你的使用者名稱).members.mac.com,帳號就是剛剛那一組,密碼則是Server會產生一組給你。所以只要我們能夠有這組賬號密碼,我們就能在Internet上取得我們AEBS的網路位置。而這組位置是能ping的喔,所以我們要測試的話並不需要離開區網,只要打開terminal去ping他看看...











Screen shot 2011-01-02 at 3.13.57 AM.png











只要能夠ping到這組位置,其實我們就可以確定他在internet下能夠正常作業了。Finder上的Shared標簽中的AirDisk,即使你離開區域網路環境,也可以毫無問題的正常使用喔。






Saturday, July 24, 2010

Ogre SDK on Mac

Ogre SDK在Mac XCode下的安裝



首先,我們當然要有SDK

Download

選擇Mac OS X, 這個版本應該就可以了 (iPhone又是另外一個故事,下一篇再介紹)



接下來把他解壓縮到本機,我個人是直接丟到Documents



然後各位應該就會碰到第一個障礙:XCode Project打開後build出一堆錯(多半是CMake找不到甚麼檔案有的沒有的)這是一個已知bug,請升級CMake到2.8.2以上

Download



再度執行看看,如果再不行的話就需要重建.xcodeproj

Screen shot 2010-07-24 at 4.00.47 AM.png

重建也沒那麼恐怖,按照下面一步一步來

首先先在Application裡面找出CMake按下去

將Source指到你的sdk跟目錄,build binaries也指到同樣的地方

按下Configure會出現選擇編譯器跟目的檔的畫面

Screen shot 2010-07-24 at 4.05.36 AM.png

選好後再按Configure一次,Generate就亮了,按下Generate,收工。夠簡單了吧



接下來.xcodeproj似乎就可以正常運作了,記得把左上角調整成Release或者RelWithDebInfo

Screen shot 2010-07-24 at 4.08.23 AM.png



ok 接下來就是build and run! 大多數的人會在這裡碰到第二道難題:奇怪,為什麼build and run跑不出執行檔?這時候應該要打開console看一下了!

Screen shot 2010-07-24 at 3.56.33 AM.png



歐賣尬,要是一輩子沒想到開console不就被它栽到了。這個問題的成因是,nVidia顯卡下它需要CG Toolkit來執行demo(ATi要不要我不知道,有人能給個答案嗎 =P) 來吧,我們拿個最新版本來玩玩

Download



安裝好以後,再度執行他的執行檔,成功!

Screen shot 2010-07-24 at 4.13.48 AM.png





希望這對用Mac OSX開發Ogre3D遊戲的人有點幫助 :3



Wednesday, February 03, 2010

else....where??

http://thedailywtf.com/Articles/Else-where.aspx

「我手下曾經有一個非常強的專家,他留下一句名言:給我足夠的NAND Gate(譯註 : 這是一種邏輯閘,相當於先取and再取not...剩下的請查閱這裡),我將統治全世界」,Rob B,在他的一本書裡面寫到:「其實換個繞口令一點的說法,你用上一整片的NAND Gates,你可以做出其他邏輯閘能作到的任何事情。當然啦,因為有其他邏輯閘能作這些事情,你實在不該浪費一狗票NAND gates來作這種無聊的事情。恩...這樣的確是辦得到的...寫code的時候偶爾也會有類似的思維」

「前陣子我們從我們的外包商那裡看到了一份實在是爛到爆炸的C++ code。這東西平均每行出錯率實在是真他媽的高,而且他的寫碼風格讓我們越看越想咒他老母。不過,這種What the fuck的感覺,到我們看到這組code的時候達到了最高點。」


while(true)
{
if(mainType == 7)
{
subType = 4;
break;
}

if(mainType == 9)
{
subType = 6;
break;
}

if(mainType == 11)
{
subType = 9;
break;
}

break;
}


「來來來我們看看這堆鳥東西....」Rob繼續寫到:「我花了些時間在想,他幹麼寫這樣?這個while loop到底是幹麼的?只是拿來搭配break跳過下面那些if的嗎?我還真沒看過那麼蠢的,完全不是拿來作條件判斷的break...好啦,這是我第一次看到。」

Bob補充:「我幾乎可以確定這傢伙完全不知道什麼叫做else if....他好像只知道if while break,所以就把他們拼在一起了...用這種超白爛的方法做出這個邏輯。」

Tuesday, February 02, 2010

Classic WTF : What the hell enum!?

One day, while I was roaming through Internet, I bump into a article while I was viewing a frequently viewed forum =3

in HeaderDefine.h(This is a header file that will be included in almost every files)


/*----Be sure you have READ this!----
...
...(a long term of manual of this header)
...

I have made this way to make sure
everyone will read this manual.
By Genius Jason
----------------------------------------------/*
enum DECLARE
{
I_HAVE_READ_THE_MANUAL_AND_KNOW_WHAT_I_AM_DOING_THIS = 38106,
I_HAVE_READ_ABOVE_AND_AGGREED_THE_TERM_OF_USE = 39100
};


You might be confused what the hell it is for, ya, it's a trick. While using some function or callback, you have to follow his way or a assert will be invoked :

KaimCore.Init(I_HAVE_READ_ABOVE_AND_.....
KamiCore.CleanupDump(I_HAVE_READ_THE_MANUAL_AND...



"Fuck you Jason you damn moron!"

Game loop in C#

Game update loop is a problem in C#. Of course, first thought of us must be attach the Idle event of Application, like this.


Application.Idle += new EventHandler(OnAppIdle);
Application.Run(mMainFrame);

........
........

static void OnAppIdle(object sender, EventArgs e)
{
//Do some game loop update here
mMainFrame.DoUpdate();

}



It seems reasonable, we register a listener to Idle event, so it must be run OnAppIdle while application idle, right?

Partially right.

When the application keep going, it will only get message while "When application need to be updated". It means, therefore, if you leave mouse out of this application form(so no MouseMove event sent), it will totally stop, so it will be updated only when getting some message : such like OnMouseMove....etc.

Solution is from Rich, and he found it in sample of MDX applications. Don't ask me how to do it, just need to know use this way to keep the game loop.

We might discuss this in later post =3


static class Program
{
///
/// The main entry point for the application.
///

///
static SceneEditorMain mMainFrame;
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);

mMainFrame = new SceneEditorMain();
Application.Idle += new EventHandler(OnAppIdle);
Application.Run(mMainFrame);
}

static void OnAppIdle(object sender, EventArgs e)
{
while (AppStillIdle)
{
mMainFrame.DoUpdate();
}
}


private static bool AppStillIdle
{
get
{
NativeMethods.Message msg;
return !NativeMethods.PeekMessage(out msg, IntPtr.Zero, 0, 0, 0);
}
}


}

public class NativeMethods
{
/**/
/// Windows Message
[StructLayout(LayoutKind.Sequential)]
public struct Message
{
public IntPtr hWnd;
public uint msg;
public IntPtr wParam;
public IntPtr lParam;
public uint time;
public System.Drawing.Point p;
}

[System.Security.SuppressUnmanagedCodeSecurity]
[DllImport("User32.dll", CharSet = CharSet.Auto)]
public static extern bool PeekMessage(out Message msg, IntPtr hWnd, uint messageFilterMin, uint messageFilterMax, uint flags);
}

Friday, November 27, 2009

只是「為了呼吸自由空氣,所以你應該...」的話,真是大可不必

說真的,對我來講,如果用linux只是為了覺得與眾不同,還是高人一等,還是只是『想呼吸自由空氣』,那我真的覺得何必這樣。我個人也是非常反MS,可是我之所以用ubuntu只是因為「他對於開發程式的我來講是另外一種選擇,而且很好用」。我也不用諱言說我因為他沒辦法執行Visual Studio 2008所以可能會想把他換回winxp or win7。



很多人把「使用ubuntu linux」想得太異端或者太特別了。我一直認為,會一直用些偏激的語言推廣linux的,多半反而是生手,而真正熟練的使用且知道自己需要的,才是至少有一定使用程度的使用者。投其所好,自己需要什麼就用什麼吧,什麼微軟奴隸那麼難聽的話都大剌剌POST在社群網站上,這真的是... (重點是還用匿名來post,唉)



說真的這種環境下,只要想用,不可能拿不到windows,至少要拿個XP是輕而易舉的。自己需要用哪種作業系統就用吧,用linux並沒有比較高手。



我自己這篇文章就是在ubuntu下用BloGTK打出來的,這東西可不比MS的Live Writer差(也許感覺還更好一點),對我來講,linux適合我現在開發環境,所以對我來說就是好用。相對的,我相信也有更多人在windows底下才是適合他們的環境。



不要像那些 Aggressive apple fan 阿...