Giới thiệu
Ngày nay với sự xuất hiện của nhiều platform khác nhau có thể thực thi C/C++, để tiết kiệm chi phí, một thư viện game phải đảm bảo có thể compile và run tốt trên nhiều platform.
Về cơ bản, thư viện chuẩn C/C++ trên các platform là gần như tương thích với nhau hoàn toàn. Tuy nhiên, trên từng platform vẫn có những đặc điểm riêng, khác biệt.
Một ví dụ, trong lớp CGame.cpp, để sử dụng hàmSleep(80), ta cần đến thư việnwindows.h, vốn không phải là thư viện chuẩn của C/C++. Điều này làm cho việc compile CGame.cpp là không thể khi biên dịch trên trình biên dịchGNU GCC
Một ví dụ khác, hàmprintfdùng cho debug có thể dùng cho console win32, tuy nhiên với Android thì không thể, mà phải được thay bằng__android_log_print.
Cách thức cấu hình
Để làm được như đã nêu, trước tiên, ta cần cấu hình cho từng platform khác nhau khi compile. Ta định nghĩa 1 số file header:
- Header.h: chứa những thông tin header cần cho chương trình
- Config.h: chứa các thông tin cấu hình
- Macros.h: chứa các macro thông dụng
Trong file Header.h, ta giả sử sẽ có 2 option về platform là win32 VS hoặc Android
Trong config.h, ta giả chọn cấu hình hiện tại là win32 VS
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
| /// Macros.h #ifndef __MACROS_H__ #define __MACROS_H__ #include "Header.h" #define STRINGIFY(x) #x #define TOSTRING(x) STRINGIFY(x) #if CONFIG_PLATFORM==PLATFORM_ANDROID # include # define Log(...) __android_log_print(ANDROID_LOG_INFO, "NativeLib",__VA_ARGS__) #elif CONFIG_PLATFORM==PLATFORM_WIN32_VS # define Log(...) printf(__VA_ARGS__);printf("\n") #endif #if CONFIG_PLATFORM==PLATFORM_WIN32_VS # define TODO(x) __pragma(message("[TODO]:" __FILE__ "("TOSTRING(__LINE__)")" TOSTRING(x))); Log(x); #else # define TODO(x) ; #endif #endif |
Xây dựng lớp đại diện / cầu nối
Tuy nhiên, không phải trong trường hợp nào ta cũng có thể sử dụng macro. Với những trường hợp phức tạp, ta thay thế bằng hàm. Ta định nghĩa một lớp gọi là CDevice chứa các tập hàm này. (Trong ví dụ này, ta giả sử Sleep là một trường hợp ví dụ)
Trong trường hợp cần can thiệp sang một môi trường khác C/C++ (Obj-C hoặc Android Java), lớp device làm nhiệm vụ như một wrapper, đóng vai trò cầu nối, giúp thư viện game tương đối độc lập với platform
Trong ví dụ trên, hàm SleepEx được thay đổi tùy theo platform.
Lúc này, lớp CGame được hiệu chỉnh:
Ngoài CDeivce, trong các phần tới, sẽ có một số lớp khác đóng vai trò tương tự, nhưng chuyên biệt cho một mục đích sử dụng nào đó.
Post a Comment Blogger Facebook
Post a Comment