@@ -7,7 +7,7 @@ mod variables;
77
88use std:: {
99 borrow:: Cow ,
10- cell:: { Cell , RefCell } ,
10+ cell:: Cell ,
1111 collections:: HashMap ,
1212 rc:: Rc ,
1313 time:: { Duration , Instant } ,
@@ -25,8 +25,10 @@ const MILLIS_PER_SEC: u64 = 1_000;
2525const NANOS_PER_MILLI : u32 = 1_000_000 ;
2626
2727pub struct LogicVM < ' a > {
28- buildings : HashMap < Point2 , Rc < RefCell < Building > > > ,
29- processors : Vec < Rc < RefCell < Building > > > ,
28+ /// Sorted with all processors first, then all other buildings.
29+ buildings : Vec < Building > ,
30+ buildings_map : HashMap < Point2 , usize > ,
31+ total_processors : usize ,
3032 running_processors : Rc < Cell < usize > > ,
3133 time : Rc < Cell < f64 > > ,
3234 globals : Cow < ' a , HashMap < String , LVar > > ,
@@ -39,8 +41,9 @@ impl<'a> LogicVM<'a> {
3941
4042 pub fn new_with_globals ( globals : Cow < ' a , HashMap < String , LVar > > ) -> Self {
4143 Self {
42- buildings : HashMap :: new ( ) ,
43- processors : Vec :: new ( ) ,
44+ buildings : Vec :: new ( ) ,
45+ buildings_map : HashMap :: new ( ) ,
46+ total_processors : 0 ,
4447 running_processors : Rc :: new ( Cell :: new ( 0 ) ) ,
4548 time : Rc :: new ( Cell :: new ( 0. ) ) ,
4649 globals,
@@ -57,41 +60,42 @@ impl<'a> LogicVM<'a> {
5760 Ok ( vm)
5861 }
5962
60- pub fn add_building ( & mut self , building : Building ) -> VMLoadResult < ( ) > {
63+ pub fn add_building ( & mut self , building : Building ) {
6164 let position = building. position ;
6265 let size = building. block . size ;
6366
64- let building = Rc :: new ( RefCell :: new ( building) ) ;
67+ let index = if let BuildingData :: Processor ( processor) = & * building. data . borrow ( ) {
68+ if processor. state . enabled ( ) {
69+ self . running_processors . update ( |n| n + 1 ) ;
70+ }
71+ self . total_processors += 1 ;
72+ self . total_processors - 1
73+ } else {
74+ self . buildings . len ( )
75+ } ;
76+
77+ self . buildings . insert ( index, building) ;
6578
6679 for x in position. x ..position. x + size {
6780 for y in position. y ..position. y + size {
68- self . buildings . insert ( Point2 { x, y } , building. clone ( ) ) ;
69- }
70- }
71-
72- if let BuildingData :: Processor ( processor) = & building. borrow ( ) . data {
73- self . processors . push ( building. clone ( ) ) ;
74- if processor. state . enabled ( ) {
75- self . running_processors . update ( |n| n + 1 ) ;
81+ self . buildings_map . insert ( Point2 { x, y } , index) ;
7682 }
7783 }
78-
79- Ok ( ( ) )
8084 }
8185
82- pub fn add_buildings < T > ( & mut self , buildings : T ) -> VMLoadResult < ( ) >
86+ pub fn add_buildings < T > ( & mut self , buildings : T )
8387 where
8488 T : IntoIterator < Item = Building > ,
8589 {
8690 for building in buildings. into_iter ( ) {
87- self . add_building ( building) ? ;
91+ self . add_building ( building) ;
8892 }
89- Ok ( ( ) )
9093 }
9194
9295 pub fn add_schematic_tile ( & mut self , tile : & SchematicTile ) -> VMLoadResult < ( ) > {
9396 let building = Building :: from_schematic_tile ( tile, self ) ?;
94- self . add_building ( building)
97+ self . add_building ( building) ;
98+ Ok ( ( ) )
9599 }
96100
97101 pub fn add_schematic_tiles ( & mut self , tiles : & [ SchematicTile ] ) -> VMLoadResult < ( ) > {
@@ -101,6 +105,12 @@ impl<'a> LogicVM<'a> {
101105 Ok ( ( ) )
102106 }
103107
108+ pub fn building ( & self , position : Point2 ) -> Option < & Building > {
109+ self . buildings_map
110+ . get ( & position)
111+ . map ( |& i| & self . buildings [ i] )
112+ }
113+
104114 /// Run the simulation until all processors halt, or until a number of ticks are finished.
105115 /// Returns true if all processors halted, or false if the tick limit was reached.
106116 pub fn run ( & mut self , max_ticks : Option < usize > ) -> bool {
@@ -134,10 +144,10 @@ impl<'a> LogicVM<'a> {
134144 let time = self . time . get ( ) + duration_millis_f64 ( delta) . max ( 0. ) ;
135145 self . time . set ( time) ;
136146
137- for processor in & self . processors {
147+ for processor in self . buildings . iter ( ) . take ( self . total_processors ) {
138148 processor
139- . borrow_mut ( )
140149 . data
150+ . borrow_mut ( )
141151 . unwrap_processor_mut ( )
142152 . do_tick ( self , time) ;
143153 }
@@ -189,23 +199,22 @@ mod tests {
189199 buildings:: { HYPER_PROCESSOR , MICRO_PROCESSOR } ,
190200 variables:: { Content , LValue , LVar } ,
191201 } ,
192- types:: { Object , PackedPoint2 , ProcessorConfig , Team , colors:: COLORS , content } ,
202+ types:: { Object , PackedPoint2 , ProcessorConfig , Team , colors:: COLORS } ,
193203 } ;
194204
195205 use super :: { buildings:: WORLD_PROCESSOR , processor:: Processor , * } ;
196206
197207 fn single_processor_vm < ' a > ( name : & str , code : & str ) -> LogicVM < ' a > {
198208 let mut vm = LogicVM :: new ( ) ;
199209 vm. add_building (
200- Building :: new_processor (
210+ Building :: from_processor_config (
201211 name,
202212 Point2 :: new ( 0 , 0 ) ,
203213 & ProcessorConfig :: from_code ( code) ,
204214 & vm,
205215 )
206216 . unwrap ( ) ,
207- )
208- . unwrap ( ) ;
217+ ) ;
209218 vm
210219 }
211220
@@ -216,15 +225,14 @@ mod tests {
216225 ) -> LogicVM < ' a > {
217226 let mut vm = LogicVM :: new_with_globals ( Cow :: Borrowed ( globals) ) ;
218227 vm. add_building (
219- Building :: new_processor (
228+ Building :: from_processor_config (
220229 name,
221230 Point2 :: new ( 0 , 0 ) ,
222231 & ProcessorConfig :: from_code ( code) ,
223232 & vm,
224233 )
225234 . unwrap ( ) ,
226- )
227- . unwrap ( ) ;
235+ ) ;
228236 vm
229237 }
230238
@@ -239,19 +247,15 @@ mod tests {
239247 }
240248
241249 fn with_processor ( vm : & mut LogicVM , idx : usize , f : impl FnOnce ( & mut Processor ) ) {
242- f ( vm. processors [ idx] . borrow_mut ( ) . data . unwrap_processor_mut ( ) )
250+ f ( vm. buildings [ idx] . data . borrow_mut ( ) . unwrap_processor_mut ( ) )
243251 }
244252
245253 fn take_processor ( vm : & mut LogicVM , idx : usize ) -> Processor {
246- vm. processors [ idx]
247- . replace ( Building {
248- position : Point2 :: new ( 0 , 0 ) ,
249- block : & content:: blocks:: VALUES [ 0 ] ,
250- data : BuildingData :: Unknown {
251- config : Object :: Null ,
252- } ,
253- } )
254+ vm. buildings [ idx]
254255 . data
256+ . replace ( BuildingData :: Unknown {
257+ config : Object :: Null ,
258+ } )
255259 . into_processor ( )
256260 }
257261
0 commit comments