Callback Functions
1. Overview
WebGLHost C++ SDK uses callback function mechanisms to notify host applications of asynchronous events and operation results. All callback function types are defined in the IAppletManagerV3.h header file.
2. Callback Function Types
2.1 LaunchCallback - Game Launch Callback
Called when the game launch operation completes, notifying the host application of the launch result.
Type Definition
typedef void (*LaunchCallback)(
const char* app_id,
int result_code,
const char* error_desc
);
Parameter Description
| Parameter | Type | Description |
|---|---|---|
app_id | const char* | Game ID |
result_code | int | Result code (0 for success, non-zero for failure) |
error_desc | const char* | Error description string (empty or nullptr on success) |
Call Timing
- After game launch succeeds
- When game launch fails
- After game resources finish loading
Code Example
void OnGameLaunched(const char* app_id, int result_code, const char* error_desc) {
std::cout << "=== Game Launch Callback ===" << std::endl;
std::cout << "App ID: " << app_id << std::endl;
std::cout << "Result Code: " << result_code << std::endl;
if (result_code == WMPF_ERRCODE_SUCCESS) {
std::cout << "Game launched successfully!" << std::endl;
// Continue with game interaction
} else {
std::cerr << "Game launch failed!" << std::endl;
if (error_desc && strlen(error_desc) > 0) {
std::cerr << "Error: " << error_desc << std::endl;
}
// Handle error (e.g., show error message to user)
}
}
// Usage
appletMgr->LaunchApplet(appId, launchConfig, strlen(launchConfig), OnGameLaunched);
2.2 JsApiHandler - JsApi Call Handler
Handles JsApi call requests initiated by games.
Type Definition
typedef bool (*JsApiHandler)(
const char* app_id,
const char* api_name,
const char* data,
size_t data_size,
int task_id
);
Parameter Description
| Parameter | Type | Description |
|---|---|---|
app_id | const char* | Game ID that initiated the call |
api_name | const char* | API name |
data | const char* | API request data (JSON format) |
data_size | size_t | Data size (bytes) |
task_id | int | Task ID, used to send response |
Return Value
true: API call processed successfullyfalse: API call processing failed
Call Timing
- When the game calls a JsApi
- When functionality requiring host implementation is needed
Common JsApis
| API Name | Description | Request Data |
|---|---|---|
TJLoginHost | Unity Connect authentication | {"accessToken": "..."} |
loadRewardAd | Load reward ad | {"adUnitId": "..."} |
showRewardAd | Show reward ad | {} |
Code Example
bool OnJsApiCall(
const char* app_id,
const char* api_name,
const char* data,
size_t data_size,
int task_id
) {
std::cout << "[JsApi] " << api_name << " from " << app_id << std::endl;
std::string requestData(data, data_size);
// Handle TJLoginHost - Unity Connect authentication
if (strcmp(api_name, "TJLoginHost") == 0) {
// Extract accessToken from request data
// Perform authentication with Unity Connect API
// ...
// Send success response
const char* response = R"({"success":true,"result":{"code":"auth_code_here"}})";
g_appletMgr->SendJsApiOrEventResponse(task_id, response, strlen(response));
return true;
}
// API not handled
std::cout << "[JsApi] Unknown API: " << api_name << std::endl;
const char* response = R"({"success":false,"errorCode":"NOT_HANDLED","error":"API not implemented"})";
g_appletMgr->SendJsApiOrEventResponse(task_id, response, strlen(response));
return false;
}
// Register handler
appletMgr->SetJsApiHandler(OnJsApiCall);
For a complete JsApi handler implementation, please refer to the demo_handlers.cpp file in the Demo Project.
2.3 EventHandler - Game Event Handler
Handles event notifications sent by games.
Type Definition
typedef bool (*EventHandler)(
const char* event_name,
const char* data,
size_t data_size,
int task_id
);
Parameter Description
| Parameter | Type | Description |
|---|---|---|
event_name | const char* | Event name |
data | const char* | Event data (JSON format) |
data_size | size_t | Data size (bytes) |
task_id | int | Task ID (for response if needed) |
Return Value
true: Event processed successfullyfalse: Event processing failed
Common Events
game_exited: Game exit notification
Code Example
bool OnGameEvent(
const char* event_name,
const char* data,
size_t data_size,
int task_id
) {
std::cout << "=== Game Event ===" << std::endl;
std::cout << "Event: " << event_name << std::endl;
if (data && data_size > 0) {
std::string eventData(data, data_size);
std::cout << "Data: " << eventData << std::endl;
}
// Handle game exit event
if (strcmp(event_name, "game_exited") == 0) {
std::cout << "Game exited" << std::endl;
// Perform cleanup, exit application, etc.
return true;
}
return true;
}
// Register handler
appletMgr->SetAppletEventHandler(OnGameEvent);
3. Thread Safety
Important: All callback functions may execute in different threads; thread safety must be ensured.
- Use
std::mutexto protect shared data - Consider using an event queue to pass callback data to the main thread for processing
- Avoid time-consuming operations in callbacks
4. Best Practices
4.1 Quick Return
// Good: Quick processing
bool OnJsApiCall(...) {
// Quick validation
if (!ValidateRequest(data)) {
SendError(task_id);
return false;
}
// Queue for async processing
QueueApiRequest(api_name, data, task_id);
return true;
}
// Bad: Blocking operation
bool OnJsApiCall(...) {
// DON'T DO THIS - blocks SDK thread
DownloadLargeFile(); // Slow!
ProcessHeavyComputation(); // Slow!
return true;
}
4.2 Error Handling
bool OnJsApiCall(...) {
try {
ProcessApi(api_name, data);
return true;
} catch (const std::exception& e) {
std::cerr << "API error: " << e.what() << std::endl;
SendError(task_id, e.what());
return false;
}
}
4.3 Memory Management
bool OnJsApiCall(const char* app_id, const char* api_name,
const char* data, size_t data_size, int task_id) {
// Good: Copy data if needed beyond callback scope
std::string dataCopy(data, data_size);
// Bad: Storing pointer (data may become invalid)
// const char* storedData = data; // DON'T DO THIS
// Process with copied data
ProcessAsync(dataCopy, task_id);
return true;
}
5. Important Notes
- Thread Safety: Callbacks may execute in different threads; use appropriate synchronization mechanisms
- Quick Return: Don't perform time-consuming operations in callbacks
- Data Lifecycle: Don't use passed pointer parameters outside the callback
- Exception Handling: Catch all exceptions; don't let exceptions propagate to the SDK
- Timely Response: Respond promptly after handling JsApi and events