1use std::sync::{Arc, Mutex, RwLock};
2
3use crate::{
4 models::{Announcement, Card, Player},
5 PlayerError, SchnapsenDuo,
6};
7
8pub struct SchnapsenDuoClient {
9 player: Arc<RwLock<Player>>,
10 instance: Arc<Mutex<SchnapsenDuo>>,
11}
12
13impl SchnapsenDuoClient {
14 pub fn new(player: Arc<RwLock<Player>>, instance: Arc<Mutex<SchnapsenDuo>>) -> Self {
15 Self { player, instance }
16 }
17
18 #[inline]
19 pub fn cutt_deck(&self, cards_to_take: usize) -> Result<(), crate::PlayerError> {
20 self.instance
21 .lock()
22 .unwrap()
23 .cutt_deck(self.player.clone(), cards_to_take)
24 }
25
26 #[inline]
27 pub fn get_player_id(&self) -> String {
28 self.player.read().unwrap().id.clone()
29 }
30
31 #[inline]
32 pub fn is_active(&self) -> bool {
33 self.instance
34 .lock()
35 .unwrap()
36 .is_active(&self.player.read().unwrap())
37 }
38
39 pub fn draw_card(&self) -> Result<(), crate::PlayerError> {
40 let card = self
41 .instance
42 .lock()
43 .unwrap()
44 .draw_card_after_trick(self.player.clone())?;
45 self.player.write().unwrap().cards.push(card);
46
47 self.update_player_state();
48 Ok(())
49 }
50
51 pub fn close_talon(&self) -> Result<(), crate::PlayerError> {
52 self.instance
53 .lock()
54 .unwrap()
55 .close_talon(self.player.clone())
56 }
57
58 pub fn take_cards_til(&self, idx: usize) -> Result<(), crate::PlayerError> {
59 let cards = self
60 .instance
61 .lock()
62 .unwrap()
63 .take_cards_til(self.player.clone(), idx)?;
64
65 self.player.write().unwrap().cards.extend(cards);
66 Ok(())
67 }
68
69 pub fn play_card(&self, card: crate::Card) -> Result<(), crate::PlayerError> {
70 self.instance
71 .lock()
72 .unwrap()
73 .play_card(self.player.clone(), card.clone())?;
74 Ok(())
75 }
76
77 pub fn swap_trump(&self, card: crate::Card) -> Result<(), crate::PlayerError> {
78 let swap = self
79 .instance
80 .lock()
81 .unwrap()
82 .swap_trump(self.player.clone(), card.clone())?;
83
84 self.player.write().unwrap().cards.retain(|x| *x != card);
85 self.player.write().unwrap().cards.push(swap);
86
87 self.update_player_state();
88
89 Ok(())
90 }
91
92 pub fn announce_40(&self) -> Result<(), crate::PlayerError> {
93 let announcement = self
94 .instance
95 .lock()
96 .unwrap()
97 .announce_40(&self.player.read().unwrap())?;
98
99 self.announce_state_changes(announcement)?;
100 Ok(())
101 }
102
103 pub fn announce_20(&self, cards: [Card; 2]) -> Result<(), crate::PlayerError> {
104 let announcement = self
105 .instance
106 .lock()
107 .unwrap()
108 .announce_20(&self.player.read().unwrap(), cards)?;
109
110 self.announce_state_changes(announcement)?;
111 Ok(())
112 }
113
114 fn announce_state_changes(&self, announcement: Announcement) -> Result<(), PlayerError> {
115 self.player
116 .write()
117 .unwrap()
118 .announcements
119 .push(announcement.clone());
120
121 self.player
122 .write()
123 .unwrap()
124 .announcable
125 .retain(|x| *x == announcement);
126
127 let mut instance_lock = self.instance.lock().unwrap();
128 instance_lock
129 .notify_changes_playable_cards(&self.player.read().unwrap(), &announcement.cards);
130
131 self.player.write().unwrap().playable_cards = announcement.cards.to_vec();
132 instance_lock.update_announcable_props(self.player.clone());
133 instance_lock.update_finish_round(self.player.clone())?;
134 Ok(())
135 }
136
137 fn update_player_state(&self) {
138 let instance_lock = self.instance.lock().unwrap();
139 let (_, announcable) = instance_lock.notify_announcable_props(&self.player.read().unwrap());
140 self.player.write().unwrap().announcable = announcable;
141
142 let (_, can_swap) = instance_lock.notify_swap_trump_check(&self.player.read().unwrap());
143 self.player.write().unwrap().possible_trump_swap = can_swap;
144
145 let playable_cards = instance_lock.find_playable_cards(self.player.clone());
146 instance_lock.notify_changes_playable_cards(&self.player.read().unwrap(), &playable_cards);
147
148 self.player.write().unwrap().playable_cards = playable_cards.to_vec();
149 }
150}