using System; using System.Runtime.InteropServices; using System.Reflection; namespace UltraControls { public class ControlInfo { internal bool m_has_range; internal Type m_type; internal string m_name; internal object m_value_default; internal object m_value_min; internal object m_value_max; } public class Factroy { public static ControlInfo CreateInfo< T > (string name, T value) { Type type = typeof(T); if (!Utils.IsSupport(type)) { return null; } ControlInfo info = new ControlInfo(); info.m_value_default = value; info.m_type = type; info.m_has_range = false; info.m_name = name; return info; } public static ControlInfo CreateInfo(string name, T value, T min, T max) { Type type = typeof(T); if (!Utils.IsSupport(type)) { return null; } ControlInfo info = new ControlInfo(); info.m_value_default = value; info.m_type = type; info.m_value_min = min; info.m_value_max = max; info.m_has_range = true; info.m_name = name; return info; } } public class ParameterBase { internal Control m_ctrl; internal PropertyInfo m_prop; public object val { set { m_prop.SetValue(m_ctrl, value, null); } get { return m_prop.GetValue(m_ctrl, null); } } } public class Parameter < T > : ParameterBase { internal Parameter(Control ctrl) { m_ctrl = ctrl; string name_prop = ""; Type type = typeof(T); if (type != ctrl.realType) { throw new Exception("Control[" + ctrl.name + "]: ParamControl<" + type.ToString() + "> is not fit the type : " + ctrl.realType.ToString() + "."); } if (type == typeof(string)) { name_prop = "text"; } else if (type == typeof(bool)) { name_prop = "valBool"; } else if (type == typeof(int)) { name_prop = "valInt"; } else if (type == typeof(float)) { name_prop = "valFloat"; } else if (type == typeof(UnityEngine.Vector2)) { name_prop = "valVector2"; } else if (type == typeof(UnityEngine.Vector3)) { name_prop = "valVector3"; } else if (type == typeof(UnityEngine.Vector4)) { name_prop = "valVector4"; } else if (type == typeof(UnityEngine.Color)) { name_prop = "valColor"; } else if (type == typeof(UnityEngine.Color32)) { name_prop = "valColor32"; } if (name_prop == "") { throw new Exception("Control[" + ctrl.name + "]: ParamControl<" + type.ToString() + "> is not support."); } m_prop = typeof(Control).GetProperty(name_prop); if (m_prop == null) { throw new Exception("Control[" + ctrl.name + "]: The property[" + name_prop + "] of Control is not exist."); } } } public class ParamSetter< T > { private Parameter m_param; internal ParamSetter(Parameter param) { m_param = param; } public T val { set { m_param.val = value; } } } public class ParamGetter { private Parameter m_param; internal ParamGetter(Parameter param) { m_param = param; } public T val { get { return (T)m_param.val; } } } public enum CtrlType: uint { Bool = 0, Event = 1, Float = 10, Text = 100, Int = 200, Vec2F = 500, Vec3F = 510, Vec4F = 520, Color = 600, ColorF = 610, Mat33F = 900, Mat44F = 950, Unknown = 0xDEADBEEF } [StructLayout(LayoutKind.Sequential)] public struct RawCtrl { [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)] public string name; public uint type; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 236)] public byte[] data; } [StructLayout(LayoutKind.Sequential)] public sealed class CtrlValues { [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] public float[] val; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] public float[] min; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] public float[] max; } public sealed class Control { [Flags] enum DirtyFlag { None = 0x00, Data = 0x01, Values = 0x02, All = Data | Values, } [Flags] enum FeatureFlag { None = 0x00, HasRange = 0x01, IsAlive = 0x02, } private string m_name; private CtrlType m_type; private byte[] m_data; private CtrlValues m_values; private string m_text; private DirtyFlag m_dirty; private FeatureFlag m_feature; private Type m_realType; internal Control(ref RawCtrl raw_ctrl) { m_name = raw_ctrl.name; m_type = (CtrlType)raw_ctrl.type; m_data = raw_ctrl.data; m_feature = FeatureFlag.IsAlive; if (m_type == CtrlType.Text) { int count = 0; while (m_data[count] != 0) { ++count; } m_text = System.Text.Encoding.UTF8.GetString(m_data, 0, count); m_realType = typeof(string); } else { m_values = Utils.BytesToStructure(m_data); bool has_range = !(m_values.min[0] == 0.0f && m_values.min[1] == 0.0f && m_values.min[2] == 0.0f && m_values.min[3] == 0.0f && m_values.max[0] == 0.0f && m_values.max[1] == 0.0f && m_values.max[2] == 0.0f && m_values.max[3] == 0.0f); if (has_range) { m_feature |= FeatureFlag.HasRange; } switch (m_type) { case CtrlType.Bool: m_realType = typeof(bool); break; case CtrlType.Float: m_realType = typeof(float); break; case CtrlType.Int: m_realType = typeof(int); break; case CtrlType.Vec2F: m_realType = typeof(UnityEngine.Vector2); break; case CtrlType.Vec3F: m_realType = typeof(UnityEngine.Vector3); break; case CtrlType.Vec4F: m_realType = typeof(UnityEngine.Vector4); break; case CtrlType.Color: m_realType = typeof(UnityEngine.Color32); break; case CtrlType.ColorF: m_realType = typeof(UnityEngine.Color); break; default: UnityEngine.Debug.LogError("The type is not support"); break; } } m_dirty = DirtyFlag.None; } public void Die() { m_feature &= ~FeatureFlag.IsAlive; } public bool IsValue() { return m_values != null; } public bool IsBool() { return m_type == CtrlType.Bool; } public bool IsFloat() { return m_type == CtrlType.Float; } public bool IsString() { return m_type == CtrlType.Text; } public bool IsInt() { return m_type == CtrlType.Int; } public bool IsVector2() { return m_type == CtrlType.Vec2F; } public bool IsVector3() { return m_type == CtrlType.Vec3F; } public bool IsVector4() { return m_type == CtrlType.Vec4F; } public bool IsColor32() { return m_type == CtrlType.Color; } public bool IsColor() { return m_type == CtrlType.ColorF; } //public bool IsEvent() { return m_type == CtrlType.Event; } //public bool IsMatrix4x4() { return m_type == CtrlType.Mat44F; } public ParamSetter CreateParamSetter() { Parameter param = mf_CreateParam(); if (param == null) { return null; } return new ParamSetter(param); } public ParamGetter CreateParamGetter() { Parameter param = mf_CreateParam(); if (param == null) { return null; } return new ParamGetter(param); } public void UpdateDirty() { //if (m_dirty == DirtyFlag.None) //{ // return; //} // if (IsValue()) { if ((m_dirty & DirtyFlag.Values) != 0) { Utils.StructureToBytes(m_values, m_data); } } else { Array.Clear(m_data, 0, m_data.Length); byte[] bytes = System.Text.Encoding.ASCII.GetBytes(m_text); Buffer.BlockCopy(bytes, 0, m_data, 0, Math.Min(bytes.Length, m_data.Length)); m_data[m_data.Length - 1] = 0; } m_dirty = DirtyFlag.None; } public CtrlType ctrlType { get { return m_type; } } public Type realType { get { return m_realType; } } public bool isDirty { get { return m_dirty != DirtyFlag.None; } } public bool isAlive { get { return (m_feature & FeatureFlag.IsAlive) != 0; } } public bool hasRange { get { return (m_feature & FeatureFlag.HasRange) != 0; } } public string name { get { return m_name; } } public bool valBool { set { if (!IsValue()) { mf_TraceWarning("set valBool - is not value!!!"); return; } m_values.val[0] = value? 1.0f: 0.0f; m_dirty |= DirtyFlag.All; } get { if (!IsValue()) { mf_TraceWarning("get valBool - is not value!!!"); return false; } return m_values.val[0] > 0.0f? true: false; } } public string text { set { if (!IsString()) { mf_TraceWarning("set text - is not string!!!"); return; } m_text = value; m_dirty |= DirtyFlag.Data; } get { if (!IsString()) { mf_TraceWarning("get text - is not string!!!"); return ""; } return m_text; } } public float valFloat { set { if (!IsValue()) { mf_TraceWarning("set valFloat - is not value!!!"); return; } m_values.val[0] = value; m_dirty |= DirtyFlag.All; } get { if (!IsValue()) { mf_TraceWarning("get valFloat - is not value!!!"); return 0.0f; } return m_values.val[0]; } } public float minFloat { set { if (!IsValue()) { mf_TraceWarning("set minFloat - is not value!!!"); return; } m_values.min[0] = value; m_dirty |= DirtyFlag.All; } get { if (!IsValue()) { mf_TraceWarning("get minFloat - is not value!!!"); return 0.0f; } return m_values.min[0]; } } public float maxFloat { set { if (!IsValue()) { mf_TraceWarning("set maxFloat - is not value!!!"); return; } m_values.min[0] = value; m_dirty |= DirtyFlag.All; } get { if (!IsValue()) { mf_TraceWarning("get maxFloat - is not value!!!"); return 0.0f; } return m_values.max[0]; } } public int valInt { set { if (!IsValue()) { mf_TraceWarning("set valInt - is not value!!!"); return; } m_values.val[0] = value; m_dirty |= DirtyFlag.All; } get { if (!IsValue()) { mf_TraceWarning("get valInt - is not value!!!"); return 0; } return (int)m_values.val[0]; } } public int minInt { set { if (!IsValue()) { mf_TraceWarning("set minInt - is not value!!!"); return; } m_values.min[0] = value; m_dirty |= DirtyFlag.All; } get { if (!IsValue()) { mf_TraceWarning("get minInt - is not value!!!"); return 0; } return (int)m_values.min[0]; } } public int maxInt { set { if (!IsValue()) { mf_TraceWarning("set maxInt - is not value!!!"); return; } m_values.min[0] = value; m_dirty |= DirtyFlag.All; } get { if (!IsValue()) { mf_TraceWarning("get maxFloat - is not value!!!"); return 0; } return (int)m_values.max[0]; } } public UnityEngine.Vector2 valVector2 { set { if (!IsValue()) { return; } mf_SetVec2(value, m_values.val); } get { return IsValue() ? mf_GetVec2(m_values.val) : UnityEngine.Vector2.zero; } } public UnityEngine.Vector2 minVector2 { set { if (!IsValue()) { return; } mf_SetVec2(value, m_values.min); } get { return IsValue() ? mf_GetVec2(m_values.min) : UnityEngine.Vector2.zero; } } public UnityEngine.Vector2 maxVector2 { set { if (!IsValue()) { return; } mf_SetVec2(value, m_values.max); } get { return IsValue() ? mf_GetVec2(m_values.max) : UnityEngine.Vector2.zero; } } public UnityEngine.Vector3 valVector3 { set { if (!IsValue()) { return; } mf_SetVec3(value, m_values.val); } get { return IsValue() ? mf_GetVec3(m_values.val) : UnityEngine.Vector3.zero; } } public UnityEngine.Vector3 minVector3 { set { if (!IsValue()) { return; } mf_SetVec3(value, m_values.min); } get { return IsValue() ? mf_GetVec3(m_values.min) : UnityEngine.Vector3.zero; } } public UnityEngine.Vector3 maxVector3 { set { if (!IsValue()) { return; } mf_SetVec3(value, m_values.max); } get { return IsValue() ? mf_GetVec3(m_values.max) : UnityEngine.Vector3.zero; } } public UnityEngine.Vector4 valVector4 { set { if (!IsValue()) { return; } mf_SetVec4(value, m_values.val); } get { return IsValue() ? mf_GetVec4(m_values.val) : UnityEngine.Vector4.zero; } } public UnityEngine.Vector4 minVector4 { set { if (!IsValue()) { return; } mf_SetVec4(value, m_values.min); } get { return IsValue() ? mf_GetVec4(m_values.min) : UnityEngine.Vector4.zero; } } public UnityEngine.Vector4 maxVector4 { set { if (!IsValue()) { return; } mf_SetVec4(value, m_values.max); } get { return IsValue() ? mf_GetVec4(m_values.max): UnityEngine.Vector4.zero; } } public UnityEngine.Color valColor { set { if (!IsValue()) { return; } mf_SetColor(value, m_values.val); } get { return IsValue() ? mf_GetColor(m_values.val) : UnityEngine.Color.black; } } public UnityEngine.Color32 valColor32 { set { if (!IsValue()) { return; } mf_SetColor32(value); } get { if (IsValue()) { return new UnityEngine.Color32(m_data[0], m_data[1], m_data[2], m_data[3]); } else { return new UnityEngine.Color32(0, 0, 0, 0); } } } public byte[] data { set { m_data = value; if (m_type == CtrlType.Text) { int count = 0; while (m_data[count] != 0) { ++count; } m_text = System.Text.Encoding.UTF8.GetString(m_data, 0, count); } else { m_values = Utils.BytesToStructure(m_data); } } get { UpdateDirty(); return m_data; } } private void mf_SetVec2(UnityEngine.Vector2 vec2, float[] ary_f) { Utils.SetVec2(vec2, ary_f); m_dirty |= DirtyFlag.All; } private void mf_SetVec3(UnityEngine.Vector3 vec3, float[] ary_f) { Utils.SetVec3(vec3, ary_f); m_dirty |= DirtyFlag.All; } private void mf_SetVec4(UnityEngine.Vector4 vec4, float[] ary_f) { Utils.SetVec4(vec4, ary_f); m_dirty |= DirtyFlag.All; } private void mf_SetColor(UnityEngine.Color clr, float[] ary_f) { Utils.SetColor(clr, ary_f); m_dirty |= DirtyFlag.All; } private void mf_SetColor32(UnityEngine.Color32 clr32) { Utils.SetColor32(clr32, m_data); m_dirty |= DirtyFlag.Data; } private UnityEngine.Vector2 mf_GetVec2(float[] ary_f) { return new UnityEngine.Vector2(ary_f[0], ary_f[1]); } private UnityEngine.Vector3 mf_GetVec3(float[] ary_f) { return new UnityEngine.Vector3(ary_f[0], ary_f[1], ary_f[2]); } private UnityEngine.Vector4 mf_GetVec4(float[] ary_f) { return new UnityEngine.Vector4(ary_f[0], ary_f[1], ary_f[2], ary_f[3]); } private UnityEngine.Color mf_GetColor(float[] ary_f) { return new UnityEngine.Color(ary_f[0], ary_f[1], ary_f[2], ary_f[3]); } private void mf_TraceWarning(string msg) { UnityEngine.Debug.LogWarning("[WARNING] UltraControls::Control name = " + m_name + " : " + msg); } private Parameter mf_CreateParam() { Parameter param; try { param = new Parameter(this); } catch (Exception ex) { UnityEngine.Debug.LogError("UltraControls::Control[" + m_name + "] CreateParam(): " + ex.Message); param = null; } return param; } } public sealed class NativeLib { //Imports [DllImport("NativeUltraControlsPluginD", EntryPoint = "nucpInitLib")] //[DllImport("NativeUltraControlsPlugin", EntryPoint = "nucpInitLib")] public static extern int Init(); [DllImport("NativeUltraControlsPluginD", EntryPoint = "nucpTermLib")] //[DllImport("NativeUltraControlsPlugin", EntryPoint = "nucpTermLib")] public static extern void Term(); [DllImport("NativeUltraControlsPluginD", EntryPoint = "nucpCreateHandle")] //[DllImport("NativeUltraControlsPlugin", EntryPoint = "nucpCreateHandle")] public static extern int CreateHandle([In] string in_name, [In] uint in_max_num_ctrls, [Out] out uint out_handle); [DllImport("NativeUltraControlsPluginD", EntryPoint = "nucpDestroyHandle")] //[DllImport("NativeUltraControlsPlugin", EntryPoint = "nucpCreateHandle")] public static extern int DestroyHandle([In] uint in_handle); //[Setter]/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// [DllImport("NativeUltraControlsPluginD", EntryPoint = "nucpFindGetter")] //[DllImport("NativeUltraControlsPlugin", EntryPoint = "nucpFindGetter")] public static extern int FindGetter([In] uint in_handle, [In, Out] RawCtrl[] out_p_ary, [In] uint in_max_cnt, [Out] out uint out_p_cnt); [DllImport("NativeUltraControlsPluginD", EntryPoint = "nucpSetControls")] //[DllImport("NativeUltraControlsPlugin", EntryPoint = "nucpSetControls")] public static extern int SetControls([In] uint in_handle, [In, Out] RawCtrl[] in_p_ary, [In] uint in_max_cnt); //[Getter]/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// [DllImport("NativeUltraControlsPluginD", EntryPoint = "nucpCreateGetter")] //[DllImport("NativeUltraControlsPlugin", EntryPoint = "nucpCreateGetter")] public static extern int CreateGetter([In] uint in_handle, [In] RawCtrl[] out_p_ary, [In] uint in_max_cnt); [DllImport("NativeUltraControlsPluginD", EntryPoint = "nucpGetControls")] //[DllImport("NativeUltraControlsPlugin", EntryPoint = "nucpGetControls")] public static extern int GetControls([In] uint in_handle, [In, Out] RawCtrl[] out_p_ary, [In] uint in_max_cnt, [Out] out uint out_p_cnt); [DllImport("NativeUltraControlsPluginD", EntryPoint = "nucpCheckControls")] //[DllImport("NativeUltraControlsPlugin", EntryPoint = "nucpCheckControls")] public static extern int CheckControls([In] uint in_handle, [In, Out] RawCtrl[] out_p_ary, [In] uint in_max_cnt, [Out] out uint out_p_cnt); } }