public static ResourceResponse WebControlResourceRequest(object o, ResourceRequestEventArgs e)
        {
            // This tries to get a local resource. If there is no local resource null is returned by GetLocalResource, which
            // triggers the default handler, which should respect the "target='_blank'" attribute added
            // in ParsedDocument.ToHtml(), thus avoiding a bug in Awesomium where trying to navigate to a
            // local resource fails when showing an in-memory file (https://github.com/Code52/DownmarkerWPF/pull/208)

            // What works:
            //	- resource requests for remote resources (like <link href="http://somecdn.../jquery.js"/>)
            //	- resource requests for local resources that exist relative to filename of the file (like <img src="images/logo.png"/>)
            //	- clicking links for remote resources (like [Google](http://www.google.com))
            //	- clicking links for local resources which don't exist (eg [test](test)) does nothing (WebControl_LinkClicked checks for existence)
            // What fails:
            //	- clicking links for local resources where the resource exists (like [test](images/logo.png))
            //		- This _sometimes_ opens the resource in the preview pane, and sometimes opens the resource
            //		using Process.Start (WebControl_LinkClicked gets triggered). The behaviour seems stochastic.
            //	- alt text for images where the image resource is not found

            if (e.Request.Url.StartsWith(LocalRequestUrlBase))
            {
                return(GetLocalResource(e.Request.Url.Replace(LocalRequestUrlBase, "")));
            }

            // If the request wasn't local, return null to let the usual handler load the url from the network
            return(null);
        }
        private ResourceResponse WebBrowserOnResourceRequest(object sender, ResourceRequestEventArgs resourceRequestEventArgs)
        {
            string url = resourceRequestEventArgs.Request.Url;

            if (url.StartsWith(LocalhostWidgetUrl, StringComparison.InvariantCultureIgnoreCase))
            {
                if (resourceRequestEventArgs.Request.Method.Equals("post", StringComparison.InvariantCultureIgnoreCase) &&
                    resourceRequestEventArgs.Request.UploadElementsCount > 0)
                {
                    if (resourceRequestEventArgs.Request.UploadElementsCount < 1)
                    {
                        throw new InvalidOperationException();
                    }

                    var    uploadElement = resourceRequestEventArgs.Request.GetUploadElement(0);
                    string data          = uploadElement.GetBytes();
                    PostAction(() => ProcessLoginComplete(data));
                }

                var widgetBytes = Encoding.UTF8.GetBytes(_widgetHtml);
                var response    = new ResourceResponse(widgetBytes, "text/html");

                return(response);
            }

            return(null);
        }
Exemple #3
0
    private Awesomium.Mono.ResourceResponse OnResourceRequest(System.Object sender, ResourceRequestEventArgs args)
    {
        if (IsBlackListedRequest(args.Request.Url))
        {
            RaiseURLChangeRequestEvent(args.Request.Url);
            args.Request.Cancel();
        }

        if (requestReplacements.ContainsKey(args.Request.Url))
        {
            return(new Awesomium.Mono.ResourceResponse(requestReplacements[args.Request.Url]));
        }

        return(new Awesomium.Mono.ResourceResponse(args.Request.Url));
    }
        public static ResourceResponse WebControlResourceRequest(object o, ResourceRequestEventArgs e)
        {
            // This tries to get a local resource. If there is no local resource null is returned by GetLocalResource, which
            // triggers the default handler, which should respect the "target='_blank'" attribute added
            // in ParsedDocument.ToHtml(), thus avoiding a bug in Awesomium where trying to navigate to a
            // local resource fails when showing an in-memory file (https://github.com/Code52/DownmarkerWPF/pull/208)

            // What works:
            //	- resource requests for remote resources (like <link href="http://somecdn.../jquery.js"/>)
            //	- resource requests for local resources that exist relative to filename of the file (like <img src="images/logo.png"/>)
            //	- clicking links for remote resources (like [Google](http://www.google.com))
            //	- clicking links for local resources which don't exist (eg [test](test)) does nothing (WebControl_LinkClicked checks for existence)
            // What fails:
            //	- clicking links for local resources where the resource exists (like [test](images/logo.png))
            //		- This _sometimes_ opens the resource in the preview pane, and sometimes opens the resource
            //		using Process.Start (WebControl_LinkClicked gets triggered). The behaviour seems stochastic.
            //	- alt text for images where the image resource is not found

            if (e.Request.Url.StartsWith(LocalRequestUrlBase)) return GetLocalResource(e.Request.Url.Replace(LocalRequestUrlBase, ""));

            // If the request wasn't local, return null to let the usual handler load the url from the network
            return null;
        }
Exemple #5
0
        private static ResourceResponse OnRessourceRequest(object sender, ResourceRequestEventArgs e)
        {
            string host = GetHost(e.Request.Url);
            if (host == null || blockedHosts.Contains(host))
            {
                PrintMessage("blocked: " + host);

                //ignore request from this domain
                e.Request.Cancel();
                return null;
            }
            lastAction = DateTime.Now;
            PrintMessage("ressource: " + e.Request.Url);
            return new ResourceResponse(e.Request.Url);
        }
Exemple #6
0
        private void OnEndOfMonth(object sender, EventArgs e)
        {
            // Interest is paid and earned on the last day of the month after all other acitivites have made financial transactions.
            // Interest payment does not occur in the Activity order.

            Status = ActivityStatus.NotNeeded;
            if (financesExist)
            {
                // make interest payments on bank accounts
                foreach (FinanceType accnt in Apsim.Children(Resources.FinanceResource(), typeof(FinanceType)))
                {
                    if (accnt.Balance > 0)
                    {
                        accnt.Add(accnt.Balance * accnt.InterestRatePaid / 1200, this, "Interest earned");
                        SetStatusSuccess();
                    }
                    else
                    {
                        double interest = Math.Round(Math.Abs(accnt.Balance) * accnt.InterestRateCharged / 1200, 2, MidpointRounding.ToEven);
                        if (Math.Abs(accnt.Balance) * accnt.InterestRateCharged / 1200 != 0)
                        {
                            ResourceRequest interestRequest = new ResourceRequest
                            {
                                ActivityModel      = this,
                                Required           = interest,
                                AllowTransmutation = false,
                                Reason             = "Pay interest charged"
                            };
                            accnt.Remove(interestRequest);

                            // report status
                            if (interestRequest.Required > interestRequest.Provided)
                            {
                                interestRequest.ResourceType     = typeof(Finance);
                                interestRequest.ResourceTypeName = accnt.Name;
                                interestRequest.Available        = accnt.FundsAvailable;
                                ResourceRequestEventArgs rre = new ResourceRequestEventArgs()
                                {
                                    Request = interestRequest
                                };
                                OnShortfallOccurred(rre);

                                switch (OnPartialResourcesAvailableAction)
                                {
                                case OnPartialResourcesAvailableActionTypes.ReportErrorAndStop:
                                    throw new ApsimXException(this, String.Format("Insufficient funds in [r={0}] to pay interest charged.\nConsider changing OnPartialResourcesAvailableAction to Skip or Use Partial.", accnt.Name));

                                case OnPartialResourcesAvailableActionTypes.SkipActivity:
                                    Status = ActivityStatus.Ignored;
                                    break;

                                case OnPartialResourcesAvailableActionTypes.UseResourcesAvailable:
                                    Status = ActivityStatus.Partial;
                                    break;

                                default:
                                    break;
                                }
                            }
                            else
                            {
                                Status = ActivityStatus.Success;
                            }
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Method used to perform activity if it can occur as soon as resources are available.
        /// </summary>
        public override void DoActivity()
        {
            this.Status = ActivityStatus.NotNeeded;

            // get labour shortfall
            double labourLimit = this.LabourLimitProportion;
            // get finance purchase shortfall
            double financeLimit = (spent - earned > 0) ? Math.Min(bankAccount.Amount, spent - earned) / (spent - earned) : 1;

            if (resourceList.Count() == 0)
            {
                if (currentEntries.Count > 0)
                {
                    this.Status = ActivityStatus.Warning;
                }
                return;
            }
            else
            {
                if (financeLimit < 1)
                {
                    ResourceRequest purchaseRequest = new ResourceRequest
                    {
                        ActivityModel      = this,
                        Required           = spent - earned,
                        Available          = bankAccount.Amount,
                        Provided           = bankAccount.Amount,
                        AllowTransmutation = false,
                        ResourceType       = typeof(Finance),
                        ResourceTypeName   = AccountName,
                        Category           = "External purchases"
                    };
                    ResourceRequestEventArgs rre = new ResourceRequestEventArgs()
                    {
                        Request = purchaseRequest
                    };
                    OnShortfallOccurred(rre);
                }

                if (financeLimit < 1 || labourLimit < 1)
                {
                    switch (OnPartialResourcesAvailableAction)
                    {
                    case OnPartialResourcesAvailableActionTypes.ReportErrorAndStop:
                        Summary.WriteWarning(this, $"Ensure resources are available or change OnPartialResourcesAvailableAction setting for activity [a={this.NameWithParent}]");
                        Status = ActivityStatus.Critical;
                        throw new ApsimXException(this, $"Insufficient resources [r={AccountName}] for activity [a={this.NameWithParent}]");

                    case OnPartialResourcesAvailableActionTypes.SkipActivity:
                        this.Status = ActivityStatus.Ignored;
                        return;

                    default:
                        break;
                    }
                    this.Status = ActivityStatus.Partial;
                }
                else
                {
                    this.Status = ActivityStatus.Success;
                }

                // loop through all resources to exchange and make transactions
                for (int i = 0; i < currentEntries.Count; i++)
                {
                    if (resourceList[i] is null)
                    {
                        this.Status = ActivityStatus.Warning;
                    }
                    else
                    {
                        // matching resource was found
                        double amount = Convert.ToDouble(currentEntries[i][fileResource.AmountColumnName], CultureInfo.InvariantCulture);
                        bool   isSale = (amount < 0);
                        amount = Math.Abs(amount);
                        ResourcePricing price = null;
                        if (bankAccount != null && !(resourceList[i] is FinanceType))
                        {
                            price = resourceList[i].Price((amount > 0 ? PurchaseOrSalePricingStyleType.Purchase : PurchaseOrSalePricingStyleType.Sale));
                        }
                        // transactions
                        if (isSale)
                        {
                            // sell, so limit to labour and amount available
                            amount = Math.Min(amount * labourLimit, resourceList[i].Amount);
                            if (amount > 0)
                            {
                                if (price != null)
                                {
                                    double packets = amount / price.PacketSize;
                                    if (price.UseWholePackets)
                                    {
                                        packets = Math.Truncate(packets);
                                        amount  = packets * price.PacketSize;
                                    }
                                    bankAccount.Add(packets * price.PricePerPacket, this, (resourceList[i] as CLEMModel).NameWithParent, "External output");
                                }
                                ResourceRequest sellRequest = new ResourceRequest
                                {
                                    ActivityModel      = this,
                                    Required           = amount,
                                    AllowTransmutation = false,
                                    Category           = "External output",
                                    RelatesToResource  = (resourceList[i] as CLEMModel).NameWithParent
                                };
                                resourceList[i].Remove(sellRequest);
                            }
                        }
                        else
                        {
                            // limit to labour and financial constraints as this is a purchase
                            amount *= Math.Min(labourLimit, financeLimit);
                            if (amount > 0)
                            {
                                if (price != null)
                                {
                                    // need to limit amount by financial constraints
                                    double packets = amount / price.PacketSize;
                                    if (price.UseWholePackets)
                                    {
                                        packets = Math.Truncate(packets);
                                    }
                                    amount = packets * price.PacketSize;
                                    ResourceRequest sellRequestDollars = new ResourceRequest
                                    {
                                        ActivityModel      = this,
                                        Required           = packets * price.PacketSize,
                                        AllowTransmutation = false,
                                        Category           = "External input",
                                        RelatesToResource  = (resourceList[i] as CLEMModel).NameWithParent
                                    };
                                    bankAccount.Remove(sellRequestDollars);
                                }
                                resourceList[i].Add(amount, this, (resourceList[i] as CLEMModel).NameWithParent, "External input");
                            }
                        }
                    }
                }
            }
        }
        private void BuyWithTrucking()
        {
            // This activity will purchase animals based on available funds.
            RuminantHerd ruminantHerd = Resources.RuminantHerd();

            int    trucks         = 0;
            int    head           = 0;
            double aESum          = 0;
            double fundsAvailable = 0;

            if (bankAccount != null)
            {
                fundsAvailable = bankAccount.FundsAvailable;
            }
            double cost          = 0;
            double shortfall     = 0;
            bool   fundsexceeded = false;

            // get current untrucked list of animal purchases
            List <Ruminant> herd = ruminantHerd.PurchaseIndividuals.Where(a => a.BreedParams.Breed == this.PredictedHerdBreed).OrderByDescending(a => a.Weight).ToList();

            if (herd.Count() == 0)
            {
                return;
            }

            // if purchase herd > min loads before allowing trucking
            if (herd.Select(a => a.Weight / 450.0).Sum() / trucking.Number450kgPerTruck >= trucking.MinimumTrucksBeforeSelling)
            {
                // while truck to fill
                while (herd.Select(a => a.Weight / 450.0).Sum() / trucking.Number450kgPerTruck > trucking.MinimumLoadBeforeSelling)
                {
                    bool nonloaded = true;
                    trucks++;
                    double load450kgs = 0;
                    // while truck below carrying capacity load individuals
                    foreach (var ind in herd)
                    {
                        if (load450kgs + (ind.Weight / 450.0) <= trucking.Number450kgPerTruck)
                        {
                            nonloaded = false;
                            head++;
                            aESum      += ind.AdultEquivalent;
                            load450kgs += ind.Weight / 450.0;

                            if (bankAccount != null)  // perform with purchasing
                            {
                                double value = 0;
                                if (ind.SaleFlag == HerdChangeReason.SirePurchase)
                                {
                                    value = ind.BreedParams.ValueofIndividual(ind, PurchaseOrSalePricingStyleType.Purchase, RuminantFilterParameters.BreedingSire, "true");
                                }
                                else
                                {
                                    value = ind.BreedParams.ValueofIndividual(ind, PurchaseOrSalePricingStyleType.Purchase);
                                }
                                if (cost + value <= fundsAvailable && fundsexceeded == false)
                                {
                                    ind.ID = ruminantHerd.NextUniqueID;
                                    ruminantHerd.AddRuminant(ind, this);
                                    ruminantHerd.PurchaseIndividuals.Remove(ind);
                                    cost += value;
                                }
                                else
                                {
                                    fundsexceeded = true;
                                    shortfall    += value;
                                }
                            }
                            else // no financial transactions
                            {
                                ind.ID = ruminantHerd.NextUniqueID;
                                ruminantHerd.AddRuminant(ind, this);
                                ruminantHerd.PurchaseIndividuals.Remove(ind);
                            }
                        }
                    }
                    if (nonloaded)
                    {
                        Summary.WriteWarning(this, String.Format("There was a problem loading the purchase truck as purchase individuals did not meet the loading criteria for breed [r={0}]", this.PredictedHerdBreed));
                        break;
                    }
                    if (shortfall > 0)
                    {
                        break;
                    }

                    herd = ruminantHerd.PurchaseIndividuals.Where(a => a.BreedParams.Breed == this.PredictedHerdBreed).OrderByDescending(a => a.Weight).ToList();
                }

                // create trucking emissions
                if (trucking != null && trucks > 0)
                {
                    trucking.ReportEmissions(trucks, false);
                    SetStatusSuccess();
                }

                if (bankAccount != null && (trucks > 0 || trucking == null))
                {
                    ResourceRequest purchaseRequest = new ResourceRequest
                    {
                        ActivityModel      = this,
                        Required           = cost,
                        AllowTransmutation = false,
                        Reason             = this.PredictedHerdName + " purchases"
                    };
                    bankAccount.Remove(purchaseRequest);

                    // report any financial shortfall in purchases
                    if (shortfall > 0)
                    {
                        purchaseRequest.Available        = bankAccount.Amount;
                        purchaseRequest.Required         = cost + shortfall;
                        purchaseRequest.Provided         = cost;
                        purchaseRequest.ResourceType     = typeof(Finance);
                        purchaseRequest.ResourceTypeName = BankAccountName;
                        ResourceRequestEventArgs rre = new ResourceRequestEventArgs()
                        {
                            Request = purchaseRequest
                        };
                        OnShortfallOccurred(rre);
                    }

                    ResourceRequest expenseRequest = new ResourceRequest
                    {
                        Available          = bankAccount.Amount,
                        ActivityModel      = this,
                        AllowTransmutation = false
                    };

                    // calculate transport costs
                    if (trucking != null)
                    {
                        expenseRequest.Required = trucks * trucking.DistanceToMarket * trucking.CostPerKmTrucking;
                        expenseRequest.Reason   = "Transport purchases";
                        bankAccount.Remove(expenseRequest);

                        if (expenseRequest.Required > expenseRequest.Available)
                        {
                            expenseRequest.Available        = bankAccount.Amount;
                            expenseRequest.ResourceType     = typeof(Finance);
                            expenseRequest.ResourceTypeName = BankAccountName;
                            ResourceRequestEventArgs rre = new ResourceRequestEventArgs()
                            {
                                Request = expenseRequest
                            };
                            OnShortfallOccurred(rre);
                        }
                    }
                }
            }
        }
        private void BuyWithoutTrucking()
        {
            // This activity will purchase animals based on available funds.
            RuminantHerd ruminantHerd = Resources.RuminantHerd();

            // get current untrucked list of animal purchases
            List <Ruminant> herd = ruminantHerd.PurchaseIndividuals.Where(a => a.BreedParams.Breed == this.PredictedHerdBreed).ToList();

            if (herd.Count() > 0)
            {
                SetStatusSuccess();
            }

            double fundsAvailable = 0;

            if (bankAccount != null)
            {
                fundsAvailable = bankAccount.FundsAvailable;
            }
            double cost          = 0;
            double shortfall     = 0;
            bool   fundsexceeded = false;

            foreach (var newind in herd)
            {
                if (bankAccount != null)  // perform with purchasing
                {
                    double value = 0;
                    if (newind.SaleFlag == HerdChangeReason.SirePurchase)
                    {
                        value = newind.BreedParams.ValueofIndividual(newind, PurchaseOrSalePricingStyleType.Purchase, RuminantFilterParameters.BreedingSire, "true");
                    }
                    else
                    {
                        value = newind.BreedParams.ValueofIndividual(newind, PurchaseOrSalePricingStyleType.Purchase);
                    }
                    if (cost + value <= fundsAvailable && fundsexceeded == false)
                    {
                        ruminantHerd.PurchaseIndividuals.Remove(newind);
                        newind.ID = ruminantHerd.NextUniqueID;
                        ruminantHerd.AddRuminant(newind, this);
                        cost += value;
                    }
                    else
                    {
                        fundsexceeded = true;
                        shortfall    += value;
                    }
                }
                else // no financial transactions
                {
                    ruminantHerd.PurchaseIndividuals.Remove(newind);
                    newind.ID = ruminantHerd.NextUniqueID;
                    ruminantHerd.AddRuminant(newind, this);
                }
            }

            if (bankAccount != null)
            {
                ResourceRequest purchaseRequest = new ResourceRequest
                {
                    ActivityModel      = this,
                    Required           = cost,
                    AllowTransmutation = false,
                    Reason             = this.PredictedHerdName + " purchases"
                };
                bankAccount.Remove(purchaseRequest);

                // report any financial shortfall in purchases
                if (shortfall > 0)
                {
                    purchaseRequest.Available        = bankAccount.Amount;
                    purchaseRequest.Required         = cost + shortfall;
                    purchaseRequest.Provided         = cost;
                    purchaseRequest.ResourceType     = typeof(Finance);
                    purchaseRequest.ResourceTypeName = BankAccountName;
                    ResourceRequestEventArgs rre = new ResourceRequestEventArgs()
                    {
                        Request = purchaseRequest
                    };
                    OnShortfallOccurred(rre);
                }
            }
        }
Exemple #10
0
        /// <inheritdoc/>
        public override void DoActivity()
        {
            Status = ActivityStatus.NotNeeded;
            if (finance != null)
            {
                // make interest payments on bank accounts
                foreach (FinanceType accnt in finance.FindAllChildren <FinanceType>())
                {
                    if (accnt.Balance > 0)
                    {
                        if (accnt.InterestRatePaid > 0)
                        {
                            accnt.Add(accnt.Balance * accnt.InterestRatePaid / 1200, this, "", "Interest");
                            SetStatusSuccess();
                        }
                    }
                    else if (accnt.Balance < 0)
                    {
                        double interest = Math.Round(Math.Abs(accnt.Balance) * accnt.InterestRateCharged / 1200, 2, MidpointRounding.ToEven);
                        if (Math.Abs(accnt.Balance) * accnt.InterestRateCharged / 1200 != 0)
                        {
                            ResourceRequest interestRequest = new ResourceRequest
                            {
                                ActivityModel      = this,
                                Required           = interest,
                                AllowTransmutation = false,
                                Category           = TransactionCategory
                            };
                            accnt.Remove(interestRequest);

                            // report status
                            if (interestRequest.Required > interestRequest.Provided)
                            {
                                interestRequest.ResourceType     = typeof(Finance);
                                interestRequest.ResourceTypeName = accnt.NameWithParent;
                                interestRequest.Available        = accnt.FundsAvailable;
                                ResourceRequestEventArgs rre = new ResourceRequestEventArgs()
                                {
                                    Request = interestRequest
                                };
                                OnShortfallOccurred(rre);

                                switch (OnPartialResourcesAvailableAction)
                                {
                                case OnPartialResourcesAvailableActionTypes.ReportErrorAndStop:
                                    throw new ApsimXException(this, String.Format("Insufficient funds in [r={0}] to pay interest charged.\r\nConsider changing OnPartialResourcesAvailableAction to Skip or Use Partial.", accnt.Name));

                                case OnPartialResourcesAvailableActionTypes.SkipActivity:
                                    Status = ActivityStatus.Ignored;
                                    break;

                                case OnPartialResourcesAvailableActionTypes.UseResourcesAvailable:
                                    Status = ActivityStatus.Partial;
                                    break;

                                default:
                                    break;
                                }
                            }
                            else
                            {
                                Status = ActivityStatus.Success;
                            }
                        }
                    }
                }
            }
        }
Exemple #11
0
        private IntPtr internalResourceRequestCallback( IntPtr caller, IntPtr request )
        {
            ResourceRequest requestWrap = new ResourceRequest( request );
            ResourceRequestEventArgs e = new ResourceRequestEventArgs( requestWrap );

            if ( ResourceRequest != null )
            {
                ResourceResponse response = this.OnResourceRequest( this, e );
                CommandManager.InvalidateRequerySuggested();

                if ( response != null )
                    return response.getInstance();
            }

            return IntPtr.Zero;
        }
Exemple #12
0
        private void BuyWithTrucking()
        {
            // This activity will purchase animals based on available funds.

            int    trucks         = 0;
            int    head           = 0;
            double aESum          = 0;
            double fundsAvailable = 0;

            if (bankAccount != null)
            {
                fundsAvailable = bankAccount.FundsAvailable;
            }
            double cost          = 0;
            double shortfall     = 0;
            bool   fundsexceeded = false;

            // get current untrucked list of animal purchases
            List <Ruminant> herd = HerdResource.PurchaseIndividuals.Where(a => a.BreedParams.Breed == this.PredictedHerdBreed).OrderByDescending(a => a.Weight).ToList();

            if (herd.Count == 0)
            {
                return;
            }

            List <Ruminant> boughtIndividuals = new List <Ruminant>();

            // if purchase herd > min loads before allowing trucking
            if (herd.Select(a => a.Weight / 450.0).Sum() / trucking.Number450kgPerTruck >= trucking.MinimumTrucksBeforeBuying)
            {
                // while truck to fill
                while (herd.Select(a => a.Weight / 450.0).Sum() / trucking.Number450kgPerTruck > trucking.MinimumLoadBeforeBuying)
                {
                    bool nonloaded = true;
                    trucks++;
                    double load450kgs = 0;
                    // while truck below carrying capacity load individuals
                    foreach (var ind in herd)
                    {
                        if (load450kgs + (ind.Weight / 450.0) <= trucking.Number450kgPerTruck)
                        {
                            nonloaded = false;
                            head++;
                            aESum      += ind.AdultEquivalent;
                            load450kgs += ind.Weight / 450.0;

                            if (bankAccount != null)  // perform with purchasing
                            {
                                double           value   = 0;
                                AnimalPriceGroup pricing = null;
                                if (ind.SaleFlag == HerdChangeReason.SirePurchase)
                                {
                                    pricing = ind.BreedParams.GetPriceGroupOfIndividual(ind, PurchaseOrSalePricingStyleType.Purchase, "IsSire", "true");
                                }
                                else
                                {
                                    pricing = ind.BreedParams.GetPriceGroupOfIndividual(ind, PurchaseOrSalePricingStyleType.Purchase);
                                }

                                if (pricing != null)
                                {
                                    value = pricing.CalculateValue(ind);
                                }

                                if (cost + value <= fundsAvailable && fundsexceeded == false)
                                {
                                    ind.ID = HerdResource.NextUniqueID;
                                    boughtIndividuals.Add(ind);
                                    HerdResource.AddRuminant(ind, this);
                                    HerdResource.PurchaseIndividuals.Remove(ind);
                                    cost += value;
                                }
                                else
                                {
                                    fundsexceeded = true;
                                    shortfall    += value;
                                }
                            }
                            else // no financial transactions
                            {
                                ind.ID = HerdResource.NextUniqueID;
                                boughtIndividuals.Add(ind);
                                HerdResource.AddRuminant(ind, this);
                                HerdResource.PurchaseIndividuals.Remove(ind);
                            }
                        }
                    }
                    if (nonloaded)
                    {
                        Summary.WriteMessage(this, String.Format("There was a problem loading the purchase truck as purchase individuals did not meet the loading criteria for breed [r={0}]", this.PredictedHerdBreed), MessageType.Warning);
                        break;
                    }
                    if (shortfall > 0)
                    {
                        break;
                    }

                    herd = HerdResource.PurchaseIndividuals.Where(a => a.BreedParams.Breed == this.PredictedHerdBreed).OrderByDescending(a => a.Weight).ToList();
                }

                if (Status != ActivityStatus.Warning)
                {
                    if (HerdResource.PurchaseIndividuals.Where(a => a.BreedParams.Breed == this.PredictedHerdBreed).Any() == false)
                    {
                        SetStatusSuccess();
                    }
                    else
                    {
                        Status = ActivityStatus.Partial;
                    }
                }

                // create trucking emissions
                if (trucking != null && trucks > 0)
                {
                    trucking.ReportEmissions(trucks, false);
                }

                if (bankAccount != null && (trucks > 0 || trucking == null))
                {
                    ResourceRequest purchaseRequest = new ResourceRequest
                    {
                        ActivityModel      = this,
                        Required           = cost,
                        AllowTransmutation = false,
                        Category           = TransactionCategory,
                        RelatesToResource  = this.PredictedHerdName
                    };

                    var groupedIndividuals = HerdResource.SummarizeIndividualsByGroups(boughtIndividuals, PurchaseOrSalePricingStyleType.Purchase);
                    foreach (var item in groupedIndividuals)
                    {
                        foreach (var item2 in item.RuminantTypeGroup)
                        {
                            purchaseRequest.Required = item2.TotalPrice ?? 0;
                            purchaseRequest.Category = $"{TransactionCategory}.{item2.GroupName}";
                            bankAccount.Remove(purchaseRequest);
                        }
                    }

                    // report any financial shortfall in purchases
                    if (shortfall > 0)
                    {
                        purchaseRequest.Available        = bankAccount.Amount;
                        purchaseRequest.Required         = cost + shortfall;
                        purchaseRequest.Provided         = cost;
                        purchaseRequest.ResourceType     = typeof(Finance);
                        purchaseRequest.ResourceTypeName = BankAccountName;
                        ResourceRequestEventArgs rre = new ResourceRequestEventArgs()
                        {
                            Request = purchaseRequest
                        };
                        OnShortfallOccurred(rre);
                    }

                    ResourceRequest expenseRequest = new ResourceRequest
                    {
                        Available          = bankAccount.Amount,
                        ActivityModel      = this,
                        AllowTransmutation = false
                    };

                    // calculate transport costs
                    if (trucking != null)
                    {
                        expenseRequest.Required = trucks * trucking.DistanceToMarket * trucking.CostPerKmTrucking;
                        expenseRequest.Category = trucking.TransactionCategory;
                        bankAccount.Remove(expenseRequest);

                        if (expenseRequest.Required > expenseRequest.Available)
                        {
                            expenseRequest.Available        = bankAccount.Amount;
                            expenseRequest.ResourceType     = typeof(Finance);
                            expenseRequest.ResourceTypeName = BankAccountName;
                            ResourceRequestEventArgs rre = new ResourceRequestEventArgs()
                            {
                                Request = expenseRequest
                            };
                            OnShortfallOccurred(rre);
                        }
                    }
                }
            }
            else
            {
                this.Status = ActivityStatus.Warning;
            }
        }
Exemple #13
0
        private IntPtr internalResourceRequestCallback(IntPtr caller, IntPtr url, IntPtr referrer, IntPtr http_method,
                                                                IntPtr post_data, uint post_data_length)
        {
            byte[] postDataBytes = null;

            if (post_data_length > 0)
            {
                postDataBytes = new byte[post_data_length];
                Marshal.Copy(post_data, postDataBytes, 0, (int)post_data_length);
            }

            ResourceRequestEventArgs e = new ResourceRequestEventArgs(this, StringHelper.ConvertAweString(url), StringHelper.ConvertAweString(referrer),
                            StringHelper.ConvertAweString(http_method), postDataBytes);

            if (OnResourceRequest != null)
            {
                ResourceResponse response = OnResourceRequest(this, e);

                if (response != null)
                    return response.getInstance();
            }

            return IntPtr.Zero;
        }
        private IntPtr internalResourceRequestCallback(IntPtr caller, IntPtr request)
        {
            ResourceRequest requestWrap = new ResourceRequest(request);

            ResourceRequestEventArgs e = new ResourceRequestEventArgs(this, requestWrap);

            if (OnResourceRequest != null)
            {
                ResourceResponse response = OnResourceRequest(this, e);

                if (response != null)
                    return response.getInstance();
            }

            return IntPtr.Zero;
        }
Exemple #15
0
        /// <summary>
        /// Determine resources available and perform transmutation if needed.
        /// </summary>
        /// <param name="resourceRequests">List of requests</param>
        /// <param name="uniqueActivityID">Unique id for the activity</param>
        public void CheckResources(IEnumerable<ResourceRequest> resourceRequests, Guid uniqueActivityID)
        {
            if (resourceRequests is null || !resourceRequests.Any())
            {
                this.Status = ActivityStatus.Success;
                return;
            }

            foreach (ResourceRequest request in resourceRequests)
            {
                request.ActivityID = uniqueActivityID;
                request.Available = 0;

                // If resource group does not exist then provide required.
                // This means when resource is not added to model it will not limit simulations
                if (request.ResourceType == null || Resources.FindResource(request.ResourceType) == null)
                {
                    request.Available = request.Required;
                    request.Provided = request.Required;
                }
                else
                {
                    if (request.ResourceType == typeof(Labour))
                        // get available labour based on rules.
                        request.Available = TakeLabour(request, false, this, Resources, this.OnPartialResourcesAvailableAction);
                    else
                        request.Available = TakeNonLabour(request, false);
                }
            }

            // are all resources available
            IEnumerable<ResourceRequest> shortfallRequests = resourceRequests.Where(a => a.Required > a.Available);
            if (shortfallRequests.Any())
                // check what transmutations can occur
                Resources.TransmutateShortfall(shortfallRequests);

            // check if need to do transmutations
            int countTransmutationsSuccessful = shortfallRequests.Where(a => a.TransmutationPossible == true && a.AllowTransmutation).Count();
            bool allTransmutationsSuccessful = (shortfallRequests.Where(a => a.TransmutationPossible == false && a.AllowTransmutation).Count() == 0);

            // OR at least one transmutation successful and PerformWithPartialResources
            if ((shortfallRequests.Any() && (shortfallRequests.Count() == countTransmutationsSuccessful)) || (countTransmutationsSuccessful > 0 && OnPartialResourcesAvailableAction == OnPartialResourcesAvailableActionTypes.UseResourcesAvailable))
            {
                // do transmutations.
                // this uses the current zone resources, but will find markets if needed in the process
                Resources.TransmutateShortfall(shortfallRequests, false);

                // recheck resource amounts now that resources have been topped up
                foreach (ResourceRequest request in resourceRequests)
                {
                    // get resource
                    request.Available = 0;
                    if (request.Resource != null)
                        // get amount available
                        request.Available = Math.Min(request.Resource.Amount, request.Required);
                }
            }

            bool deficitFound = false;
            // report any resource defecits here
            foreach (var item in resourceRequests.Where(a => (a.Required - a.Available) > 0.000001))
            {
                ResourceRequestEventArgs rrEventArgs = new ResourceRequestEventArgs() { Request = item };

                if (item.Resource != null && (item.Resource as Model).FindAncestor<Market>() != null)
                {
                    ActivitiesHolder marketActivities = Resources.FoundMarket.FindChild<ActivitiesHolder>();
                    if(marketActivities != null)
                        marketActivities.ActivitiesHolder_ResourceShortfallOccurred(this, rrEventArgs);
                }
                else
                    OnShortfallOccurred(rrEventArgs);
                Status = ActivityStatus.Partial;
                deficitFound = true;
            }
            if(!deficitFound)
                this.Status = ActivityStatus.Success;
        }
        public override void DoActivity()
        {
            //Go through amount received and put it into the animals intake with quality measures.
            if (ResourceRequestList != null)
            {
                List <Ruminant> herd = this.CurrentHerd(false).Where(a => a.Location == this.GrazeFoodStoreModel.Name && a.HerdName == this.RuminantTypeModel.Name).ToList();
                if (herd.Count() > 0)
                {
                    // Get total amount
                    // assumes animals will stop eating at potential intake if they have been feed before grazing.
                    // hours grazed is not adjusted for this reduced feeding. Used to be 1.2 * Potential
                    double totalDesired = 0;
                    double totalEaten   = 0;
                    // sucklings
                    totalDesired = herd.Where(a => !a.Weaned).Sum(a => a.PotentialIntake - a.Intake);
                    totalEaten   = herd.Where(a => !a.Weaned).Sum(a => a.PotentialIntake - a.Intake);
                    // weaned
                    totalDesired += herd.Where(a => a.Weaned).Sum(a => Math.Min(a.PotentialIntake - a.Intake, a.PotentialIntake * PotentialIntakePastureQualityLimiter * (HoursGrazed / 8)));
                    totalEaten   += herd.Where(a => a.Weaned).Sum(a => Math.Min(a.PotentialIntake - a.Intake, a.PotentialIntake * PotentialIntakePastureQualityLimiter * (1 - Math.Exp(-a.BreedParams.IntakeCoefficientBiomass * this.GrazeFoodStoreModel.TonnesPerHectareStartOfTimeStep * 1000)) * (HoursGrazed / 8)));

                    totalEaten *= GrazingCompetitionLimiter;

                    // take resource
                    if (totalEaten > 0)
                    {
                        ResourceRequest request = new ResourceRequest()
                        {
                            ActivityModel     = this,
                            AdditionalDetails = this,
                            Reason            = RuminantTypeModel.Name + " grazing",
                            Required          = totalEaten,
                            Resource          = GrazeFoodStoreModel as IResourceType
                        };
                        GrazeFoodStoreModel.Remove(request);

                        FoodResourcePacket food = new FoodResourcePacket()
                        {
                            DMD      = ((RuminantActivityGrazePastureHerd)request.AdditionalDetails).DMD,
                            PercentN = ((RuminantActivityGrazePastureHerd)request.AdditionalDetails).N
                        };

                        double shortfall = request.Provided / request.Required;

                        // allocate to individuals
                        foreach (Ruminant ind in herd)
                        {
                            double eaten;
                            if (ind.Weaned)
                            {
                                eaten = ind.PotentialIntake * PotentialIntakePastureQualityLimiter * (HoursGrazed / 8);
                            }
                            else
                            {
                                eaten = ind.PotentialIntake - ind.Intake;
                            }
                            food.Amount = eaten * GrazingCompetitionLimiter * shortfall;
                            ind.AddIntake(food);
                        }
                        Status = ActivityStatus.Success;

                        // if insufficent provided or no pasture (nothing eaten) use totalNeededifPasturePresent
                        if (GrazingCompetitionLimiter < 1)
                        {
                            request.Available        = request.Provided; // display all that was given
                            request.Required         = totalDesired;
                            request.ResourceType     = typeof(GrazeFoodStore);
                            request.ResourceTypeName = GrazeFoodStoreModel.Name;
                            ResourceRequestEventArgs rre = new ResourceRequestEventArgs()
                            {
                                Request = request
                            };
                            OnShortfallOccurred(rre);

                            if (this.OnPartialResourcesAvailableAction == OnPartialResourcesAvailableActionTypes.ReportErrorAndStop)
                            {
                                throw new ApsimXException(this, "Insufficient pasture available for grazing in paddock (" + GrazeFoodStoreModel.Name + ") in " + Clock.Today.Month.ToString() + "\\" + Clock.Today.Year.ToString());
                            }
                            this.Status = ActivityStatus.Partial;
                        }
                    }
                    else
                    {
                        Status = ActivityStatus.NotNeeded;
                    }
                }
            }
            else
            {
                if (Status != ActivityStatus.Partial && Status != ActivityStatus.Critical)
                {
                    Status = ActivityStatus.NotNeeded;
                }
            }
        }
Exemple #17
0
        /// <summary>
        /// Determine resources available and perform transmutation if needed.
        /// </summary>
        /// <param name="resourceRequestList">List of requests</param>
        /// <param name="uniqueActivityID">Unique id for the activity</param>
        public void CheckResources(List <ResourceRequest> resourceRequestList, Guid uniqueActivityID)
        {
            if ((resourceRequestList == null) || (resourceRequestList.Count() == 0))
            {
                this.Status = ActivityStatus.Success;
                return;
            }

            foreach (ResourceRequest request in resourceRequestList)
            {
                request.ActivityID = uniqueActivityID;
                request.Available  = 0;

                // If resource group does not exist then provide required.
                // This means when resource is not added to model it will not limit simulations
                if (request.ResourceType == null || Resources.GetResourceGroupByType(request.ResourceType) == null)
                {
                    request.Available = request.Required;
                    request.Provided  = request.Required;
                }
                else
                {
                    if (request.ResourceType == typeof(Labour))
                    {
                        // get available labour based on rules.
                        request.Available = TakeLabour(request, false, this, Resources, this.OnPartialResourcesAvailableAction);
                    }
                    else
                    {
                        request.Available = TakeNonLabour(request, false);
                    }
                }
            }

            // are all resources available
            List <ResourceRequest> shortfallRequests = resourceRequestList.Where(a => a.Required > a.Available).ToList();
            int countShortfallRequests = shortfallRequests.Count();

            if (countShortfallRequests > 0)
            {
                // check what transmutations can occur
                Resources.TransmutateShortfall(shortfallRequests, true);
            }

            // check if need to do transmutations
            int  countTransmutationsSuccessful = shortfallRequests.Where(a => a.TransmutationPossible == true && a.AllowTransmutation).Count();
            bool allTransmutationsSuccessful   = (shortfallRequests.Where(a => a.TransmutationPossible == false && a.AllowTransmutation).Count() == 0);

            // OR at least one transmutation successful and PerformWithPartialResources
            if (((countShortfallRequests > 0) && (countShortfallRequests == countTransmutationsSuccessful)) || (countTransmutationsSuccessful > 0 && OnPartialResourcesAvailableAction == OnPartialResourcesAvailableActionTypes.UseResourcesAvailable))
            {
                // do transmutations.
                // this uses the current zone resources, but will find markets if needed in the process
                Resources.TransmutateShortfall(shortfallRequests, false);

                // recheck resource amounts now that resources have been topped up
                foreach (ResourceRequest request in resourceRequestList)
                {
                    // get resource
                    request.Available = 0;
                    if (request.Resource != null)
                    {
                        // get amount available
                        request.Available = Math.Min(request.Resource.Amount, request.Required);
                    }
                }
            }

            bool deficitFound = false;

            // report any resource defecits here
            foreach (var item in resourceRequestList.Where(a => a.Required > a.Available))
            {
                ResourceRequestEventArgs rrEventArgs = new ResourceRequestEventArgs()
                {
                    Request = item
                };
                OnShortfallOccurred(rrEventArgs);
                Status       = ActivityStatus.Partial;
                deficitFound = true;
            }
            if (!deficitFound)
            {
                this.Status = ActivityStatus.Success;
            }
        }
Exemple #18
0
        /// <summary>
        /// Raises the <see cref="ResourceRequest"/> event.
        /// </summary>
        protected virtual ResourceResponse OnResourceRequest( object sender, ResourceRequestEventArgs e )
        {
            if ( ResourceRequest != null )
                return ResourceRequest( sender, e );

            return null;
        }
Exemple #19
0
        /// <summary>
        /// Try to take the Resources based on Resource Request List provided.
        /// Returns true if it was able to take the resources it needed.
        /// Returns false if it was unable to take the resources it needed.
        /// </summary>
        /// <param name="ResourceRequestList"></param>
        /// <param name="TriggerActivityPerformed"></param>
        public bool TakeResources(List <ResourceRequest> ResourceRequestList, bool TriggerActivityPerformed)
        {
            bool resourceAvailable = false;

            // no resources required or this is an Activity folder.
            if ((ResourceRequestList == null) || (ResourceRequestList.Count() == 0))
            {
                return(false);
            }

            Guid uniqueRequestID = Guid.NewGuid();

            // check resource amounts available
            foreach (ResourceRequest request in ResourceRequestList)
            {
                request.ActivityID = uniqueRequestID;
                request.Available  = 0;
                // get resource
                if (request.Resource == null)
                {
                    //If it hasn't been assigned try and find it now.
                    request.Resource = Resources.GetResourceItem(request, OnMissingResourceActionTypes.Ignore, OnMissingResourceActionTypes.Ignore) as IResourceType;
                }
                if (request.Resource != null)
                {
                    // get amount available
                    request.Available = Math.Min(request.Resource.Amount, request.Required);
                }
                else
                {
                    if (!resourceAvailable)
                    {
                        // if resource does not exist in simulation assume unlimited resource available
                        // otherwise 0 will be assigned to available when no resouces match request
                        request.Available = request.Required;
                    }
                }
            }

            // are all resources available
            List <ResourceRequest> shortfallRequests = ResourceRequestList.Where(a => a.Required > a.Available).ToList();
            int countShortfallRequests = shortfallRequests.Count();

            if (countShortfallRequests > 0)
            {
                // check what transmutations can occur
                Resources.TransmutateShortfall(shortfallRequests, true);
            }

            // check if need to do transmutations
            int  countTransmutationsSuccessful = shortfallRequests.Where(a => a.TransmutationPossible == true & a.AllowTransmutation).Count();
            bool allTransmutationsSuccessful   = (shortfallRequests.Where(a => a.TransmutationPossible == false & a.AllowTransmutation).Count() == 0);

            // OR at least one transmutation successful and PerformWithPartialResources
            if (((countShortfallRequests > 0) & (countShortfallRequests == countTransmutationsSuccessful)) || (countTransmutationsSuccessful > 0 & OnPartialResourcesAvailableAction == OnPartialResourcesAvailableActionTypes.UseResourcesAvailable))
            {
                // do transmutations.
                Resources.TransmutateShortfall(shortfallRequests, false);

                // recheck resource amounts now that resources have been topped up
                foreach (ResourceRequest request in ResourceRequestList)
                {
                    // get resource
                    request.Available = 0;
                    if (request.Resource != null)
                    {
                        // get amount available
                        request.Available = Math.Min(request.Resource.Amount, request.Required);
                    }
                }
            }

            // report any resource defecits here
            foreach (var item in ResourceRequestList.Where(a => a.Required > a.Available))
            {
                ResourceRequestEventArgs rrEventArgs = new ResourceRequestEventArgs()
                {
                    Request = item
                };
                OnShortfallOccurred(rrEventArgs);
                Status = ActivityStatus.Partial;
            }

            // remove activity resources
            // check if deficit and performWithPartial
            if ((ResourceRequestList.Where(a => a.Required > a.Available).Count() == 0) || OnPartialResourcesAvailableAction != OnPartialResourcesAvailableActionTypes.SkipActivity)
            {
                if (OnPartialResourcesAvailableAction == OnPartialResourcesAvailableActionTypes.ReportErrorAndStop)
                {
                    string resourcelist = "";
                    foreach (var item in ResourceRequestList.Where(a => a.Required > a.Available))
                    {
                        Summary.WriteWarning(this, String.Format("Insufficient ({0}) resource of type ({1}) for activity ({2})", item.ResourceType, item.ResourceTypeName, this.Name));
                        resourcelist += ((resourcelist.Length > 0)?",":"") + item.ResourceType.Name;
                    }
                    if (resourcelist.Length > 0)
                    {
                        Summary.WriteWarning(this, String.Format("Ensure resources are available or change OnPartialResourcesAvailableAction setting for activity ({0}) to handle previous error", this.Name));
                        Status = ActivityStatus.Critical;
                        throw new Exception(String.Format("Insufficient resources ({0}) for activity ({1}) (see Summary for details)", resourcelist, this.Name));
                    }
                }

                foreach (ResourceRequest request in ResourceRequestList)
                {
                    // get resource
                    request.Provided = 0;
                    if (request.Resource != null)
                    {
                        // remove resource
                        request.Resource.Remove(request);
                    }
                }
                //return true; //could take all the resources it needed or is able to do with partial amounts
            }
            else
            {
                Status = ActivityStatus.Ignored;
                //return false;  //could not take all the resources it needed.
            }

            return(Status != ActivityStatus.Ignored);
        }
Exemple #20
0
        private void BuyWithoutTrucking()
        {
            // This activity will purchase animals based on available funds.

            // get current untrucked list of animal purchases
            List <Ruminant> herd = HerdResource.PurchaseIndividuals.Where(a => a.BreedParams.Breed == this.PredictedHerdBreed).ToList();

            if (herd.Count > 0)
            {
                if (this.Status != ActivityStatus.Warning)
                {
                    this.Status = ActivityStatus.Success;
                }
            }
            else
            {
                return;
            }

            List <Ruminant> boughtIndividuals = new List <Ruminant>();

            double fundsAvailable = 0;

            if (bankAccount != null)
            {
                fundsAvailable = bankAccount.FundsAvailable;
            }

            double cost          = 0;
            double shortfall     = 0;
            bool   fundsexceeded = false;

            foreach (var newind in herd)
            {
                if (bankAccount != null)  // perform with purchasing
                {
                    double           value   = 0;
                    AnimalPriceGroup pricing = null;
                    if (newind.SaleFlag == HerdChangeReason.SirePurchase)
                    {
                        pricing = newind.BreedParams.ValueofIndividual(newind, PurchaseOrSalePricingStyleType.Purchase, "Male.IsSire", "true");
                    }
                    else
                    {
                        pricing = newind.BreedParams.ValueofIndividual(newind, PurchaseOrSalePricingStyleType.Purchase);
                    }

                    if (pricing != null)
                    {
                        value = pricing.CalculateValue(newind);
                    }

                    if (cost + value <= fundsAvailable && fundsexceeded == false)
                    {
                        boughtIndividuals.Add(newind);
                        HerdResource.PurchaseIndividuals.Remove(newind);
                        newind.ID = HerdResource.NextUniqueID;

                        HerdResource.AddRuminant(newind, this);
                        cost += value;
                    }
                    else
                    {
                        fundsexceeded = true;
                        shortfall    += value;
                    }
                }
                else // no financial transactions
                {
                    boughtIndividuals.Add(newind);
                    HerdResource.PurchaseIndividuals.Remove(newind);
                    newind.ID = HerdResource.NextUniqueID;
                    HerdResource.AddRuminant(newind, this);
                }
            }

            if (bankAccount != null)
            {
                ResourceRequest purchaseRequest = new ResourceRequest
                {
                    ActivityModel      = this,
                    Required           = cost,
                    AllowTransmutation = false,
                    Category           = TransactionCategory,
                    RelatesToResource  = this.PredictedHerdName
                };

                //bankAccount.Add(saleValue, this, this.PredictedHerdName, TransactionCategory);
                var groupedIndividuals = HerdResource.SummarizeIndividualsByGroups(boughtIndividuals, PurchaseOrSalePricingStyleType.Purchase);
                foreach (var item in groupedIndividuals)
                {
                    foreach (var item2 in item.RuminantTypeGroup)
                    {
                        purchaseRequest.Required = item2.TotalPrice ?? 0;
                        purchaseRequest.Category = $"{TransactionCategory}.{item2.GroupName}";
                        bankAccount.Remove(purchaseRequest);
//                        bankAccount.Add(item2.TotalPrice, this, item.RuminantTypeName, $"{TransactionCategory}.{item2.GroupName}");
                    }
                }

                // report any financial shortfall in purchases
                if (shortfall > 0)
                {
                    purchaseRequest.Available        = bankAccount.Amount;
                    purchaseRequest.Required         = cost + shortfall;
                    purchaseRequest.Provided         = cost;
                    purchaseRequest.ResourceType     = typeof(Finance);
                    purchaseRequest.ResourceTypeName = BankAccountName;
                    ResourceRequestEventArgs rre = new ResourceRequestEventArgs()
                    {
                        Request = purchaseRequest
                    };
                    OnShortfallOccurred(rre);
                }
            }
        }