Geary.State.Machine: Support GObject notify signal for state changes

Modernise the API a bit by using properties instead of explicit
getters/setters, an hence support GObject notify signals when the
state property changes.
This commit is contained in:
Michael Gratton 2020-09-27 15:58:40 +10:00 committed by Michael James Gratton
parent ac425f57b1
commit ed4ba33127
3 changed files with 18 additions and 32 deletions

View file

@ -483,11 +483,10 @@ public class Geary.Imap.ClientSession : BaseObject, Logging.Source {
}; };
fsm = new Geary.State.Machine(machine_desc, mappings, on_ignored_transition); fsm = new Geary.State.Machine(machine_desc, mappings, on_ignored_transition);
fsm.set_logging(false);
} }
~ClientSession() { ~ClientSession() {
switch (fsm.get_state()) { switch (fsm.state) {
case State.NOT_CONNECTED: case State.NOT_CONNECTED:
case State.CLOSED: case State.CLOSED:
// no problem-o // no problem-o
@ -782,7 +781,7 @@ public class Geary.Imap.ClientSession : BaseObject, Logging.Source {
private bool on_greeting_timeout() { private bool on_greeting_timeout() {
// if still in CONNECTING state, the greeting never arrived // if still in CONNECTING state, the greeting never arrived
if (fsm.get_state() == State.CONNECTING) if (fsm.state == State.CONNECTING)
fsm.issue(Event.TIMEOUT); fsm.issue(Event.TIMEOUT);
return false; return false;
@ -1645,12 +1644,12 @@ public class Geary.Imap.ClientSession : BaseObject, Logging.Source {
return (this.selected_mailbox == null) return (this.selected_mailbox == null)
? new Logging.State( ? new Logging.State(
this, this,
this.fsm.get_state_string(fsm.get_state()) this.fsm.get_state_string(fsm.state)
) )
: new Logging.State( : new Logging.State(
this, this,
"%s:%s selected %s", "%s:%s selected %s",
this.fsm.get_state_string(fsm.get_state()), this.fsm.get_state_string(fsm.state),
this.selected_mailbox.to_string(), this.selected_mailbox.to_string(),
this.selected_readonly ? "RO" : "RW" this.selected_readonly ? "RO" : "RW"
); );

View file

@ -294,7 +294,7 @@ public class Geary.Imap.Deserializer : BaseObject, Logging.Source {
/** {@inheritDoc} */ /** {@inheritDoc} */
public Logging.State to_logging_state() { public Logging.State to_logging_state() {
return new Logging.State(this, fsm.get_state_string(fsm.get_state())); return new Logging.State(this, fsm.get_state_string(fsm.state));
} }
/** Sets the connection's logging parent. */ /** Sets the connection's logging parent. */
@ -429,7 +429,7 @@ public class Geary.Imap.Deserializer : BaseObject, Logging.Source {
} }
private Mode get_mode() { private Mode get_mode() {
switch (fsm.get_state()) { switch (fsm.state) {
case State.LITERAL_DATA: case State.LITERAL_DATA:
return Mode.BLOCK; return Mode.BLOCK;

View file

@ -5,13 +5,20 @@
*/ */
public class Geary.State.Machine : BaseObject { public class Geary.State.Machine : BaseObject {
/** The state machine's current state. */
public uint state { get; private set; }
/** Determines if the state machine crashes your app when mis-configured. */
public bool abort_on_no_transition { get; set; default = true; }
/** Determines if transition logging is enabled. */
public bool logging { get; private set; default = false; }
private Geary.State.MachineDescriptor descriptor; private Geary.State.MachineDescriptor descriptor;
private uint state;
private Mapping[,] transitions; private Mapping[,] transitions;
private unowned Transition? default_transition; private unowned Transition? default_transition;
private bool locked = false; private bool locked = false;
private bool abort_on_no_transition = true;
private bool logging = false;
private unowned PostTransition? post_transition = null; private unowned PostTransition? post_transition = null;
private void *post_user = null; private void *post_user = null;
private Object? post_object = null; private Object? post_object = null;
@ -39,26 +46,6 @@ public class Geary.State.Machine : BaseObject {
} }
} }
public uint get_state() {
return state;
}
public bool get_abort_on_no_transition() {
return abort_on_no_transition;
}
public void set_abort_on_no_transition(bool abort) {
abort_on_no_transition = abort;
}
public void set_logging(bool logging) {
this.logging = logging;
}
public bool is_logging() {
return logging;
}
public uint issue(uint event, void *user = null, Object? object = null, Error? err = null) { public uint issue(uint event, void *user = null, Object? object = null, Error? err = null) {
assert(event < descriptor.event_count); assert(event < descriptor.event_count);
assert(state < descriptor.state_count); assert(state < descriptor.state_count);
@ -70,7 +57,7 @@ public class Geary.State.Machine : BaseObject {
string msg = "%s: No transition defined for %s@%s".printf(to_string(), string msg = "%s: No transition defined for %s@%s".printf(to_string(),
descriptor.get_event_string(event), descriptor.get_state_string(state)); descriptor.get_event_string(event), descriptor.get_state_string(state));
if (get_abort_on_no_transition()) if (this.abort_on_no_transition)
error(msg); error(msg);
else else
critical(msg); critical(msg);
@ -96,7 +83,7 @@ public class Geary.State.Machine : BaseObject {
} }
locked = false; locked = false;
if (is_logging()) if (this.logging)
message("%s: %s", to_string(), get_transition_string(old_state, event, state)); message("%s: %s", to_string(), get_transition_string(old_state, event, state));
// Perform post-transition if registered // Perform post-transition if registered