Added Emesary Multiplayer bridge
This commit is contained in:
parent
f87afb2677
commit
1ec48a966c
4 changed files with 485 additions and 16 deletions
|
@ -65,21 +65,53 @@ var ANSPN46ActiveNotification =
|
|||
# param(_anspn46_system): instance of ANSPN46_System which will send the notification
|
||||
new: func(_anspn46_system)
|
||||
{
|
||||
var new_class = emesary.Notification.new("ANSPN46ActiveNotification", _anspn46_system.Ident);
|
||||
var ident="none";
|
||||
if (_anspn46_system != nil)
|
||||
ident=_anspn46_system.Ident;
|
||||
|
||||
var new_class = emesary.Notification.new("ANSPN46ActiveNotification", ident);
|
||||
|
||||
new_class.ANSPN46_system = _anspn46_system;
|
||||
new_class.Position = nil;
|
||||
new_class.BeamPosition = nil;
|
||||
|
||||
new_class.BeamAngle = 35;
|
||||
new_class.Channel = 2;
|
||||
new_class.BeamRange = 35; ##nm
|
||||
new_class.BeamPower = 999; ## mw ???
|
||||
|
||||
#
|
||||
# Set notification properties from the ANSPN46_System.
|
||||
new_class.set_from = func(_anspn)
|
||||
{
|
||||
me.Position = _anspn.GetCarrierPosition();
|
||||
me.BeamPosition = _anspn.GetTDZPosition();
|
||||
me.BeamAngle = 35;
|
||||
me.Channel = _anspn.GetChannel();
|
||||
me.BeamRange = 35; ##nm
|
||||
me.BeamPower = 999; ## mw ???
|
||||
if (_anspn != nil)
|
||||
{
|
||||
me.Ident = _anspn.Ident;
|
||||
me.Position = _anspn.GetCarrierPosition();
|
||||
me.BeamPosition = _anspn.GetTDZPosition();
|
||||
|
||||
me.BeamAngle = 35;
|
||||
me.Channel = _anspn.GetChannel();
|
||||
me.BeamRange = 35; ##nm
|
||||
me.BeamPower = 999; ## mw ???
|
||||
}
|
||||
print("\nANSPN46ActiveNotification::set_from: ", me.Ident);
|
||||
};
|
||||
new_class.set_from(_anspn46_system);
|
||||
new_class.bridgeProperties = func
|
||||
{
|
||||
return
|
||||
[
|
||||
{
|
||||
getValue:func{return emesary.TransferCoord.encode(new_class.Position);},
|
||||
setValue:func(v){new_class.Position=emesary.TransferCoord.decode(v);},
|
||||
},
|
||||
{
|
||||
getValue:func{return emesary.TransferByte.encode(new_class.Channel);},
|
||||
setValue:func(v){new_class.Channel=emesary.TransferByte.decode(v);},
|
||||
},
|
||||
];
|
||||
};
|
||||
new_class.set_from(new_class.ANSPN46_system);
|
||||
return new_class;
|
||||
},
|
||||
};
|
||||
|
@ -228,7 +260,7 @@ var ANSPN46_System =
|
|||
{
|
||||
print("AN/SNP46 created for "~_ident);
|
||||
|
||||
var new_class = emesary.Recipient.new("ANSPN46_System "~_ident);
|
||||
var new_class = emesary.Recipient.new(_ident~".ANSPN46");
|
||||
|
||||
new_class.ara_63_position = geo.Coord.new();
|
||||
new_class.Model = _model;
|
||||
|
@ -315,7 +347,7 @@ var ANSPN46_System =
|
|||
# this will be reset if we receive something back from the aircraft.
|
||||
if (me.UpdateRate < 10)
|
||||
me.UpdateRate = me.UpdateRate+1;
|
||||
# print("AN/SPN 46 : update from",me.Ident," rate=",me.UpdateRate);
|
||||
print("AN/SPN 46 : update msg: ",me.msg.Ident," sys.rate=",me.UpdateRate);
|
||||
return emesary.GlobalTransmitter.NotifyAll(me.msg);
|
||||
};
|
||||
|
||||
|
|
|
@ -24,6 +24,8 @@
|
|||
#
|
||||
#---------------------------------------------------------------------------*/
|
||||
|
||||
var __emesaryUniqueId = 14; # 0-15 are reserved, this way the global transmitter will be 15.
|
||||
|
||||
# Transmitters send notifications to all recipients that are registered.
|
||||
var Transmitter =
|
||||
{
|
||||
|
@ -41,6 +43,8 @@ var Transmitter =
|
|||
var new_class = { parents: [Transmitter]};
|
||||
new_class.Recipients = [];
|
||||
new_class.Ident = _ident;
|
||||
__emesaryUniqueId += 1;
|
||||
new_class.UniqueId = __emesaryUniqueId;
|
||||
return new_class;
|
||||
},
|
||||
|
||||
|
@ -78,9 +82,9 @@ var Transmitter =
|
|||
|
||||
PrintRecipients: func
|
||||
{
|
||||
print("Recpient list");
|
||||
print("Recpient list for ",me.Ident,"(",me.UniqueId,")");
|
||||
for (var idx = 0; idx < size(me.Recipients); idx += 1)
|
||||
print("Recpient ",idx," ",me.Recipients[idx].Ident);
|
||||
print("Recpient ",idx," ",me.Recipients[idx].Ident," (",me.Recipients[idx].UniqueId,")");
|
||||
},
|
||||
|
||||
# Notify all registered recipients. Stop when receipt status of abort or finished are received.
|
||||
|
@ -94,7 +98,7 @@ var Transmitter =
|
|||
var return_status = Transmitter.ReceiptStatus_NotProcessed;
|
||||
foreach (var recipient; me.Recipients)
|
||||
{
|
||||
if (recipient.Active)
|
||||
if (recipient.RecipientActive)
|
||||
{
|
||||
var rstat = recipient.Receive(message);
|
||||
|
||||
|
@ -147,13 +151,27 @@ var Transmitter =
|
|||
#
|
||||
# Base class for Notifications. By convention a Notification has a type and a value.
|
||||
# SubClasses can add extra properties or methods.
|
||||
# Properties:
|
||||
# Ident : Generic message identity. Can be an ident, or for simple messages a value that needs transmitting.
|
||||
# Type : Message Type
|
||||
# IsDistinct : non zero if this message supercedes previous messages of this type.
|
||||
# Distinct messages are usually sent often and self contained
|
||||
# (i.e. no relative state changes such as toggle value)
|
||||
# Messages that indicate an event (such as after a pilot action)
|
||||
# will usually be non-distinct. So an example would be gear/up down
|
||||
# or ATC acknowledgements that all need to be transmitted
|
||||
# The IsDistinct is important for any messages that are bridged over MP as
|
||||
# only the most recently sent distinct message will be transmitted over MP
|
||||
var Notification =
|
||||
{
|
||||
new: func(_type, _value)
|
||||
new: func(_type, _ident)
|
||||
{
|
||||
var new_class = { parents: [Notification]};
|
||||
new_class.Value = _value;
|
||||
new_class.Ident = _ident;
|
||||
new_class.Type = _type;
|
||||
new_class.IsDistinct = 1;
|
||||
new_class.FromIncomingBridge = 0;
|
||||
new_class.Callsign = nil;
|
||||
return new_class;
|
||||
},
|
||||
};
|
||||
|
@ -174,7 +192,9 @@ var Recipient =
|
|||
construct: func(_ident, new_class)
|
||||
{
|
||||
new_class.Ident = _ident;
|
||||
new_class.Active = 1;
|
||||
new_class.RecipientActive = 1;
|
||||
__emesaryUniqueId += 1;
|
||||
new_class.UniqueId = __emesaryUniqueId;
|
||||
new_class.Receive = func(notification)
|
||||
{
|
||||
# warning if required function not
|
||||
|
@ -189,3 +209,52 @@ var Recipient =
|
|||
# Instantiate a Global Transmitter, this is a convenience and a known starting point. Generally most classes will
|
||||
# use this transmitters, however other transmitters can be created and merely use the global transmitter to discover each other
|
||||
var GlobalTransmitter = Transmitter.new("GlobalTransmitter");
|
||||
|
||||
var TransferCoord =
|
||||
{
|
||||
encode : func(v)
|
||||
{
|
||||
return mp_broadcast.Binary.encodeCoord(v);
|
||||
},
|
||||
decode : func(v)
|
||||
{
|
||||
return mp_broadcast.Binary.decodeCoord(v);
|
||||
}
|
||||
};
|
||||
|
||||
var TransferByte =
|
||||
{
|
||||
encode : func(v)
|
||||
{
|
||||
return mp_broadcast.Binary.encodeByte(v);
|
||||
},
|
||||
decode : func(v)
|
||||
{
|
||||
return mp_broadcast.Binary.decodeByte(v);
|
||||
}
|
||||
};
|
||||
|
||||
var TransferInt =
|
||||
{
|
||||
encode : func(v)
|
||||
{
|
||||
return mp_broadcast.Binary.encodeInt(v);
|
||||
},
|
||||
decode : func(v)
|
||||
{
|
||||
return mp_broadcast.Binary.decodeInt(v);
|
||||
}
|
||||
};
|
||||
|
||||
var TransferDouble =
|
||||
{
|
||||
encode : func(v)
|
||||
{
|
||||
return mp_broadcast.Binary.encodeDouble(v);
|
||||
},
|
||||
decode : func(v)
|
||||
{
|
||||
return mp_broadcast.Binary.decodeDouble(v);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
319
Nasal/emesary_mp_bridge.nas
Normal file
319
Nasal/emesary_mp_bridge.nas
Normal file
|
@ -0,0 +1,319 @@
|
|||
#
|
||||
# bridge message rules;
|
||||
# - if distinct must be absolute and self contained as a later message will supercede any earlier ones in the outgoing queue.
|
||||
# - use the message type and ident to identify distinct messages
|
||||
# The outgoing 'port' is a multiplay/generic/string index.
|
||||
# - ! is used as a seperator between the elements that are used to send the notification (typeid, sequence, notification)
|
||||
# - ; is used to seperate serialzied elemnts of the notification
|
||||
#
|
||||
# Outgoing messages are sent in a scheduled manner, usually once per second, and each message has a lifetime (to allow for propogation to
|
||||
# all clients over UDP). Clients will ignore messages that they have already received (based on the sequence id).
|
||||
#
|
||||
# The incoming bridge will usually be created part of the aircraft model file; it is important to understand that each AI/MP model will have an incoming bridge
|
||||
# as each element in /ai/models needs its own bridge to keep up with the incoming sequence id. This scheme may not work properly as it relies on the model being
|
||||
# loaded which may only happen when visible so it may be necessary to track AI models in a seperate instantiatable incoming bridge manager.
|
||||
#
|
||||
# The outgoing bridge would usually be created within the aircraft loading Nasal.
|
||||
var OutgoingMPBridge =
|
||||
{
|
||||
new: func(_ident, _notifications_to_bridge=nil, _mpidx=19, _root="", _transmitter=nil)
|
||||
{
|
||||
if (_transmitter == nil)
|
||||
_transmitter = emesary.GlobalTransmitter;
|
||||
|
||||
print("OutgoingMPBridge created for "~_ident);
|
||||
|
||||
var new_class = emesary.Recipient.new("OutgoingMPBridge "~_ident);
|
||||
|
||||
new_class.MessageIndex = 100;
|
||||
# foreach (var notification; _notifications_to_bridge)
|
||||
# new_class.NotificationsToBridge = notification.new(;
|
||||
if(_notifications_to_bridge == nil)
|
||||
new_class.NotificationsToBridge = [];
|
||||
else
|
||||
new_class.NotificationsToBridge = _notifications_to_bridge;
|
||||
|
||||
new_class.MPout = "";
|
||||
new_class.MPidx = _mpidx;
|
||||
new_class.MessageLifeTime = 10; # seconds
|
||||
new_class.OutgoingList = [];
|
||||
new_class.Transmitter = _transmitter;
|
||||
new_class.TransmitRequired=0;
|
||||
new_class.Transmitter.Register(new_class);
|
||||
new_class.MpVariable = _root~"sim/multiplay/generic/string["~new_class.MPidx~"]";
|
||||
new_class.TransmitterActive = 0;
|
||||
|
||||
new_class.TransmitTimer =
|
||||
maketimer(6, func
|
||||
{
|
||||
if(new_class.TransmitterActive)
|
||||
new_class.Transmit();
|
||||
|
||||
new_class.TransmitTimer.restart(1);
|
||||
});
|
||||
new_class.TransmitTimer.restart(1);
|
||||
|
||||
new_class.Delete = func
|
||||
{
|
||||
if (me.Transmitter != nil) {
|
||||
me.Transmitter.DeRegister(me);
|
||||
me.Transmitter = nil;
|
||||
}
|
||||
};
|
||||
new_class.AddMessage = func(m)
|
||||
{
|
||||
append(me.NotificationsToBridge, m);
|
||||
};
|
||||
|
||||
#-------------------------------------------
|
||||
# Receive override:
|
||||
new_class.Receive = func(notification)
|
||||
{
|
||||
if (notification.FromIncomingBridge)
|
||||
return emesary.Transmitter.ReceiptStatus_NotProcessed;
|
||||
|
||||
#print("Receive ",notification.Type," (",notification.Ident);
|
||||
for (var idx = 0; idx < size(me.NotificationsToBridge); idx += 1)
|
||||
{
|
||||
if(me.NotificationsToBridge[idx].Type == notification.Type)
|
||||
{
|
||||
me.MessageIndex += 1;
|
||||
notification.MessageExpiryTime = systime()+me.MessageLifeTime;
|
||||
notification.BridgeMessageId = me.MessageIndex;
|
||||
notification.BridgeMessageTypeId = idx;
|
||||
#
|
||||
# The message key is a composite of the type and ident to allow for multiple senders
|
||||
# of the same message type.
|
||||
notification.BridgeMessageTypeKey = notification.Type~"."~notification.Ident;
|
||||
#print("Received ",notification.BridgeMessageTypeKey," expire=",notification.MessageExpiryTime);
|
||||
me.AddToOutgoing(notification);
|
||||
return emesary.Transmitter.ReceiptStatus_Pending;
|
||||
}
|
||||
}
|
||||
return emesary.Transmitter.ReceiptStatus_NotProcessed;
|
||||
};
|
||||
new_class.AddToOutgoing = func(notification)
|
||||
{
|
||||
if (notification.IsDistinct)
|
||||
{
|
||||
for (var idx = 0; idx < size(me.OutgoingList); idx += 1)
|
||||
{
|
||||
if(me.OutgoingList[idx].BridgeMessageTypeKey == notification.BridgeMessageTypeKey)
|
||||
{
|
||||
#print("Update ",me.OutgoingList[idx].BridgeMessageTypeKey);
|
||||
me.OutgoingList[idx]= notification;
|
||||
me.TransmitterActive = size(me.OutgoingList);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
#print("Added ",notification.BridgeMessageTypeKey);
|
||||
append(me.OutgoingList, notification);
|
||||
me.TransmitterActive = size(me.OutgoingList);
|
||||
};
|
||||
new_class.Transmit = func
|
||||
{
|
||||
var outgoing = "";
|
||||
var cur_time=systime();
|
||||
var out_idx = 0;
|
||||
for (var idx = 0; idx < size(me.OutgoingList); idx += 1)
|
||||
{
|
||||
var sect = "";
|
||||
var notification = me.OutgoingList[idx];
|
||||
if (notification.MessageExpiryTime > cur_time)
|
||||
{
|
||||
var encval="";
|
||||
var first_time = 1;
|
||||
var eidx = 0;
|
||||
foreach(var p ; notification.bridgeProperties())
|
||||
{
|
||||
if (encval != "")
|
||||
encval = encval ~ ";";
|
||||
encval = encval ~ p.getValue();
|
||||
#print("Encode ",eidx,"=",encval);
|
||||
eidx += 1;
|
||||
}
|
||||
sect = sprintf("%d!%d!%s",notification.BridgeMessageId, notification.BridgeMessageTypeId, encval);
|
||||
outgoing = outgoing~sect;
|
||||
me.OutgoingList[out_idx] = me.OutgoingList[idx];
|
||||
# print("xmit ",idx," out=",out_idx);
|
||||
out_idx += 1;
|
||||
}
|
||||
# else
|
||||
# printf("expired ",idx,out_idx);
|
||||
}
|
||||
me.TransmitterActive = size(me.OutgoingList);
|
||||
var del_count = size(me.OutgoingList)-out_idx;
|
||||
setprop(me.MpVariable,outgoing);
|
||||
# print("Set ",me.MpVariable," to ",outgoing);
|
||||
# print("outgoingList : ",out_idx, " ", size(me.OutgoingList), " del count=",del_count);
|
||||
for(var del_i=0; del_i < del_count; del_i += 1)
|
||||
pop(me.OutgoingList);
|
||||
};
|
||||
return new_class;
|
||||
},
|
||||
};
|
||||
|
||||
#
|
||||
#
|
||||
# one of these for each model instantiated in the model XML - it will
|
||||
# route messages to
|
||||
var IncomingMPBridge =
|
||||
{
|
||||
new: func(_ident, _notifications_to_bridge=nil, _mpidx=19, _transmitter=nil)
|
||||
{
|
||||
if (_transmitter == nil)
|
||||
_transmitter = emesary.GlobalTransmitter;
|
||||
|
||||
print("IncominggMPBridge created for "~_ident);
|
||||
|
||||
var new_class = emesary.Transmitter.new("IncominggMPBridge "~_ident);
|
||||
|
||||
new_class.IncomingMessageIndex = 100;
|
||||
if(_notifications_to_bridge == nil)
|
||||
new_class.NotificationsToBridge = [];
|
||||
else
|
||||
new_class.NotificationsToBridge = _notifications_to_bridge;
|
||||
|
||||
new_class.MPout = "";
|
||||
new_class.MPidx = _mpidx;
|
||||
new_class.MessageLifeTime = 10; # seconds
|
||||
new_class.OutgoingList = [];
|
||||
new_class.Transmitter = _transmitter;
|
||||
new_class.MpVariable = "";
|
||||
|
||||
new_class.Connect = func(_root)
|
||||
{
|
||||
me.MpVariable = _root~"sim/multiplay/generic/string["~new_class.MPidx~"]";
|
||||
me.Callsign = getprop(_root~"callsign");
|
||||
print("bridge ",me.MpVariable, " callsign ",me.Callsign);
|
||||
setlistener(me.MpVariable, func(v)
|
||||
{
|
||||
me.ProcessIncoming(v.getValue());
|
||||
});
|
||||
};
|
||||
|
||||
new_class.AddMessage = func(m)
|
||||
{
|
||||
append(me.NotificationsToBridge, m);
|
||||
};
|
||||
|
||||
new_class.Remove = func
|
||||
{
|
||||
print("Emesary IncomingMPBridge Remove() ",me.Ident);
|
||||
me.Transmitter.DeRegister(me);
|
||||
};
|
||||
|
||||
#-------------------------------------------
|
||||
# Receive override:
|
||||
new_class.ProcessIncoming = func(encoded_val)
|
||||
{
|
||||
if (encoded_val == "")
|
||||
return;
|
||||
# print("ProcessIncoming ", encoded_val);
|
||||
var encoded_notifications = split(";", encoded_val);
|
||||
for (var idx = 0; idx < size(encoded_notifications); idx += 1)
|
||||
{
|
||||
# get the message parts
|
||||
var encoded_notification = split("!", encoded_val);
|
||||
if (size(encoded_notification) < 3)
|
||||
print("Error: emesary.IncomingBridge.ProcessIncoming bad msg ",encoded_val);
|
||||
else
|
||||
{
|
||||
var msg_idx = encoded_notification[0];
|
||||
var msg_type_id = encoded_notification[1];
|
||||
if (msg_type_id >= size(me.NotificationsToBridge))
|
||||
{
|
||||
print("Error: emesary.IncomingBridge.ProcessIncoming invalid type_id ",msg_type_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
var msg = me.NotificationsToBridge[msg_type_id];
|
||||
var msg_notify = encoded_notification[2];
|
||||
print("received idx=",msg_idx," ",msg_type_id,":",msg.Type);
|
||||
if(msg_idx <= me.IncomingMessageIndex)
|
||||
print(" **Already processed");
|
||||
else
|
||||
{
|
||||
# raise notification
|
||||
var bridged_notification = msg; #emesary.Notification.new(msg.Type,"BridgedMessage");
|
||||
# populate fields
|
||||
var bridgedProperties = msg.bridgeProperties();
|
||||
var encvals=split(";", msg_notify);
|
||||
|
||||
for (var bpi = 0; bpi < size(encvals); bpi += 1) {
|
||||
if (bpi < size(bridgedProperties)) {
|
||||
var bp = bridgedProperties[bpi];
|
||||
print("encval ",bpi,"=",encvals[bpi]);
|
||||
if (encvals[bpi] != ";" and encvals[bpi] != "") {
|
||||
var bp = bridgedProperties[bpi];
|
||||
bp.setValue(encvals[bpi]);
|
||||
}
|
||||
#else
|
||||
#print("EMPTY encoded ",bpi," empty");
|
||||
} else
|
||||
print("Error: emesary.IncomingBridge.ProcessIncoming: supplementary encoded value at",bpi);
|
||||
}
|
||||
if (bridged_notification.Ident == "none")
|
||||
bridged_notification.Ident = "mp-bridge";
|
||||
bridged_notification.FromIncomingBridge = 1;
|
||||
bridged_notification.Callsign = me.Callsign;
|
||||
me.Transmitter.NotifyAll(bridged_notification);
|
||||
me.IncomingMessageIndex = msg_idx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach(var n; new_class.NotificationsToBridge)
|
||||
{
|
||||
print("IncomingBridge: ",n.Type);
|
||||
}
|
||||
return new_class;
|
||||
},
|
||||
startMPBridge : func(notification_list)
|
||||
{
|
||||
var incomingBridgeList = {};
|
||||
setlistener("/ai/models/model-added", func(v)
|
||||
{
|
||||
#Model added /ai[0]/models[0]/multiplayer[0]
|
||||
var path = v.getValue();
|
||||
print("Model added ",path);
|
||||
if (find("/multiplayer",path) > 0)
|
||||
{
|
||||
var callsign = getprop(path~"/callsign");
|
||||
print("Creating Emesary MPBridge for ",callsign);
|
||||
if (callsign == "" or callsign == nil)
|
||||
callsign = path;
|
||||
var incomingBridge = emesary_mp_bridge.IncomingMPBridge.new(callsign~"mp", notification_list, 19);
|
||||
incomingBridge.Connect(path~"/");
|
||||
incomingBridgeList[path] = incomingBridge;
|
||||
}
|
||||
});
|
||||
|
||||
setlistener("/ai/models/model-removed", func(v){
|
||||
print("Model removed ",v.getValue());
|
||||
var path = v.getValue();
|
||||
var bridge = incomingBridgeList[path];
|
||||
if (bridge != nil)
|
||||
{
|
||||
bridge.Remove();
|
||||
incomingBridgeList[path]=nil;
|
||||
}
|
||||
});
|
||||
},
|
||||
};
|
||||
#to setup bridges;
|
||||
#io.load_nasal(getprop("/sim/fg-root") ~ "/Nasal/emesary_mp_bridge.nas");
|
||||
#var outgoingBridge = emesary_mp_bridge.OutgoingMPBridge.new("F-15mp");
|
||||
#outgoingBridge.AddMessage(an_spn_46.ANSPN46ActiveNotification.new("template"));
|
||||
#incomingBridge = emesary_mp_bridge.IncomingMPBridge.new("F-15mp");
|
||||
#incomingBridge.AddMessage(an_spn_46.ANSPN46ActiveNotification.new("template"));
|
||||
#var outgoingBridge = emesary_mp_bridge.OutgoingMPBridge.new("F-15mp");
|
||||
#outgoingBridge.AddMessage(an_spn_46.ANSPN46ActiveNotification.new("template"));
|
||||
# var m = emesary.notifications.TacticalNotification("rr",2);
|
||||
# emesary.GlobalTransmitter.NotifyAll(m);
|
||||
#var outgoingBridge = emesary_mp_bridge.OutgoingMPBridge.new("F-15mp");
|
||||
#outgoingBridge.AddMessage(notifications.TacticalNotification.new(nil));
|
||||
# var m = emesary.notifications.TacticalNotification("rr",2);
|
||||
# emesary.GlobalTransmitter.NotifyAll(m);
|
49
Nasal/notifications.nas
Normal file
49
Nasal/notifications.nas
Normal file
|
@ -0,0 +1,49 @@
|
|||
#---------------------------------------------------------------------------
|
||||
#
|
||||
# Title : EMESARY flightgear standardised notifications
|
||||
#
|
||||
# File Type : Implementation File
|
||||
#
|
||||
# Description : Messages that are applicable across all models and do not specifically relate to a single sysmte
|
||||
# : - mostly needed when using the mutiplayer bridge
|
||||
#
|
||||
# Author : Richard Harrison (richard@zaretto.com)
|
||||
#
|
||||
# Creation Date : 06 April 2016
|
||||
#
|
||||
# Version : 4.8
|
||||
#
|
||||
# Copyright © 2016 Richard Harrison Released under GPL V2
|
||||
#
|
||||
#---------------------------------------------------------------------------*/
|
||||
|
||||
var TacticalNotification =
|
||||
{
|
||||
new: func(_ident=nil, _kind=0)
|
||||
{
|
||||
if(_ident==nil)
|
||||
_ident="none";
|
||||
|
||||
var new_class = emesary.Notification.new("TacticalNotification", _ident);
|
||||
|
||||
new_class.Kind = _kind;
|
||||
new_class.Position=geo.aircraft_position();
|
||||
new_class.IsDistinct = 0;
|
||||
|
||||
new_class.bridgeProperties = func
|
||||
{
|
||||
return
|
||||
[
|
||||
{
|
||||
getValue:func{return emesary.TransferCoord.encode(new_class.Position);},
|
||||
setValue:func(v){new_class.Position=emesary.TransferCoord.decode(v);},
|
||||
},
|
||||
{
|
||||
getValue:func{return emesary.TransferByte.encode(new_class.Kind);},
|
||||
setValue:func(v){new_class.Kind=emesary.TransferByte.decode(v);},
|
||||
},
|
||||
];
|
||||
};
|
||||
return new_class;
|
||||
},
|
||||
};
|
Loading…
Reference in a new issue