Example #1
0
        /// <summary>
        /// Returns the link to the matching resource in the market place if found or creates a new clone copy for future transactions
        /// This allows this action to be performed once to store the link rather than at every transaction
        /// This functionality allows resources not in the market at the start of the simulation to be traded.
        /// </summary>
        /// <param name="resourceType">The resource type to trade</param>
        /// <returns>Whether the search was successful</returns>
        public IResourceWithTransactionType LinkToMarketResourceType(CLEMResourceTypeBase resourceType)
        {
            if (!(this.Parent is Market))
            {
                throw new ApsimXException(this, $"Logic error in code. Trying to link a resource type [r={resourceType.Name}] from the market with the same market./nThis is a coding issue. Please contact the developers");
            }

            // find parent group type
            ResourceBaseWithTransactions parent   = (resourceType as Model).Parent as ResourceBaseWithTransactions;
            ResourceBaseWithTransactions resGroup = GetResourceGroupByType(parent.GetType()) as ResourceBaseWithTransactions;

            if (resGroup is null)
            {
                // add warning the market is not currently trading in this resource
                string zoneName = FindAncestor <Zone>().Name;
                string warn     = $"[{zoneName}] is currently not accepting resources of type [r={parent.GetType().ToString()}]\nOnly resources groups provided in the [r=ResourceHolder] in the simulation tree will be traded.";
                if (!Warnings.Exists(warn) & Summary != null)
                {
                    Summary.WriteWarning(this, warn);
                    Warnings.Add(warn);
                }
                return(null);
            }

            // TODO: do some group checks. land units, currency

            // TODO: if market and looking for finance only return or create "Bank"

            // find resource type in group
            object resType = resGroup.GetByName((resourceType as IModel).Name) as IResourceWithTransactionType;

            if (resType is null)
            {
                // clone resource
                // too many problems with linked events to clone these objects and setup again
                // it will be the responsibility of the user to ensure the resources and details are in the market
                // resType = Apsim.Clone(resourceType);

                if (resType is null)
                {
                    // add warning the market does not have the resource
                    string zoneName = FindAncestor <Zone>().Name;
                    string warn     = $"The resource [r={resourceType.Parent.Name}.{resourceType.Name}] does not exist in [m={this.Parent.Name}].\nAdd resource and associated components to the market to permit trading.";
                    if (!Warnings.Exists(warn) & Summary != null)
                    {
                        Summary.WriteWarning(this, warn);
                        Warnings.Add(warn);
                    }
                    return(null);
                }
                else
                {
                    (resType as IModel).Parent            = resGroup;
                    (resType as CLEMModel).CLEMParentName = resGroup.CLEMParentName;
                    // add new resource type
                    resGroup.AddNewResourceType(resType as IResourceWithTransactionType);
                }
            }
            return(resType as IResourceWithTransactionType);
        }
Example #2
0
        /// <summary>
        /// Returns the link to the matching resource in the market place if found or creates a new clone copy for future transactions
        /// This allows this action to be performed once to store the link rather than at every transaction
        /// This functionality allows resources not in the market at the start of the simulation to be traded.
        /// </summary>
        /// <param name="resourceType">The resource type to trade</param>
        /// <param name="linkToResourceType">A link to the associated resource type</param>
        /// <returns>Whether the search was successful</returns>
        public bool ResourceTypeExists(CLEMResourceTypeBase resourceType, out object linkToResourceType)
        {
            linkToResourceType = null;

            // find parent group type
            ResourceBaseWithTransactions parent   = (resourceType as Model).Parent as ResourceBaseWithTransactions;
            ResourceBaseWithTransactions resGroup = GetResourceGroupByType(parent.GetType()) as ResourceBaseWithTransactions;

            if (resGroup is null)
            {
                // add warning the market is not currently trading in this resource
                string zoneName = Apsim.Parent(this, typeof(Zone)).Name;
                Warnings.Add($"[{zoneName}] is currently not accepting resources of type [r={parent.GetType().ToString()}]\nOnly resources groups provided in the [r=ResourceHolder] in the simulation tree will be traded.");
                return(false);
            }

            // TODO: do some group checks. land units, currency

            // TODO: if market and looking for finance only return or create "Bank"

            // find resource type in group
            var resType = resGroup.GetByName((resourceType as IModel).Name);

            if (resType is null)
            {
                // clone resource
                resType = resourceType.Clone as CLEMResourceTypeBase;
                (resType as IModel).Parent = resGroup;

                // wire up events
                resGroup.AddChildEvents(resType as IResourceWithTransactionType);
            }
            linkToResourceType = resType;
            return(true);
        }
Example #3
0
        /// <summary>
        /// Returns the link to the matching resource in the market place if found or creates a new clone copy for future transactions
        /// This allows this action to be performed once to store the link rather than at every transaction
        /// This functionality allows resources not in the market at the start of the simulation to be traded.
        /// </summary>
        /// <param name="resourceType">The resource type to trade</param>
        /// <returns>Whether the search was successful</returns>
        public IResourceWithTransactionType LinkToMarketResourceType(CLEMResourceTypeBase resourceType)
        {
            if (!this.Parent.GetType().Name.Contains("Market"))
            {
                throw new ApsimXException(this, "ooops");
            }

            // find parent group type
            ResourceBaseWithTransactions parent   = (resourceType as Model).Parent as ResourceBaseWithTransactions;
            ResourceBaseWithTransactions resGroup = GetResourceGroupByType(parent.GetType()) as ResourceBaseWithTransactions;

            if (resGroup is null)
            {
                // add warning the market is not currently trading in this resource
                string zoneName = Apsim.Parent(this, typeof(Zone)).Name;
                Warnings.Add($"[{zoneName}] is currently not accepting resources of type [r={parent.GetType().ToString()}]\nOnly resources groups provided in the [r=ResourceHolder] in the simulation tree will be traded.");
                return(null);
            }

            // TODO: do some group checks. land units, currency

            // TODO: if market and looking for finance only return or create "Bank"

            // find resource type in group
            object resType = resGroup.GetByName((resourceType as IModel).Name) as IResourceWithTransactionType;

            if (resType is null)
            {
                // clone resource
                resType = Apsim.Clone(resourceType);

                if (resType is null)
                {
                    // add warning the market does not have the resource
                    string zoneName = Apsim.Parent(this, typeof(Zone)).Name;
                    Warnings.Add($"The resource [r={resourceType.Name}] does not exist in the market and the resource of type [r={resourceType.GetType().ToString()}] cannot be cloned\nAdd resource and associated components to the market.");
                    return(null);
                }
                else
                {
                    (resType as IModel).Parent = resGroup;
                    // add new resource type
                    resGroup.AddNewResourceType(resType as IResourceWithTransactionType);
                }
            }
            return(resType as IResourceWithTransactionType);
        }
Example #4
0
        /// <summary>
        /// Returns the link to the matching resource in the market place if found or creates a new clone copy for future transactions
        /// This allows this action to be performed once to store the link rather than at every transaction
        /// This functionality allows resources not in the market at the start of the simulation to be traded.
        /// </summary>
        /// <param name="resourceType">The resource type to trade</param>
        /// <returns>Whether the search was successful</returns>
        public IResourceWithTransactionType LinkToMarketResourceType(CLEMResourceTypeBase resourceType)
        {
            if (!(this.Parent is Market))
            {
                throw new ApsimXException(this, $"Logic error in code. Trying to link a resource type [r={resourceType.Name}] from the market with the same market./nThis is a coding issue. Please contact the developers");
            }

            // find parent group type
            ResourceBaseWithTransactions parent = (resourceType as Model).Parent as ResourceBaseWithTransactions;

            if (!(FindResource(parent.GetType()) is ResourceBaseWithTransactions resourceGroupInMarket))
            {
                // add warning the market is not currently trading in this resource
                string zoneName = FindAncestor <Zone>().Name;
                string warn     = $"[{zoneName}] is currently not accepting resources of type [r={parent.GetType().Name}]\r\nOnly resources groups provided in the [r=ResourceHolder] in the simulation tree will be traded.";
                Warnings.CheckAndWrite(warn, Summary, this);
                return(null);
            }

            // TODO: do some group checks. land units, currency

            // TODO: if market and looking for finance only return or create "Bank"

            // find resource type in group
            object resType = resourceGroupInMarket.FindChild <IResourceWithTransactionType>(resourceType.Name);

            // clone resource: too many problems with linked events to clone these objects and setup again
            // it will be the responsibility of the user to ensure the resources and details are in the market
            if (resType is null)
            {
                // add warning the market does not have the resource
                string warn = $"The resource [r={resourceType.Parent.Name}.{resourceType.Name}] does not exist in [m={this.Parent.Name}].\r\nAdd resource and associated components to the market to permit trading.";
                Warnings.CheckAndWrite(warn, Summary, this);
                return(null);
            }

            // TODO: create a clone of the resource and put it in the market

            return(resType as IResourceWithTransactionType);
        }
Example #5
0
        /// <summary>
        /// Find a resource type from  type of resources and name of resource type component
        /// </summary>
        /// <typeparam name="T">Type of ResourceType to return</typeparam>
        /// <typeparam name="R">Type of Resource group containing resource type</typeparam>
        /// <param name="requestingModel">The model requesting this resource</param>
        /// <param name="resourceName">The name identifier NameOfResource.NameOfResourceType or simply NameOfResourceType</param>
        /// <param name="missingResourceAction">Action if resource group missing</param>
        /// <param name="missingResourceTypeAction">Action if resource type is missing</param>
        /// <returns>A resource type component</returns>
        public T FindResourceType <R, T>(IModel requestingModel, string resourceName, OnMissingResourceActionTypes missingResourceAction = OnMissingResourceActionTypes.Ignore, OnMissingResourceActionTypes missingResourceTypeAction = OnMissingResourceActionTypes.Ignore) where T : IResourceType where R : ResourceBaseWithTransactions
        {
            string[] nameParts = new string[] { "", resourceName };
            if (nameParts.Last().Contains('.'))
            {
                nameParts = nameParts.Last().Split('.');
                if (nameParts.Length > 2)
                {
                    throw new ApsimXException(requestingModel, $"Invalid resource name identifier for [{requestingModel.Name}], expecting 'ResourceName.ResourceTypeName' or 'ResourceTypeName'. Value provided [{resourceName}]");
                }
            }

            // not sure it's quickets to find the resource then look at it's children
            // or look through all descendents for the type and name
            // if we find children then we use R as a double check

            bool searchForAllIresourceType = false;
            bool resGroupNameMatch         = true;
            T    resType = default(T);
            ResourceBaseWithTransactions resGroup = null;

            if (!typeof(R).IsSubclassOf(typeof(ResourceBaseWithTransactions)))
            {
                if (nameParts.First() == "")
                {
                    searchForAllIresourceType = true;
                }
                else
                {
                    // find resource by name
                    resGroup = FindChild <R>(nameParts.First());
                }
            }
            else
            {
                resGroup = (nameParts.First() != "") ? FindResource <R>(nameParts.First()) : FindResource <R>();
                if (resGroup == null && nameParts.First() != "")
                {
                    // no resource name match so try with just the type
                    resGroupNameMatch = false;
                    resGroup          = FindResource <R>();
                }
            }

            if (searchForAllIresourceType)
            {
                resType = FindAllDescendants <T>(nameParts.Last()).FirstOrDefault();
            }
            else
            {
                if (resGroup != null)
                {
                    resType = (resGroup as IModel).FindChild <T>(nameParts.Last());
                }
            }

            string errorMsg;

            if (resGroup == null)
            {
                errorMsg = $"Unable to locate resource group [r={typeof(R).Name}] for [a={requestingModel.Name}]";

                switch (missingResourceAction)
                {
                case OnMissingResourceActionTypes.ReportErrorAndStop:
                    throw new ApsimXException(this, errorMsg);

                case OnMissingResourceActionTypes.ReportWarning:
                    Warnings.CheckAndWrite(errorMsg, Summary, this);
                    break;

                default:
                    break;
                }
                return(default(T));
            }
            else
            {
                if (!resGroupNameMatch)
                {
                    errorMsg = $"Unable to locate resource named [r={nameParts.First()}] for [a={requestingModel.Name}] but a [{typeof(R).Name}] resource was found and will be used.";
                    Warnings.CheckAndWrite(errorMsg, Summary, this);
                }
            }

            if (resType as IModel is null)
            {
                errorMsg = $"Unable to locate resource type [r={nameParts.Last()}] in [r={resGroup.Name}] for [a={requestingModel.Name}]";
                switch (missingResourceTypeAction)
                {
                case OnMissingResourceActionTypes.ReportErrorAndStop:
                    throw new ApsimXException(this, errorMsg);

                case OnMissingResourceActionTypes.ReportWarning:
                    Warnings.CheckAndWrite(errorMsg, Summary, this);
                    break;

                default:
                    break;
                }
            }
            return(resType);
        }