# Event Examples

## Events - Action/Delegates

### Synchronous - Normal way of doing events

```csharp
using System;
using UnityEngine;
using VivoxUnity;

public class NormalEvents : MonoBehaviour
{
    public event Action<ILoginSession> LoggingIn;

    void Start()
    {
        LoggingIn += PlayerLoggingIn;
    }
    private void OnApplicationQuit()
    {
        LoggingIn -= PlayerLoggingIn;
    }

    public void PlayerLoggingIn(ILoginSession loginSession)
    {
        Debug.Log($"Invoking Normal Event from {nameof(PlayerLoggingIn)}");
    }
}

```

### Synchronous - Easy Code way of doing events

Read more about <mark style="color:blue;">**\[Inject]**</mark> attribute and[ Method Injection here](https://fullstackindie.gitbook.io/easy-code-for-vivox/dependency-injection/inject-classes#method-injection)

```csharp
internal class EasyCodeEvents : MonoBehaviour
{
    private EasyEvents _events;

    [Inject]
    private void Initialize(EasyEvents events)
    {
        _events = events;
    }

    public void AddEvent()
    {
        _events.LoggedIn += OnLoggedIn;
    }

    public void RemoveEvent()
    {
        _events.LoggedIn -= OnLoggedIn;
    }

    private void OnLoggedIn(ILoginSession loginSession)
    {
        Debug.Log($"User {loginSession.LoginSessionId.DisplayName} has logged in");
    }
}
```

## Easy Code Dynamic Events

Don't want to Subscribe and Unsubscribe from events or use Zenject dependency injection. Use Dynamic events instead. They are a tad bit slower in some cases but events are fire and forget and aren't called in Unity's **`Update()`** loop, so you really can't tell the difference until you have hundreds of game objects firing events.&#x20;

Vivox events arent fired that often so unless you are updating hundreds of gameobejcts based on a players's name or login status you should be fine to use Dynamic Events.

{% hint style="warning" %}
Remember to use <mark style="color:blue;">async void</mark> or <mark style="color:blue;">async Task</mark> when using **Dynamic Async events**
{% endhint %}

### Synchronous - Dynamic Events

```csharp
public class DynamicAsyncEvents : MonoBehaviour
{
    [LoginEvent(LoginStatus.LoggingIn)]
    public void LoginCallback(ILoginSession loginSession)
    {
        Debug.Log($"Invoking Async Event Dynamically from {nameof(LoginCallback)}");
    }

    [LoginEvent(LoginStatus.LoggedIn)]
    public void OnLoggedIn(ILoginSession loginSession)
    {
        await Task.Run(() =>
        {
            for (int i = 0; i < 100; i++)
            {
                Debug.Log($"Method Event has been invoked dynamically");
            }
        });
    }
    
}
```

### Asynchronous - Dynamic Async Events

{% hint style="danger" %}
**Reminder&#x20;**<mark style="color:red;">**not to use**</mark>**&#x20;Dynamic Async Events that** <mark style="color:red;">**modify the UI or GameObjects in Scene .**</mark>&#x20;
{% endhint %}

```csharp
public class DynamicAsyncEvents : MonoBehaviour
{
    [LoginEventAsync(LoginStatus.LoggedIn)]
    public async void DynamicEventAsyncVoid(ILoginSession loginSession)
    {
        var bytes = Encoding.Unicode.GetBytes(loginSession.LoginSessionId.DisplayName);
        using (FileStream fileStream = new FileStream($"{Directory.GetCurrentDirectory()}\\Assets\\playerName.txt", FileMode.Create, FileAccess.Write, FileShare.ReadWrite, bufferSize: 4096, useAsync: true))
        {
            await fileStream.WriteAsync(bytes, 0, bytes.Length);
        }
        Debug.Log("Done creating text file");
    }

    [LoginEventAsync(LoginStatus.LoggedIn)]
    public async Task AsyncMethod(ILoginSession loginSession)
    {
        await Task.Run(() =>
        {
            for (int i = 0; i < 100; i++)
            {
                Debug.Log($"Async Method Event has been invoked");
            }
        });
    }
}
```

##
