1 | from typing import List, Dict, Set, Optional
|
---|
2 |
|
---|
3 | from geniusweb.actions.Action import Action
|
---|
4 | from geniusweb.actions.LearningDone import LearningDone
|
---|
5 | from geniusweb.actions.PartyId import PartyId
|
---|
6 | from geniusweb.inform.Agreements import Agreements
|
---|
7 | from geniusweb.progress.Progress import Progress
|
---|
8 | from geniusweb.protocol.ProtocolException import ProtocolException
|
---|
9 | from geniusweb.protocol.session.DefaultSessionState import DefaultSessionState
|
---|
10 | from geniusweb.protocol.session.SessionResult import SessionResult
|
---|
11 | from geniusweb.protocol.session.learn.LearnSettings import LearnSettings
|
---|
12 | from geniusweb.references.PartyWithProfile import PartyWithProfile
|
---|
13 |
|
---|
14 | class LearnState (DefaultSessionState["LearnState", "LearnSettings"]):
|
---|
15 | '''
|
---|
16 | Stores the state for Learn protocol. Immutable.
|
---|
17 | '''
|
---|
18 |
|
---|
19 | def __init__(self, actions:List[Action] , conns:List[PartyId] ,
|
---|
20 | progress:Optional[Progress] , settings:LearnSettings ,
|
---|
21 | partyprofiles:Dict[PartyId, PartyWithProfile]={},
|
---|
22 | e:Optional[ProtocolException]=None ):
|
---|
23 | '''
|
---|
24 | @param actions the actions done by the parties
|
---|
25 | @param conns the existing party connections. we assume ownership
|
---|
26 | of this so it should not be modified although
|
---|
27 | connections may of course break. If null, default
|
---|
28 | empty list is used. Can be less than 2 parties in
|
---|
29 | the first phases of the setup.
|
---|
30 | @param progress the {@link Progress} line. can be null
|
---|
31 | @param settings the {@link LearnSettings}
|
---|
32 | @param partyprofiles map with the {@link PartyWithProfile} for connected
|
---|
33 | parties.
|
---|
34 | @param e the {@link ProtocolException}, or null if none
|
---|
35 | occurred.
|
---|
36 | '''
|
---|
37 |
|
---|
38 | super().__init__(actions, conns, progress, settings, partyprofiles, e)
|
---|
39 |
|
---|
40 | # def LearnState(LearnSettings settings) {
|
---|
41 | # '''
|
---|
42 | # Creates the initial state from the given settings and progress=null
|
---|
43 | #
|
---|
44 | # @param settings the {@link LearnSettings}
|
---|
45 | # '''
|
---|
46 | # this(Collections.emptyList(), Collections.emptyList(), null, settings,
|
---|
47 | # null, null);
|
---|
48 | #
|
---|
49 | # }
|
---|
50 |
|
---|
51 | def With(self, actions:List[Action] , conns:List[PartyId],
|
---|
52 | progr:Optional[Progress] , settings:LearnSettings,
|
---|
53 | partyprofiles:Dict[PartyId, PartyWithProfile] ,
|
---|
54 | e:Optional[ProtocolException] ) -> "LearnState" :
|
---|
55 | return LearnState(actions, conns, progr, settings, partyprofiles,
|
---|
56 | e)
|
---|
57 |
|
---|
58 | def getAgreements(self)->Agreements :
|
---|
59 | return Agreements()
|
---|
60 |
|
---|
61 | def getResult(self)->SessionResult :
|
---|
62 | return SessionResult(self.getPartyProfiles(), self.getAgreements(),
|
---|
63 | {}, None)
|
---|
64 |
|
---|
65 | def isFinal(self, currentTimeMs:int) ->bool:
|
---|
66 | done = self._getDoneLearning()
|
---|
67 | # if done is empty we're probably still starting up.
|
---|
68 | return super().isFinal(currentTimeMs)\
|
---|
69 | or (len(done)!=0 and set(self.getConnections()).issubset(done))
|
---|
70 |
|
---|
71 | def WithException(self, e:ProtocolException) ->"LearnState" :
|
---|
72 | '''
|
---|
73 | @param e the error that occured
|
---|
74 | @return a new state with the error set.
|
---|
75 | '''
|
---|
76 | return LearnState(self.getActions(), self.getConnections(), self.getProgress(),
|
---|
77 | self.getSettings(), self.getPartyProfiles(), e)
|
---|
78 |
|
---|
79 | def checkAction(self, actor:PartyId , action:Action ) ->Optional[str]:
|
---|
80 | '''
|
---|
81 | @param actor the known real actor that did this action
|
---|
82 | @param action an {@link Action}
|
---|
83 | @return null if action seems ok, or message explaining why not.
|
---|
84 | '''
|
---|
85 | msg = super().checkAction(actor, action)
|
---|
86 | if msg != None:
|
---|
87 | return msg
|
---|
88 | if actor in self._getDoneLearning():
|
---|
89 | return "actor already was done learning"
|
---|
90 | if not isinstance(action, LearningDone):
|
---|
91 | return "Action " + str(action) + " is not allowed"
|
---|
92 | return None
|
---|
93 |
|
---|
94 | def _getDoneLearning(self)->Set[PartyId] :
|
---|
95 | '''
|
---|
96 | @return set of parties that reported they are done with learning.
|
---|
97 | '''
|
---|
98 | return set([party.getActor() for party in self.getActions() ])
|
---|
99 | |
---|