[iOS] Pointer to Block Pointer

iOS block programming feature is pretty cool, it makes asynchronous programming easier. This time I want to talk about block pointer. A block pointer is a type of variable that we can use to refer to a block, for example

void (^blockPointer)(void) = void ^(void) { NSLog(@"inside a block"); };

We can then execute the block like normal function call.

blockPointer();

What’s interesting is that a block pointer is actually an Objective-C object. We can do copy, retain, release, autorelease (more on this can be read here) on it, and also assign a pointer to it :D.

I’ll show you a sample use case where I want to make a pointer to a block pointer. Suppose I have a function that does something asynchronously and executes a block at the end of it.

- (void) asyncFunction:(void (^)(void)) block {
  // do something asynchronously, then execute the block at the end
  block();
}

Then I have another function, a nasty one with many nested ifs, that passes a block to asyncFunction depending on the conditions. When it doesn’t call asyncFunction, the block still has to be executed. So the block must be called exactly once, no matter which conditional route it takes.

Solution A: do some brute force with myriads of if-else

- (void)nastyFunction:(void (^)(void)) block {
  if (...) {
    if (...) {
      [self asyncFunction:block];
    } else {
      /* myriads of other if-else */
    }
  } else (...) {
    block();
  }
}

Solution B: Because a block pointer is an Objective-C object, we can assign nil to it. So after calling asyncFunction, we assign the block to nil. At the end of nastyFunction we execute the block only if it’s not nil.

- (void)nastyFunction:(void (^)(void)) block {
  if (...) {
    if (...) {
      [self asyncFunction:block];
      block = nil;
    }
    /* myriads of other ifs */
  }
  if (block != nil){
    block();
  }
}

The number of else decreases, the number of ‘block = nil‘ increases.

Solution C: this is where pointer to block pointer becomes useful. Instead of writing ‘block=nil‘ numerous times, we write it only once inside asyncFunction. But to change the value of block inside nastyFunction, we have to pass it to asyncFunction using a pointer. We declare a pointer to block pointer using this statement.

void (^pointerToBlockPointer *)(void)

So asyncFunction becomes

- (void) asyncFunction:(void (^*)(void)) block {
  // do something asynchronously, then execute the block at the end and assign it to nil
  *block();
  *block = nil;
}

And we pass the block from nastyFunction using its address.

- (void)nastyFunction:(void (^)(void)) block {
  if (...) {
    if (...) {
      [self asyncFunction:&block];  
    }
    /* myriads of other ifs */
  }
  if (block != nil){
    block();
  }
}

The declaration for pointer to block pointer is pretty funny, I got it from XCode compilation error message :D.

Another useful tips: if you want to simplify the declaration, you can typedef the block pointer.

typedef (void)(^BlockPointerType)(void);

So the pointer to it can be written as

BlockPointerType * pointerToBlockPointer;
Advertisements
Posted in Programming | Tagged , , , , , | Leave a comment

[AS3] Nested function and asynchronous model

In early days I’m used to synchronous programming model, everything can be called sequentially so I don’t have to deal with callback, I can write the code very neatly. When I meet AS3, I learn much about asynchronous functions, callbacks and event handlers.  AS3 uses asynchronous model so extensively, almost everything that needs “loading time” is asynchronous, like URLLoader, Loader, SQLStatement, and more. On one side it makes my job easier because I don’t need to create a background process (as in Java / C#) to do the loading in background and prevent the application from hanging. On the other side it makes the code I write pretty messy.

Imagine a case where I need to do multiple INSERT statement to an SQLite database and do something when all insertions finish. I can either 1) do all insertions sequentially and handle all success callbacks. Then when the number of callbacks equals the number of insertions, I continue. Or 2) do first insertion, wait callback, insert the next, wait callback, and so on until the last callback. In either case, I need to add a new object variable to count the number of callbacks. That makes the code more unclean because the variable should only be used temporarily.

This is where I find nested function to be really useful. I have known that AS3 has nested function since way back then, but I prefer not to use it in my code for the sake of clean and more readable code. However in this case of multiple asynchronous functions, I find no better way to do it than nested function. This is due to one magical property of nested function: it preserves the local variable of its parent function, even across asynchronous calls.

So for example, if I want to do multiple insert to SQLite using method 2) above, the code will look something like this.

function insertAll(){
  var i:int = 0, max:int = 10;
  var statement:SQLStatement = new SQLStatement();
  statement.sqlConnection = this.connection;
  function insert(){
    if (i < max){
      statement.text = "INSERT INTO table VALUES ("+i+")";
      statement.execute(-1, new Responder(insert));
      i++;
    } else {
      //do something after
    }
  }
  insert();
}

In function insertAll(), the value of local variable “i” will be preserved across calls to nested function insert(). So I don’t need to add any new object variable. In this case I find asynchronous model and nested function are meant to be used together, maybe that’s actually the idea behind them anyway.

Posted in Programming | Tagged , , , , , | Leave a comment

Cara Sederhana Membedakan Script PHP untuk Development/Deployment

Saat sedang kodang-koding di kantor, tiba-tiba saya menemukan penggunaan require_once pada php yang agak menarik. Seperti yang kita tahu, require_once memasukkan sebuah script hanya pertama kali dipanggil. Jika script yang sama dimasukkan 2 kali, pemasukan kedua tidak dilakukan.

Masalah yang sedang saya kerjakan seperti ini: saya membuat script php yang menerima input parameter dan melakukan validasi sederhana dengan hashing parameter. Yang merepotkan, untuk melakukan testing pada script tersebut saya harus menghitung hash dari parameter yang saya input -___-, padahal saya ingin melakukan testing cepat dengan memasukkan parameter lewat browser. Salah satu solusinya, saya dapat menonaktifkan dahulu fitur hashing untuk melakukan pengujian lewat browser, tapi untuk menguji aplikasi sebenarnya saya harus mengaktifkan hashing lagi, jadinya bolak-balik deh.

Ada cara lain yang ternyata lebih mudah, yaitu membuat script terpisah untuk testing pada browser dan meng-require_once script asli. Pada script asli saya menambahkan konfigurasi aktif/tidaknya hashing dengan variable $use_hash. Variable $use_hash ini saya definisikan pada script terpisah “config.php” yang di-require_once oleh script asli. Untuk lebih gampangnya, isi script kurang lebih sebagai berikut.


//script config.php
$use_hash = true;

//script asli.php
require_once("config.php");
if ($use_hash) {
//hitung hash
} else {

}

//script testing.php
require_once("config.php");
$use_hash = false;
require_once("asli.php");

Mekanisme pada script testing.php: karena require_once hanya meng-include sekali, script config.php hanya dibaca pertama kali. require_once(“config.php”) yang terdapat di script asli.php tidak akan terpanggil, sehingga nilai akhir variable $use_hash adalah false. Dengan cara ini saya dapat melakukan testing pada browser cukup dengan membuka testing.php (muhaha). Mungkin trik ini juga bisa dipakai untuk keperluan lain, seperti membedakan script yang akan digunakan untuk tahapan development/deployment.

Posted in Programming | Tagged , , | Leave a comment

Review Game: Ever17 – The Out of Infinity

Setelah berbulan-bulan ga nulis blog, akhirnya gatel juga pengen nulis review game Ever17. Ever17 – The Out of Infinity adalah visual novel non-eroge keluaran 2002 yang diproduksi Kindle Imagine Develop (KID) – perusahaan game Jepang yang sayangnya udah bangkrut -_-“.

Ever17 mengambil latar belakang di sebuah tempat wisata laut bernama LeMu. LeMu merupakan sebuah pulau buatan manusia yang terapung di tengah lautan, terdiri dari lantai utama yang tersusun dari tanah seperti layaknya pulau alami dan 3 tingkat lantai bawah yang tenggelam di bawah permukaan laut. LeMu dibuat sedemikian rupa sehingga strukturnya tidak akan rusak oleh tekanan air laut yang semakin ke dalam semakin tinggi.

Suatu hari terjadi bencana di LeMu yang mengakibatkan kebocoran air laut dan menenggelamkan setengah bagian dari LeMu. Enam orang tertinggal saat evakuasi dilakukan dan terjebak di lantai bawah karena jalan menuju lantai utama sudah tenggelam. Kamu pun akan melanjutkan cerita dengan sudut pandang salah satu dari dua tokoh utama: Takeshi Kuranari, mahasiswa 20 tahun yang selalu tampak santai; atau Kid, seorang anak lelaki yang kehilangan ingatan sesaat sebelum kecelakaan terjadi.

Ever17 bisa dibilang bergenre misteri-fiksi ilmiah. Berbagai misteri disajikan kepada pembaca, seperti sensor pendeteksi manusia yang menunjukkan angka 7, ingatan Kid yang hilang, pintu yang tidak bisa dibuka, dan hubungan masa lalu dari semua orang yang terjebak. Semua misteri baru akan terjawab tuntas waktu kita menamatkan True Ending, yang membuat saya terkagum-kagum pada si penulis skenario. Penyampaian cerita membuat kita terus berpikir dan bertanya-tanya: apa arti di balik semua keanehan yang terjadi?

Sebagai tambahan, Ever17 menempati posisi pertama di VNDB saat tulisan ini dibuat dengan rating 9.07/10. Rating usia pembaca 13+.






Posted in Review | Tagged , , , , , , | 2 Comments

Material is not everything

Kenapa ya banyak orang pengen punya duit segudang kayak Gayus? Jadi inget lirik lagu Black Eyed Pea feat Jack Johnson – Gone Going.

Johnny wanna be a big star
Get on stage and play the guitar
Make a little money, buy a fancy car
Big old house and an alligator
Just to match with them alligator shoes
He’s a rich man so he’s no longer singing the blues
He’s singing songs about material things
And platinum rings and watches that go bling
But, diamonds don’t bling in the dark
He a star now, but he ain’t singing from the heart
Sooner or later he’s just gonna fall apart
Coz his fans can’t relate to his new found art
He ain’t doing what he did from the start
And that’s putting in some feeling and thought
He decided to live his life shallow
Passion is love for material

[Chorus]
And its gone… gone… going…
Gone… everything gone… give a damn…
Gone be the birds when they don’t want to sing…
Gone people… up awkward with their things… gone.

You see yourself in the mirror
And you feel safe coz it looks familiar
But you afraid to open up your soul
Coz you don’t really know, don’t really know
Who is, the person that’s deep within
Coz you are content with just being the na¯ve brown man
And you fail to see that its trivial
Insignificant, you addicted to material
I’ve seen your kind before
Your the type that thinks souls is sold in a store
Packaged up with inscent sticks
With them vegetarian meals
To you that’s righteous
You’re fiction like books
You need to go out to life and look
Coz… what happens when they take your material
You already sold your soul and its…

[Chorus]

You say that time is money and money is time
So you got mind in your money and your money on your mind
But what about… that crime that you did to get paid
And what about… that bid, you can’t take it to your brain
Why you on about those shoes you’ll wear today
They’ll do no good on the bridges you’ve walked along the way

All that money that you got gonna be gone
That gear that you rock gonna be gone
The house up on the hill gonna be gone
The gold — on your grill gonna be gone
The ice on your wrist gonna be gone
That nice little Miss gonna be gone
That whip that you roll gonna be gone
And what’s worst is your soul’s already gone

Posted in Wacana | Tagged , , | 1 Comment

C++ vector iterator: a foolish amateur mistake by me

I write this so other people won’t make the same mistake like me.. well no, just to babble about my bad day.

I wrote a code and tried to debug hours without result, my program keeps crashing. I thought my algorithm was wrong somewhere, division by zero have been handled and all. And it turns out the problem was because I foolishly push_back a vector while iterating it using iterator.

std::vector<SomeClass>::iterator i;
for (i=v.begin(); i<v.end(); i++){
  .....
  //in some cases, I have to do this
  v.push_back(SomeClass());
}

After reading c++ reference about push_back I just realized that “Reallocations invalidate all previously obtained iterators, references and pointers.” Well… really a stupid mistake. I called push_back several times, the vector size changed, reallocation occurs, and segmentation fault is my friend…

From this day onward, I’ll make a note to use [] whenever I need to change the size of a vector.

Posted in Curahan Hati, Programming | Tagged , , , , | 5 Comments

Class Profiler sederhana pada c++

Optimisasi adalah hal yang mungkin jarang kita perhatikan saat sedang membuat aplikasi, terutama aplikasi-aplikasi yang ringan. Dengan kemampuan CPU yang semakin tinggi, kita dapat membuat aplikasi dengan fitur yang banyak namun tetap dapat berjalan dengan cepat. Namun ada kalanya kita dihadapkan pada aplikasi yang membutuhkan komputasi kompleks yang mengakibatkan kinerja buruk (baca: ngelag) kalau kita tidak melakukan optimisasi. Contohnya pada semester ini saya mengambil kuliah Grafika 3D yang membutuhkan perhitungan kompleks sehingga mau tak mau optimisasi algoritma harus dilakukan.

Untuk membantu tahap optimisasi tersebut saya membuat sebuah class Profiler sederhana yang dapat menghitung rentang waktu yang dipakai komputer untuk menjalankan tahapan-tahapan proses. Setelah melihat tahapan mana yang membutuhkan waktu paling lama, baru saya mencoba melakukan optimisasi pada bagian tersebut. Source codenya dapat diunduh di sini. Contoh cara pemakaiannya adalah sebagai berikut:

Profiler::enabled = true;
Profiler::reportDelay = 30;
while (loop){
  Profiler * profiler = Profiler::start("mainloop");
  //lakukan perhitungan berat di sini
  //
  Profiler::stop(profiler);
  Profiler::reportAll();
}

Untuk saat ini Profiler yang saya buat baru bisa mengenerate report sekali saja. reportDelay menunjukkan berapa kali reportAll() harus dipanggil sampai report yang sebenarnya ditulis. Pada setiap pemanggilan reportAll, Profiler akan mencatat waktu, lalu reportDelay akan dikurangi 1. Saat reportDelay mencapai 0, laporan ditulis ke stdout, setelah itu profiler berhenti berfungsi. Waktu yang ditampilkan merupakan rata-rata dari waktu yang dicatat pada setiap pemanggilan reportAll().

Laporan yang dicatat memiliki label nama yang dipassing pada fungsi start(), seperti label “mainloop” pada contoh di atas. Dengan cara ini kita bisa membagi-bagi program menjadi beberapa bagian dan menjalankan Profiler dengan label yang berbeda-beda. Di bawah ini contoh screenshot laporan Profiler dari tugas saya:

Hanya saja karena class Profiler ini sendiri belum dioptimisasi, penggunaan Profiler terlalu banyak malah akan menurunkan kinerja program. Dan karena perhitungannya dalam millidetik, presisinya kurang tinggi, tapi cukup untuk mengukur kinerja program yang berat.

Profiler ini saya buat untuk compiler gcc dan baru dites di Windows saja.

Posted in Programming | Tagged , , , , | 3 Comments