com.ges.tinyreactive
1.3.13
dotnet add package com.ges.tinyreactive --version 1.3.13
NuGet\Install-Package com.ges.tinyreactive -Version 1.3.13
<PackageReference Include="com.ges.tinyreactive" Version="1.3.13" />
<PackageVersion Include="com.ges.tinyreactive" Version="1.3.13" />
<PackageReference Include="com.ges.tinyreactive" />
paket add com.ges.tinyreactive --version 1.3.13
#r "nuget: com.ges.tinyreactive, 1.3.13"
#:package com.ges.tinyreactive@1.3.13
#addin nuget:?package=com.ges.tinyreactive&version=1.3.13
#tool nuget:?package=com.ges.tinyreactive&version=1.3.13
TinyReactive
A lightweight reactive programming library for C#, optimized for use in Unity and other .NET environments. It provides a convenient toolkit for working with reactive data and events.
Key Features:
- Notification of all subscribers when data changes
- Use of the
Unloadcollection for automatic unsubscribe and prevention of memory leaks - Support for passing
unmanageddata by reference - Serialization to a base data format
Table of Contents
Installation
You should replace the "1.0.0" version shown in the examples with the current or available version!
Unity (OpenUPM or TGZ)
This package is available on OpenUPM for Unity.
Project/Packages/manifest.json:
{
"dependencies": {
"com.ges.tinyreactive": "1.0.0"
},
"scopedRegistries": [
{
"name": "package.openupm.com",
"url": "https://package.openupm.com",
"scopes": [
"com.ges"
]
}
]
}
It is also available in .tgz format in the current releases.
After downloading, place the .tgz archive in your project's Packages folder, and add a reference to it in your manifest.json file.
Project/Packages/manifest.json:
{
"dependencies": {
"com.ges.tinyreactive": "file:com.ges.tinyreactive-1.0.0.tgz"
}
}
NuGet - Without Unity dependency
To install from NuGet, there is a library without a Unity dependency.
<PackageReference Include="com.ges.tinyreactive" Version="1.0.0" />
Usage
Observed<T>
Allows tracking changes to a T value.
// Create Observed field
Observed<int> counter = new Observed<int>(100);
// Add listeners
counter.AddListener(ListenValue);
counter.AddListener(ListenValueChange);
counter.AddListener(ListenChange);
// Get current value
Console.WriteLine($"Counter current value: {counter.value}");
// Change value
counter.Set(90);
// Will be ignored because the current value is already 90
counter.TrySet(90);
// Change value without invoke listeners
counter.SetSilent(60);
// Remove listeners
counter.RemoveListener(ListenValue);
counter.RemoveListener(ListenValueChange);
counter.RemoveListener(ListenChange);
// Change value without any listeners
counter.Set(0);
// Listen value change
void ListenValue(int newValue) {
Console.WriteLine($"Counter changed: {newValue}");
}
// Listen value change with current value
void ListenValueChange(int currentValue, int newValue) {
Console.WriteLine($"Counter changed: from {currentValue} to {newValue}");
}
// Listen any value change
void ListenChange() {
Console.WriteLine("Counter changed");
}
Counter current value: 100
Counter changed: 90
Counter changed: from 100 to 90
Counter changed
InputListener and InputListener<T>
A trackable event without storing the current value.
// Create InputListener field
InputListener inputEvent = new InputListener();
// Add listeners
inputEvent.AddListener(ListenChange);
// Send event
inputEvent.Send();
// Remove listeners
inputEvent.RemoveListener(ListenChange);
// Listen any change
void ListenChange() {
Console.WriteLine("Input Event");
}
Input Event
Variants with additional parameters are also available.
// Create InputListener field
InputListener<int> inputEvent = new InputListener<int>();
// Add listeners
inputEvent.AddListener(ListenValue);
inputEvent.AddListener(ListenChange);
// Send event
inputEvent.Send(10);
// Remove listeners
inputEvent.RemoveListener(ListenValue);
inputEvent.RemoveListener(ListenChange);
// Listen value change
void ListenValue(int newValue) {
Console.WriteLine($"Input Event: {newValue}");
}
// Listen any change
void ListenChange() {
Console.WriteLine("Input Event");
}
Input Event: 10
Input Event
InputChanger<T>
Exists for tracking and modifying unmanaged values.
// Create InputChanger field
InputChanger<int> changeEvent = new InputChanger<int>();
// Add listeners
changeEvent.AddListener(ValueModify);
// Change value
int currentValue = 100;
changeEvent.Send(ref currentValue);
Console.WriteLine($"Changed first: {currentValue}");
// Remove listeners
changeEvent.RemoveListener(ValueModify);
// Change value without any listeners
changeEvent.Send(ref currentValue);
Console.WriteLine($"Changed second: {currentValue}");
// Listen value change
void ValueModify(ref int value) {
value += 10;
}
Changed first: 110
Changed second: 110
ObservedList<T>
Tracks the addition and removal of values in a List<T>, as well as its clearing.
// Create ObservedList field
ObservedList<int> values = new ObservedList<int>();
// Add listeners
values.AddOnAddListener(OnValueAdd);
values.AddOnRemoveListener(OnValueRemove);
// Change values
values.Add(15);
values.Add(25);
values.Remove(15);
values.Add(40);
Console.WriteLine($"Current values: {values.Count}");
foreach(int item in values) {
Console.WriteLine($"Value: {item}");
}
// Remove listeners
values.RemoveOnAddListener(OnValueAdd);
values.RemoveOnRemoveListener(OnValueRemove);
// Listen value add
void OnValueAdd(int value) {
Console.WriteLine($"Added: {value}");
}
// Listen value add
void OnValueRemove(int value) {
Console.WriteLine($"Removed: {value}");
}
Added: 15
Added: 25
Removed: 15
Added: 40
Current values: 2
Value: 25
Value: 40
ObservedDictionary<TKey, TValue>
Tracks the addition and removal of values in a Dictionary<TKey, TValue>.
// Create ObservedDictionary field
ObservedDictionary<string, int> values = new ObservedDictionary<string, int>();
// Add listeners
values.AddOnAddListener(OnValueAdd);
values.AddOnRemoveListener(OnValueRemove);
// Change values
values.Add("Key1", 15);
values.Add("Key2", 25);
values.Add("Key3", 35);
values.Remove("Key1");
values["Key2"] = 40; // Triggers Remove for old value, then Add for new
// Get values by key
if (values.TryGetValue("Key2", out int foundValue)) {
Console.WriteLine($"Found: {foundValue}");
}
// Batch remove by values
values.RemoveRange(new List<int> { 40 });
Console.WriteLine($"Current values: {values.Count}");
foreach(KeyValuePair<string, int> item in values) {
Console.WriteLine($"Pair: {item.Key}:{item.Value}");
}
// Remove listeners
values.RemoveOnAddListener(OnValueAdd);
values.RemoveOnRemoveListener(OnValueRemove);
// Listen value add
void OnValueAdd(int value) {
Console.WriteLine($"Added: {value}");
}
// Listen value remove
void OnValueRemove(int value) {
Console.WriteLine($"Removed: {value}");
}
Added: 15
Added: 25
Added: 35
Removed: 15
Removed: 25
Added: 40
Found: 40
Removed: 40
Current values: 1
Pair: Key3:35
Tracking a specific type of value.
// Create ObservedDictionary field
ObservedDictionary<string, object> values = new ObservedDictionary<string, object>();
UnloadPool unload = new UnloadPool();
// Add listeners
values.AddOnAddListenerValue<int>(OnIntValueAdd, unload);
values.AddOnAddListenerValue<string>(OnStringValueAdd, unload);
// Change values
values.Add("Key1", 15);
values.Add("Key2", "Hello");
values.Add("Key3", "World");
values.Add("Key4", true);
Console.WriteLine($"Current values: {values.Count}");
// Remove listeners
unload.Unload();
// Listen value add, with type-specific filter
void OnIntValueAdd(int value) {
Console.WriteLine($"Int added: {value}");
}
// Listen value add, with type-specific filter
void OnStringValueAdd(string value) {
Console.WriteLine($"String added: {value}");
}
Int added: 15
String added: Hello
String added: World
Current values: 4
Serialization
The Observed<T> and ObservedList<T> classes
have built-in converters to the base type T and List<T> respectively.
Implemented via System.Text.Json.
The serialization code is located in ObservedJsonConverter
and ObservedListJsonConverter.
Tools and Extensions
...
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.1 is compatible. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.1
- com.ges.tinyutilities (>= 1.3.16)
- System.Text.Json (>= 10.0.9)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.