Пример #1
0
 public DescribableObject RegisterProperty <TVal>(string prop, TVal defaultValue = default(TVal), bool isReadOnly = false)
 {
     if (prop == "Item")
     {
         throw new ArgumentException("Item property name is reserved for indexer properties, please choose another name");
     }
     InternalDictionary[prop] = new DescribableProperty(prop, isReadOnly, defaultValue);
     return(this);
 }
Пример #2
0
 /// <summary>
 /// Only call this for quickly registering the properties of the class, instead of calling RegisterProperty in the constructor each time
 /// </summary>
 /// <typeparam name="TVal">the type of the value to get</typeparam>
 /// <param name="prop">the property name (gets auto filled)</param>
 /// <param name="isReadOnly">if the property is read only or not</param>
 /// <param name="defaultValue"></param>
 /// <returns></returns>
 public TVal RegisterAndGet <TVal>([CallerMemberName] string prop = null, bool isReadOnly = false, TVal defaultValue = default(TVal))
 {
     if (InternalDictionary.TryGetValue(prop, out var p))
     {
         return((TVal)p.Value);
     }
     else
     {
         InternalDictionary[prop] = new DescribableProperty(prop, isReadOnly, defaultValue);
         return(defaultValue);
     }
 }
Пример #3
0
 /// <summary>
 /// Only call this for quickly registering the properties of the class, instead of calling RegisterProperty in the constructor each time
 /// </summary>
 /// <typeparam name="TVal">the type of the new value</typeparam>
 /// <param name="value">the new value</param>
 /// <param name="prop">the property name (gets auto filled)</param>
 /// <param name="isReadOnly">if the property is read only or not</param>
 /// <param name="defaultValue"></param>
 public void RegisterAndSet <TVal>(TVal value, [CallerMemberName] string prop = null, bool isReadOnly = false, TVal defaultValue = default(TVal))
 {
     if (prop == "Item")
     {
         throw new ArgumentException("Item property name is reserved for indexer properties, please choose another name");
     }
     if (InternalDictionary.TryGetValue(prop, out var p))
     {
         Before_Set(prop, value);
         p.Value = value;
         After_Set(prop, value);
     }
     else
     {
         p = new DescribableProperty(prop, isReadOnly, defaultValue);
         InternalDictionary[prop] = p;
         Before_Set(prop, value);
         p.Value = value;
         After_Set(prop, value);
     }
 }
Пример #4
0
        /// <summary>
        /// registers an indexer then returns the current type
        /// </summary>
        /// <param name="descriptor"></param>
        /// <returns></returns>
        public DescribableObject RegisterIndexer(IndexerDescriptor descriptor)
        {
            IndexerDescriptorContainer idc;

            if (InternalDictionary.TryGetValue("Item", out var dc))
            {
                if (dc.Value is IndexerDescriptorContainer)
                {
                    idc = dc.Value as IndexerDescriptorContainer;
                }
                else
                {
                    //Item must always be the indexer descriptor container
                    dc.Value = idc = new IndexerDescriptorContainer();
                }
            }
            else
            {
                InternalDictionary["Item"] = new DescribableProperty("Item", true, idc = new IndexerDescriptorContainer());
            }
            idc[descriptor.GetHashCode()] = descriptor;
            return(this);
        }
Пример #5
0
        public virtual void SetPropertyValue <TVal>(TVal value, [CallerMemberName] string prop = null)
        {
            var paths = Helpers.ParsePropertyParts(prop);

            if (paths.Length == 0)
            {
                return;
            }
            int lastIndex = 0;
            //check if last path was an indexer

            /*
             *   A=value -> Get Owner = this, owner["A"] = value
             *   A.B=value -> Get Owner = A, owner["B"] = value
             *   Item[A,B]=value -> Get Indexer = Item[A,B],indexer[A,B] = value
             *   A.Item[A,B]=value -> Get Indexer = Item[A,B], indexer [A,B] = value
             */
            var lastPath = paths[paths.Length - 1];

            if (lastPath.Contains("["))
            {
                //last part is an indexer
                lastIndex = paths.Length - 1;
            }
            else
            {
                lastIndex = paths.Length - 2;
            }
            DescribableObject curObj = this;

            //end loop before reaching last part
            for (int i = 0; i <= lastIndex; i++)
            {
                if (curObj == null)
                {
                    break;
                }
                //each iteration yields a curObj or an ownerIndexer
                var path     = paths[i];
                var purePath = path.Contains("[") ? path.Substring(0, path.IndexOf('[')) : path;
                if (purePath.Length == 0)
                {
                    purePath = "Item";
                }
                if (curObj.InternalDictionary.TryGetValue(purePath, out DescribableProperty dProperty))
                {
                    if (path.Contains("["))
                    {
                        IndexerDescriptorContainer idc;
                        if (dProperty.Value is IndexerDescriptorContainer)
                        {
                            idc = dProperty.Value as IndexerDescriptorContainer;
                        }
                        else if (dProperty.Value is DescribableObject dindexer)
                        {
                            idc = dindexer.InternalDictionary["Item"].Value as IndexerDescriptorContainer;
                            Console.WriteLine("A logically impossible case just happened ! please tell the developers (me) that they suck");
                        }
                        else
                        {
                            return;
                        }
                        //now we have the indexer container, curObj = result value, or either final value = result value
                        var pureIndexedParameters = path.Substring(path.IndexOf('[') + 1, path.Length - purePath.Length - 2);

                        var desc = idc.GetDescriptor(pureIndexedParameters, out var indices, out bool suc);
                        if (!suc)
                        {
                            return;
                        }
                        var matchDict = new MethodParameterValue[desc.Parameters.Length];
                        for (int j = 0; j < desc.Parameters.Length; j++)
                        {
                            var param = desc.Parameters[j];
                            matchDict[j] = new MethodParameterValue(param, indices[j]);
                        }
                        if (i == lastIndex)
                        {
                            //set indexer here
                            if (desc.IsReadOnly)
                            {
                                return;
                            }
                            curObj.Before_Set(path, value);
                            desc.SetValue(matchDict, value);
                            curObj.After_Set(path, value);
                            return;
                        }
                        else
                        {
                            //get owner object
                            var IndexerRes = desc.GetValue <object>(matchDict);
                            //check indexer result
                            if (IndexerRes is DescribableObject d)
                            {
                                curObj = d;
                            }
                            else
                            {
                                curObj = null;
                            }
                        }
                    }
                    else if (dProperty.Value is DescribableObject d)
                    {
                        curObj = d;
                    }
                    else
                    {
                        curObj = null;
                    }
                }
                else
                {
                    return;
                }
            }

            if (curObj == null)
            {
                return;
            }

            if (curObj.InternalDictionary.TryGetValue(lastPath, out var dp))
            {
                if (dp.IsReadOnly)
                {
                    return;
                }
                curObj.Before_Set(dp.Name, value);
                dp.Value = value;
                curObj.After_Set(dp.Name, value);
            }
            else
            {
                dp = new DescribableProperty(lastPath, false)
                {
                    Value = value
                };
                //unregistered property
                curObj.Before_Set(dp.Name, value);
                curObj.InternalDictionary[lastPath] = dp;
                curObj.After_Set(dp.Name, value);
            }
        }