Code development platform for open source projects from the European Union institutions :large_blue_circle: EU Login authentication by SMS has been phased out. To see alternatives please check here

Skip to content
Snippets Groups Projects
Select Git revision
  • a82bba5bf433cad9a0fb394bdd8e17ca61e22997
  • tug-dev default
  • amdm3/develop
  • fix/scripts1
  • amdm2/develop
  • amdm2/main
  • playground
  • feat/changelog
  • fix/solution_tests
  • test/full_release_process
  • test/art10_test_execution
  • test/gitlab_files_api
  • test/multiplatform_david
  • trgbot
  • set-sast-config-3
  • set-sast-config-2
  • set-secret-detection-config-2
  • set-secret-detection-config-1
  • set-sast-config-1
  • test-linux-fixes
  • tug-stable
  • Release/v4.3.2
  • v1.0.1
  • v1.0.0
  • Build/v0.7.10.2996
  • v0.7.5b0+2524.multistep
  • Release/v3.3.14.2981-RC
  • Build/v0.7.9.2975
  • Release/v3.3.13.2924
  • Release/v3.3.13.2891-RC
  • Build/0.7.9.2890
  • Build/v0.7.9.2864
  • Build/v0.7.9.2849
  • Build/v0.7.9.2836
  • Release/TrailerTool_V0.9.0.2759
  • Release/TrailerTool_V0.9.0.2735
  • Release/TrailerTool_V0.9.0.2799
  • Release/v3.3.12.2800
  • Release/v3.3.12.2769-RC
  • Build/v0.7.9.2741
  • Build/v0.5.0.1812_VectoFF
41 results

Program.cs

Blame
  • Forked from VECTO / VECTO Sim
    Source project has a limited visibility.
    Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    BackingStorage.cs 3.70 KiB
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.ComponentModel;
    using System.Linq;
    using System.Reflection;
    using TUGraz.VectoCommon.Utils;
    
    namespace VECTO3GUI2020.ViewModel.Implementation.Common
    {
    	public class BackingStorage<T> : ObservableObject 
    		where T : INotifyPropertyChanged
    	{
    
    		delegate object GetterDelegate();
    		private IReadOnlyCollection<string> _observedProperties;
    		private T _observedObject;
    
    		private Dictionary<string, GetterDelegate> _getterDelegatesMap = new Dictionary<string, GetterDelegate>();
    		private Dictionary<string, Type> _propertyTypesMap = new Dictionary<string, Type>();
    		private IDictionary<string, IEqualityComparer> _equalityComparers = new Dictionary<string, IEqualityComparer>();
    
    		private IDictionary<string, object> _savedValues = null;
    		private IDictionary<string, object> _unsavedChanges = new Dictionary<string, object>();
    		private IDictionary<string, object> _currentValues = new Dictionary<string, object>();
    
    
    		public BackingStorage(T observedObject, params string[] observedProperties)
    		{
    			_observedProperties = new HashSet<string>(observedProperties);
    			_observedObject = observedObject;
    			observedObject.PropertyChanged += OnObservedPropertyChanged;
    		}
    
    		public bool UnsavedChanges
    		{
    			get => (_savedValues == null) || (_unsavedChanges.Count != 0);
    		}
    
    		private void ResetUnsavedChanges()
    		{
    			OnPropertyChanged(nameof(UnsavedChanges));
    			_unsavedChanges.Clear();
    		}
    
    		public void SaveChanges()
    		{
    			_savedValues = new ReadOnlyDictionary<string, object>(new Dictionary<string, object>(_currentValues));
    			ResetUnsavedChanges();
    		}
    
    		private void OnObservedPropertyChanged(object sender, PropertyChangedEventArgs e)
    		{
    			var propertyName = e.PropertyName;
    			if (!_observedProperties.Contains(propertyName)) {
    				return;
    			}
    
    			if (!_getterDelegatesMap.ContainsKey(propertyName)) {
    				StorePropertyInfo(propertyName);
    			}
    
    			UpdateValue(propertyName);
    		}
    
    		private void UpdateValue(string propertyName)
    		{
    			
    			var newValue = _getterDelegatesMap[propertyName]();
    			_currentValues[propertyName] = newValue;
    			if (ValueHasChanged(newValue, propertyName)) {
    				_unsavedChanges[propertyName] = newValue;
    			} else {
    				_unsavedChanges.Remove(propertyName);
    			}
    			OnPropertyChanged(nameof(UnsavedChanges));
    		}
    
    		private bool ValueHasChanged(object newValue, string propertyName)
    		{
    			if (_savedValues == null
    				|| !_savedValues.ContainsKey(propertyName)) {
    				return true;
    			}
    
    			var savedValue = _savedValues[propertyName];
    
    			if (_equalityComparers.ContainsKey(propertyName)) {
    				var equalityComparer = _equalityComparers[propertyName];
    				return !equalityComparer.Equals(newValue, savedValue);
    			} else {
    				return newValue == savedValue;
    			}
    		}
    
    		private void StorePropertyInfo(string propertyName)
    		{
    			var propInfo = _observedObject.GetType().GetProperty(propertyName);
    
    
    			var propertyType = propInfo.PropertyType;
    			_propertyTypesMap[propertyName] = propInfo.PropertyType;
    
    			try {
    				_equalityComparers[propertyName] = CreateEqualityComparer(propertyType);
    			} catch (Exception ex) {
    				// TODO;
    			}
    			
    
    
    			var getMethod = propInfo.GetGetMethod();
    			var getterDelegate = (GetterDelegate)getMethod.CreateDelegate(typeof(GetterDelegate), _observedObject);
    			_getterDelegatesMap[propertyName] = getterDelegate;
    
    
    		}
    
    		private static IEqualityComparer CreateEqualityComparer(Type type)
    		{
    
    			Type myGeneric = typeof(EqualityComparer<>);
    			Type constructedClass = myGeneric.MakeGenericType(type);
    			return (IEqualityComparer)constructedClass
    				.GetProperty(nameof(EqualityComparer<T>.Default), BindingFlags.Static | BindingFlags.Public)
    				.GetValue(null);
    
    		}
    	}
    }