Closed Shylie closed 4 years ago
Possible implementation as follows:
using System;
using System.Collections.Generic;
public class UserData
{
public void SetData<T>(T data)
{
_data[typeof(T)] = data;
}
public bool HasData<T>()
{
return _data.ContainsKey(typeof(T));
}
public T GetData<T>()
{
return _data.ContainsKey(typeof(T)) ? (T)_data[typeof(T)] : default;
}
private Dictionary<Type, object> _data = new Dictionary<Type, object>();
}
and have Fixture
implement UserData
in one of the following ways:
public class Fixture : LoveObject
{
.... // current implementation
public readonly UserData CustomData = new UserData();
}
or
public class Fixture : LoveObject
{
.... // current implementation
public T GetData<T>()
{
return _data.GetData<T>();
}
public bool HasData<T>()
{
return _data.HasData<T>();
}
public void SetData<T>(T data)
{
_data.SetData(data);
}
protected readonly UserData _data = new UserData();
}
Alternate implementation for UserData
could replace HasData<T>
and GetData<T>
with
bool GetData<T>(out T data)
{
if (_data.ContainsKey(typeof(T)))
{
data = _data[typeof(T)];
return true;
}
else
{
data = default;
return false;
}
}
Thanks for your code! And i want to keep the function name consistent with the original, i want change the SetData
to SetUserData
.
And i think it's necessary to provide more complete functions, so i want provide the GetUserDataAll
RemoveUserData
and ClearUserData
.
Body:setUserData and Joint:setUserData have same function, so i will also add them at their class.
And there a bug on them, beacuse love.physics.newFixture , Fixture:getBody and Body:getFixtureList is create(get) object from difference place. so it will be a bug. so, in my oponion, if set/getUserData implement on C# layer, it will need a center.
so, finally i will implement by this:
class UserData
{
public void SetData<T>(T data)
{
_data[typeof(T)] = data;
}
public bool HasData<T>()
{
return _data.ContainsKey(typeof(T));
}
public bool GetData<T>(out T data)
{
if (_data.TryGetValue(typeof(T), out var objData) == false)
{
data = default(T);
return false;
}
data = (T)objData;
return true;
}
public bool RemoveData<T>()
{
return _data.Remove(typeof(T));
}
public IEnumerator<KeyValuePair<Type, object>> GetAll()
{
return _data.GetEnumerator();
}
public void Clear()
{
_data.Clear();
}
private Dictionary<Type, object> _data = new Dictionary<Type, object>();
}
class UserDataCenter
{
public static UserData Get(LoveObject lob)
{
if (_data.TryGetValue(lob.p, out var ud) == false)
{
ud = new UserData();
_data[lob.p] = ud;
}
return ud;
}
private static readonly Dictionary<IntPtr, UserData> _data = new Dictionary<IntPtr, UserData>();
}
public class Body/Fixture/Joint : xxxx
{
// .... other code .....
#region UserData
/// <summary>
/// Get data by type. Each type can has one data.
/// </summary>
/// <typeparam name="T">the key</typeparam>
/// <param name="data">The data to get.</param>
/// <returns></returns>
public bool GetUserData<T>(out T data) => _userData.GetData<T>(out data);
/// <summary>
/// Query exist data by type. Each type can has one data.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public bool HasUserData<T>() => _userData.HasData<T>();
/// <summary>
/// Set user data by type, each type can has one data.
/// </summary>
/// <typeparam name="T">the key</typeparam>
/// <param name="data">The data to set.</param>
public void SetUserData<T>(T data) => _userData.SetData(data);
/// <summary>
/// Remove user data by type, each type can has one data.
/// </summary>
/// <typeparam name="T">the key</typeparam>
public bool RemoveUserData<T>() => _userData.RemoveData<T>();
/// <summary>
/// Clear all user data.
/// </summary>
public void ClearUserData() => _userData.Clear();
/// <summary>
/// Get all exists data.
/// </summary>
/// <returns></returns>
public IEnumerator<KeyValuePair<Type, object>> GetUserDataAll() => _userData.GetAll();
private UserData _userData
{
get
{
if(_userDataCache == null)
_userDataCache = UserDataCenter.Get(this);
return _userDataCache;
}
}
private UserData _userDataCache;
#endregion
}
is this is feasible or not ?
Looks good! Thanks!
Might want to add
class UserDataCenter
{
// existing code
Remove(LoveObject lob)
{
if (_data.ContainsKey(lob.p))
{
_data.Remove(lob.p);
}
}
}
Side note: Naming convention for properties is private UserData UserData
, rather than _userData
, but that's not really important.
UserData
available from 11.0.34
Thanks!
closed because it finished .
See Fixture:setUserData for more information.
Perhaps the implementation could use generic types like so:
void SetUserData<TData>(TData data);
TData GetUserData<TData>();
using
System.Collections.Generic.Dictionary<System.Type, object>
to store the data?