Nasal optimisation: Difference between revisions

Jump to navigation Jump to search
No edit summary
Line 86: Line 86:


The F-15 I think is the reference implementation of my three main Nasal optimisation techniques;  
The F-15 I think is the reference implementation of my three main Nasal optimisation techniques;  
== Emesary real time executive ==
The following code can be used to provide a basic and yet sophisticated way to run Nasal code in a scheduled (per frame or at a suitable rate) and in a managed way (i.e. something knows which modules are registered)
Each module that wish to be executes needs to implement itself as a receiver or have a receiver wrapper (as follows). Generally I prefer to use a receiver wrapper as it helps to isolate the code that does the work from the code that interfaces to the scheduler.
var ModuleRecipient =
{
    new: func(_ident)
    {
        var new_class = emesary.Recipient.new(_ident);
        new_class.Object = nil;
        new_class.Receive = func(notification)
        {
            if (notification.NotificationType == "FrameNotification")
            {
                if (new_class.Object == nil)
                  new_class.Object = ModuleObject.new();
                if (!math.mod(notifications.frameNotification.FrameCount,2)){
                    new_class.Object.update(notification);
                }
                return emesary.Transmitter.ReceiptStatus_OK;
            }
            return emesary.Transmitter.ReceiptStatus_NotProcessed;
        };
        return new_class;
    },
};
emesary.GlobalTransmitter.Register(ModuleRecipient.new("MODULE-NAME"));
</syntaxhighlight>
<syntaxhighlight lang="nasal">
#---------------------------------------------------------------------------
#
# Title                : Emesary based real time executive
#
# File Type            : Implementation File
#
# Description          : Uses emesary notifications to permit nasal subsystems to
#                      : be invoked in a controlled manner.
#
# Author              : Richard Harrison (richard@zaretto.com)
#
# Creation Date        : 4 June 2018
#
# Version              : 1.0
#
#  Copyright (C) 2018 Richard Harrison          Released under GPL V2
#
#---------------------------------------------------------------------------*/
# to add properties to the FrameNotification simply send a FrameNotificationAddProperty
# to the global transmitter. This will be received by the frameNotifcation object and
# included in the update.
#emesary.GlobalTransmitter.NotifyAll(notifications.FrameNotificationAddProperty.new("MODULE", "wow","gear/gear[0]/wow"));
#emesary.GlobalTransmitter.NotifyAll(notifications.FrameNotificationAddProperty.new("MODULE", "engine_n2", "engines/engine[0]/n2"));
#   
#
# real time exec loop.
var frame_inc = 0;
var cur_frame_inc = 0.03;
var rtExec_loop = func
{
    #   
    notifications.frameNotification.fetchvars();
    if (!notifications.frameNotification.running){
        return;
    }
    notifications.frameNotification.dT = notifications.frameNotification.elapsed_seconds - notifications.frameNotification.curT;
    if (notifications.frameNotification.dT > 1.0)
      notifications.frameNotification.curT = notifications.frameNotification.elapsed_seconds;
    if (notifications.frameNotification.FrameCount >= 16) {
        notifications.frameNotification.FrameCount = 0;
    }
    emesary.GlobalTransmitter.NotifyAll(notifications.frameNotification);
    #   
    notifications.frameNotification.FrameCount = notifications.frameNotification.FrameCount + 1;
    # adjust exec rate based on frame rate.
    if (notifications.frameNotification.frame_rate_worst < 5) {
        frame_inc = 0.25;#4 Hz
    } elsif (notifications.frameNotification.frame_rate_worst < 10) {
        frame_inc = 0.125;#8 Hz
    } elsif (notifications.frameNotification.frame_rate_worst < 15) {
        frame_inc = 0.10;#10 Hz
    } elsif (notifications.frameNotification.frame_rate_worst < 20) {
        frame_inc = 0.075;#13.3 Hz
    } elsif (notifications.frameNotification.frame_rate_worst < 25) {
        frame_inc = 0.05;#20 Hz
    } elsif (notifications.frameNotification.frame_rate_worst < 40) {
        frame_inc = 0.0333;#30 Hz
    } else {
        frame_inc = 0.02;#50 Hz
    }
    if (frame_inc != cur_frame_inc) {
        cur_frame_inc = frame_inc;
    }
    execTimer.restart(cur_frame_inc);
}
# setup the properties to monitor for this system
  input = {
          frame_rate                : "/sim/frame-rate",
          frame_rate_worst          : "/sim/frame-rate-worst",
          elapsed_seconds          : "/sim/time/elapsed-sec",
          };
foreach (var name; keys(input)) {
    emesary.GlobalTransmitter.NotifyAll(notifications.FrameNotificationAddProperty.new("EXEC", name, input[name]));
}
setlistener("sim/signals/fdm-initialized", func {
    notifications.frameNotification.running = 1;
});
notifications.frameNotification.running = 0;
notifications.frameNotification.dT = 0; # seconds
notifications.frameNotification.curT = 0;
var execTimer = maketimer(cur_frame_inc, rtExec_loop);
execTimer.simulatedTime = 1;
setlistener("/sim/signals/fdm-initialized", func {
    print("M_exec: starting");
    execTimer.start()
});
#
# Turn on the automatic overrun detection - this will notify on the console
# if any recipient takes more than the allocated (9ms) amount of time
emesary.GlobalTransmitter.OverrunDetection(9); # warn at 9ms
</syntaxhighlight>


== FrameNotification ==
== FrameNotification ==
Line 93: Line 236:
Use the FrameNotificationAddProperty to request that certain properties are contained within the FrameNotification.
Use the FrameNotificationAddProperty to request that certain properties are contained within the FrameNotification.


<syntaxhighlight lang="nasal">
notifications.FrameNotificationAddProperty.new("F15-HUD", **[HASH-Name]**, **[property-string]**)
notifications.FrameNotificationAddProperty.new("F15-HUD", **[HASH-Name]**, **[property-string]**)
</syntaxhighlight>


e.g.
e.g.
Line 179: Line 324:


------
------
== props.UpdateManager ==
== props.UpdateManager ==


308

edits

Navigation menu