# Promise-based WebGL Interop System

This directory contains the new promise-based interop system for Unity WebGL that provides a cleaner, more maintainable approach to C#-JavaScript communication.

## Files

- `WebGLInterop.cs` - C# interop utility class
- `WebGLInterop.jslib` - JavaScript interop library
- `MIGRATION_GUIDE.md` - Guide for migrating from the old approach
- `README.md` - This file

## Quick Start

### 1. Basic Usage

```csharp
using Arkadium.Interop;

// Invoke a JavaScript method and get a result
var result = await WebGLInterop.InvokeAsync<string>("wallet.getGems");
Debug.Log($"Gems: {result}");

// Invoke a method with parameters
var success = await WebGLInterop.InvokeAsync<bool>("wallet.consumeGems", new { value = 100 });

// Invoke a void method
WebGLInterop.InvokeVoid("lifecycle.onGameStart");
```

### 2. Create an API Class

```csharp
public class ArkadiumWalletV2
{
    public async Task<bool> IsGemsSupportedAsync()
    {
        var result = await WebGLInterop.InvokeAsync<string>("wallet.isGemsSupported");
        return result.ToLower() == "true";
    }

    public async Task<int> GetGemsAsync()
    {
        var result = await WebGLInterop.InvokeAsync<string>("wallet.getGems");
        return int.TryParse(result, out var gems) ? gems : 0;
    }

    public async Task<bool> ConsumeGemsAsync(int value)
    {
        var result = await WebGLInterop.InvokeAsync<string>("wallet.consumeGems", new { value });
        return result.ToLower() == "true";
    }
}
```

### 3. Use in Your Code

```csharp
public class GameManager : MonoBehaviour
{
    private ArkadiumWalletV2 _wallet = new ArkadiumWalletV2();

    private async void Start()
    {
        try
        {
            var isSupported = await _wallet.IsGemsSupportedAsync();
            if (isSupported)
            {
                var gems = await _wallet.GetGemsAsync();
                Debug.Log($"Player has {gems} gems");
            }
        }
        catch (Exception ex)
        {
            Debug.LogError($"Error: {ex.Message}");
        }
    }
}
```

## Features

### ✅ Async/Await Support
Write clean, readable code without callback hell.

### ✅ Automatic Memory Management
No need to manually clean up callbacks or manage static fields.

### ✅ Better Error Handling
Use try/catch blocks for natural error handling.

### ✅ Type Safety
Generic methods provide compile-time type checking.

### ✅ Reduced Boilerplate
Single interop layer handles all API calls.

### ✅ Backward Compatibility
Legacy callback methods can coexist with new async methods.

## How It Works

### 1. C# Side (`WebGLInterop.cs`)
- Manages task completion sources for async operations
- Handles parameter serialization to JSON
- Provides type conversion utilities
- Manages memory automatically

### 2. JavaScript Side (`WebGLInterop.jslib`)
- Receives method calls and parameters
- Dynamically invokes methods on the Arkadium API
- Returns results through callbacks
- Handles errors gracefully

### 3. Method Resolution
The system uses dot notation to resolve methods:
- `"wallet.getGems"` → `arkSt.api.wallet.getGems()`
- `"ads.showAd"` → `arkSt.api.ads.showAd()`

## Error Handling

```csharp
try
{
    var result = await WebGLInterop.InvokeAsync<string>("wallet.getGems");
    Debug.Log($"Success: {result}");
}
catch (Exception ex)
{
    Debug.LogError($"Failed: {ex.Message}");
    // Handle error gracefully
}
```

## Performance Considerations

- **Memory**: Tasks are automatically cleaned up when completed
- **Threading**: All operations run on the main thread (Unity requirement)
- **Serialization**: JSON serialization is used for parameters (minimal overhead)
- **Caching**: No caching is implemented - each call is a fresh interop

## Limitations

- **WebGL Only**: This system only works in WebGL builds
- **Main Thread**: All operations must run on the main thread
- **JSON Serialization**: Complex objects are serialized to JSON
- **Error Propagation**: JavaScript errors are converted to C# exceptions

## Testing

Use the `WalletExample.cs` script in the Examples folder to test the system:

1. Attach the script to a GameObject
2. Run the scene
3. Check the console for examples
4. Test both async/await and callback approaches

## Migration

See `MIGRATION_GUIDE.md` for detailed instructions on migrating from the old callback-based approach.

## Troubleshooting

### Common Issues

1. **Task never completes**: Check that the JavaScript method exists and returns a promise
2. **Type conversion errors**: Ensure the return type matches the JavaScript method's return value
3. **Method not found**: Verify the method path (e.g., "wallet.getGems") matches the API structure

### Debug Tips

1. Enable Unity's WebGL logging to see interop calls
2. Check the browser console for JavaScript errors
3. Use try/catch blocks to handle errors gracefully
4. Test in both editor and WebGL builds

## Future Enhancements

- **Code Generation**: Automatically generate interop code from API definitions
- **Caching**: Cache frequently used method lookups
- **Batch Operations**: Support for multiple operations in a single call
- **Type Validation**: Runtime type checking for parameters and return values 