MFMv2.0.10
Movable Feast Machine Simulator 2.0.10
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
AbstractElement_Reprovert.h
Go to the documentation of this file.
1 /* -*- mode:C++ -*-
2  AbstractElement_Reprovert.h Vertically reproducing base element type
3  Copyright (C) 2014 The Regents of the University of New Mexico. All rights reserved.
4 
5  This library is free software; you can redistribute it and/or
6  modify it under the terms of the GNU Lesser General Public
7  License as published by the Free Software Foundation; either
8  version 2.1 of the License, or (at your option) any later version.
9 
10  This library is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  Lesser General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this library; if not, write to the Free Software
17  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
18  USA
19 */
20 
28 #ifndef ELEMENT_REPROVERT_H
29 #define ELEMENT_REPROVERT_H
30 
31 #include "Element.h"
32 #include "EventWindow.h"
33 #include "ElementTable.h"
34 #include "itype.h"
35 #include "UUID.h"
36 
37 namespace MFM
38 {
39 
40 
41  template <class CC>
43  {
44  // Extract short names for parameter types
45  typedef typename CC::ATOM_TYPE T;
46  typedef typename CC::PARAM_CONFIG P;
47  enum { R = P::EVENT_WINDOW_RADIUS };
48 
49  public:
50  AbstractElement_Reprovert(const UUID & uuid) : Element<CC>(uuid) { }
51 
52  static const u32 STATE_BELOW_IDX = 0;
53  static const u32 STATE_BELOW_LEN = 9;
54  static const u32 STATE_ABOVE_IDX = STATE_BELOW_IDX+STATE_BELOW_LEN;
55  static const u32 STATE_ABOVE_LEN = 9;
56  static const u32 STATE_GAP_IDX = STATE_ABOVE_IDX+STATE_ABOVE_LEN;
57  static const u32 STATE_GAP_LEN = 2;
58  static const u32 STATE_BITS = STATE_GAP_IDX+STATE_GAP_LEN;
59 
60  static const u32 MAX_BELOW = (1<<STATE_BELOW_LEN)-1;
61  static const u32 MAX_ABOVE = (1<<STATE_ABOVE_LEN)-1;
62 
63  u32 GetBelow(const T &atom, u32 badType) const {
64  if (!Atom<CC>::IsType(atom,Element<CC>::GetType())) return badType;
65  return atom.GetStateField(STATE_BELOW_IDX,STATE_BELOW_LEN);
66  }
67 
68  bool SetBelow(T &atom, u32 value) const {
69  if (!Atom<CC>::IsType(atom,Element<CC>::GetType())) return false;
70  atom.SetStateField(STATE_BELOW_IDX,STATE_BELOW_LEN,value);
71  return true;
72  }
73 
74  u32 GetAbove(const T &atom, u32 badType) const {
75  if (!Atom<CC>::IsType(atom,Element<CC>::GetType())) return badType;
76  return atom.GetStateField(STATE_ABOVE_IDX,STATE_ABOVE_LEN);
77  }
78 
79  bool SetAbove(T &atom, u32 value) const {
80  if (!Atom<CC>::IsType(atom,Element<CC>::GetType())) return false;
81  atom.SetStateField(STATE_ABOVE_IDX,STATE_ABOVE_LEN,value);
82  return true;
83  }
84 
85  u32 GetGap(const T &atom, u32 badType) const {
86  if (!Atom<CC>::IsType(atom,Element<CC>::GetType())) return badType;
87  return atom.GetStateField(STATE_GAP_IDX,STATE_GAP_LEN)+1;
88  }
89 
90  bool SetGap(T &atom, u32 value) const {
91  if (value==0 || !Atom<CC>::IsType(atom,Element<CC>::GetType())) return false;
92  atom.SetStateField(STATE_GAP_IDX,STATE_GAP_LEN,value-1);
93  return true;
94  }
95 
99  virtual u32 Diffusability(EventWindow<CC> & ew, SPoint nowAt, SPoint maybeAt) const {
100  return this->NoDiffusability(ew, nowAt, maybeAt);
101  }
102 
103  void ReproduceVertically(EventWindow<CC>& window) const;
104 
105  };
106 
107  template <class CC>
108  void AbstractElement_Reprovert<CC>::ReproduceVertically(EventWindow<CC>& window) const
109  {
110  Random & random = window.GetRandom();
111  T self = window.GetCenterAtom();
112  s32 gap = GetGap(self,0);
113 
114  u32 selfType = self.GetType();
115  s32 belowSelf = GetBelow(self,0);
116  s32 aboveSelf = GetAbove(self,0);
117  bool down = random.CreateBool();
118  SPoint repPt(0, down ? gap : -gap);
119 
120  if (!window.IsLiveSite(repPt))
121  {
122  return;
123  }
124 
125  T other = window.GetRelativeAtom(repPt);
126  u32 otherType = other.GetType();
127 
128  bool weChanged = false;
129 
130  if (Element_Empty<CC>::THE_INSTANCE.IsType(otherType)) {
131  T newAtom = self;
132 
133  // New guys are assumed maximally extreme in their direction
134  // from us, so if they're stuck in the edge of the universe
135  // getting no events, we'll believe their numbers. When the
136  // empty is just a dreg glitch, hopefully they'll listen to
137  // their neighbors faster than their neighbors listen to them.
138  SetBelow(newAtom, down || belowSelf==0 ? 0 : belowSelf + 1);
139  SetAbove(newAtom, !down || aboveSelf==0 ? 0 : aboveSelf + 1);
140  window.SetRelativeAtom(repPt, newAtom);
141 
142  } else if (otherType == selfType) {
143  s32 belowThem = GetBelow(other,0);
144  s32 aboveThem = GetAbove(other,0);
145 
146  if (down && belowThem + 1 != belowSelf) {
147  SetBelow(self, belowThem + 1);
148  weChanged = true;
149  }
150 
151  if (!down && aboveThem + 1 != aboveSelf) {
152  SetAbove(self, aboveThem + 1);
153  weChanged = true;
154  }
155 
156  } else {
157 
158  // Something not empty and not one of us is there. We will
159  // slowly decide we are the last guy in that direction.
160 
161  if (down && belowSelf > 0 && random.OneIn(10)) {
162  --belowSelf;
163  SetBelow(self, belowSelf);
164  weChanged = true;
165  } else if (!down && aboveSelf > 0 && random.OneIn(10)) {
166  --aboveSelf;
167  SetAbove(self, aboveSelf);
168  weChanged = true;
169  }
170  }
171 
172  if (weChanged)
173  window.SetCenterAtom(self);
174  }
175 
176 
177 }
178 
179 
180 #endif /* ELEMENT_REPROVERT_H */
Definition: Atom.h:71
u32 NoDiffusability(EventWindow< CC > &ew, SPoint nowAt, SPoint maybeAt) const
Definition: Element.h:508
Definition: AbstractElement_Reprovert.h:42
virtual u32 Diffusability(EventWindow< CC > &ew, SPoint nowAt, SPoint maybeAt) const
Definition: AbstractElement_Reprovert.h:99
Definition: ElementTable.h:43
Definition: UUID.h:44
Definition: Atom.h:43