1
0
Fork 0

MFD framework - add support for Emesary

Allow a MFD to be controlled via Emesary notifications (notifications.PFDEventNotification);

Notification needs to be constructed with the following parameters;

1 - MFD designation (text; name of MFD)
2 - MFD identity (int, id of the MFD within the model). Default 1; same as used when creating the MFD
3 - Event type (PFDEventNotification.SoftKeyPushed, notifications.PFDEventNotification.ChangeMenuText
4 - Event parameter.
  a) for PFDEventNotification.SoftKeyPushed an int identifying the button
  b) for notifications.PFDEventNotification.ChangeMenuText a hash array containing the menu ID and the new text (e.g. [{ Id: 1, Text: "NNN"}])

Method obj.PFD.RegisterWithEmesary(emesary.GlobalTransmitter) need to be called to connect the MFD to a transmitter
This commit is contained in:
Richard Harrison 2017-11-16 02:55:07 +01:00
parent c8e3c0c394
commit 8dafff9933
2 changed files with 121 additions and 3 deletions

View file

@ -137,7 +137,7 @@ var PFD_Device =
# This does not actually create the canvas elements, or parse the SVG, that would typically be done in
# a higher level class that contains an instance of this class.
# see: http://wiki.flightgear.org/Canvas_MFD_Framework
new : func(svg, num_menu_buttons, button_prefix, _canvas)
new : func(svg, num_menu_buttons, button_prefix, _canvas, designation="MFD")
{
var obj = {parents : [PFD_Device] };
obj.svg = svg;
@ -146,6 +146,11 @@ var PFD_Device =
obj.pages = [];
obj.page_index = {};
obj.buttons = setsize([], num_menu_buttons);
obj.transmitter = nil;
# change after creation if required
obj.device_id = 1;
obj.designation = designation;
for(var idx = 0; idx < num_menu_buttons; idx += 1)
{
@ -159,9 +164,64 @@ var PFD_Device =
obj.buttons[idx].setText(sprintf("M",idx));
}
}
obj.Recipient = nil;
return obj;
},
#
# instead of using the direct call method this allows the use of Emesary (via a specified or default global transmitter)
# example to notify that a softkey has been used. The "1" in the line below is the device ID
# var notification = notifications.PFDEventNotification.new(me.designation, me.DeviceId, notifications.PFDEventNotification.SoftKeyPushed, me.mpcd_button_pushed);
# emesary.GlobalTransmitter.NotifyAll(notification);
# - currently supported is
# 1. setting menu text directly (after page has been loaded)
# notifications.PFDEventNotification.new(me.designation, 1, notifications.PFDEventNotification.ChangeMenuText, [{ Id: 1, Text: "NNN"}]);
# 2. SoftKey selection.
#
# the device ID must match this device ID (to allow for multiple devices).
RegisterWithEmesary : func(transmitter = nil){
if (transmitter == nil)
transmitter = emesary.GlobalTransmitter;
if (me.Recipient == nil){
me.Recipient = emesary.Recipient.new("PFD_"~me.designation);
var pfd_obj = me;
me.Recipient.Receive = func(notification)
{
if (notification.Device_id = pfd_obj.device_id
and notification.NotificationType == notifications.PFDEventNotification.DefaultType) {
if (notification.Event_Id == notifications.PFDEventNotification.SoftKeyPushed
and notification.EventParameter != nil)
{
pfd_obj.notifyButton(notification.EventParameter);
}
else if (notification.Event_Id == notifications.PFDEventNotification.ChangeMenuText
and notification.EventParameter != nil)
{
foreach(var eventMenu; notification.EventParameter) {
foreach (var mi ; pfd_obj.current_page.menus) {
if (pfd_obj.buttons[eventMenu.Id] != nil) {
pfd_obj.buttons[eventMenu.Id].setText(eventMenu.Text);
}
else
printf("PFD_device: Menu for button not found. Menu ID '%s'",mi.menu_id);
}
}
}
return emesary.Transmitter.ReceiptStatus_OK;
}
return emesary.Transmitter.ReceiptStatus_NotProcessed;
};
transmitter.Register(me.Recipient);
me.transmitter = transmitter;
}
},
DeRegisterWithEmesary : func(transmitter = nil){
# remove registration from transmitter; but keep the recipient once it is created.
if (me.transmitter != nil)
me.transmitter.DeRegister(me.Recipient);
me.transmitter = nil;
},
#
# called when a button is pushed - connecting the property to this method is implemented in the outer class
notifyButton : func(button_id)
{

View file

@ -25,7 +25,8 @@
var PropertySyncNotificationBase_Id = 16;
var AircraftControlNotification_Id = 17;
var GeoEventNotification_Id = 18;
# event ID 19 reserved for armaments and stores (model defined).
var PFDEventNotification_Id = 20;
#
# PropertySyncNotificationBase is a wrapper class for allow properties to be synchronized between
@ -167,6 +168,8 @@ var GeoEventNotification =
new_class.w_fps = getprop("/velocities/wBody-fps");
new_class.IsDistinct = 0;
new_class.Callsign = nil; # populated automatically by the incoming bridge when routed
new_class.RemoteCallsign = ""; # associated remote callsign.
new_class.Flags = 0; # 8 bits for whatever.
new_class.bridgeProperties = func
{
@ -200,6 +203,14 @@ var GeoEventNotification =
getValue:func{return emesary.TransferFixedDouble.encode(new_class.w_fps,2,10);},
setValue:func(v,root,pos){var dv=emesary.TransferFixedDouble.decode(v,2,10,pos);new_class.w_fps=dv.value;return dv},
},
{
getValue:func{return emesary.TransferString.encode(new_class.RemoteCallsign);},
setValue:func(v,root,pos){var dv=emesary.TransferString.decode(v,pos);new_class.RemoteCallsign=dv.value;return dv},
},
{
getValue:func{return emesary.TransferByte.encode(new_class.Flags);},
setValue:func(v,root,pos){var dv=emesary.TransferByte.decode(v,pos);new_class.Flags=dv.value;return dv},
},
];
};
return new_class;
@ -210,7 +221,7 @@ var GeoEventNotification =
# 1 - Created
# 2 - Moved
# 3 - Deleted
# 4 -
# 4 - Collision
# ----
# Secondary kind (8 bits)
# using the first 4 bits as the classification and the second 4 bits as the sub-classification
@ -502,3 +513,50 @@ var GeoEventNotification =
# 253 1111 1101 -
# 254 1111 1110 -
# 255 1111 1111 -
#
#
# Use to transmit events that happen at a specific place; can be used to make
# models that are simulated locally (e.g. tankers) appear on other player's MP sessions.
var PFDEventNotification =
{
# new:
# _ident - the identifier for the notification. not bridged.
# _pfd_id - numeric identification of the PFD within the model
# _event_id - event ID.
# 1 softkey pushed.
# 2 select page by ID
# _event_param - param related to the event ID. implementation specific.
##
SoftKeyPushed : 1,
SelectPageById : 2,
ChangeMenuText : 3, #event parameter contains hash of { Id: , Text: }
DefaultType : "PFDEventNotification",
new: func(_ident, _device_id,_event_id,_event_parameter_id)
{
var new_class = emesary.Notification.new(PFDEventNotification.DefaultType, _ident, PFDEventNotification_Id);
new_class.Device_Id = _device_id;
new_class.Event_Id = _event_id;
new_class.EventParameter = _event_parameter_id;
new_class.IsDistinct = 1; # each of these events is unique and needs to be bridged
new_class.bridgeProperties = func
{
return
[
{
getValue:func{return emesary.TransferByte.encode(new_class.Event_Id);},
setValue:func(v,root,pos){var dv=emesary.TransferByte.decode(v,pos);new_class.Event_Id=dv.value;return dv},
},
{
getValue:func{return emesary.TransferByte.encode(new_class.EventParameter);},
setValue:func(v,root,pos){var dv=emesary.TransferByte.decode(v,pos);new_class.EventParameter=dv.value;return dv},
},
];
};
return new_class;
},
};