demands.h

Go to the documentation of this file.
00001 /* $Id$ */
00002 
00003 /*
00004  * This file is part of OpenTTD.
00005  * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
00006  * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00007  * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
00008  */
00009 
00012 #ifndef DEMANDS_H_
00013 #define DEMANDS_H_
00014 
00015 #include "linkgraph.h"
00016 #include "../stdafx.h"
00017 #include "../cargo_type.h"
00018 #include "../map_func.h"
00019 
00023 class Scaler {
00024 public:
00025   Scaler() : demand_per_node(0) {}
00026 
00027   void SetDemands(LinkGraphComponent * graph, NodeID from, NodeID to, uint demand_forw);
00028 protected:
00029   uint demand_per_node; 
00030 };
00031 
00035 class SymmetricScaler : public Scaler {
00036 public:
00037   FORCEINLINE SymmetricScaler(uint mod_size) : mod_size(mod_size), supply_sum(0) {}
00038 
00043   FORCEINLINE void AddNode(const Node &node) {this->supply_sum += node.supply;}
00044 
00049   FORCEINLINE void SetDemandPerNode(uint num_demands)
00050     {this->demand_per_node = max(this->supply_sum / num_demands, 1U);}
00051 
00059   FORCEINLINE uint EffectiveSupply(const Node &from, const Node &to)
00060     {return max(from.supply * max(1U, to.supply) * this->mod_size / 100 / this->demand_per_node, 1U);}
00061 
00068   FORCEINLINE bool DemandLeft(Node &to)
00069     {return (to.supply == 0 || to.undelivered_supply > 0) && to.demand > 0;}
00070 
00071   void SetDemands(LinkGraphComponent * graph, NodeID from, NodeID to, uint demand_forw);
00072 
00073 private:
00074   uint mod_size;
00075   uint supply_sum;
00076 };
00077 
00081 class AsymmetricScaler : public Scaler {
00082 public:
00083   AsymmetricScaler() : demand_sum(0) {}
00084 
00089   FORCEINLINE void AddNode(const Node &node) {this->demand_sum += node.demand;}
00090 
00095   FORCEINLINE void SetDemandPerNode(uint num_demands)
00096     {this->demand_per_node = max(this->demand_sum / num_demands, (uint)1);}
00097 
00104   FORCEINLINE uint EffectiveSupply(const Node &from, const Node &to)
00105     {return max(from.supply * to.demand / this->demand_per_node, (uint)1);}
00106 
00112   FORCEINLINE bool DemandLeft(Node &to) {return to.demand > 0;}
00113 
00114 private:
00115   uint demand_sum;
00116 
00117 };
00118 
00124 class DemandCalculator {
00125 public:
00126   DemandCalculator(LinkGraphComponent *graph);
00127 
00128 private:
00129   int32 max_distance; 
00130   int32 mod_dist;     
00131   int32 accuracy;     
00132 
00133   template<class Tscaler>
00134   void CalcDemand(LinkGraphComponent *graph, Tscaler scaler);
00135 };
00136 
00140 class DemandHandler : public ComponentHandler {
00141 public:
00142 
00147   virtual void Run(LinkGraphComponent *graph) {DemandCalculator c(graph);}
00148 
00152   virtual ~DemandHandler() {}
00153 };
00154 
00155 #endif /* DEMANDS_H_ */