2013-09-01 43 views
6

Tôi hiện đang sử dụng Thư viện SDL2 và C để viết một ứng dụng iPhone và mọi thứ đã diễn ra tốt đẹp cho hầu hết các phần. Thật không may, tài liệu có vẻ khá mỏng ở một số khu vực, đặc biệt là các chức năng cụ thể của iOS. Tôi mới sử dụng SDL2, và điều này làm cho mọi việc trở nên rất khó khăn. Cho đến nay, tất cả mọi thứ đã làm việc, nhưng tôi stumped về một vấn đề. SDL2 định nghĩa sáu loại sự kiện được sử dụng riêng cho các ứng dụng di động. Tệp README-ios.txt mô tả chúng và sử dụng chúng như vậy:Tôi nên sử dụng Sự kiện ứng dụng iOS SDL2 như thế nào?

int HandleAppEvents(void *userdata, SDL_Event *event) 
{ 
    switch (event->type) 
    { 
    case SDL_APP_TERMINATING: 
     /* Terminate the app. 
      Shut everything down before returning from this function. 
     */ 
     return 0; 
    case SDL_APP_LOWMEMORY: 
     /* You will get this when your app is paused and iOS wants more memory. 
      Release as much memory as possible. 
     */ 
     return 0; 
    case SDL_APP_WILLENTERBACKGROUND: 
     /* Prepare your app to go into the background. Stop loops, etc. 
      This gets called when the user hits the home button, or gets a call. 
     */ 
     return 0; 
    case SDL_APP_DIDENTERBACKGROUND: 
     /* This will get called if the user accepted whatever sent your app to the background. 
      If the user got a phone call and canceled it, you'll instead get an SDL_APP_DIDENTERFOREGROUND event and restart your loops. 
      When you get this, you have 5 seconds to save all your state or the app will be terminated. 
      Your app is NOT active at this point. 
     */ 
     return 0; 
    case SDL_APP_WILLENTERFOREGROUND: 
     /* This call happens when your app is coming back to the foreground. 
      Restore all your state here. 
     */ 
     return 0; 
    case SDL_APP_DIDENTERFOREGROUND: 
     /* Restart your loops here. 
      Your app is interactive and getting CPU again. 
     */ 
     return 0; 
    default: 
     /* No special processing, add it to the event queue */ 
     return 1; 
    } 
} 

int main(int argc, char *argv[]) 
{ 
    SDL_SetEventFilter(HandleAppEvents, NULL); 

    //... run your main loop 

    return 0; 
} 

Tôi có một số câu hỏi về mã này.

SDL_SetEventFilter() làm gì? Tôi đọc trang SDL Wiki, và nó có vẻ đặc biệt mơ hồ.

Trong thực tế, hàm HandleAppEvents() hoạt động như thế nào? Ví dụ, nếu tôi có mã như thế này:

int main(int argc, char* argv[]) 
{ 
    //Initialize SDL, etc... 
    SDL_SetEventFilter(HandleAppEvents, NULL); 


    //I've got some SDL_Textures and windows and things... 
    SDL_Window* my_window; 
    SDL_Renderer* windowrend; 
    SDL_Texture* tex1, tex2, tex3; 

    //Primitive game loop 
    while(game_is_running){ 
     handle_input(); 
     do_logic(); 
     update_screen(); 
    } 

    destroy_all_my_data(); 
    SDL_Quit(); 
    return 0; 
} 

Những loại mã nên được đặt trong HandleAppEvents() hoặc main() để tiêu diệt bộ nhớ hoặc ngừng vòng lặp trò chơi của tôi khi tôi nhận được một SDL_APP_WILLENTERBACKGROUND, ví dụ?

Giả sử tex2 có thể sử dụng được và có thể bị xóa nếu ứng dụng nhận được SDL_APP_LOWMEMORY. Làm thế nào tôi sẽ xóa tex2 từ HandleAppEvents() mà không gây rối với các dữ liệu khác?

Có gì trong con trỏ userdata?

Khi ứng dụng của tôi vào nền, tôi có nên chuyển họa tiết của mình thành các bề mặt và lưu chúng trong thư mục ../tmp/ dưới dạng bmps hoặc chúng vẫn còn trong bộ nhớ khi ứng dụng quay lại nền trước không?

Tôi hy vọng các câu hỏi khó hiểu của tôi sẽ mang lại một số ý nghĩa. Nếu có một nơi tôi có thể tìm thấy một tài liệu kỹ lưỡng cho SDL2, nó sẽ là tuyệt vời để biết.

Cảm ơn bạn đã xem!

Trả lời

5

SDL_SetEventFilter là một cách để "tiến lên" hàng đợi sự kiện của SDL. Bạn về cơ bản nhận được các sự kiện khi họ nhận được, trước khi họ nhận được đặt trong hàng đợi, và trong trường hợp iOS bạn phải phản ứng với họ ngay lập tức. Lý do kỹ thuật đằng sau việc này là đối với các loại thư này, iOS sử dụng một loạt các cuộc gọi lại, mà SDL nhận và kết thúc tốt đẹp cho bạn để làm cho trải nghiệm nền tảng liền mạch nhất có thể, nhưng thực tế vẫn là iOS. vẫn mong bạn hành động với họ trước khi trở về từ cuộc gọi lại. Vì vậy, ví dụ, nếu chúng ta chỉ cần đặt thông báo rằng hệ thống là thấp trên bộ nhớ trên hàng đợi thay vì chuyển nó trực tiếp đến ứng dụng thông qua cơ chế này, và bạn chỉ cần làm gì cho đến khi sự kiện đó đi qua hàng đợi, bạn bỏ phiếu, v.v., iOS có thể đóng ứng dụng của bạn một cách mạnh mẽ bởi vì nó không hoạt động như mong đợi.

Khi ứng dụng chuyển sang nền, bạn không cần lưu họa tiết của mình. iOS làm điều đó cho bạn, và nếu nó không có đủ bộ nhớ để làm như vậy nó chỉ giết chết ứng dụng của bạn (bạn không bao giờ mất bối cảnh GL ES/ES2, đó là một cái gì đó có thể xảy ra trên một số thiết bị Android).

Con trỏ userdata sẽ chứa dữ liệu bạn chuyển làm tham số thứ hai cho SDL_SetEventFilter, vì vậy nếu bạn sử dụng SDL_SetEventFilter (HandleAppEvents, NULL), userdata sẽ là NULL.

Trên SDL_APP_WILLENTERBACKGROUND, nếu tôi nhớ chính xác, bạn không phải làm gì cả.Tôi đã không khởi động ứng dụng iOS của mình trong một thời gian, nhưng tôi nghĩ SDL xử lý tất cả trạng thái nội bộ của nó (bao gồm cả chặn vòng lặp sự kiện và sau đó khởi động lại nó) một mình. Các sự kiện bạn phải tự xử lý là SDL_APP_LOWMEMORY và SDL_APP_TERMINATING, cách bạn xử lý đó là ứng dụng cụ thể (xóa kết cấu, bộ nhớ miễn phí, v.v., nó vượt quá SDL cụ thể)

+0

+1 Đối với một câu trả lời rất có nhiều thông tin. Tôi thực sự muốn nhìn thấy một chút mã để giải thích ý của bạn, nếu bạn có thời gian! – BrainSteel

+0

Tôi không nghĩ rằng một ví dụ mã áp dụng trong trường hợp này khi bạn hỏi hầu hết các câu hỏi "triết học" và mã nào sẽ hữu ích trong phần ứng dụng cụ thể (SDL_APP_LOWMEMORY, v.v ...) nhưng tôi không có Ví dụ để đưa ra ở đó, nó có thể liên quan đến việc giải phóng tài nguyên và theo dõi chúng để tạo lại chúng khi cần thiết. Nhưng nếu bạn muốn làm rõ câu trả lời, hãy hỏi đi! – gabomdq

+0

Được rồi, tôi hiểu ý của bạn là gì. Tôi sẽ cập nhật câu hỏi với mã sau và hy vọng tôi có thể hiểu rõ hơn về chủ đề thông qua phản hồi của bạn. – BrainSteel

1

Vì nó xuất hiện từ this thread bạn phải dừng vòng lặp trò chơi trên SDL_APP_WILLENTERBACKGROUND và tiếp tục trên SDL_APP_WILLENTERFOREGROUND để tránh sự cố.