public IData GetData(VMBehaviour vm) { ParseKey(); if (vm == null) { return(null); } if (keyChain.Count <= 0) { return(null); } // 从 VMBehaviour 中获取数据第一项只能是属性 if (keyChain[0].Index > -1 || !string.IsNullOrEmpty(keyChain[0].HashKey)) { return(null); } IData data = keyChain[0].GetData(vm); for (int i = 1; i < keyChain.Count; i++) { if (data == null) { break; } data = keyChain[i].GetData(data); } return(data); }
private void DoAnimatorBind(VMBehaviour vm, GameObject obj) { Animator cptAnim = obj.GetComponent <Animator>(); if (cptAnim == null) { Debugger.LogError("DataBinder", obj.name + " Animator null."); return; } Type propertyType = typeof(string); if (!CheckDataTypeValid(propertyType, obj)) { return; } this.SetValueHandler = delegate(IData source) { object value = this.Source.FastGetValue(); if (this.Converter != null) { value = this.Converter.Convert(value, propertyType, this.Definer.ConverterParameter, vm); } cptAnim.StopPlayback(); string animName = (string)value; if (!string.IsNullOrEmpty(animName)) { cptAnim.Play(animName, this.AnimatorLayer); } }; this.Source.AddValueChangedListener(this.SetValueHandler); this.SetValueHandler.Invoke(this.Source); }
public override void Bind(VMBehaviour vm, IData data) { base.Bind(vm, data); if (Source == null) { return; } if (Template == null) { return; } if (data == null) { return; } this.sourceData = Source.GetData(data) as StructData; if (this.sourceData == null) { return; } DoBind(); }
public IData GetData(VMBehaviour vm) { // 从 VMBehaviour 中获取数据只能是属性 if (Index > -1 || !string.IsNullOrEmpty(HashKey)) { return(null); } return(vm.GetData(Key)); }
public override void BindListItem(VMBehaviour vm, int index) { base.BindListItem(vm, index); for (int i = 0; i < BindItems.Count; i++) { CommandBinderItem item = BindItems[i]; item.DoBind(vm, index, this.gameObject, GetBindComponent()); } }
public void EditorBind() { if (!Application.isPlaying) { this.BindVM = this.GetComponentInParent <VMBehaviour>(true); if (this.BindVM != null) { this.BindVM.EditorCollect(); } } }
public override void Bind(VMBehaviour vm, IData data) { base.Bind(vm, data); for (int i = 0; i < BindItems.Count; i++) { DataBinderItem item = BindItems[i]; IData source = item.Definer.GetData(data); if (source == null || source.GetDataType() != DataType.Base) { Debugger.LogError("DataBinder", this.gameObject.name + " data is not base data."); continue; } item.Source = (IBaseData)source; item.Converter = item.Definer.GetConverter(vm); item.DoBind(vm, this.gameObject); } }
private void DoActiveBind(VMBehaviour vm, GameObject obj) { Type propertyType = typeof(bool); if (!CheckDataTypeValid(propertyType, obj)) { return; } this.SetValueHandler = delegate(IData source) { object value = this.Source.FastGetValue(); if (this.Converter != null) { value = this.Converter.Convert(value, propertyType, this.Definer.ConverterParameter, vm); } obj.SetActive((bool)value); }; this.Source.AddValueChangedListener(this.SetValueHandler); this.SetValueHandler.Invoke(this.Source); }
public void DoBind(VMBehaviour vm, GameObject obj) { switch (this.Type) { case BindType.Property: DoPropertyBind(vm, obj); break; case BindType.Active: DoActiveBind(vm, obj); break; case BindType.Animation: DoAnimationBind(vm, obj); break; case BindType.Animator: DoAnimatorBind(vm, obj); break; } }
private void DoBind() { if (!this.isActiveAndEnabled) { return; } if (this.Template == null || this.sourceData == null) { return; } if (this.obj != null) { Destroy(this.obj); } this.obj = GameObject.Instantiate(this.Template, this.transform); this.obj.SetActive(true); this.objVM = this.obj.GetComponent <VMBehaviour>(); this.handlers.Clear(); foreach (KeyValuePair <string, IData> kv in this.sourceData.Fields) { IData dstData = this.objVM.GetData(kv.Key); IData srcData = this.sourceData[kv.Key]; if (dstData != null) // && srcData.GetType() == dstData.GetType()) // CopyFrom 本身做了数据检查 { DataChangedHandler handler = delegate(IData src) { dstData.CopyFrom(src); }; handler.Invoke(srcData); srcData.AddValueChangedListener(handler); this.handlers[srcData] = handler; } } }
public void Bind(VMBehaviour vm, int index, IListData data) { this.index = index; this.source = data; this.item = this.source.GetAt(this.index); this.vm = vm; for (int i = 0; i < dataBinders.Count; i++) { if (dataBinders[i].CanBind(this.vm, item)) { dataBinders[i].Bind(this.vm, item); } } for (int i = 0; i < commandBinders.Count; i++) { if (commandBinders[i].CanBindListItem(this.vm, this.index)) { commandBinders[i].BindListItem(this.vm, this.index); } } }
public IConverter GetConverter(VMBehaviour vm) { if (vm == null) { return(null); } if (!string.IsNullOrEmpty(this.Converter)) { IConverter converter = vm.GetConverter(this.Converter); if (converter == null) { Type converterType = Type.GetType("VVMUI.Core.Converter." + this.Converter); if (converterType != null) { converter = (IConverter)Activator.CreateInstance(converterType); } } return(converter); } return(null); }
public override void OnInspectorGUI() { ListTemplateBinder binder = target as ListTemplateBinder; VMBehaviour vm = binder.GetComponentInParent <VMBehaviour>(true); if (definerDrawer == null) { definerDrawer = new DataDefinerDrawer(binder.ItemSource); } definerDrawer.Draw(vm, null, typeof(IList)); IData data = binder.ItemSource.GetData(vm); IListData list = data as IListData; if (list == null) { GUIStyle style = new GUIStyle(EditorStyles.boldLabel); style.normal.textColor = Color.red; EditorGUILayout.LabelField("no source list data.", style); } EditorGUILayout.LabelField("index: " + binder.Index); }
public override void Bind(VMBehaviour vm) { base.Bind(vm); if (Source == null) { return; } IData data = Source.GetData(vm); if (data == null) { return; } this.sourceData = data as IListData; if (this.sourceData == null) { return; } this.DoBind(); }
public virtual bool CanBindListItem(VMBehaviour vm, int index) { return(true); }
public void BindVM(VMBehaviour vm) { _vm = vm; }
public void DoBind(VMBehaviour vm, object parameter, GameObject obj, Component component) { if (component == null) { Debugger.LogError("CommandBinder", obj.name + " component null."); return; } if (string.IsNullOrEmpty(this.Command)) { Debugger.LogError("CommandBinder", obj.name + " command key empty."); return; } if (string.IsNullOrEmpty(this.Event)) { Debugger.LogError("CommandBinder", obj.name + " event key empty."); return; } // component type reflection componentType = component.GetType(); componentReflection = ReflectionCache.Singleton[componentType]; // command type reflection command = vm.GetCommand(this.Command); if (command == null) { Debugger.LogError("CommandBinder", obj.name + " command null."); return; } commandType = command.GetType().BaseType; if (!typeof(BaseCommand).IsAssignableFrom(commandType)) { Debugger.LogError("CommandBinder", obj.name + " command type error."); return; } commandReflection = ReflectionCache.Singleton[commandType]; // source event type reflection // TODO: 性能优化 GetValue // UGUI 组件的 event 有的是 property,有的不是,所以 field 和 property 都判断 FieldInfo sourceEventFieldInfo = componentReflection.GetField(this.Event); PropertyInfo sourceEventPropertyInfo = componentReflection.GetProperty(this.Event); if (sourceEventFieldInfo != null) { sourceEventType = sourceEventFieldInfo.FieldType.BaseType; sourceEventObj = sourceEventFieldInfo.GetValue(component); } if (sourceEventPropertyInfo != null) { sourceEventType = sourceEventPropertyInfo.PropertyType.BaseType; sourceEventObj = sourceEventPropertyInfo.GetValue(component); } if (sourceEventType == null || sourceEventObj == null) { Debugger.LogError("CommandBinder", obj.name + " event null."); return; } if (!typeof(UnityEngine.Events.UnityEventBase).IsAssignableFrom(sourceEventType)) { Debugger.LogError("CommandBinder", obj.name + " event type error."); return; } sourceEventReflection = ReflectionCache.Singleton[sourceEventType]; // 判断 event 和 command 参数类型是否匹配 bool genericTypeExplicit = true; while (true) { if (sourceEventType.IsGenericType != commandType.IsGenericType) { genericTypeExplicit = false; break; } Type[] sourceEventGenericTypes = sourceEventReflection.GetGenericArguments(); Type[] commandGenericTypes = commandReflection.GetGenericArguments(); if (sourceEventGenericTypes.Length != commandGenericTypes.Length) { genericTypeExplicit = false; break; } for (int j = 0; j < sourceEventGenericTypes.Length; j++) { if (sourceEventGenericTypes[j] != commandGenericTypes[j]) { genericTypeExplicit = false; break; } } break; } if (!genericTypeExplicit) { Debugger.LogError("CommandBinder", obj.name + " event type and command type not explicit."); return; } command.BindVM(vm); sourceEventAction = command.AddListenerToEvent(sourceEventObj, parameter); Selectable selectableComponent = component as Selectable; if (selectableComponent != null) { canExecuteHandler = new Action(delegate { selectableComponent.interactable = command.CanExecute(parameter); }); command.AddCanExecuteChangedListener(canExecuteHandler); selectableComponent.interactable = command.CanExecute(parameter); } }
public void Draw(VMBehaviour vm, IData sourceData, Type propertyType) { if (vm == null || definer == null || propertyType == null) { return; } definer.ParseKey(true); // 获取当前链下的可选数据 IData currentChainData = sourceData != null?definer.GetData(sourceData) : definer.GetData(vm); Dictionary <DataType, Dictionary <string, IData> > datas = new Dictionary <DataType, Dictionary <string, IData> >(); if (definer.KeyChain.Count <= 0) { if (sourceData != null && sourceData.GetDataType() == DataType.Struct) { StructData strct = sourceData as StructData; foreach (string k in strct.Fields.Keys) { IData d = strct.Fields[k]; if (!datas.TryGetValue(d.GetDataType(), out Dictionary <string, IData> dict)) { dict = new Dictionary <string, IData>(); datas[d.GetDataType()] = dict; } dict[k] = d; } } else if (sourceData == null) { foreach (string k in vm.GetDataKeys()) { IData d = vm.GetData(k); if (!datas.TryGetValue(d.GetDataType(), out Dictionary <string, IData> dict)) { dict = new Dictionary <string, IData>(); datas[d.GetDataType()] = dict; } dict[k] = d; } } } if (currentChainData != null && currentChainData.GetDataType() == DataType.Struct) { StructData strct = currentChainData as StructData; foreach (string k in strct.Fields.Keys) { IData d = strct.Fields[k]; if (!datas.TryGetValue(d.GetDataType(), out Dictionary <string, IData> dict)) { dict = new Dictionary <string, IData>(); datas[d.GetDataType()] = dict; } dict[k] = d; } } List <string> convertersStr = new List <string>(); convertersStr.Add(""); convertersStr.AddRange(vm.GetConverterKeys()); converterIndex = convertersStr.IndexOf(definer.Converter); if (converterIndex < 0) { converterIndex = 0; } bool typeFit = currentChainData != null && currentChainData.GetBindDataType().IsAssignableFrom(propertyType); if (!string.IsNullOrEmpty(definer.Converter)) { typeFit = true; } EditorGUILayout.LabelField("Definder:"); EditorGUI.indentLevel++; EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Key: " + (string.IsNullOrEmpty(definer.Key) ? "NULL" : definer.Key), EditorStyles.boldLabel); if (typeFit) { GUIStyle style = new GUIStyle(EditorStyles.boldLabel); style.normal.textColor = Color.green; EditorGUILayout.LabelField("√", style); } else { GUIStyle style = new GUIStyle(EditorStyles.boldLabel); style.normal.textColor = Color.red; EditorGUILayout.LabelField("x", style); } EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Select:"); bool add = false; DefinerKey addkey = new DefinerKey(); if (datas.Count > 0) { List <string> fields = new List <string>(); foreach (var catData in datas) { if (catData.Key == DataType.Base) { foreach (var kv in catData.Value) { if (kv.Value.GetBindDataType().IsAssignableFrom(propertyType) || !string.IsNullOrEmpty(definer.Converter)) { fields.Add(kv.Key); } } } else { fields.AddRange(catData.Value.Keys); } } fields.Sort(delegate(string e1, string e2) { return(e1.CompareTo(e2)); }); if (fields.Count > 0) { fieldIndex = EditorGUILayout.Popup(fieldIndex, fields.ToArray()); fieldIndex = Mathf.Clamp(fieldIndex, 0, fields.Count - 1); add = true; addkey = new DefinerKey(fields[fieldIndex]); } } else if (currentChainData != null) { if (currentChainData.GetDataType() == DataType.Dictionary) { hashKey = EditorGUILayout.TextField(hashKey); if (!string.IsNullOrEmpty(hashKey)) { add = true; addkey = new DefinerKey(null, -1, hashKey); } } else if (currentChainData.GetDataType() == DataType.List) { dataIndex = Mathf.Max(0, EditorGUILayout.IntField(dataIndex)); add = true; addkey = new DefinerKey(null, dataIndex, null); } } if (definer.KeyChain.Count > 0) { if (GUILayout.Button("Prev")) { definer.RemoveKeyChain(); definer.SerializeKey(); } } if (add) { if (GUILayout.Button("Next")) { definer.AddKeyChain(addkey); definer.SerializeKey(); } } EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Input:"); definer.Key = EditorGUILayout.DelayedTextField(definer.Key); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Converter:"); converterIndex = EditorGUILayout.Popup(converterIndex, convertersStr.ToArray()); definer.Converter = convertersStr[converterIndex]; if (!string.IsNullOrEmpty(definer.Converter)) { definer.ConverterParameter = EditorGUILayout.DelayedTextField(definer.ConverterParameter); if (GUILayout.Button("Clear")) { definer.Converter = ""; } } EditorGUILayout.EndHorizontal(); EditorGUI.indentLevel--; }
private void DoPropertyBind(VMBehaviour vm, GameObject obj) { if (this.Component == null) { Debugger.LogError("DataBinder", obj.name + " component null."); return; } if (string.IsNullOrEmpty(this.Property)) { Debugger.LogError("DataBinder", obj.name + " property empty."); return; } if (componentType == null) { componentType = this.Component.GetType(); componentReflection = ReflectionCache.Singleton[componentType]; } PropertyInfo propertyInfo = componentReflection.GetProperty(this.Property); if (propertyInfo == null || propertyInfo.GetSetMethod() == null) { Debugger.LogError("DataBinder", obj.name + " property null or not support."); return; } Type propertyType = propertyInfo.PropertyType; if (!CheckDataTypeValid(propertyType, obj)) { return; } ISetValue propertySetter = SetterWrapper.CreatePropertySetterWrapper(propertyInfo); if (propertySetter == null) { return; } // 数据单向绑定 this.SetValueHandler = delegate(IData source) { object value = this.Source.FastGetValue(); if (this.Converter != null) { value = this.Converter.Convert(value, propertyType, this.Definer.ConverterParameter, vm); } propertySetter.Set(this.Component, value); // ToggleGroup 特殊处理 if (Toggle_Type.IsAssignableFrom(componentType) && this.Property.Equals("isOn")) { Toggle t = this.Component as Toggle; if (t.group != null && t.isOn) { try { t.group.NotifyToggleOn(t); } catch (System.Exception) { } } } }; this.Source.AddValueChangedListener(this.SetValueHandler); this.SetValueHandler.Invoke(this.Source); // 可交互组件的双向绑定 if (Toggle_Type.IsAssignableFrom(componentType) && this.Property.Equals("isOn")) { this.ValueChangedHandler = new UnityAction <bool>(delegate(bool arg) { if (this.Converter != null) { object value = this.Converter.ConvertBack(arg, this.Source.GetBindDataType(), this.Definer.ConverterParameter, vm); this.Source.FastSetValue(value); } else { (this.Source as BaseData <bool>).Set(arg); } }); (this.Component as Toggle).onValueChanged.AddListener((UnityAction <bool>) this.ValueChangedHandler); } if (Input_Type.IsAssignableFrom(componentType) && this.Property.Equals("text")) { this.ValueChangedHandler = new UnityAction <string>(delegate(string arg) { if (this.Converter != null) { object value = this.Converter.ConvertBack(arg, this.Source.GetBindDataType(), this.Definer.ConverterParameter, vm); this.Source.FastSetValue(value); } else { (this.Source as BaseData <string>).Set(arg); } }); (this.Component as InputField).onValueChanged.AddListener((UnityAction <string>) this.ValueChangedHandler); } if (Dropdown_Type.IsAssignableFrom(componentType) && this.Property.Equals("value")) { this.ValueChangedHandler = new UnityAction <int>(delegate(int arg) { if (this.Converter != null) { object value = this.Converter.ConvertBack(arg, this.Source.GetBindDataType(), this.Definer.ConverterParameter, vm); this.Source.FastSetValue(value); } else { (this.Source as BaseData <int>).Set(arg); } }); (this.Component as Dropdown).onValueChanged.AddListener((UnityAction <int>) this.ValueChangedHandler); } if (Slider_Type.IsAssignableFrom(componentType) && this.Property.Equals("value")) { this.ValueChangedHandler = new UnityAction <float>(delegate(float arg) { if (this.Converter != null) { object value = this.Converter.ConvertBack(arg, this.Source.GetBindDataType(), this.Definer.ConverterParameter, vm); this.Source.FastSetValue(value); } else { (this.Source as BaseData <float>).Set(arg); } }); (this.Component as Slider).onValueChanged.AddListener((UnityAction <float>) this.ValueChangedHandler); } }
public virtual void UnBind() { this.BindVM = null; }
public virtual bool CanBind(VMBehaviour vm, IData data) { return(true); }
public virtual void Bind(VMBehaviour vm, IData data) { this.BindVM = vm; this.BindData = data; }
public virtual bool CanBind(VMBehaviour vm) { return(true); }
public object Convert(object target, Type targetType, object parameter, VMBehaviour context) { return(System.Convert.ToString(target)); }
public object ConvertBack(object target, Type targetType, object parameter, VMBehaviour context) { return(target); }
public virtual void Bind(VMBehaviour vm) { this.BindVM = vm; }
public virtual void BindListItem(VMBehaviour vm, int index) { this.BindVM = vm; }