Sức mạnh của template trong C++

Có một số các phép tính toán tuy phức tạp, nhưng với input là những hằng số, nếu lợi dụng template khéo léo, chương trình sẽ chạy rất nhanh.

Trước hết lấy ví dụ đơn giản: tính số Fibonaci thứ 40. Có hai cách dễ thấy ngay: đệ quy, vòng lặp. Giờ ta tìm hiểu cách dùng template:

template<int N> struct TFib
{
	enum
	{
		EVal = TFib<N - 1>::EVal + TFib<N - 2>::EVal
	};
};

Trong code trên, ta định nghĩa một cấu trúc tên là TFib, TFib có template nhận tham số là một hằng N kiểu int. Nhiệm vụ của TFib<N> là tính số Fibonaci thứ N, phản ánh kết quả qua một enum tên là EVal:

Read the rest of this entry »

Posted in CPP. Tags: , . Leave a Comment »

Best implementation of Singleton Pattern

File Singleton.h

#ifndef _SINGLETON_H_
#define _SINGLETON_H_

#include <cassert>

template<typename T> class Singleton
{
public:
	Singleton()
	{
		assert(!m_spSingleton);
		int offset = (int)(T*)1 - (int)(Singleton<T>*)(T*)1;
		m_spSingleton = (T*)( (int)this + offset );
	}
	~Singleton()
	{
		assert(m_spSingleton);
		m_spSingleton = 0;
	}
	static T& GetSingleton()
	{
		assert(m_spSingleton);
		return *m_spSingleton;
	}
	static T* GetSingletonPtr()
	{
		return m_spSingleton;
	}
private:
	static T* m_spSingleton;
};

template<typename T> T* Singleton<T>::m_spSingleton = 0;

#endif

To convert any class into a singleton, e.g class TextureMgr:

#include "Singleton.h"

#define g_rTextureMgr TextureMgr::GetSingleton()
#define g_pTextureMgr TextureMgr::GetSingletonPtr()

class TextureMgr : public Singleton<TextureMgr>
{
public:
	int GetTexByName(const char* texName);
};

How to use:

void GameInit()
{
	new TextureMgr();
}

void GameUpdate()
{
	int texId = g_rTextureMgr.GetTexByName("test.tga");
	// ...
}

void GameDestroy()
{
	delete g_pTextureMgr;
}

Dennis Ritchie (1941-2011)

Steve Jobs (1955-2011)

Symbian Descriptor

Symbian đưa ra Descriptor để thay thế cho String trong C/C++. Gọi là “Descriptor” vì chúng tự mô tả bản thân, mỗi đối tượng Descriptor đều cho biết thông tin về mình: độ dài của chuỗi mà nó nắm giữ, kiểu của ký tự, địa chỉ con trỏ trỏ tới ký tự đầu tiên, cách bố trí dữ liệu (data layout).

Descriptor không dùng ký tự NULL cho việc đánh dấu sự kết thúc chuỗi, nên chúng có thể chứa dữ liệu text hoặc nhị phân đều được. Có 2 loại Descriptor chính: Narrow và Wide.

  • Loại Narrow sử dụng 8 bit để biểu diễn một ký tự và do đó, con trỏ trỏ đến ký tự đầu tiên có kiểu TUint8*. Các lớp Descriptor thuộc loại này có tên gọi tận cùng bằng số 8 (ví dụ TDesC8). Ta thường dùng Narrow để chứa chuỗi ASCII hoặc nhị phân.
  • Loại Wide sử dụng 16 bit để biểu diễn một ký tự và do đó, con trỏ trỏ đến ký tự đầu tiên có kiểu TUint16*. Các lớp Descriptor thuộc loại này có tên gọi tận cùng bằng số 16 (ví dụ TBuf16) hoặc được typedef để không có số gì (ví dụ TBuf). Tuy nhiên nên viết tường minh số 16 để tránh nhầm lẫn. Ta thường dùng Wide để chứa chuỗi Unicode.

Mỗi lớp 16 bit đều có lớp 8 bit tương ứng và ngược lại, cho nên ta chỉ bàn về các lớp 16 bit. Cây kế thừa sau đây liệt kê các loại Descriptor và quan hệ giữa chúng:

Read the rest of this entry »

JavaScript Kata

JavaScript Kata

Làm việc ở cái công ty này thật kỳ cục, có những lúc bận rộn đến nỗi OT điên cuồng, lại có lúc rảnh rỗi đến mức phát chán.

Mặc dù công việc của tôi không hề đụng đến JavaScript (JS), nhưng tôi vẫn dành cho ngôn ngữ kịch bản này một tình cảm đặc biệt.

Sáng nay vào thăm http://www.javascriptkata.com/ (blog của một anh lập trình viên JS Hà Lan) thấy có nhiều điều thú vị, xin được kể lại.

Read the rest of this entry »

Asynchronous Functions và Active Objects

Active Objects là một trong những tinh túy của Symbian OS. Cơ chế này giúp cho việc gọi các hàm bất đồng bộ (Asynchronous Functions) trở nên rất hiệu quả và do đó tiết kiệm năng lượng cho thiết bị di động.

Mặc dù trong Symbian OS cho phép tạo nhiều Thread, nhưng việc này vốn khá nguy hiểm (kể cả trên các nền tảng khác), cần thiết lắm ta mới phải dùng, và phải dùng cẩn thận. Một lựa chọn phổ biến là hãy để chương trình chạy trên một Main Thread duy nhất, hướng sự kiện (event-driven) bằng cách dùng Asynchronous Functions và Active Objects.

Trước hết chúng ta tìm hiểu sơ qua thế nào là Synchronous/Asynchronous Functions.

Read the rest of this entry »

Lập trình thanh toán tiền qua mạng với PayPal API

Cách đây 3 năm, tôi cũng có viết về vấn đề này (sử dụng Java), API của PayPal khi đó (2008) giờ đã lỗi thời. PayPal hiện nay cung cấp bộ API mới cho việc thanh toán tiền: “Adaptive Payments API”, rõ ràng hơn, tiện lợi hơn và độc lập nền tảng hơn.Có nhiều kịch bản chuyển tiền, từ đơn giản đến phức tạp, nhưng thông thường nhất là chuyển tiền từ 1 tài khoản A đến 1 tài khoản B, nên chúng ta sẽ chỉ bàn về tình huống này.

A và B đương nhiên phải là 2 tài khoản đã đăng ký với PayPal, đặc trưng cho mỗi tài khoản là địa chỉ email, chẳng hạn a@gmail.comb@gmail.com. Giả sử phần mềm chúng ta định viết tên là phần mềm K.

Read the rest of this entry »

Vector 3D

Đây là một cài đặt Vector 3D cùng các phép tính trên nó khá hoàn hảo:

Read the rest of this entry »

Design Pattern cho lập trình Game

Design Pattern (thuật ngữ này vốn là của ngành Kiến trúc) rất quan trọng trong việc lập trình phần mềm. Tuân thủ theo nó, chương trình không những dễ dò lỗi, sửa lỗi, nâng cấp, mở rộng mà còn tạo cảm giác sung sướng cho lập trình viên trước cái đẹp.

Lập trình game cũng chả phải ngoại lệ. Trong quá trình làm việc, tôi đúc kết ra những chuẩn, những mẫu lập trình cơ bản nhất mà một game (không kể lớn nhỏ) nên áp dụng.

Như thường lệ, ban đầu, chúng ta có một đống code để khởi tạo cửa sổ, khởi tạo môi trường đồ họa, âm thanh, đăng ký các loại sự kiện, … Nó na ná nhau cho tất cả các ứng dụng trên cùng một platform. Và trên mỗi SDK của mỗi platform, người ta thường cho sẵn các example, tốt hơn hết ta nên lấy các example đó và thêm thắt vào. Hãy thiết kế sao cho đoạn này đừng liên quan đến code trong game, chỉ cho gọi những hàm, method của lớp bao (wrapper) của game (sẽ tốt hơn nữa nếu các hàm, method đó được thiết kế chỉ để cho mục đích này).

Trước khi đi tiếp, ta tìm hiểu một số khái niệm cơ bản.

Read the rest of this entry »

Follow

Get every new post delivered to your Inbox.