Skip to content

Instantly share code, notes, and snippets.

@ruccho
Created November 23, 2020 23:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ruccho/717fac0755212ba791d287d6c127f0b9 to your computer and use it in GitHub Desktop.
Save ruccho/717fac0755212ba791d287d6c127f0b9 to your computer and use it in GitHub Desktop.
using System;
using System.Collections.Generic;
using UnityEngine;
namespace Ruccho.Utilities
{
public class LockerSubject
{
public bool IsLocked => Keys.Count > 0;
private List<object> Keys { get; } = new List<object>();
private Action OnLocked { get; }
private Action OnUnlocked { get; }
public LockerSubject(Action onLocked, Action onUnlocked)
{
OnLocked = onLocked;
OnUnlocked = onUnlocked;
}
public LockerSession Lock()
{
var session = new LockerSession(this);
Lock(session);
return session;
}
public void Lock(object key)
{
bool old = IsLocked;
if (Keys.Contains(key))
{
Debug.LogWarning($"LockerSubject: This key ({key}) is already registered.");
}
else
{
Keys.Add(key);
}
if (old != IsLocked) OnLocked?.Invoke();
}
public void Unlock(object key)
{
bool old = IsLocked;
if (!Keys.Contains(key))
{
Debug.LogWarning($"LockerSubject: This key ({key}) is not registered.");
}
else
{
Keys.Remove(key);
}
if (old != IsLocked) OnUnlocked?.Invoke();
}
}
public class LockerSession : IDisposable
{
private LockerSubject subject;
private bool isDisposed = false;
public LockerSession(LockerSubject subject)
{
this.subject = subject;
}
public void Dispose()
{
if (isDisposed) return;
isDisposed = true;
subject.Unlock(this);
}
}
}
using UnityEngine;
namespace Ruccho.Utilities
{
public class LockerSubjectSample : MonoBehaviour
{
void Start()
{
Test();
}
private void Test()
{
var subject = new LockerSubject(OnLocked, OnUnlocked);
Debug.Log("Lock by \"A\"");
subject.Lock("A");
//Output: LockerSubject has been locked.
Debug.Log("Lock by \"B\"");
subject.Lock("B");
Debug.Log("Unlock by \"A\"");
subject.Unlock("A");
Debug.Log("Unlock by \"B\"");
subject.Unlock("B");
//Output: LockerSubject has been unlocked.
Debug.Log("Lock with using statement");
using (subject.Lock())
{
//Output: LockerSubject has been locked.
Debug.Log("~~ in using statement ~~");
}
//Output: LockerSubject has been unlocked.
}
private void OnLocked() => Debug.Log("LockerSubject has been locked.");
private void OnUnlocked() => Debug.Log("LockerSubject has been unlocked.");
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment