@@ -80,7 +80,7 @@ def value(self) -> float:
8080 def update (self , time : float ) -> None :
8181 """Update state value based on elapsed time."""
8282 elapsed = time - self ._last_update_time
83- self ._value = self . _value + self .rate_function (self ._value , elapsed )
83+ self ._value += self .rate_function (self ._value , elapsed )
8484 self ._last_update_time = time
8585
8686
@@ -111,30 +111,46 @@ def update(self, time: float) -> None:
111111
112112
113113class StateAgent (Agent ):
114- """An agent with integrated state management."""
114+ """An agent with integrated state management that allows direct attribute-based state access ."""
115115
116- def __init__ (self , model ) -> None :
116+ def __init__ (self , model ):
117117 """Create a new agent with state management."""
118118 super ().__init__ (model )
119- self .states = {} # name -> State mapping
120-
121- def add_state (self , state : State ) -> None :
122- """Add a new state to the agent."""
123- state .model = self .model
124- self .states [state .name ] = state
125-
126- def get_state (self , name : str ) -> Any :
127- """Get the current value of a state."""
128- return self .states [name ].value
129-
130- def set_state (self , name : str , value : Any ) -> None :
131- """Set value for a discrete state."""
132- if isinstance (self .states [name ], DiscreteState ):
133- self .states [name ].value = value
134- else :
135- raise ValueError ("Cannot directly set value of non-discrete state" )
119+ object .__setattr__ (self , "states" , {}) # Use object.__setattr__ to avoid recursion
136120
137121 def update_states (self ) -> None :
138122 """Update all states to current time."""
139123 for state in self .states .values ():
140124 state .update (self .model .time )
125+
126+ def __getattribute__ (self , name : str ) -> Any :
127+ """Get an attribute, routing state access to its value."""
128+ states = object .__getattribute__ (self , "states" )
129+ if name in states :
130+ # If it's a known state, return its current value
131+ return states [name ].value
132+ else :
133+ # Otherwise, return the attribute normally
134+ return object .__getattribute__ (self , name )
135+
136+ def __setattr__ (self , name : str , value : Any ) -> None :
137+ """Set an attribute, allowing direct state assignment or updates."""
138+ states = object .__getattribute__ (self , "states" )
139+ # If setting a State object, add or update the states dictionary
140+ if isinstance (value , State ):
141+ # The state's name should match the attribute name
142+ if value .name != name :
143+ raise ValueError (f"State name '{ value .name } ' does not match attribute name '{ name } '" )
144+ states [name ] = value
145+ value .model = self .model
146+ else :
147+ # If we're setting a non-state value and a corresponding state exists
148+ if name in states :
149+ # The state must be discrete to allow direct setting
150+ if isinstance (states [name ], DiscreteState ):
151+ states [name ].value = value
152+ else :
153+ raise ValueError ("Cannot directly set value of non-discrete state" )
154+ else :
155+ # Otherwise, it's just a normal attribute
156+ object .__setattr__ (self , name , value )
0 commit comments