diff --git a/Moose Development/Moose/Core/Base.lua b/Moose Development/Moose/Core/Base.lua index 1b809252a..ccb8c8755 100644 --- a/Moose Development/Moose/Core/Base.lua +++ b/Moose Development/Moose/Core/Base.lua @@ -1,28 +1,28 @@ --- **Core** - The base class within the framework. --- +-- -- === --- +-- -- ## Features: --- +-- -- * The construction and inheritance of MOOSE classes. -- * The class naming and numbering system. -- * The class hierarchy search system. --- * The tracing of information or objects during mission execution for debuggin purposes. +-- * The tracing of information or objects during mission execution for debugging purposes. -- * The subscription to DCS events for event handling in MOOSE objects. -- * Object inspection. --- +-- -- === --- +-- -- All classes within the MOOSE framework are derived from the BASE class. -- Note: The BASE class is an abstract class and is not meant to be used directly. --- +-- -- === --- +-- -- ### Author: **FlightControl** --- ### Contributions: --- +-- ### Contributions: +-- -- === --- +-- -- @module Core.Base -- @image Core_Base.JPG @@ -42,107 +42,107 @@ local _ClassID = 0 --- BASE class -- -- # 1. BASE constructor. --- --- Any class derived from BASE, will use the @{Core.Base#BASE.New} constructor embedded in the @{Core.Base#BASE.Inherit} method. +-- +-- Any class derived from BASE, will use the @{Core.Base#BASE.New} constructor embedded in the @{Core.Base#BASE.Inherit} method. -- See an example at the @{Core.Base#BASE.New} method how this is done. --- +-- -- # 2. Trace information for debugging. --- +-- -- The BASE class contains trace methods to trace progress within a mission execution of a certain object. --- These trace methods are inherited by each MOOSE class interiting BASE, soeach object created from derived class from BASE can use the tracing methods to trace its execution. --- +-- These trace methods are inherited by each MOOSE class inheriting BASE, thus all objects created from +-- a class derived from BASE can use the tracing methods to trace its execution. +-- -- Any type of information can be passed to these tracing methods. See the following examples: --- +-- -- self:E( "Hello" ) --- +-- -- Result in the word "Hello" in the dcs.log. --- +-- -- local Array = { 1, nil, "h", { "a","b" }, "x" } -- self:E( Array ) --- --- Results with the text [1]=1,[3]="h",[4]={[1]="a",[2]="b"},[5]="x"} in the dcs.log. --- +-- +-- Results with the text [1]=1,[3]="h",[4]={[1]="a",[2]="b"},[5]="x"} in the dcs.log. +-- -- local Object1 = "Object1" -- local Object2 = 3 -- local Object3 = { Object 1, Object 2 } -- self:E( { Object1, Object2, Object3 } ) --- +-- -- Results with the text [1]={[1]="Object",[2]=3,[3]={[1]="Object",[2]=3}} in the dcs.log. --- +-- -- local SpawnObject = SPAWN:New( "Plane" ) -- local GroupObject = GROUP:FindByName( "Group" ) -- self:E( { Spawn = SpawnObject, Group = GroupObject } ) --- --- Results with the text [1]={Spawn={....),Group={...}} in the dcs.log. --- +-- +-- Results with the text [1]={Spawn={....),Group={...}} in the dcs.log. +-- -- Below a more detailed explanation of the different method types for tracing. --- +-- -- ## 2.1. Tracing methods categories. -- -- There are basically 3 types of tracing methods available: --- +-- -- * @{#BASE.F}: Used to trace the entrance of a function and its given parameters. An F is indicated at column 44 in the DCS.log file. -- * @{#BASE.T}: Used to trace further logic within a function giving optional variables or parameters. A T is indicated at column 44 in the DCS.log file. -- * @{#BASE.E}: Used to always trace information giving optional variables or parameters. An E is indicated at column 44 in the DCS.log file. --- +-- -- ## 2.2 Tracing levels. -- --- There are 3 tracing levels within MOOSE. +-- There are 3 tracing levels within MOOSE. -- These tracing levels were defined to avoid bulks of tracing to be generated by lots of objects. --- +-- -- As such, the F and T methods have additional variants to trace level 2 and 3 respectively: -- -- * @{#BASE.F2}: Trace the beginning of a function and its given parameters with tracing level 2. -- * @{#BASE.F3}: Trace the beginning of a function and its given parameters with tracing level 3. -- * @{#BASE.T2}: Trace further logic within a function giving optional variables or parameters with tracing level 2. -- * @{#BASE.T3}: Trace further logic within a function giving optional variables or parameters with tracing level 3. --- +-- -- ## 2.3. Trace activation. --- +-- -- Tracing can be activated in several ways: --- +-- -- * Switch tracing on or off through the @{#BASE.TraceOnOff}() method. -- * Activate all tracing through the @{#BASE.TraceAll}() method. -- * Activate only the tracing of a certain class (name) through the @{#BASE.TraceClass}() method. -- * Activate only the tracing of a certain method of a certain class through the @{#BASE.TraceClassMethod}() method. -- * Activate only the tracing of a certain level through the @{#BASE.TraceLevel}() method. --- +-- -- ## 2.4. Check if tracing is on. --- +-- -- The method @{#BASE.IsTrace}() will validate if tracing is activated or not. --- --- +-- -- # 3. DCS simulator Event Handling. --- --- The BASE class provides methods to catch DCS Events. These are events that are triggered from within the DCS simulator, +-- +-- The BASE class provides methods to catch DCS Events. These are events that are triggered from within the DCS simulator, -- and handled through lua scripting. MOOSE provides an encapsulation to handle these events more efficiently. --- +-- -- ## 3.1. Subscribe / Unsubscribe to DCS Events. --- +-- -- At first, the mission designer will need to **Subscribe** to a specific DCS event for the class. -- So, when the DCS event occurs, the class will be notified of that event. -- There are two methods which you use to subscribe to or unsubscribe from an event. --- +-- -- * @{#BASE.HandleEvent}(): Subscribe to a DCS Event. -- * @{#BASE.UnHandleEvent}(): Unsubscribe from a DCS Event. --- +-- -- ## 3.2. Event Handling of DCS Events. --- +-- -- Once the class is subscribed to the event, an **Event Handling** method on the object or class needs to be written that will be called -- when the DCS event occurs. The Event Handling method receives an @{Core.Event#EVENTDATA} structure, which contains a lot of information -- about the event that occurred. --- --- Find below an example of the prototype how to write an event handling function for two units: +-- +-- Find below an example of the prototype how to write an event handling function for two units: -- -- local Tank1 = UNIT:FindByName( "Tank A" ) -- local Tank2 = UNIT:FindByName( "Tank B" ) --- +-- -- -- Here we subscribe to the Dead events. So, if one of these tanks dies, the Tank1 or Tank2 objects will be notified. -- Tank1:HandleEvent( EVENTS.Dead ) -- Tank2:HandleEvent( EVENTS.Dead ) --- +-- -- --- This function is an Event Handling function that will be called when Tank1 is Dead. --- -- @param Wrapper.Unit#UNIT self +-- -- @param Wrapper.Unit#UNIT self -- -- @param Core.Event#EVENTDATA EventData -- function Tank1:OnEventDead( EventData ) -- @@ -150,49 +150,47 @@ local _ClassID = 0 -- end -- -- --- This function is an Event Handling function that will be called when Tank2 is Dead. --- -- @param Wrapper.Unit#UNIT self +-- -- @param Wrapper.Unit#UNIT self -- -- @param Core.Event#EVENTDATA EventData -- function Tank2:OnEventDead( EventData ) -- -- self:SmokeBlue() -- end --- --- --- +-- -- See the @{Event} module for more information about event handling. --- +-- -- # 4. Class identification methods. --- +-- -- BASE provides methods to get more information of each object: --- +-- -- * @{#BASE.GetClassID}(): Gets the ID (number) of the object. Each object created is assigned a number, that is incremented by one. -- * @{#BASE.GetClassName}(): Gets the name of the object, which is the name of the class the object was instantiated from. -- * @{#BASE.GetClassNameAndID}(): Gets the name and ID of the object. --- +-- -- # 5. All objects derived from BASE can have "States". --- --- A mechanism is in place in MOOSE, that allows to let the objects administer **states**. --- States are essentially properties of objects, which are identified by a **Key** and a **Value**. --- --- The method @{#BASE.SetState}() can be used to set a Value with a reference Key to the object. --- To **read or retrieve** a state Value based on a Key, use the @{#BASE.GetState} method. --- +-- +-- A mechanism is in place in MOOSE, that allows to let the objects administer **states**. +-- States are essentially properties of objects, which are identified by a **Key** and a **Value**. +-- +-- The method @{#BASE.SetState}() can be used to set a Value with a reference Key to the object. +-- To **read or retrieve** a state Value based on a Key, use the @{#BASE.GetState} method. +-- -- These two methods provide a very handy way to keep state at long lasting processes. -- Values can be stored within the objects, and later retrieved or changed when needed. -- There is one other important thing to note, the @{#BASE.SetState}() and @{#BASE.GetState} methods -- receive as the **first parameter the object for which the state needs to be set**. -- Thus, if the state is to be set for the same object as the object for which the method is used, then provide the same -- object name to the method. --- +-- -- # 6. Inheritance. --- +-- -- The following methods are available to implement inheritance --- +-- -- * @{#BASE.Inherit}: Inherits from a class. -- * @{#BASE.GetParent}: Returns the parent object from the object it is handling, or nil if there is no parent object. --- +-- -- === --- +-- -- @field #BASE BASE = { ClassName = "BASE", @@ -203,13 +201,12 @@ BASE = { Scheduler = nil, } - --- @field #BASE.__ BASE.__ = {} --- @field #BASE._ BASE._ = { - Schedules = {} --- Contains the Schedulers Active + Schedules = {}, --- Contains the Schedulers Active } --- The Formation Class @@ -217,35 +214,33 @@ BASE._ = { -- @field Cone A cone formation. FORMATION = { Cone = "Cone", - Vee = "Vee" + Vee = "Vee", } - - ---- BASE constructor. --- +--- BASE constructor. +-- -- This is an example how to use the BASE:New() constructor in a new class definition when inheriting from BASE. --- +-- -- function EVENT:New() -- local self = BASE:Inherit( self, BASE:New() ) -- #EVENT -- return self -- end --- +-- -- @param #BASE self -- @return #BASE function BASE:New() local self = routines.utils.deepCopy( self ) -- Create a new self instance - _ClassID = _ClassID + 1 - self.ClassID = _ClassID - - -- This is for "private" methods... - -- When a __ is passed to a method as "self", the __index will search for the method on the public method list too! --- if rawget( self, "__" ) then - --setmetatable( self, { __index = self.__ } ) --- end - - return self + _ClassID = _ClassID + 1 + self.ClassID = _ClassID + + -- This is for "private" methods... + -- When a __ is passed to a method as "self", the __index will search for the method on the public method list too! + -- if rawget( self, "__" ) then + -- setmetatable( self, { __index = self.__ } ) + -- end + + return self end --- This is the worker method to inherit from a parent class. @@ -256,29 +251,28 @@ end function BASE:Inherit( Child, Parent ) -- Create child. - local Child = routines.utils.deepCopy( Child ) + local Child = routines.utils.deepCopy( Child ) - if Child ~= nil then + if Child ~= nil then - -- This is for "private" methods... - -- When a __ is passed to a method as "self", the __index will search for the method on the public method list of the same object too! + -- This is for "private" methods... + -- When a __ is passed to a method as "self", the __index will search for the method on the public method list of the same object too! if rawget( Child, "__" ) then - setmetatable( Child, { __index = Child.__ } ) + setmetatable( Child, { __index = Child.__ } ) setmetatable( Child.__, { __index = Parent } ) else setmetatable( Child, { __index = Parent } ) end - - --Child:_SetDestructor() - end - - return Child -end + -- Child:_SetDestructor() + end + + return Child +end local function getParent( Child ) local Parent = nil - + if Child.ClassName == 'BASE' then Parent = nil else @@ -286,46 +280,44 @@ local function getParent( Child ) Parent = getmetatable( Child.__ ).__index else Parent = getmetatable( Child ).__index - end + end end return Parent end - ---- This is the worker method to retrieve the Parent class. +--- This is the worker method to retrieve the Parent class. -- Note that the Parent class must be passed to call the parent class method. --- +-- -- self:GetParent(self):ParentMethod() --- --- +-- +-- -- @param #BASE self -- @param #BASE Child This is the Child class from which the Parent class needs to be retrieved. -- @param #BASE FromClass (Optional) The class from which to get the parent. -- @return #BASE function BASE:GetParent( Child, FromClass ) - local Parent -- BASE class has no parent if Child.ClassName == 'BASE' then Parent = nil else - - --self:E({FromClass = FromClass}) - --self:E({Child = Child.ClassName}) + + -- self:E({FromClass = FromClass}) + -- self:E({Child = Child.ClassName}) if FromClass then - while( Child.ClassName ~= "BASE" and Child.ClassName ~= FromClass.ClassName ) do + while (Child.ClassName ~= "BASE" and Child.ClassName ~= FromClass.ClassName) do Child = getParent( Child ) - --self:E({Child.ClassName}) + -- self:E({Child.ClassName}) end - end + end if Child.ClassName == 'BASE' then Parent = nil else Parent = getParent( Child ) end end - --self:E({Parent.ClassName}) + -- self:E({Parent.ClassName}) return Parent end @@ -339,7 +331,7 @@ end -- * ZONE:New( 'some zone' ):IsInstanceOf( 'BASE' ) will return true -- -- * ZONE:New( 'some zone' ):IsInstanceOf( 'GROUP' ) will return false --- +-- -- @param #BASE self -- @param ClassName is the name of the class or the class itself to run the check against -- @return #boolean @@ -347,32 +339,32 @@ function BASE:IsInstanceOf( ClassName ) -- Is className NOT a string ? if type( ClassName ) ~= 'string' then - + -- Is className a Moose class ? if type( ClassName ) == 'table' and ClassName.ClassName ~= nil then - + -- Get the name of the Moose class as a string ClassName = ClassName.ClassName - - -- className is neither a string nor a Moose class, throw an error + + -- className is neither a string nor a Moose class, throw an error else - + -- I'm not sure if this should take advantage of MOOSE logging function, or throw an error for pcall - local err_str = 'className parameter should be a string; parameter received: '..type( ClassName ) + local err_str = 'className parameter should be a string; parameter received: ' .. type( ClassName ) self:E( err_str ) -- error( err_str ) return false - + end end - + ClassName = string.upper( ClassName ) if string.upper( self.ClassName ) == ClassName then return true end - local Parent = getParent(self) + local Parent = getParent( self ) while Parent do @@ -388,7 +380,7 @@ function BASE:IsInstanceOf( ClassName ) end --- Get the ClassName + ClassID of the class instance. --- The ClassName + ClassID is formatted as '%s#%09d'. +-- The ClassName + ClassID is formatted as '%s#%09d'. -- @param #BASE self -- @return #string The ClassName + ClassID of the class instance. function BASE:GetClassNameAndID() @@ -415,22 +407,21 @@ do -- Event Handling -- @param #BASE self -- @return Core.Event#EVENT function BASE:EventDispatcher() - + return _EVENTDISPATCHER end - - + --- Get the Class @{Event} processing Priority. - -- The Event processing Priority is a number from 1 to 10, + -- The Event processing Priority is a number from 1 to 10, -- reflecting the order of the classes subscribed to the Event to be processed. -- @param #BASE self -- @return #number The @{Event} processing Priority. function BASE:GetEventPriority() return self._.EventPriority or 5 end - + --- Set the Class @{Event} processing Priority. - -- The Event processing Priority is a number from 1 to 10, + -- The Event processing Priority is a number from 1 to 10, -- reflecting the order of the classes subscribed to the Event to be processed. -- @param #BASE self -- @param #number EventPriority The @{Event} processing Priority. @@ -438,240 +429,239 @@ do -- Event Handling function BASE:SetEventPriority( EventPriority ) self._.EventPriority = EventPriority end - + --- Remove all subscribed events -- @param #BASE self -- @return #BASE function BASE:EventRemoveAll() - + self:EventDispatcher():RemoveAll( self ) - + return self end - + --- Subscribe to a DCS Event. -- @param #BASE self -- @param Core.Event#EVENTS EventID Event ID. -- @param #function EventFunction (optional) The function to be called when the event occurs for the unit. -- @return #BASE function BASE:HandleEvent( EventID, EventFunction ) - + self:EventDispatcher():OnEventGeneric( EventFunction, self, EventID ) - + return self end - + --- UnSubscribe to a DCS event. -- @param #BASE self -- @param Core.Event#EVENTS EventID Event ID. -- @return #BASE function BASE:UnHandleEvent( EventID ) - + self:EventDispatcher():RemoveEvent( self, EventID ) - + return self end - + -- Event handling function prototypes - - --- Occurs whenever any unit in a mission fires a weapon. But not any machine gun or autocannon based weapon, those are handled by EVENT.ShootingStart. + + --- Occurs whenever any unit in a mission fires a weapon. But not any machine gun or auto cannon based weapon, those are handled by EVENT.ShootingStart. -- @function [parent=#BASE] OnEventShot -- @param #BASE self -- @param Core.Event#EVENTDATA EventData The EventData structure. --- Occurs whenever an object is hit by a weapon. - -- initiator : The unit object the fired the weapon - -- weapon: Weapon object that hit the target - -- target: The Object that was hit. + -- initiator : The unit object the fired the weapon. + -- weapon: Weapon object that hit the target. + -- target: The Object that was hit. -- @function [parent=#BASE] OnEventHit -- @param #BASE self -- @param Core.Event#EVENTDATA EventData The EventData structure. --- Occurs when an aircraft takes off from an airbase, farp, or ship. - -- initiator : The unit that tookoff - -- place: Object from where the AI took-off from. Can be an Airbase Object, FARP, or Ships + -- initiator : The unit that took off. + -- place: Object from where the AI took-off from. Can be an Airbase Object, FARP, or Ships. -- @function [parent=#BASE] OnEventTakeoff -- @param #BASE self -- @param Core.Event#EVENTDATA EventData The EventData structure. --- Occurs when an aircraft lands at an airbase, farp or ship - -- initiator : The unit that has landed - -- place: Object that the unit landed on. Can be an Airbase Object, FARP, or Ships + -- initiator : The unit that has landed. + -- place: Object that the unit landed on. Can be an Airbase Object, FARP, or Ships. -- @function [parent=#BASE] OnEventLand -- @param #BASE self -- @param Core.Event#EVENTDATA EventData The EventData structure. --- Occurs when any aircraft crashes into the ground and is completely destroyed. - -- initiator : The unit that has crashed + -- initiator : The unit that has crashed. -- @function [parent=#BASE] OnEventCrash -- @param #BASE self -- @param Core.Event#EVENTDATA EventData The EventData structure. --- Occurs when a pilot ejects from an aircraft - -- initiator : The unit that has ejected + -- initiator : The unit that has ejected -- @function [parent=#BASE] OnEventEjection -- @param #BASE self -- @param Core.Event#EVENTDATA EventData The EventData structure. --- Occurs when an aircraft connects with a tanker and begins taking on fuel. - -- initiator : The unit that is receiving fuel. + -- initiator : The unit that is receiving fuel. -- @function [parent=#BASE] OnEventRefueling -- @param #BASE self -- @param Core.Event#EVENTDATA EventData The EventData structure. --- Occurs when an object is dead. - -- initiator : The unit that is dead. + -- initiator : The unit that is dead. -- @function [parent=#BASE] OnEventDead -- @param #BASE self -- @param Core.Event#EVENTDATA EventData The EventData structure. --- Occurs when an object is completely destroyed. - -- initiator : The unit that is was destroyed. + -- initiator : The unit that is was destroyed. -- @function [parent=#BASE] OnEvent -- @param #BASE self -- @param Core.Event#EVENTDATA EventData The EventData structure. --- Occurs when the pilot of an aircraft is killed. Can occur either if the player is alive and crashes or if a weapon kills the pilot without completely destroying the plane. - -- initiator : The unit that the pilot has died in. + -- initiator : The unit that the pilot has died in. -- @function [parent=#BASE] OnEventPilotDead -- @param #BASE self -- @param Core.Event#EVENTDATA EventData The EventData structure. --- Occurs when a ground unit captures either an airbase or a farp. - -- initiator : The unit that captured the base - -- place: The airbase that was captured, can be a FARP or Airbase. When calling place:getCoalition() the faction will already be the new owning faction. + -- initiator : The unit that captured the base. + -- place: The airbase that was captured, can be a FARP or Airbase. When calling place:getCoalition() the faction will already be the new owning faction. -- @function [parent=#BASE] OnEventBaseCaptured -- @param #BASE self -- @param Core.Event#EVENTDATA EventData The EventData structure. - --- Occurs when a mission starts + --- Occurs when a mission starts. -- @function [parent=#BASE] OnEventMissionStart -- @param #BASE self -- @param Core.Event#EVENTDATA EventData The EventData structure. - --- Occurs when a mission ends + --- Occurs when a mission ends. -- @function [parent=#BASE] OnEventMissionEnd -- @param #BASE self -- @param Core.Event#EVENTDATA EventData The EventData structure. --- Occurs when an aircraft is finished taking fuel. - -- initiator : The unit that was receiving fuel. + -- initiator : The unit that was receiving fuel. -- @function [parent=#BASE] OnEventRefuelingStop -- @param #BASE self -- @param Core.Event#EVENTDATA EventData The EventData structure. --- Occurs when any object is spawned into the mission. - -- initiator : The unit that was spawned + -- initiator : The unit that was spawned. -- @function [parent=#BASE] OnEventBirth -- @param #BASE self -- @param Core.Event#EVENTDATA EventData The EventData structure. --- Occurs when any system fails on a human controlled aircraft. - -- initiator : The unit that had the failure + -- initiator : The unit that had the failure. -- @function [parent=#BASE] OnEventHumanFailure -- @param #BASE self -- @param Core.Event#EVENTDATA EventData The EventData structure. --- Occurs when any aircraft starts its engines. - -- initiator : The unit that is starting its engines. + -- initiator : The unit that is starting its engines.. -- @function [parent=#BASE] OnEventEngineStartup -- @param #BASE self -- @param Core.Event#EVENTDATA EventData The EventData structure. --- Occurs when any aircraft shuts down its engines. - -- initiator : The unit that is stopping its engines. + -- initiator : The unit that is stopping its engines.. -- @function [parent=#BASE] OnEventEngineShutdown -- @param #BASE self -- @param Core.Event#EVENTDATA EventData The EventData structure. --- Occurs when any player assumes direct control of a unit. - -- initiator : The unit that is being taken control of. + -- initiator : The unit that is being taken control of. -- @function [parent=#BASE] OnEventPlayerEnterUnit -- @param #BASE self -- @param Core.Event#EVENTDATA EventData The EventData structure. --- Occurs when any player relieves control of a unit to the AI. - -- initiator : The unit that the player left. + -- initiator : The unit that the player left. -- @function [parent=#BASE] OnEventPlayerLeaveUnit -- @param #BASE self -- @param Core.Event#EVENTDATA EventData The EventData structure. - --- Occurs when any unit begins firing a weapon that has a high rate of fire. Most common with aircraft cannons (GAU-8), autocannons, and machine guns. + --- Occurs when any unit begins firing a weapon that has a high rate of fire. Most common with aircraft cannons (GAU-8), auto cannons, and machine guns. -- initiator : The unit that is doing the shooting. - -- target: The unit that is being targeted. + -- target: The unit that is being targeted. -- @function [parent=#BASE] OnEventShootingStart -- @param #BASE self -- @param Core.Event#EVENTDATA EventData The EventData structure. --- Occurs when any unit stops firing its weapon. Event will always correspond with a shooting start event. - -- initiator : The unit that was doing the shooting. + -- initiator : The unit that was doing the shooting. -- @function [parent=#BASE] OnEventShootingEnd -- @param #BASE self -- @param Core.Event#EVENTDATA EventData The EventData structure. --- Occurs when a new mark was added. - -- MarkID: ID of the mark. + -- MarkID: ID of the mark. -- @function [parent=#BASE] OnEventMarkAdded -- @param #BASE self -- @param Core.Event#EVENTDATA EventData The EventData structure. --- Occurs when a mark was removed. - -- MarkID: ID of the mark. + -- MarkID: ID of the mark. -- @function [parent=#BASE] OnEventMarkRemoved -- @param #BASE self -- @param Core.Event#EVENTDATA EventData The EventData structure. --- Occurs when a mark text was changed. - -- MarkID: ID of the mark. + -- MarkID: ID of the mark. -- @function [parent=#BASE] OnEventMarkChange -- @param #BASE self -- @param Core.Event#EVENTDATA EventData The EventData structure. - --- Unknown precisely what creates this event, likely tied into newer damage model. Will update this page when new information become available. - -- + -- -- * initiator: The unit that had the failure. - -- + -- -- @function [parent=#BASE] OnEventDetailedFailure -- @param #BASE self -- @param Core.Event#EVENTDATA EventData The EventData structure. - --- Occurs when any modification to the "Score" as seen on the debrief menu would occur. + --- Occurs when any modification to the "Score" as seen on the debrief menu would occur. -- There is no information on what values the score was changed to. Event is likely similar to player_comment in this regard. -- @function [parent=#BASE] OnEventScore -- @param #BASE self -- @param Core.Event#EVENTDATA EventData The EventData structure. --- Occurs on the death of a unit. Contains more and different information. Similar to unit_lost it will occur for aircraft before the aircraft crash event occurs. - -- - -- * initiator: The unit that killed the target + -- + -- * initiator: The unit that killed the target. -- * target: Target Object -- * weapon: Weapon Object - -- + -- -- @function [parent=#BASE] OnEventKill -- @param #BASE self -- @param Core.Event#EVENTDATA EventData The EventData structure. - --- Occurs when any modification to the "Score" as seen on the debrief menu would occur. + --- Occurs when any modification to the "Score" as seen on the debrief menu would occur. -- There is no information on what values the score was changed to. Event is likely similar to player_comment in this regard. -- @function [parent=#BASE] OnEventScore -- @param #BASE self -- @param Core.Event#EVENTDATA EventData The EventData structure. --- Occurs when the game thinks an object is destroyed. - -- + -- -- * initiator: The unit that is was destroyed. - -- + -- -- @function [parent=#BASE] OnEventUnitLost -- @param #BASE self -- @param Core.Event#EVENTDATA EventData The EventData structure. --- Occurs shortly after the landing animation of an ejected pilot touching the ground and standing up. Event does not occur if the pilot lands in the water and sub combs to Davey Jones Locker. - -- + -- -- * initiator: Static object representing the ejected pilot. Place : Aircraft that the pilot ejected from. -- * place: may not return as a valid object if the aircraft has crashed into the ground and no longer exists. -- * subplace: is always 0 for unknown reasons. - -- + -- -- @function [parent=#BASE] OnEventLandingAfterEjection -- @param #BASE self -- @param Core.Event#EVENTDATA EventData The EventData structure. @@ -696,7 +686,7 @@ do -- Event Handling -- @param #BASE self -- @param Core.Event#EVENTDATA EventData The EventData structure. - --- Landing quality mark. + --- Landing quality mark. -- @function [parent=#BASE] OnEventLandingQualityMark -- @param #BASE self -- @param Core.Event#EVENTDATA EventData The EventData structure. @@ -706,16 +696,14 @@ do -- Event Handling -- @param #BASE self -- @param Core.Event#EVENTDATA EventData The EventData structure. - --- Occurs when a player enters a slot and takes control of an aircraft. - -- **NOTE**: This is a workaround of a long standing DCS bug with the PLAYER_ENTER_UNIT event. - -- initiator : The unit that is being taken control of. + -- **NOTE**: This is a workaround of a long standing DCS bug with the PLAYER_ENTER_UNIT event. + -- initiator : The unit that is being taken control of. -- @function [parent=#BASE] OnEventPlayerEnterAircraft -- @param #BASE self -- @param Core.Event#EVENTDATA EventData The EventData structure. end - --- Creation of a Birth Event. -- @param #BASE self @@ -725,18 +713,18 @@ end -- @param place -- @param subplace function BASE:CreateEventBirth( EventTime, Initiator, IniUnitName, place, subplace ) - self:F( { EventTime, Initiator, IniUnitName, place, subplace } ) + self:F( { EventTime, Initiator, IniUnitName, place, subplace } ) - local Event = { - id = world.event.S_EVENT_BIRTH, - time = EventTime, - initiator = Initiator, - IniUnitName = IniUnitName, - place = place, - subplace = subplace - } + local Event = { + id = world.event.S_EVENT_BIRTH, + time = EventTime, + initiator = Initiator, + IniUnitName = IniUnitName, + place = place, + subplace = subplace, + } - world.onEvent( Event ) + world.onEvent( Event ) end --- Creation of a Crash Event. @@ -744,15 +732,15 @@ end -- @param DCS#Time EventTime The time stamp of the event. -- @param DCS#Object Initiator The initiating object of the event. function BASE:CreateEventCrash( EventTime, Initiator ) - self:F( { EventTime, Initiator } ) + self:F( { EventTime, Initiator } ) - local Event = { - id = world.event.S_EVENT_CRASH, - time = EventTime, - initiator = Initiator, - } + local Event = { + id = world.event.S_EVENT_CRASH, + time = EventTime, + initiator = Initiator, + } - world.onEvent( Event ) + world.onEvent( Event ) end --- Creation of a Dead Event. @@ -766,7 +754,7 @@ function BASE:CreateEventDead( EventTime, Initiator ) id = world.event.S_EVENT_DEAD, time = EventTime, initiator = Initiator, - } + } world.onEvent( Event ) end @@ -782,7 +770,7 @@ function BASE:CreateEventRemoveUnit( EventTime, Initiator ) id = EVENTS.RemoveUnit, time = EventTime, initiator = Initiator, - } + } world.onEvent( Event ) end @@ -798,56 +786,56 @@ function BASE:CreateEventTakeoff( EventTime, Initiator ) id = world.event.S_EVENT_TAKEOFF, time = EventTime, initiator = Initiator, - } + } world.onEvent( Event ) end - --- Creation of a `S_EVENT_PLAYER_ENTER_AIRCRAFT` event. - -- @param #BASE self - -- @param Wrapper.Unit#UNIT PlayerUnit The aircraft unit the player entered. - function BASE:CreateEventPlayerEnterAircraft( PlayerUnit ) - self:F( { PlayerUnit } ) - - local Event = { - id = EVENTS.PlayerEnterAircraft, - time = timer.getTime(), - initiator = PlayerUnit:GetDCSObject() - } - - world.onEvent(Event) - end +--- Creation of a `S_EVENT_PLAYER_ENTER_AIRCRAFT` event. +-- @param #BASE self +-- @param Wrapper.Unit#UNIT PlayerUnit The aircraft unit the player entered. +function BASE:CreateEventPlayerEnterAircraft( PlayerUnit ) + self:F( { PlayerUnit } ) --- TODO: Complete DCS#Event structure. + local Event = { + id = EVENTS.PlayerEnterAircraft, + time = timer.getTime(), + initiator = PlayerUnit:GetDCSObject(), + } + + world.onEvent( Event ) +end + +-- TODO: Complete DCS#Event structure. --- The main event handling function... This function captures all events generated for the class. -- @param #BASE self -- @param DCS#Event event -function BASE:onEvent(event) +function BASE:onEvent( event ) - if self then - - for EventID, EventObject in pairs(self.Events) do - if EventObject.EventEnabled then + if self then - if event.id == EventObject.Event then + for EventID, EventObject in pairs( self.Events ) do + if EventObject.EventEnabled then - if self == EventObject.Self then - - if event.initiator and event.initiator:isExist() then - event.IniUnitName = event.initiator:getName() - end - - if event.target and event.target:isExist() then - event.TgtUnitName = event.target:getName() - end - - end - - end - - end - end - end + if event.id == EventObject.Event then + + if self == EventObject.Self then + + if event.initiator and event.initiator:isExist() then + event.IniUnitName = event.initiator:getName() + end + + if event.target and event.target:isExist() then + event.TgtUnitName = event.target:getName() + end + + end + + end + + end + end + end end do -- Scheduling @@ -861,28 +849,28 @@ do -- Scheduling function BASE:ScheduleOnce( Start, SchedulerFunction, ... ) self:F2( { Start } ) self:T3( { ... } ) - + local ObjectName = "-" ObjectName = self.ClassName .. self.ClassID - - self:F3( { "ScheduleOnce: ", ObjectName, Start } ) - + + self:F3( { "ScheduleOnce: ", ObjectName, Start } ) + if not self.Scheduler then self.Scheduler = SCHEDULER:New( self ) end - - local ScheduleID = _SCHEDULEDISPATCHER:AddSchedule( - self, - SchedulerFunction, - { ... }, - Start, - nil, - nil, - nil - ) - - self._.Schedules[#self._.Schedules+1] = ScheduleID - + + local ScheduleID = _SCHEDULEDISPATCHER:AddSchedule( + self, + SchedulerFunction, + { ... }, + Start, + nil, + nil, + nil + ) + + self._.Schedules[#self._.Schedules + 1] = ScheduleID + return self._.Schedules[#self._.Schedules] end @@ -898,29 +886,29 @@ do -- Scheduling function BASE:ScheduleRepeat( Start, Repeat, RandomizeFactor, Stop, SchedulerFunction, ... ) self:F2( { Start } ) self:T3( { ... } ) - + local ObjectName = "-" ObjectName = self.ClassName .. self.ClassID - + self:F3( { "ScheduleRepeat: ", ObjectName, Start, Repeat, RandomizeFactor, Stop } ) if not self.Scheduler then self.Scheduler = SCHEDULER:New( self ) end - - local ScheduleID = self.Scheduler:Schedule( - self, - SchedulerFunction, - { ... }, - Start, - Repeat, - RandomizeFactor, - Stop, - 4 - ) - - self._.Schedules[#self._.Schedules+1] = ScheduleID - + + local ScheduleID = self.Scheduler:Schedule( + self, + SchedulerFunction, + { ... }, + Start, + Repeat, + RandomizeFactor, + Stop, + 4 + ) + + self._.Schedules[#self._.Schedules + 1] = ScheduleID + return self._.Schedules[#self._.Schedules] end @@ -928,9 +916,9 @@ do -- Scheduling -- @param #BASE self -- @param #function SchedulerFunction The event function to be called when a timer event occurs. The event function needs to accept the parameters specified in SchedulerArguments. function BASE:ScheduleStop( SchedulerFunction ) - + self:F3( { "ScheduleStop:" } ) - + if self.Scheduler then _SCHEDULEDISPATCHER:Stop( self.Scheduler, self._.Schedules[SchedulerFunction] ) end @@ -938,9 +926,8 @@ do -- Scheduling end - --- Set a state or property of the Object given a Key and a Value. --- Note that if the Object is destroyed, nillified or garbage collected, then the Values and Keys will also be gone. +-- Note that if the Object is destroyed, set to nil, or garbage collected, then the Values and Keys will also be gone. -- @param #BASE self -- @param Object The object that will hold the Value set by the Key. -- @param Key The key that is used as a reference of the value. Note that the key can be a #string, but it can also be any other type! @@ -952,13 +939,12 @@ function BASE:SetState( Object, Key, Value ) self.States[ClassNameAndID] = self.States[ClassNameAndID] or {} self.States[ClassNameAndID][Key] = Value - + return self.States[ClassNameAndID][Key] end - --- Get a Value given a Key from the Object. --- Note that if the Object is destroyed, nillified or garbage collected, then the Values and Keys will also be gone. +-- Note that if the Object is destroyed, set to nil, or garbage collected, then the Values and Keys will also be gone. -- @param #BASE self -- @param Object The object that holds the Value set by the Key. -- @param Key The key that is used to retrieve the value. Note that the key can be a #string, but it can also be any other type! @@ -971,7 +957,7 @@ function BASE:GetState( Object, Key ) local Value = self.States[ClassNameAndID][Key] or false return Value end - + return nil end @@ -1010,8 +996,6 @@ function BASE:TraceOff() self:TraceOnOff( false ) end - - --- Set trace on or off -- Note that when trace is off, no BASE.Debug statement is performed, increasing performance! -- When Moose is loaded statically, (as one file), tracing is switched off by default. @@ -1020,28 +1004,29 @@ end -- @param #BASE self -- @param #boolean TraceOnOff Switch the tracing on or off. -- @usage --- -- Switch the tracing On --- BASE:TraceOnOff( true ) --- --- -- Switch the tracing Off --- BASE:TraceOnOff( false ) +-- +-- -- Switch the tracing On +-- BASE:TraceOnOff( true ) +-- +-- -- Switch the tracing Off +-- BASE:TraceOnOff( false ) +-- function BASE:TraceOnOff( TraceOnOff ) - if TraceOnOff==false then + if TraceOnOff == false then self:I( "Tracing in MOOSE is OFF" ) _TraceOnOff = false else - self:I( "Tracing in MOOSE is ON" ) + self:I( "Tracing in MOOSE is ON" ) _TraceOnOff = true end end - --- Enquires if tracing is on (for the class). -- @param #BASE self -- @return #boolean function BASE:IsTrace() - if BASE.Debug and ( _TraceAll == true ) or ( _TraceClass[self.ClassName] or _TraceClassMethod[self.ClassName] ) then + if BASE.Debug and (_TraceAll == true) or (_TraceClass[self.ClassName] or _TraceClassMethod[self.ClassName]) then return true else return false @@ -1060,13 +1045,13 @@ end -- @param #BASE self -- @param #boolean TraceAll true = trace all methods in MOOSE. function BASE:TraceAll( TraceAll ) - - if TraceAll==false then - _TraceAll=false + + if TraceAll == false then + _TraceAll = false else _TraceAll = true end - + if _TraceAll then self:I( "Tracing all methods in MOOSE " ) else @@ -1101,16 +1086,16 @@ end -- @param Arguments A #table or any field. function BASE:_F( Arguments, DebugInfoCurrentParam, DebugInfoFromParam ) - if BASE.Debug and ( _TraceAll == true ) or ( _TraceClass[self.ClassName] or _TraceClassMethod[self.ClassName] ) then + if BASE.Debug and (_TraceAll == true) or (_TraceClass[self.ClassName] or _TraceClassMethod[self.ClassName]) then local DebugInfoCurrent = DebugInfoCurrentParam and DebugInfoCurrentParam or BASE.Debug.getinfo( 2, "nl" ) local DebugInfoFrom = DebugInfoFromParam and DebugInfoFromParam or BASE.Debug.getinfo( 3, "l" ) - + local Function = "function" if DebugInfoCurrent.name then Function = DebugInfoCurrent.name end - + if _TraceAll == true or _TraceClass[self.ClassName] or _TraceClassMethod[self.ClassName].Method[Function] then local LineCurrent = 0 if DebugInfoCurrent.currentline then @@ -1120,7 +1105,7 @@ function BASE:_F( Arguments, DebugInfoCurrentParam, DebugInfoFromParam ) if DebugInfoFrom then LineFrom = DebugInfoFrom.currentline end - env.info( string.format( "%6d(%6d)/%1s:%30s%05d.%s(%s)" , LineCurrent, LineFrom, "F", self.ClassName, self.ClassID, Function, routines.utils.oneLineSerialize( Arguments ) ) ) + env.info( string.format( "%6d(%6d)/%1s:%30s%05d.%s(%s)", LineCurrent, LineFrom, "F", self.ClassName, self.ClassID, Function, routines.utils.oneLineSerialize( Arguments ) ) ) end end end @@ -1133,14 +1118,13 @@ function BASE:F( Arguments ) if BASE.Debug and _TraceOnOff then local DebugInfoCurrent = BASE.Debug.getinfo( 2, "nl" ) local DebugInfoFrom = BASE.Debug.getinfo( 3, "l" ) - + if _TraceLevel >= 1 then self:_F( Arguments, DebugInfoCurrent, DebugInfoFrom ) end - end + end end - --- Trace a function call level 2. Must be at the beginning of the function logic. -- @param #BASE self -- @param Arguments A #table or any field. @@ -1149,11 +1133,11 @@ function BASE:F2( Arguments ) if BASE.Debug and _TraceOnOff then local DebugInfoCurrent = BASE.Debug.getinfo( 2, "nl" ) local DebugInfoFrom = BASE.Debug.getinfo( 3, "l" ) - + if _TraceLevel >= 2 then self:_F( Arguments, DebugInfoCurrent, DebugInfoFrom ) end - end + end end --- Trace a function call level 3. Must be at the beginning of the function logic. @@ -1164,11 +1148,11 @@ function BASE:F3( Arguments ) if BASE.Debug and _TraceOnOff then local DebugInfoCurrent = BASE.Debug.getinfo( 2, "nl" ) local DebugInfoFrom = BASE.Debug.getinfo( 3, "l" ) - + if _TraceLevel >= 3 then self:_F( Arguments, DebugInfoCurrent, DebugInfoFrom ) end - end + end end --- Trace a function logic. @@ -1176,28 +1160,28 @@ end -- @param Arguments A #table or any field. function BASE:_T( Arguments, DebugInfoCurrentParam, DebugInfoFromParam ) - if BASE.Debug and ( _TraceAll == true ) or ( _TraceClass[self.ClassName] or _TraceClassMethod[self.ClassName] ) then + if BASE.Debug and (_TraceAll == true) or (_TraceClass[self.ClassName] or _TraceClassMethod[self.ClassName]) then local DebugInfoCurrent = DebugInfoCurrentParam and DebugInfoCurrentParam or BASE.Debug.getinfo( 2, "nl" ) local DebugInfoFrom = DebugInfoFromParam and DebugInfoFromParam or BASE.Debug.getinfo( 3, "l" ) - - local Function = "function" - if DebugInfoCurrent.name then - Function = DebugInfoCurrent.name - end + + local Function = "function" + if DebugInfoCurrent.name then + Function = DebugInfoCurrent.name + end if _TraceAll == true or _TraceClass[self.ClassName] or _TraceClassMethod[self.ClassName].Method[Function] then local LineCurrent = 0 if DebugInfoCurrent.currentline then LineCurrent = DebugInfoCurrent.currentline end - local LineFrom = 0 - if DebugInfoFrom then - LineFrom = DebugInfoFrom.currentline - end - env.info( string.format( "%6d(%6d)/%1s:%30s%05d.%s" , LineCurrent, LineFrom, "T", self.ClassName, self.ClassID, routines.utils.oneLineSerialize( Arguments ) ) ) + local LineFrom = 0 + if DebugInfoFrom then + LineFrom = DebugInfoFrom.currentline + end + env.info( string.format( "%6d(%6d)/%1s:%30s%05d.%s", LineCurrent, LineFrom, "T", self.ClassName, self.ClassID, routines.utils.oneLineSerialize( Arguments ) ) ) end - end + end end --- Trace a function logic level 1. Can be anywhere within the function logic. @@ -1208,14 +1192,13 @@ function BASE:T( Arguments ) if BASE.Debug and _TraceOnOff then local DebugInfoCurrent = BASE.Debug.getinfo( 2, "nl" ) local DebugInfoFrom = BASE.Debug.getinfo( 3, "l" ) - + if _TraceLevel >= 1 then self:_T( Arguments, DebugInfoCurrent, DebugInfoFrom ) end - end + end end - --- Trace a function logic level 2. Can be anywhere within the function logic. -- @param #BASE self -- @param Arguments A #table or any field. @@ -1224,7 +1207,7 @@ function BASE:T2( Arguments ) if BASE.Debug and _TraceOnOff then local DebugInfoCurrent = BASE.Debug.getinfo( 2, "nl" ) local DebugInfoFrom = BASE.Debug.getinfo( 3, "l" ) - + if _TraceLevel >= 2 then self:_T( Arguments, DebugInfoCurrent, DebugInfoFrom ) end @@ -1239,7 +1222,7 @@ function BASE:T3( Arguments ) if BASE.Debug and _TraceOnOff then local DebugInfoCurrent = BASE.Debug.getinfo( 2, "nl" ) local DebugInfoFrom = BASE.Debug.getinfo( 3, "l" ) - + if _TraceLevel >= 3 then self:_T( Arguments, DebugInfoCurrent, DebugInfoFrom ) end @@ -1252,27 +1235,26 @@ end function BASE:E( Arguments ) if BASE.Debug then - local DebugInfoCurrent = BASE.Debug.getinfo( 2, "nl" ) - local DebugInfoFrom = BASE.Debug.getinfo( 3, "l" ) - - local Function = "function" - if DebugInfoCurrent.name then - Function = DebugInfoCurrent.name - end - - local LineCurrent = DebugInfoCurrent.currentline - local LineFrom = -1 - if DebugInfoFrom then - LineFrom = DebugInfoFrom.currentline - end - - env.info( string.format( "%6d(%6d)/%1s:%30s%05d.%s(%s)" , LineCurrent, LineFrom, "E", self.ClassName, self.ClassID, Function, routines.utils.oneLineSerialize( Arguments ) ) ) - else - env.info( string.format( "%1s:%30s%05d(%s)" , "E", self.ClassName, self.ClassID, routines.utils.oneLineSerialize( Arguments ) ) ) - end - -end + local DebugInfoCurrent = BASE.Debug.getinfo( 2, "nl" ) + local DebugInfoFrom = BASE.Debug.getinfo( 3, "l" ) + local Function = "function" + if DebugInfoCurrent.name then + Function = DebugInfoCurrent.name + end + + local LineCurrent = DebugInfoCurrent.currentline + local LineFrom = -1 + if DebugInfoFrom then + LineFrom = DebugInfoFrom.currentline + end + + env.info( string.format( "%6d(%6d)/%1s:%30s%05d.%s(%s)", LineCurrent, LineFrom, "E", self.ClassName, self.ClassID, Function, routines.utils.oneLineSerialize( Arguments ) ) ) + else + env.info( string.format( "%1s:%30s%05d(%s)", "E", self.ClassName, self.ClassID, routines.utils.oneLineSerialize( Arguments ) ) ) + end + +end --- Log an information which will be traced always. Can be anywhere within the function logic. -- @param #BASE self @@ -1282,38 +1264,35 @@ function BASE:I( Arguments ) if BASE.Debug then local DebugInfoCurrent = BASE.Debug.getinfo( 2, "nl" ) local DebugInfoFrom = BASE.Debug.getinfo( 3, "l" ) - + local Function = "function" if DebugInfoCurrent.name then Function = DebugInfoCurrent.name end - + local LineCurrent = DebugInfoCurrent.currentline - local LineFrom = -1 + local LineFrom = -1 if DebugInfoFrom then LineFrom = DebugInfoFrom.currentline end - - env.info( string.format( "%6d(%6d)/%1s:%30s%05d.%s(%s)" , LineCurrent, LineFrom, "I", self.ClassName, self.ClassID, Function, routines.utils.oneLineSerialize( Arguments ) ) ) + + env.info( string.format( "%6d(%6d)/%1s:%30s%05d.%s(%s)", LineCurrent, LineFrom, "I", self.ClassName, self.ClassID, Function, routines.utils.oneLineSerialize( Arguments ) ) ) else - env.info( string.format( "%1s:%30s%05d(%s)" , "I", self.ClassName, self.ClassID, routines.utils.oneLineSerialize( Arguments ) ) ) + env.info( string.format( "%1s:%30s%05d(%s)", "I", self.ClassName, self.ClassID, routines.utils.oneLineSerialize( Arguments ) ) ) end - + end - - --- old stuff ---function BASE:_Destructor() +-- function BASE:_Destructor() -- --self:E("_Destructor") -- -- --self:EventRemoveAll() ---end - +-- end -- THIS IS WHY WE NEED LUA 5.2 ... ---function BASE:_SetDestructor() +-- function BASE:_SetDestructor() -- -- -- TODO: Okay, this is really technical... -- -- When you set a proxy to a table to catch __gc, weak tables don't behave like weak... @@ -1333,5 +1312,5 @@ end -- -- table is about to be garbage-collected - then the __gc hook -- -- will be invoked and the destructor called -- rawset( self, '__proxy', proxy ) --- ---end \ No newline at end of file +-- +-- end