11use std:: mem:: swap;
2+ use std:: collections:: HashMap ;
23
34use race_api:: engine:: GameHandler ;
45use race_api:: event:: Event ;
6+ use race_api:: types:: RandomId ;
57use race_core:: context:: { EventEffects , GameContext } ;
68use race_core:: engine:: general_handle_event;
79use race_core:: error:: Result ;
810use race_encryptor:: Encryptor ;
911
10- use crate :: client_helpers:: TestClient ;
11-
1212// Some event has special handling in event loop.
1313fn patch_handle_event_effects ( context : & mut GameContext , event_effects : & EventEffects ) {
1414 if event_effects. start_game {
2323 H : GameHandler ,
2424{
2525 handler : H ,
26+ random_results : HashMap < RandomId , HashMap < usize , String > > ,
2627}
2728
2829impl < H : GameHandler > TestHandler < H > {
@@ -32,9 +33,10 @@ impl<H: GameHandler> TestHandler<H> {
3233 let mut effect = new_context. derive_effect ( true ) ;
3334 let handler = H :: init_state ( & mut effect, init_account) ?;
3435 let event_effects = new_context. apply_effect ( effect) ?;
36+ let random_results = HashMap :: default ( ) ;
3537 patch_handle_event_effects ( & mut new_context, & event_effects) ;
3638 swap ( context, & mut new_context) ;
37- Ok ( ( Self { handler } , event_effects) )
39+ Ok ( ( Self { handler, random_results } , event_effects) )
3840 }
3941
4042 pub fn handle_event (
@@ -46,125 +48,19 @@ impl<H: GameHandler> TestHandler<H> {
4648 let encryptor = Encryptor :: default ( ) ;
4749 general_handle_event ( & mut new_context, event, & encryptor) ?;
4850 let mut effect = new_context. derive_effect ( false ) ;
51+ // patch the fake random result if we have
52+ if !self . random_results . is_empty ( ) {
53+ effect. revealed = self . random_results . clone ( ) ;
54+ }
4955 self . handler . handle_event ( & mut effect, event. to_owned ( ) ) ?;
5056 let event_effects = new_context. apply_effect ( effect) ?;
5157 patch_handle_event_effects ( & mut new_context, & event_effects) ;
5258 swap ( context, & mut new_context) ;
5359 Ok ( event_effects)
5460 }
5561
56- /// Find the event which is going to be disptached in the context, then process it.
57- /// In real cases, the disptached event will be handled by an event loop.
58- /// We use this function to simulate such cases, since we don't have an event loop in tests.
59- pub fn handle_dispatch_event ( & mut self , context : & mut GameContext ) -> Result < EventEffects > {
60- let evt = context
61- . get_dispatch ( )
62- . as_ref ( )
63- . expect ( "No dispatch event" )
64- . event
65- . clone ( ) ;
66- context. cancel_dispatch ( ) ;
67- println ! ( "* Dispatch event: {}" , evt) ;
68- self . handle_event ( context, & evt)
69- }
70-
71- pub fn handle_dispatch_until_no_events (
72- & mut self ,
73- context : & mut GameContext ,
74- clients : Vec < & mut TestClient > ,
75- ) -> Result < EventEffects > {
76- let evt = context
77- . get_dispatch ( )
78- . as_ref ( )
79- . expect ( "No dispatch event" )
80- . event
81- . clone ( ) ;
82- context. cancel_dispatch ( ) ;
83- println ! ( "* Dispatch event: {}" , evt) ;
84- self . handle_event_until_no_events ( context, & evt, clients)
85- }
86-
87- // Handle both client events and dispatch event, until there's no more.
88- pub fn handle_until_no_events (
89- & mut self ,
90- context : & mut GameContext ,
91- mut clients : Vec < & mut TestClient > ,
92- ) -> Result < EventEffects > {
93- let mut evts: Vec < Event > = vec ! [ ] ;
94- let mut event_effects = EventEffects :: default ( ) ;
95-
96- loop {
97- if let Some ( ctx_evt) = context. get_dispatch ( ) {
98- if ctx_evt. timeout == context. get_timestamp ( ) {
99- evts. push ( ctx_evt. event . clone ( ) ) ;
100- context. cancel_dispatch ( ) ;
101- }
102- }
103-
104- for c in clients. iter_mut ( ) {
105- let cli_evts = c. handle_updated_context ( context) ?;
106- evts. extend_from_slice ( & cli_evts) ;
107- if event_effects. checkpoint . is_some ( ) {
108- c. flush_secret_state ( ) ;
109- }
110- }
111-
112- if let Some ( evt) = evts. first ( ) {
113- event_effects = self . handle_event ( context, evt) ?;
114- evts. remove ( 0 ) ;
115- } else {
116- break ;
117- }
118- }
119- Ok ( event_effects)
120- }
121-
122- /// This fn keeps handling events of the following two types, until there is none:
123- /// 1. Event dispatched from within the (updated) context: context.dispatch
124- /// 2. Event dispatched by clients after they see the updated context
125- pub fn handle_event_until_no_events (
126- & mut self ,
127- context : & mut GameContext ,
128- event : & Event ,
129- mut clients : Vec < & mut TestClient > ,
130- ) -> Result < EventEffects > {
131- // 1. Process the `event'(arg) --> context updated
132- // 2. context may dispatch --> take care those with timeout == current timestamp
133- // 3. iter clients to syn with updated context --> a couple of events
134- // 4. handle these client/trans events
135- let mut evts: Vec < Event > = vec ! [ event. clone( ) ] ; // keep handling events in this vec
136- let mut event_effects = EventEffects :: default ( ) ;
137-
138- while !evts. is_empty ( ) {
139- let evt = & evts[ 0 ] ;
140- println ! ( "* Received event: {}" , evt) ;
141-
142- event_effects = self . handle_event ( context, evt) ?;
143- if evts. len ( ) == 1 {
144- evts. clear ( ) ;
145- } else {
146- evts = evts. iter ( ) . skip ( 1 ) . map ( |e| e. clone ( ) ) . collect ( ) ;
147- }
148- if let Some ( ctx_evt) = context. get_dispatch ( ) {
149- if ctx_evt. timeout == context. get_timestamp ( ) {
150- evts. push ( ctx_evt. event . clone ( ) ) ;
151- context. cancel_dispatch ( ) ;
152- }
153- }
154-
155- for c in clients. iter_mut ( ) {
156- let cli_evts = c. handle_updated_context ( context) ?;
157- evts. extend_from_slice ( & cli_evts) ;
158- if event_effects. checkpoint . is_some ( ) {
159- c. flush_secret_state ( ) ;
160- }
161- }
162-
163- if let Some ( dispatch) = context. get_dispatch ( ) {
164- println ! ( "* Context dispatch: {:?}" , dispatch) ;
165- }
166- }
167- Ok ( event_effects)
62+ pub fn set_random_result ( & mut self , random_id : RandomId , result : HashMap < usize , String > ) {
63+ self . random_results . insert ( random_id, result) ;
16864 }
16965
17066 pub fn state ( & self ) -> & H {
0 commit comments