Skip to content

Commit

Permalink
Merge branch 'dev'
Browse files Browse the repository at this point in the history
  • Loading branch information
ChanyaVRC committed Feb 25, 2022
2 parents 01a64a7 + 67477ba commit ba1e003
Show file tree
Hide file tree
Showing 24 changed files with 433 additions and 125 deletions.
2 changes: 1 addition & 1 deletion Sample/GuiController/MainWindow.xaml.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using System.Windows;
using System.Windows.Input;
using BuildSoft.VRChat.Osc;

using BuildSoft.VRChat.Osc.Input;

namespace GuiController;

Expand Down
30 changes: 19 additions & 11 deletions Sample/LogAvatarParametars/Program.cs
Original file line number Diff line number Diff line change
@@ -1,18 +1,26 @@
using BuildSoft.VRChat.Osc;

OscUtility.Initialize();
using BuildSoft.VRChat.Osc.Avatar;

OscAvatarConfig? avatarConfig = null;

Console.WriteLine("Reading now... Try to \"Reset Avatar.\"");
Console.WriteLine($"[NOTIFICATION] Reading now... Try to \"Reset Avatar.\"");
avatarConfig = await OscAvatarConfig.WaitAndCreateCurrentOscAvatarConfigAsync();
Console.WriteLine($"Read avatar config. Name: {avatarConfig.Name}");
Console.WriteLine($"[NOTIFICATION] Read avatar config. Name: {avatarConfig.Name}");

OscAvatarParameterChangedEventHandler? handler = (parameter, e) =>
{
DateTime now = DateTime.Now;
Console.WriteLine($"[{now.ToShortDateString()} {now.ToShortTimeString()}] " +
$"{parameter.Name}: {e.OldValue} => {e.NewValue}");
};
OscAvatarUtility.AvatarChanged += (sender, e) =>
{
avatarConfig.Parameters.ParameterChanged -= handler;

avatarConfig = OscAvatarConfig.CreateCurrentOscAvatarConfig()!;
Console.WriteLine($"[NOTIFICATION] Changed avatar. Name: {avatarConfig.Name}");

avatarConfig.Parameters.ParameterChanged += (parameter, e) =>
{
DateTime now = DateTime.Now;
Console.WriteLine($"[{now.ToShortDateString()} {now.ToShortTimeString()}] " +
$"{parameter.Name}: {e.OldValue} => {e.NewValue}");
};
avatarConfig.Parameters.ParameterChanged += handler;
};
avatarConfig.Parameters.ParameterChanged += handler;

await Task.Delay(-1);
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
namespace BuildSoft.VRChat.Osc.Avatar;

public delegate void OscAvatarParameterChangedEventHandler(OscAvatarParameter parameter, ValueChangedEventArgs e);
2 changes: 1 addition & 1 deletion src/vrcosclib/Avatar/OscAvatar.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace BuildSoft.VRChat.Osc;
namespace BuildSoft.VRChat.Osc.Avatar;

public struct OscAvatar
{
Expand Down
8 changes: 4 additions & 4 deletions src/vrcosclib/Avatar/OscAvatarConfig.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using Newtonsoft.Json;

namespace BuildSoft.VRChat.Osc;
namespace BuildSoft.VRChat.Osc.Avatar;

public class OscAvatarConfig
{
Expand All @@ -19,12 +19,12 @@ public class OscAvatarConfig
public string Name => _name;

[JsonIgnore]
private OscAvatarParametorContainer? _paramaters;
private OscAvatarParametorContainer? _parameters;
[JsonIgnore]
public OscAvatarParametorContainer Parameters
=> _paramaters ??= new OscAvatarParametorContainer(_parametersList);
=> _parameters ??= new OscAvatarParametorContainer(_parametersList);

internal bool IsCreatedParameters => _paramaters != null;
internal bool IsCreatedParameters => _parameters != null;

[field: JsonExtensionData]
public Dictionary<string, object> Extra { get; } = new();
Expand Down
8 changes: 7 additions & 1 deletion src/vrcosclib/Avatar/OscAvatarParameter.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using Newtonsoft.Json;

namespace BuildSoft.VRChat.Osc;
namespace BuildSoft.VRChat.Osc.Avatar;

[JsonObject]
public record class OscAvatarParameter
Expand All @@ -18,12 +18,18 @@ public record class OscAvatarParameter
public OscAvatarParameterInterface? Input => _input;
public OscAvatarParameterInterface? Output => _output;

public string ReadableAddress => (Output ?? Input)!.Address;

public OscAvatarParameter()
{

}
public OscAvatarParameter(string name, OscAvatarParameterInterface? input = null, OscAvatarParameterInterface? output = null)
{
if (input == null && output == null)
{
throw new ArgumentException();
}
_name = name;
_input = input;
_output = output;
Expand Down
4 changes: 0 additions & 4 deletions src/vrcosclib/Avatar/OscAvatarParameterChangedEventHandler.cs

This file was deleted.

3 changes: 1 addition & 2 deletions src/vrcosclib/Avatar/OscAvatarParameterInterface.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using BlobHandles;
using Newtonsoft.Json;

namespace BuildSoft.VRChat.Osc;
namespace BuildSoft.VRChat.Osc.Avatar;

[JsonObject]
public class OscAvatarParameterInterface
Expand All @@ -28,5 +28,4 @@ public BlobString AddressBlob
}

public string Type => _type;

}
76 changes: 33 additions & 43 deletions src/vrcosclib/Avatar/OscAvatarParametorContainer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,24 @@
using BlobHandles;
using BuildSoft.OscCore;

namespace BuildSoft.VRChat.Osc;
namespace BuildSoft.VRChat.Osc.Avatar;

public class OscAvatarParametorContainer : IReadOnlyDictionary<string, object?>
{
#region Static methods(s)
/// <summary>
/// Call initializer of dependencies.
/// </summary>
internal static void Initialize()
{
}

/// <summary>
/// Initialize static members.
/// </summary>
static OscAvatarParametorContainer()
{
OscParameter.Initialize();
}
#endregion

Expand All @@ -21,25 +31,14 @@ public OscAvatarParametorContainer(ImmutableArray<OscAvatarParameter> parameters
{
Parameters = parameters;

var uniqueParamsBuilder = ImmutableDictionary.CreateBuilder<BlobString, OscAvatarParameter>();
var uniqueParamValues = new Dictionary<string, object?>();
var allParams = OscParameter.Parameters;
for (int i = 0; i < parameters.Length; i++)
{
var param = parameters[i];
if (OscAvatarUtility.IsCommonParameter(param.Name))
{
continue;
}

var outputInterface = param.Output;
Debug.Assert(outputInterface != null);
uniqueParamsBuilder.Add(outputInterface.AddressBlob, param);
uniqueParamValues.Add(param.Name, null);
allParams.AddValueChangedEventByAddress(outputInterface.Address, GetValueCallback);
}

_addressToUniqueParam = uniqueParamsBuilder.ToImmutable();
_paramNameToUniqueParamValues = uniqueParamValues;
OscUtility.Server.AddMonitorCallback(GetValueCallback);
}

public OscAvatarParametorContainer(IEnumerable<OscAvatarParameter> parameters)
Expand All @@ -49,14 +48,23 @@ public OscAvatarParametorContainer(IEnumerable<OscAvatarParameter> parameters)
#endregion

#region Datas
private readonly ImmutableDictionary<BlobString, OscAvatarParameter> _addressToUniqueParam;
private readonly Dictionary<string, object?> _paramNameToUniqueParamValues;

public ImmutableArray<OscAvatarParameter> Parameters { get; }
public OscAvatarParameter GetParameter(string name) => Parameters.First(p => p.Name == name);

public IEnumerable<OscAvatarParameter> UniqueParameters => _addressToUniqueParam.Values;
public IEnumerable<object?> UniqueParameterValues => _paramNameToUniqueParamValues.Values;
public IEnumerable<OscAvatarParameter> UniqueParameters => Parameters.Where(parm => !OscAvatarUtility.IsCommonParameter(parm.Name));
public IEnumerable<object?> UniqueParameterValues
{
get
{
var allParams = OscParameter.Parameters;
foreach (var item in UniqueParameters)
{
var address = (item.Output ?? item.Input)!.Address;
allParams.TryGetValue(address, out var value);
yield return value;
}
}
}

public IEnumerable<string> Names => Parameters.Select(param => param.Name);

Expand All @@ -75,11 +83,9 @@ public object this[string name]

public T? GetAs<T>(string name) where T : notnull
{
if (OscAvatarUtility.IsCommonParameter(name))
{
return (T?)OscAvatarUtility.GetCommonParameterValue(name) ?? default;
}
if (_paramNameToUniqueParamValues.TryGetValue(name, out var value))
var param = GetParameter(name);
var allParams = OscParameter.Parameters;
if (allParams.TryGetValue((param.Output ?? param.Input)!.Address, out var value))
{
return (T?)value ?? default;
}
Expand Down Expand Up @@ -129,26 +135,10 @@ public bool TryGetValue(string key, [NotNullWhen(true)] out object? value)
#endregion

#region Events
private void GetValueCallback(BlobString address, OscMessageValues values)
private void GetValueCallback(OscParameterCollection sender, ParameterChangedEventArgs e)
{
if (!_addressToUniqueParam.ContainsKey(address))
{
return;
}

var param = _addressToUniqueParam[address];
var paramName = param.Name;
var paramToValue = _paramNameToUniqueParamValues;

for (int i = 0; i < values.ElementCount; i++)
{
var oldValue = paramToValue[paramName];
var newValue = values.ReadValue(i);
paramToValue[paramName] = newValue;

var eventArgs = new ValueChangedEventArgs(oldValue, newValue);
OnParameterChanged(param, eventArgs);
}
var name = e.Address[(OscConst.ParameterAddressSpace.Length + 1)..];
OnParameterChanged(GetParameter(name), e);
}

public event OscAvatarParameterChangedEventHandler? ParameterChanged;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
using BlobHandles;
using BuildSoft.OscCore;

namespace BuildSoft.VRChat.Osc;
namespace BuildSoft.VRChat.Osc.Avatar;

public class OscAvatarUtility
public static class OscAvatarUtility
{
internal static readonly Dictionary<string, object?> _commonParameters = new()
{
Expand Down Expand Up @@ -36,14 +36,14 @@ internal static void RegisterAvaterConfig(OscAvatarConfig avatarConfig)
_avatarConfigs.Add(new WeakReference<OscAvatarConfig>(avatarConfig));
}

public IReadOnlyDictionary<string, object?> CommonParameters => _commonParameters;
public static IReadOnlyDictionary<string, object?> CommonParameters => _commonParameters;

public static OscAvatar CurrentAvatar => _currentAvatar;

private static OscAvatar _currentAvatar;
private static OscAvatar _changedAvatar;

public static event OscValueChangedEventHandler<OscAvatar, OscAvatar>? OnAvatarChanged;
public static event OscValueChangedEventHandler<OscAvatar, OscAvatar>? AvatarChanged;

internal static void Initialize()
{
Expand All @@ -52,49 +52,7 @@ internal static void Initialize()
static OscAvatarUtility()
{
var server = OscUtility.Server;
server.TryAddMethod("/avatar/change", ReadAvatarIdFromApp);
server.AddMonitorCallback(ReadCommonParamsFromApp);
}

private static void ReadCommonParamsFromApp(BlobString blobString, OscMessageValues message)
{
string str = blobString.ToString();
if (!str.StartsWith("/avatar/parameters/"))
{
return;
}

var name = str["/avatar/parameters/".Length..];
if (!_commonParameters.ContainsKey(name))
{
return;
}
for (int i = 0; i < message.ElementCount; i++)
{
var oldValue = _commonParameters[name];
var newValue = message.ReadValue(i);
_commonParameters[name] = newValue;
CallOnCommonParamaterChanged(name, new ValueChangedEventArgs(oldValue, newValue));
}
}

private static void CallOnCommonParamaterChanged(string paramName, ValueChangedEventArgs e)
{
var configs = _avatarConfigs;

for (int i = configs.Count - 1; i >= 0; i--)
{
if (!configs[i].TryGetTarget(out var config))
{
configs.RemoveAt(i);
continue;
}
if (config.IsCreatedParameters)
{
var parameters = config.Parameters;
parameters.OnParameterChanged(parameters.GetParameter(paramName), e);
}
}
server.TryAddMethod(OscConst.AvatarIdAddress, ReadAvatarIdFromApp);
}

private static void ReadAvatarIdFromApp(OscMessageValues message)
Expand All @@ -115,6 +73,6 @@ private static void CallOnAvatarChanged()
_currentAvatar = newAvatar;
_changedAvatar = default;

OnAvatarChanged?.Invoke(_currentAvatar, new ValueChangedEventArgs<OscAvatar>(oldAvatar, newAvatar));
AvatarChanged?.Invoke(_currentAvatar, new ValueChangedEventArgs<OscAvatar>(oldAvatar, newAvatar));
}
}
Loading

0 comments on commit ba1e003

Please sign in to comment.