Kaynağa Gözat

json-update

lvjincheng 3 yıl önce
ebeveyn
işleme
0b97c80c13

+ 161 - 0
Assets/BowArrow/Scripts/Bluetooth/New/AttitudeJson.cs

@@ -0,0 +1,161 @@
+using System.Collections.Generic;
+using Newtonsoft.Json.Linq;
+using o0.IMU;
+using o0.Geometry;
+using o0;
+
+public class AttitudeJson : JCUnityLib.CustomJson
+{
+    public AttitudeJson() : base()
+    {
+        InitAttitudeImporter();
+        InitAttitudeExporter();
+    }
+
+    void InitAttitudeImporter()
+    {
+        importerDict.Add(typeof(_9AxisPreProcessor), (cs, o) => {
+            JToken jt = new JObject();
+            cs.FetchJsonProperties(jt, o,
+                "AccByteIndex", 
+                "GyrByteIndex", 
+                "MagByteIndex",
+                "ByteToAcc", 
+                "ByteToGyr", 
+                "ByteToMag",
+                "GyrCalibrater", 
+                "MagCalibrater"
+            );
+            return jt; 
+        });
+        importerDict.Add(typeof(MagnetometerAutoCalibrater), (cs, o) => {
+            JToken jt = new JObject();
+            cs.FetchJsonProperties(jt, o, 
+                "CountPerLength", 
+                "EllipsoidFitting", 
+                "FitCountLeft",
+                "FitThreshold", 
+                "LastTimestamp", 
+                "Lock", 
+                "MaxCount",
+                "NewBlock", 
+                "NewBlockAccumulation", 
+                "Variance",
+                "VectorByBlock"
+            );
+            return jt;
+        });
+        importerDict.Add(typeof(EllipsoidFitting), (cs, o) => {
+            JToken jt = new JObject();
+            cs.FetchJsonProperties(jt, o, "Center", "CorrectMatrixArray", "Radius");
+            return jt;
+        });
+        importerDict.Add(typeof(Dictionary<Vector<int>, Vector<double>>), (cs, o) => JToken.FromObject(o));
+        importerDict.Add(typeof(MeanMaintainer<Vector<double>>), (cs, o) => {
+            JToken jt = new JObject();
+            cs.FetchJsonProperties(jt, o, "Count", "Mean");
+            return jt; 
+        });
+        importerDict.Add(typeof(ByteToShortByVariance[]), (cs, o) => {
+            var oArr = (ByteToShortByVariance[]) o;
+            var ja = new JArray();
+            for (int i = 0; i < oArr.Length; i++) 
+            {
+                var jo = new JObject();
+                cs.FetchJsonProperties(jo, oArr[i], "Count", "Reverse", "Short", "ThresholdRate");
+                ja.Add(jo);
+            }
+            return ja;
+        });
+        importerDict.Add(typeof(ByteToShorts), (cs, o) => {
+            JToken jt = new JObject();
+            cs.FetchJsonProperties(jt, o, "ByteToShort");
+            return jt; 
+        });
+        importerDict.Add(typeof(Vector<int>), (cs, o) => JToken.FromObject(o));
+        importerDict.Add(typeof(Vector<double>), (cs, o) => JToken.FromObject(o));
+    }
+
+    void InitAttitudeExporter()
+    {
+        exporterDict.Add(typeof(_9AxisPreProcessor), (cs, jt) => {
+            var o = new _9AxisPreProcessor();
+            FetchFieldValue(o, jt, 
+                "AccByteIndex", 
+                "GyrByteIndex", 
+                "MagByteIndex", 
+                "ByteToAcc", 
+                "ByteToGyr", 
+                "ByteToMag", 
+                "GyrCalibrater", 
+                "MagCalibrater"
+            );
+            return o; 
+        });
+        exporterDict.Add(typeof(MagnetometerAutoCalibrater), (cs, jt) => {
+            var o = new MagnetometerAutoCalibrater();
+            cs.FetchFieldValue(o, jt, 
+                "CountPerLength", 
+                "EllipsoidFitting",
+                "FitCountLeft",
+                "FitThreshold",
+                "LastTimestamp",
+                "Lock",
+                "MaxCount",
+                "NewBlock",
+                "NewBlockAccumulation",
+                "Variance",
+                "VectorByBlock"
+            );
+            return o;
+        });
+        exporterDict.Add(typeof(EllipsoidFitting), (cs, jt) => {
+            var Center = cs.ParseByExporter<Vector<double>>(jt["Center"]);
+            var CorrectMatrix = cs.ParseByExporter
+                <MathNet.Numerics.LinearAlgebra.Matrix<double>>(jt["CorrectMatrixArray"]);
+            var Radius = cs.ParseByExporter<Vector<double>>(jt["Radius"]);
+            return new EllipsoidFitting(Center, CorrectMatrix, Radius);
+        });
+        exporterDict.Add(typeof(Dictionary<Vector<int>, Vector<double>>), (cs, jt) => {
+            var o = new Dictionary<Vector<int>, Vector<double>>();
+            foreach (JProperty item in jt)
+                o[cs.ParseByExporter<Vector<int>>(JArray.Parse(item.Name))] 
+                    = cs.ParseByExporter<Vector<double>>(item.Value);
+            return o;
+        });
+        exporterDict.Add(typeof(MeanMaintainer<Vector<double>>), (cs, jt) => {
+            var o = new MeanMaintainer<Vector<double>>();
+            cs.FetchFieldValue(o, jt, "Count", "Mean");
+            return o; 
+        });
+        exporterDict.Add(typeof(ByteToShortByVariance[]), (cs, jt) => {
+            var o = new ByteToShortByVariance[3];
+            var arr = (JArray) jt;
+            for (int i = 0; i < o.Length; i++) 
+            {
+                var item = arr[i];
+                var byteToShortByVariance = new ByteToShortByVariance();
+                cs.FetchFieldValue(byteToShortByVariance, item, "Count", "Reverse", "Short", "ThresholdRate");
+                o[i] = byteToShortByVariance;
+            }
+            return o;
+        });
+        exporterDict.Add(typeof(ByteToShorts), (cs, jt) => {
+            ByteToShorts o = new ByteToShorts(3);
+            cs.FetchFieldValue(o, jt, "ByteToShort");
+            return o; 
+        });
+        exporterDict.Add(typeof(MathNet.Numerics.LinearAlgebra.Matrix<double>), (cs, jt) => {
+            JArray arr = (JArray) jt;
+            int rcCount = arr.Count;
+            MathNet.Numerics.LinearAlgebra.Matrix<double> matrix 
+                = MathNet.Numerics.LinearAlgebra.CreateMatrix.Dense<double>(rcCount, rcCount);
+            for (var i = 0; i < rcCount; ++i)
+                for (var j = 0; j < rcCount; ++j)
+                    matrix[i, j] = arr[i][j].Value<double>();
+            return matrix;
+        });
+        exporterDict.Add(typeof(Vector<int>), (cs, jt) => new Vector<int>(jt.ToObject<int[]>()));
+        exporterDict.Add(typeof(Vector<double>), (cs, jt) => new Vector<double>(jt.ToObject<double[]>()));
+    }
+}

+ 11 - 0
Assets/BowArrow/Scripts/Bluetooth/New/AttitudeJson.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: b54aed8acff685645a8e0c21404fa68c
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 3 - 3
Assets/BowArrow/Scripts/Bluetooth/New/Axis9Handler.cs

@@ -8,7 +8,7 @@ using System.Reflection;
 public class Axis9Handler : AxisBaseHandler
 {
     private o0.Bow.o09AxisAfterXiaMenFromDll _9Axis;
-
+    private AttitudeJson attitudeJson = new AttitudeJson();
     /*
     public o0.Geometry.Vector<int> GyrByteIndex = new o0.Geometry.Vector<int>(3, -2, 1);
     public o0.Geometry.Vector<int> AccByteIndex = new o0.Geometry.Vector<int>(3, -2, 1);
@@ -103,7 +103,7 @@ public class Axis9Handler : AxisBaseHandler
     {
         try
         {
-            string record = JsonConvert.SerializeObject(_9Axis.Attitude);
+            string record = attitudeJson.Stringify(_9Axis.Attitude);
             if (!string.IsNullOrEmpty(record))
             {
                 Debug.Log("9轴数据序列化成功");
@@ -121,7 +121,7 @@ public class Axis9Handler : AxisBaseHandler
     {
         try
         {
-            Json.FromJson<o0.IMU._9AxisPreProcessor>(record, ref _9Axis.Attitude);
+            _9Axis.Attitude = attitudeJson.Parse<o0.IMU._9AxisPreProcessor>(record);
             Type t = _9Axis.Attitude.GetType();
             object o = _9Axis.Attitude;
             bool gyrEqual = GyrByteIndex.Equals(t.GetField("GyrByteIndex", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(o));

+ 99 - 0
Assets/ThirdAssets/JCUnityLib/CustomJson.cs

@@ -0,0 +1,99 @@
+using System;
+using System.Reflection;
+using System.Collections.Generic;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+
+namespace JCUnityLib
+{
+    public class CustomJson
+    {
+        public Dictionary<Type, Func<CustomJson, JToken, object>> exporterDict = new Dictionary<Type, Func<CustomJson, JToken, object>>();
+        public Dictionary<Type, Func<CustomJson, object, JToken>> importerDict = new Dictionary<Type, Func<CustomJson, object, JToken>>();
+
+        public CustomJson()
+        {
+            //add exporter
+            exporterDict.Add(typeof(short), (cs, jt) => jt.Value<short>());
+            exporterDict.Add(typeof(int), (cs, jt) => jt.Value<int>());
+            exporterDict.Add(typeof(long), (cs, jt) => jt.Value<long>());
+            exporterDict.Add(typeof(float), (cs, jt) => jt.Value<float>());
+            exporterDict.Add(typeof(double), (cs, jt) => jt.Value<double>());
+            exporterDict.Add(typeof(bool), (cs, jt) => jt.Value<bool>());
+            //add importer
+            importerDict.Add(typeof(short), (cs, o) => JValue.FromObject(o));
+            importerDict.Add(typeof(int), (cs, o) => JValue.FromObject(o));
+            importerDict.Add(typeof(long), (cs, o) => JValue.FromObject(o));
+            importerDict.Add(typeof(float), (cs, o) => JValue.FromObject(o));
+            importerDict.Add(typeof(double), (cs, o) => JValue.FromObject(o));
+            importerDict.Add(typeof(bool), (cs, o) => JValue.FromObject(o));
+            importerDict.Add(typeof(double[][]), (cs, o) => JArray.FromObject(o));
+        }
+
+        public T Parse<T>(string text)
+        {
+            var jt = JToken.Parse(text);
+            return (T)ParseByExporter(jt, typeof(T));
+        }
+
+        public string Stringify(object o)
+        {
+            return JsonConvert.SerializeObject(ToJTokenByImporter(o));
+        }
+
+        public void FetchJsonProperties(JToken target, object fromObject, params string[] propertyNames)
+        {
+            Type fromObjectType = fromObject.GetType();
+            foreach (var propertyName in propertyNames)
+            {
+                FieldInfo targetField = fromObjectType.GetField(propertyName, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
+                if (targetField == null) {
+                    PropertyInfo propertyInfo = fromObjectType.GetProperty(propertyName);
+                    JToken propertyValue = ToJTokenByImporter(propertyInfo.GetValue(fromObject));
+                    target[propertyName] = propertyValue;
+                } else {
+                    JToken propertyValue = ToJTokenByImporter(targetField.GetValue(fromObject));
+                    target[propertyName] = propertyValue;
+                }
+            }
+        }
+
+        public JToken ToJTokenByImporter(object o)
+        {
+            Type type = o.GetType();
+            Func<CustomJson, object, JToken> importer = null;
+            importerDict.TryGetValue(type, out importer);
+            if (importer == null) throw new Exception($"缺少Type<{type.Name}>的Importer");
+            return importer.Invoke(this, o);
+        }
+
+        public T ParseByExporter<T>(JToken jt)
+        {
+            return (T)ParseByExporter(jt, typeof(T));
+        }
+
+        public object ParseByExporter(JToken jt, Type type)
+        {
+            Func<CustomJson, JToken, object> exporter = null;
+            exporterDict.TryGetValue(type, out exporter);
+            if (exporter == null) throw new Exception($"缺少Type<{type.Name}>的Exporter");
+            return exporter.Invoke(this, jt);
+        }
+
+        public void FetchFieldValue(object target, JToken fromJson, params string[] fieldNames) {
+            Type targetType = target.GetType();
+            foreach (var fieldName in fieldNames)
+            {
+                FieldInfo targetField = targetType.GetField(fieldName, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
+                if (targetField == null) {
+                    PropertyInfo propertyInfo = targetType.GetProperty(fieldName);
+                    object fieldValue = ParseByExporter(fromJson[fieldName], propertyInfo.PropertyType);
+                    propertyInfo.SetValue(target, fieldValue);
+                } else {
+                    object fieldValue = ParseByExporter(fromJson[fieldName], targetField.FieldType);
+                    targetField.SetValue(target, fieldValue);
+                }
+            }
+        }
+    }
+}

+ 11 - 0
Assets/ThirdAssets/JCUnityLib/CustomJson.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 4d90253d2a2649e469687a88a93d2554
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: