Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simplify the sending of asynchronous events with new OpenLCB API option #658

Merged
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
123 changes: 15 additions & 108 deletions src/openlcb/BroadcastTime.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,9 @@ public:
/// @param minutes minutes (0 to 59)
void set_time(int hours, int minutes)
{
new SetFlow(this, SetFlow::Command::SET_TIME, hours, minutes);
EventId event_id = BroadcastTimeDefs::EVENT_SET_SUFFIX_MASK |
BroadcastTimeDefs::time_to_event(eventBase_, hours, minutes);
send_event(node_, event_id);
}

/// Set the time in seconds since the system Epoch. The new date does not
Expand All @@ -71,15 +73,19 @@ public:
/// @param day day of month (1 to 31)
void set_date(int month, int day)
{
new SetFlow(this, SetFlow::Command::SET_DATE, month, day);
EventId event_id = BroadcastTimeDefs::EVENT_SET_SUFFIX_MASK |
BroadcastTimeDefs::date_to_event(eventBase_, month, day);
send_event(node_, event_id);
}

/// Set the time in seconds since the system Epoch. The new year does not
/// become valid until the update callbacks are called.
/// @param year (0AD to 4095AD)
void set_year(int year)
{
new SetFlow(this, SetFlow::Command::SET_YEAR, year);
EventId event_id = BroadcastTimeDefs::EVENT_SET_SUFFIX_MASK |
BroadcastTimeDefs::year_to_event(eventBase_, year);
send_event(node_, event_id);
}

/// Set the date and year from a C string.
Expand All @@ -92,25 +98,27 @@ public:
/// rrrrrrrrrr.rr
void set_rate_quarters(int16_t rate)
{
new SetFlow(this, SetFlow::Command::SET_RATE, rate);
EventId event_id = BroadcastTimeDefs::EVENT_SET_SUFFIX_MASK |
BroadcastTimeDefs::rate_to_event(eventBase_, rate);
send_event(node_, event_id);
}

/// Start clock
void start()
{
new SetFlow(this, SetFlow::Command::START);
send_event(node_, eventBase_ | BroadcastTimeDefs::START_EVENT_SUFFIX);
}

/// Stop clock
void stop()
{
new SetFlow(this, SetFlow::Command::STOP);
send_event(node_, eventBase_ | BroadcastTimeDefs::STOP_EVENT_SUFFIX);
}

/// Query the current time.
void query()
{
new SetFlow(this, SetFlow::Command::QUERY);
send_event(node_, eventBase_ | BroadcastTimeDefs::QUERY_EVENT_SUFFIX);
}

/// Get the time as a value of seconds relative to the system epoch. At the
Expand Down Expand Up @@ -410,107 +418,6 @@ public:
virtual bool is_server_self() = 0;

protected:
class SetFlow : public StateFlowBase
{
public:
/// Supported operations.
enum Command
{
SET_TIME, ///< set time request
SET_DATE, ///< set date request
SET_YEAR, ///< set year reauest
SET_RATE, ///< set rate request
START, ///< stop request
STOP, ///< start request
QUERY, ///< issue a query
};

/// Constructor.
/// @param clock the parent clock instance
/// @param command operation to perform
/// @param data1 first data argument
/// @param data2 second data argument
SetFlow(BroadcastTime *clock, Command command,
int data1 = 0, int data2 = 0)
: StateFlowBase(clock->node()->iface())
, clock_(clock)
, command_(command)
, data1_(data1)
, data2_(data2)
{
start_flow(STATE(send_event));
}

private:

/// Send the necessary event.
/// @return delete_this()
Action send_event()
{
uint64_t event_id;
switch (command_)
{
case SET_TIME:
event_id = BroadcastTimeDefs::EVENT_SET_SUFFIX_MASK |
BroadcastTimeDefs::time_to_event(clock_->event_base(),
data1_, data2_);
break;
case SET_DATE:
event_id = BroadcastTimeDefs::EVENT_SET_SUFFIX_MASK |
BroadcastTimeDefs::date_to_event(clock_->event_base(),
data1_, data2_);
break;
case SET_YEAR:
event_id = BroadcastTimeDefs::EVENT_SET_SUFFIX_MASK |
BroadcastTimeDefs::year_to_event(clock_->event_base(),
data1_);
break;
case SET_RATE:
event_id = BroadcastTimeDefs::EVENT_SET_SUFFIX_MASK |
BroadcastTimeDefs::rate_to_event(clock_->event_base(),
data1_);
break;
case START:
event_id = clock_->event_base() |
BroadcastTimeDefs::START_EVENT_SUFFIX;
break;
case STOP:
event_id = clock_->event_base() |
BroadcastTimeDefs::STOP_EVENT_SUFFIX;
break;
case QUERY:
event_id = clock_->event_base() |
BroadcastTimeDefs::QUERY_EVENT_SUFFIX;
break;
default:
// should never get here.
LOG_ERROR("Unhanded SetFlow command");
return delete_this();
}

if (!clock_->node()->is_initialized())
{
// since the node is not yet initialized, events get thrown on
// the floor, we will try a shortcut instead
clock_->set_shortcut(event_id);
return delete_this();
}
else
{
writer_.WriteAsync(clock_->node(), Defs::MTI_EVENT_REPORT,
WriteHelper::global(), eventid_to_buffer(event_id), this);

return wait_and_call(STATE(delete_this));
}
}

WriteHelper writer_; ///< helper for sending event messages
BroadcastTime *clock_; ///< the parent clock instance
Command command_; ///< operation to perform;
int data1_; ///< first data argument
int data2_; ///< second data argument
};

/// Constructor.
/// @param node the virtual node that will be listening for events and
/// responding to Identify messages.
Expand Down