From f7c9e1849655f18b951edb87cb589d59589b7178 Mon Sep 17 00:00:00 2001 From: Chris Woerz Date: Sat, 27 Dec 2014 23:26:44 -0700 Subject: [PATCH 001/446] Work on #456 --- src/kOS/Suffixed/Part/PartValue.cs | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/kOS/Suffixed/Part/PartValue.cs b/src/kOS/Suffixed/Part/PartValue.cs index 956004cb6..fc3bc6291 100644 --- a/src/kOS/Suffixed/Part/PartValue.cs +++ b/src/kOS/Suffixed/Part/PartValue.cs @@ -44,8 +44,24 @@ private void PartInitializeSuffixes() AddSuffix("PARENT", new Suffix(() => PartValueFactory.Construct(Part.parent,shared), "The parent part of this part")); AddSuffix("HASPARENT", new Suffix(() => Part.parent != null, "Tells you if this part has a parent, is used to avoid null exception from PARENT")); AddSuffix("CHILDREN", new Suffix(() => PartValueFactory.Construct(Part.children, shared), "A LIST() of the children parts of this part")); + AddSuffix("DRYMASS", new Suffix(() => Part.mass)); + AddSuffix("MASS", new Suffix(() => Part.mass + Part.GetResourceMass())); + AddSuffix("WETMASS", new Suffix(GetWetMass)); } - + + private float GetWetMass() + { + float mass = Part.mass; + + for (int index = 0; index < Part.Resources.Count; ++index) + { + PartResource partResource = Part.Resources[index]; + mass += (float)partResource.maxAmount * partResource.info.density; + } + + return mass; + } + private PartModuleFields GetModule(string modName) { foreach (PartModule mod in Part.Modules) From 8b3f081aa7bccba97a920bcf60728f9962ef5481 Mon Sep 17 00:00:00 2001 From: hvacengi Date: Sun, 28 Dec 2014 22:10:28 -0500 Subject: [PATCH 002/446] Initial enable of built in autopilot abilities SteeringHelper.cs - enable SAS.LockHeading support if SAS is turned on. Allows for control to be handled through built in libraries rather than through the adapted MechJeb library. FlightControlManager.cs - Add two new parameters (maneuver and prograde) to test enabling the built in matching autopilot modes. Added some debugging to try and figure out how things are working. Added a switch/case to handle the different modes. These modes do not require a callback, so no new action is required for these parameters, nor a value call back, I think. --- src/kOS/Binding/FlightControlManager.cs | 43 ++++++++++++++++++++++++- src/kOS/Utilities/SteeringHelper.cs | 6 ++++ 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/src/kOS/Binding/FlightControlManager.cs b/src/kOS/Binding/FlightControlManager.cs index 1542f4f84..22f3b1fee 100644 --- a/src/kOS/Binding/FlightControlManager.cs +++ b/src/kOS/Binding/FlightControlManager.cs @@ -41,6 +41,8 @@ public override void AddTo(SharedObjects shared) AddNewFlightParam("steering", Shared); AddNewFlightParam("wheelthrottle", Shared); AddNewFlightParam("wheelsteering", Shared); + AddNewFlightParam("maneuver", Shared); + AddNewFlightParam("prograde", Shared); } @@ -55,12 +57,51 @@ private void OnFlyByWire(FlightCtrlState c) } } + private void clearStockAutopilot(string enabledMode) + { + if (enabledMode != "maneuver") flightParameters["maneuver"].Enabled = false; + if (enabledMode != "prograde") flightParameters["prograde"].Enabled = false; + } + public void ToggleFlyByWire(string paramName, bool enabled) { Debug.Log(string.Format("kOS: FlightControlManager: ToggleFlyByWire: {0} {1}", paramName, enabled)); - if (!flightParameters.ContainsKey(paramName)) return; + if (!flightParameters.ContainsKey(paramName)) { UnityEngine.Debug.LogError("kOS: no such flybywire parameter " + paramName); return; } flightParameters[paramName].Enabled = enabled; + UnityEngine.Debug.LogWarning("kOS: flybywire parameter " + paramName); + UnityEngine.Debug.LogWarning("kOS: parameter enabled " + enabled.ToString()); + switch (paramName.ToLower()) + { + case "maneuver": + if (enabled) + { + currentVessel.Autopilot.SetMode(VesselAutopilot.AutopilotMode.Maneuver); + currentVessel.Autopilot.Enable(); + } + else + { + currentVessel.Autopilot.SetMode(VesselAutopilot.AutopilotMode.StabilityAssist); + currentVessel.Autopilot.Disable(); + } + clearStockAutopilot("maneuver"); + break; + case "prograde": + if (enabled) + { + currentVessel.Autopilot.SetMode(VesselAutopilot.AutopilotMode.Prograde); + currentVessel.Autopilot.Enable(); + } + else + { + currentVessel.Autopilot.SetMode(VesselAutopilot.AutopilotMode.StabilityAssist); + currentVessel.Autopilot.Disable(); + } + clearStockAutopilot("prograde"); + break; + default: + break; + } if (!enabled) { flightParameters[paramName].ClearValue(); diff --git a/src/kOS/Utilities/SteeringHelper.cs b/src/kOS/Utilities/SteeringHelper.cs index 774a9b2b8..c0c9b060d 100644 --- a/src/kOS/Utilities/SteeringHelper.cs +++ b/src/kOS/Utilities/SteeringHelper.cs @@ -38,6 +38,12 @@ public static void SteerShipToward(Direction targetDir, FlightCtrlState c, Vesse var target = targetDir.Rotation; var vesselRotation = vessel.ReferenceTransform.rotation; + if (vessel.ActionGroups[KSPActionGroup.SAS]) + { + vessel.Autopilot.SAS.LockHeading(target * Quaternion.Euler(90, 0, 0), true); + return; + } + // some validations if (!Utils.IsValidNumber(c.mainThrottle) || !Utils.IsValidVector(centerOfMass) || From 40f2d8398b7e2227978f8fff884482926524dda8 Mon Sep 17 00:00:00 2001 From: Chris Woerz Date: Mon, 29 Dec 2014 13:03:43 -0700 Subject: [PATCH 003/446] vesseltarget uses new suffixes, added type and name as settable values, mass calculations respect physics state --- src/kOS.Safe/Utilities/EnumUtilities.cs | 12 ++ src/kOS.Safe/kOS.Safe.csproj | 1 + src/kOS/Suffixed/Part/PartValue.cs | 19 +-- src/kOS/Suffixed/VesselTarget.cs | 148 +++++++++++++++--------- src/kOS/Utilities/PartUtilities.cs | 45 +++++++ src/kOS/Utilities/VesselUtils.cs | 10 ++ src/kOS/kOS.csproj | 1 + 7 files changed, 168 insertions(+), 68 deletions(-) create mode 100644 src/kOS.Safe/Utilities/EnumUtilities.cs create mode 100644 src/kOS/Utilities/PartUtilities.cs diff --git a/src/kOS.Safe/Utilities/EnumUtilities.cs b/src/kOS.Safe/Utilities/EnumUtilities.cs new file mode 100644 index 000000000..c00855667 --- /dev/null +++ b/src/kOS.Safe/Utilities/EnumUtilities.cs @@ -0,0 +1,12 @@ +using System; + +namespace kOS.Safe.Utilities +{ + public static class EnumUtilities + { + public static T ToEnum(this string value, bool ignoreCase = true) + { + return (T)Enum.Parse(typeof(T), value, ignoreCase); + } + } +} diff --git a/src/kOS.Safe/kOS.Safe.csproj b/src/kOS.Safe/kOS.Safe.csproj index 405961995..4ab43bcf3 100644 --- a/src/kOS.Safe/kOS.Safe.csproj +++ b/src/kOS.Safe/kOS.Safe.csproj @@ -136,6 +136,7 @@ + diff --git a/src/kOS/Suffixed/Part/PartValue.cs b/src/kOS/Suffixed/Part/PartValue.cs index fc3bc6291..efa7cd22c 100644 --- a/src/kOS/Suffixed/Part/PartValue.cs +++ b/src/kOS/Suffixed/Part/PartValue.cs @@ -44,23 +44,12 @@ private void PartInitializeSuffixes() AddSuffix("PARENT", new Suffix(() => PartValueFactory.Construct(Part.parent,shared), "The parent part of this part")); AddSuffix("HASPARENT", new Suffix(() => Part.parent != null, "Tells you if this part has a parent, is used to avoid null exception from PARENT")); AddSuffix("CHILDREN", new Suffix(() => PartValueFactory.Construct(Part.children, shared), "A LIST() of the children parts of this part")); - AddSuffix("DRYMASS", new Suffix(() => Part.mass)); - AddSuffix("MASS", new Suffix(() => Part.mass + Part.GetResourceMass())); - AddSuffix("WETMASS", new Suffix(GetWetMass)); + AddSuffix("DRYMASS", new Suffix(() => Part.HasPhysics() ? Part.mass : 0)); + AddSuffix("MASS", new Suffix(Part.CalculateCurrentMass)); + AddSuffix("WETMASS", new Suffix(Part.GetWetMass)); + AddSuffix("HASPHYSICS", new Suffix(Part.HasPhysics)); } - private float GetWetMass() - { - float mass = Part.mass; - - for (int index = 0; index < Part.Resources.Count; ++index) - { - PartResource partResource = Part.Resources[index]; - mass += (float)partResource.maxAmount * partResource.info.density; - } - - return mass; - } private PartModuleFields GetModule(string modName) { diff --git a/src/kOS/Suffixed/VesselTarget.cs b/src/kOS/Suffixed/VesselTarget.cs index 857cdc35e..98e603bbc 100644 --- a/src/kOS/Suffixed/VesselTarget.cs +++ b/src/kOS/Suffixed/VesselTarget.cs @@ -1,9 +1,9 @@ using System; using System.Linq; using kOS.Binding; -using kOS.Safe.Exceptions; using kOS.Safe.Encapsulation; using kOS.Safe.Encapsulation.Suffixes; +using kOS.Safe.Utilities; using kOS.Suffixed.Part; using kOS.Utilities; using kOS.Module; @@ -400,64 +400,106 @@ private void InitializeSuffixes() AddSuffix("PARTSTAGGED", new OneArgsSuffix(GetPartsTagged)); AddSuffix("ALLTAGGEDPARTS", new NoArgsSuffix(GetAllTaggedParts)); AddSuffix("PARTS", new NoArgsSuffix(GetAllParts)); + + AddSuffix("CONTROL", new Suffix(() => FlightControlManager.GetControllerByVessel(Vessel))); + AddSuffix("BEARING", new Suffix(() => VesselUtils.GetTargetBearing(CurrentVessel, Vessel))); + AddSuffix("HEADING", new Suffix(() => VesselUtils.GetTargetHeading(CurrentVessel, Vessel))); + AddSuffix("AVAILABLETHRUST", new Suffix(() => VesselUtils.GetAvailableThrust(Vessel))); + AddSuffix("MAXTHRUST", new Suffix(() => VesselUtils.GetMaxThrust(Vessel))); + AddSuffix("FACING", new Suffix(() => VesselUtils.GetFacing(Vessel))); + AddSuffix("ANGULARMOMENTUM", new Suffix(() => new Vector(Vessel.angularMomentum))); + AddSuffix("ANGULARVEL", new Suffix(() => new Vector(Vessel.angularVelocity))); + AddSuffix("MASS", new Suffix(() => Vessel.GetTotalMass())); + AddSuffix("VERTICALSPEED", new Suffix(() => Vessel.verticalSpeed)); + AddSuffix("SURFACESPEED", new Suffix(() => Vessel.horizontalSrfSpeed)); + AddSuffix("AIRSPEED", new Suffix(() => (Vessel.orbit.GetVel() - FlightGlobals.currentMainBody.getRFrmVel(Vessel.findWorldCenterOfMass())).magnitude,"the velocity of the vessel relative to the air")); + AddSuffix(new[] {"SHIPNAME", "NAME"}, new SetSuffix(() => Vessel.vesselName, RenameVessel)); + AddSuffix("TYPE", new SetSuffix(() => Vessel.vesselType.ToString(), RetypeVessel)); + AddSuffix("SENSORS", new Suffix(() => new VesselSensors(Vessel))); + AddSuffix("TERMVELOCITY", new Suffix(() => VesselUtils.GetTerminalVelocity(Vessel))); + AddSuffix("LOADED", new Suffix(() => Vessel.loaded)); + AddSuffix("ROOTPART", new Suffix(() => PartValueFactory.Construct(Vessel.rootPart, Shared))); + AddSuffix("DRYMASS", new Suffix(() => Vessel.GetDryMass())); + AddSuffix("WETMASS", new Suffix(Vessel.GetWetMass)); + + //// Although there is an implementation of lat/long/alt in Orbitible, + //// it's better to use the methods for vessels that are faster if they're + //// available: + AddSuffix("LATITUDE", new Suffix(() => VesselUtils.GetVesselLattitude(Vessel))); + AddSuffix("LONGITUDE", new Suffix(() => VesselUtils.GetVesselLongitude(Vessel))); + AddSuffix("ALTITUDE", new Suffix(() => Vessel.altitude)); } + + private void RetypeVessel(string value) + { + Vessel.vesselType = value.ToEnum(); + } + + private void RenameVessel(string value) + { + if (Vessel.IsValidVesselName(value)) + { + Vessel.vesselName = value; + } + } + public override object GetSuffix(string suffixName) { switch (suffixName) { - // TODO: These need to be moved into InitializeSuffixes() at some point: - - case "CONTROL": - return FlightControlManager.GetControllerByVessel(Vessel); - case "BEARING": - return VesselUtils.GetTargetBearing(CurrentVessel, Vessel); - case "HEADING": - return VesselUtils.GetTargetHeading(CurrentVessel, Vessel); - case "AVAILABLETHRUST": - return VesselUtils.GetAvailableThrust(Vessel); - case "MAXTHRUST": - return VesselUtils.GetMaxThrust(Vessel); - case "FACING": - return VesselUtils.GetFacing(Vessel); - case "ANGULARMOMENTUM": - return new Vector(Vessel.angularMomentum); - case "ANGULARVEL": - return new Vector(Vessel.angularVelocity); - case "MASS": - return Vessel.GetTotalMass(); - case "VERTICALSPEED": - return Vessel.verticalSpeed; - case "SURFACESPEED": - return Vessel.horizontalSrfSpeed; - case "AIRSPEED": - return - (Vessel.orbit.GetVel() - FlightGlobals.currentMainBody.getRFrmVel(Vessel.findWorldCenterOfMass())) - .magnitude; //the velocity of the vessel relative to the air); - //DEPRICATED VESSELNAME - case "VESSELNAME": - throw new KOSException("VESSELNAME is DEPRICATED, use SHIPNAME."); - case "SHIPNAME": - return Vessel.vesselName; - - // Although there is an implementation of lat/long/alt in Orbitible, - // it's better to use the methods for vessels that are faster if they're - // available: - case "LATITUDE": - return VesselUtils.GetVesselLattitude(Vessel); - case "LONGITUDE": - return VesselUtils.GetVesselLongitude(Vessel); - case "ALTITUDE": - return Vessel.altitude; - - case "SENSORS": - return new VesselSensors(Vessel); - case "TERMVELOCITY": - return VesselUtils.GetTerminalVelocity(Vessel); - case "LOADED": - return Vessel.loaded; - case "ROOTPART": - return PartValueFactory.Construct(Vessel.rootPart,Shared); + // TODO: I left this code in commented to let the reviewer check my work for yank put mistakes, after that it should be removed + + //case "CONTROL": + // return FlightControlManager.GetControllerByVessel(Vessel); + //case "BEARING": + // return VesselUtils.GetTargetBearing(CurrentVessel, Vessel); + //case "HEADING": + // return VesselUtils.GetTargetHeading(CurrentVessel, Vessel); + //case "AVAILABLETHRUST": + // return VesselUtils.GetAvailableThrust(Vessel); + //case "MAXTHRUST": + // return VesselUtils.GetMaxThrust(Vessel); + //case "FACING": + // return VesselUtils.GetFacing(Vessel); + //case "ANGULARMOMENTUM": + // return new Vector(Vessel.angularMomentum); + //case "ANGULARVEL": + // return new Vector(Vessel.angularVelocity); + //case "MASS": + // return Vessel.GetTotalMass(); + //case "VERTICALSPEED": + // return Vessel.verticalSpeed; + //case "SURFACESPEED": + // return Vessel.horizontalSrfSpeed; + //case "AIRSPEED": + // return + // (Vessel.orbit.GetVel() - FlightGlobals.currentMainBody.getRFrmVel(Vessel.findWorldCenterOfMass())) + // .magnitude; //the velocity of the vessel relative to the air); + ////DEPRICATED VESSELNAME + //case "VESSELNAME": + // throw new KOSException("VESSELNAME is DEPRICATED, use SHIPNAME."); + //case "SHIPNAME": + // return Vessel.vesselName; + + //// Although there is an implementation of lat/long/alt in Orbitible, + //// it's better to use the methods for vessels that are faster if they're + //// available: + //case "LATITUDE": + // return VesselUtils.GetVesselLattitude(Vessel); + //case "LONGITUDE": + // return VesselUtils.GetVesselLongitude(Vessel); + //case "ALTITUDE": + // return Vessel.altitude; + + //case "SENSORS": + // return new VesselSensors(Vessel); + //case "TERMVELOCITY": + // return VesselUtils.GetTerminalVelocity(Vessel); + //case "LOADED": + // return Vessel.loaded; + //case "ROOTPART": + // return PartValueFactory.Construct(Vessel.rootPart,Shared); } // Is this a resource? diff --git a/src/kOS/Utilities/PartUtilities.cs b/src/kOS/Utilities/PartUtilities.cs new file mode 100644 index 000000000..5f7a62d5e --- /dev/null +++ b/src/kOS/Utilities/PartUtilities.cs @@ -0,0 +1,45 @@ +using System; + +namespace kOS.Utilities +{ + public static class PartUtilities + { + public static float CalculateCurrentMass(this Part part) + { + return part.HasPhysics() ? part.mass + part.GetResourceMass() : 0; + } + + public static bool HasPhysics(this Part part) + { + switch (part.physicalSignificance) + { + case Part.PhysicalSignificance.FULL: + return true; + case Part.PhysicalSignificance.NONE: + return false; + default: + throw new NotImplementedException("Unknown Part physics type: " + part.physicalSignificance); + } + } + + public static float GetDryMass(this Part part) + { + return !part.HasPhysics() ? 0 : part.mass; + } + + public static float GetWetMass(this Part part) + { + if (!part.HasPhysics()) return 0; + + float mass = part.mass; + + for (int index = 0; index < part.Resources.Count; ++index) + { + PartResource partResource = part.Resources[index]; + mass += (float)partResource.maxAmount * partResource.info.density; + } + + return mass; + } + } +} \ No newline at end of file diff --git a/src/kOS/Utilities/VesselUtils.cs b/src/kOS/Utilities/VesselUtils.cs index e812ba0b0..3be1bb65a 100644 --- a/src/kOS/Utilities/VesselUtils.cs +++ b/src/kOS/Utilities/VesselUtils.cs @@ -330,6 +330,16 @@ private static double GetMassDrag(Vessel vessel) current + (p.mass + p.GetResourceMass()) * p.maximum_drag); } + public static float GetDryMass(this Vessel vessel) + { + return vessel.parts.Sum(part => part.GetDryMass()); + } + + public static float GetWetMass(this Vessel vessel) + { + return vessel.parts.Sum(part => part.GetWetMass()); + } + private static double RealMaxAtmosphereAltitude(CelestialBody body) { // This comes from MechJeb CelestialBodyExtensions.cs diff --git a/src/kOS/kOS.csproj b/src/kOS/kOS.csproj index 128e66cd8..3cfb10f1c 100644 --- a/src/kOS/kOS.csproj +++ b/src/kOS/kOS.csproj @@ -124,6 +124,7 @@ + From b713232b5c6276c107a8a16089fe8ea0cdc102ee Mon Sep 17 00:00:00 2001 From: Chris Woerz Date: Mon, 29 Dec 2014 13:03:51 -0700 Subject: [PATCH 004/446] updated documentation --- doc/source/structures/vessels/engine.rst | 2 +- doc/source/structures/vessels/part.rst | 42 ++++++++++++++++++++++++ doc/source/structures/vessels/vessel.rst | 33 ++++++++++++++++--- 3 files changed, 72 insertions(+), 5 deletions(-) diff --git a/doc/source/structures/vessels/engine.rst b/doc/source/structures/vessels/engine.rst index 4263eb92e..42314f542 100644 --- a/doc/source/structures/vessels/engine.rst +++ b/doc/source/structures/vessels/engine.rst @@ -77,7 +77,7 @@ Some of the Parts returned by :ref:`LIST PARTS ` will be of type E .. attribute:: Engine:THRUSTLIMIT - :access: Get only + :access: Get/Set :type: scalar (%) If this an engine with a thrust limiter (tweakable) enabled, what percentage is it limited to? diff --git a/doc/source/structures/vessels/part.rst b/doc/source/structures/vessels/part.rst index ca11234b8..a4849788a 100644 --- a/doc/source/structures/vessels/part.rst +++ b/doc/source/structures/vessels/part.rst @@ -21,6 +21,15 @@ These are the generic properties every PART has. You can obtain a list of values * - :attr:`TITLE` - string - Title as it appears in KSP + * - :attr:`MASS` + - scalar + - Current mass of part and its resources + * - :attr:`DRYMASS` + - scalar + - Mass of part if all resources were empty + * - :attr:`WETMASS` + - scalar + - Mass of part if all resources were full * - :attr:`TAG` - string - Name-tag if assigned by the player @@ -66,6 +75,9 @@ These are the generic properties every PART has. You can obtain a list of values * - :attr:`HASPARENT` - boolean - Check if this part has a parent :struct:`Part` + * - :attr:`HASPHYSICS` + - boolean + - Does this part have mass or drag * - :attr:`CHILDREN` - :struct:`List` - List of attached :struct:`Parts ` @@ -158,7 +170,28 @@ These are the generic properties every PART has. You can obtain a list of values :type: :struct:`Direction` the direction that this part is facing. + +.. attribute:: Part:MASS + + :access: Get only + :type: scalar + + The current mass or the part and its resources. If the part has no physics this will always be 0. + +.. attribute:: Part:WETMASS + + :access: Get only + :type: scalar + + The mass of the part if all of its resources were full. If the part has no physics this will always be 0. + +.. attribute:: Part:DRYMASS + :access: Get only + :type: scalar + + The mass of the part if all of its resources were empty. If the part has no physics this will always be 0. + .. attribute:: Part:RESOURCES :access: Get only @@ -205,6 +238,15 @@ These are the generic properties every PART has. You can obtain a list of values When walking the :ref:`tree of parts `, this is the part that this part is attached to on the way "up" toward the root part. +.. attribute:: Part:HASPHYSICS + + :access: Get only + :type: bool + + This comes from a part's configuration and is an artifact of the KSP simulation. + + For a list of stock parts that have this attribute and a fuller explanation see: http://wiki.kerbalspaceprogram.com/wiki/Massless_part + .. attribute:: Part:HASPARENT :access: Get only diff --git a/doc/source/structures/vessels/vessel.rst b/doc/source/structures/vessels/vessel.rst index 604b18522..d5d63d76d 100644 --- a/doc/source/structures/vessels/vessel.rst +++ b/doc/source/structures/vessels/vessel.rst @@ -37,11 +37,14 @@ All vessels share a structure. To get a variable referring to any vessel you can :attr:`MAXTHRUST` scalar Sum of active maximum thrusts :attr:`FACING` :struct:`Direction` The way the vessel is pointed :attr:`MASS` scalar (metric tons) Mass of the ship + :attr:`WETMASS` scalar (metric tons) Mass of the ship fully fuelled + :attr:`DRYMASS` scalar (metric tons) Mass of the ship with no resources :attr:`VERTICALSPEED` scalar (m/s) How fast the ship is moving "up" :attr:`SURFACESPEED` scalar (m/s) How fast the ship is moving "horizontally" :attr:`AIRSPEED` scalar (m/s) How fast the ship is moving relative to the air :attr:`TERMVELOCITY` scalar (m/s) terminal velocity of the vessel - :attr:`VESSELNAME` string The name of the vessel + :attr:`SHIPNAME` string The name of the vessel + :attr:`NAME` string Synomym for SHIPNAME :attr:`ANGULARMOMENTUM` :struct:`Vector` In :ref:`SHIP_RAW ` :attr:`ANGULARVEL` :struct:`Vector` In :ref:`SHIP_RAW ` :attr:`SENSORS` :struct:`VesselSensors` Sensor data @@ -100,6 +103,20 @@ All vessels share a structure. To get a variable referring to any vessel you can :access: Get only The mass of the ship + +.. attribute:: Vessel:WETMASS + + :type: scalar (metric tons) + :access: Get only + + The mass of the ship if all resources were full + +.. attribute:: Vessel:DRYMASS + + :type: scalar (metric tons) + :access: Get only + + The mass of the ship if all resources were empty .. attribute:: Vessel:VERTICALSPEED @@ -129,12 +146,20 @@ All vessels share a structure. To get a variable referring to any vessel you can terminal velocity of the vessel in freefall through atmosphere, based on the vessel's current altitude above sea level, and its drag properties. Warning, can cause values of Infinity if used in a vacuum, and kOS sometimes does not let you store Infinity in a variable. -.. attribute:: Vessel:VESSELNAME +.. attribute:: Vessel:SHIPNAME :type: string - :access: Get only + :access: Get/Set + :synomym: NAME + + The name of the vessel as it appears in the tracking station. When you set this, it cannot be empty. + +.. attribute:: Vessel:TYPE + + :type: string + :access: Get/Set - The name of the vessel as it appears in the tracking station. + The ship's type as described here: http://wiki.kerbalspaceprogram.com/wiki/Craft#Vessel_types .. attribute:: Vessel:ANGULARMOMENTUM From 1f9ad61dccd57f547cfbfe9d3ddf6a0e25d64ee8 Mon Sep 17 00:00:00 2001 From: Johann Goetz Date: Mon, 29 Dec 2014 20:14:21 -0500 Subject: [PATCH 005/446] updated gh-pages and fixed some small issues with links in the rst source. --- doc/source/structures/vessels/part.rst | 34 +++++++-------- doc/source/structures/vessels/vessel.rst | 55 +++++++++++++++--------- 2 files changed, 52 insertions(+), 37 deletions(-) diff --git a/doc/source/structures/vessels/part.rst b/doc/source/structures/vessels/part.rst index a4849788a..a544a8271 100644 --- a/doc/source/structures/vessels/part.rst +++ b/doc/source/structures/vessels/part.rst @@ -21,13 +21,13 @@ These are the generic properties every PART has. You can obtain a list of values * - :attr:`TITLE` - string - Title as it appears in KSP - * - :attr:`MASS` + * - :attr:`MASS` - scalar - Current mass of part and its resources - * - :attr:`DRYMASS` + * - :attr:`DRYMASS` - scalar - Mass of part if all resources were empty - * - :attr:`WETMASS` + * - :attr:`WETMASS` - scalar - Mass of part if all resources were full * - :attr:`TAG` @@ -111,21 +111,21 @@ These are the generic properties every PART has. You can obtain a list of values The name tag value that may exist on this part if you have given the part a name via the :ref:`name-tag system `. A part's *tag* is whatever custom name you have given it using the :ref:`name-tag system described here `. This is probably the best naming convention to use because it lets you make up whatever name you like for the part and use it to pick the parts you want to deal with in your script. - + This example assumes you have a target vessel picked, and that the target vessel is loaded into full-physics range and not "on rails". vessels that are "on rails" do not have their full list of parts entirely populated at the moment:: LIST PARTS FROM TARGET IN tParts. - + PRINT "The target vessel has a". PRINT "partcount of " + tParts:LENGTH. - + SET totTargetable to 0. FOR part in tParts { IF part:TARGETABLE { SET totTargetable TO totTargetable + 1. } } - + PRINT "...and " + totTargetable. PRINT " of them are targetable parts.". @@ -135,7 +135,7 @@ These are the generic properties every PART has. You can obtain a list of values :type: boolean Set to TRUE to cause the game to do the same thing as when you right-click a part on a vessel and select "control from here" on the menu. It rotates the control orientation so that fore/aft/left/right/up/down now match the orientation of this part. NOTE that this will not work for every type of part. It only works for those parts that KSP itself allows this for (control cores and docking ports). - + .. attribute:: Part:STAGE :access: Get only @@ -170,28 +170,28 @@ These are the generic properties every PART has. You can obtain a list of values :type: :struct:`Direction` the direction that this part is facing. - + .. attribute:: Part:MASS :access: Get only :type: scalar The current mass or the part and its resources. If the part has no physics this will always be 0. - + .. attribute:: Part:WETMASS :access: Get only :type: scalar The mass of the part if all of its resources were full. If the part has no physics this will always be 0. - + .. attribute:: Part:DRYMASS :access: Get only :type: scalar The mass of the part if all of its resources were empty. If the part has no physics this will always be 0. - + .. attribute:: Part:RESOURCES :access: Get only @@ -226,7 +226,7 @@ These are the generic properties every PART has. You can obtain a list of values :type: :struct:`List` of strings list of the names of :struct:`PartModules ` enabled for this part. - + .. attribute:: Part:ALLMODULES Same as :attr:`Part:MODULES` @@ -243,10 +243,10 @@ These are the generic properties every PART has. You can obtain a list of values :access: Get only :type: bool - This comes from a part's configuration and is an artifact of the KSP simulation. - - For a list of stock parts that have this attribute and a fuller explanation see: http://wiki.kerbalspaceprogram.com/wiki/Massless_part - + This comes from a part's configuration and is an artifact of the KSP simulation. + + For a list of stock parts that have this attribute and a fuller explanation see `the KSP wiki page about massless parts `_. + .. attribute:: Part:HASPARENT :access: Get only diff --git a/doc/source/structures/vessels/vessel.rst b/doc/source/structures/vessels/vessel.rst index d5d63d76d..126b33378 100644 --- a/doc/source/structures/vessels/vessel.rst +++ b/doc/source/structures/vessels/vessel.rst @@ -74,14 +74,14 @@ All vessels share a structure. To get a variable referring to any vessel you can :type: scalar :access: Get only - *relative* compass heading (degrees) to this vessel from the `CPU Vessel <../../summary_topics/CPU_Vessel/index.html>`__, taking into account the CPU Vessel's own heading. + *relative* compass heading (degrees) to this vessel from the :ref:`CPU Vessel `, taking into account the CPU Vessel's own heading. .. attribute:: Vessel:HEADING :type: scalar :access: Get only - *absolute* compass heading (degrees) to this vessel from the `CPU Vessel <../../summary_topics/CPU_Vessel/index.html>`__ + *absolute* compass heading (degrees) to this vessel from the :ref:`CPU Vessel ` .. attribute:: Vessel:MAXTHRUST @@ -103,14 +103,14 @@ All vessels share a structure. To get a variable referring to any vessel you can :access: Get only The mass of the ship - + .. attribute:: Vessel:WETMASS :type: scalar (metric tons) :access: Get only The mass of the ship if all resources were full - + .. attribute:: Vessel:DRYMASS :type: scalar (metric tons) @@ -150,30 +150,45 @@ All vessels share a structure. To get a variable referring to any vessel you can :type: string :access: Get/Set - :synomym: NAME The name of the vessel as it appears in the tracking station. When you set this, it cannot be empty. - + +.. attribute:: Vessel:NAME + + Same as :attr:`Vessel:SHIPNAME`. + .. attribute:: Vessel:TYPE :type: string :access: Get/Set - The ship's type as described here: http://wiki.kerbalspaceprogram.com/wiki/Craft#Vessel_types + The ship's type as described `on the KSP wiki `_. .. attribute:: Vessel:ANGULARMOMENTUM :type: :struct:`Direction` :access: Get only - Given in :ref:`SHIP_RAW ` reference frame. *As of* ``kOS 0.15.4`` *this has been changed to a vector, as it should have been all along.* The vector represents the axis of the rotation, and its magnitude is the angular momentum of the rotation, which varies not only with the speed of the rotation, but also with the angular inertia of the vessel. + Given in :ref:`SHIP_RAW ` reference frame. The vector represents the axis of the rotation, and its magnitude is the angular momentum of the rotation, which varies not only with the speed of the rotation, but also with the angular inertia of the vessel. + + .. note:: + + .. versionchanged:: 0.15.4 + + This has been changed to a vector, as it should have been all along. .. attribute:: Vessel:ANGULARVEL :type: :struct:`Direction` :access: Get only - Given in :ref:`SHIP_RAW ` reference frame. *As of* ``kOS 0.15.4`` *this has been changed to a vector, as it should have been all along.* The vector represents the axis of the rotation, and its magnitude is the speed of that rotation (Presumably in degrees per second? This is not documented in the KSP API and may take some experimentation to discover if it's radians or degrees). + Given in :ref:`SHIP_RAW ` reference frame. The vector represents the axis of the rotation, and its magnitude is the speed of that rotation (Presumably in degrees per second? This is not documented in the KSP API and may take some experimentation to discover if it's radians or degrees). + + .. note:: + + .. versionchanged:: 0.15.4 + + This has been changed to a vector, as it should have been all along. .. attribute:: Vessel:SENSORS @@ -194,21 +209,21 @@ All vessels share a structure. To get a variable referring to any vessel you can :type: :struct:`List` :access: Get only - The list of `orbit patches <../orbit/index.html>`__ that describe this vessel's current travel path based on momentum alone with no thrusting changes. If the current path has no transitions to other bodies, then this will be a list of only one orbit. If the current path intersects other bodies, then this will be a list describing the transitions into and out of the intersecting body's sphere of influence. SHIP:PATCHES[0] is always exactly the same as SHIP:OBT, SHIP:PATCHES[1] is the same as SHIP:OBT:NEXTPATCH, SHIP:PATCHES[2] is the same as SHIP:OBT:NEXTPATCH:NEXTPATCH, and so on. Note that you will only see as far into the future as your KSP settings allow. (See the setting CONIC\_PATCH\_LIMIT in your settings.cfg file) + The list of :ref:`orbit patches ` that describe this vessel's current travel path based on momentum alone with no thrusting changes. If the current path has no transitions to other bodies, then this will be a list of only one orbit. If the current path intersects other bodies, then this will be a list describing the transitions into and out of the intersecting body's sphere of influence. SHIP:PATCHES[0] is always exactly the same as SHIP:OBT, SHIP:PATCHES[1] is the same as SHIP:OBT:NEXTPATCH, SHIP:PATCHES[2] is the same as SHIP:OBT:NEXTPATCH:NEXTPATCH, and so on. Note that you will only see as far into the future as your KSP settings allow. (See the setting CONIC\_PATCH\_LIMIT in your settings.cfg file) .. attribute:: Vessel:ROOTPART :type: :struct:`Part` :access: Get only - The first `part <../part/index.html>`__ that was used to begin the ship design - the command core. Vessels in KSP are built in a tree-structure, and the first part that was placed is the root of that tree. + The first :struct:`Part` that was used to begin the ship design - the command core. Vessels in KSP are built in a tree-structure, and the first part that was placed is the root of that tree. .. attribute:: Vessel:PARTS :type: :struct:`List` of :struct:`Part` objects :access: Get only - A List of all the `parts <../part/index.html>`__ on the vessel. SET FOO TO SHIP:PARTS has exactly the same effect as LIST PARTS IN FOO. For more information, see `ship parts and modules <../../summary_topics/ship_parts_and_modules/index.html>`__ + A List of all the :ref:`parts ` on the vessel. ``SET FOO TO SHIP:PARTS.`` has exactly the same effect as ``LIST PARTS IN FOO.``. For more information, see :ref:`ship parts and modules `. .. method:: Vessel:PARTSNAMED(name) @@ -216,52 +231,52 @@ All vessels share a structure. To get a variable referring to any vessel you can :parameter name: (string) Name of the parts :return: :struct:`List` of :struct:`Part` objects - Part:NAME. The matching is done case-insensitively. For more information, see `ship parts and modules <../../summary_topics/ship_parts_and_modules/index.html>`__ + Part:NAME. The matching is done case-insensitively. For more information, see :ref:`ship parts and modules `. .. method:: Vessel:PARTSTITLED(title) :parameter title: (string) Title of the parts :return: :struct:`List` of :struct:`Part` objects - Part:TITLE. The matching is done case-insensitively. For more information, see `ship parts and modules <../../summary_topics/ship_parts_and_modules/index.html>`__ + Part:TITLE. The matching is done case-insensitively. For more information, see :ref:`ship parts and modules `. .. method:: Vessel:PARTSTAGGED(tag) :parameter tag: (string) Tag of the parts :return: :struct:`List` of :struct:`Part` objects - Part:TAG value. The matching is done case-insensitively. For more information, see `ship parts and modules <../../summary_topics/ship_parts_and_modules/index.html>`__ + Part:TAG value. The matching is done case-insensitively. For more information, see :ref:`ship parts and modules `. .. method:: Vessel:PARTSDUBBED(name) :parameter name: (string) name, title or tag of the parts :return: :struct:`List` of :struct:`Part` objects - name regardless of whether that name is the Part:Name, the Part:Tag, or the Part:Title. It is effectively the distinct union of :PARTSNAMED(val), :PARTSTITLED(val), :PARTSTAGGED(val). The matching is done case-insensitively. For more information, see `ship parts and modules <../../summary_topics/ship_parts_and_modules/index.html>`__ + name regardless of whether that name is the Part:Name, the Part:Tag, or the Part:Title. It is effectively the distinct union of :PARTSNAMED(val), :PARTSTITLED(val), :PARTSTAGGED(val). The matching is done case-insensitively. For more information, see :ref:`ship parts and modules `. .. method:: Vessel:MODULESNAMED(name) :parameter name: (string) Name of the part modules :return: :struct:`List` of :struct:`PartModule` objects - match the given name. The matching is done case-insensitively. For more information, see `ship parts and modules <../../summary_topics/ship_parts_and_modules/index.html>`__ + match the given name. The matching is done case-insensitively. For more information, see :ref:`ship parts and modules `. .. method:: Vessel:PARTSINGROUP(group) :parameter group: (integer) the action group number :return: :struct:`List` of :struct:`Part` objects - one action triggered by the given action group. For more information, see `ship parts and modules <../../summary_topics/ship_parts_and_modules/index.html>`__ + one action triggered by the given action group. For more information, see :ref:`ship parts and modules `. .. method:: Vessel:MODULESINGROUP(group) :parameter group: (integer) the action group number :return: :struct:`List` of :struct:`PartModule` objects - have at least one action triggered by the given action group. For more information, see `ship parts and modules <../../summary_topics/ship_parts_and_modules/index.html>`__ + have at least one action triggered by the given action group. For more information, see :ref:`ship parts and modules `. .. method:: Vessel:ALLPARTSTAGGED() :return: :struct:`List` of :struct:`Part` objects - nametag on them of any sort that is nonblank. For more information, see `ship parts and modules <../../summary_topics/ship_parts_and_modules/index.html>`__ + nametag on them of any sort that is nonblank. For more information, see :ref:`ship parts and modules `. From 659bb11bb26b63f4b88ab945babde3c94ffa4f9f Mon Sep 17 00:00:00 2001 From: goblin Date: Tue, 30 Dec 2014 02:31:54 +0000 Subject: [PATCH 006/446] Fix case on one of the filenames --- src/kOS.Safe/kOS.Safe.csproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/kOS.Safe/kOS.Safe.csproj b/src/kOS.Safe/kOS.Safe.csproj index 405961995..aee4f09dd 100644 --- a/src/kOS.Safe/kOS.Safe.csproj +++ b/src/kOS.Safe/kOS.Safe.csproj @@ -59,7 +59,7 @@ - + @@ -159,4 +159,4 @@ --> - \ No newline at end of file + From e2d9c484a5ea38776ee82804f41436e5e67b4c49 Mon Sep 17 00:00:00 2001 From: goblin Date: Tue, 30 Dec 2014 13:51:05 +0000 Subject: [PATCH 007/446] rename Opcode to match the class's case also fixes a compilation problem on linux also reverts commit 659bb11bb26b63f4b88ab945babde3c94ffa4f9f. --- src/kOS.Safe/Compilation/{OpCode.cs => Opcode.cs} | 0 src/kOS.Safe/kOS.Safe.csproj | 4 ++-- 2 files changed, 2 insertions(+), 2 deletions(-) rename src/kOS.Safe/Compilation/{OpCode.cs => Opcode.cs} (100%) diff --git a/src/kOS.Safe/Compilation/OpCode.cs b/src/kOS.Safe/Compilation/Opcode.cs similarity index 100% rename from src/kOS.Safe/Compilation/OpCode.cs rename to src/kOS.Safe/Compilation/Opcode.cs diff --git a/src/kOS.Safe/kOS.Safe.csproj b/src/kOS.Safe/kOS.Safe.csproj index aee4f09dd..405961995 100644 --- a/src/kOS.Safe/kOS.Safe.csproj +++ b/src/kOS.Safe/kOS.Safe.csproj @@ -59,7 +59,7 @@ - + @@ -159,4 +159,4 @@ --> - + \ No newline at end of file From 1458ad3ee5e29aa76f3d259c292afe901dbe2be0 Mon Sep 17 00:00:00 2001 From: Chris Woerz Date: Tue, 30 Dec 2014 10:33:55 -0700 Subject: [PATCH 008/446] we are using the new extension methods everywhere now --- src/kOS/Suffixed/Part/PartValue.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kOS/Suffixed/Part/PartValue.cs b/src/kOS/Suffixed/Part/PartValue.cs index efa7cd22c..10716c5fd 100644 --- a/src/kOS/Suffixed/Part/PartValue.cs +++ b/src/kOS/Suffixed/Part/PartValue.cs @@ -44,7 +44,7 @@ private void PartInitializeSuffixes() AddSuffix("PARENT", new Suffix(() => PartValueFactory.Construct(Part.parent,shared), "The parent part of this part")); AddSuffix("HASPARENT", new Suffix(() => Part.parent != null, "Tells you if this part has a parent, is used to avoid null exception from PARENT")); AddSuffix("CHILDREN", new Suffix(() => PartValueFactory.Construct(Part.children, shared), "A LIST() of the children parts of this part")); - AddSuffix("DRYMASS", new Suffix(() => Part.HasPhysics() ? Part.mass : 0)); + AddSuffix("DRYMASS", new Suffix(Part.GetDryMass)); AddSuffix("MASS", new Suffix(Part.CalculateCurrentMass)); AddSuffix("WETMASS", new Suffix(Part.GetWetMass)); AddSuffix("HASPHYSICS", new Suffix(Part.HasPhysics)); From f34f13ee26358cfb01d8644a95788ae29c10470d Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Tue, 30 Dec 2014 11:38:03 -0600 Subject: [PATCH 009/446] Temp commit of first part of fixes to #461 --- src/kOS/Function/Suffixed.cs | 10 ++++++++++ src/kOS/kOS.csproj | 1 + 2 files changed, 11 insertions(+) diff --git a/src/kOS/Function/Suffixed.cs b/src/kOS/Function/Suffixed.cs index e92ce4756..a3511f83b 100644 --- a/src/kOS/Function/Suffixed.cs +++ b/src/kOS/Function/Suffixed.cs @@ -289,6 +289,16 @@ public override void Execute(SharedObjects shared) } } + [Function("career")] + public class FunctionCareer : FunctionBase + { + public override void Execute(SharedObjects shared) + { + var career = new Career(); + shared.Cpu.PushStack(career); + } + } + [Function("constant")] public class FunctionConstant : FunctionBase { diff --git a/src/kOS/kOS.csproj b/src/kOS/kOS.csproj index 128e66cd8..7e177d833 100644 --- a/src/kOS/kOS.csproj +++ b/src/kOS/kOS.csproj @@ -92,6 +92,7 @@ + From 7af6f2e239798276e0b8d1803a3270102f4cb146 Mon Sep 17 00:00:00 2001 From: Chris Woerz Date: Tue, 30 Dec 2014 10:44:58 -0700 Subject: [PATCH 010/446] added descriptions --- src/kOS/Suffixed/Part/PartValue.cs | 8 ++++---- src/kOS/Suffixed/VesselTarget.cs | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/kOS/Suffixed/Part/PartValue.cs b/src/kOS/Suffixed/Part/PartValue.cs index 10716c5fd..e406be9b1 100644 --- a/src/kOS/Suffixed/Part/PartValue.cs +++ b/src/kOS/Suffixed/Part/PartValue.cs @@ -44,10 +44,10 @@ private void PartInitializeSuffixes() AddSuffix("PARENT", new Suffix(() => PartValueFactory.Construct(Part.parent,shared), "The parent part of this part")); AddSuffix("HASPARENT", new Suffix(() => Part.parent != null, "Tells you if this part has a parent, is used to avoid null exception from PARENT")); AddSuffix("CHILDREN", new Suffix(() => PartValueFactory.Construct(Part.children, shared), "A LIST() of the children parts of this part")); - AddSuffix("DRYMASS", new Suffix(Part.GetDryMass)); - AddSuffix("MASS", new Suffix(Part.CalculateCurrentMass)); - AddSuffix("WETMASS", new Suffix(Part.GetWetMass)); - AddSuffix("HASPHYSICS", new Suffix(Part.HasPhysics)); + AddSuffix("DRYMASS", new Suffix(Part.GetDryMass, "The Part's mass when empty")); + AddSuffix("MASS", new Suffix(Part.CalculateCurrentMass, "The Part's current mass")); + AddSuffix("WETMASS", new Suffix(Part.GetWetMass, "The Part's mass when full")); + AddSuffix("HASPHYSICS", new Suffix(Part.HasPhysics, "Is this a strange 'massless' part")); } diff --git a/src/kOS/Suffixed/VesselTarget.cs b/src/kOS/Suffixed/VesselTarget.cs index 98e603bbc..3e46f3187 100644 --- a/src/kOS/Suffixed/VesselTarget.cs +++ b/src/kOS/Suffixed/VesselTarget.cs @@ -413,14 +413,14 @@ private void InitializeSuffixes() AddSuffix("VERTICALSPEED", new Suffix(() => Vessel.verticalSpeed)); AddSuffix("SURFACESPEED", new Suffix(() => Vessel.horizontalSrfSpeed)); AddSuffix("AIRSPEED", new Suffix(() => (Vessel.orbit.GetVel() - FlightGlobals.currentMainBody.getRFrmVel(Vessel.findWorldCenterOfMass())).magnitude,"the velocity of the vessel relative to the air")); - AddSuffix(new[] {"SHIPNAME", "NAME"}, new SetSuffix(() => Vessel.vesselName, RenameVessel)); - AddSuffix("TYPE", new SetSuffix(() => Vessel.vesselType.ToString(), RetypeVessel)); + AddSuffix(new[] {"SHIPNAME", "NAME"}, new SetSuffix(() => Vessel.vesselName, RenameVessel, "The KSP name for a craft, cannot be empty")); + AddSuffix("TYPE", new SetSuffix(() => Vessel.vesselType.ToString(), RetypeVessel, "The Ship's KSP type (e.g. rover, base, probe)")); AddSuffix("SENSORS", new Suffix(() => new VesselSensors(Vessel))); AddSuffix("TERMVELOCITY", new Suffix(() => VesselUtils.GetTerminalVelocity(Vessel))); AddSuffix("LOADED", new Suffix(() => Vessel.loaded)); AddSuffix("ROOTPART", new Suffix(() => PartValueFactory.Construct(Vessel.rootPart, Shared))); - AddSuffix("DRYMASS", new Suffix(() => Vessel.GetDryMass())); - AddSuffix("WETMASS", new Suffix(Vessel.GetWetMass)); + AddSuffix("DRYMASS", new Suffix(() => Vessel.GetDryMass(), "The Ship's mass when empty")); + AddSuffix("WETMASS", new Suffix(Vessel.GetWetMass, "The Ship's mass when full")); //// Although there is an implementation of lat/long/alt in Orbitible, //// it's better to use the methods for vessels that are faster if they're From 7cbb594a350416d3b42c3fbd04c13ee3f3bca0dc Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Tue, 30 Dec 2014 12:01:12 -0600 Subject: [PATCH 011/446] part masses from erendrake, minus some comments. --- src/kOS/Suffixed/VesselTarget.cs | 60 +++----------------------------- 1 file changed, 4 insertions(+), 56 deletions(-) diff --git a/src/kOS/Suffixed/VesselTarget.cs b/src/kOS/Suffixed/VesselTarget.cs index 3e46f3187..b7f751609 100644 --- a/src/kOS/Suffixed/VesselTarget.cs +++ b/src/kOS/Suffixed/VesselTarget.cs @@ -446,62 +446,10 @@ private void RenameVessel(string value) public override object GetSuffix(string suffixName) { - switch (suffixName) - { - // TODO: I left this code in commented to let the reviewer check my work for yank put mistakes, after that it should be removed - - //case "CONTROL": - // return FlightControlManager.GetControllerByVessel(Vessel); - //case "BEARING": - // return VesselUtils.GetTargetBearing(CurrentVessel, Vessel); - //case "HEADING": - // return VesselUtils.GetTargetHeading(CurrentVessel, Vessel); - //case "AVAILABLETHRUST": - // return VesselUtils.GetAvailableThrust(Vessel); - //case "MAXTHRUST": - // return VesselUtils.GetMaxThrust(Vessel); - //case "FACING": - // return VesselUtils.GetFacing(Vessel); - //case "ANGULARMOMENTUM": - // return new Vector(Vessel.angularMomentum); - //case "ANGULARVEL": - // return new Vector(Vessel.angularVelocity); - //case "MASS": - // return Vessel.GetTotalMass(); - //case "VERTICALSPEED": - // return Vessel.verticalSpeed; - //case "SURFACESPEED": - // return Vessel.horizontalSrfSpeed; - //case "AIRSPEED": - // return - // (Vessel.orbit.GetVel() - FlightGlobals.currentMainBody.getRFrmVel(Vessel.findWorldCenterOfMass())) - // .magnitude; //the velocity of the vessel relative to the air); - ////DEPRICATED VESSELNAME - //case "VESSELNAME": - // throw new KOSException("VESSELNAME is DEPRICATED, use SHIPNAME."); - //case "SHIPNAME": - // return Vessel.vesselName; - - //// Although there is an implementation of lat/long/alt in Orbitible, - //// it's better to use the methods for vessels that are faster if they're - //// available: - //case "LATITUDE": - // return VesselUtils.GetVesselLattitude(Vessel); - //case "LONGITUDE": - // return VesselUtils.GetVesselLongitude(Vessel); - //case "ALTITUDE": - // return Vessel.altitude; - - //case "SENSORS": - // return new VesselSensors(Vessel); - //case "TERMVELOCITY": - // return VesselUtils.GetTerminalVelocity(Vessel); - //case "LOADED": - // return Vessel.loaded; - //case "ROOTPART": - // return PartValueFactory.Construct(Vessel.rootPart,Shared); - } - + // Most suffixes are handled by the newer AddSuffix system, except for the + // resource levels, which have to use this older technique as a fallback because + // the AddSuffix system doesn't support this type of late-binding string matching: + // Is this a resource? double dblValue; if (VesselUtils.TryGetResource(Vessel, suffixName, out dblValue)) From 4f5c74fe0fe12120c80ec5c685b310aa6ca7bca5 Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Wed, 31 Dec 2014 00:03:10 -0600 Subject: [PATCH 012/446] Fixes #461 with new limit checks. --- doc/source/general/career_limits.rst | 113 ++++++++++++ .../Exceptions/KOSLowTechException.cs | 37 ++++ src/kOS.Safe/kOS.Safe.csproj | 1 + src/kOS/Module/KOSNameTag.cs | 12 ++ src/kOS/Suffixed/Career.cs | 173 ++++++++++++++++++ src/kOS/Suffixed/Node.cs | 9 + src/kOS/Suffixed/Orbitable.cs | 5 +- src/kOS/Suffixed/Part/PartModuleFields.cs | 5 + 8 files changed, 354 insertions(+), 1 deletion(-) create mode 100644 doc/source/general/career_limits.rst create mode 100644 src/kOS.Safe/Exceptions/KOSLowTechException.cs create mode 100644 src/kOS/Suffixed/Career.cs diff --git a/doc/source/general/career_limits.rst b/doc/source/general/career_limits.rst new file mode 100644 index 000000000..3f9274d42 --- /dev/null +++ b/doc/source/general/career_limits.rst @@ -0,0 +1,113 @@ +.. _career_limits: + + +Career Limits +============= + +The theme of KSP 0.90 is that some features of your space program don't work until after you've made some upgrades. +kOS now supports enforcing these checks, as described below. + +.. contents:: + :local: + :depth: 2 + +.. warning:: + + .. These limitation enforcements do not exist in versions of kOS prior to kOS 0.15.4 + +The rules being enforced +------------------------ + +These are rules inherited from the stock KSP game that kOS is simply adhering to: + +- If your tracking center is not upgraded far enough, then you cannot see + future orbit patches. + +- If your mission control center AND tracking center are not upgraded enough, + then you cannot add manuever nodes. + +The following are rules invented by kOS that are thematically very similar to stock KSP, intended to be as close to the meaning of the stock game's rules as possible: + +- In order to be allowed to execute the :struct:`PartModule` :DOACTION method, either + your VAB or your SPH must be upgraded to the point where it will allow access to + custom action groups. This is because otherwise the :DOACTION method would be a + backdoor "cheat" past the restricted access to the action group feaures of various + PartModules that the game is meant to have. + +- In order to be allowed to add a ``nametag`` to parts inside the editor so they get + saved to the craft file, you must have upgraded your current editor building (VAB or + SPH, depending) to the point where it allows at least stock action groups. This is + because name tags are a sort of semi-advanced feature. + +You can see some of these settings by reading the values of the Career() global object, +for example: + +:: + print Career():PATCHLIMIT. + print Career():CANDOACTIONS. + +Structure +--------- + +.. structure:: Career + + .. list-table:: **Members** + :widths: 4 2 1 1 + :header-rows: 1 + + * - Suffix + - Type + - Get + - Set + + * - :attr:`CANTRACKOBJECTS` + - boolean + - yes + - no + * - :attr:`PATCHLIMIT` + - number + - yes + - no + * - :attr:`CANMAKENODES` + - boolean + - yes + - no + * - :attr:`CANDOACTIONS` + - boolean + - yes + - no + +.. attribute:: Career:CANTRACKOBJECTS + + :type: boolean + :access: Get + + If your tracking center allows the tracking of unnamed objects (asteroids, mainly) then this will return true. + +.. attribute:: Career:PATCHLIMIT + + :type: number + :access: Get + + If your tracking center allows some patched conics predictions, then this number will be greater than zero. + The number represents how many patches beyond the current one that you are allowed to see. It influences + attempts to call SHIP:PATCHES and SHIP:OBT:NEXTPATCH. + +.. attribute:: Career:CANMAKENODES + + :type: boolean + :access: Get + + If your tracking center and mission control buildings are both upgraded enough, then the game allows + you to make manuever nodes (which the game calls "flight planning"). This will return true if you + can make maneuver nodes. + +.. attribute:: Career:CANDOACTIONS + + :type: boolean + :access: Get + + If your VAB or SPH are upgraded enough to allow custom action groups, then you will also be allowed + to execute the :DOACTION method of PartModules. Otherwise you can't. This will return a boolean + letting you know if the condition has been met. + diff --git a/src/kOS.Safe/Exceptions/KOSLowTechException.cs b/src/kOS.Safe/Exceptions/KOSLowTechException.cs new file mode 100644 index 000000000..b07c4165a --- /dev/null +++ b/src/kOS.Safe/Exceptions/KOSLowTechException.cs @@ -0,0 +1,37 @@ +using System; + +namespace kOS.Safe.Exceptions +{ + public class KOSLowTechException : KOSException + { + public override string HelpURL + { + get { /*TODO:*/ return "TODO - need to write docs about this feature and put URL here"; } + } + + private const string terseMessageFmt = "You need a better {0} in order to {1}."; + + public override string VerboseMessage + { + get + { + return base.Message + "\n" + + "This requirement was added in order to make kOS thematically fit the new career paradigm first introduced by KSP 0.90."; + } + } + + /// + /// A KOSException to be thrown whenever the tech level of either + /// the kOS CPU part or an upgradable career building isn't good enough to allow + /// the feature that the script is trying to use. + ///

+ /// TODO: Replace this with a mere warning if and when warnings get implemented later. + ///
+ /// string describing what kOS feature is being disallowed. Phrase it as a verb. + /// string describing what thing is too low-tech to allow the feature. Phrase it as a noun. + public KOSLowTechException(string feature, string thingToUpgrade) : + base(String.Format(terseMessageFmt, thingToUpgrade, feature)) + { + } + } +} \ No newline at end of file diff --git a/src/kOS.Safe/kOS.Safe.csproj b/src/kOS.Safe/kOS.Safe.csproj index 4ab43bcf3..fd2aa3b75 100644 --- a/src/kOS.Safe/kOS.Safe.csproj +++ b/src/kOS.Safe/kOS.Safe.csproj @@ -89,6 +89,7 @@ + diff --git a/src/kOS/Module/KOSNameTag.cs b/src/kOS/Module/KOSNameTag.cs index fe1d36ffe..dca63e8ad 100644 --- a/src/kOS/Module/KOSNameTag.cs +++ b/src/kOS/Module/KOSNameTag.cs @@ -1,4 +1,5 @@ using kOS.Screen; +using kOS.Suffixed; using UnityEngine; namespace kOS.Module @@ -20,6 +21,17 @@ public void PopupNameTagChanger() { if (typingWindow != null) typingWindow.Close(); + if (HighLogic.LoadedSceneIsEditor) + { + EditorFacility whichEditor = EditorLogic.fetch.ship.shipFacility; + if (!(Career.CanTagInEditor(whichEditor))) + { + ScreenMessages.PostScreenMessage("The "+whichEditor.ToString()+" requires an upgrade to assign name tags", + 6, + ScreenMessageStyle.UPPER_CENTER); + return; + } + } GameObject gObj = new GameObject("nametag", typeof(KOSNameTagWindow) ); DontDestroyOnLoad(gObj); typingWindow = (KOSNameTagWindow)gObj.GetComponent(typeof(KOSNameTagWindow)); diff --git a/src/kOS/Suffixed/Career.cs b/src/kOS/Suffixed/Career.cs new file mode 100644 index 000000000..8894c9492 --- /dev/null +++ b/src/kOS/Suffixed/Career.cs @@ -0,0 +1,173 @@ +using System; +using kOS.Safe.Encapsulation.Suffixes; +using kOS.Safe.Encapsulation; + +namespace kOS.Suffixed +{ + public class Career : Structure + { + static Career() + { + AddGlobalSuffix("CANTRACKOBJECTS", new StaticSuffix(() => CanTrackObjects(), + "Can the Tracking Center track small space objects (asteroids)?")); + AddGlobalSuffix("PATCHLIMIT", new StaticSuffix(() => PatchLimit(), + "The Tracking Center's orbit patch prediction limit (an integer)")); + AddGlobalSuffix("CANMAKENODES", new StaticSuffix(() => CanMakeNodes(), + "Can the Mission Control support maneuver nodes yet?")); + AddGlobalSuffix("CANDOACTIONS", new StaticSuffix(() => CanDoActions(), + "Can either the VAB or SPH allow custom action groups? " + + "If either one allows it, then you are allowed to call " + + "the :DOACTION suffix of a PartModule." )); + } + + /// + /// Detect whether or not you can track small space objects like asteroids yet. + /// + /// returns a string describing what would need upgrading to change the answer. + /// true if you can. false if you cannot. + public static bool CanTrackObjects(out string reason) + { + reason = "tracking station building"; + float building_level = ScenarioUpgradeableFacilities.GetFacilityLevel(SpaceCenterFacility.TrackingStation); + return GameVariables.Instance.UnlockedSpaceObjectDiscovery(building_level); + + // TODO: This isn't really being used anywhere yet because it's supposed to apply to the ability to track + // and name asteroids. So far I don't know yet where that would be used in kOS. I guess it might be + // checked if you try to make a Vessel() wrapper around an asteroid? (are Asteroids Vessels? I think they + // are?) The UI will already prevent you from doing a SET TARGET TO if your tech isn't right for it. + } + + /// + /// Same as CanTrackObjects, but without the 'reason' parameter. (This is a separate method + /// only because you can't default out parameters like 'out string reason' to make them optional.) + /// + /// true if you can. false if you cannot. + public static bool CanTrackObjects() + { + string dummy; + return CanTrackObjects(out dummy); + } + + /// + /// Detect how good the tracking center is at seeing future SOI transfers (encounters, escapes, etc). + /// + /// returns a string describing what would need upgrading to change the answer. + /// Maximum number of patches that can be predicted ahead (not including the current one). + public static int PatchLimit(out string reason) + { + reason = "tracking station building"; + float building_level = ScenarioUpgradeableFacilities.GetFacilityLevel(SpaceCenterFacility.TrackingStation); + return GameVariables.Instance.GetPatchesAheadLimit(building_level); + } + + /// + /// Same as PatchLImit, but without the 'reason' parameter. (This is a separate method + /// only because you can't default out parameters like 'out string reason' to make them optional.) + /// + /// max number of patches ahead (not including the current one). + public static int PatchLimit() + { + string dummy; + return PatchLimit(out dummy); + } + + /// + /// Detect whether mission control is capable of manuever node creation yet. + /// + /// returns a string describing what would need upgrading to change the answer. + /// true if it can. false if it cannot. + public static bool CanMakeNodes(out string reason) + { + // This one is a weird check. It requires TWO building conditions, as far as I can tell: + reason = "mission control building"; + float building_level = ScenarioUpgradeableFacilities.GetFacilityLevel(SpaceCenterFacility.MissionControl); + if (! GameVariables.Instance.UnlockedFlightPlanning(building_level)) + return false; + return (PatchLimit(out reason) > 0); // if the tracking center isn't good enough then that ALSO prevents manuever nodes. + } + + /// + /// Same as CanMakeNodes, but without the 'reason' parameter. (This is a separate method + /// only because you can't default out parameters like 'out string reason' to make them optional.) + /// + /// true if you can. false if you cannot. + public static bool CanMakeNodes() + { + string dummy; + return CanMakeNodes(out dummy); + } + + /// + /// Detect whether we'll allow arbitrary use of :DOACTION from partmodules, which + /// depends on whether at least one of the editors (VAB,SPH) allows custom action groups: + /// + /// returns a string describing what would need upgrading to change the answer. + /// true if it can. false if it cannot. + public static bool CanDoActions(out string reason) + { + reason = "vehicle assembly building or spaceplane hangar"; + float building_level = Math.Max(ScenarioUpgradeableFacilities.GetFacilityLevel(SpaceCenterFacility.VehicleAssemblyBuilding), + ScenarioUpgradeableFacilities.GetFacilityLevel(SpaceCenterFacility.SpaceplaneHangar)); + return GameVariables.Instance.UnlockedActionGroupsCustom(building_level); + } + + /// + /// Same as CanDoActions, but without the 'reason' parameter. (This is a separate method + /// only because you can't default out parameters like 'out string reason' to make them optional.) + /// + /// true if you can. false if you cannot. + public static bool CanDoActions() + { + string dummy; + return CanDoActions(out dummy); + } + + /// + /// Detect whether we'll allow you to add a NameTag to a part during the editor. + /// You can always add one post-editor during flight, but during editing it will + /// depend on building level.
+ /// NOTE: This method does NOT have an associated suffix because it is meant to be called + /// from inside the editor, when a script won't be running. + ///
+ /// Pass in whether you are checking from the VAB or SPH. + /// returns a string describing what would need upgrading to change the answer. + /// true if it can. false if it cannot. + public static bool CanTagInEditor(EditorFacility whichEditor, out string reason) + { + float building_level; + switch (whichEditor) + { + case EditorFacility.VAB: + reason = "vehicle assembly building"; + building_level = ScenarioUpgradeableFacilities.GetFacilityLevel(SpaceCenterFacility.VehicleAssemblyBuilding); + break; + case EditorFacility.SPH: + reason = "spaceplane hangar"; + building_level = ScenarioUpgradeableFacilities.GetFacilityLevel(SpaceCenterFacility.SpaceplaneHangar); + break; + default: + reason = "unknown editor building"; + return false; // not even sure how you could get here. + } + // We'll attach it to the same point where the game starts unlocking basic action groups: + return GameVariables.Instance.UnlockedActionGroupsStock(building_level); + } + + /// + /// Same as CanTagInEditor, but without the 'reason' parameter. (This is a separate method + /// only because you can't default out parameters like 'out string reason' to make them optional.) + /// + /// true if you can. false if you cannot. + public static bool CanTagInEditor(EditorFacility whichEditor) + { + string dummy; + return CanTagInEditor(whichEditor, out dummy); + } + + public override string ToString() + { + return string.Format("{0} Career", base.ToString()); + } + } + +} \ No newline at end of file diff --git a/src/kOS/Suffixed/Node.cs b/src/kOS/Suffixed/Node.cs index 4a29acb57..784515890 100644 --- a/src/kOS/Suffixed/Node.cs +++ b/src/kOS/Suffixed/Node.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using kOS.Safe.Encapsulation; +using kOS.Safe.Exceptions; namespace kOS.Suffixed { @@ -55,6 +56,10 @@ public void AddToVessel(Vessel v) { if (nodeRef != null) throw new Exception("Node has already been added"); + string careerReason; + if (! Career.CanMakeNodes(out careerReason)) + throw new KOSLowTechException("use manuever nodes", careerReason); + vesselRef = v; nodeRef = v.patchedConicSolver.AddManeuverNode(time); @@ -140,6 +145,10 @@ public void Remove() { if (nodeRef == null) return; + string careerReason; + if (! Career.CanMakeNodes(out careerReason)) + throw new KOSLowTechException("use manuever nodes", careerReason); + nodeLookup.Remove(nodeRef); vesselRef.patchedConicSolver.RemoveManeuverNode(nodeRef); diff --git a/src/kOS/Suffixed/Orbitable.cs b/src/kOS/Suffixed/Orbitable.cs index d9a0c3821..e62cf9ecf 100644 --- a/src/kOS/Suffixed/Orbitable.cs +++ b/src/kOS/Suffixed/Orbitable.cs @@ -207,7 +207,9 @@ private object BuildPatchList() { var list = new ListValue(); var orb = Orbit; - while (true) + int index = 0; + int highestAllowedIndex = Career.PatchLimit(); + while (index <= highestAllowedIndex) { if (orb == null || (!orb.activePatch)) { @@ -216,6 +218,7 @@ private object BuildPatchList() list.Add(new OrbitInfo(orb, Shared)); orb = orb.nextPatch; + ++index; } return list; } diff --git a/src/kOS/Suffixed/Part/PartModuleFields.cs b/src/kOS/Suffixed/Part/PartModuleFields.cs index 3b50e5fd5..9ae90b491 100644 --- a/src/kOS/Suffixed/Part/PartModuleFields.cs +++ b/src/kOS/Suffixed/Part/PartModuleFields.cs @@ -444,6 +444,8 @@ private void CallKSPEvent(string suffixName) /// Trigger whatever action the PartModule has attached to this Action, given the kOS name for the action. /// Warning - it probably triggers the entire action group that is attached to this action if there is one, /// not just the action on this one part. + ///

+ /// NOTE: After kOS 0.15.5, this ability is limited by career progress of the VAB/SPH. /// /// /// true = activate, false = de-activate @@ -452,6 +454,9 @@ private void CallKSPAction(string suffixName, bool param) BaseAction act = GetAction(suffixName); if (act==null) throw new KOSLookupFailException( "ACTION", suffixName, this); + string careerReason; + if (! Career.CanDoActions(out careerReason)) + throw new KOSLowTechException("use :DOACTION", careerReason); act.Invoke( new KSPActionParam( act.actionGroup, (param ? KSPActionType.Activate : KSPActionType.Deactivate) )); } } From b10954080fd069d0284c523d4e851982ad74975c Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Wed, 31 Dec 2014 15:15:56 -0600 Subject: [PATCH 013/446] Require tech for positionat() and velocityat(). Using the prediction functions on vessels should require the same tech level as one needs for maneuver nodes. I decided that it's okay to get the position of Bodies without the tech, but not the position of Vessels, which is why the check is only in VesselTarget and not on all Orbitables. My rationale for this is that presumably the position of known celestial bodies would be a matter of looking up data gathered centuries ago before the space age even began. Whomever the Kerbal equivalent of Kepler is would have already worked it out ages ago. And, Celestial bodies don't perform manuevers so their predictions were set in stone for some time. --- src/kOS/Suffixed/VesselTarget.cs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/kOS/Suffixed/VesselTarget.cs b/src/kOS/Suffixed/VesselTarget.cs index b7f751609..af3fbe867 100644 --- a/src/kOS/Suffixed/VesselTarget.cs +++ b/src/kOS/Suffixed/VesselTarget.cs @@ -3,6 +3,7 @@ using kOS.Binding; using kOS.Safe.Encapsulation; using kOS.Safe.Encapsulation.Suffixes; +using kOS.Safe.Exceptions; using kOS.Safe.Utilities; using kOS.Suffixed.Part; using kOS.Utilities; @@ -42,6 +43,10 @@ override public OrbitableVelocity GetVelocities() /// The position as a user-readable Vector in Shared.Vessel-origin raw rotation coordinates. override public Vector GetPositionAtUT(TimeSpan timeStamp) { + string blockingTech; + if (! Career.CanMakeNodes(out blockingTech)) + throw new KOSLowTechException("use POSITIONAT on a vessel", blockingTech); + double desiredUT = timeStamp.ToUnixStyleTime(); Orbit patch = GetOrbitAtUT( desiredUT ); @@ -76,6 +81,10 @@ override public Vector GetPositionAtUT(TimeSpan timeStamp) /// The orbit/surface velocity pair as a user-readable Vector in raw rotation coordinates. override public OrbitableVelocity GetVelocitiesAtUT(TimeSpan timeStamp) { + string blockingTech; + if (! Career.CanMakeNodes(out blockingTech)) + throw new KOSLowTechException("use VELOCITYAT on a vessel", blockingTech); + double desiredUT = timeStamp.ToUnixStyleTime(); Orbit patch = GetOrbitAtUT( desiredUT ); From 0c9f77a16c010e1a41ed1da2485538d277e4bb00 Mon Sep 17 00:00:00 2001 From: Chris Woerz Date: Wed, 31 Dec 2014 09:27:04 -0700 Subject: [PATCH 014/446] fixed warning from skin creation and make sure that MM shows us with the correct version --- src/kOS/Properties/AssemblyInfo.cs | 2 +- src/kOS/Screen/KOSToolBarWindow.cs | 49 ++++++++++++++-------------- src/kOS/Utilities/Utils.cs | 52 +++++++++++++++--------------- 3 files changed, 51 insertions(+), 52 deletions(-) diff --git a/src/kOS/Properties/AssemblyInfo.cs b/src/kOS/Properties/AssemblyInfo.cs index c70ca20ff..76d4c01e5 100644 --- a/src/kOS/Properties/AssemblyInfo.cs +++ b/src/kOS/Properties/AssemblyInfo.cs @@ -32,6 +32,6 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] [assembly: AssemblyFileVersion("0.15.4.0")] +[assembly: AssemblyVersion("0.15.4.0")] [assembly: KSPAssembly("kOS", 0, 15)] \ No newline at end of file diff --git a/src/kOS/Screen/KOSToolBarWindow.cs b/src/kOS/Screen/KOSToolBarWindow.cs index 67d15bdd5..0ac3dce0e 100644 --- a/src/kOS/Screen/KOSToolBarWindow.cs +++ b/src/kOS/Screen/KOSToolBarWindow.cs @@ -1,6 +1,5 @@ using System; using System.Linq; -using kOS.Safe.Utilities; using UnityEngine; using kOS.Utilities; using kOS.Suffixed; @@ -96,7 +95,7 @@ public class KOSToolBarWindow : MonoBehaviour public KOSToolBarWindow() { // This really needs fixing - the name ambiguity between UnityEngine's Debug and ours forces this long fully qualified name: - kOS.Safe.Utilities.Debug.Logger.SuperVerbose("KOSToolbarWindow: PROOF that constructor was called."); + Safe.Utilities.Debug.Logger.SuperVerbose("KOSToolbarWindow: PROOF that constructor was called."); launcherButtonTexture = new Texture2D(0, 0, TextureFormat.DXT1, false); terminalClosedIconTexture = new Texture2D(0, 0, TextureFormat.DXT1, false); terminalOpenIconTexture = new Texture2D(0, 0, TextureFormat.DXT1, false); @@ -110,7 +109,7 @@ public void FirstTimeSetup() { ++countInstances; myInstanceNum = countInstances; - kOS.Safe.Utilities.Debug.Logger.SuperVerbose("KOSToolBarWindow: Now making instance number "+myInstanceNum+" of KOSToolBarWindow"); + Safe.Utilities.Debug.Logger.SuperVerbose("KOSToolBarWindow: Now making instance number "+myInstanceNum+" of KOSToolBarWindow"); const string LAUNCHER_BUTTON_PNG = "GameData/kOS/GFX/launcher-button.png"; const string TERMINAL_OPEN_ICON_PNG = "GameData/kOS/GFX/terminal-icon-open.png"; @@ -135,7 +134,7 @@ public void FirstTimeSetup() public void Start() { - kOS.Safe.Utilities.Debug.Logger.SuperVerbose("KOSToolbarWindow: PROOF that Start() was called."); + Safe.Utilities.Debug.Logger.SuperVerbose("KOSToolbarWindow: PROOF that Start() was called."); // Prevent multiple calls of this: if (alreadyAwake) return; alreadyAwake = true; @@ -145,7 +144,7 @@ public void Start() public void RunWhenReady() { - kOS.Safe.Utilities.Debug.Logger.SuperVerbose("KOSToolBarWindow: Instance number " + myInstanceNum + " is trying to ready the hooks"); + Safe.Utilities.Debug.Logger.SuperVerbose("KOSToolBarWindow: Instance number " + myInstanceNum + " is trying to ready the hooks"); // KSP claims the hook ApplicationLauncherReady.Add will not run until // the application is ready, even though this is emphatically false. It actually // fires the event a few times before the one that "sticks" and works: @@ -154,7 +153,7 @@ public void RunWhenReady() thisInstanceHasHooks = true; someInstanceHasHooks = true; - kOS.Safe.Utilities.Debug.Logger.SuperVerbose("KOSToolBarWindow: Instance number " + myInstanceNum + " will now actually make its hooks"); + Safe.Utilities.Debug.Logger.SuperVerbose("KOSToolBarWindow: Instance number " + myInstanceNum + " will now actually make its hooks"); ApplicationLauncher launcher = ApplicationLauncher.Instance; launcherButton = launcher.AddModApplication( @@ -174,10 +173,10 @@ public void RunWhenReady() public void GoAway() { - kOS.Safe.Utilities.Debug.Logger.SuperVerbose("KOSToolBarWindow: PROOF: Instance " + myInstanceNum + " is in GoAway()."); + Safe.Utilities.Debug.Logger.SuperVerbose("KOSToolBarWindow: PROOF: Instance " + myInstanceNum + " is in GoAway()."); if (thisInstanceHasHooks) { - kOS.Safe.Utilities.Debug.Logger.SuperVerbose("KOSToolBarWindow: PROOF: Instance " + myInstanceNum + " has hooks and is entering the guts of GoAway()."); + Safe.Utilities.Debug.Logger.SuperVerbose("KOSToolBarWindow: PROOF: Instance " + myInstanceNum + " has hooks and is entering the guts of GoAway()."); if (isOpen) Close(); clickedOn = false; thisInstanceHasHooks = false; @@ -202,7 +201,7 @@ public void OnDestroy() /// Callback for when the button is toggled on public void CallbackOnTrue() { - kOS.Safe.Utilities.Debug.Logger.SuperVerbose("KOSToolBarWindow: PROOF: CallbackOnTrue()"); + Safe.Utilities.Debug.Logger.SuperVerbose("KOSToolBarWindow: PROOF: CallbackOnTrue()"); clickedOn = true; Open(); } @@ -210,7 +209,7 @@ public void CallbackOnTrue() /// Callback for when the button is toggled off public void CallbackOnFalse() { - kOS.Safe.Utilities.Debug.Logger.SuperVerbose("KOSToolBarWindow: PROOF: CallbackOnFalse()"); + Safe.Utilities.Debug.Logger.SuperVerbose("KOSToolBarWindow: PROOF: CallbackOnFalse()"); clickedOn = false; Close(); } @@ -218,7 +217,7 @@ public void CallbackOnFalse() /// Callback for when the mouse is hovering over the button public void CallbackOnHover() { - kOS.Safe.Utilities.Debug.Logger.SuperVerbose("KOSToolBarWindow: PROOF: CallbackOnHover()"); + Safe.Utilities.Debug.Logger.SuperVerbose("KOSToolBarWindow: PROOF: CallbackOnHover()"); if (!clickedOn) Open(); } @@ -226,7 +225,7 @@ public void CallbackOnHover() /// Callback for when the mouse is hover is off the button public void CallbackOnHoverOut() { - kOS.Safe.Utilities.Debug.Logger.SuperVerbose("KOSToolBarWindow: PROOF: CallbackOnHoverOut()"); + Safe.Utilities.Debug.Logger.SuperVerbose("KOSToolBarWindow: PROOF: CallbackOnHoverOut()"); if (!clickedOn) Close(); } @@ -234,7 +233,7 @@ public void CallbackOnHoverOut() /// Callback for when the mouse is hovering over the button public void CallbackOnShow() { - kOS.Safe.Utilities.Debug.Logger.SuperVerbose("KOSToolBarWindow: PROOF: CallbackOnShow()"); + Safe.Utilities.Debug.Logger.SuperVerbose("KOSToolBarWindow: PROOF: CallbackOnShow()"); if (!clickedOn && !isOpen) Open(); } @@ -242,7 +241,7 @@ public void CallbackOnShow() /// Callback for when the mouse is hover is off the button public void CallbackOnHide() { - kOS.Safe.Utilities.Debug.Logger.SuperVerbose("KOSToolBarWindow: PROOF: CallbackOnHide()"); + Safe.Utilities.Debug.Logger.SuperVerbose("KOSToolBarWindow: PROOF: CallbackOnHide()"); if (!clickedOn && isOpen) { Close(); @@ -252,7 +251,7 @@ public void CallbackOnHide() public void Open() { - kOS.Safe.Utilities.Debug.Logger.SuperVerbose("KOSToolBarWindow: PROOF: Open()"); + Safe.Utilities.Debug.Logger.SuperVerbose("KOSToolBarWindow: PROOF: Open()"); bool isTop = ApplicationLauncher.Instance.IsPositionedAtTop; @@ -266,14 +265,14 @@ public void Open() float topEdge = isTop ? (40f) : (UnityEngine.Screen.height - (height+40) ); windowRect = new Rect(leftEdge, topEdge, 0, 0); // will resize upon first GUILayout-ing. - kOS.Safe.Utilities.Debug.Logger.SuperVerbose("KOSToolBarWindow: PROOF: Open(), windowRect = " + windowRect); + Safe.Utilities.Debug.Logger.SuperVerbose("KOSToolBarWindow: PROOF: Open(), windowRect = " + windowRect); isOpen = true; } public void Close() { - kOS.Safe.Utilities.Debug.Logger.SuperVerbose("KOSToolBarWindow: PROOF: Close()"); + Safe.Utilities.Debug.Logger.SuperVerbose("KOSToolBarWindow: PROOF: Close()"); if (! isOpen) return; @@ -283,14 +282,14 @@ public void Close() /// Callback for when the button is shown or enabled by the application launcher public void CallbackOnEnable() { - kOS.Safe.Utilities.Debug.Logger.SuperVerbose("KOSToolBarWindow: PROOF: CallbackOnEnable()"); + Safe.Utilities.Debug.Logger.SuperVerbose("KOSToolBarWindow: PROOF: CallbackOnEnable()"); // do nothing, but leaving the hook here as a way to document "this thing exists and might be used". } /// Callback for when the button is hidden or disabled by the application launcher public void CallbackOnDisable() { - kOS.Safe.Utilities.Debug.Logger.SuperVerbose("KOSToolBarWindow: PROOF: CallbackOnDisable()"); + Safe.Utilities.Debug.Logger.SuperVerbose("KOSToolBarWindow: PROOF: CallbackOnDisable()"); // do nothing, but leaving the hook here as a way to document "this thing exists and might be used". } @@ -302,7 +301,7 @@ public void OnGUI() if (!onGUICalledThisInstance) // I want proof it was called, but without spamming the log: { - kOS.Safe.Utilities.Debug.Logger.SuperVerbose("KOSToolBarWindow: PROOF: OnGUI() was called at least once on instance number " + myInstanceNum); + Safe.Utilities.Debug.Logger.SuperVerbose("KOSToolBarWindow: PROOF: OnGUI() was called at least once on instance number " + myInstanceNum); onGUICalledThisInstance = true; } @@ -310,7 +309,7 @@ public void OnGUI() if (!onGUIWasOpenThisInstance) // I want proof it was called, but without spamming the log: { - kOS.Safe.Utilities.Debug.Logger.SuperVerbose("KOSToolBarWindow: PROOF: OnGUI() was called while the window was supposed to be open at least once on instance number " + myInstanceNum); + Safe.Utilities.Debug.Logger.SuperVerbose("KOSToolBarWindow: PROOF: OnGUI() was called while the window was supposed to be open at least once on instance number " + myInstanceNum); onGUIWasOpenThisInstance = true; } @@ -551,7 +550,7 @@ public void CheckHoverOnPreviousGUIElement(Part part) private void CountBeginVertical(string debugHelp="") { if (! String.IsNullOrEmpty(debugHelp)) - kOS.Safe.Utilities.Debug.Logger.SuperVerbose("BeginVertical(\""+debugHelp+"\") Nest "+verticalSectionCount); + Safe.Utilities.Debug.Logger.SuperVerbose("BeginVertical(\""+debugHelp+"\") Nest "+verticalSectionCount); GUILayout.BeginVertical(); ++verticalSectionCount; } @@ -564,7 +563,7 @@ private void CountEndVertical(string debugHelp="") GUILayout.EndVertical(); --verticalSectionCount; if (! String.IsNullOrEmpty(debugHelp)) - kOS.Safe.Utilities.Debug.Logger.SuperVerbose("EndVertical(\""+debugHelp+"\") Nest "+verticalSectionCount); + Safe.Utilities.Debug.Logger.SuperVerbose("EndVertical(\""+debugHelp+"\") Nest "+verticalSectionCount); } // Tracking the count to help detect when there's a mismatch: @@ -573,7 +572,7 @@ private void CountEndVertical(string debugHelp="") private void CountBeginHorizontal(string debugHelp="") { if (! String.IsNullOrEmpty(debugHelp)) - kOS.Safe.Utilities.Debug.Logger.SuperVerbose("BeginHorizontal(\""+debugHelp+"\"): Nest "+horizontalSectionCount); + Safe.Utilities.Debug.Logger.SuperVerbose("BeginHorizontal(\""+debugHelp+"\"): Nest "+horizontalSectionCount); GUILayout.BeginHorizontal(); ++horizontalSectionCount; } @@ -586,7 +585,7 @@ private void CountEndHorizontal(string debugHelp="") GUILayout.EndHorizontal(); --horizontalSectionCount; if (! String.IsNullOrEmpty(debugHelp)) - kOS.Safe.Utilities.Debug.Logger.SuperVerbose("EndHorizontal(\""+debugHelp+"\"): Nest "+horizontalSectionCount); + Safe.Utilities.Debug.Logger.SuperVerbose("EndHorizontal(\""+debugHelp+"\"): Nest "+horizontalSectionCount); } diff --git a/src/kOS/Utilities/Utils.cs b/src/kOS/Utilities/Utils.cs index c337cf75f..c09f0478b 100644 --- a/src/kOS/Utilities/Utils.cs +++ b/src/kOS/Utilities/Utils.cs @@ -202,32 +202,32 @@ public static GUISkin GetSkinCopy(GUISkin toCopy) // causes this next block of code. It's starting off theSkin as a deep // copy of HighLogic.Skin, at least as much as it can: // - return new GUISkin - { - // This is literally every GUISTyle mentioned in Unity's documention for - // GUISkin, as of 11/11/2014. If Unity updates these, we could be screwed: - // - box = new GUIStyle(toCopy.box), - button = new GUIStyle(toCopy.button), - horizontalScrollbar = new GUIStyle(toCopy.horizontalScrollbar), - horizontalScrollbarLeftButton = new GUIStyle(toCopy.horizontalScrollbarLeftButton), - horizontalScrollbarRightButton = new GUIStyle(toCopy.horizontalScrollbarRightButton), - horizontalScrollbarThumb = new GUIStyle(toCopy.horizontalScrollbarThumb), - horizontalSlider = new GUIStyle(toCopy.horizontalSlider), - horizontalSliderThumb = new GUIStyle(toCopy.horizontalSliderThumb), - label = new GUIStyle(toCopy.label), - scrollView = new GUIStyle(toCopy.scrollView), - textArea = new GUIStyle(toCopy.textArea), - textField = new GUIStyle(toCopy.textField), - toggle = new GUIStyle(toCopy.toggle), - verticalScrollbar = new GUIStyle(toCopy.verticalScrollbar), - verticalScrollbarDownButton = new GUIStyle(toCopy.verticalScrollbarDownButton), - verticalScrollbarThumb = new GUIStyle(toCopy.verticalScrollbarThumb), - verticalScrollbarUpButton = new GUIStyle(toCopy.verticalScrollbarUpButton), - verticalSlider = new GUIStyle(toCopy.verticalSlider), - verticalSliderThumb = new GUIStyle(toCopy.verticalSliderThumb), - window = new GUIStyle(toCopy.window), - }; + var skin = ScriptableObject.CreateInstance(); + + // This is literally every GUISTyle mentioned in Unity's documention for + // GUISkin, as of 11/11/2014. If Unity updates these, we could be screwed: + // + skin.box = new GUIStyle(toCopy.box); + skin.button = new GUIStyle(toCopy.button); + skin.horizontalScrollbar = new GUIStyle(toCopy.horizontalScrollbar); + skin.horizontalScrollbarLeftButton = new GUIStyle(toCopy.horizontalScrollbarLeftButton); + skin.horizontalScrollbarRightButton = new GUIStyle(toCopy.horizontalScrollbarRightButton); + skin.horizontalScrollbarThumb = new GUIStyle(toCopy.horizontalScrollbarThumb); + skin.horizontalSlider = new GUIStyle(toCopy.horizontalSlider); + skin.horizontalSliderThumb = new GUIStyle(toCopy.horizontalSliderThumb); + skin.label = new GUIStyle(toCopy.label); + skin.scrollView = new GUIStyle(toCopy.scrollView); + skin.textArea = new GUIStyle(toCopy.textArea); + skin.textField = new GUIStyle(toCopy.textField); + skin.toggle = new GUIStyle(toCopy.toggle); + skin.verticalScrollbar = new GUIStyle(toCopy.verticalScrollbar); + skin.verticalScrollbarDownButton = new GUIStyle(toCopy.verticalScrollbarDownButton); + skin.verticalScrollbarThumb = new GUIStyle(toCopy.verticalScrollbarThumb); + skin.verticalScrollbarUpButton = new GUIStyle(toCopy.verticalScrollbarUpButton); + skin.verticalSlider = new GUIStyle(toCopy.verticalSlider); + skin.verticalSliderThumb = new GUIStyle(toCopy.verticalSliderThumb); + skin.window = new GUIStyle(toCopy.window); + return skin; } /// From 50d98c03268d33d7f64c8a9e3821b377bdb131ff Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Wed, 31 Dec 2014 21:04:13 -0600 Subject: [PATCH 015/446] fixed #458 - you can now "tail -f" on LOG output. As long as the log file is on the Archive and is therefore a real file and not just a string in memory, the LOG command will now append lines of text to the end of the file without erasing and re-writing the whole file on each line like it used to. This means the unix (or gitbash) "tail -f" command now works properly on log files and can see them being appended to as they are being written. I thought this would be simple but it was a bit slower to solve than I expected because apparently Microsoft's mentality is to presume that the *default* behavior every programmer would naturally want is to have the most crippling file access rules possible. It threw exceptions if I tried to write to a file that is currently being tail'ed. I eventually found the right flags to force C#'s File.Open() to behave more reasonably (allowing multiple processes to have the file open so one can read what the other is writing) and got it working now. It wasn't that hard once I knew that was the problem. It just took a while to notice that's what was wrong because the idea that never mentioning file acess rules causes exclusivity was utterly alien. So alien it never even occurred to me to check for that as a potential cause. I'm used to the case where totally open anything-goes simultaneous file access is the norm and you only ever think about changing it when hitting one of those rare algorithms where it matters - like with multithreaded code with atomic crtical sections. --- src/kOS.Safe/Persistence/Archive.cs | 40 ++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/src/kOS.Safe/Persistence/Archive.cs b/src/kOS.Safe/Persistence/Archive.cs index 24a513e45..784b5389e 100644 --- a/src/kOS.Safe/Persistence/Archive.cs +++ b/src/kOS.Safe/Persistence/Archive.cs @@ -194,7 +194,7 @@ public override float RequiredPower() /// /// filename to look for /// if true, it prefers to use the KSM filename over the KS. The default is to prefer KS. - /// + /// the full fileinfo of the filename if found private System.IO.FileInfo FileSearch(string name, bool ksmDefault = false) { var path = ArchiveFolder + name; @@ -232,5 +232,43 @@ private byte[] ProcessBinaryReader(BinaryReader infile) return ms.ToArray(); } } + + public override void AppendToFile(string name, string textToAppend) + { + Debug.Logger.SuperVerbose("Archive: AppendToFile: " + name); + string fullPath; + System.IO.FileInfo info = FileSearch(name, false); + + if (info == null) + fullPath = string.Format("{0}{1}", ArchiveFolder, PersistenceUtilities.CookedFilename(name, KERBOSCRIPT_EXTENSION, true)); + else + fullPath = info.FullName; + + // Using binary writer so we can bypass the OS behavior about ASCII end-of-lines and always use \n's no matter the OS: + // Deliberately not catching potential I/O exceptions from this, so they will percolate upward and be seen by the user: + using (var outfile = new BinaryWriter(File.Open(fullPath, FileMode.Append, FileAccess.Write,FileShare.ReadWrite))) + { + byte[] binaryLine = System.Text.Encoding.UTF8.GetBytes((textToAppend+"\n").ToCharArray()); + outfile.Write(binaryLine); + } + } + + public override void AppendToFile(string name, byte[] bytesToAppend) + { + Debug.Logger.SuperVerbose("Archive: AppendToFile: " + name); + string fullPath; + System.IO.FileInfo info = FileSearch(name, false); + + if (info == null) + fullPath = string.Format("{0}{1}", ArchiveFolder, PersistenceUtilities.CookedFilename(name, KERBOSCRIPT_EXTENSION, true)); + else + fullPath = info.FullName; + + // Deliberately not catching potential I/O exceptions from this, so they will percolate upward and be seen by the user: + using (var outfile = new BinaryWriter(File.Open(fullPath, FileMode.Append, FileAccess.Write, FileShare.ReadWrite))) + { + outfile.Write(bytesToAppend); + } + } } } From cdbc227995b64f8f94894748375b128859240394 Mon Sep 17 00:00:00 2001 From: Chris Woerz Date: Thu, 1 Jan 2015 15:05:07 -0700 Subject: [PATCH 016/446] first pass for new prospect resources --- src/kOS/Suffixed/StageValues.cs | 4 +- src/kOS/Utilities/Utils.cs | 111 ++++++-------------------------- 2 files changed, 21 insertions(+), 94 deletions(-) diff --git a/src/kOS/Suffixed/StageValues.cs b/src/kOS/Suffixed/StageValues.cs index 3a4a23a59..fc88537c1 100644 --- a/src/kOS/Suffixed/StageValues.cs +++ b/src/kOS/Suffixed/StageValues.cs @@ -1,4 +1,5 @@ using System; +using System.Linq; using kOS.Safe.Encapsulation; using kOS.Utilities; @@ -21,7 +22,8 @@ public override object GetSuffix(string suffixName) private object GetResourceOfCurrentStage(string resourceName) { var activeEngines = VesselUtils.GetListOfActivatedEngines(vessel); - var total = Utils.ProspectForResource(resourceName, activeEngines); + var resource = vessel.GetActiveResources().First(r => r.info.name == resourceName); + var total = Utils.ProspectForResource(resource, activeEngines); return Math.Round(total, 2); } diff --git a/src/kOS/Utilities/Utils.cs b/src/kOS/Utilities/Utils.cs index c337cf75f..0efb7fad3 100644 --- a/src/kOS/Utilities/Utils.cs +++ b/src/kOS/Utilities/Utils.cs @@ -63,90 +63,6 @@ public static bool IsValidRotation(Quaternion quaternion) IsValidNumber(quaternion.w); } - public static double ProspectForResource(string resourceName, List engines) - { - var visited = new List(); - - IEnumerable lines; - if (engines.Count > 0) - { - // The recursive algorithm is written to assume all the engines are on - // the same vessel, so just use one of the engines to get the vessel: - lines = engines[0].vessel.parts.OfType(); - } - else - { - // Uhh... no engines in engine list - no point in doing the work. - return 0.0; - } - return engines.Sum(part => ProspectForResource(resourceName, part, lines, 0, ref visited)); - } - - public static double ProspectForResource(string resourceName, Part engine) - { - var visited = new List(); - - IEnumerable lines = engine.vessel.parts.OfType(); - - return ProspectForResource(resourceName, engine, lines, 0, ref visited); - } - - public static double ProspectForResource(string resourceName, Part part, IEnumerable lines, int rDepth, ref List visited) - { -#pragma warning disable 162 - const bool DEBUG_WALK = false; // set to true to enable the logging of the recursive walk. - var indent = new String(',', rDepth); - - if (DEBUG_WALK) Debug.Log(indent + "ProspectForResource( " + resourceName + ", " + part.uid() + ":" + part.name + ", ...)"); - double ret = 0; - - if (visited.Contains(part)) - { - if (DEBUG_WALK) Debug.Log(indent + "- Already visited, truncate recurse branch here."); - return 0; - } - - visited.Add(part); - - foreach (PartResource resource in part.Resources) - { - if (String.Equals(resource.resourceName, resourceName, StringComparison.CurrentCultureIgnoreCase)) - { - ret += resource.amount; - } - } - - foreach (var attachNode in GetActualAttachedNodes(part)) - { - if (DEBUG_WALK) Debug.Log(indent + "- AttachNode " + attachNode.id); - if (!attachNode.ResourceXFeed) continue; - - if (DEBUG_WALK) Debug.Log(indent + "- - It is an xfeed-able attachnode."); - if (attachNode.attachedPart == null || (!attachNode.attachedPart.fuelCrossFeed)) continue; - - if (DEBUG_WALK) Debug.Log(indent + "- - AttachNode's other part allows crossfeed in general."); - if (part.NoCrossFeedNodeKey.Length > 0 && attachNode.id.Contains(part.NoCrossFeedNodeKey)) continue; - - if (DEBUG_WALK) Debug.Log(indent + "- - This part allows crossfeed through specifically through this AttachNode."); - if (attachNode.attachedPart.NoCrossFeedNodeKey.Length > 0 && attachNode.id.Contains(attachNode.attachedPart.NoCrossFeedNodeKey)) continue; - - if (DEBUG_WALK) Debug.Log(indent + "- - Part on other side allows flow specifically through this AttachNode."); - ret += ProspectForResource(resourceName, attachNode.attachedPart, lines, rDepth + 1, ref visited); - } - - // Fuel lines have to be handled specially because they are not in the normal parts tree - // and are not connected via AttachNodes: - foreach (var fuelLine in lines.Where(fuelLine => part == fuelLine.target && fuelLine.fuelLineOpen && fuelLine.fuelCrossFeed)) - { - if (DEBUG_WALK) Debug.Log(indent + "- Part is target of a fuel line, traversing fuel line upstream."); - ret += ProspectForResource(resourceName, fuelLine.parent, lines, rDepth + 1, ref visited); - } - - if (DEBUG_WALK) Debug.Log(indent + "Sum from this branch of the recurse tree is " + ret); - return ret; -#pragma warning restore 162 - } - /// /// Gets the *actual* list of attachnodes for a part. Use as a replacement /// for the KSP API property part.attachNodes because that doesn't seem to @@ -277,15 +193,15 @@ public static string KOSType(Type type) { return "Number"; } - else if (type.IsSubclassOf(typeof(Boolean))) + if (type.IsSubclassOf(typeof(Boolean))) { return "Boolean"; } - else if (type.IsSubclassOf(typeof(String))) + if (type.IsSubclassOf(typeof(String))) { return "String"; } - else if (type.IsSubclassOf(typeof(Safe.Encapsulation.Structure)) ) + if (type.IsSubclassOf(typeof(Safe.Encapsulation.Structure)) ) { // If it's one of our suffixed Types, then // first chop it down to just the lastmost term @@ -300,11 +216,8 @@ public static string KOSType(Type type) return name; } - else // fallback to use the System's native type name: - { - return type.Name; - } - + // fallback to use the System's native type name: + return type.Name; } /// @@ -334,6 +247,18 @@ public static string GetCodeFragment(List codes) return codeFragment.Aggregate(string.Empty, (current, s) => current + (s + "\n")); } - + + public static double ProspectForResource(Vessel.ActiveResource resource, List activeEngines) + { + double toReturn = 0.0; + foreach (var activeEngine in activeEngines) + { + var attachedResources = new List(); + activeEngine.GetConnectedResources(resource.info.id,resource.info.resourceFlowMode, attachedResources); + + toReturn += attachedResources.Sum(ar => ar.amount); + } + return toReturn; + } } } \ No newline at end of file From 04aeb459b8ee38ed287582909e1a237576b9163f Mon Sep 17 00:00:00 2001 From: Chris Woerz Date: Thu, 1 Jan 2015 21:08:38 -0700 Subject: [PATCH 017/446] I think i found a simplier way --- src/kOS/Suffixed/StageValues.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/kOS/Suffixed/StageValues.cs b/src/kOS/Suffixed/StageValues.cs index fc88537c1..d07c3c064 100644 --- a/src/kOS/Suffixed/StageValues.cs +++ b/src/kOS/Suffixed/StageValues.cs @@ -21,10 +21,8 @@ public override object GetSuffix(string suffixName) private object GetResourceOfCurrentStage(string resourceName) { - var activeEngines = VesselUtils.GetListOfActivatedEngines(vessel); var resource = vessel.GetActiveResources().First(r => r.info.name == resourceName); - var total = Utils.ProspectForResource(resource, activeEngines); - return Math.Round(total, 2); + return Math.Round(resource.amount, 2); } public override string ToString() From 772e7a6703fe13cab57dafdde01b198f323a1aa9 Mon Sep 17 00:00:00 2001 From: Chris Woerz Date: Fri, 2 Jan 2015 00:08:28 -0700 Subject: [PATCH 018/446] implemented a generic listvalue --- src/kOS.Safe.Test/ListValueTest.cs | 21 +- src/kOS.Safe/Encapsulation/Enumerator.cs | 42 ++++ src/kOS.Safe/Encapsulation/ListValue.cs | 218 +++++++++++---------- src/kOS.Safe/Encapsulation/SuffixedList.cs | 21 ++ src/kOS.Safe/kOS.Safe.csproj | 2 + src/kOS/Function/BuildList.cs | 4 +- src/kOS/Suffixed/Part/PartModuleFields.cs | 12 +- 7 files changed, 201 insertions(+), 119 deletions(-) create mode 100644 src/kOS.Safe/Encapsulation/Enumerator.cs create mode 100644 src/kOS.Safe/Encapsulation/SuffixedList.cs diff --git a/src/kOS.Safe.Test/ListValueTest.cs b/src/kOS.Safe.Test/ListValueTest.cs index 635c5157c..48b382de8 100644 --- a/src/kOS.Safe.Test/ListValueTest.cs +++ b/src/kOS.Safe.Test/ListValueTest.cs @@ -62,17 +62,16 @@ public void CanGetIndex() var length = InvokeDelegate(list, "LENGTH"); Assert.AreEqual(4,length); - IIndexable indexable = list; - Assert.AreSame(zedObject, indexable.GetIndex(0)); - Assert.AreSame(firstObject, indexable.GetIndex(1)); - Assert.AreSame(secondObject, indexable.GetIndex(2)); - Assert.AreSame(thirdObject, indexable.GetIndex(3)); - Assert.AreNotSame(indexable.GetIndex(0),indexable.GetIndex(1)); - Assert.AreNotSame(indexable.GetIndex(0),indexable.GetIndex(2)); - Assert.AreNotSame(indexable.GetIndex(0),indexable.GetIndex(3)); - Assert.AreNotSame(indexable.GetIndex(1),indexable.GetIndex(2)); - Assert.AreNotSame(indexable.GetIndex(1),indexable.GetIndex(3)); - Assert.AreNotSame(indexable.GetIndex(2),indexable.GetIndex(3)); + Assert.AreSame(zedObject, list[0]); + Assert.AreSame(firstObject, list[1]); + Assert.AreSame(secondObject, list[2]); + Assert.AreSame(thirdObject, list[3]); + Assert.AreNotSame(list[0],list[1]); + Assert.AreNotSame(list[0],list[2]); + Assert.AreNotSame(list[0],list[3]); + Assert.AreNotSame(list[1],list[2]); + Assert.AreNotSame(list[1],list[3]); + Assert.AreNotSame(list[2],list[3]); } [Test] diff --git a/src/kOS.Safe/Encapsulation/Enumerator.cs b/src/kOS.Safe/Encapsulation/Enumerator.cs new file mode 100644 index 000000000..fc1688b30 --- /dev/null +++ b/src/kOS.Safe/Encapsulation/Enumerator.cs @@ -0,0 +1,42 @@ +using System.Collections; +using kOS.Safe.Encapsulation.Suffixes; + +namespace kOS.Safe.Encapsulation +{ + public class Enumerator : Structure + { + private readonly IEnumerator enumerator; + private int index = -1; + private bool status; + + public Enumerator(IEnumerator enumerator) + { + this.enumerator = enumerator; + EnumeratorInitializeSuffixes(); + } + + private void EnumeratorInitializeSuffixes() + { + AddSuffix("RESET", new NoArgsSuffix(() => + { + index = -1; + status = false; + enumerator.Reset(); + })); + AddSuffix("NEXT", new NoArgsSuffix(() => + { + status = enumerator.MoveNext(); + index++; + return status; + })); + AddSuffix("ATEND", new NoArgsSuffix(() => !status)); + AddSuffix("INDEX", new NoArgsSuffix(() => index)); + AddSuffix("VALUE", new NoArgsSuffix(() => enumerator.Current)); + } + + public override string ToString() + { + return string.Format("{0} Iterator", base.ToString()); + } + } +} \ No newline at end of file diff --git a/src/kOS.Safe/Encapsulation/ListValue.cs b/src/kOS.Safe/Encapsulation/ListValue.cs index 09756920d..b933aa4dd 100644 --- a/src/kOS.Safe/Encapsulation/ListValue.cs +++ b/src/kOS.Safe/Encapsulation/ListValue.cs @@ -1,56 +1,119 @@ +using kOS.Safe.Encapsulation.Suffixes; +using kOS.Safe.Properties; using System; using System.Collections; using System.Collections.Generic; +using System.Diagnostics; using System.Linq; using System.Text; -using System.Diagnostics; - -using kOS.Safe.Encapsulation.Suffixes; -using kOS.Safe.Properties; namespace kOS.Safe.Encapsulation { - public class ListValue : Structure, IIndexable + public class ListValue : Structure, IList { - private readonly IList list; - - // It's nice for other parts of kOS's C# code to be able to operate on ListValues - // without having to go through the suffix system to do so. Other wrappers should - // go here too, probably: Remove, element access with '[]', etc. - public int Count { get{ return list.Count;} } + private readonly IList internalList; public ListValue() + : this(new List()) { - list = new List(); - ListInitializeSuffixes(); } - private ListValue(IList list) + public ListValue(IEnumerable listValue) { - this.list = list; + internalList = listValue.ToList(); ListInitializeSuffixes(); } - // This looks useful. Why is it private? - private ListValue(ListValue toCopy) + public IEnumerator GetEnumerator() { - list = new List(toCopy.list); - ListInitializeSuffixes(); + return internalList.GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + + public void Add(T item) + { + internalList.Add(item); + } + + public void Clear() + { + internalList.Clear(); + } + + public bool Contains(T item) + { + return internalList.Contains(item); + } + + public void CopyTo(T[] array, int arrayIndex) + { + internalList.CopyTo(array, arrayIndex); + } + + public bool Remove(T item) + { + return internalList.Remove(item); + } + + public int Count + { + get { return internalList.Count; } + } + + public bool IsReadOnly + { + get { return internalList.IsReadOnly; } + } + + public int IndexOf(T item) + { + return internalList.IndexOf(item); + } + + public void Insert(int index, T item) + { + internalList.Insert(index, item); + } + + public void RemoveAt(int index) + { + internalList.RemoveAt(index); + } + + public T this[int index] + { + get { return internalList[index]; } + set { internalList[index] = value; } } private void ListInitializeSuffixes() { - AddSuffix("ADD", new OneArgsSuffix (toAdd => list.Add(toAdd), Resources.ListAddDescription)); - AddSuffix("INSERT", new TwoArgsSuffix ((index,toAdd) => list.Insert(index,toAdd))); - AddSuffix("REMOVE", new OneArgsSuffix (toRemove => list.RemoveAt(toRemove))); - AddSuffix("CLEAR", new NoArgsSuffix (() => list.Clear())); - AddSuffix("LENGTH", new NoArgsSuffix (() => list.Count)); - AddSuffix("ITERATOR", new NoArgsSuffix (() => new Enumerator(list.GetEnumerator()))); - AddSuffix("COPY", new NoArgsSuffix (() => new ListValue(this))); - AddSuffix("CONTAINS", new OneArgsSuffix (item => list.Contains(item))); - AddSuffix("SUBLIST", new TwoArgsSuffix(SubListMethod)); - AddSuffix("EMPTY", new NoArgsSuffix (() => !list.Any())); - AddSuffix("DUMP", new NoArgsSuffix (ListDumpDeep)); + AddSuffix("ADD", new OneArgsSuffix(toAdd => internalList.Add(toAdd), Resources.ListAddDescription)); + AddSuffix("INSERT", new TwoArgsSuffix((index, toAdd) => internalList.Insert(index, toAdd))); + AddSuffix("REMOVE", new OneArgsSuffix(toRemove => internalList.RemoveAt(toRemove))); + AddSuffix("CLEAR", new NoArgsSuffix(() => internalList.Clear())); + AddSuffix("LENGTH", new NoArgsSuffix(() => internalList.Count)); + AddSuffix("ITERATOR", new NoArgsSuffix(() => new Enumerator(internalList.GetEnumerator()))); + AddSuffix("COPY", new NoArgsSuffix>(() => new ListValue(this))); + AddSuffix("CONTAINS", new OneArgsSuffix(item => internalList.Contains(item))); + AddSuffix("SUBLIST", new TwoArgsSuffix(SubListMethod)); + AddSuffix("EMPTY", new NoArgsSuffix(() => !internalList.Any())); + AddSuffix("DUMP", new NoArgsSuffix(ListDumpDeep)); + } + + // This test case was added to ensure there was an example method with more than 1 argument. + private ListValue SubListMethod(int start, int runLength) + { + var subList = new ListValue(); + for (int i = start; i < internalList.Count && i < start + runLength; ++i) + { + subList.Add(internalList[i]); + } + return subList; } public override bool SetSuffix(string suffixName, object value) @@ -78,28 +141,13 @@ public override bool SetSuffix(string suffixName, object value) } } - // This test case was added to ensure there was an example method with more than 1 argument. - private ListValue SubListMethod(int start, int runLength) - { - var subList = new ListValue(); - for (int i = start; i < list.Count && i < start + runLength; ++i) - { - subList.Add(list[i]); - } - return subList; - } - - public void Add(object toAdd) - { - list.Add(toAdd); - } - // Using Statics for this is not thread-safe, but kOS doesn't do threads at the moment. // TODO: find a better way later to track the nesting level through all the messy // calls of nested objects' ToStrings. private static int currentNestDepth; + private static int maxVerboseDepth; - + public override string ToString() { // If toString is nested inside another object's toString that was @@ -136,7 +184,7 @@ private bool CalledFrom(string methodName) // (i starts at 1 not 0 deliberately. That's not a bug - skipping to top stack // frame on purpose because the top stack frame is the current method we're in // the middle of executing): - for (int i = 1 ; i < callStack.Length ; ++i ) + for (int i = 1; i < callStack.Length; ++i) { var type = callStack[i].GetMethod().DeclaringType; if (type == null) continue; @@ -158,7 +206,7 @@ private bool CalledFrom(string methodName) /// short string without eoln private string TerseDump() { - return "LIST of " + list.Count + " item" + (list.Count==1 ? "" : "s"); + return "LIST of " + internalList.Count + " item" + (internalList.Count == 1 ? "" : "s"); } /// @@ -174,7 +222,7 @@ private string ListDumpShallow() maxVerboseDepth = 1; return ListDump(); } - + /// /// Dump the contents of the list into a string, by descending through the /// list and appending the "ToString"'s of all the elements in the list.
@@ -188,7 +236,7 @@ private string ListDumpDeep() maxVerboseDepth = 99; return ListDump(); } - + /// /// This is the engine underneath ListDump shallow/deep. /// @@ -202,74 +250,42 @@ private string ListDump() if (truncateHere) { - --currentNestDepth; + --currentNestDepth; return TerseDump(); } var contents = new StringBuilder(); - contents.AppendLine( TerseDump() + ":" ); - var indent = new string(' ', currentNestDepth*SPACES_PER_INDENT); - for (int i = 0 ; i < list.Count ; ++i) + contents.AppendLine(TerseDump() + ":"); + var indent = new string(' ', currentNestDepth * SPACES_PER_INDENT); + for (int i = 0; i < internalList.Count; ++i) { - contents.AppendLine( string.Format("{0}[{1,2}]= {2}", indent, i, list[i]) ); + contents.AppendLine(string.Format("{0}[{1,2}]= {2}", indent, i, internalList[i])); } - --currentNestDepth; + --currentNestDepth; return contents.ToString(); } - public static ListValue CreateList(IEnumerable sourceList) - { - return new ListValue(sourceList.Cast().ToList()); - } - - #region IIndexable Members - - public object GetIndex(int index) - { - return list[index]; - } - - public void SetIndex(int index, object value) - { - list[index] = value; - } - - #endregion IIndexable Members } - public class Enumerator : Structure + public class ListValue : ListValue { - private readonly IEnumerator enumerator; - private int index = -1; - private bool status; + public ListValue() + { + InitializeSuffixes(); + } - public Enumerator(IEnumerator enumerator) + public ListValue(IEnumerable toCopy) + : base(toCopy) { - this.enumerator = enumerator; - EnumeratorInitializeSuffixes(); + InitializeSuffixes(); } - private void EnumeratorInitializeSuffixes() + private void InitializeSuffixes() { - AddSuffix("RESET", new NoArgsSuffix (() => - { - index = -1; - status = false; - enumerator.Reset(); - })); - AddSuffix("NEXT", new NoArgsSuffix (() => - { - status = enumerator.MoveNext(); - index++; - return status; - })); - AddSuffix("ATEND", new NoArgsSuffix (() => !status)); - AddSuffix("INDEX", new NoArgsSuffix (() => index)); - AddSuffix("VALUE", new NoArgsSuffix(() => enumerator.Current)); - AddSuffix("ITERATOR", new NoArgsSuffix(() => this)); + AddSuffix("COPY", new NoArgsSuffix(() => new ListValue(this))); } - public override string ToString() + public static ListValue CreateList(List toCopy) { - return string.Format("{0} Iterator", base.ToString()); + return new ListValue(toCopy.Cast()); } } } \ No newline at end of file diff --git a/src/kOS.Safe/Encapsulation/SuffixedList.cs b/src/kOS.Safe/Encapsulation/SuffixedList.cs new file mode 100644 index 000000000..95f6bbfab --- /dev/null +++ b/src/kOS.Safe/Encapsulation/SuffixedList.cs @@ -0,0 +1,21 @@ +using System.Collections.Generic; +using System.Linq; + +namespace kOS.Safe.Encapsulation +{ + public class SuffixedList : ListValue where T : ISuffixed + { + public SuffixedList() + { + } + + public SuffixedList(IEnumerable toCopy) : base(toCopy) + { + } + + public static ListValue CreateList(List toCopy) + { + return new ListValue(toCopy.Cast()); + } + } +} \ No newline at end of file diff --git a/src/kOS.Safe/kOS.Safe.csproj b/src/kOS.Safe/kOS.Safe.csproj index fd2aa3b75..6051f3d86 100644 --- a/src/kOS.Safe/kOS.Safe.csproj +++ b/src/kOS.Safe/kOS.Safe.csproj @@ -65,6 +65,7 @@ + @@ -75,6 +76,7 @@ + diff --git a/src/kOS/Function/BuildList.cs b/src/kOS/Function/BuildList.cs index 2c95e631b..8ab014d1b 100644 --- a/src/kOS/Function/BuildList.cs +++ b/src/kOS/Function/BuildList.cs @@ -1,6 +1,8 @@ using System; +using System.Linq; using kOS.Safe.Encapsulation; using kOS.Safe.Function; +using kOS.Safe.Persistence; using kOS.Suffixed; using kOS.Utilities; @@ -38,7 +40,7 @@ public override void Execute(SharedObjects shared) list = ListValue.CreateList(shared.VolumeMgr.CurrentVolume.GetFileList()); break; case "volumes": - list = ListValue.CreateList(shared.VolumeMgr.Volumes); + list = ListValue.CreateList(shared.VolumeMgr.Volumes.Values.ToList()); break; default: throw new ArgumentOutOfRangeException(); diff --git a/src/kOS/Suffixed/Part/PartModuleFields.cs b/src/kOS/Suffixed/Part/PartModuleFields.cs index 9ae90b491..58d2b9b29 100644 --- a/src/kOS/Suffixed/Part/PartModuleFields.cs +++ b/src/kOS/Suffixed/Part/PartModuleFields.cs @@ -340,17 +340,17 @@ private ListValue AllThings() ListValue fields = AllFields(FORMATTER); ListValue events = AllEvents(FORMATTER); ListValue actions = AllActions(FORMATTER); - for (int i = 0; i < fields.Count ; ++i) + foreach (object t in fields) { - all.Add(fields.GetIndex(i)); + all.Add(t); } - for (int i = 0; i < events.Count ; ++i) + foreach (object t in events) { - all.Add(events.GetIndex(i)); + all.Add(t); } - for (int i = 0; i < actions.Count ; ++i) + foreach (object t in actions) { - all.Add(actions.GetIndex(i)); + all.Add(t); } return all; } From ce4d58eb46cb09778480411b9e44c2ef3c265b7c Mon Sep 17 00:00:00 2001 From: Chris Woerz Date: Fri, 2 Jan 2015 00:17:41 -0700 Subject: [PATCH 019/446] stage can give you a list of active resources --- src/kOS.Safe/Persistence/Volume.cs | 4 +- src/kOS/Binding/FlightStats.cs | 2 +- src/kOS/Suffixed/AggregateResourceValue.cs | 51 ++++++++++++++-------- src/kOS/Suffixed/Part/PartValue.cs | 11 +++++ src/kOS/Suffixed/StageValues.cs | 46 +++++++++++++++---- src/kOS/Utilities/VesselUtils.cs | 2 +- 6 files changed, 85 insertions(+), 31 deletions(-) diff --git a/src/kOS.Safe/Persistence/Volume.cs b/src/kOS.Safe/Persistence/Volume.cs index aaca88740..130d47f34 100644 --- a/src/kOS.Safe/Persistence/Volume.cs +++ b/src/kOS.Safe/Persistence/Volume.cs @@ -46,7 +46,7 @@ private void InitializeVolumeSuffixes() AddSuffix("CAPACITY" , new Suffix(() => Capacity)); AddSuffix("NAME" , new Suffix(() => Name)); AddSuffix("RENAMEABLE" , new Suffix(() => Name)); - AddSuffix("FILES" , new Suffix(() => ListValue.CreateList(GetFileList()))); + AddSuffix("FILES" , new Suffix>(() => new SuffixedList(GetFileList()))); AddSuffix("POWERREQUIREMENT" , new Suffix(RequiredPower)); } @@ -176,7 +176,7 @@ public virtual List GetFileList() private int FileInfoComparer(FileInfo a, FileInfo b) { - return String.Compare(a.Name,b.Name); + return String.CompareOrdinal(a.Name, b.Name); } public virtual float RequiredPower() diff --git a/src/kOS/Binding/FlightStats.cs b/src/kOS/Binding/FlightStats.cs index ed11ffdf6..b3aedd4ae 100644 --- a/src/kOS/Binding/FlightStats.cs +++ b/src/kOS/Binding/FlightStats.cs @@ -29,7 +29,7 @@ public override void AddTo(SharedObjects shared) shared.BindingMgr.AddGetter("SHIP", () => new VesselTarget(shared)); shared.BindingMgr.AddGetter("ACTIVESHIP", () => new VesselTarget(FlightGlobals.ActiveVessel, shared)); shared.BindingMgr.AddGetter("STATUS", () => shared.Vessel.situation.ToString()); - shared.BindingMgr.AddGetter("STAGE", () => new StageValues(shared.Vessel)); + shared.BindingMgr.AddGetter("STAGE", () => new StageValues(shared)); //DEPRICATED VESSELNAME shared.BindingMgr.AddSetter("VESSELNAME", diff --git a/src/kOS/Suffixed/AggregateResourceValue.cs b/src/kOS/Suffixed/AggregateResourceValue.cs index b4e0fea0c..842282cf2 100644 --- a/src/kOS/Suffixed/AggregateResourceValue.cs +++ b/src/kOS/Suffixed/AggregateResourceValue.cs @@ -1,44 +1,57 @@ using System.Collections.Generic; using kOS.Safe.Encapsulation; +using kOS.Safe.Encapsulation.Suffixes; +using kOS.Suffixed.Part; namespace kOS.Suffixed { public class AggregateResourceValue : Structure { + private readonly Vessel.ActiveResource activeResource; private readonly string name; + private readonly SharedObjects shared; private double amount; private double capacity; - private readonly ListValue parts; + private readonly SuffixedList parts; - public AggregateResourceValue(string name) + public AggregateResourceValue(string name, SharedObjects shared) { this.name = name; + this.shared = shared; amount = 0; capacity = 0; - parts = new ListValue(); + parts = new SuffixedList(); + InitializeAggregateResourceSuffixes(); } - public override object GetSuffix(string suffixName) + private void InitializeAggregateResourceSuffixes() { - switch (suffixName) - { - case "NAME": - return name; - case "AMOUNT": - return amount; - case "CAPACITY": - return capacity; - case "PARTS": - return parts; - } - return base.GetSuffix(suffixName); + AddSuffix("NAME", new Suffix(() => name)); + AddSuffix("AMOUNT", new Suffix(() => amount)); + AddSuffix("CAPICITY", new Suffix(() => capacity)); + AddSuffix("PARTS", new Suffix>(() => parts)); + } + + public AggregateResourceValue(Vessel.ActiveResource activeResource, SharedObjects shared) + { + this.activeResource = activeResource; + this.shared = shared; + InitializeActiveResourceSuffixes(); + } + + private void InitializeActiveResourceSuffixes() + { + AddSuffix("NAME", new Suffix(() => activeResource.info.name)); + AddSuffix("AMOUNT", new Suffix(() => activeResource.amount)); + AddSuffix("CAPICITY", new Suffix(() => activeResource.maxAmount)); + AddSuffix("PARTS", new Suffix>(() => PartValue.PartsToList(activeResource.parts, shared))); } public void AddResource(PartResource resource) { amount += resource.amount; capacity += resource.maxAmount; - parts.Add(resource.part); + parts.Add(new PartValue(resource.part, shared)); } public override string ToString() @@ -46,7 +59,7 @@ public override string ToString() return string.Format("SHIPRESOURCE({0},{1},{2})", name, amount, capacity); } - public static ListValue PartsToList(IEnumerable parts) + public static ListValue PartsToList(IEnumerable parts, SharedObjects shared) { var list = new ListValue(); var resources = new Dictionary(); @@ -57,7 +70,7 @@ public static ListValue PartsToList(IEnumerable parts) AggregateResourceValue aggregateResourceAmount; if (!resources.TryGetValue(module.resourceName, out aggregateResourceAmount)) { - aggregateResourceAmount = new AggregateResourceValue(module.resourceName); + aggregateResourceAmount = new AggregateResourceValue(module.resourceName, shared); } aggregateResourceAmount.AddResource(module); resources[module.resourceName] = aggregateResourceAmount; diff --git a/src/kOS/Suffixed/Part/PartValue.cs b/src/kOS/Suffixed/Part/PartValue.cs index e406be9b1..d7ceb82b5 100644 --- a/src/kOS/Suffixed/Part/PartValue.cs +++ b/src/kOS/Suffixed/Part/PartValue.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using kOS.Module; using kOS.Safe.Encapsulation; using kOS.Safe.Exceptions; @@ -161,5 +162,15 @@ public override int GetHashCode() { return !Equals(left, right); } + + public static SuffixedList PartsToList(IEnumerable parts, SharedObjects shared) + { + var toReturn = new SuffixedList(); + foreach (var part in parts) + { + toReturn.Add(new PartValue(part, shared)); + } + return toReturn; + } } } diff --git a/src/kOS/Suffixed/StageValues.cs b/src/kOS/Suffixed/StageValues.cs index d07c3c064..b84328d4c 100644 --- a/src/kOS/Suffixed/StageValues.cs +++ b/src/kOS/Suffixed/StageValues.cs @@ -1,28 +1,58 @@ using System; using System.Linq; using kOS.Safe.Encapsulation; -using kOS.Utilities; +using kOS.Safe.Encapsulation.Suffixes; namespace kOS.Suffixed { public class StageValues : Structure { - private readonly Vessel vessel; + private readonly SharedObjects shared; - public StageValues(Vessel vessel) + public StageValues(SharedObjects shared) { - this.vessel = vessel; + this.shared = shared; + + InitializeSuffixes(); + } + + private void InitializeSuffixes() + { + AddSuffix("RESOURCES", new Suffix>(GetResourceManifest)); + } + + private SuffixedList GetResourceManifest() + { + var resources = shared.Vessel.GetActiveResources(); + var toReturn = new SuffixedList(); + + foreach (var resource in resources) + { + toReturn.Add(new AggregateResourceValue(resource, shared)); + } + + return toReturn; } public override object GetSuffix(string suffixName) { - return GetResourceOfCurrentStage(suffixName); + var resourceAmount = GetResourceOfCurrentStage(suffixName); + if (resourceAmount.HasValue) + { + return resourceAmount.Value; + } + + return base.GetSuffix(suffixName); } - private object GetResourceOfCurrentStage(string resourceName) + private double? GetResourceOfCurrentStage(string resourceName) { - var resource = vessel.GetActiveResources().First(r => r.info.name == resourceName); - return Math.Round(resource.amount, 2); + Safe.Utilities.Debug.Logger.Log("GetResourceOfCurrentStage: " + resourceName); + var resource = shared.Vessel.GetActiveResources().FirstOrDefault(r => r.info.name == resourceName); + + Safe.Utilities.Debug.Logger.Log("GetResourceOfCurrentStage: " + resourceName); + + return resource == null ? null : (double?) Math.Round(resource.amount, 2); } public override string ToString() diff --git a/src/kOS/Utilities/VesselUtils.cs b/src/kOS/Utilities/VesselUtils.cs index 3be1bb65a..85a5a28f7 100644 --- a/src/kOS/Utilities/VesselUtils.cs +++ b/src/kOS/Utilities/VesselUtils.cs @@ -73,7 +73,7 @@ public static ListValue PartList(this IShipconstruct vessel, string partType, Sh switch (partType.ToUpper()) { case "RESOURCES": - list = AggregateResourceValue.PartsToList(partList); + list = AggregateResourceValue.PartsToList(partList, sharedObj); break; case "PARTS": From 81d682f795af9fb6b7dba74f20047e3910dbfc6c Mon Sep 17 00:00:00 2001 From: Chris Woerz Date: Fri, 2 Jan 2015 03:27:42 -0700 Subject: [PATCH 020/446] split active and aggregate resources and fixed a bunch of bugs --- src/kOS/Suffixed/ActiveResourceValue.cs | 32 ++++++++++++++++++++++ src/kOS/Suffixed/AggregateResourceValue.cs | 16 ----------- src/kOS/Suffixed/StageValues.cs | 14 ++++------ src/kOS/kOS.csproj | 1 + 4 files changed, 38 insertions(+), 25 deletions(-) create mode 100644 src/kOS/Suffixed/ActiveResourceValue.cs diff --git a/src/kOS/Suffixed/ActiveResourceValue.cs b/src/kOS/Suffixed/ActiveResourceValue.cs new file mode 100644 index 000000000..671f515e4 --- /dev/null +++ b/src/kOS/Suffixed/ActiveResourceValue.cs @@ -0,0 +1,32 @@ +using kOS.Safe.Encapsulation; +using kOS.Safe.Encapsulation.Suffixes; +using kOS.Suffixed.Part; + +namespace kOS.Suffixed +{ + public class ActiveResourceValue : Structure + { + private readonly Vessel.ActiveResource activeResource; + private readonly SharedObjects shared; + + public ActiveResourceValue(Vessel.ActiveResource activeResource, SharedObjects shared) + { + this.activeResource = activeResource; + this.shared = shared; + InitializeActiveResourceSuffixes(); + } + + private void InitializeActiveResourceSuffixes() + { + AddSuffix("NAME", new Suffix(() => activeResource.info.name)); + AddSuffix("AMOUNT", new Suffix(() => activeResource.amount)); + AddSuffix("CAPICITY", new Suffix(() => activeResource.maxAmount)); + AddSuffix("PARTS", new Suffix>(() => PartValue.PartsToList(activeResource.parts, shared))); + } + + public override string ToString() + { + return string.Format("ACTIVERESOURCE({0},{1},{2})", activeResource.info.name, activeResource.amount, activeResource.maxAmount); + } + } +} \ No newline at end of file diff --git a/src/kOS/Suffixed/AggregateResourceValue.cs b/src/kOS/Suffixed/AggregateResourceValue.cs index 842282cf2..7a17c0d39 100644 --- a/src/kOS/Suffixed/AggregateResourceValue.cs +++ b/src/kOS/Suffixed/AggregateResourceValue.cs @@ -7,7 +7,6 @@ namespace kOS.Suffixed { public class AggregateResourceValue : Structure { - private readonly Vessel.ActiveResource activeResource; private readonly string name; private readonly SharedObjects shared; private double amount; @@ -32,21 +31,6 @@ private void InitializeAggregateResourceSuffixes() AddSuffix("PARTS", new Suffix>(() => parts)); } - public AggregateResourceValue(Vessel.ActiveResource activeResource, SharedObjects shared) - { - this.activeResource = activeResource; - this.shared = shared; - InitializeActiveResourceSuffixes(); - } - - private void InitializeActiveResourceSuffixes() - { - AddSuffix("NAME", new Suffix(() => activeResource.info.name)); - AddSuffix("AMOUNT", new Suffix(() => activeResource.amount)); - AddSuffix("CAPICITY", new Suffix(() => activeResource.maxAmount)); - AddSuffix("PARTS", new Suffix>(() => PartValue.PartsToList(activeResource.parts, shared))); - } - public void AddResource(PartResource resource) { amount += resource.amount; diff --git a/src/kOS/Suffixed/StageValues.cs b/src/kOS/Suffixed/StageValues.cs index b84328d4c..2e3f541d9 100644 --- a/src/kOS/Suffixed/StageValues.cs +++ b/src/kOS/Suffixed/StageValues.cs @@ -18,17 +18,17 @@ public StageValues(SharedObjects shared) private void InitializeSuffixes() { - AddSuffix("RESOURCES", new Suffix>(GetResourceManifest)); + AddSuffix("RESOURCES", new Suffix>(GetResourceManifest)); } - private SuffixedList GetResourceManifest() + private SuffixedList GetResourceManifest() { var resources = shared.Vessel.GetActiveResources(); - var toReturn = new SuffixedList(); + var toReturn = new SuffixedList(); foreach (var resource in resources) { - toReturn.Add(new AggregateResourceValue(resource, shared)); + toReturn.Add(new ActiveResourceValue(resource, shared)); } return toReturn; @@ -47,11 +47,7 @@ public override object GetSuffix(string suffixName) private double? GetResourceOfCurrentStage(string resourceName) { - Safe.Utilities.Debug.Logger.Log("GetResourceOfCurrentStage: " + resourceName); - var resource = shared.Vessel.GetActiveResources().FirstOrDefault(r => r.info.name == resourceName); - - Safe.Utilities.Debug.Logger.Log("GetResourceOfCurrentStage: " + resourceName); - + var resource = shared.Vessel.GetActiveResources().FirstOrDefault(r => string.Equals(r.info.name, resourceName, StringComparison.OrdinalIgnoreCase)); return resource == null ? null : (double?) Math.Round(resource.amount, 2); } diff --git a/src/kOS/kOS.csproj b/src/kOS/kOS.csproj index 2ccf125a4..f3db39c24 100644 --- a/src/kOS/kOS.csproj +++ b/src/kOS/kOS.csproj @@ -90,6 +90,7 @@ + From 071aec954e68b5eb5f051825a91a4f7d3e086a57 Mon Sep 17 00:00:00 2001 From: Chris Woerz Date: Fri, 2 Jan 2015 13:19:14 -0700 Subject: [PATCH 021/446] changes from review comments --- src/kOS.Safe/Encapsulation/ListValue.cs | 30 ++++++++++++---------- src/kOS.Safe/Encapsulation/SuffixedList.cs | 21 --------------- src/kOS.Safe/Persistence/Volume.cs | 2 +- src/kOS.Safe/kOS.Safe.csproj | 1 - src/kOS/Suffixed/ActiveResourceValue.cs | 8 +++--- src/kOS/Suffixed/AggregateResourceValue.cs | 6 ++--- src/kOS/Suffixed/Part/PartValue.cs | 13 +--------- src/kOS/Suffixed/Part/PartValueFactory.cs | 29 +++++++-------------- src/kOS/Suffixed/StageValues.cs | 6 ++--- src/kOS/Utilities/Utils.cs | 13 ---------- 10 files changed, 38 insertions(+), 91 deletions(-) delete mode 100644 src/kOS.Safe/Encapsulation/SuffixedList.cs diff --git a/src/kOS.Safe/Encapsulation/ListValue.cs b/src/kOS.Safe/Encapsulation/ListValue.cs index b933aa4dd..0be9b9656 100644 --- a/src/kOS.Safe/Encapsulation/ListValue.cs +++ b/src/kOS.Safe/Encapsulation/ListValue.cs @@ -9,7 +9,7 @@ namespace kOS.Safe.Encapsulation { - public class ListValue : Structure, IList + public class ListValue : Structure, IList { private readonly IList internalList; @@ -92,17 +92,17 @@ public T this[int index] private void ListInitializeSuffixes() { - AddSuffix("ADD", new OneArgsSuffix(toAdd => internalList.Add(toAdd), Resources.ListAddDescription)); - AddSuffix("INSERT", new TwoArgsSuffix((index, toAdd) => internalList.Insert(index, toAdd))); - AddSuffix("REMOVE", new OneArgsSuffix(toRemove => internalList.RemoveAt(toRemove))); - AddSuffix("CLEAR", new NoArgsSuffix(() => internalList.Clear())); - AddSuffix("LENGTH", new NoArgsSuffix(() => internalList.Count)); - AddSuffix("ITERATOR", new NoArgsSuffix(() => new Enumerator(internalList.GetEnumerator()))); - AddSuffix("COPY", new NoArgsSuffix>(() => new ListValue(this))); - AddSuffix("CONTAINS", new OneArgsSuffix(item => internalList.Contains(item))); - AddSuffix("SUBLIST", new TwoArgsSuffix(SubListMethod)); - AddSuffix("EMPTY", new NoArgsSuffix(() => !internalList.Any())); - AddSuffix("DUMP", new NoArgsSuffix(ListDumpDeep)); + AddSuffix("ADD", new OneArgsSuffix (toAdd => internalList.Add(toAdd), Resources.ListAddDescription)); + AddSuffix("INSERT", new TwoArgsSuffix ((index, toAdd) => internalList.Insert(index, toAdd))); + AddSuffix("REMOVE", new OneArgsSuffix (toRemove => internalList.RemoveAt(toRemove))); + AddSuffix("CLEAR", new NoArgsSuffix (() => internalList.Clear())); + AddSuffix("LENGTH", new NoArgsSuffix (() => internalList.Count)); + AddSuffix("ITERATOR", new NoArgsSuffix (() => new Enumerator(internalList.GetEnumerator()))); + AddSuffix("COPY", new NoArgsSuffix> (() => new ListValue(this))); + AddSuffix("CONTAINS", new OneArgsSuffix (item => internalList.Contains(item))); + AddSuffix("SUBLIST", new TwoArgsSuffix(SubListMethod)); + AddSuffix("EMPTY", new NoArgsSuffix (() => !internalList.Any())); + AddSuffix("DUMP", new NoArgsSuffix (ListDumpDeep)); } // This test case was added to ensure there was an example method with more than 1 argument. @@ -145,7 +145,6 @@ public override bool SetSuffix(string suffixName, object value) // TODO: find a better way later to track the nesting level through all the messy // calls of nested objects' ToStrings. private static int currentNestDepth; - private static int maxVerboseDepth; public override string ToString() @@ -263,6 +262,11 @@ private string ListDump() --currentNestDepth; return contents.ToString(); } + + public static ListValue CreateList(IEnumerable list) + { + return new ListValue(list.Cast()); + } } public class ListValue : ListValue diff --git a/src/kOS.Safe/Encapsulation/SuffixedList.cs b/src/kOS.Safe/Encapsulation/SuffixedList.cs deleted file mode 100644 index 95f6bbfab..000000000 --- a/src/kOS.Safe/Encapsulation/SuffixedList.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System.Collections.Generic; -using System.Linq; - -namespace kOS.Safe.Encapsulation -{ - public class SuffixedList : ListValue where T : ISuffixed - { - public SuffixedList() - { - } - - public SuffixedList(IEnumerable toCopy) : base(toCopy) - { - } - - public static ListValue CreateList(List toCopy) - { - return new ListValue(toCopy.Cast()); - } - } -} \ No newline at end of file diff --git a/src/kOS.Safe/Persistence/Volume.cs b/src/kOS.Safe/Persistence/Volume.cs index 130d47f34..506c41db7 100644 --- a/src/kOS.Safe/Persistence/Volume.cs +++ b/src/kOS.Safe/Persistence/Volume.cs @@ -46,7 +46,7 @@ private void InitializeVolumeSuffixes() AddSuffix("CAPACITY" , new Suffix(() => Capacity)); AddSuffix("NAME" , new Suffix(() => Name)); AddSuffix("RENAMEABLE" , new Suffix(() => Name)); - AddSuffix("FILES" , new Suffix>(() => new SuffixedList(GetFileList()))); + AddSuffix("FILES" , new Suffix>(() => new ListValue(GetFileList()))); AddSuffix("POWERREQUIREMENT" , new Suffix(RequiredPower)); } diff --git a/src/kOS.Safe/kOS.Safe.csproj b/src/kOS.Safe/kOS.Safe.csproj index 6051f3d86..6973a2350 100644 --- a/src/kOS.Safe/kOS.Safe.csproj +++ b/src/kOS.Safe/kOS.Safe.csproj @@ -76,7 +76,6 @@ - diff --git a/src/kOS/Suffixed/ActiveResourceValue.cs b/src/kOS/Suffixed/ActiveResourceValue.cs index 671f515e4..458b2e821 100644 --- a/src/kOS/Suffixed/ActiveResourceValue.cs +++ b/src/kOS/Suffixed/ActiveResourceValue.cs @@ -18,10 +18,10 @@ public ActiveResourceValue(Vessel.ActiveResource activeResource, SharedObjects s private void InitializeActiveResourceSuffixes() { - AddSuffix("NAME", new Suffix(() => activeResource.info.name)); - AddSuffix("AMOUNT", new Suffix(() => activeResource.amount)); - AddSuffix("CAPICITY", new Suffix(() => activeResource.maxAmount)); - AddSuffix("PARTS", new Suffix>(() => PartValue.PartsToList(activeResource.parts, shared))); + AddSuffix("NAME", new Suffix(() => activeResource.info.name, "The name of the resource (eg LiguidFuel, ElectricCharge)")); + AddSuffix("AMOUNT", new Suffix(() => activeResource.amount, "The resources currently available")); + AddSuffix("CAPICITY", new Suffix(() => activeResource.maxAmount, "The total storage capacity currently available")); + AddSuffix("PARTS", new Suffix>(() => PartValueFactory.ConstructGeneric(activeResource.parts, shared), "The containers for this resource")); } public override string ToString() diff --git a/src/kOS/Suffixed/AggregateResourceValue.cs b/src/kOS/Suffixed/AggregateResourceValue.cs index 7a17c0d39..cb7dd5abb 100644 --- a/src/kOS/Suffixed/AggregateResourceValue.cs +++ b/src/kOS/Suffixed/AggregateResourceValue.cs @@ -11,7 +11,7 @@ public class AggregateResourceValue : Structure private readonly SharedObjects shared; private double amount; private double capacity; - private readonly SuffixedList parts; + private readonly ListValue parts; public AggregateResourceValue(string name, SharedObjects shared) { @@ -19,7 +19,7 @@ public AggregateResourceValue(string name, SharedObjects shared) this.shared = shared; amount = 0; capacity = 0; - parts = new SuffixedList(); + parts = new ListValue(); InitializeAggregateResourceSuffixes(); } @@ -28,7 +28,7 @@ private void InitializeAggregateResourceSuffixes() AddSuffix("NAME", new Suffix(() => name)); AddSuffix("AMOUNT", new Suffix(() => amount)); AddSuffix("CAPICITY", new Suffix(() => capacity)); - AddSuffix("PARTS", new Suffix>(() => parts)); + AddSuffix("PARTS", new Suffix>(() => parts)); } public void AddResource(PartResource resource) diff --git a/src/kOS/Suffixed/Part/PartValue.cs b/src/kOS/Suffixed/Part/PartValue.cs index d7ceb82b5..53ecab4be 100644 --- a/src/kOS/Suffixed/Part/PartValue.cs +++ b/src/kOS/Suffixed/Part/PartValue.cs @@ -1,5 +1,4 @@ using System; -using System.Collections.Generic; using kOS.Module; using kOS.Safe.Encapsulation; using kOS.Safe.Exceptions; @@ -44,7 +43,7 @@ private void PartInitializeSuffixes() AddSuffix(new [] {"MODULES","ALLMODULES"}, new Suffix(GetAllModules, "A List of all the modules' names on this part")); AddSuffix("PARENT", new Suffix(() => PartValueFactory.Construct(Part.parent,shared), "The parent part of this part")); AddSuffix("HASPARENT", new Suffix(() => Part.parent != null, "Tells you if this part has a parent, is used to avoid null exception from PARENT")); - AddSuffix("CHILDREN", new Suffix(() => PartValueFactory.Construct(Part.children, shared), "A LIST() of the children parts of this part")); + AddSuffix("CHILDREN", new Suffix>(() => PartValueFactory.ConstructGeneric(Part.children, shared), "A LIST() of the children parts of this part")); AddSuffix("DRYMASS", new Suffix(Part.GetDryMass, "The Part's mass when empty")); AddSuffix("MASS", new Suffix(Part.CalculateCurrentMass, "The Part's current mass")); AddSuffix("WETMASS", new Suffix(Part.GetWetMass, "The Part's mass when full")); @@ -162,15 +161,5 @@ public override int GetHashCode() { return !Equals(left, right); } - - public static SuffixedList PartsToList(IEnumerable parts, SharedObjects shared) - { - var toReturn = new SuffixedList(); - foreach (var part in parts) - { - toReturn.Add(new PartValue(part, shared)); - } - return toReturn; - } } } diff --git a/src/kOS/Suffixed/Part/PartValueFactory.cs b/src/kOS/Suffixed/Part/PartValueFactory.cs index 1d74be75d..e6a6f8044 100644 --- a/src/kOS/Suffixed/Part/PartValueFactory.cs +++ b/src/kOS/Suffixed/Part/PartValueFactory.cs @@ -1,32 +1,21 @@ -/* - * Created by SharpDevelop. - * User: Dunbaratu - * Date: 11/5/2014 - * Time: 3:13 AM - * - * To change this template use Tools | Options | Coding | Edit Standard Headers. - */ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.Linq; -using System.Net; using kOS.Safe.Encapsulation; namespace kOS.Suffixed.Part { - /// - /// Description of PartValueFactory. - /// public class PartValueFactory { public static ListValue Construct(IEnumerable parts, SharedObjects shared) { - var list = new List(); - foreach (var part in parts) - { - list.Add(Construct(part, shared)); - } - return ListValue.CreateList(list); + var partList = parts.Select(part => Construct(part, shared)).ToList(); + return ListValue.CreateList(partList); + } + + public static ListValue ConstructGeneric(IEnumerable parts, SharedObjects shared) + { + var partList = parts.Select(part => Construct(part, shared)).ToList(); + return ListValue.CreateList(partList); } public static PartValue Construct(global::Part part, SharedObjects shared) diff --git a/src/kOS/Suffixed/StageValues.cs b/src/kOS/Suffixed/StageValues.cs index 2e3f541d9..b5500d636 100644 --- a/src/kOS/Suffixed/StageValues.cs +++ b/src/kOS/Suffixed/StageValues.cs @@ -18,13 +18,13 @@ public StageValues(SharedObjects shared) private void InitializeSuffixes() { - AddSuffix("RESOURCES", new Suffix>(GetResourceManifest)); + AddSuffix("RESOURCES", new Suffix>(GetResourceManifest)); } - private SuffixedList GetResourceManifest() + private ListValue GetResourceManifest() { var resources = shared.Vessel.GetActiveResources(); - var toReturn = new SuffixedList(); + var toReturn = new ListValue(); foreach (var resource in resources) { diff --git a/src/kOS/Utilities/Utils.cs b/src/kOS/Utilities/Utils.cs index 0efb7fad3..a2aa0304a 100644 --- a/src/kOS/Utilities/Utils.cs +++ b/src/kOS/Utilities/Utils.cs @@ -247,18 +247,5 @@ public static string GetCodeFragment(List codes) return codeFragment.Aggregate(string.Empty, (current, s) => current + (s + "\n")); } - - public static double ProspectForResource(Vessel.ActiveResource resource, List activeEngines) - { - double toReturn = 0.0; - foreach (var activeEngine in activeEngines) - { - var attachedResources = new List(); - activeEngine.GetConnectedResources(resource.info.id,resource.info.resourceFlowMode, attachedResources); - - toReturn += attachedResources.Sum(ar => ar.amount); - } - return toReturn; - } } } \ No newline at end of file From 7e15216ce43975730209ed735f454752640dd915 Mon Sep 17 00:00:00 2001 From: Chris Woerz Date: Fri, 2 Jan 2015 13:44:46 -0700 Subject: [PATCH 022/446] added SHIP:RESOURCES --- src/kOS/Suffixed/AggregateResourceValue.cs | 20 ++++++++++++++++++++ src/kOS/Suffixed/VesselTarget.cs | 1 + 2 files changed, 21 insertions(+) diff --git a/src/kOS/Suffixed/AggregateResourceValue.cs b/src/kOS/Suffixed/AggregateResourceValue.cs index cb7dd5abb..cf5177983 100644 --- a/src/kOS/Suffixed/AggregateResourceValue.cs +++ b/src/kOS/Suffixed/AggregateResourceValue.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Linq; using kOS.Safe.Encapsulation; using kOS.Safe.Encapsulation.Suffixes; using kOS.Suffixed.Part; @@ -66,5 +67,24 @@ public static ListValue PartsToList(IEnumerable parts, SharedObjec } return list; } + + public static ListValue FromVessel(Vessel vessel, SharedObjects shared) + { + var resources = new Dictionary(); + + foreach (var resource in vessel.parts.SelectMany(part => part.Resources.list)) + { + AggregateResourceValue resourceValue; + if (resources.TryGetValue(resource.name, out resourceValue)) + { + resourceValue.AddResource(resource); + } + else + { + resources.Add(resource.name, new AggregateResourceValue(resource.name, shared)); + } + } + return ListValue.CreateList(resources.Values); + } } } \ No newline at end of file diff --git a/src/kOS/Suffixed/VesselTarget.cs b/src/kOS/Suffixed/VesselTarget.cs index af3fbe867..38328204f 100644 --- a/src/kOS/Suffixed/VesselTarget.cs +++ b/src/kOS/Suffixed/VesselTarget.cs @@ -430,6 +430,7 @@ private void InitializeSuffixes() AddSuffix("ROOTPART", new Suffix(() => PartValueFactory.Construct(Vessel.rootPart, Shared))); AddSuffix("DRYMASS", new Suffix(() => Vessel.GetDryMass(), "The Ship's mass when empty")); AddSuffix("WETMASS", new Suffix(Vessel.GetWetMass, "The Ship's mass when full")); + AddSuffix("RESOURCES", new Suffix>(() => AggregateResourceValue.FromVessel(Vessel, Shared), "The Aggregate resources from every part on the craft")); //// Although there is an implementation of lat/long/alt in Orbitible, //// it's better to use the methods for vessels that are faster if they're From f5d03503c202599f804955a29b5c40e1ca5185f2 Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Fri, 2 Jan 2015 14:47:23 -0600 Subject: [PATCH 023/446] version number increment for 0.15.5 --- CHANGELOG.md | 14 ++++++++++++++ Resources/GameData/kOS/kOS.version | 2 +- src/kOS/Properties/AssemblyInfo.cs | 2 +- 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1ec3c197b..dbdc65cae 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,20 @@ kOS Mod Changelog ================= +# v0.15.5 +The KSP 0.90 compatibility release. +(The full thematic following of KSP 0.90's new way of +thinking will come in a future version. This is just +to make sure everything works.) + +###BREAKING CHANGES +* TODO +###New Stuff +* TODO +###Bug Fixes +* TODO + + # v0.15.4 ###BREAKING CHANGES * Issue #431: SHIP:ANGULARMOMENTUM and SHIP:ANGULARVEL have been changed from directions to vectors to me more consistant with their nature diff --git a/Resources/GameData/kOS/kOS.version b/Resources/GameData/kOS/kOS.version index 2b1fb05f7..945dd9ab4 100644 --- a/Resources/GameData/kOS/kOS.version +++ b/Resources/GameData/kOS/kOS.version @@ -11,7 +11,7 @@ "VERSION": { "MAJOR": 0, "MINOR": 15, - "PATCH": 4 + "PATCH": 5 }, "KSP_VERSION": { "MAJOR": 0, diff --git a/src/kOS/Properties/AssemblyInfo.cs b/src/kOS/Properties/AssemblyInfo.cs index c70ca20ff..a1772c55f 100644 --- a/src/kOS/Properties/AssemblyInfo.cs +++ b/src/kOS/Properties/AssemblyInfo.cs @@ -33,5 +33,5 @@ // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("0.15.4.0")] +[assembly: AssemblyFileVersion("0.15.5.0")] [assembly: KSPAssembly("kOS", 0, 15)] \ No newline at end of file From 70861b9f20e0368ea289a5a6ea4f4e88e175208e Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Fri, 2 Jan 2015 14:57:18 -0600 Subject: [PATCH 024/446] merge of erendrake --- src/kOS/Properties/AssemblyInfo.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/kOS/Properties/AssemblyInfo.cs b/src/kOS/Properties/AssemblyInfo.cs index 76d4c01e5..f8a9c5e16 100644 --- a/src/kOS/Properties/AssemblyInfo.cs +++ b/src/kOS/Properties/AssemblyInfo.cs @@ -32,6 +32,6 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyFileVersion("0.15.4.0")] -[assembly: AssemblyVersion("0.15.4.0")] -[assembly: KSPAssembly("kOS", 0, 15)] \ No newline at end of file +[assembly: AssemblyFileVersion("0.15.5.0")] +[assembly: AssemblyVersion("0.15.5.0")] +[assembly: KSPAssembly("kOS", 0, 15)] From 7c4a4a51dc7a7063f39b3e6c5cb63789c2faa2f3 Mon Sep 17 00:00:00 2001 From: Chris Woerz Date: Fri, 2 Jan 2015 14:01:41 -0700 Subject: [PATCH 025/446] resource.name is the part name? using resource.info.name is correct --- src/kOS/Suffixed/AggregateResourceValue.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/kOS/Suffixed/AggregateResourceValue.cs b/src/kOS/Suffixed/AggregateResourceValue.cs index cf5177983..ef8f262d2 100644 --- a/src/kOS/Suffixed/AggregateResourceValue.cs +++ b/src/kOS/Suffixed/AggregateResourceValue.cs @@ -75,13 +75,13 @@ public static ListValue FromVessel(Vessel vessel, Shared foreach (var resource in vessel.parts.SelectMany(part => part.Resources.list)) { AggregateResourceValue resourceValue; - if (resources.TryGetValue(resource.name, out resourceValue)) + if (resources.TryGetValue(resource.info.name, out resourceValue)) { resourceValue.AddResource(resource); } else { - resources.Add(resource.name, new AggregateResourceValue(resource.name, shared)); + resources.Add(resource.info.name, new AggregateResourceValue(resource.info.name, shared)); } } return ListValue.CreateList(resources.Values); From 0b7a7f8a0a90847a2cb50034b414955efd0494fc Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Fri, 2 Jan 2015 15:38:25 -0600 Subject: [PATCH 026/446] made proposed new changelog for 0.15.5. Edit it some more after final docs are set in stone. --- CHANGELOG.md | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1ec3c197b..cdf8f19a0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,37 @@ kOS Mod Changelog ================= +# v0.15.5 +The KSP 0.90 compatibility release. +(The full thematic following of KSP 0.90's new way of +thinking will come in a future version. This is just +to make sure everything works.) + +###BREAKING CHANGES +* + +###New Stuff +* Thanks to a new dev team volunteer (username theodoregoetz on github), we have a new, much better and cleaner looking [documentation site](http://ksp-kos.github.io/KOS/) +* Better flight input handling to detect the pilot controls and keep them isolated. +* "plays nice" with other autopilots a bit better, using KSP 0.90's new autopiloting hooks. +* Ability to read [more data about a ship resource](TODO - Are these in the docs? Put URL here if so.) TODO: i.e. SingleResourceValue:FLOWMODE, for example - see PR #452) +* New [suffixes to handle directions better](http://ksp-kos.github.io/KOS/math/direction.html) as mentioned in [long detail in this video](https://www.youtube.com/watch?v=7byYiZZBBVc) +* Separate Dry Mass, Wet Mass, and Current Mass readings for parts and for the vessel as a whole (TODO: Link here, but the public gh-pages hasn't be regenned yet so I don't know the link yet) +* Now respects the limitations of [0.90 career mode upgrades](http://ksp-kos.github.io/KOS/general/career_limits.html). +* + +###Bug Fixes +* Better handling of range checking and loading the boot file when remotetech is installed (thanks to hvacengi for this contribution) +* Boot file overwrite fix (thanks to pakrym) +* (For developers) fixed compile error on UNIX platforms that was due to filename case-sensitivity differences. +* LOG command to the Archive now appends to the file properly instead of rewriting the entire contents each time just to tack on one line. It is now possible to read its output from outside KSP using a tool like the UNIX "tail -f" program. +* Better calculations of stage resource values, using SQUAD'S provided API for it instead of trying to walk the tree ourselves (which broke in 0.90). + +###Small maintenence issues +* Bundling a newer version of ModuleManager +* Better use of the "skin" system for the app panel. Should see no obvious effect on the surface. + + # v0.15.4 ###BREAKING CHANGES * Issue #431: SHIP:ANGULARMOMENTUM and SHIP:ANGULARVEL have been changed from directions to vectors to me more consistant with their nature From 835a87f8cbebef140b99e25984c3357bd5ab2254 Mon Sep 17 00:00:00 2001 From: Chris Woerz Date: Fri, 2 Jan 2015 14:38:47 -0700 Subject: [PATCH 027/446] no longer skipping the first resource of each type in SHIP:RESOURCES --- src/kOS/Suffixed/AggregateResourceValue.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/kOS/Suffixed/AggregateResourceValue.cs b/src/kOS/Suffixed/AggregateResourceValue.cs index ef8f262d2..db25e1399 100644 --- a/src/kOS/Suffixed/AggregateResourceValue.cs +++ b/src/kOS/Suffixed/AggregateResourceValue.cs @@ -81,7 +81,10 @@ public static ListValue FromVessel(Vessel vessel, Shared } else { - resources.Add(resource.info.name, new AggregateResourceValue(resource.info.name, shared)); + var newResource = new AggregateResourceValue(resource.info.name, shared); + newResource.AddResource(resource); + + resources.Add(resource.info.name, newResource); } } return ListValue.CreateList(resources.Values); From dcbf2d4a7dc21abb1edbd4d5be1b376dff767b6a Mon Sep 17 00:00:00 2001 From: Chris Woerz Date: Fri, 2 Jan 2015 15:22:37 -0700 Subject: [PATCH 028/446] fixed version in core --- src/kOS/Core.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kOS/Core.cs b/src/kOS/Core.cs index 6ce0fcaae..e9004c513 100644 --- a/src/kOS/Core.cs +++ b/src/kOS/Core.cs @@ -5,7 +5,7 @@ namespace kOS { public class Core : MonoBehaviour { - public static VersionInfo VersionInfo = new VersionInfo(0, 15, 4); + public static VersionInfo VersionInfo = new VersionInfo(0, 15, 5); public static Core Fetch; From c0d29d8ab3367453cd9d443cc083c4790d1022a8 Mon Sep 17 00:00:00 2001 From: Chris Woerz Date: Fri, 2 Jan 2015 22:02:05 -0700 Subject: [PATCH 029/446] restore ListValue's IIndexable interface while a refactor is done --- src/kOS.Safe/Encapsulation/ListValue.cs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/kOS.Safe/Encapsulation/ListValue.cs b/src/kOS.Safe/Encapsulation/ListValue.cs index 0be9b9656..cd822e90c 100644 --- a/src/kOS.Safe/Encapsulation/ListValue.cs +++ b/src/kOS.Safe/Encapsulation/ListValue.cs @@ -9,7 +9,7 @@ namespace kOS.Safe.Encapsulation { - public class ListValue : Structure, IList + public class ListValue : Structure, IList, IIndexable { private readonly IList internalList; @@ -267,6 +267,16 @@ public static ListValue CreateList(IEnumerable list) { return new ListValue(list.Cast()); } + + public object GetIndex(int index) + { + return internalList[index]; + } + + public void SetIndex(int index, object value) + { + internalList[index] = (T)value; + } } public class ListValue : ListValue From e224f4add26828105608c7ad62a7911960744283 Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Sat, 3 Jan 2015 00:25:31 -0600 Subject: [PATCH 030/446] fixes #475 - waypoint data --- doc/source/structures/waypoint.rst | 127 +++++++++++++++++++++++++++++ src/kOS/Function/Suffixed.cs | 50 ++++++++++++ src/kOS/Suffixed/Career.cs | 5 +- src/kOS/Suffixed/GeoCoordinates.cs | 18 +++- src/kOS/Suffixed/WaypointValue.cs | 79 ++++++++++++++++++ src/kOS/kOS.csproj | 1 + 6 files changed, 276 insertions(+), 4 deletions(-) create mode 100644 doc/source/structures/waypoint.rst create mode 100644 src/kOS/Suffixed/WaypointValue.cs diff --git a/doc/source/structures/waypoint.rst b/doc/source/structures/waypoint.rst new file mode 100644 index 000000000..2961e8331 --- /dev/null +++ b/doc/source/structures/waypoint.rst @@ -0,0 +1,127 @@ +Waypoints +========= + +.. contents:: Contents + :local: + :depth: 1 + +Waypoints are the location markers you can see on the map view showing +you where contracts are targeted for. With this strucure, you can obtain +coordinate data for the locations of these waypoints. + +Creation +-------- + +.. function:: WAYPOINT(name) + + :parameter name: (string) Name of the waypoint as it appears on the map or in the contract description + :return: :struct:`Waypoint` + + This creates a new Waypoint from a name of a waypoint you read from the contract paramters. Note that this only works on contracts you've accpted. Waypoints for proposed contracts haven't accepted yet do not actually work in kOS. + + SET spot TO WAYPOINT("herman's folly beta"). + + The name match is case-insensitive. + +.. function:: ALLWAYPOINTS(name) + :return: :struct:`Waypoint` + + This creates a `List` of `Waypoint` structures for all accepted contracts. Waypoints for proposed contracts you haven't accepted yet do not appear in the list. + +Structure +--------- + +.. structure:: Waypoint + + .. list-table:: **Members** + :widths: 4 2 1 1 + :header-rows: 1 + + * - Suffix + - Type + - Get + - Set + + * - :attr:`NAME` + - string + - yes + - no + * - :attr:`BODY` + - `BodyTarget` + - yes + - no + * - :attr:`GEOPOSITION` + - `GeoCoordinates` + - yes + - no + * - :attr:`ALTITUDE` + - scalar + - yes + - no + * - :attr:`AGL` + - scalar + - yes + - no + * - :attr:`NEARSURFACE` + - boolean + - yes + - no + * - :attr:`GROUNDED` + - boolean + - yes + - no + + +.. attribute:: Waypoint:NAME + + :type: string + :access: Get + + Name of waypoint as it appears on the map and contract + +.. attribute:: Waypoint:BODY + + :type: `BodyTarget` + :access: Get + + Celestial body the waypoint is attached to + + +.. attribute:: Waypoint:GEOPOSITION + + :type: GeoCoordinates + :access: Get + + The LATLNG of this waypoint + +.. attribute:: Waypoint:ALTITUDE + + :type: scalar + :access: Get + + Altitude of waypoint **above "sea" level**. Warning, this a point somewhere in the midst of the contract altitude range, not the edge of the altitude range. It corresponds towhere the marker tip hovers on the map, which is not actually at the very edge of the contract condition's range. It represents a typical midling location inside the contract's altitude range. + + +.. attribute:: Waypoint:AGL + + :type: scalar + :access: Get + + Altitude of waypoint **above ground**. Warning, this a point somewhere in the midst of the contract altitude range, not the edge of the altitude range. It corresponds to where the marker tip hovers on the map, which is not actually at the very edge of the contract condition's range. It represents a typical midling location inside the contract's altitude range. + + +.. attribute:: Waypoint:NEARSURFACE + + :type: boolean + :access: Get + + True if waypoint is a point near or on the body rather than high in orbit. + + +.. attribute:: Waypoint:GROUNDED + + :type: boolean + :access: Get + + True if waypoint is actually glued to the ground. + diff --git a/src/kOS/Function/Suffixed.cs b/src/kOS/Function/Suffixed.cs index a3511f83b..794bee2db 100644 --- a/src/kOS/Function/Suffixed.cs +++ b/src/kOS/Function/Suffixed.cs @@ -1,8 +1,11 @@ using System; +using System.Collections.Generic; +using System.Linq; using kOS.Safe.Encapsulation; using kOS.Safe.Function; using kOS.Suffixed; using kOS.Utilities; +using FinePrint; namespace kOS.Function { @@ -308,4 +311,51 @@ public override void Execute(SharedObjects shared) shared.Cpu.PushStack(constants); } } + + [Function("allwaypoints")] + public class FunctionAllWaypoints : FunctionBase + { + public override void Execute(SharedObjects shared) + { + // ReSharper disable SuggestUseVarKeywordEvident + ListValue returnList = new ListValue(); + // ReSharper ensable SuggestUseVarKeywordEvident + + WaypointManager wpm = WaypointManager.Instance(); + if (wpm == null) + shared.Cpu.PushStack(returnList); // When no waypoints exist, there isn't even a waypoint manager at all. + + List points = wpm.AllWaypoints(); + + // If the code below gets used in more places it may be worth moving into a factory method + // akin to how PartValueFactory makes a ListValue from a List. + // But for now, this is the only place it's done: + + foreach (Waypoint point in points) + returnList.Add(new WaypointValue(point, shared)); + shared.Cpu.PushStack(returnList); + } + } + + [Function("waypoint")] + public class FunctionWaypoint : FunctionBase + { + public override void Execute(SharedObjects shared) + { + string pointName = shared.Cpu.PopValue().ToString(); + + FinePrint.WaypointManager wpm = WaypointManager.Instance(); + if (wpm == null) + { + shared.Cpu.PushStack(null); // When no waypoints exist, there isn't even a waypoint manager. + // I don't like returning null here without the user being able to test for that, but + // we don't have another way to communicate "no such waypoint". We really need to address + // that problem once and for all. + } + + Waypoint point = wpm.AllWaypoints().FirstOrDefault(p => String.Equals(p.name, pointName,StringComparison.OrdinalIgnoreCase)); + + shared.Cpu.PushStack(new WaypointValue(point, shared)); + } + } } diff --git a/src/kOS/Suffixed/Career.cs b/src/kOS/Suffixed/Career.cs index ae5551ed2..242dfd52e 100644 --- a/src/kOS/Suffixed/Career.cs +++ b/src/kOS/Suffixed/Career.cs @@ -1,11 +1,13 @@ using System; +using System.Collections.Generic; using kOS.Safe.Encapsulation.Suffixes; using kOS.Safe.Encapsulation; +using FinePrint; // waypoints are defined here. namespace kOS.Suffixed { public class Career : Structure - { + { static Career() { AddGlobalSuffix("CANTRACKOBJECTS", new StaticSuffix(CanTrackObjects, @@ -163,6 +165,7 @@ public static bool CanTagInEditor(EditorFacility whichEditor) string dummy; return CanTagInEditor(whichEditor, out dummy); } + public override string ToString() { diff --git a/src/kOS/Suffixed/GeoCoordinates.cs b/src/kOS/Suffixed/GeoCoordinates.cs index 3dbbe7272..36a1b5eb5 100644 --- a/src/kOS/Suffixed/GeoCoordinates.cs +++ b/src/kOS/Suffixed/GeoCoordinates.cs @@ -34,18 +34,30 @@ public GeoCoordinates(Orbitable orb, SharedObjects sharedObj) /// /// Build a GeoCoordinates from any arbitrary lat/long pair of floats. /// + /// A different celestial body to select a lat/long for that might not be the curent one /// to know the current CPU's running vessel /// latitude /// longitude - public GeoCoordinates(SharedObjects sharedObj, float lat, float lng) + public GeoCoordinates(CelestialBody body, SharedObjects sharedObj, double lat, double lng) { Lat = lat; Lng = lng; Shared = sharedObj; - Body = Shared.Vessel.GetOrbit().referenceBody; + Body = body; GeoCoordsInitializeSuffixes(); } + /// + /// Build a GeoCoordinates from any arbitrary lat/long pair of floats. + /// + /// to know the current CPU's running vessel + /// latitude + /// longitude + public GeoCoordinates(SharedObjects sharedObj, float lat, float lng) : + this(sharedObj.Vessel.GetOrbit().referenceBody, sharedObj, lat, lng) + { + } + /// /// Build a GeoCoordinates from any arbitrary lat/long pair of doubles. /// @@ -75,7 +87,7 @@ public double GetBearing() /// Returns the ground's altitude above sea level at this geo position. /// /// - private double GetTerrainAltitude() + public double GetTerrainAltitude() { double alt = 0.0; PQS bodyPQS = Body.pqsController; diff --git a/src/kOS/Suffixed/WaypointValue.cs b/src/kOS/Suffixed/WaypointValue.cs new file mode 100644 index 000000000..73c65c67b --- /dev/null +++ b/src/kOS/Suffixed/WaypointValue.cs @@ -0,0 +1,79 @@ +using System; +using kOS.Utilities; +using kOS.Safe.Encapsulation.Suffixes; +using kOS.Safe.Encapsulation; +using FinePrint; // This is part of KSP's own DLL now. The Waypoint info is in here. + +namespace kOS.Suffixed +{ + public class WaypointValue : Structure + { + protected Waypoint wayPoint; + protected CelestialBody cachedBody; + protected SharedObjects shared; + + public WaypointValue(Waypoint wayPoint, SharedObjects shared) + { + this.wayPoint = wayPoint; + this.shared = shared; + AddSuffix("DUMP", new NoArgsSuffix(ToVerboseString)); // for debugging + AddSuffix("NAME", new NoArgsSuffix(() => wayPoint.name, "Name of waypoint as it appears on the map and contract")); + AddSuffix("BODY", new NoArgsSuffix(() => new BodyTarget(GetBody(),shared), "Celestial body the waypoint is attached to")); + AddSuffix("GEOPOSITION", new NoArgsSuffix(BuildGeoCoordinates, "the LATLNG of this waypoint")); + AddSuffix("ALTITUDE", new NoArgsSuffix(BuildSeaLevelAltitude, + "Altitude of waypoint above sea level. Warning, this a point somewhere in the " + + "midst of the contract altitude range, not the edge of the altitude range.")); + AddSuffix("AGL", new NoArgsSuffix(() => wayPoint.altitude, + "Altitude of waypoint above ground. Warning, this a point somewhere" + + "in the midst of the contract altitude range, not the edge of the altitude range.")); + AddSuffix("NEARSURFACE", new NoArgsSuffix(() => wayPoint.isOnSurface, "True if waypoint is a point near or on the body rather than high in orbit.")); + AddSuffix("GROUNDED", new NoArgsSuffix(() => wayPoint.landLocked, "True if waypoint is actually glued to the ground.")); + } + + public CelestialBody GetBody() + { + if (cachedBody == null) + cachedBody = VesselUtils.GetBodyByName(wayPoint.celestialName); + return cachedBody; + } + + public GeoCoordinates BuildGeoCoordinates() + { + return new GeoCoordinates(GetBody(), shared, wayPoint.latitude, wayPoint.longitude); + } + + public double BuildSeaLevelAltitude() + { + GeoCoordinates gCoord = BuildGeoCoordinates(); + return gCoord.GetTerrainAltitude() + wayPoint.altitude; + } + + public override string ToString() + { + return String.Format("Waypoint \"{0}\"", wayPoint.name); + } + + public string ToVerboseString() + { + // Remember to change this if you alter the suffix names: + return String.Format("A Waypoint consisting of\n" + + " name= {0}\n" + + " body= {1}\n" + + " latitude= {2}\n" + + " longitude= {3}\n" + + " altitutde= {4}\n" + + " height= {5}\n" + + " isOnSurface= {6}\n" + + " worldPosition= {7}\n", + wayPoint.name, + wayPoint.celestialName, + wayPoint.latitude, + wayPoint.longitude, + wayPoint.altitude, // A location inside the contract range's altitude range - and NOT the edge of it. + wayPoint.height, + wayPoint.isOnSurface, + wayPoint.worldPosition); + } + + } +} \ No newline at end of file diff --git a/src/kOS/kOS.csproj b/src/kOS/kOS.csproj index f3db39c24..e7e330456 100644 --- a/src/kOS/kOS.csproj +++ b/src/kOS/kOS.csproj @@ -125,6 +125,7 @@ + From 65d483353c817480a31aeb633fa79b7b9c358a58 Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Sat, 3 Jan 2015 00:32:58 -0600 Subject: [PATCH 031/446] Docs falsely showed a parameter for allwaypoints ALLWAYPONITS actually takes zero arguments. --- doc/source/structures/waypoint.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/structures/waypoint.rst b/doc/source/structures/waypoint.rst index 2961e8331..f7bdb6787 100644 --- a/doc/source/structures/waypoint.rst +++ b/doc/source/structures/waypoint.rst @@ -23,7 +23,7 @@ Creation The name match is case-insensitive. -.. function:: ALLWAYPOINTS(name) +.. function:: ALLWAYPOINTS() :return: :struct:`Waypoint` This creates a `List` of `Waypoint` structures for all accepted contracts. Waypoints for proposed contracts you haven't accepted yet do not appear in the list. From 0d718af95f82d77a14e96d5fc162c6930ccf8984 Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Sat, 3 Jan 2015 00:34:39 -0600 Subject: [PATCH 032/446] more doc fixing for waypoints --- doc/source/structures/waypoint.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/structures/waypoint.rst b/doc/source/structures/waypoint.rst index f7bdb6787..7a57decc0 100644 --- a/doc/source/structures/waypoint.rst +++ b/doc/source/structures/waypoint.rst @@ -24,7 +24,7 @@ Creation The name match is case-insensitive. .. function:: ALLWAYPOINTS() - :return: :struct:`Waypoint` + :return: :struct: `List` of `Waypoint`s This creates a `List` of `Waypoint` structures for all accepted contracts. Waypoints for proposed contracts you haven't accepted yet do not appear in the list. From ffa6d4a18507d9697d59a3a2baa74b97cabb3c63 Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Sat, 3 Jan 2015 13:35:46 -0600 Subject: [PATCH 033/446] Fixes #444, #478. --- doc/source/math/geocoordinates.rst | 37 ++++++++++++++++++++++++++++++ src/kOS/Suffixed/GeoCoordinates.cs | 33 +++++++++++++++++++++++--- 2 files changed, 67 insertions(+), 3 deletions(-) diff --git a/doc/source/math/geocoordinates.rst b/doc/source/math/geocoordinates.rst index d4d4dd093..353d6f635 100644 --- a/doc/source/math/geocoordinates.rst +++ b/doc/source/math/geocoordinates.rst @@ -35,26 +35,41 @@ Structure * - Suffix - Type + - Args - Description * - :attr:`LAT` - scalar (deg) + - none - Latitude * - :attr:`LNG` - scalar (deg) + - none - Longitude * - :attr:`DISTANCE` - scalar (m) + - none - distance from :ref:`CPU Vessel ` * - :attr:`TERRAINHEIGHT` - scalar (m) + - none - above or below sea level * - :attr:`HEADING` - scalar (deg) + - none - *absolute* heading from :ref:`CPU Vessel ` * - :attr:`BEARING` - scalar (deg) + - none - *relative* direction from :ref:`CPU Vessel ` + * - :attr:`POSITION` + - `Vector` (3D Ship-Raw coords) + - none + - Position of the surface point. + * - :attr:`ALTITUDEPOSITION` + - `Vector` (3D Ship-Raw coords) + - scalar (altitude above sea level) + - Position of a point above (or below) the surface point, by giving the altitude number. .. attribute:: GeoCoordinates:LAT @@ -80,6 +95,14 @@ Structure The *relative* compass direction from the :ref:`CPU_Vessel ` to this point on the surface. For example, if the vessel is heading at compass heading 45, and the geo-coordinates location is at heading 30, then :attr:`GeoCoordinates:BEARING` will return -15. +.. attribute:: GeoCoordinates:POSITION + + The ship-raw 3D position on the surface of the body, relative to the current ship's Center of mass. + +.. attribute:: GeoCoordinates:ALTITUDEPOSITION (altitude) + + The ship-raw 3D position above or below the surface of the body, relative to the current ship's Center of mass. You pass in an altitude number for the altitude above "sea" level of the desired location. + Examples Usage -------------- @@ -105,6 +128,20 @@ Examples Usage // location 5 degrees east // of the old one + // Point nose of ship at a spot 100,000 meters altitude above a + // particular known latitude of 50 east, 20.2 north: + LOCK STEERING TO LATLNG(50,20.2):ALTITUDEPOSITION(100000). + + // A nice complex example: + // ------------------------- + // Drawing an debug arrow in 3D space at the spot where the Geocoordinate 'spot' is: + // It starts at a position 100m above the ground altitude and is aimed down at + // the spot on the ground: + SET VD TO VECDRAWARGS( + spot:ALTITUDEPOSITION(spot:TERRAINHEIGHT+100), + spot:POSITION - spot:ALTITUDEPOSITION(TERRAINHEIGHT+100), + red, "THIS IS THE SPOT", 1, true). + PRINT "THESE TWO NUMBERS SHOULD BE THE SAME:". PRINT (SHIP:ALTITIUDE - SHIP:GEOPOSITION:TERRAINHEIGHT). PRINT ALT:RADAR. diff --git a/src/kOS/Suffixed/GeoCoordinates.cs b/src/kOS/Suffixed/GeoCoordinates.cs index 3dbbe7272..24d790f0f 100644 --- a/src/kOS/Suffixed/GeoCoordinates.cs +++ b/src/kOS/Suffixed/GeoCoordinates.cs @@ -118,7 +118,7 @@ private double GetTerrainAltitude() // a point a bit below it, to aim down to the terrain: Vector3d worldRayCastStop = Body.GetWorldSurfacePosition( Lat, Lng, alt+POINT_AGL ); RaycastHit hit; - if (Physics.Raycast(worldRayCastStart, (worldRayCastStop - worldRayCastStart), out hit, 1<distance scalar private double GetDistanceFrom() { - Vector3d latLongCoords = Body.GetWorldSurfacePosition( Lat, Lng, GetTerrainAltitude() ); + return GetPosition().Magnitude(); + } + + /// + /// The surface point of this LAT/LONG from where + /// the current CPU vessel is now. + /// + /// position vector + public Vector GetPosition() + { + return GetAltitudePosition(GetTerrainAltitude()); + } + + /// + /// The point above or below the surface of this LAT/LONG from where + /// the current CPU vessel is now. + /// + /// The (sea level) altitude to get a position for> + /// position vector + public Vector GetAltitudePosition(double altitude) + { + Vector3d latLongCoords = Body.GetWorldSurfacePosition(Lat, Lng, altitude); Vector3d hereCoords = Shared.Vessel.findWorldCenterOfMass(); - return Vector3d.Distance( latLongCoords, hereCoords ); + return new Vector(latLongCoords - hereCoords); } private void GeoCoordsInitializeSuffixes() @@ -172,6 +193,12 @@ private void GeoCoordsInitializeSuffixes() AddSuffix("DISTANCE", new Suffix(GetDistanceFrom)); AddSuffix("HEADING", new Suffix(GetHeadingFrom)); AddSuffix("BEARING", new Suffix(GetBearing)); + AddSuffix("POSITION", new Suffix(GetPosition, + "Get the 3-D space position relative to the ship center, of this lat/long, " + + "at a point on the terrain surface")); + AddSuffix("ALTITUDEPOSITION", new OneArgsSuffix(GetAltitudePosition, + "Get the 3-D space position relative to the ship center, " + + "of this lat/long, at this (sea level) altitude")); } public override string ToString() From 4ab8e3c1cafc2255cf7c098695034637398d0660 Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Sat, 3 Jan 2015 13:45:24 -0600 Subject: [PATCH 034/446] Added mention of new geocoordinates suffixes --- CHANGELOG.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cdf8f19a0..a2e07b3a5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,7 +18,8 @@ to make sure everything works.) * New [suffixes to handle directions better](http://ksp-kos.github.io/KOS/math/direction.html) as mentioned in [long detail in this video](https://www.youtube.com/watch?v=7byYiZZBBVc) * Separate Dry Mass, Wet Mass, and Current Mass readings for parts and for the vessel as a whole (TODO: Link here, but the public gh-pages hasn't be regenned yet so I don't know the link yet) * Now respects the limitations of [0.90 career mode upgrades](http://ksp-kos.github.io/KOS/general/career_limits.html). -* +* Added new [WAYPOINT object](http://ksp-kos.github.io/structures/waypoint.html) to help with locations of some contracts. +* Added new :POSITION and :ALTITUDEPOSITION suffixes to [Geocoordinates](http://ksp-kos.github.io/math/geocoordinates.html) to obtain 3D vectors of their positions in ship-raw coordinate space. ###Bug Fixes * Better handling of range checking and loading the boot file when remotetech is installed (thanks to hvacengi for this contribution) @@ -26,6 +27,7 @@ to make sure everything works.) * (For developers) fixed compile error on UNIX platforms that was due to filename case-sensitivity differences. * LOG command to the Archive now appends to the file properly instead of rewriting the entire contents each time just to tack on one line. It is now possible to read its output from outside KSP using a tool like the UNIX "tail -f" program. * Better calculations of stage resource values, using SQUAD'S provided API for it instead of trying to walk the tree ourselves (which broke in 0.90). +* Fixed lonstanding [bug with geocoordinates:TERRAINHEIGHT](https://github.com/KSP-KOS/KOS/issues/478) ###Small maintenence issues * Bundling a newer version of ModuleManager From 5d7852bc78f3f5995ca5e917c4d7549655c7d823 Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Sat, 3 Jan 2015 13:47:02 -0600 Subject: [PATCH 035/446] moved career mode limitation to 'breaking' section --- CHANGELOG.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a2e07b3a5..59ecd1c96 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,7 @@ thinking will come in a future version. This is just to make sure everything works.) ###BREAKING CHANGES -* +* Now respects the limitations of [0.90 career mode upgrades](http://ksp-kos.github.io/KOS/general/career_limits.html), which may make a few features not work anymore in career mode until you get further progressed along in your building upgrades. ###New Stuff * Thanks to a new dev team volunteer (username theodoregoetz on github), we have a new, much better and cleaner looking [documentation site](http://ksp-kos.github.io/KOS/) @@ -17,7 +17,6 @@ to make sure everything works.) * Ability to read [more data about a ship resource](TODO - Are these in the docs? Put URL here if so.) TODO: i.e. SingleResourceValue:FLOWMODE, for example - see PR #452) * New [suffixes to handle directions better](http://ksp-kos.github.io/KOS/math/direction.html) as mentioned in [long detail in this video](https://www.youtube.com/watch?v=7byYiZZBBVc) * Separate Dry Mass, Wet Mass, and Current Mass readings for parts and for the vessel as a whole (TODO: Link here, but the public gh-pages hasn't be regenned yet so I don't know the link yet) -* Now respects the limitations of [0.90 career mode upgrades](http://ksp-kos.github.io/KOS/general/career_limits.html). * Added new [WAYPOINT object](http://ksp-kos.github.io/structures/waypoint.html) to help with locations of some contracts. * Added new :POSITION and :ALTITUDEPOSITION suffixes to [Geocoordinates](http://ksp-kos.github.io/math/geocoordinates.html) to obtain 3D vectors of their positions in ship-raw coordinate space. From 912635357b1b4f64e87ad59e941d89e38853aba9 Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Sat, 3 Jan 2015 13:49:39 -0600 Subject: [PATCH 036/446] arrrggg typed URL wrong - missed the KOS/ part --- CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 59ecd1c96..5360450e3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,8 +17,8 @@ to make sure everything works.) * Ability to read [more data about a ship resource](TODO - Are these in the docs? Put URL here if so.) TODO: i.e. SingleResourceValue:FLOWMODE, for example - see PR #452) * New [suffixes to handle directions better](http://ksp-kos.github.io/KOS/math/direction.html) as mentioned in [long detail in this video](https://www.youtube.com/watch?v=7byYiZZBBVc) * Separate Dry Mass, Wet Mass, and Current Mass readings for parts and for the vessel as a whole (TODO: Link here, but the public gh-pages hasn't be regenned yet so I don't know the link yet) -* Added new [WAYPOINT object](http://ksp-kos.github.io/structures/waypoint.html) to help with locations of some contracts. -* Added new :POSITION and :ALTITUDEPOSITION suffixes to [Geocoordinates](http://ksp-kos.github.io/math/geocoordinates.html) to obtain 3D vectors of their positions in ship-raw coordinate space. +* Added new [WAYPOINT object](http://ksp-kos.github.io/KOS/structures/waypoint.html) to help with locations of some contracts. +* Added new :POSITION and :ALTITUDEPOSITION suffixes to [Geocoordinates](http://ksp-kos.github.io/KOS/math/geocoordinates.html) to obtain 3D vectors of their positions in ship-raw coordinate space. ###Bug Fixes * Better handling of range checking and loading the boot file when remotetech is installed (thanks to hvacengi for this contribution) From 0dabb161c30b7f5518174d95946a26b717495463 Mon Sep 17 00:00:00 2001 From: Chris Woerz Date: Sat, 3 Jan 2015 13:39:10 -0700 Subject: [PATCH 037/446] spelling fixes --- src/kOS/Suffixed/GeoCoordinates.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/kOS/Suffixed/GeoCoordinates.cs b/src/kOS/Suffixed/GeoCoordinates.cs index 24d790f0f..9419cb8d6 100644 --- a/src/kOS/Suffixed/GeoCoordinates.cs +++ b/src/kOS/Suffixed/GeoCoordinates.cs @@ -79,12 +79,12 @@ private double GetTerrainAltitude() { double alt = 0.0; PQS bodyPQS = Body.pqsController; - if (bodyPQS != null) // The sun has no terrain. Everthing else has a PQScontroller. + if (bodyPQS != null) // The sun has no terrain. Everything else has a PQScontroller. { // The PQS controller gives the theoretical ideal smooth surface curve terrain. // The actual ground that exists in-game that you land on, however, is the terrain // polygon mesh which is built dynamically from the PQS controller's altitude values, - // and it only approximates the PQS controller. The discrepency between the two + // and it only approximates the PQS controller. The discrepancy between the two // can be as high as 20 meters on relatively mild rolling terrain and is probably worse // in mountainous terrain with steeper slopes. It also varies with the user terrain detail // graphics setting. From 7b155b5957440100f15b14c3636a727ecc751c1d Mon Sep 17 00:00:00 2001 From: Chris Woerz Date: Sat, 3 Jan 2015 13:41:36 -0700 Subject: [PATCH 038/446] review comments --- src/kOS/Function/Suffixed.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/kOS/Function/Suffixed.cs b/src/kOS/Function/Suffixed.cs index 794bee2db..9dde2641b 100644 --- a/src/kOS/Function/Suffixed.cs +++ b/src/kOS/Function/Suffixed.cs @@ -323,7 +323,11 @@ public override void Execute(SharedObjects shared) WaypointManager wpm = WaypointManager.Instance(); if (wpm == null) + { shared.Cpu.PushStack(returnList); // When no waypoints exist, there isn't even a waypoint manager at all. + return; + } + List points = wpm.AllWaypoints(); @@ -344,13 +348,14 @@ public override void Execute(SharedObjects shared) { string pointName = shared.Cpu.PopValue().ToString(); - FinePrint.WaypointManager wpm = WaypointManager.Instance(); + WaypointManager wpm = WaypointManager.Instance(); if (wpm == null) { shared.Cpu.PushStack(null); // When no waypoints exist, there isn't even a waypoint manager. // I don't like returning null here without the user being able to test for that, but // we don't have another way to communicate "no such waypoint". We really need to address // that problem once and for all. + return; } Waypoint point = wpm.AllWaypoints().FirstOrDefault(p => String.Equals(p.name, pointName,StringComparison.OrdinalIgnoreCase)); From 25c91b479260bc3924c0eab3669b3b03928c9c94 Mon Sep 17 00:00:00 2001 From: Chris Woerz Date: Sat, 3 Jan 2015 13:12:05 -0700 Subject: [PATCH 039/446] finished documentation on the new resource classes, also removed a few suffixes that i added that in hindsight dont really add much value --- doc/source/bindings.rst | 2 + .../structures/vessels/aggregateresource.rst | 84 +++++++++++++++++++ doc/source/structures/vessels/resource.rst | 37 ++++---- doc/source/structures/vessels/vessel.rst | 8 ++ src/kOS/Suffixed/AggregateResourceValue.cs | 29 +++---- src/kOS/Suffixed/SingleResourceValue.cs | 6 +- 6 files changed, 129 insertions(+), 37 deletions(-) create mode 100644 doc/source/structures/vessels/aggregateresource.rst diff --git a/doc/source/bindings.rst b/doc/source/bindings.rst index f93c41d59..30c68c27b 100644 --- a/doc/source/bindings.rst +++ b/doc/source/bindings.rst @@ -114,6 +114,8 @@ Any other resources that you have added using other mods should be query-able this way, provided that you spell the term exactly as it appears in the resources window. +You can also get a list of all resources, either in SHIP: or STAGE: with the :RESOURCES suffix. + ALT ALIAS --------- diff --git a/doc/source/structures/vessels/aggregateresource.rst b/doc/source/structures/vessels/aggregateresource.rst new file mode 100644 index 000000000..64947c232 --- /dev/null +++ b/doc/source/structures/vessels/aggregateresource.rst @@ -0,0 +1,84 @@ +.. _aggregateresource: + +AggregateResource +======== + +A ship can have many parts that contain resources (i.e. fuel, electric charge, etc). kOS has several tools for getting the summation of each resource. + +This is the type returned as the elements of the list in :ref:`LIST RESOURCES + +IN MyList `:: + + PRINT "THESE ARE ALL THE RESOURCES ON THE SHIP:". + LIST RESOURCES IN RESLIST. + FOR RES IN RESLIST { + PRINT "Resource " + RES:NAME. + PRINT " value = " + AMOUNT. + PRINT " which is " + + ROUND(100*RES:AMOUNT/RES:CAPACITY) + + "% full.". + }. + +This is also the type returned by STAGE:RESOURCES + + PRINT "THESE ARE ALL THE RESOURCES active in this stage:". + SET RESLIST TO STAGE:RESOURCES. + FOR RES IN RESLIST { + PRINT "Resource " + RES:NAME. + PRINT " value = " + AMOUNT. + PRINT " which is " + + ROUND(100*RES:AMOUNT/RES:CAPACITY) + + "% full.". + }. + +.. structure:: Resource + + .. list-table:: + :header-rows: 1 + :widths: 2 1 4 + + * - Suffix + - Type + - Description + + * - :attr:`NAME` + - string + - Resource name + * - :attr:`AMOUNT` + - scalar + - Amount of this resource left + * - :attr:`CAPACITY` + - scalar + - Maximum amount of this resource + * - :attr:`PARTS` + - List + - A collection of the parts that can contain this resource + + +.. attribute:: Resource:NAME + + :access: Get only + :type: string + + The name of the resource, i.e. "LIQUIDFUEL", "ELECTRICCHARGE", "MONOPROP". + +.. attribute:: Resource:AMOUNT + + :access: Get only + :type: scalar + + The value of how much resource is left. + +.. attribute:: Resource:CAPACITY + + :access: Get only + :type: scalar + + What AMOUNT would be if the resource was filled to the top. + +.. attribute:: Resource:PARTS + + :access: Get only + :type: List + + Because this is a summation of the resources from many parts. kOS gives you the list of all parts that do or could contain the resource. \ No newline at end of file diff --git a/doc/source/structures/vessels/resource.rst b/doc/source/structures/vessels/resource.rst index fe5e2aecb..976851c18 100644 --- a/doc/source/structures/vessels/resource.rst +++ b/doc/source/structures/vessels/resource.rst @@ -3,19 +3,7 @@ Resource ======== -A single resource value a thing holds (i.e. fuel, electric charge, etc). This is the type returned as the elements of the list in :ref:`LIST RESOURCES -IN MyList `:: - - PRINT "THESE ARE ALL THE RESOURCES ON THE SHIP:". - LIST RESOURCES IN RESLIST. - FOR RES IN RESLIST { - PRINT "Resource " + RES:NAME. - PRINT " value = " + AMOUNT. - PRINT " which is " - + ROUND(100*RES:AMOUNT/RES:CAPACITY) - + "% full.". - }. - +A single resource value a thing holds (i.e. fuel, electric charge, etc). This is the type returned by the :struct:`Part`:RESOURCES suffix .. structure:: Resource @@ -36,7 +24,14 @@ IN MyList `:: * - :attr:`CAPACITY` - scalar - Maximum amount of this resource - + * - :attr:`TOGGLEABLE` + - boolean + - Can this tank be removed from the fuel flow + * - :attr:`ENABLED` + - boolean + - Is this tank currently in the fuel flow + + .. attribute:: Resource:NAME :access: Get only @@ -58,3 +53,17 @@ IN MyList `:: What AMOUNT would be if the resource was filled to the top. + +.. attribute:: Resource:TOGGLEABLE + + :access: Get only + :type: boolean + + Many, but not all, resources can be turned on and off, this removes them from the fuel flow. + +.. attribute:: Resource:ENABLED + + :access: Get/Set + :type: boolean + + If the resource is TOGGLEABLE, setting this to false will prevent the resource from being taken out normally. diff --git a/doc/source/structures/vessels/vessel.rst b/doc/source/structures/vessels/vessel.rst index 126b33378..af25fb906 100644 --- a/doc/source/structures/vessels/vessel.rst +++ b/doc/source/structures/vessels/vessel.rst @@ -52,6 +52,7 @@ All vessels share a structure. To get a variable referring to any vessel you can :attr:`PATCHES` :struct:`List` :struct:`Orbit` patches :attr:`ROOTPART` :struct:`Part` Root :struct:`Part` of this vessel :attr:`PARTS` :struct:`List` all :struct:`Parts ` + :attr:`RESOURCES` :struct:`List` all :struct:`AggrgateResources ` :meth:`PARTSNAMED(name)` :struct:`List` :struct:`Parts ` by :attr:`NAME ` :meth:`PARTSTITLED(title)` :struct:`List` :struct:`Parts ` by :attr:`TITLE ` :meth:`PARTSTAGGED(tag)` :struct:`List` :struct:`Parts ` by :attr:`TAG ` @@ -225,6 +226,13 @@ All vessels share a structure. To get a variable referring to any vessel you can A List of all the :ref:`parts ` on the vessel. ``SET FOO TO SHIP:PARTS.`` has exactly the same effect as ``LIST PARTS IN FOO.``. For more information, see :ref:`ship parts and modules `. +.. attribute:: Vessel:RESOURCES + + :type: :struct:`List` of :struct:`AggregateResource` objects + :access: Get only + + A List of all the :ref:`AggregateResources ` on the vessel. ``SET FOO TO SHIP:RESOURCES.`` has exactly the same effect as ``LIST RESOURCES IN FOO.``. + .. method:: Vessel:PARTSNAMED(name) diff --git a/src/kOS/Suffixed/AggregateResourceValue.cs b/src/kOS/Suffixed/AggregateResourceValue.cs index db25e1399..6891c6df0 100644 --- a/src/kOS/Suffixed/AggregateResourceValue.cs +++ b/src/kOS/Suffixed/AggregateResourceValue.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using System.Linq; +using System.Net; using kOS.Safe.Encapsulation; using kOS.Safe.Encapsulation.Suffixes; using kOS.Suffixed.Part; @@ -44,9 +45,8 @@ public override string ToString() return string.Format("SHIPRESOURCE({0},{1},{2})", name, amount, capacity); } - public static ListValue PartsToList(IEnumerable parts, SharedObjects shared) + private static Dictionary ProspectResources(IEnumerable parts, SharedObjects shared) { - var list = new ListValue(); var resources = new Dictionary(); foreach (var part in parts) { @@ -61,6 +61,13 @@ public static ListValue PartsToList(IEnumerable parts, SharedObjec resources[module.resourceName] = aggregateResourceAmount; } } + return resources; + } + + public static ListValue PartsToList(IEnumerable parts, SharedObjects shared) + { + var list = new ListValue(); + var resources = ProspectResources(parts, shared); foreach (var resource in resources) { list.Add(resource.Value); @@ -70,23 +77,7 @@ public static ListValue PartsToList(IEnumerable parts, SharedObjec public static ListValue FromVessel(Vessel vessel, SharedObjects shared) { - var resources = new Dictionary(); - - foreach (var resource in vessel.parts.SelectMany(part => part.Resources.list)) - { - AggregateResourceValue resourceValue; - if (resources.TryGetValue(resource.info.name, out resourceValue)) - { - resourceValue.AddResource(resource); - } - else - { - var newResource = new AggregateResourceValue(resource.info.name, shared); - newResource.AddResource(resource); - - resources.Add(resource.info.name, newResource); - } - } + var resources = ProspectResources(vessel.parts, shared); return ListValue.CreateList(resources.Values); } } diff --git a/src/kOS/Suffixed/SingleResourceValue.cs b/src/kOS/Suffixed/SingleResourceValue.cs index 690a31713..5dc592206 100644 --- a/src/kOS/Suffixed/SingleResourceValue.cs +++ b/src/kOS/Suffixed/SingleResourceValue.cs @@ -19,11 +19,9 @@ private void InitializeSuffixes() AddSuffix("NAME", new Suffix(() => partResource.resourceName)); AddSuffix("AMOUNT", new Suffix(() => partResource.amount)); AddSuffix("DENSITY", new Suffix(() => partResource.info.density)); - AddSuffix("UNITCOST", new Suffix(() => partResource.info.unitCost)); AddSuffix("CAPACITY", new Suffix(() => partResource.maxAmount)); - AddSuffix("TWEAKABLE", new Suffix(() => partResource.isTweakable)); - AddSuffix("FLOWMODE", new Suffix(() => partResource.flowMode.ToString())); - AddSuffix("FLOWSTATE", new SetSuffix(() => partResource.flowState, value => + AddSuffix("TOGGLEABLE", new Suffix(() => partResource.isTweakable)); + AddSuffix("ENABLED", new SetSuffix(() => partResource.flowState, value => { if (partResource.isTweakable) { From bd5c2aded0d1dc037038b48e3fe43a3348aa800c Mon Sep 17 00:00:00 2001 From: Chris Woerz Date: Sat, 3 Jan 2015 13:16:27 -0700 Subject: [PATCH 040/446] fixing some references going to the wrong resource type --- doc/source/commands/list.rst | 2 +- doc/source/structures.rst | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/source/commands/list.rst b/doc/source/commands/list.rst index 39c6c7fd9..049370c7a 100644 --- a/doc/source/commands/list.rst +++ b/doc/source/commands/list.rst @@ -49,7 +49,7 @@ Vessel Lists These generate :struct:`lists ` of items on the :struct:`Vessel`: ``Resources`` - :struct:`List` of :struct:`Resources ` + :struct:`List` of :struct:`AggregateResources ` ``Parts`` :struct:`List` of :struct:`Parts ` ``Engines`` diff --git a/doc/source/structures.rst b/doc/source/structures.rst index b656b65aa..607b5b095 100644 --- a/doc/source/structures.rst +++ b/doc/source/structures.rst @@ -24,7 +24,7 @@ A general discussion of structures :ref:`can be found here * :struct:`Control` * :struct:`ManeuverNode` * :struct:`Engine` - * :struct:`Resource` + * :struct:`AggregateResource` * :struct:`DockingPort` * :struct:`Part` * :struct:`PartModule` From 4db677e53c83978caf0e4ae5bcef15388504893a Mon Sep 17 00:00:00 2001 From: Chris Woerz Date: Sat, 3 Jan 2015 13:21:27 -0700 Subject: [PATCH 041/446] minor --- src/kOS/Suffixed/AggregateResourceValue.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/kOS/Suffixed/AggregateResourceValue.cs b/src/kOS/Suffixed/AggregateResourceValue.cs index 6891c6df0..1c43195dd 100644 --- a/src/kOS/Suffixed/AggregateResourceValue.cs +++ b/src/kOS/Suffixed/AggregateResourceValue.cs @@ -1,6 +1,4 @@ using System.Collections.Generic; -using System.Linq; -using System.Net; using kOS.Safe.Encapsulation; using kOS.Safe.Encapsulation.Suffixes; using kOS.Suffixed.Part; From 5cfa54947c4afc546db71e0ac8813ef736079cc8 Mon Sep 17 00:00:00 2001 From: Chris Woerz Date: Sat, 3 Jan 2015 13:54:44 -0700 Subject: [PATCH 042/446] modifications to previous PRs --- src/kOS/Suffixed/Career.cs | 2 -- src/kOS/Suffixed/WaypointValue.cs | 40 +++++++++++++++---------------- 2 files changed, 19 insertions(+), 23 deletions(-) diff --git a/src/kOS/Suffixed/Career.cs b/src/kOS/Suffixed/Career.cs index 242dfd52e..89efc7ec2 100644 --- a/src/kOS/Suffixed/Career.cs +++ b/src/kOS/Suffixed/Career.cs @@ -1,8 +1,6 @@ using System; -using System.Collections.Generic; using kOS.Safe.Encapsulation.Suffixes; using kOS.Safe.Encapsulation; -using FinePrint; // waypoints are defined here. namespace kOS.Suffixed { diff --git a/src/kOS/Suffixed/WaypointValue.cs b/src/kOS/Suffixed/WaypointValue.cs index 73c65c67b..e9e249e5f 100644 --- a/src/kOS/Suffixed/WaypointValue.cs +++ b/src/kOS/Suffixed/WaypointValue.cs @@ -8,14 +8,14 @@ namespace kOS.Suffixed { public class WaypointValue : Structure { - protected Waypoint wayPoint; - protected CelestialBody cachedBody; - protected SharedObjects shared; + protected Waypoint WayPoint { get; set; } + protected CelestialBody CachedBody { get; set; } + protected SharedObjects Shared { get; set; } public WaypointValue(Waypoint wayPoint, SharedObjects shared) { - this.wayPoint = wayPoint; - this.shared = shared; + WayPoint = wayPoint; + Shared = shared; AddSuffix("DUMP", new NoArgsSuffix(ToVerboseString)); // for debugging AddSuffix("NAME", new NoArgsSuffix(() => wayPoint.name, "Name of waypoint as it appears on the map and contract")); AddSuffix("BODY", new NoArgsSuffix(() => new BodyTarget(GetBody(),shared), "Celestial body the waypoint is attached to")); @@ -32,25 +32,23 @@ public WaypointValue(Waypoint wayPoint, SharedObjects shared) public CelestialBody GetBody() { - if (cachedBody == null) - cachedBody = VesselUtils.GetBodyByName(wayPoint.celestialName); - return cachedBody; + return CachedBody ?? (CachedBody = VesselUtils.GetBodyByName(WayPoint.celestialName)); } - + public GeoCoordinates BuildGeoCoordinates() { - return new GeoCoordinates(GetBody(), shared, wayPoint.latitude, wayPoint.longitude); + return new GeoCoordinates(GetBody(), Shared, WayPoint.latitude, WayPoint.longitude); } public double BuildSeaLevelAltitude() { GeoCoordinates gCoord = BuildGeoCoordinates(); - return gCoord.GetTerrainAltitude() + wayPoint.altitude; + return gCoord.GetTerrainAltitude() + WayPoint.altitude; } public override string ToString() { - return String.Format("Waypoint \"{0}\"", wayPoint.name); + return String.Format("Waypoint \"{0}\"", WayPoint.name); } public string ToVerboseString() @@ -61,18 +59,18 @@ public string ToVerboseString() " body= {1}\n" + " latitude= {2}\n" + " longitude= {3}\n" + - " altitutde= {4}\n" + + " altitude= {4}\n" + " height= {5}\n" + " isOnSurface= {6}\n" + " worldPosition= {7}\n", - wayPoint.name, - wayPoint.celestialName, - wayPoint.latitude, - wayPoint.longitude, - wayPoint.altitude, // A location inside the contract range's altitude range - and NOT the edge of it. - wayPoint.height, - wayPoint.isOnSurface, - wayPoint.worldPosition); + WayPoint.name, + WayPoint.celestialName, + WayPoint.latitude, + WayPoint.longitude, + WayPoint.altitude, // A location inside the contract range's altitude range - and NOT the edge of it. + WayPoint.height, + WayPoint.isOnSurface, + WayPoint.worldPosition); } } From 28f734f3d1a535eab882380f196ab935a59469fe Mon Sep 17 00:00:00 2001 From: Chris Woerz Date: Sat, 3 Jan 2015 14:04:26 -0700 Subject: [PATCH 043/446] added to the changelog --- CHANGELOG.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5360450e3..08c278310 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,7 +11,7 @@ to make sure everything works.) * Now respects the limitations of [0.90 career mode upgrades](http://ksp-kos.github.io/KOS/general/career_limits.html), which may make a few features not work anymore in career mode until you get further progressed along in your building upgrades. ###New Stuff -* Thanks to a new dev team volunteer (username theodoregoetz on github), we have a new, much better and cleaner looking [documentation site](http://ksp-kos.github.io/KOS/) +* Thanks to a new dev team volunteer (username theodoregoetz on github), we have a new, much better and cleaner looking [documentation site](http://ksp-kos.github.io/KOS_DOC/) * Better flight input handling to detect the pilot controls and keep them isolated. * "plays nice" with other autopilots a bit better, using KSP 0.90's new autopiloting hooks. * Ability to read [more data about a ship resource](TODO - Are these in the docs? Put URL here if so.) TODO: i.e. SingleResourceValue:FLOWMODE, for example - see PR #452) @@ -20,6 +20,10 @@ to make sure everything works.) * Added new [WAYPOINT object](http://ksp-kos.github.io/KOS/structures/waypoint.html) to help with locations of some contracts. * Added new :POSITION and :ALTITUDEPOSITION suffixes to [Geocoordinates](http://ksp-kos.github.io/KOS/math/geocoordinates.html) to obtain 3D vectors of their positions in ship-raw coordinate space. +* ADDED muliple new ways to deal with resources. + * STAGE:RESOURCES, SHIP:RESOURCES and TARGET:RESOURCES will let you get a list of the resources for the craft, the difference being that SHIP: and TARGET: includes all resources and STAGE: includes only the resoures that are for "this stage". All three of these will let you get a list of :PARTS that can contain that resource. + * Part resources now gives you access to the resource's tweakable :ENABLE and :TOGGLEABLE can let you remove add a resource to the normal resource flow. + ###Bug Fixes * Better handling of range checking and loading the boot file when remotetech is installed (thanks to hvacengi for this contribution) * Boot file overwrite fix (thanks to pakrym) From 794b75e1a5200276642480e1e7a38814bb045890 Mon Sep 17 00:00:00 2001 From: Chris Woerz Date: Sat, 3 Jan 2015 14:06:26 -0700 Subject: [PATCH 044/446] changed attribution for Johann --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 08c278310..91366eced 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,7 +11,7 @@ to make sure everything works.) * Now respects the limitations of [0.90 career mode upgrades](http://ksp-kos.github.io/KOS/general/career_limits.html), which may make a few features not work anymore in career mode until you get further progressed along in your building upgrades. ###New Stuff -* Thanks to a new dev team volunteer (username theodoregoetz on github), we have a new, much better and cleaner looking [documentation site](http://ksp-kos.github.io/KOS_DOC/) +* Thanks to a new dev team contributer Johann Goetz (@theodoregoetz on github), we have a new, much better and cleaner looking [documentation site](http://ksp-kos.github.io/KOS_DOC/) * Better flight input handling to detect the pilot controls and keep them isolated. * "plays nice" with other autopilots a bit better, using KSP 0.90's new autopiloting hooks. * Ability to read [more data about a ship resource](TODO - Are these in the docs? Put URL here if so.) TODO: i.e. SingleResourceValue:FLOWMODE, for example - see PR #452) From d1b9074b702dd3787051abbedc95e949674f6613 Mon Sep 17 00:00:00 2001 From: Chris Woerz Date: Sat, 3 Jan 2015 17:53:27 -0700 Subject: [PATCH 045/446] fixed some case insensitive matches --- src/kOS/Function/Suffixed.cs | 2 +- src/kOS/Suffixed/StageValues.cs | 19 +++++++++++++------ src/kOS/Utilities/VesselUtils.cs | 2 +- 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/src/kOS/Function/Suffixed.cs b/src/kOS/Function/Suffixed.cs index 9dde2641b..bd050a979 100644 --- a/src/kOS/Function/Suffixed.cs +++ b/src/kOS/Function/Suffixed.cs @@ -358,7 +358,7 @@ public override void Execute(SharedObjects shared) return; } - Waypoint point = wpm.AllWaypoints().FirstOrDefault(p => String.Equals(p.name, pointName,StringComparison.OrdinalIgnoreCase)); + Waypoint point = wpm.AllWaypoints().FirstOrDefault(p => String.Equals(p.name, pointName,StringComparison.CurrentCultureIgnoreCase)); shared.Cpu.PushStack(new WaypointValue(point, shared)); } diff --git a/src/kOS/Suffixed/StageValues.cs b/src/kOS/Suffixed/StageValues.cs index b5500d636..4e04af4af 100644 --- a/src/kOS/Suffixed/StageValues.cs +++ b/src/kOS/Suffixed/StageValues.cs @@ -36,19 +36,26 @@ private ListValue GetResourceManifest() public override object GetSuffix(string suffixName) { - var resourceAmount = GetResourceOfCurrentStage(suffixName); - if (resourceAmount.HasValue) + if (!IsResource(suffixName)) { - return resourceAmount.Value; + return base.GetSuffix(suffixName); } - return base.GetSuffix(suffixName); + var resourceAmount = GetResourceOfCurrentStage(suffixName); + return resourceAmount.HasValue ? resourceAmount.Value : 0.0; + } + + private bool IsResource(string suffixName) + { + return PartResourceLibrary.Instance.resourceDefinitions.Any( + pr => string.Equals(pr.name, suffixName, StringComparison.CurrentCultureIgnoreCase)); } private double? GetResourceOfCurrentStage(string resourceName) { - var resource = shared.Vessel.GetActiveResources().FirstOrDefault(r => string.Equals(r.info.name, resourceName, StringComparison.OrdinalIgnoreCase)); - return resource == null ? null : (double?) Math.Round(resource.amount, 2); + var resource = shared.Vessel.GetActiveResources(); + var match = resource.FirstOrDefault(r => string.Equals(r.info.name, resourceName, StringComparison.InvariantCultureIgnoreCase)); + return match == null ? null : (double?) Math.Round(match.amount, 2); } public override string ToString() diff --git a/src/kOS/Utilities/VesselUtils.cs b/src/kOS/Utilities/VesselUtils.cs index 85a5a28f7..afac4c2c8 100644 --- a/src/kOS/Utilities/VesselUtils.cs +++ b/src/kOS/Utilities/VesselUtils.cs @@ -47,7 +47,7 @@ public static bool TryGetResource(Vessel vessel, string resourceName, out double total = 0; PartResourceDefinition resourceDefinition = PartResourceLibrary.Instance.resourceDefinitions.FirstOrDefault( - rd => rd.name.Equals(resourceName, StringComparison.OrdinalIgnoreCase)); + rd => rd.name.Equals(resourceName, StringComparison.CurrentCultureIgnoreCase)); // Ensure the built-in resource types never produce an error, even if the particular vessel is incapable of carrying them if (resourceDefinition != null) resourceIsFound = true; From a13814b817e697ccd4d0db6d1b99c75392c27dcc Mon Sep 17 00:00:00 2001 From: SirDiazo Date: Sat, 3 Jan 2015 22:17:57 -0700 Subject: [PATCH 046/446] Add AGX support Add AG11 through AG250 get/set commands. Does not support group names Requires AGX Version 1.29 or newer --- src/kOS/Binding/ActionGroups.cs | 38 +++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/src/kOS/Binding/ActionGroups.cs b/src/kOS/Binding/ActionGroups.cs index 5131f2815..c57b32bda 100644 --- a/src/kOS/Binding/ActionGroups.cs +++ b/src/kOS/Binding/ActionGroups.cs @@ -47,7 +47,45 @@ public override void AddTo(SharedObjects shared) shared.BindingMgr.AddGetter("AG8", () => shared.Vessel.ActionGroups[KSPActionGroup.Custom08]); shared.BindingMgr.AddGetter("AG9", () => shared.Vessel.ActionGroups[KSPActionGroup.Custom09]); shared.BindingMgr.AddGetter("AG10", () => shared.Vessel.ActionGroups[KSPActionGroup.Custom10]); + + if (AGExtInstalled()) + { + for (int i2 = 11; i2 <= 250; i2++) + { + int i = i2; + shared.BindingMgr.AddSetter("AG"+i.ToString(), val => AGX2VslActivateGroup(shared.Vessel.rootPart.flightID, i, (bool)val)); + shared.BindingMgr.AddGetter("AG"+i.ToString(), () => AGX2VslGroupState(shared.Vessel.rootPart.flightID, i)); + } + } + + } + + public static bool AGExtInstalled() //is AGX installed? + { + try //try-catch is required as the below code returns a NullRef if AGX is not present. + { + System.Type calledType = System.Type.GetType("ActionGroupsExtended.AGExtExternal, AGExt"); + return (bool)calledType.InvokeMember("AGXInstalled", System.Reflection.BindingFlags.InvokeMethod | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static, null, null, null); + } + catch + { + return false; + } + } + + public static bool AGX2VslActivateGroup(uint FlightID, int group, bool forceDir) //activate/deactivate an action group + { + System.Type calledType = System.Type.GetType("ActionGroupsExtended.AGExtExternal, AGExt"); + bool GroupAct = (bool)calledType.InvokeMember("AGX2VslActivateGroup", System.Reflection.BindingFlags.InvokeMethod | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static, null, null, new System.Object[] { FlightID, group, forceDir }); + return GroupAct; + } + + public static bool AGX2VslGroupState(uint FlightID, int group) + { + System.Type calledType = System.Type.GetType("ActionGroupsExtended.AGExtExternal, AGExt"); + bool GroupAct = (bool)calledType.InvokeMember("AGX2VslGroupState", System.Reflection.BindingFlags.InvokeMethod | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static, null, null, new System.Object[] { FlightID, group }); + return GroupAct; } } } \ No newline at end of file From 061625f3ef7f2c28f23e158753514e1d2d255a6c Mon Sep 17 00:00:00 2001 From: Chris Woerz Date: Sat, 3 Jan 2015 22:43:50 -0700 Subject: [PATCH 047/446] stubbing some api work --- .../ActionGroupsExtended/ActionGroupsExtendedAPI.cs | 12 ++++++++++++ src/kOS/Screen/TermWindow.cs | 9 +++++---- src/kOS/kOS.csproj | 2 ++ 3 files changed, 19 insertions(+), 4 deletions(-) create mode 100644 src/kOS/AddOns/ActionGroupsExtended/ActionGroupsExtendedAPI.cs diff --git a/src/kOS/AddOns/ActionGroupsExtended/ActionGroupsExtendedAPI.cs b/src/kOS/AddOns/ActionGroupsExtended/ActionGroupsExtendedAPI.cs new file mode 100644 index 000000000..4f3623d88 --- /dev/null +++ b/src/kOS/AddOns/ActionGroupsExtended/ActionGroupsExtendedAPI.cs @@ -0,0 +1,12 @@ +namespace kOS.AddOns.ActionGroupsExtended +{ + public class ActionGroupsExtendedAPI + { + private static ActionGroupsExtendedAPI instance; + + public static ActionGroupsExtendedAPI Instance + { + get { return instance ?? (instance = new ActionGroupsExtendedAPI()); } + } + } +} diff --git a/src/kOS/Screen/TermWindow.cs b/src/kOS/Screen/TermWindow.cs index d27b90716..9df1dd855 100644 --- a/src/kOS/Screen/TermWindow.cs +++ b/src/kOS/Screen/TermWindow.cs @@ -13,6 +13,7 @@ namespace kOS.Screen public class TermWindow : KOSManagedWindow { private const int CHARSIZE = 8; + private const string CONTROL_LOCKOUT = "kOSTerminal"; private const int CHARS_PER_ROW = 16; private static readonly string root = KSPUtil.ApplicationRootPath.Replace("\\", "/"); private static readonly Color color = new Color(1, 1, 1, 1); @@ -111,12 +112,12 @@ private void Lock() cameraManager = CameraManager.Instance; cameraManager.enabled = false; - InputLockManager.SetControlLock("kOSTerminal"); + InputLockManager.SetControlLock(CONTROL_LOCKOUT); // Prevent editor keys from being pressed while typing EditorLogic editor = EditorLogic.fetch; //TODO: POST 0.90 REVIEW - if (editor != null && InputLockManager.IsUnlocked(ControlTypes.All)) editor.Lock(true, true, true, "kOSTerminal"); + if (editor != null && InputLockManager.IsUnlocked(ControlTypes.All)) editor.Lock(true, true, true, CONTROL_LOCKOUT); // This seems to be the only way to force KSP to let me lock out the "X" throttle // key. It seems to entirely bypass the logic of every other keypress in the game, @@ -135,13 +136,13 @@ private void Unlock() isLocked = false; - InputLockManager.RemoveControlLock("kOSTerminal"); + InputLockManager.RemoveControlLock(CONTROL_LOCKOUT); cameraManager.enabled = true; EditorLogic editor = EditorLogic.fetch; - if (editor != null) editor.Unlock("kOSTerminal"); + if (editor != null) editor.Unlock(CONTROL_LOCKOUT); // This seems to be the only way to force KSP to let me lock out the "X" throttle // key. It seems to entirely bypass the logic of every other keypress in the game: diff --git a/src/kOS/kOS.csproj b/src/kOS/kOS.csproj index e7e330456..2c445eb01 100644 --- a/src/kOS/kOS.csproj +++ b/src/kOS/kOS.csproj @@ -48,6 +48,7 @@ + @@ -155,6 +156,7 @@ Resources.Designer.cs + From b23b78c5871baeabd47c23e96dc248deb9a827eb Mon Sep 17 00:00:00 2001 From: Chris Woerz Date: Sat, 3 Jan 2015 23:51:22 -0700 Subject: [PATCH 048/446] reformatted AGX code --- .../ActionGroupsExtendedAPI.cs | 38 ++++++++++++++++++- .../ActionGroupsExtendedBinding.cs | 20 ++++++++++ src/kOS/Binding/ActionGroups.cs | 38 ------------------- src/kOS/kOS.csproj | 1 + 4 files changed, 57 insertions(+), 40 deletions(-) create mode 100644 src/kOS/AddOns/ActionGroupsExtended/ActionGroupsExtendedBinding.cs diff --git a/src/kOS/AddOns/ActionGroupsExtended/ActionGroupsExtendedAPI.cs b/src/kOS/AddOns/ActionGroupsExtended/ActionGroupsExtendedAPI.cs index 4f3623d88..ac7e23517 100644 --- a/src/kOS/AddOns/ActionGroupsExtended/ActionGroupsExtendedAPI.cs +++ b/src/kOS/AddOns/ActionGroupsExtended/ActionGroupsExtendedAPI.cs @@ -1,12 +1,46 @@ -namespace kOS.AddOns.ActionGroupsExtended +using System.Reflection; + +namespace kOS.AddOns.ActionGroupsExtended { public class ActionGroupsExtendedAPI { + private const BindingFlags BINDINGS = BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Static; private static ActionGroupsExtendedAPI instance; - + + private readonly System.Type calledType; + public static ActionGroupsExtendedAPI Instance { get { return instance ?? (instance = new ActionGroupsExtendedAPI()); } } + + public ActionGroupsExtendedAPI() + { + calledType = System.Type.GetType("ActionGroupsExtended.AGExtExternal, AGExt"); + } + + public bool Installed() + { + try //try-catch is required as the below code returns a NullRef if AGX is not present. + { + return (bool)calledType.InvokeMember("AGXInstalled", BINDINGS, null, null, null); + } + catch + { + return false; + } + } + + public bool ActivateGroup(uint flightID, int group, bool forceDir) //activate/deactivate an action group + { + var args = new System.Object[] {flightID, group, forceDir}; + return (bool)calledType.InvokeMember("AGX2VslActivateGroup", BINDINGS, null, null, args); + } + + public bool GetGroupState(uint flightID, int group) + { + var args = new System.Object[] {flightID, group}; + return (bool)calledType.InvokeMember("AGX2VslGroupState", BINDINGS, null, null, args); + } } } diff --git a/src/kOS/AddOns/ActionGroupsExtended/ActionGroupsExtendedBinding.cs b/src/kOS/AddOns/ActionGroupsExtended/ActionGroupsExtendedBinding.cs new file mode 100644 index 000000000..72c05c006 --- /dev/null +++ b/src/kOS/AddOns/ActionGroupsExtended/ActionGroupsExtendedBinding.cs @@ -0,0 +1,20 @@ +using kOS.Safe.Binding; + +namespace kOS.AddOns.ActionGroupsExtended +{ + [Binding("ksp")] + public class ActionGroupsExtendedBinding : Binding.Binding + { + public override void AddTo(SharedObjects shared) + { + if (!ActionGroupsExtendedAPI.Instance.Installed()) return; + + for (int outerIndex = 11; outerIndex <= 250; outerIndex++) + { + int i = outerIndex; + shared.BindingMgr.AddSetter("AG" + i, val => ActionGroupsExtendedAPI.Instance.ActivateGroup(shared.Vessel.rootPart.flightID, i, (bool) val)); + shared.BindingMgr.AddGetter("AG" + i, () => ActionGroupsExtendedAPI.Instance.GetGroupState(shared.Vessel.rootPart.flightID, i)); + } + } + } +} diff --git a/src/kOS/Binding/ActionGroups.cs b/src/kOS/Binding/ActionGroups.cs index c57b32bda..ed7a4ca2f 100644 --- a/src/kOS/Binding/ActionGroups.cs +++ b/src/kOS/Binding/ActionGroups.cs @@ -47,45 +47,7 @@ public override void AddTo(SharedObjects shared) shared.BindingMgr.AddGetter("AG8", () => shared.Vessel.ActionGroups[KSPActionGroup.Custom08]); shared.BindingMgr.AddGetter("AG9", () => shared.Vessel.ActionGroups[KSPActionGroup.Custom09]); shared.BindingMgr.AddGetter("AG10", () => shared.Vessel.ActionGroups[KSPActionGroup.Custom10]); - - if (AGExtInstalled()) - { - for (int i2 = 11; i2 <= 250; i2++) - { - int i = i2; - shared.BindingMgr.AddSetter("AG"+i.ToString(), val => AGX2VslActivateGroup(shared.Vessel.rootPart.flightID, i, (bool)val)); - shared.BindingMgr.AddGetter("AG"+i.ToString(), () => AGX2VslGroupState(shared.Vessel.rootPart.flightID, i)); - } - } - - } - - public static bool AGExtInstalled() //is AGX installed? - { - try //try-catch is required as the below code returns a NullRef if AGX is not present. - { - System.Type calledType = System.Type.GetType("ActionGroupsExtended.AGExtExternal, AGExt"); - return (bool)calledType.InvokeMember("AGXInstalled", System.Reflection.BindingFlags.InvokeMethod | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static, null, null, null); - } - catch - { - return false; - } } - public static bool AGX2VslActivateGroup(uint FlightID, int group, bool forceDir) //activate/deactivate an action group - { - - System.Type calledType = System.Type.GetType("ActionGroupsExtended.AGExtExternal, AGExt"); - bool GroupAct = (bool)calledType.InvokeMember("AGX2VslActivateGroup", System.Reflection.BindingFlags.InvokeMethod | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static, null, null, new System.Object[] { FlightID, group, forceDir }); - return GroupAct; - } - - public static bool AGX2VslGroupState(uint FlightID, int group) - { - System.Type calledType = System.Type.GetType("ActionGroupsExtended.AGExtExternal, AGExt"); - bool GroupAct = (bool)calledType.InvokeMember("AGX2VslGroupState", System.Reflection.BindingFlags.InvokeMethod | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static, null, null, new System.Object[] { FlightID, group }); - return GroupAct; - } } } \ No newline at end of file diff --git a/src/kOS/kOS.csproj b/src/kOS/kOS.csproj index 2c445eb01..e1c4f7d61 100644 --- a/src/kOS/kOS.csproj +++ b/src/kOS/kOS.csproj @@ -49,6 +49,7 @@ + From 512ce8ba742e62d1b600885174ef72e928216dc9 Mon Sep 17 00:00:00 2001 From: Chris Woerz Date: Sun, 4 Jan 2015 00:01:12 -0700 Subject: [PATCH 049/446] more DRY --- .../ActionGroupsExtended/ActionGroupsExtendedBinding.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/kOS/AddOns/ActionGroupsExtended/ActionGroupsExtendedBinding.cs b/src/kOS/AddOns/ActionGroupsExtended/ActionGroupsExtendedBinding.cs index 72c05c006..b3a9f7424 100644 --- a/src/kOS/AddOns/ActionGroupsExtended/ActionGroupsExtendedBinding.cs +++ b/src/kOS/AddOns/ActionGroupsExtended/ActionGroupsExtendedBinding.cs @@ -9,11 +9,14 @@ public override void AddTo(SharedObjects shared) { if (!ActionGroupsExtendedAPI.Instance.Installed()) return; + var flightId = shared.Vessel.rootPart.flightID; + var api = ActionGroupsExtendedAPI.Instance; + for (int outerIndex = 11; outerIndex <= 250; outerIndex++) { int i = outerIndex; - shared.BindingMgr.AddSetter("AG" + i, val => ActionGroupsExtendedAPI.Instance.ActivateGroup(shared.Vessel.rootPart.flightID, i, (bool) val)); - shared.BindingMgr.AddGetter("AG" + i, () => ActionGroupsExtendedAPI.Instance.GetGroupState(shared.Vessel.rootPart.flightID, i)); + shared.BindingMgr.AddSetter("AG" + i, val => api.ActivateGroup(flightId, i, (bool) val)); + shared.BindingMgr.AddGetter("AG" + i, () => api.GetGroupState(flightId, i)); } } } From 61b1450a86570ba93fb716a845880325006793b2 Mon Sep 17 00:00:00 2001 From: Chris Woerz Date: Sun, 4 Jan 2015 00:21:16 -0700 Subject: [PATCH 050/446] changed parameter type to be less derived --- .../ActionGroupsExtendedAPI.cs | 25 ++++++++++++++++--- .../ActionGroupsExtendedBinding.cs | 6 ++--- 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/src/kOS/AddOns/ActionGroupsExtended/ActionGroupsExtendedAPI.cs b/src/kOS/AddOns/ActionGroupsExtended/ActionGroupsExtendedAPI.cs index ac7e23517..cd39eb9fa 100644 --- a/src/kOS/AddOns/ActionGroupsExtended/ActionGroupsExtendedAPI.cs +++ b/src/kOS/AddOns/ActionGroupsExtended/ActionGroupsExtendedAPI.cs @@ -19,6 +19,10 @@ public ActionGroupsExtendedAPI() calledType = System.Type.GetType("ActionGroupsExtended.AGExtExternal, AGExt"); } + /// + /// Tests for the presence of AGX + /// + /// Is AGX installed? public bool Installed() { try //try-catch is required as the below code returns a NullRef if AGX is not present. @@ -31,15 +35,28 @@ public bool Installed() } } - public bool ActivateGroup(uint flightID, int group, bool forceDir) //activate/deactivate an action group + /// + /// Activates one of the extended action group extended. + /// + /// The vessel that will catch the action + /// A ActionGroup number from 11-251 + /// The value you want to set the action group to + /// The Action group state + public bool ActivateGroup(Vessel vessel, int group, bool forceDir) //activate/deactivate an action group { - var args = new System.Object[] {flightID, group, forceDir}; + var args = new System.Object[] {vessel.rootPart.flightID, group, forceDir}; return (bool)calledType.InvokeMember("AGX2VslActivateGroup", BINDINGS, null, null, args); } - public bool GetGroupState(uint flightID, int group) + /// + /// Gets the state of an action group + /// + /// The vessel that will catch the action + /// A ActionGroup number from 11-251 + /// The Action group state + public bool GetGroupState(Vessel vessel, int group) { - var args = new System.Object[] {flightID, group}; + var args = new System.Object[] {vessel.rootPart.flightID, group}; return (bool)calledType.InvokeMember("AGX2VslGroupState", BINDINGS, null, null, args); } } diff --git a/src/kOS/AddOns/ActionGroupsExtended/ActionGroupsExtendedBinding.cs b/src/kOS/AddOns/ActionGroupsExtended/ActionGroupsExtendedBinding.cs index b3a9f7424..fb5ca6c5a 100644 --- a/src/kOS/AddOns/ActionGroupsExtended/ActionGroupsExtendedBinding.cs +++ b/src/kOS/AddOns/ActionGroupsExtended/ActionGroupsExtendedBinding.cs @@ -9,14 +9,14 @@ public override void AddTo(SharedObjects shared) { if (!ActionGroupsExtendedAPI.Instance.Installed()) return; - var flightId = shared.Vessel.rootPart.flightID; + var vessel = shared.Vessel; var api = ActionGroupsExtendedAPI.Instance; for (int outerIndex = 11; outerIndex <= 250; outerIndex++) { int i = outerIndex; - shared.BindingMgr.AddSetter("AG" + i, val => api.ActivateGroup(flightId, i, (bool) val)); - shared.BindingMgr.AddGetter("AG" + i, () => api.GetGroupState(flightId, i)); + shared.BindingMgr.AddSetter("AG" + i, val => api.ActivateGroup(vessel, i, (bool) val)); + shared.BindingMgr.AddGetter("AG" + i, () => api.GetGroupState(vessel, i)); } } } From 382faae59ef93a49d408edc667a3d7342368df09 Mon Sep 17 00:00:00 2001 From: Chris Woerz Date: Sun, 4 Jan 2015 15:11:12 -0700 Subject: [PATCH 051/446] avoided horrible 2 way merge by stealing Dunbaratu's code --- doc/source/commands/files.rst | 4 ++-- doc/source/commands/flight/raw.rst | 2 +- doc/source/general.rst | 4 ++++ doc/source/general/comm_range.rst | 2 +- doc/source/language/flow.rst | 2 +- doc/source/language/variables.rst | 7 +++++++ doc/source/math/direction.rst | 4 ++-- doc/source/math/geocoordinates.rst | 2 +- doc/source/structures.rst | 3 +++ doc/source/structures/misc/fileinfo.rst | 1 + doc/source/structures/orbits/orbit.rst | 4 ++-- doc/source/structures/vessels/aggregateresource.rst | 12 ++++++------ doc/source/structures/vessels/resource.rst | 2 +- doc/source/structures/waypoint.rst | 7 ++++--- 14 files changed, 36 insertions(+), 20 deletions(-) diff --git a/doc/source/commands/files.rst b/doc/source/commands/files.rst index f3c52c587..14b9d81a4 100644 --- a/doc/source/commands/files.rst +++ b/doc/source/commands/files.rst @@ -93,8 +93,8 @@ Pre-compiles a script into an :ref:`Kerboscript ML Exceutable image ` that can be used instead of executing the program discript directly. -The RUN command (elsewhere on this page) can work with either *.ks -script files or *.ksm compiled files. +The RUN command (elsewhere on this page) can work with either \*.ks +script files or \*.ksm compiled files. The full details of this process are long and complex enough to be placed on a separate page. diff --git a/doc/source/commands/flight/raw.rst b/doc/source/commands/flight/raw.rst index 5227f438c..cc94b8df8 100644 --- a/doc/source/commands/flight/raw.rst +++ b/doc/source/commands/flight/raw.rst @@ -41,7 +41,7 @@ Raw Flight Controls Reference These "Raw" controls allow you the direct control of flight parameters while the current program is running. .. note:: - The ``MAINTHROTTLE`` requires active engines and, of course, sufficient and appropriate fuel. The rotational controls ``YAW``, ``PITCH`` and ``ROW`` require active reaction wheels with sufficient energy or *RCS* to be ``ON`` with properly placed thrusters and appropriate fuel. The translational controls ``FORE``, ``STARBOARD`` and ``TOP`` require *RCS* to be ``ON`` with properly placed thrusters and appropriate fuel. + The ``MAINTHROTTLE`` requires active engines and, of course, sufficient and appropriate fuel. The rotational controls ``YAW``, ``PITCH`` and ``ROW`` require active reaction wheels with sufficient energy or *RCS* to be ON with properly placed thrusters and appropriate fuel. The translational controls ``FORE``, ``STARBOARD`` and ``TOP`` require *RCS* to be ON with properly placed thrusters and appropriate fuel. .. list-table:: diff --git a/doc/source/general.rst b/doc/source/general.rst index 31cb6910c..d54472c28 100644 --- a/doc/source/general.rst +++ b/doc/source/general.rst @@ -8,6 +8,8 @@ These topics discuss the interfacing between **kOS** and **Kerbal Space Program* .. toctree:: :maxdepth: 2 + Bound Variables + CPU Vessel (SHIP) CPU Hardware @@ -20,3 +22,5 @@ These topics discuss the interfacing between **kOS** and **Kerbal Space Program* Parts & PartModules Communication Range + + Respecting Career Limits diff --git a/doc/source/general/comm_range.rst b/doc/source/general/comm_range.rst index 95fcf8c95..b21c1aa10 100644 --- a/doc/source/general/comm_range.rst +++ b/doc/source/general/comm_range.rst @@ -45,7 +45,7 @@ Communications range is decided by how many antennae are installed, and of what The number of meters of range is decided by this formula: -max range = ( (100,000 + L\ *1,000,000) *\ 100^M \* 200^D ) meters Where: \* L = number of longAntenna's on the vessel. \* M = number of mediumDishAntenna's on the vessel. \* D = number of commDish's on the vessel. +max range = ( (100,000 + L\ \*1,000,000) \*\ 100^M \* 200^D ) meters Where: \* L = number of longAntenna's on the vessel. \* M = number of mediumDishAntenna's on the vessel. \* D = number of commDish's on the vessel. +----------------+----------------+-----------------------------------+ diff --git a/doc/source/language/flow.rst b/doc/source/language/flow.rst index 6743c3487..f48a28658 100644 --- a/doc/source/language/flow.rst +++ b/doc/source/language/flow.rst @@ -196,7 +196,7 @@ Example:: A ``WHEN``/``THEN`` trigger is removed when the program that created it exits, even if it has not occurred yet. The ``PRESERVE`` can be used inside the ``THEN`` clause of a ``WHEN`` statement. If you are going to make extensive use of ``WHEN``/``THEN`` triggers, it's important to understand more details of how they :ref:`work in the kOS CPU `. .. index:: ON -.. _on: +.. _on_trigger: ``ON`` ------ diff --git a/doc/source/language/variables.rst b/doc/source/language/variables.rst index 0035a5508..0289b8478 100644 --- a/doc/source/language/variables.rst +++ b/doc/source/language/variables.rst @@ -8,6 +8,7 @@ Variables & Statements :depth: 1 .. _declare: + ``DECLARE`` ----------- @@ -16,6 +17,7 @@ Declares a global variable. Alternatively, a variable can be implicitly declared DECLARE X. .. _declare parameter: + ``DECLARE PARAMETER`` --------------------- @@ -64,6 +66,7 @@ The ``DECLARE PARAMETER`` statements can appear anywhere in a program as long as At the moment the only kind of parameter supported is a pass-by-value parameter, and pass-by reference parameters don't exist. Be aware, however, that due to the way kOS is implemented on top of a reference-using object-oriented language (CSharp), if you pass an argument which is a complex aggregate structure (i.e. a Vector, or a List - anything that kOS lets you use a colon suffix with), then the parameters will behave exactly like being passed by reference because all you're passing is the handle to the object rather than the object itself. This should be familiar behavior to anyone who has written software in Java or C# before. .. _set: + ``SET`` ------- @@ -72,6 +75,7 @@ Sets the value of a variable. Declares a global variable if it doesn’t already SET X TO 1. .. _lock: + ``LOCK`` -------- @@ -84,6 +88,7 @@ Declares that the idenifier will refer to an expression that is always re-evalua PRINT X. // prints "3" .. _toggle: + ``TOGGLE`` ---------- @@ -93,6 +98,7 @@ Toggles a variable between ``TRUE`` or ``FALSE``. If the variable in question st TOGGLE SAS. // Toggles SAS on or off. .. _on: + ``ON`` ------ @@ -101,6 +107,7 @@ Sets a variable to ``TRUE``. This is useful for the ``RCS`` and ``SAS`` bindings RCS ON. // Turns on the RCS .. _off: + ``OFF`` ------- diff --git a/doc/source/math/direction.rst b/doc/source/math/direction.rst index 59ba83d14..a6ff1383e 100644 --- a/doc/source/math/direction.rst +++ b/doc/source/math/direction.rst @@ -125,7 +125,7 @@ Structure :attr:`STARVECTOR` :struct:`Vector` This Direction's starboard vector (z axis after rotation). RIGHTVECTOR :struct:`Vector` Alias synonym for :attr:`STARVECTOR` :attr:`INVERSE` :struct:`Direction` The inverse of this direction. - ================ =================== ================================ + ========================= =================== ================================ The :struct:`Direction` object exists primarily to enable automated steering. You can initialize a :struct:`Direction` using a :struct:`Vector` or a ``Rotation``. :struct:`Direction` objects represent a rotation starting from an initial point in **KSP**'s coordinate system where the initial state was looking down the :math:`+z` axis, with the camera "up" being the :math:`+y` axis. So for example, a :struct:`Direction` pointing along the :math:`x` axis might be represented as ``R(0,90,0)``, meaning the initial :math:`z`-axis direction was rotated *90 degrees* around the :math:`y` axis. @@ -192,7 +192,7 @@ Structure Operations and Methods ---------------------- -You can use math operations on :struct:`Direction` objects as well. The next example uses a rotation of "UP" which is a system variable describing a vector directly away from the celestial body you are under the influence of:: +You can use math operations on :struct:`Direction` objects as well. The next example uses a rotation of "UP" which is a system variable describing a vector directly away from the celestial body you are under the influence of: Supported Direction Operators: diff --git a/doc/source/math/geocoordinates.rst b/doc/source/math/geocoordinates.rst index 353d6f635..d3286aa06 100644 --- a/doc/source/math/geocoordinates.rst +++ b/doc/source/math/geocoordinates.rst @@ -30,7 +30,7 @@ Structure .. structure:: GeoCoordinates .. list-table:: - :widths: 2 1 4 + :widths: 2 1 2 4 :header-rows: 1 * - Suffix diff --git a/doc/source/structures.rst b/doc/source/structures.rst index 607b5b095..b6395bcea 100644 --- a/doc/source/structures.rst +++ b/doc/source/structures.rst @@ -19,6 +19,7 @@ A general discussion of structures :ref:`can be found here * :ref:`Celestial Bodies ` * :struct:`Body` * :struct:`Atmosphere` + * :struct:`Waypoint` * :ref:`Vessels ` * :struct:`Vessel` * :struct:`Control` @@ -45,4 +46,6 @@ A general discussion of structures :ref:`can be found here Orbits Celestial Bodies Vessels & Parts + Maneuvering + Waypoints Miscellaneous diff --git a/doc/source/structures/misc/fileinfo.rst b/doc/source/structures/misc/fileinfo.rst index 4f2432bbc..209be3985 100644 --- a/doc/source/structures/misc/fileinfo.rst +++ b/doc/source/structures/misc/fileinfo.rst @@ -82,6 +82,7 @@ File name and size information. You can obtain a list of values of type FileInfo .. _real world timestamp: + Real World Timestamp -------------------- diff --git a/doc/source/structures/orbits/orbit.rst b/doc/source/structures/orbits/orbit.rst index 96f3b10c8..2051880b4 100644 --- a/doc/source/structures/orbits/orbit.rst +++ b/doc/source/structures/orbits/orbit.rst @@ -131,7 +131,7 @@ Structure :type: scalar (degree) :access: Get only - `orbital_inclination`_ + `orbital inclination`_ .. attribute:: Orbit:ECCENTRICITY @@ -232,7 +232,7 @@ Structure .. _true anomaly: http://en.wikipedia.org/wiki/True_anomaly .. _mean anomaly: http://en.wikipedia.org/wiki/Mean_anomaly -:attr:`Orbit:NEXTPATCH` and :attr:`Orbit:HASNEXTPATCH` both only operate on the **current** momentum of the object, and do **not** take into account any potential changes planned with maneuver nodes. To see the possible new path you would have if a maneuver node gets executed exactly as planned, you need to first get the orbit that follows the manuever node, by looking at the :ref:`maneuver node's :ORBIT suffix `_, and then look at **it's** :attr:`Orbit:NEXTPATCH` and :attr:`Orbit:HASNEXTPATCH`. +Both ``:NEXTPATCH`` and ``:HASNEXTPATCH`` both only operate on the **current** momentum of the object, and do **not** take into account any potential changes planned with maneuver nodes. To see the possible new path you would have if a maneuver node gets executed exactly as planned, you need to first get the orbit that follows the manuever node, by looking at the maneuver node's :ORBIT suffix , and then look at **it's** ``:NEXTPATCH` and ``:HASNEXTPATCH``. Deprecated Suffix ----------------- diff --git a/doc/source/structures/vessels/aggregateresource.rst b/doc/source/structures/vessels/aggregateresource.rst index 64947c232..20f03536c 100644 --- a/doc/source/structures/vessels/aggregateresource.rst +++ b/doc/source/structures/vessels/aggregateresource.rst @@ -1,13 +1,13 @@ .. _aggregateresource: AggregateResource -======== +================= A ship can have many parts that contain resources (i.e. fuel, electric charge, etc). kOS has several tools for getting the summation of each resource. -This is the type returned as the elements of the list in :ref:`LIST RESOURCES +This is the type returned as the elements of the list in :ref:`LIST RESOURCES` -IN MyList `:: +IN MyList :: PRINT "THESE ARE ALL THE RESOURCES ON THE SHIP:". LIST RESOURCES IN RESLIST. @@ -19,7 +19,7 @@ IN MyList `:: + "% full.". }. -This is also the type returned by STAGE:RESOURCES +This is also the type returned by STAGE:RESOURCES :: PRINT "THESE ARE ALL THE RESOURCES active in this stage:". SET RESLIST TO STAGE:RESOURCES. @@ -50,7 +50,7 @@ This is also the type returned by STAGE:RESOURCES * - :attr:`CAPACITY` - scalar - Maximum amount of this resource - * - :attr:`PARTS` + * - :attr:`PARTS` - List - A collection of the parts that can contain this resource @@ -81,4 +81,4 @@ This is also the type returned by STAGE:RESOURCES :access: Get only :type: List - Because this is a summation of the resources from many parts. kOS gives you the list of all parts that do or could contain the resource. \ No newline at end of file + Because this is a summation of the resources from many parts. kOS gives you the list of all parts that do or could contain the resource. diff --git a/doc/source/structures/vessels/resource.rst b/doc/source/structures/vessels/resource.rst index 976851c18..f05f1fe78 100644 --- a/doc/source/structures/vessels/resource.rst +++ b/doc/source/structures/vessels/resource.rst @@ -29,7 +29,7 @@ A single resource value a thing holds (i.e. fuel, electric charge, etc). This is - Can this tank be removed from the fuel flow * - :attr:`ENABLED` - boolean - - Is this tank currently in the fuel flow + - Is this tank currently in the fuel flow .. attribute:: Resource:NAME diff --git a/doc/source/structures/waypoint.rst b/doc/source/structures/waypoint.rst index 7a57decc0..8bff67ee9 100644 --- a/doc/source/structures/waypoint.rst +++ b/doc/source/structures/waypoint.rst @@ -19,14 +19,15 @@ Creation This creates a new Waypoint from a name of a waypoint you read from the contract paramters. Note that this only works on contracts you've accpted. Waypoints for proposed contracts haven't accepted yet do not actually work in kOS. - SET spot TO WAYPOINT("herman's folly beta"). + SET spot TO WAYPOINT("herman's folly beta"). The name match is case-insensitive. .. function:: ALLWAYPOINTS() - :return: :struct: `List` of `Waypoint`s - This creates a `List` of `Waypoint` structures for all accepted contracts. Waypoints for proposed contracts you haven't accepted yet do not appear in the list. + :return: :struct:`List` of :struct:`Waypoint` + + This creates a :struct:`List` of :struct:`Waypoint` structures for all accepted contracts. Waypoints for proposed contracts you haven't accepted yet do not appear in the list. Structure --------- From be5e3f0d8280871a9d61566c958cb06ac31b621c Mon Sep 17 00:00:00 2001 From: SirDiazo Date: Sun, 4 Jan 2015 15:57:58 -0700 Subject: [PATCH 052/446] Update ActionGroupsExtendedAPI.cs Tweak what return bool means. --- src/kOS/AddOns/ActionGroupsExtended/ActionGroupsExtendedAPI.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kOS/AddOns/ActionGroupsExtended/ActionGroupsExtendedAPI.cs b/src/kOS/AddOns/ActionGroupsExtended/ActionGroupsExtendedAPI.cs index cd39eb9fa..820378b32 100644 --- a/src/kOS/AddOns/ActionGroupsExtended/ActionGroupsExtendedAPI.cs +++ b/src/kOS/AddOns/ActionGroupsExtended/ActionGroupsExtendedAPI.cs @@ -41,7 +41,7 @@ public bool Installed() /// The vessel that will catch the action /// A ActionGroup number from 11-251 /// The value you want to set the action group to - /// The Action group state + /// Did the action execute? If yes, return True public bool ActivateGroup(Vessel vessel, int group, bool forceDir) //activate/deactivate an action group { var args = new System.Object[] {vessel.rootPart.flightID, group, forceDir}; From 25967d3af2f14bce8afe7b77eddb968c955c73c3 Mon Sep 17 00:00:00 2001 From: SirDiazo Date: Sun, 4 Jan 2015 15:58:34 -0700 Subject: [PATCH 053/446] Update ActionGroupsExtendedAPI.cs --- src/kOS/AddOns/ActionGroupsExtended/ActionGroupsExtendedAPI.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kOS/AddOns/ActionGroupsExtended/ActionGroupsExtendedAPI.cs b/src/kOS/AddOns/ActionGroupsExtended/ActionGroupsExtendedAPI.cs index 820378b32..ab204fbf5 100644 --- a/src/kOS/AddOns/ActionGroupsExtended/ActionGroupsExtendedAPI.cs +++ b/src/kOS/AddOns/ActionGroupsExtended/ActionGroupsExtendedAPI.cs @@ -53,7 +53,7 @@ public bool ActivateGroup(Vessel vessel, int group, bool forceDir) //activate/de /// /// The vessel that will catch the action /// A ActionGroup number from 11-251 - /// The Action group state + /// Did the action execute? If yes, return True public bool GetGroupState(Vessel vessel, int group) { var args = new System.Object[] {vessel.rootPart.flightID, group}; From 69fef5e3c85542f7151ac7e23d2f2fc44dd82c30 Mon Sep 17 00:00:00 2001 From: SirDiazo Date: Sun, 4 Jan 2015 15:59:43 -0700 Subject: [PATCH 054/446] Update ActionGroupsExtendedAPI.cs Undo copy-paste error --- src/kOS/AddOns/ActionGroupsExtended/ActionGroupsExtendedAPI.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kOS/AddOns/ActionGroupsExtended/ActionGroupsExtendedAPI.cs b/src/kOS/AddOns/ActionGroupsExtended/ActionGroupsExtendedAPI.cs index ab204fbf5..c3e6ee473 100644 --- a/src/kOS/AddOns/ActionGroupsExtended/ActionGroupsExtendedAPI.cs +++ b/src/kOS/AddOns/ActionGroupsExtended/ActionGroupsExtendedAPI.cs @@ -53,7 +53,7 @@ public bool ActivateGroup(Vessel vessel, int group, bool forceDir) //activate/de /// /// The vessel that will catch the action /// A ActionGroup number from 11-251 - /// Did the action execute? If yes, return True + /// The group's state. public bool GetGroupState(Vessel vessel, int group) { var args = new System.Object[] {vessel.rootPart.flightID, group}; From c57e8b4a29bbec426155d8b11c373f017cabdf27 Mon Sep 17 00:00:00 2001 From: SirDiazo Date: Sun, 4 Jan 2015 16:01:07 -0700 Subject: [PATCH 055/446] Update README.md --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index f94ba53e8..16b2e25c4 100644 --- a/README.md +++ b/README.md @@ -8,3 +8,6 @@ Documentation : http://ksp-kos.github.io/KOS_DOC/ Addon release thread: http://forum.kerbalspaceprogram.com/threads/68089-0-23-kOS-Scriptable-Autopilot-System-v0-11-2-13 Addon development thread: http://forum.kerbalspaceprogram.com/threads/68096-kOS-Autopilot + + +This fork for adding Action Group Extended support. From 765b3616cc00c18395aa3a3a3c135f2970e71d0a Mon Sep 17 00:00:00 2001 From: SirDiazo Date: Sun, 4 Jan 2015 16:03:26 -0700 Subject: [PATCH 056/446] Update README.md Undo change specific to this fork, it should not carry over to master. --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index 16b2e25c4..3d70c3b11 100644 --- a/README.md +++ b/README.md @@ -9,5 +9,3 @@ Addon release thread: http://forum.kerbalspaceprogram.com/threads/68089-0-23-kOS Addon development thread: http://forum.kerbalspaceprogram.com/threads/68096-kOS-Autopilot - -This fork for adding Action Group Extended support. From c07290cc77addad49504a0a7ca76d657721931ae Mon Sep 17 00:00:00 2001 From: Chris Woerz Date: Sun, 4 Jan 2015 23:11:35 -0700 Subject: [PATCH 057/446] stubbed out addon documentation --- doc/source/addons.rst | 10 ++++++++++ doc/source/addons/AGX.rst | 4 ++++ doc/source/addons/RemoteTech.rst | 4 ++++ 3 files changed, 18 insertions(+) create mode 100644 doc/source/addons.rst create mode 100644 doc/source/addons/AGX.rst create mode 100644 doc/source/addons/RemoteTech.rst diff --git a/doc/source/addons.rst b/doc/source/addons.rst new file mode 100644 index 000000000..5de82956f --- /dev/null +++ b/doc/source/addons.rst @@ -0,0 +1,10 @@ +.. _addons: + +Addon Reference +=================== + +.. toctree:: + :hidden: + + Action Groups Extended + RemoteTech \ No newline at end of file diff --git a/doc/source/addons/AGX.rst b/doc/source/addons/AGX.rst new file mode 100644 index 000000000..3ab82637c --- /dev/null +++ b/doc/source/addons/AGX.rst @@ -0,0 +1,4 @@ +Action Groups Extended +======= + +Stub for action groups extended documentation. \ No newline at end of file diff --git a/doc/source/addons/RemoteTech.rst b/doc/source/addons/RemoteTech.rst new file mode 100644 index 000000000..56ce8af71 --- /dev/null +++ b/doc/source/addons/RemoteTech.rst @@ -0,0 +1,4 @@ +RemoteTech +======= + +Stub for RemoteTech documentation. \ No newline at end of file From ff81199d607e6ee8b291aa0f97a577a2453d49c4 Mon Sep 17 00:00:00 2001 From: SirDiazo Date: Mon, 5 Jan 2015 11:12:16 -0700 Subject: [PATCH 058/446] Update AGX.rst in progress edit 1 --- doc/source/addons/AGX.rst | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/doc/source/addons/AGX.rst b/doc/source/addons/AGX.rst index 3ab82637c..6014c5a15 100644 --- a/doc/source/addons/AGX.rst +++ b/doc/source/addons/AGX.rst @@ -1,4 +1,15 @@ Action Groups Extended ======= -Stub for action groups extended documentation. \ No newline at end of file +- Download: https://github.com/SirDiazo/AGExt/releases +- Forum thread, including full instructions: http://forum.kerbalspaceprogram.com/threads/74195 + +Increase the action groups available to kOS from 10 to 250 and add the ability to edit actions in flight and the ability to name action groups so you describe what a group does. + +Includes a Script Trigger action that can be used to control a running program and visual feedback if an action group is currently activated. + +Works via adding the AG11 through AG250 bindings that behave the same as the AG1 through AG10 bindings in base kOS. + +**Basic Quick Start:** +![](http://members.shaw.ca/diazo/AGExtQuickStart1.jpg) +![](http://members.shaw.ca/diazo/AGExtQuickStart2.jpg) From f887c3bcbea99c9734e5b2e0c837f5df064a4dd0 Mon Sep 17 00:00:00 2001 From: SirDiazo Date: Mon, 5 Jan 2015 11:41:07 -0700 Subject: [PATCH 059/446] Update AGX.rst step2 --- doc/source/addons/AGX.rst | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/doc/source/addons/AGX.rst b/doc/source/addons/AGX.rst index 6014c5a15..e6eafcb72 100644 --- a/doc/source/addons/AGX.rst +++ b/doc/source/addons/AGX.rst @@ -8,8 +8,21 @@ Increase the action groups available to kOS from 10 to 250 and add the ability t Includes a Script Trigger action that can be used to control a running program and visual feedback if an action group is currently activated. -Works via adding the AG11 through AG250 bindings that behave the same as the AG1 through AG10 bindings in base kOS. +**Usage:** +Adds action groups AG11 through AG250 to kOS that are interacted with the same way as the AG1 through AG10 bindings in base kOS are. **Basic Quick Start:** ![](http://members.shaw.ca/diazo/AGExtQuickStart1.jpg) ![](http://members.shaw.ca/diazo/AGExtQuickStart2.jpg) + +**Overview Walkthrough:** +(Video, imagur album, animated gif, something) + +**Known limitations:** + +- The following limitations apply only to AG11 through AG250. AG1 through AG10 will as they have regardless of whether AGX is installed or not. +- For an action group to be useable, it must have an action assigned to it. When installed, AGX adds a "Script Trigger" action to the kOS computer part that serves this purpose if you want an "empty" action group to trigger kOS scripts with. +- Be aware that if you query an emtpy action group, it will always return a state of False and trying to turn an emtpy action group On will do nothing and silently fail without any sort of error message. +- The state of action groups is tracked on a per-action basis, rather then on a per-group basis. Note the following for actions that are assigned to multiple action groups: +-- The state of actions are monitored on the part. + From 9e10cb4672d8e6a77c27c3c26ac4f5eb0af0eb8d Mon Sep 17 00:00:00 2001 From: SirDiazo Date: Mon, 5 Jan 2015 12:00:42 -0700 Subject: [PATCH 060/446] Update AGX.rst 3 --- doc/source/addons/AGX.rst | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/doc/source/addons/AGX.rst b/doc/source/addons/AGX.rst index e6eafcb72..7734a3b00 100644 --- a/doc/source/addons/AGX.rst +++ b/doc/source/addons/AGX.rst @@ -22,7 +22,13 @@ Adds action groups AG11 through AG250 to kOS that are interacted with the same w - The following limitations apply only to AG11 through AG250. AG1 through AG10 will as they have regardless of whether AGX is installed or not. - For an action group to be useable, it must have an action assigned to it. When installed, AGX adds a "Script Trigger" action to the kOS computer part that serves this purpose if you want an "empty" action group to trigger kOS scripts with. -- Be aware that if you query an emtpy action group, it will always return a state of False and trying to turn an emtpy action group On will do nothing and silently fail without any sort of error message. -- The state of action groups is tracked on a per-action basis, rather then on a per-group basis. Note the following for actions that are assigned to multiple action groups: --- The state of actions are monitored on the part. +- Be aware that if you query an empty action group, it will always return a state of False and trying to turn an emtpy action group On will do nothing and silently fail without any sort of error message. +- At this point, AG11 through AG250 do not support RemoteTech. Triggering those action groups will bypass the signal delay and execute those actions immediately. (On the immediate fix list.) + +**Action state monitoring** +Note that the state of action groups is tracked on a per-action basis, rather then on a per-group basis. This results in the group state being handled differently. (Note the following applies only to AG11 through AG250, AG1 through AG10 are not affected by this.) + +- The Script Trigger action found on the kOS computer module is not subject to the below considerations and is the recommended action to use when interacting with a running kOS script. +- The state of actions are monitored on the part and updated automatically. A closed solar panel will return a state of false for all it's actions. (Extend Panels, Retract Panels, Toggle Panels) When you extend the solar panel with either the Extend Panels or Toggle Panels action, all three actions will change to a state of True. Retract the panels and the state of all three actions will become False. +- This can result in an action group have actions in a mixed state where some actions are on and some are off. In this case querying the group state will result in a state of False. For the purposes of the group state being True or False, if *all* actions in the action group are true, the group state will return true. If *any* actions in the group are false,the group state with return False. From fe1792163430659cca8c502092e7c8d39e365d46 Mon Sep 17 00:00:00 2001 From: SirDiazo Date: Mon, 5 Jan 2015 12:17:21 -0700 Subject: [PATCH 061/446] Update AGX.rst 4 --- doc/source/addons/AGX.rst | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/doc/source/addons/AGX.rst b/doc/source/addons/AGX.rst index 7734a3b00..6b573a35e 100644 --- a/doc/source/addons/AGX.rst +++ b/doc/source/addons/AGX.rst @@ -21,14 +21,16 @@ Adds action groups AG11 through AG250 to kOS that are interacted with the same w **Known limitations:** - The following limitations apply only to AG11 through AG250. AG1 through AG10 will as they have regardless of whether AGX is installed or not. -- For an action group to be useable, it must have an action assigned to it. When installed, AGX adds a "Script Trigger" action to the kOS computer part that serves this purpose if you want an "empty" action group to trigger kOS scripts with. -- Be aware that if you query an empty action group, it will always return a state of False and trying to turn an emtpy action group On will do nothing and silently fail without any sort of error message. +- For an action group to be useable, it must have an action assigned to it. When installed, AGX adds a "Script Trigger" action to the kOS computer part that serves this purpose if you want an "empty" action group to trigger kOS scripts with. +- Be aware that if you query an empty action group, it will always return a state of False and trying to turn an emtpy action group On will do nothing and silently fail without any sort of error message. (Groups AG11 through AG250 only. Groups AG1 through AG10 can be empty and will turn On and Off when commanded to.) - At this point, AG11 through AG250 do not support RemoteTech. Triggering those action groups will bypass the signal delay and execute those actions immediately. (On the immediate fix list.) **Action state monitoring** -Note that the state of action groups is tracked on a per-action basis, rather then on a per-group basis. This results in the group state being handled differently. (Note the following applies only to AG11 through AG250, AG1 through AG10 are not affected by this.) + +Note that the state of action groups is tracked on a per-action basis, rather then on a per-group basis. This results in the group state being handled differently. - The Script Trigger action found on the kOS computer module is not subject to the below considerations and is the recommended action to use when interacting with a running kOS script. -- The state of actions are monitored on the part and updated automatically. A closed solar panel will return a state of false for all it's actions. (Extend Panels, Retract Panels, Toggle Panels) When you extend the solar panel with either the Extend Panels or Toggle Panels action, all three actions will change to a state of True. Retract the panels and the state of all three actions will become False. +- The state of actions are monitored on the part and updated automatically. A closed solar panel will return a state of false for all it's actions. (Extend Panels, Retract Panels, Toggle Panels) When you extend the solar panel with either the Extend Panels or Toggle Panels action, all three actions will change to a state of True. Retract the panels and the state of all three actions will become False. Note that this state will update in any action group that contains that action, not just the action group that was activated. - This can result in an action group have actions in a mixed state where some actions are on and some are off. In this case querying the group state will result in a state of False. For the purposes of the group state being True or False, if *all* actions in the action group are true, the group state will return true. If *any* actions in the group are false,the group state with return False. +- When an action triggers an animation, the state of the action will be uncertain until the animation finishes playing. Some parts will report True during the animation and some will report False. It depends on how the part creator set things up and not something AGX can control. From d782427b9079a63e653402e22300790836a6a857 Mon Sep 17 00:00:00 2001 From: SirDiazo Date: Mon, 5 Jan 2015 12:31:11 -0700 Subject: [PATCH 062/446] Update AGX.rst 5 --- doc/source/addons/AGX.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/doc/source/addons/AGX.rst b/doc/source/addons/AGX.rst index 6b573a35e..f52883535 100644 --- a/doc/source/addons/AGX.rst +++ b/doc/source/addons/AGX.rst @@ -20,7 +20,7 @@ Adds action groups AG11 through AG250 to kOS that are interacted with the same w **Known limitations:** -- The following limitations apply only to AG11 through AG250. AG1 through AG10 will as they have regardless of whether AGX is installed or not. +- The following limitations apply only to AG11 through AG250. AG1 through AG10 will behave as they have regardless of whether AGX is installed or not. - For an action group to be useable, it must have an action assigned to it. When installed, AGX adds a "Script Trigger" action to the kOS computer part that serves this purpose if you want an "empty" action group to trigger kOS scripts with. - Be aware that if you query an empty action group, it will always return a state of False and trying to turn an emtpy action group On will do nothing and silently fail without any sort of error message. (Groups AG11 through AG250 only. Groups AG1 through AG10 can be empty and will turn On and Off when commanded to.) - At this point, AG11 through AG250 do not support RemoteTech. Triggering those action groups will bypass the signal delay and execute those actions immediately. (On the immediate fix list.) @@ -33,4 +33,6 @@ Note that the state of action groups is tracked on a per-action basis, rather th - The state of actions are monitored on the part and updated automatically. A closed solar panel will return a state of false for all it's actions. (Extend Panels, Retract Panels, Toggle Panels) When you extend the solar panel with either the Extend Panels or Toggle Panels action, all three actions will change to a state of True. Retract the panels and the state of all three actions will become False. Note that this state will update in any action group that contains that action, not just the action group that was activated. - This can result in an action group have actions in a mixed state where some actions are on and some are off. In this case querying the group state will result in a state of False. For the purposes of the group state being True or False, if *all* actions in the action group are true, the group state will return true. If *any* actions in the group are false,the group state with return False. - When an action triggers an animation, the state of the action will be uncertain until the animation finishes playing. Some parts will report True during the animation and some will report False. It depends on how the part creator set things up and not something AGX can control. +- For clarity, visual feedback can be provided of the current state of an action group. When editing action groups, find the "Toggle Grp." button just below the text entry field for the group name in the main AGX window and enable it. (It is enabled/disabled for the current action group when you click the button.) Once you do this, the text displaying that group will change from gray to colored. Green: Group is activated (state True). Red: Group is deactivated (state False). Yellow: Group is in a mixed state, will return a state False when queried. +- It is okay to activate an already activated group and deactivate a non-activated group. Actions in the group will stil try to execute as normal. From 147d0ea8861ef29777790dab611fc73109879058 Mon Sep 17 00:00:00 2001 From: SirDiazo Date: Mon, 5 Jan 2015 12:58:51 -0700 Subject: [PATCH 063/446] Update AGX.rst 6 --- doc/source/addons/AGX.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/doc/source/addons/AGX.rst b/doc/source/addons/AGX.rst index f52883535..cf8efa076 100644 --- a/doc/source/addons/AGX.rst +++ b/doc/source/addons/AGX.rst @@ -11,6 +11,12 @@ Includes a Script Trigger action that can be used to control a running program a **Usage:** Adds action groups AG11 through AG250 to kOS that are interacted with the same way as the AG1 through AG10 bindings in base kOS are. +- ``AG15 on.`` Activate action group 13. +- ``AG15 off.`` Deactivate action group 13. +- ``print AG15.`` Prints True or False based on action group 15's state. +- And however else you used AG1 can be used for AG15. +- Note: When you issue the ``AG15 on.`` command, all actions in action group 15 are trigged in the activate direction regardless of the current state of the action group. How an action handles being activated when already activated will depend on how the original creator of the action set things up. + **Basic Quick Start:** ![](http://members.shaw.ca/diazo/AGExtQuickStart1.jpg) ![](http://members.shaw.ca/diazo/AGExtQuickStart2.jpg) From c0bdd58f57d08e78c974efe1b1bbf4014b32b6aa Mon Sep 17 00:00:00 2001 From: SirDiazo Date: Mon, 5 Jan 2015 13:27:08 -0700 Subject: [PATCH 064/446] Update AGX.rst --- doc/source/addons/AGX.rst | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/doc/source/addons/AGX.rst b/doc/source/addons/AGX.rst index cf8efa076..d7b4ffa1d 100644 --- a/doc/source/addons/AGX.rst +++ b/doc/source/addons/AGX.rst @@ -4,7 +4,7 @@ Action Groups Extended - Download: https://github.com/SirDiazo/AGExt/releases - Forum thread, including full instructions: http://forum.kerbalspaceprogram.com/threads/74195 -Increase the action groups available to kOS from 10 to 250 and add the ability to edit actions in flight and the ability to name action groups so you describe what a group does. +Increase the action groups available to kOS from 10 to 250 and add the ability to edit actions in flight as well as the ability to name action groups so you describe what a group does. Includes a Script Trigger action that can be used to control a running program and visual feedback if an action group is currently activated. @@ -15,7 +15,23 @@ Adds action groups AG11 through AG250 to kOS that are interacted with the same w - ``AG15 off.`` Deactivate action group 13. - ``print AG15.`` Prints True or False based on action group 15's state. - And however else you used AG1 can be used for AG15. -- Note: When you issue the ``AG15 on.`` command, all actions in action group 15 are trigged in the activate direction regardless of the current state of the action group. How an action handles being activated when already activated will depend on how the original creator of the action set things up. +- Note: When you issue the ``AG15 on.`` command, all actions in action group 15 are trigged in the activate direction regardless of the current state of the action group. How an action handles being activated when already activated will depend on how the original creator of the action set things up. + +Caution: + + + ON AG15 { + print"AG15 triggered!". + preserve. + } + +will behave unexpected if a action triggered by action group 15 has an animation. Because AGX montiors group state per action, the above code will most likely trigger three times (assuming AG15 has a Solar Panel Toggle Action in it): + 1. AG15 is triggered by the player somehow. (AG15 Off -> On) + 2. Panel starts deploying, but AGX sees the action as off while the animation plays and turns the action back off. (AG15 On -> Off) + 3. Animation finishes playing, AGX now sees the action as on and turns the action on (AG15 Off -> On) +If you need to do this, you have to add a delay that is long then the animation time as so: +``Add code snippet`` + **Basic Quick Start:** ![](http://members.shaw.ca/diazo/AGExtQuickStart1.jpg) @@ -40,5 +56,5 @@ Note that the state of action groups is tracked on a per-action basis, rather th - This can result in an action group have actions in a mixed state where some actions are on and some are off. In this case querying the group state will result in a state of False. For the purposes of the group state being True or False, if *all* actions in the action group are true, the group state will return true. If *any* actions in the group are false,the group state with return False. - When an action triggers an animation, the state of the action will be uncertain until the animation finishes playing. Some parts will report True during the animation and some will report False. It depends on how the part creator set things up and not something AGX can control. - For clarity, visual feedback can be provided of the current state of an action group. When editing action groups, find the "Toggle Grp." button just below the text entry field for the group name in the main AGX window and enable it. (It is enabled/disabled for the current action group when you click the button.) Once you do this, the text displaying that group will change from gray to colored. Green: Group is activated (state True). Red: Group is deactivated (state False). Yellow: Group is in a mixed state, will return a state False when queried. -- It is okay to activate an already activated group and deactivate a non-activated group. Actions in the group will stil try to execute as normal. +- It is okay to activate an already activated group and deactivate a non-activated group. Actions in the group will stil try to execute as normal. Exact behavior of a specific action will depend on how the action's creator set things up. From 8ea0a18a7e0dff916b1f7df17fd9b3c14edcc1c8 Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Tue, 6 Jan 2015 05:14:45 -0600 Subject: [PATCH 065/446] telnet server proof of concept start (not working yet) --- src/kOS.Safe/Encapsulation/IConfig.cs | 3 + src/kOS/Suffixed/Config.cs | 35 +++++- src/kOS/UserIO/TelnetMainServer.cs | 100 ++++++++++++++++ src/kOS/UserIO/TelnetSingletonServer.cs | 144 ++++++++++++++++++++++++ src/kOS/kOS.csproj | 6 +- 5 files changed, 284 insertions(+), 4 deletions(-) create mode 100644 src/kOS/UserIO/TelnetMainServer.cs create mode 100644 src/kOS/UserIO/TelnetSingletonServer.cs diff --git a/src/kOS.Safe/Encapsulation/IConfig.cs b/src/kOS.Safe/Encapsulation/IConfig.cs index 6fdfecb20..a3b868f83 100644 --- a/src/kOS.Safe/Encapsulation/IConfig.cs +++ b/src/kOS.Safe/Encapsulation/IConfig.cs @@ -9,6 +9,9 @@ public interface IConfig: ISuffixed, IOperable bool StartOnArchive { get; set; } bool EnableSafeMode { get; set; } bool VerboseExceptions { get; set; } + bool EnableTelnet { get; set; } + int TelnetPort { get; set; } + bool TelnetUsesLoopback { get; set; } void SaveConfig(); } } \ No newline at end of file diff --git a/src/kOS/Suffixed/Config.cs b/src/kOS/Suffixed/Config.cs index 309da5999..fab656c28 100644 --- a/src/kOS/Suffixed/Config.cs +++ b/src/kOS/Suffixed/Config.cs @@ -20,6 +20,9 @@ public class Config : Structure, IConfig public bool StartOnArchive { get { return GetPropValue(PropId.StartOnArchive); } set { SetPropValue(PropId.StartOnArchive, value); } } public bool EnableSafeMode { get { return GetPropValue(PropId.EnableSafeMode); } set { SetPropValue(PropId.EnableSafeMode, value); } } public bool VerboseExceptions { get { return GetPropValue(PropId.VerboseExceptions); } set { SetPropValue(PropId.VerboseExceptions, value); } } + public bool EnableTelnet { get { return GetPropValue(PropId.EnableTelnet); } set { SetPropValue(PropId.EnableTelnet, value); } } + public int TelnetPort { get { return GetPropValue(PropId.TelnetPort); } set { SetPropValue(PropId.TelnetPort, value); } } + public bool TelnetUsesLoopback { get { return GetPropValue(PropId.TelnetUsesLoopback); } set { SetPropValue(PropId.TelnetUsesLoopback, value); } } private Config() { @@ -39,6 +42,9 @@ private void BuildValuesDictionary() AddConfigKey(PropId.StartOnArchive, new ConfigKey("StartOnArchive", "ARCH", "Start on Archive volume", false, false, true, typeof(bool))); AddConfigKey(PropId.EnableSafeMode, new ConfigKey("EnableSafeMode", "SAFE", "Enable safe mode", true, false, true, typeof(bool))); AddConfigKey(PropId.VerboseExceptions, new ConfigKey("VerboseExceptions", "VERBOSE", "Enable verbose exception msgs", true, false, true, typeof(bool))); + AddConfigKey(PropId.EnableTelnet, new ConfigKey("EnableTelnet", "TELNET", "Enable Telnet server", false, false, true, typeof(bool))); + AddConfigKey(PropId.TelnetPort, new ConfigKey("TelnetPort", "TPORT", "Telnet port number", 5410, 1024, 32767, typeof(bool))); + AddConfigKey(PropId.TelnetUsesLoopback, new ConfigKey("TelnetUsesLoopback", "LOOPBACK", "Force telnet to use 127.0.0.1", true, false, true, typeof(bool))); } private void AddConfigKey(PropId id, ConfigKey key) @@ -88,7 +94,7 @@ private void SetPropValue(PropId id, object value) { properties[id].Value = value; } - + public void SaveConfig() { var config = PluginConfiguration.CreateForType(); @@ -173,18 +179,22 @@ private enum PropId EnableRT2Integration = 4, StartOnArchive = 5, EnableSafeMode = 6, - VerboseExceptions = 7 + VerboseExceptions = 7, + EnableTelnet = 8, + TelnetPort = 9, + TelnetUsesLoopback = 10 } } public class ConfigKey { private object val; + private bool valChanged; public string StringKey {get;private set;} public string Alias {get;set;} public string Name {get;set;} public Type ValType {get;set;} - public object Value {get{return val;} set{ val = SafeSetValue(value);} } + public object Value {get{return val;} set{ valChanged = (val != value) ; val = SafeSetValue(value); PostChangeTriggers();} } public object MinValue {get;set;} public object MaxValue {get;set;} @@ -233,5 +243,24 @@ private object SafeSetValue(object newValue) } return returnValue; } + + private void PostChangeTriggers() + { + if (!valChanged) + return; + + // I don't like doing this this way, but I had to put the catch this low-level or else some + // cases of changing the values skips past it: + if (String.Equals(Alias,"TELNET",StringComparison.CurrentCultureIgnoreCase)) + { + if ((bool)Value) + kOS.UserIO.TelnetMainServer.Instance.StartListening(); + else + kOS.UserIO.TelnetMainServer.Instance.StopListening(); + } + + valChanged = false; // reset for next time + } + } } diff --git a/src/kOS/UserIO/TelnetMainServer.cs b/src/kOS/UserIO/TelnetMainServer.cs new file mode 100644 index 000000000..937881458 --- /dev/null +++ b/src/kOS/UserIO/TelnetMainServer.cs @@ -0,0 +1,100 @@ +using System; +using System.Net; +using System.Collections.Generic; +using System.Net.Sockets; +using kOS.Safe.Utilities; +using kOS.Suffixed; +using UnityEngine; + +namespace kOS.UserIO +{ + /// + /// A single instance of the telnet server embedded into kOS. + /// Presents clients with the initial choices and connects + /// them to instances of terminals in the game. + /// kOS should create exactly one and only one instance of this class, + /// and control its options from the Applauncher panel. + ///
+ /// Implemented as a Monobehavior so that it can simulate the concept of forking + /// and threading by having multiple instances of itself responding to their own + /// Update() calls. + ///
+ public class TelnetMainServer : MonoBehaviour + { + private TcpListener server = null; + private IPAddress bindAddr; + private Int32 port; + private List telnets; + private bool isListening; + + public TelnetMainServer() + { + isListening = false; + gameObject.SetActive(false); // Should prevent the Update() from triggering until we turn it on. + telnets = new List(); + + kOS.Safe.Utilities.Debug.Logger.Log("kOS TelnetMainServer class exists."); + } + + public void StartListening() + { + // calling StartListening when already started can cause problems, so quit if already started: + if (isListening) + return; + + // Build the server settings here, not in the constructor, because the settings might have been altered by the user post-init: + + port = Config.Instance.TelnetPort; + if (Config.Instance.TelnetUsesLoopback) + bindAddr = IPAddress.Parse("127.0.0.1"); + else + bindAddr = IPAddress.Any; + + server = new TcpListener(bindAddr, port); + server.Start(); + kOS.Safe.Utilities.Debug.Logger.Log("kOS TelnetMainServer started listening on " + bindAddr + " " + port); + gameObject.SetActive(true); + isListening = true; + } + + public void StopListening() + { + // calling StopListening when already stopped can cause problems, so quit if already stopped: + if (!isListening) + return; + + gameObject.SetActive(false); + kOS.Safe.Utilities.Debug.Logger.Log("kOS TelnetMainServer stopped listening on " + bindAddr + " " + port); + server.Stop(); + foreach (TelnetSingletonServer telnet in telnets) + telnet.StopListening(); + } + + public void Update() + { + Console.WriteLine("PROOF UPDATE IS CALLED A"); + if (!isListening) + return; + Console.WriteLine("PROOF UPDATE IS CALLED B"); + + // .NET's TCP handler only gives you blocking socket accepting, but for the Unity + // Update(), we need to always finish quickly and never block, so check if anything + // is pending first to simulate the effect of a nonblocking socket accept check: + if (!server.Pending()) + return; + Console.WriteLine("PROOF UPDATE IS CALLED C"); + + TcpClient incomingClient = server.AcceptTcpClient(); + Console.WriteLine("PROOF UPDATE IS CALLED D"); + + string remoteIdent = ((IPEndPoint)(incomingClient.Client.RemoteEndPoint)).Address.ToString(); + kOS.Safe.Utilities.Debug.Logger.Log("kOS telnet server got an incoming connection from " + remoteIdent); + Console.WriteLine("PROOF UPDATE IS CALLED E"); + + // Perform something akin to a 'fork', but in Unity by making a new MonoBehavior to handle this + // single client and talk to it, while the main server goes back to just listening to new clients: + telnets.Add(new TelnetSingletonServer(incomingClient)); + telnets[telnets.Count].StartListening(); + } + } +} diff --git a/src/kOS/UserIO/TelnetSingletonServer.cs b/src/kOS/UserIO/TelnetSingletonServer.cs new file mode 100644 index 000000000..2169563c3 --- /dev/null +++ b/src/kOS/UserIO/TelnetSingletonServer.cs @@ -0,0 +1,144 @@ +using System; +using System.Net; +using System.Net.Sockets; +using System.Text; +using kOS.Safe.Utilities; +using UnityEngine; + +namespace kOS.UserIO +{ + /// + /// Spawned by TelnetMainServer, this handles the connection to just one + /// single telnet client, leaving the main server free to go back to listening + /// to other new connecting clients. + /// + public class TelnetSingletonServer : MonoBehaviour + { + // ReSharper disable SuggestUseVarKeywordEvident + // ReSharper disable RedundantDefaultFieldInitializer + private TcpClient client; + private NetworkStream stream; + + private StringBuilder inBuffer = new StringBuilder(); + private int inBufferNextPos = 0; // rather than inefficiently shrinking the buffer from the left end, requiring a new buffer, just track where we are in it. + + private StringBuilder outBuffer = new StringBuilder(); + private int outBufferNextPos = 0; // rather than inefficiently shrinking the buffer from the left end, requiring a new buffer, just track where we are in it. + + private byte[] rawByteBuffer = new byte[32]; // use small chunks to spread across multiple Update()'s + private char[] rawCharBuffer = new char[32]; // use small chunks to spread across multiple Update()'s + + private bool closeWhenFlushed; + // ReSharper enable RedundantDefaultFieldInitializer + // ReSharper enable SuggestUseVarKeywordEvident + + public TelnetSingletonServer(TcpClient client) + { + this.client = client; + stream = client.GetStream(); + + enabled = false; // don't start running the Update() until StartListening(). + } + + public void StartListening() + { + kOS.Safe.Utilities.Debug.Logger.Log("kOS telnet singleton server started listening."); + enabled = true; + closeWhenFlushed = false; + SendText("\r\n\r\nkOS telnet server connection established.\r\n\r\n"); + } + + public void StopListening() + { + kOS.Safe.Utilities.Debug.Logger.Log("kOS telnet singleton server stopped listening."); + SendText("\r\n\r\nkOS telnet server signing off.\r\n\r\n"); + closeWhenFlushed = true; + } + + /// + /// Buffers text to start being sent out to the client on the next Update(). You can + /// make multiple calls to this to keep appending more text to the send buffer. It will + /// start going out to the client as soon as the next Update() hits. + /// + /// + public void SendText(string str) + { + outBuffer.Append(str); + } + + /// + /// Get the next buffer chunk of data from the client stream, or print the next buffer chunk of + /// bytes out to the client stream, or both. Update()'s must finish + /// fast, so don't try to consume or print everything in one call. If there's too much + /// just leave the remainder for the next Update() call. + /// + public virtual void Update() + { + // Detect if the client closed from its end: + if (!client.Connected) + { + enabled = false; + return; + } + + OutputSome(); + InputSome(); + } + + /// + /// Consume a small chunk from the outBuffer to the client stream. Update()'s must finish + /// fast, so don't try to print everything in one call. If there's too much + /// just leave the remainder for the next Update() call. + /// + public void OutputSome() + { + // do nothing if outbuffer is flushed out. + if (outBuffer.Length == 0) + { + // If we were being closed but waiting for flush first, now it's time to close: + if (closeWhenFlushed) + { + enabled = false; + client.Close(); + } + return; + } + + // If it got this far, it has to be because there's at least 1 char to print out. + + // Write the next few chars out: + int numToWrite = System.Math.Min(outBuffer.Length - outBufferNextPos, rawCharBuffer.Length); + inBuffer.CopyTo(outBufferNextPos, rawCharBuffer, 0, numToWrite); + byte[] bytesFromChars = System.Text.Encoding.UTF8.GetBytes(rawCharBuffer, 0, numToWrite); + stream.Write(bytesFromChars, 0, bytesFromChars.Length); + + // Track where in the buffer we are: + outBufferNextPos += numToWrite; + + // If we printed everything and it's all flushed out, then just empty the output buffer entirely and reset the counter: + if (outBufferNextPos >= outBuffer.Length) + { + outBuffer.Remove(0, outBuffer.Length); + outBufferNextPos = 0; + } + } + + /// + /// Read a small chunk from the client stream and add it to the inBuffer. Update()'s must finish + /// fast, so don't try to read everything in one call. If there's too much + /// just leave the remainder for the next Update() call. + /// + public void InputSome() + { + // do nothing if socket has nothing coming in. + if (!stream.DataAvailable) + return; + + // TODO - make this better - right now I'm ignoring the inBuffer and just echoing this out + // to the out buffer to print it back to the user for a test: + int numRead = stream.Read(rawByteBuffer, 0, rawByteBuffer.Length); + outBuffer.AppendFormat("[{0}]",System.Text.Encoding.UTF8.GetString(rawByteBuffer, 0, numRead)); + + } + } +} diff --git a/src/kOS/kOS.csproj b/src/kOS/kOS.csproj index e1c4f7d61..d251cdb42 100644 --- a/src/kOS/kOS.csproj +++ b/src/kOS/kOS.csproj @@ -128,6 +128,8 @@ + + @@ -157,7 +159,9 @@ Resources.Designer.cs
- + + + From f3bea83dc34b8265785eff3bcb6b25f89d96e1a0 Mon Sep 17 00:00:00 2001 From: Johann Goetz Date: Tue, 6 Jan 2015 11:09:50 -0500 Subject: [PATCH 066/446] cleared all warnings in sphinx build. fixed many broken internal links. --- doc/ksdomain.py | 17 +++--- doc/source/addons/AGX.rst | 6 ++- doc/source/addons/RemoteTech.rst | 6 ++- doc/source/commands/flight.rst | 27 ++-------- doc/source/commands/flight/cooked.rst | 14 ++--- doc/source/commands/flight/pilot.rst | 22 ++++---- doc/source/commands/flight/raw.rst | 22 ++++---- doc/source/commands/flight/systems.rst | 2 + doc/source/commands/flight/warp.rst | 3 ++ doc/source/commands/prediction.rst | 32 ++++++------ doc/source/conf.py | 4 +- doc/source/general/cpu_hardware.rst | 6 +-- doc/source/index.rst | 1 + doc/source/language/features.rst | 6 +-- doc/source/language/flow.rst | 18 +++---- doc/source/language/variables.rst | 8 ++- doc/source/math/basic.rst | 12 ++--- doc/source/math/direction.rst | 17 +++--- doc/source/math/ref_frame.rst | 2 +- doc/source/structures.rst | 3 +- doc/source/structures/maneuvering.rst | 10 ---- .../structures/misc/{rgba.rst => colors.rst} | 1 + doc/source/structures/misc/fileinfo.rst | 2 +- doc/source/structures/misc/time.rst | 1 + .../structures/vessels/aggregateresource.rst | 26 +++++----- doc/source/structures/waypoint.rst | 52 ++++++------------- doc/source/tutorials/quickstart.rst | 27 +++++----- 27 files changed, 156 insertions(+), 191 deletions(-) delete mode 100644 doc/source/structures/maneuvering.rst rename doc/source/structures/misc/{rgba.rst => colors.rst} (99%) diff --git a/doc/ksdomain.py b/doc/ksdomain.py index a51d8faa0..398c6ac45 100644 --- a/doc/ksdomain.py +++ b/doc/ksdomain.py @@ -35,7 +35,7 @@ class KOSObject(ObjectDescription): def add_target_and_index(self, name, sig, signode): - targetname = name.upper() + targetname = self.objtype + ':' + name.upper() if targetname not in self.state.document.ids: signode['names'].append(targetname) signode['ids'].append(targetname) @@ -43,14 +43,15 @@ def add_target_and_index(self, name, sig, signode): self.state.document.note_explicit_target(signode) objects = self.env.domaindata['ks']['objects'] - key = (self.objtype, targetname) + key = (self.objtype, name.upper()) if key in objects: self.env.warn(self.env.docname, 'duplicate description of %s %s, ' % - (self.objtype, name) + + (self.objtype, name.upper()) + 'other instance in ' + self.env.doc2path(objects[key]), self.lineno) + objects[key] = self.env.docname indextext = self.get_index_text(self.objtype, name) if indextext: @@ -86,7 +87,7 @@ class KOSFunction(KOSObject): Field('returntype', label=l_('Return type'), has_arg=False, names=('rtype','type')), ] - + def handle_signature(self, sig, signode): m = ks_sig_re.match(sig) name = m.group('object') @@ -177,7 +178,7 @@ def handle_signature(self, sig, signode): if struct is not None: if struct != '': signode += addnodes.desc_type(struct,struct+':') - + signode += addnodes.desc_name(fullname, name) args = m.group('args') @@ -202,7 +203,7 @@ def process_link(self, *args): struct = m.group('prefix').split(':')[-1] target = ':'.join([struct,target]) return title, target.upper() - + class KOSAttrXRefRole(XRefRole): def process_link(self, env, *args): @@ -252,10 +253,10 @@ def resolve_xref(self, env, fromdocname, builder, typ, target, node, objects = self.data['objects'] objtypes = self.objtypes_for_role(typ) for objtype in objtypes: - if (objtype, target) in objects: + if (objtype, target.upper()) in objects: return make_refnode(builder, fromdocname, objects[objtype, target], - target.upper(), + objtype + ':' + target.upper(), contnode, target + ' ' + objtype) def get_objects(self): diff --git a/doc/source/addons/AGX.rst b/doc/source/addons/AGX.rst index 3ab82637c..ebccfd01a 100644 --- a/doc/source/addons/AGX.rst +++ b/doc/source/addons/AGX.rst @@ -1,4 +1,6 @@ +.. _agx: + Action Groups Extended -======= +====================== -Stub for action groups extended documentation. \ No newline at end of file +Stub for action groups extended documentation. diff --git a/doc/source/addons/RemoteTech.rst b/doc/source/addons/RemoteTech.rst index 56ce8af71..4b29d4e9f 100644 --- a/doc/source/addons/RemoteTech.rst +++ b/doc/source/addons/RemoteTech.rst @@ -1,4 +1,6 @@ +.. _remotetech: + RemoteTech -======= +========== -Stub for RemoteTech documentation. \ No newline at end of file +Stub for RemoteTech documentation. diff --git a/doc/source/commands/flight.rst b/doc/source/commands/flight.rst index c70d56683..5f4996b80 100644 --- a/doc/source/commands/flight.rst +++ b/doc/source/commands/flight.rst @@ -4,7 +4,7 @@ Flight Control ++++++++++++++ .. toctree:: - :hidden: + :maxdepth: 1 flight/cooked flight/raw @@ -12,36 +12,17 @@ Flight Control flight/systems flight/warp -.. contents:: - :local: - :depth: 1 - -Unless otherwise stated, all controls that a **kOS** CPU attempts will be done on the :ref:`CPU Vessel `. There are three styles of control: +Unless otherwise stated, all controls that a **kOS** CPU attempts will be done on the :ref:`CPU Vessel `. There are three styles of control: :ref:`Cooked ` Give a goal direction to seek, and let **kOS** find the way to maneuver toward it. - + :ref:`Raw ` Control the craft just like a manual pilot would do from a keyboard or joystick. - + :ref:`Pilot ` This is the stock way of controlling craft, the state of which can be read in **KerboScript**. .. warning:: **SAS OVERRIDES kOS** With the current implementation of flight control, if you leave ``SAS`` turned on, it will override **kOS**'s attempts to steer the ship. In order for **kOS** to be able to turn the ship, you need to set ``SAS OFF``. In manual control, you can pilot with ``SAS ON``, because the pilot's manual controls override the ``SAS`` and "fight" against it. In **KOS** no such ability exists. If ``SAS`` is on, **kOS** won't be able to turn the ship. It is common for people writing **kOS** scripts to explicitly start them with a use of the ``SAS OFF`` command just in case you forgot to turn it off before running the script. - -.. _cooked: -.. include:: flight/cooked.rst - -.. _raw: -.. include:: flight/raw.rst - -.. _pilot: -.. include:: flight/pilot.rst - -.. _systems: -.. include:: flight/systems.rst - -.. _warp: -.. include:: flight/warp.rst diff --git a/doc/source/commands/flight/cooked.rst b/doc/source/commands/flight/cooked.rst index b10331834..af6e107b6 100644 --- a/doc/source/commands/flight/cooked.rst +++ b/doc/source/commands/flight/cooked.rst @@ -1,3 +1,5 @@ +.. _cooked: + Cooked Control ============== @@ -11,7 +13,7 @@ In this style of controlling the craft, you do not steer the craft directly, but .. _LOCK STEERING: .. object:: LOCK STEERING TO value. - This sets the direction **kOS** should point the ship where *value* is a :ref:`Vector ` or a :ref:`Direction ` created from a :ref:`Rotation ` or :ref:`Heading `: + This sets the direction **kOS** should point the ship where *value* is a :struct:`Vector` or a :ref:`Direction ` created from a :ref:`Rotation ` or :ref:`Heading `: :ref:`Rotation ` @@ -22,18 +24,18 @@ In this style of controlling the craft, you do not steer the craft directly, but LOCK STEERING TO Up + R(20,0,0). To select a direction that is due east, aimed at the horizon:: - + LOCK STEERING TO North + R(0,90,0). - + ``UP`` and ``NORTH`` are the only two predefined rotations. - + :ref:`Heading ` - + A heading expressed as ``HEADING(compass, pitch)``. This will aim 30 degrees above the horizon, due south:: LOCK STEERING TO HEADING(180, 30). - :ref:`Vector ` + :struct:`Vector` Any vector can also be used to lock steering:: diff --git a/doc/source/commands/flight/pilot.rst b/doc/source/commands/flight/pilot.rst index de370d21c..c78fe64da 100644 --- a/doc/source/commands/flight/pilot.rst +++ b/doc/source/commands/flight/pilot.rst @@ -1,3 +1,5 @@ +.. _pilot: + Pilot Input =========== @@ -16,11 +18,11 @@ Will ensure that the throttle will be 0 when execution stops. These suffixes all * - Suffix - Type, Range - Equivalent Key - + * - :ref:`PILOTMAINTHROTTLE ` - scalar [0,1] - ``LEFT-CTRL``, ``LEFT-SHIFT`` - + * - :ref:`PILOTYAW ` - scalar [-1,1] - ``D``, ``A`` @@ -31,9 +33,9 @@ Will ensure that the throttle will be 0 when execution stops. These suffixes all - scalar [-1,1] - ``Q``, ``E`` * - :ref:`PILOTROTATION ` - - :ref:`Vector ` + - :struct:`Vector` - ``(YAW,PITCH,ROLL)`` - + * - :ref:`PILOTYAWTRIM ` - scalar [-1,1] - ``ALT+D``, ``ALT+A`` @@ -54,7 +56,7 @@ Will ensure that the throttle will be 0 when execution stops. These suffixes all - scalar [-1,1] - ``I``, ``K`` * - :ref:`PILOTTRANSLATION ` - - :ref:`Vector ` + - :struct:`Vector` - ``(FORE,STARBOARD,TOP)`` * - :ref:`PILOTWHEELSTEER ` @@ -63,7 +65,7 @@ Will ensure that the throttle will be 0 when execution stops. These suffixes all * - :ref:`PILOTWHEELTHROTTLE ` - scalar [-1,1] - ``W``, ``S`` - + * - :ref:`PILOTWHEELSTEERTRIM ` - scalar [-1,1] - ``ALT+A``, ``ALT+D`` @@ -99,7 +101,7 @@ Will ensure that the throttle will be 0 when execution stops. These suffixes all .. _SHIP CONTROL PILOTROTATION: .. object:: SHIP:CONTROL:ROTATION - Returns the pilot's rotation input as a :ref:`Vector ` object containing ``(YAW, PITCH, ROLL)`` in that order. + Returns the pilot's rotation input as a :struct:`Vector` object containing ``(YAW, PITCH, ROLL)`` in that order. @@ -107,12 +109,12 @@ Will ensure that the throttle will be 0 when execution stops. These suffixes all .. object:: SHIP:CONTROL:YAWTRIM Returns the pilot's input for the ``YAW`` of the rotational trim. - + .. _SHIP CONTROL PILOTPITCHTRIM: .. object:: SHIP:CONTROL:PITCHTRIM Returns the pilot's input for the ``PITCH`` of the rotational trim. - + .. _SHIP CONTROL PILOTROLLTRIM: .. object:: SHIP:CONTROL:ROLLTRIM @@ -139,7 +141,7 @@ Will ensure that the throttle will be 0 when execution stops. These suffixes all .. _SHIP CONTROL PILOTTRANSLATION: .. object:: SHIP:CONTROL:TRANSLATION - Returns the the pilot's input for translation as a :ref:`Vector ` ``(FORE, STARBOARD, TOP)``. + Returns the the pilot's input for translation as a :struct:`Vector` ``(FORE, STARBOARD, TOP)``. .. _SHIP CONTROL PILOTWHEELSTEER: .. object:: SHIP:CONTROL:WHEELSTEER diff --git a/doc/source/commands/flight/raw.rst b/doc/source/commands/flight/raw.rst index cc94b8df8..a5d28a5e9 100644 --- a/doc/source/commands/flight/raw.rst +++ b/doc/source/commands/flight/raw.rst @@ -1,3 +1,5 @@ +.. _raw: + Raw Control =========== @@ -51,11 +53,11 @@ These "Raw" controls allow you the direct control of flight parameters while the * - Suffix - Type, Range - Equivalent Key - + * - :ref:`MAINTHROTTLE ` - scalar [0,1] - ``LEFT-CTRL``, ``LEFT-SHIFT`` - + * - :ref:`YAW ` - scalar [-1,1] - ``D``, ``A`` @@ -66,9 +68,9 @@ These "Raw" controls allow you the direct control of flight parameters while the - scalar [-1,1] - ``Q``, ``E`` * - :ref:`ROTATION ` - - :ref:`Vector ` + - :struct:`Vector` - ``(YAW,PITCH,ROLL)`` - + * - :ref:`YAWTRIM ` - scalar [-1,1] - ``ALT+D``, ``ALT+A`` @@ -89,7 +91,7 @@ These "Raw" controls allow you the direct control of flight parameters while the - scalar [-1,1] - ``I``, ``K`` * - :ref:`TRANSLATION ` - - :ref:`Vector ` + - :struct:`Vector` - ``(FORE,STARBOARD,TOP)`` * - :ref:`WHEELSTEER ` @@ -98,7 +100,7 @@ These "Raw" controls allow you the direct control of flight parameters while the * - :ref:`WHEELTHROTTLE ` - scalar [-1,1] - ``W``, ``S`` - + * - :ref:`WHEELSTEERTRIM ` - scalar [-1,1] - ``ALT+A``, ``ALT+D`` @@ -139,7 +141,7 @@ These "Raw" controls allow you the direct control of flight parameters while the .. _SHIP CONTROL ROTATION: .. object:: SHIP:CONTROL:ROTATION - This is a :ref:`Vector ` object containing ``(YAW, PITCH, ROLL)`` in that order. + This is a :struct:`Vector` object containing ``(YAW, PITCH, ROLL)`` in that order. @@ -147,12 +149,12 @@ These "Raw" controls allow you the direct control of flight parameters while the .. object:: SHIP:CONTROL:YAWTRIM Controls the ``YAW`` of the rotational trim. - + .. _SHIP CONTROL PITCHTRIM: .. object:: SHIP:CONTROL:PITCHTRIM Controls the ``PITCH`` of the rotational trim. - + .. _SHIP CONTROL ROLLTRIM: .. object:: SHIP:CONTROL:ROLLTRIM @@ -179,7 +181,7 @@ These "Raw" controls allow you the direct control of flight parameters while the .. _SHIP CONTROL TRANSLATION: .. object:: SHIP:CONTROL:TRANSLATION - Controls the translation as a :ref:`Vector ` ``(FORE, STARBOARD, TOP)``. + Controls the translation as a :struct:`Vector` ``(FORE, STARBOARD, TOP)``. .. _SHIP CONTROL WHEELSTEER: .. object:: SHIP:CONTROL:WHEELSTEER diff --git a/doc/source/commands/flight/systems.rst b/doc/source/commands/flight/systems.rst index 0d1a3efbf..5e5d413d6 100644 --- a/doc/source/commands/flight/systems.rst +++ b/doc/source/commands/flight/systems.rst @@ -1,3 +1,5 @@ +.. _systems: + Ship Systems ============ diff --git a/doc/source/commands/flight/warp.rst b/doc/source/commands/flight/warp.rst index 2bb70285a..28280a62a 100644 --- a/doc/source/commands/flight/warp.rst +++ b/doc/source/commands/flight/warp.rst @@ -1,8 +1,11 @@ +.. _warp: + Time Warping ============ .. global:: WARP + The :global:`WARP` global variable can be set to change the game warp to a value between 0 and 7:: SET WARP TO 5. // Sets warp to 1000x diff --git a/doc/source/commands/prediction.rst b/doc/source/commands/prediction.rst index d61bb3b32..4939ebb5a 100644 --- a/doc/source/commands/prediction.rst +++ b/doc/source/commands/prediction.rst @@ -9,7 +9,7 @@ Predictions of Flight Path **Manipulating the maneuver nodes** - To alter the maneuver nodes on a vessel's flight plan, use the ADD and REMOVE commands as described on the :ref:`maneuver node manipulation page `. + To alter the maneuver nodes on a vessel's flight plan, use the ADD and REMOVE commands as described on the :ref:`maneuver node manipulation page `. Using the Add and Remove commands as described on that page, you may alter the flight plan of the CPU\_vessel, however kOS does not automatically execute the nodes. You still have to write the code to decide how to successfully execute a planned maneuver node. @@ -19,33 +19,33 @@ These return predicted information about the future position and velocity of an .. function:: POSITIONAT(orbitable,time) - :param orbitable: A :Ref:`Vessel `, :ref:`Body ` or other :ref:`Orbitable ` object - :type orbitable: :ref:`Orbitable ` + :param orbitable: A :struct:`Vessel`, :struct:`Body` or other :struct:`Orbitable` object + :type orbitable: :struct:`Orbitable` :param time: Time of prediction - :type time: :ref:`Timestamp ` - :return: A position :ref:`Vector ` expressed as the coordinates in the :ref:`ship-center-raw-rotation ` frame + :type time: :struct:`TimeSpan` + :return: A position :struct:`Vector` expressed as the coordinates in the :ref:`ship-center-raw-rotation ` frame - Returns a prediction of where the :ref:`Orbitable ` will be at some :ref:`universal Timestamp `. If the :ref:`Orbitable ` is a :ref:`Vessel `, and the :ref:`Vessel ` has planned :ref:`maneuver nodes `, the prediction assumes they will be executed exactly as planned. + Returns a prediction of where the :struct:`Orbitable` will be at some :ref:`universal Timestamp `. If the :struct:`Orbitable` is a :struct:`Vessel`, and the :struct:`Vessel` has planned :ref:`maneuver nodes `, the prediction assumes they will be executed exactly as planned. .. function:: VELOCITYAT(orbitable,time) - :param orbitable: A :Ref:`Vessel `, :ref:`Body ` or other :ref:`Orbitable ` object - :type orbitable: :ref:`Orbitable ` + :param orbitable: A :struct:`Vessel`, :struct:`Body` or other :struct:`Orbitable` object + :type orbitable: :struct:`Orbitable` :param time: Time of prediction - :type time: :ref:`Timestamp ` + :type time: :struct:`TimeSpan` :return: An :ref:`ObitalVelocity ` structure. - Returns a prediction of what the :ref:`Orbitable's ` velocity will be at some :ref:`universal Timestamp `. If the :ref:`Orbitable ` is a :ref:`Vessel `, and the :ref:`Vessel ` has planned :ref:`maneuver nodes `, the prediction assumes they will be executed exactly as planned. + Returns a prediction of what the :ref:`Orbitable's ` velocity will be at some :ref:`universal Timestamp `. If the :struct:`Orbitable` is a :struct:`Vessel`, and the :struct:`Vessel` has planned :struct:`maneuver nodes `, the prediction assumes they will be executed exactly as planned. .. function:: ORBITAT(orbitable,time) - :param orbitable: A :Ref:`Vessel `, :ref:`Body ` or other :ref:`Orbitable ` object - :type orbitable: :ref:`Orbitable ` + :param orbitable: A :Ref:`Vessel `, :struct:`Body` or other :struct:`Orbitable` object + :type orbitable: :struct:`Orbitable` :param time: Time of prediction - :type time: :ref:`Timestamp ` - :return: An :ref:`Orbit ` structure. - - Returns the :ref:`Orbit patch ` where the :ref:`Orbitable ` object is predicted to be at some :ref:`universal Timestamp `. If the :ref:`Orbitable ` is a :ref:`Vessel `, and the :ref:`Vessel ` has planned :ref:`maneuver nodes `, the prediction assumes they will be executed exactly as planned. + :type time: :struct:`TimeSpan` + :return: An :struct:`Orbit` structure. + + Returns the :ref:`Orbit patch ` where the :struct:`Orbitable` object is predicted to be at some :ref:`universal Timestamp `. If the :struct:`Orbitable` is a :struct:`Vessel`, and the :struct:`Vessel` has planned :ref:`maneuver nodes `, the prediction assumes they will be executed exactly as planned. Examples:: diff --git a/doc/source/conf.py b/doc/source/conf.py index 95c603f4b..76d8d514b 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -165,12 +165,12 @@ # The name of an image file (within the static path) to use as favicon of the # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 # pixels large. -#html_favicon = None +html_favicon = '_images/favicon.ico' # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['_static','_images'] +html_static_path = ['_images'] # Add any extra paths that contain custom files (such as robots.txt or # .htaccess) here, relative to this directory. These files are copied diff --git a/doc/source/general/cpu_hardware.rst b/doc/source/general/cpu_hardware.rst index ae7eb5061..ec1e65a13 100644 --- a/doc/source/general/cpu_hardware.rst +++ b/doc/source/general/cpu_hardware.rst @@ -52,7 +52,7 @@ Because the entire body of a trigger will execute all the way to the bottom on * *As of kOS version 0.14 and higher, this condition is now being checked for* and the script will be **terminated with a runtime error** if the triggers like WHEN/THEN and ON take more than :attr:`Config:IPU` instructions to execute. The sum total of all the code within your WHEN/THEN and ON code blocks MUST be designed to complete within one update tick. -**This may seem harsh**. Ideally, kOS would only generate a runtime error if it thought your script was stuck in an **infinite loop**, and allow it to exceed the :attr:`Config:IPU` number of instructions if it was going to finish and just needed a little longer to to finish its work. But, because of a well known problem in computer science called **`the halting problem `__**, it's literally impossible for kOS, or any other software for that matter, to detect the difference between another program's infinite loop versus another program's loop that will end soon. kOS only knows how long your triggers have taken so far, not how long they're going to take before they're done, or even if they'll be done. +**This may seem harsh**. Ideally, kOS would only generate a runtime error if it thought your script was stuck in an **infinite loop**, and allow it to exceed the :attr:`Config:IPU` number of instructions if it was going to finish and just needed a little longer to to finish its work. But, because of a well known problem in computer science called `the halting problem `__, it's literally impossible for kOS, or any other software for that matter, to detect the difference between another program's infinite loop versus another program's loop that will end soon. kOS only knows how long your triggers have taken so far, not how long they're going to take before they're done, or even if they'll be done. If you suspect that your trigger body would have ended if it was allowed to run a little longer, try setting your :attr:`Config:IPU` setting a bit higher and see if that makes the error go away. @@ -122,7 +122,7 @@ The Fix: Wait for Time to Change If you are executing a loop like the one above in which it is absolutely vital that the next iteration of the loop must occur in a *different* **physics tick** than the previous one, so that it can take *new* measurements that are different, the solution is to use a WAIT statement that will delay until there's evidence that the physics clock has moved a tick. -The most effective way to do that is to check the `TIME <../../structure/timespan/index.html>`__ and see if it's different than it was before. As long as you are still within the same *physics tick*, the TIME will not move:: +The most effective way to do that is to check the :ref:`time` and see if it's different than it was before. As long as you are still within the same *physics tick*, the TIME will not move:: PRINT "Waiting until altitude is holding stable within 0.1 meters.". @@ -165,5 +165,3 @@ An Even Better Solution ~~~~~~~~~~~~~~~~~~~~~~~ There has been talk of instituting a special command: WAIT UNTIL PHYSICS that will sleep until there has been a physics update, and it's a good idea but it hasn't been implemented yet. - -.. |CONFIG:IPU| replace:: :ref:`CONFIG:IPU ` diff --git a/doc/source/index.rst b/doc/source/index.rst index aee7c51b9..23951afcb 100644 --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -17,6 +17,7 @@ Welcome to the **kOS** Documentation Website! Mathematics Commands Structures + Addons Contribute About diff --git a/doc/source/language/features.rst b/doc/source/language/features.rst index 806c63b6f..546eadd70 100644 --- a/doc/source/language/features.rst +++ b/doc/source/language/features.rst @@ -6,7 +6,7 @@ General Features of the **KerboScript** Language .. contents:: :local: :depth: 2 - + Case Insensitivity ------------------ @@ -72,12 +72,12 @@ Structures also often contain methods. A method is a suffix of a structure that // doesn't return anything. PRINT PLIST:SUBLIST(0,4). // calling a suffix method with 2 // arguments that returns a list. - + .. note:: .. versionadded:: 0.15 Methods now perform the activity when the interpreter comes up to it. Prior to this version, execution was sometimes delayed until some later time depending on the trigger setup or flow-control. -For more information, see the :ref:`Structures Section `. A full list of structure types can be found on the :doc:`Structures ` page. For a more detailed breakdown of the language, see the :doc:`Language Syntax Constructs ` page. +For more information, see the :ref:`Structures Section `. A full list of structure types can be found on the :ref:`Structures ` page. For a more detailed breakdown of the language, see the :ref:`Language Syntax Constructs ` page. .. _language structures: diff --git a/doc/source/language/flow.rst b/doc/source/language/flow.rst index f48a28658..6101195b9 100644 --- a/doc/source/language/flow.rst +++ b/doc/source/language/flow.rst @@ -33,7 +33,7 @@ Checks if the expression supplied returns true. If it does, ``IF`` executes the SET X TO 1. IF X = 1 { PRINT "X equals one.". } // Prints "X equals one." IF X > 10 { PRINT "X is greater than ten.". } // Does nothing - + // IF-ELSE structure: IF X > 10 { PRINT "X is large". } ELSE { PRINT "X is small". } @@ -60,7 +60,7 @@ Checks if the expression supplied returns true. If it does, ``IF`` executes the // syntax error - ELSE without IF. IF X > 10 { PRINT "Large". }. ELSE { PRINT "Small". }. - + .. index:: LOCK .. _lock: @@ -78,7 +78,7 @@ Locks an identifier to an expression. Each time the identifier is used in an exp Unlike variables created with the ``SET`` or ``DECLARE`` commands, ``LOCK`` variables are local to the current program. If program **A** calls program **B**, and program **B** issues a ``LOCK`` command, program **A** will not be able to read that ``LOCK`` variable's result. .. note:: - If a ``LOCK`` expression is used with a flight control such as ``THROTTLE`` or ``STEERING``, then it will get continually evaluated in the background :ref:`each update tick `. + If a ``LOCK`` expression is used with a flight control such as ``THROTTLE`` or ``STEERING``, then it will get continually evaluated in the background :ref:`each update tick `. .. index:: UNLOCK .. _unlock: @@ -120,7 +120,7 @@ Note that if you are creating a loop in which you are watching a physical value } The full explanation why is :ref:`in the CPU hardware description -page `. +page `. .. index:: FOR .. _for: @@ -161,7 +161,7 @@ Halts execution for a specified amount of time, or until a specific set of crite WAIT UNTIL X > 40. // Wait until X is greater than 40 WAIT UNTIL APOAPSIS > 150000. // You can see where this is going -Note that any ``WAIT`` statement, no matter what the actual expression is, will always result in a wait time that lasts at least :ref:`one physics tick `. +Note that any ``WAIT`` statement, no matter what the actual expression is, will always result in a wait time that lasts at least :ref:`one physics tick `. .. index:: WHEN .. _when: @@ -175,7 +175,7 @@ does not halt execution. It starts a check in the background that will keep acti The body of a ``THEN`` or an ``ON`` statement interrupts the normal flow of a **kOS** program. When the event that triggers the body happens, the main **kOS** program is paused until the body of the ``THEN`` completes. .. warning:: - Do not make the body of a ``WHEN``/``THEN`` take a long time to execute. If you attempt to run code that lasts too long in the body of your ``WHEN``/``THEN`` statement, :ref:`it will cause an error `. Avoid looping during ``WHEN``/``THEN`` if you can. For details on how to deal with this, see the :ref:`tutorial on design patterns `. + Do not make the body of a ``WHEN``/``THEN`` take a long time to execute. If you attempt to run code that lasts too long in the body of your ``WHEN``/``THEN`` statement, :ref:`it will cause an error `. Avoid looping during ``WHEN``/``THEN`` if you can. For details on how to deal with this, see the :ref:`tutorial on design patterns `. .. note:: .. versionchanged:: 0.12 @@ -193,7 +193,7 @@ Example:: AG1 ON. } -A ``WHEN``/``THEN`` trigger is removed when the program that created it exits, even if it has not occurred yet. The ``PRESERVE`` can be used inside the ``THEN`` clause of a ``WHEN`` statement. If you are going to make extensive use of ``WHEN``/``THEN`` triggers, it's important to understand more details of how they :ref:`work in the kOS CPU `. +A ``WHEN``/``THEN`` trigger is removed when the program that created it exits, even if it has not occurred yet. The ``PRESERVE`` can be used inside the ``THEN`` clause of a ``WHEN`` statement. If you are going to make extensive use of ``WHEN``/``THEN`` triggers, it's important to understand more details of how they :ref:`work in the kOS CPU `. .. index:: ON .. _on_trigger: @@ -219,9 +219,9 @@ The body of an ``ON`` statement can be a list of commands inside curly braces, j } .. warning:: - DO NOT make the body of an ``ON`` statement take a long time to execute. If you attempt to run code that lasts too long in the body of your ``ON`` statement, :ref:`it will cause an error `. For general help on how to deal with this, see the :ref:`tutorial on design patterns `. + DO NOT make the body of an ``ON`` statement take a long time to execute. If you attempt to run code that lasts too long in the body of your ``ON`` statement, :ref:`it will cause an error `. For general help on how to deal with this, see the :ref:`tutorial on design patterns `. -Avoid looping during ``ON`` code blocks if you can. If you are going to make extensive use of ``ON`` triggers, it's important to understand more details of how they :ref:`work in the kOS CPU `. +Avoid looping during ``ON`` code blocks if you can. If you are going to make extensive use of ``ON`` triggers, it's important to understand more details of how they :ref:`work in the kOS CPU `. .. index:: PRESERVE .. _preserve: diff --git a/doc/source/language/variables.rst b/doc/source/language/variables.rst index 0289b8478..52128cb4d 100644 --- a/doc/source/language/variables.rst +++ b/doc/source/language/variables.rst @@ -6,7 +6,7 @@ Variables & Statements .. contents:: :local: :depth: 1 - + .. _declare: ``DECLARE`` @@ -62,7 +62,7 @@ The ``DECLARE PARAMETER`` statements can appear anywhere in a program as long as **Pass By Value** The following paragraph is important for people familiar with other programming languages. If you are new to programming and don't understand what it is saying, that's okay you can ignore it. - + At the moment the only kind of parameter supported is a pass-by-value parameter, and pass-by reference parameters don't exist. Be aware, however, that due to the way kOS is implemented on top of a reference-using object-oriented language (CSharp), if you pass an argument which is a complex aggregate structure (i.e. a Vector, or a List - anything that kOS lets you use a colon suffix with), then the parameters will behave exactly like being passed by reference because all you're passing is the handle to the object rather than the object itself. This should be familiar behavior to anyone who has written software in Java or C# before. .. _set: @@ -74,12 +74,10 @@ Sets the value of a variable. Declares a global variable if it doesn’t already SET X TO 1. -.. _lock: - ``LOCK`` -------- -Declares that the idenifier will refer to an expression that is always re-evaluated on the fly every time it is used:: +Declares that the idenifier will refer to an expression that is always re-evaluated on the fly every time it is used (See also :ref:`Flow Control documentation `):: SET Y TO 1. LOCK X TO Y + 1. diff --git a/doc/source/math/basic.rst b/doc/source/math/basic.rst index 7e654471d..8a11cb532 100644 --- a/doc/source/math/basic.rst +++ b/doc/source/math/basic.rst @@ -1,4 +1,4 @@ -.. _math: +.. _basic math: .. _constants: .. index:: Fundamental Constants @@ -179,18 +179,18 @@ Trigonometric Functions :parameter x: (scalar) :return: (deg) angle whose sine is x - + :: - + PRINT ARCSIN(0.67). // prints 42.0670648 .. function:: ARCCOS(x) :parameter x: (scalar) :return: (deg) angle whose cosine is x - + :: - + PRINT ARCCOS(0.67). // prints 47.9329352 .. function:: ARCTAN(x) @@ -207,7 +207,7 @@ Trigonometric Functions :parameter y: (scalar) :parameter x: (scalar) :return: (deg) angle whose tangent is :math:`\frac{y}{x}` - + :: PRINT ARCTAN2(0.67, 0.89). // prints 36.9727625 diff --git a/doc/source/math/direction.rst b/doc/source/math/direction.rst index a6ff1383e..d51561614 100644 --- a/doc/source/math/direction.rst +++ b/doc/source/math/direction.rst @@ -28,6 +28,7 @@ Creation :ref:`PROGRADE, etc. ` From SHIP, TARGET or BODY =============================================== =================================== +.. _rotation: .. function:: R(pitch,yaw,roll) A :struct:`Direction` can be created out of a Euler Rotation, indicated with the :func:`R()` function, as shown below where the ``pitch``, ``yaw`` and ``roll`` values are in degrees:: @@ -40,7 +41,7 @@ Creation SET myDir TO Q( x, y, z, rot ). - +.. _heading: .. function:: HEADING(dir,pitch) A :struct:`Direction` can be created out of a :func:`HEADING()` function. The first parameter is the compass heading, and the second parameter is the pitch above the horizon:: @@ -92,7 +93,7 @@ Whenever a :struct:`Direction` is printed, it always comes out showing its Euler // Steer the vessel in the direction // suggested by direction X. - LOCK STEERING TO X. + LOCK STEERING TO X. // Create a rotation facing northeast, // 10 degrees above horizon @@ -100,10 +101,10 @@ Whenever a :struct:`Direction` is printed, it always comes out showing its Euler // Steer the vessel in the direction // suggested by direction X. - LOCK STEERING TO Y. + LOCK STEERING TO Y. // Set by a rotation in degrees - SET Direction TO R(0,90,0). + SET Direction TO R(0,90,0). Structure --------- @@ -126,7 +127,7 @@ Structure RIGHTVECTOR :struct:`Vector` Alias synonym for :attr:`STARVECTOR` :attr:`INVERSE` :struct:`Direction` The inverse of this direction. ========================= =================== ================================ - + The :struct:`Direction` object exists primarily to enable automated steering. You can initialize a :struct:`Direction` using a :struct:`Vector` or a ``Rotation``. :struct:`Direction` objects represent a rotation starting from an initial point in **KSP**'s coordinate system where the initial state was looking down the :math:`+z` axis, with the camera "up" being the :math:`+y` axis. So for example, a :struct:`Direction` pointing along the :math:`x` axis might be represented as ``R(0,90,0)``, meaning the initial :math:`z`-axis direction was rotated *90 degrees* around the :math:`y` axis. If you are going to manipulate directions a lot, it's important to note that the order in which the rotations occur is: @@ -146,14 +147,14 @@ Structure Rotation around the :math:`x` axis. - + .. attribute:: Direction:YAW :type: scalar (deg) :access: Get only Rotation around the :math:`y` axis. - + .. attribute:: Direction:ROLL :type: scalar (deg) @@ -161,7 +162,7 @@ Structure Rotation around the :math:`z` axis. - + .. attribute:: Direction:FOREVECTOR :type: :struct:`Vector` diff --git a/doc/source/math/ref_frame.rst b/doc/source/math/ref_frame.rst index 3c2936512..521928061 100644 --- a/doc/source/math/ref_frame.rst +++ b/doc/source/math/ref_frame.rst @@ -44,7 +44,7 @@ Origin Position The origin position of the :math:`(x,y,z)` coordinate grid in **KSP** is also a bit messy. It's usually *near* but not exactly *on* the current ship. **kOS** performs some conversions for you to make this a bit simpler and keep everything consistent. -Regardless of where the origin of the underlying **KSP** system is, in **kOS**, whenever a POSITION is reported, it will always be reported in a frame of reference where the origin is located at the :ref:`CPU Vessel `. +Regardless of where the origin of the underlying **KSP** system is, in **kOS**, whenever a POSITION is reported, it will always be reported in a frame of reference where the origin is located at the :ref:`CPU Vessel `. However, for the sake of VELOCITY, the origin point of all vectors is usually not SHIP, but rather it's the SOI body's center. This is because if the origin point was the SHIP, then the ship's velocity would always be zero in that frame of reference, and that would not be useful. diff --git a/doc/source/structures.rst b/doc/source/structures.rst index b6395bcea..9506f61a6 100644 --- a/doc/source/structures.rst +++ b/doc/source/structures.rst @@ -12,6 +12,7 @@ A general discussion of structures :ref:`can be found here * :struct:`Vector` * :struct:`Direction` * :struct:`GeoCoordinates` +* :struct:`Waypoint` * :ref:`Orbits ` * :struct:`Orbit` * :struct:`Orbitable` @@ -19,7 +20,6 @@ A general discussion of structures :ref:`can be found here * :ref:`Celestial Bodies ` * :struct:`Body` * :struct:`Atmosphere` - * :struct:`Waypoint` * :ref:`Vessels ` * :struct:`Vessel` * :struct:`Control` @@ -46,6 +46,5 @@ A general discussion of structures :ref:`can be found here Orbits Celestial Bodies Vessels & Parts - Maneuvering Waypoints Miscellaneous diff --git a/doc/source/structures/maneuvering.rst b/doc/source/structures/maneuvering.rst deleted file mode 100644 index f57f44b47..000000000 --- a/doc/source/structures/maneuvering.rst +++ /dev/null @@ -1,10 +0,0 @@ -.. _maneuvering: - -Orbits and Maneuver Nodes -========================= - -.. toctree:: - :glob: - :maxdepth: 1 - - maneuvering/* diff --git a/doc/source/structures/misc/rgba.rst b/doc/source/structures/misc/colors.rst similarity index 99% rename from doc/source/structures/misc/rgba.rst rename to doc/source/structures/misc/colors.rst index de75ca06d..cd6823b65 100644 --- a/doc/source/structures/misc/rgba.rst +++ b/doc/source/structures/misc/colors.rst @@ -1,4 +1,5 @@ .. _colors: +.. _color: Colors ====== diff --git a/doc/source/structures/misc/fileinfo.rst b/doc/source/structures/misc/fileinfo.rst index 209be3985..6079bd0b6 100644 --- a/doc/source/structures/misc/fileinfo.rst +++ b/doc/source/structures/misc/fileinfo.rst @@ -1,4 +1,4 @@ -.. fileinfo: +.. _fileinfo: File Information ================ diff --git a/doc/source/structures/misc/time.rst b/doc/source/structures/misc/time.rst index 47ab40324..7f1b602a8 100644 --- a/doc/source/structures/misc/time.rst +++ b/doc/source/structures/misc/time.rst @@ -1,4 +1,5 @@ .. _time: +.. _timestamp: Time Span ========= diff --git a/doc/source/structures/vessels/aggregateresource.rst b/doc/source/structures/vessels/aggregateresource.rst index 20f03536c..33b5adae5 100644 --- a/doc/source/structures/vessels/aggregateresource.rst +++ b/doc/source/structures/vessels/aggregateresource.rst @@ -5,7 +5,7 @@ AggregateResource A ship can have many parts that contain resources (i.e. fuel, electric charge, etc). kOS has several tools for getting the summation of each resource. -This is the type returned as the elements of the list in :ref:`LIST RESOURCES` +This is the type returned as the elements of the list from ``LIST RESOURCES.`` IN MyList :: @@ -18,7 +18,7 @@ IN MyList :: + ROUND(100*RES:AMOUNT/RES:CAPACITY) + "% full.". }. - + This is also the type returned by STAGE:RESOURCES :: PRINT "THESE ARE ALL THE RESOURCES active in this stage:". @@ -31,7 +31,7 @@ This is also the type returned by STAGE:RESOURCES :: + "% full.". }. -.. structure:: Resource +.. structure:: AggregateResource .. list-table:: :header-rows: 1 @@ -46,39 +46,39 @@ This is also the type returned by STAGE:RESOURCES :: - Resource name * - :attr:`AMOUNT` - scalar - - Amount of this resource left + - Total amount remaining * - :attr:`CAPACITY` - scalar - - Maximum amount of this resource + - Total amount when full * - :attr:`PARTS` - List - - A collection of the parts that can contain this resource - - -.. attribute:: Resource:NAME + - Parts containing this resource + + +.. attribute:: AggregateResource:NAME :access: Get only :type: string The name of the resource, i.e. "LIQUIDFUEL", "ELECTRICCHARGE", "MONOPROP". -.. attribute:: Resource:AMOUNT +.. attribute:: AggregateResource:AMOUNT :access: Get only :type: scalar The value of how much resource is left. -.. attribute:: Resource:CAPACITY +.. attribute:: AggregateResource:CAPACITY :access: Get only :type: scalar What AMOUNT would be if the resource was filled to the top. -.. attribute:: Resource:PARTS +.. attribute:: AggregateResource:PARTS :access: Get only :type: List - Because this is a summation of the resources from many parts. kOS gives you the list of all parts that do or could contain the resource. + Because this is a summation of the resources from many parts. kOS gives you the list of all parts that do or could contain the resource. diff --git a/doc/source/structures/waypoint.rst b/doc/source/structures/waypoint.rst index 8bff67ee9..ba5250e71 100644 --- a/doc/source/structures/waypoint.rst +++ b/doc/source/structures/waypoint.rst @@ -1,16 +1,13 @@ +.. _waypoint: + Waypoints ========= -.. contents:: Contents +.. contents:: :local: - :depth: 1 - -Waypoints are the location markers you can see on the map view showing -you where contracts are targeted for. With this strucure, you can obtain -coordinate data for the locations of these waypoints. + :depth: 2 -Creation --------- +Waypoints are the location markers you can see on the map view showing you where contracts are targeted for. With this structure, you can obtain coordinate data for the locations of these waypoints. .. function:: WAYPOINT(name) @@ -29,61 +26,42 @@ Creation This creates a :struct:`List` of :struct:`Waypoint` structures for all accepted contracts. Waypoints for proposed contracts you haven't accepted yet do not appear in the list. -Structure ---------- - .. structure:: Waypoint .. list-table:: **Members** - :widths: 4 2 1 1 + :widths: 1 1 :header-rows: 1 - + * - Suffix - Type - - Get - - Set - + * - :attr:`NAME` - string - - yes - - no * - :attr:`BODY` - `BodyTarget` - - yes - - no * - :attr:`GEOPOSITION` - `GeoCoordinates` - - yes - - no * - :attr:`ALTITUDE` - scalar - - yes - - no * - :attr:`AGL` - scalar - - yes - - no * - :attr:`NEARSURFACE` - boolean - - yes - - no * - :attr:`GROUNDED` - boolean - - yes - - no .. attribute:: Waypoint:NAME :type: string - :access: Get + :access: Get only Name of waypoint as it appears on the map and contract .. attribute:: Waypoint:BODY :type: `BodyTarget` - :access: Get + :access: Get only Celestial body the waypoint is attached to @@ -91,14 +69,14 @@ Structure .. attribute:: Waypoint:GEOPOSITION :type: GeoCoordinates - :access: Get + :access: Get only The LATLNG of this waypoint .. attribute:: Waypoint:ALTITUDE :type: scalar - :access: Get + :access: Get only Altitude of waypoint **above "sea" level**. Warning, this a point somewhere in the midst of the contract altitude range, not the edge of the altitude range. It corresponds towhere the marker tip hovers on the map, which is not actually at the very edge of the contract condition's range. It represents a typical midling location inside the contract's altitude range. @@ -106,7 +84,7 @@ Structure .. attribute:: Waypoint:AGL :type: scalar - :access: Get + :access: Get only Altitude of waypoint **above ground**. Warning, this a point somewhere in the midst of the contract altitude range, not the edge of the altitude range. It corresponds to where the marker tip hovers on the map, which is not actually at the very edge of the contract condition's range. It represents a typical midling location inside the contract's altitude range. @@ -114,7 +92,7 @@ Structure .. attribute:: Waypoint:NEARSURFACE :type: boolean - :access: Get + :access: Get only True if waypoint is a point near or on the body rather than high in orbit. @@ -122,7 +100,7 @@ Structure .. attribute:: Waypoint:GROUNDED :type: boolean - :access: Get + :access: Get only True if waypoint is actually glued to the ground. diff --git a/doc/source/tutorials/quickstart.rst b/doc/source/tutorials/quickstart.rst index d73c8d90c..bf456de20 100644 --- a/doc/source/tutorials/quickstart.rst +++ b/doc/source/tutorials/quickstart.rst @@ -92,7 +92,7 @@ Step 7: Okay, but where is this program? To see where the "HELLO" program has been saved, Issue the command ``LIST FILES`` like this:: LIST FILES. - + (Note, that the default for the ``LIST`` command is to list ``FILES``, so you can leave the word "FILES" off if you like.) It should look like this, showing you the HELLO program you just wrote: @@ -123,15 +123,16 @@ To work with the archive, and create a second "hello world" file there, you issu SWITCH TO 1. LIST FILES. RUN HELLO. - + *But where is it stored behind the scenes?* The archive is currently slightly violating the design of **KSP** mods that puts everything in the GameData folder. The kSP Archive is actually stored in the ``Ships/Script`` folder of your MAIN **KSP** home, not inside GameData. If a file is stored inside the archive, it can actually be edited *by an external text editor of your choice* instead of using **kOS**'s in-game editor. This is usually a much better practice once you start doing more complex things with **kOS**. You can also make new files in the archive folder. Just make sure that all the files end with a ``.ks`` file name suffix or **kOS** won't use them. Further reading about files and volumes: -- :ref:`Volumes` -- :ref:`File Control` +- :ref:`Volumes ` +- :ref:`File Control ` +- :ref:`File Information ` Second Example: Doing something real ------------------------------------ @@ -169,7 +170,7 @@ Okay, so type the lines below in an external *text editor of your choice* (i.e. SET countdown TO countdown - 1. WAIT 1. // pauses the script here for 1 second. } - + See those things with the two slashes ("//")? Those are comments in the kerboscript language and they're just ways to write things in the program that don't do anything - they're there for humans like you to read so you understand what's going on. In these examples you never actually have to type in the things you see after the slashes. They're there for your benefit when reading this document but you can leave them out if you wish. Save the file in your ``Ships/Script`` folder of your **KSP** installation under the filename "hellolaunch.ks". DO NOT save it anywhere under ``GameData/kOS/``. Do NOT. According to the **KSP** standard, normally **KSP** mods should put their files in ``GameData/[mod name]``, but **kOS** puts the archive outside the ``GameData`` folder because it represents content owned by you, the player, not content owned by the **kOS** mod. @@ -178,7 +179,7 @@ By saving the file in ``Ships/Script``, you have actually put it in your archive SWITCH TO 0. LIST FILES. - + after saving the file from your external text editor program, you will see a listing of your file "hellolaunch" right away. Okay, now copy it to your local drive and give it a try running it from there:: SWITCH TO 1. @@ -206,7 +207,7 @@ Okay now go back into your *text editor of choice* and append a few more lines t SET countdown TO countdown - 1. WAIT 1. // pauses the script here for 1 second. } - + PRINT "Main throttle up. 2 seconds to stabalize it.". LOCK THROTTLE TO 1.0. // 1.0 is the max, 0.0 is idle. WAIT 2. // give throttle time to adjust. @@ -222,7 +223,7 @@ Okay now go back into your *text editor of choice* and append a few more lines t // back to manual piloting so that you can fly the ship by hand again. // If the pogram just ended here, then that would cause the throttle // to turn back off again right away and nothing would happen. - + Save this file to hellolaunch.ks again, and re-copy it to your vessel that should still be sitting on the launchpad, then run it, like so:: COPY HELLOLAUNCH FROM 0. @@ -316,7 +317,7 @@ The WHEN trigger we are going to add to the launch script looks like this:: STAGE. PRESERVE. } - + It says, "Whenever the amount of liquid fuel in the current stage is so small it may as well be zero (< 0.001), then activate the next stage." The PRESERVE keyword says, "don't stop checking this condition just because it's been triggered once. It should still keep checking for it again in the future." The check for < 0.001 is because sometimes **KSP** won't quite burn the last drop of fuel in a stage. If this block of code is inserted into the script, then it will set up a constant background check that will always hit the next stage as soon as the current stage has no liquidfuel in it. @@ -385,7 +386,7 @@ So for example, HEADING(45,10) would aim northeast, 10 degrees above the horizon PRINT "Starting flat part. Aiming to horizon.". LOCK STEERING TO HEADING(90,0). // east, horizontal. } - + Note that these lack the command PRESERVE like the previous WHEN example had. This is because we want these to trigger just once and then never again. There's no point in constantly telling **kOS** to reset the steering to the same thing over and over as the script runs. Now, if you insert this new section to the script, we have a nice nifty example of a start of a launching script. Note that it works even if you insert it at the top of the script, because it sets up the triggers to occur LATER when the condition becomes true. They don't execute right away:: @@ -413,7 +414,7 @@ Now, if you insert this new section to the script, we have a nice nifty example WAIT 2. // give throttle time to adjust. // The section below replaces previous UNTIL loop: - + WHEN STAGE:LIQUIDFUEL < 0.001 THEN { PRINT "No liquidfuel. Attempting to stage.". STAGE. @@ -426,7 +427,7 @@ Now, if you insert this new section to the script, we have a nice nifty example // back to manual piloting so that you can fly the ship by hand again. // If the program just ended here, then that would cause the throttle // to turn back off again right away and nothing would happen. - + And here is it in action: .. figure:: /_images/tutorials/quickstart/example_2_5.png @@ -436,7 +437,7 @@ And toward the end: .. figure:: /_images/tutorials/quickstart/example_2_6.png :width: 80 % - + If we assume you made a vessel that has enough fuel and power to get up to orbit, this script should in principle work to get you to the point of leaving the atmosphere. It will probably still fall back down, because this script makes no attempt to ensure that the craft is going fast enough to maintain the orbit. As you can probably see, it would still have a long way to go before it would become a really GOOD launching autopilot. Think about the following features you could add yourself as you become more familiar with **kOS**: From 7f4be5fb14c488cab97ec2ec904b3a2be63703be Mon Sep 17 00:00:00 2001 From: SirDiazo Date: Thu, 8 Jan 2015 09:11:52 -0700 Subject: [PATCH 067/446] Update AGX.rst --- doc/source/addons/AGX.rst | 35 ++++++++++------------------------- 1 file changed, 10 insertions(+), 25 deletions(-) diff --git a/doc/source/addons/AGX.rst b/doc/source/addons/AGX.rst index d7b4ffa1d..0422e867d 100644 --- a/doc/source/addons/AGX.rst +++ b/doc/source/addons/AGX.rst @@ -11,45 +11,29 @@ Includes a Script Trigger action that can be used to control a running program a **Usage:** Adds action groups AG11 through AG250 to kOS that are interacted with the same way as the AG1 through AG10 bindings in base kOS are. -- ``AG15 on.`` Activate action group 13. -- ``AG15 off.`` Deactivate action group 13. -- ``print AG15.`` Prints True or False based on action group 15's state. -- And however else you used AG1 can be used for AG15. -- Note: When you issue the ``AG15 on.`` command, all actions in action group 15 are trigged in the activate direction regardless of the current state of the action group. How an action handles being activated when already activated will depend on how the original creator of the action set things up. +Anywhere you use ``AG1``, you can use ``AG15`` in exactly the same way. -Caution: +Caution: Sometimes, AGX will return an unexpected value for a group's state (On/Off), see below for the explination. (Action State Monitoring) +**Basic Quick Start:** - ON AG15 { - print"AG15 triggered!". - preserve. - } - -will behave unexpected if a action triggered by action group 15 has an animation. Because AGX montiors group state per action, the above code will most likely trigger three times (assuming AG15 has a Solar Panel Toggle Action in it): - 1. AG15 is triggered by the player somehow. (AG15 Off -> On) - 2. Panel starts deploying, but AGX sees the action as off while the animation plays and turns the action back off. (AG15 On -> Off) - 3. Animation finishes playing, AGX now sees the action as on and turns the action on (AG15 Off -> On) -If you need to do this, you have to add a delay that is long then the animation time as so: -``Add code snippet`` +http://members.shaw.ca/diazo/AGExtQuickStart1.jpg +http://members.shaw.ca/diazo/AGExtQuickStart2.jpg -**Basic Quick Start:** -![](http://members.shaw.ca/diazo/AGExtQuickStart1.jpg) -![](http://members.shaw.ca/diazo/AGExtQuickStart2.jpg) +**Overview Walkthrough:** (Video, imagur album, animated gif, something) -**Overview Walkthrough:** -(Video, imagur album, animated gif, something) +Note that this mod only adds action grousp 11 through 250, it does not change how action groups 1 through 10 behave in any way. -**Known limitations:** +**Known limitations:** -- The following limitations apply only to AG11 through AG250. AG1 through AG10 will behave as they have regardless of whether AGX is installed or not. - For an action group to be useable, it must have an action assigned to it. When installed, AGX adds a "Script Trigger" action to the kOS computer part that serves this purpose if you want an "empty" action group to trigger kOS scripts with. - Be aware that if you query an empty action group, it will always return a state of False and trying to turn an emtpy action group On will do nothing and silently fail without any sort of error message. (Groups AG11 through AG250 only. Groups AG1 through AG10 can be empty and will turn On and Off when commanded to.) - At this point, AG11 through AG250 do not support RemoteTech. Triggering those action groups will bypass the signal delay and execute those actions immediately. (On the immediate fix list.) **Action state monitoring** -Note that the state of action groups is tracked on a per-action basis, rather then on a per-group basis. This results in the group state being handled differently. +Note that the state of action groups is tracked on a per-action basis, rather then on a per-group basis. This results in the group state being handled differently. (AG 11 through AG250 only.) - The Script Trigger action found on the kOS computer module is not subject to the below considerations and is the recommended action to use when interacting with a running kOS script. - The state of actions are monitored on the part and updated automatically. A closed solar panel will return a state of false for all it's actions. (Extend Panels, Retract Panels, Toggle Panels) When you extend the solar panel with either the Extend Panels or Toggle Panels action, all three actions will change to a state of True. Retract the panels and the state of all three actions will become False. Note that this state will update in any action group that contains that action, not just the action group that was activated. @@ -58,3 +42,4 @@ Note that the state of action groups is tracked on a per-action basis, rather th - For clarity, visual feedback can be provided of the current state of an action group. When editing action groups, find the "Toggle Grp." button just below the text entry field for the group name in the main AGX window and enable it. (It is enabled/disabled for the current action group when you click the button.) Once you do this, the text displaying that group will change from gray to colored. Green: Group is activated (state True). Red: Group is deactivated (state False). Yellow: Group is in a mixed state, will return a state False when queried. - It is okay to activate an already activated group and deactivate a non-activated group. Actions in the group will stil try to execute as normal. Exact behavior of a specific action will depend on how the action's creator set things up. + From 49c0d3dda0e421de1cc7228a42d850ec46933cdb Mon Sep 17 00:00:00 2001 From: SirDiazo Date: Thu, 8 Jan 2015 09:12:46 -0700 Subject: [PATCH 068/446] Update AGX.rst --- doc/source/addons/AGX.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/addons/AGX.rst b/doc/source/addons/AGX.rst index 0422e867d..a2a7cb421 100644 --- a/doc/source/addons/AGX.rst +++ b/doc/source/addons/AGX.rst @@ -4,7 +4,7 @@ Action Groups Extended - Download: https://github.com/SirDiazo/AGExt/releases - Forum thread, including full instructions: http://forum.kerbalspaceprogram.com/threads/74195 -Increase the action groups available to kOS from 10 to 250 and add the ability to edit actions in flight as well as the ability to name action groups so you describe what a group does. +Increase the action groups available to kOS from 10 to 250. Also adds the ability to edit actions in flight as well as the ability to name action groups so you can describe what a group does. Includes a Script Trigger action that can be used to control a running program and visual feedback if an action group is currently activated. From 6cd1e5ac4d9a6504e18174e425324947824efc7d Mon Sep 17 00:00:00 2001 From: SirDiazo Date: Thu, 8 Jan 2015 09:32:42 -0700 Subject: [PATCH 069/446] Update AGX.rst --- doc/source/addons/AGX.rst | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/doc/source/addons/AGX.rst b/doc/source/addons/AGX.rst index a2a7cb421..a3b4cae11 100644 --- a/doc/source/addons/AGX.rst +++ b/doc/source/addons/AGX.rst @@ -42,4 +42,33 @@ Note that the state of action groups is tracked on a per-action basis, rather th - For clarity, visual feedback can be provided of the current state of an action group. When editing action groups, find the "Toggle Grp." button just below the text entry field for the group name in the main AGX window and enable it. (It is enabled/disabled for the current action group when you click the button.) Once you do this, the text displaying that group will change from gray to colored. Green: Group is activated (state True). Red: Group is deactivated (state False). Yellow: Group is in a mixed state, will return a state False when queried. - It is okay to activate an already activated group and deactivate a non-activated group. Actions in the group will stil try to execute as normal. Exact behavior of a specific action will depend on how the action's creator set things up. +**Example code:** +- ``AG15 on.`` Activate action group 15. +- ``print AG15.`` Print action group 15's state to the terminal. (True/False) +- ``on AG15 {`` +- ``print "Action group 15 clicked!".`` +- ``preserve.`` +- ``}`` Print to the terminal anytime you activate action group 15. Use this to change variables within a running kOS script and the "Script Trigger" action found on the kOS computer part. +- If you want to use the ``on AG15`` command to monitor a part that has an animation, a cool down is required. + +``on AG15 { print "Solar Panel Toggled!". preserve. }`` will print to the terminal 3 times when the solar panel is extened. + +- Player activates AG15, AG15's state goes from false to true and the actions are triggered. ``AG15 False -> True`` and prints to the terminal. +- On it's next update pass (100ms to 250ms later), AGX checks AG15's state and sees the solar panel is still deploying which means that AG15's state is false and so sets it that way. ``AG15 True -> False`` and prints to the terminal. +- A few seconds later, the solar panel finishes it's deployment animation. On it's next update pass AGX checks AG15's state and sees the solar panel is now deployed which means that AG15's state is now true and so sets it that way. ``AG15 False -> True`` and prints to the terminal a third time. + +As a workaround, you need to add a cooldown: + +- ``on AG15 {`` +- ``if(cooldownTimeAG15 + 7 >= currentTime) {`` +- ``print "Solar Panel Toggled!".`` +- ``cooldownTimeAG15 = currentTime.`` +- ``}`` +- ``preserve.`` +- ``}`` + +Note the 7 in the second line, that is your cooldown time in seconds. The above code will limit AG15 so it can only activate after 7 seconds have passed since the previous activation. + + + From 2108ee99dfd3013bff1ace9ae59abc491bbac62c Mon Sep 17 00:00:00 2001 From: SirDiazo Date: Thu, 8 Jan 2015 09:33:17 -0700 Subject: [PATCH 070/446] Update AGX.rst --- doc/source/addons/AGX.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/source/addons/AGX.rst b/doc/source/addons/AGX.rst index a3b4cae11..984d117b2 100644 --- a/doc/source/addons/AGX.rst +++ b/doc/source/addons/AGX.rst @@ -43,6 +43,7 @@ Note that the state of action groups is tracked on a per-action basis, rather th - It is okay to activate an already activated group and deactivate a non-activated group. Actions in the group will stil try to execute as normal. Exact behavior of a specific action will depend on how the action's creator set things up. **Example code:** + - ``AG15 on.`` Activate action group 15. - ``print AG15.`` Print action group 15's state to the terminal. (True/False) - ``on AG15 {`` From 639545dcc13cb62e4c0266e08e148571723501e0 Mon Sep 17 00:00:00 2001 From: SirDiazo Date: Thu, 8 Jan 2015 09:34:21 -0700 Subject: [PATCH 071/446] Update AGX.rst --- doc/source/addons/AGX.rst | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/doc/source/addons/AGX.rst b/doc/source/addons/AGX.rst index 984d117b2..816f4fe75 100644 --- a/doc/source/addons/AGX.rst +++ b/doc/source/addons/AGX.rst @@ -51,8 +51,10 @@ Note that the state of action groups is tracked on a per-action basis, rather th - ``preserve.`` - ``}`` Print to the terminal anytime you activate action group 15. Use this to change variables within a running kOS script and the "Script Trigger" action found on the kOS computer part. - If you want to use the ``on AG15`` command to monitor a part that has an animation, a cool down is required. - -``on AG15 { print "Solar Panel Toggled!". preserve. }`` will print to the terminal 3 times when the solar panel is extened. +- ``on AG15 {`` +- ``print "Solar Panel Toggled!".`` +- ``preserve.`` +- ``}`` will print to the terminal 3 times when the solar panel is extened. - Player activates AG15, AG15's state goes from false to true and the actions are triggered. ``AG15 False -> True`` and prints to the terminal. - On it's next update pass (100ms to 250ms later), AGX checks AG15's state and sees the solar panel is still deploying which means that AG15's state is false and so sets it that way. ``AG15 True -> False`` and prints to the terminal. From acedaca58d96c1a7de69da0682f0fc69c8fcd129 Mon Sep 17 00:00:00 2001 From: SirDiazo Date: Thu, 8 Jan 2015 09:42:44 -0700 Subject: [PATCH 072/446] Update AGX.rst --- doc/source/addons/AGX.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/addons/AGX.rst b/doc/source/addons/AGX.rst index 816f4fe75..5c65a9275 100644 --- a/doc/source/addons/AGX.rst +++ b/doc/source/addons/AGX.rst @@ -40,7 +40,7 @@ Note that the state of action groups is tracked on a per-action basis, rather th - This can result in an action group have actions in a mixed state where some actions are on and some are off. In this case querying the group state will result in a state of False. For the purposes of the group state being True or False, if *all* actions in the action group are true, the group state will return true. If *any* actions in the group are false,the group state with return False. - When an action triggers an animation, the state of the action will be uncertain until the animation finishes playing. Some parts will report True during the animation and some will report False. It depends on how the part creator set things up and not something AGX can control. - For clarity, visual feedback can be provided of the current state of an action group. When editing action groups, find the "Toggle Grp." button just below the text entry field for the group name in the main AGX window and enable it. (It is enabled/disabled for the current action group when you click the button.) Once you do this, the text displaying that group will change from gray to colored. Green: Group is activated (state True). Red: Group is deactivated (state False). Yellow: Group is in a mixed state, will return a state False when queried. -- It is okay to activate an already activated group and deactivate a non-activated group. Actions in the group will stil try to execute as normal. Exact behavior of a specific action will depend on how the action's creator set things up. +- It is okay to activate an already activated group and deactivate a non-activated group. Actions in the group will still try to execute as normal. Exact behavior of a specific action will depend on how the action's creator set things up. **Example code:** From 5c3fee66c284d77efefbea2ff8ead583417cfdde Mon Sep 17 00:00:00 2001 From: SirDiazo Date: Thu, 8 Jan 2015 09:43:25 -0700 Subject: [PATCH 073/446] Update AGX.rst --- doc/source/addons/AGX.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/source/addons/AGX.rst b/doc/source/addons/AGX.rst index 5c65a9275..387896231 100644 --- a/doc/source/addons/AGX.rst +++ b/doc/source/addons/AGX.rst @@ -50,6 +50,7 @@ Note that the state of action groups is tracked on a per-action basis, rather th - ``print "Action group 15 clicked!".`` - ``preserve.`` - ``}`` Print to the terminal anytime you activate action group 15. Use this to change variables within a running kOS script and the "Script Trigger" action found on the kOS computer part. + - If you want to use the ``on AG15`` command to monitor a part that has an animation, a cool down is required. - ``on AG15 {`` - ``print "Solar Panel Toggled!".`` From 7260bc042e604d10e4d3899566e8457a28805965 Mon Sep 17 00:00:00 2001 From: SirDiazo Date: Thu, 8 Jan 2015 09:43:52 -0700 Subject: [PATCH 074/446] Update AGX.rst --- doc/source/addons/AGX.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/source/addons/AGX.rst b/doc/source/addons/AGX.rst index 387896231..29c62ac49 100644 --- a/doc/source/addons/AGX.rst +++ b/doc/source/addons/AGX.rst @@ -51,7 +51,8 @@ Note that the state of action groups is tracked on a per-action basis, rather th - ``preserve.`` - ``}`` Print to the terminal anytime you activate action group 15. Use this to change variables within a running kOS script and the "Script Trigger" action found on the kOS computer part. -- If you want to use the ``on AG15`` command to monitor a part that has an animation, a cool down is required. +If you want to use the ``on AG15`` command to monitor a part that has an animation, a cool down is required. + - ``on AG15 {`` - ``print "Solar Panel Toggled!".`` - ``preserve.`` From 091549ff867b95da612c06931fa6179254bc66a6 Mon Sep 17 00:00:00 2001 From: SirDiazo Date: Thu, 8 Jan 2015 10:23:28 -0700 Subject: [PATCH 075/446] Update AGX.rst --- doc/source/addons/AGX.rst | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/doc/source/addons/AGX.rst b/doc/source/addons/AGX.rst index 29c62ac49..5e34786aa 100644 --- a/doc/source/addons/AGX.rst +++ b/doc/source/addons/AGX.rst @@ -64,15 +64,16 @@ If you want to use the ``on AG15`` command to monitor a part that has an animati As a workaround, you need to add a cooldown: +- ``declare cooldownTimeAG15 - ``on AG15 {`` -- ``if(cooldownTimeAG15 + 7 >= currentTime) {`` +- ``if cooldownTimeAG15 + 10 < time {`` - ``print "Solar Panel Toggled!".`` -- ``cooldownTimeAG15 = currentTime.`` +- ``set cooldownTimeAG15 to time.`` - ``}`` - ``preserve.`` - ``}`` -Note the 7 in the second line, that is your cooldown time in seconds. The above code will limit AG15 so it can only activate after 7 seconds have passed since the previous activation. +Note the 10 in the second line, that is your cooldown time in seconds. Set this to a number of seconds that is longer then your animation time and the above code will limit AG15 so it can only activate after 10 seconds have passed since the previous activation and not activate multiple times on the same activation. From fe3baa23e381486e0c378cd290225eaf69d4453e Mon Sep 17 00:00:00 2001 From: SirDiazo Date: Thu, 8 Jan 2015 10:23:46 -0700 Subject: [PATCH 076/446] Update AGX.rst --- doc/source/addons/AGX.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/addons/AGX.rst b/doc/source/addons/AGX.rst index 5e34786aa..2b94638e2 100644 --- a/doc/source/addons/AGX.rst +++ b/doc/source/addons/AGX.rst @@ -64,7 +64,7 @@ If you want to use the ``on AG15`` command to monitor a part that has an animati As a workaround, you need to add a cooldown: -- ``declare cooldownTimeAG15 +- ``declare cooldownTimeAG15`` - ``on AG15 {`` - ``if cooldownTimeAG15 + 10 < time {`` - ``print "Solar Panel Toggled!".`` From 96229b8082f81086df8b7ffc5cad62d3574ec7f6 Mon Sep 17 00:00:00 2001 From: SirDiazo Date: Thu, 8 Jan 2015 13:11:21 -0700 Subject: [PATCH 077/446] Add AGX images --- doc/source/addons/AGExtQuickStart1.jpg | Bin 0 -> 177699 bytes doc/source/addons/AGExtQuickStart2.jpg | Bin 0 -> 59285 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 doc/source/addons/AGExtQuickStart1.jpg create mode 100644 doc/source/addons/AGExtQuickStart2.jpg diff --git a/doc/source/addons/AGExtQuickStart1.jpg b/doc/source/addons/AGExtQuickStart1.jpg new file mode 100644 index 0000000000000000000000000000000000000000..4def229d71b183f8da894d9bf441e0915e5e7001 GIT binary patch literal 177699 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%0DXq!`5lxZy~~fRJA!JVkb=un1=4d< zh;}YeuuS1EOODu!-MnMV%XEjWLE%L*_v*v|f?J-Qty&gqR=H5})~_M0XufWDH>rat zr7H@PxoOHzfIQRedprT5cg}Tq6M^tu;R~4jD6)1gYBn$1F;hMIsM_xOzUc6&&K0wD zXRE$uDSFr@1Jl+?^y&I`!dKXTrhD=Z7TRR}=R+vzxej+)V8HgR^$%_Un(H6)ZU9fM zJCTB!Rq9q1Vn!Fu@f$9*CZ0OaR8yi%#~JSj{cg4GTcvUy9~5cP0rG${d16YJ1mAAg zn{>g~5H)i+h7AhuqHsub1AbDwy9hG2Ilo5=*TT_ssYO{Yc>Ss^GN=~6aau*uw6x-w zN`D(}13r``+y-sMX(4>Eg}5bSU+cA9HyIzC8xYAKYD`*KQ@J29u8?uzcnQA&{LJ`W zsnUwpmUR1>97HJF7U@setf?}_V)^XwkfHtZbv00lLiVks3GL`25zS|nqr>RGPQX5$LU)k;B=OzJj^*bHJ^@){=G$0K#U5N0{reQnzQ)bm8K{M_tUK{x z8Do^{8Sd}Z?2WEzw%qKFZCVAe90_|~yL^{X8jDT}grCWr z3KBNICgi)Ml*_Oso=dk_21mxc zf!;IYKA*H_nUJ4obk%sJC3-D*TlvcyLld6;wUtgQ|IV z{EYi;B+SUqOXeZ7^^m-$oa6ye7-XqHJCFew{q;8SUOZ-nFVkt!b;u??sRzXQW<~y$ zKg)b=jf2{3b$h~wg@k}sAFOm;PNs8J)keiBNBJ`chd*v)7Ofubz%c@++c5krq-Pj3KAZ0ezqw|~EKp?B#uE^BG# z)X$6ud<}d>;g32`p!-StX6+RsfhFtsx9{?QX)FCt+gl^|2UtAJk%d|7-vI9Zs}gvo zKBh4DsTHTw*=p8jFC8F!k@D}VyiV=p>+K(>`XN*Y^Tv14y&2>8c9c}BCnetH`O5ZO zFRz^Gk1ot5{NwuGfr0Q8!4ic?ex|F*8-Q}wZ_eMvg>B6&8?_;X2M6}j&cYYb|85^j zY9@18{f}Q0w5QrE>c_DxX{d%m6#nsR+)jIc`?XsK^exgV6DU{``k!o7vVIFFM9Tdm z;qHu)?k2xLbcLuxsIN zTqGh`as!CuXZaiTEz7@A-vDl5qiN?`5dhN=RW|6F1-7%!qe*?&sM29{B2Rv zz`wP*Wva8J^N$v=KV)kKYu(H6|4P3d1pY;LxTRP041z6yw*X4p{!^uYtOoy|R_k8Q zit&lEznumD&${p`)XqIMY*WGMSII?|SJ{Ur&x2YTjgK{Ia5lLrdpJ{|l_S|B!Ak2H zYsc;AR^J=IVMs`{-VFe4Qn=G!+bB}2yM6;0LHs>#GJKhG`Ot8#TzK;6O5^2Uc9IDX z@61H@?@U0}r_dH=JIX(Ca-_G$fYtoC<#s3+7jpy1kPRE%@Wp4(zPBnE^$fCU$NA%X z=_SEajbcVSM@oX=u;zLbz6R}P^VSx0mV?iA9KKN(!Mt8hgb+FqSIeJSr@sd)X5fvi~#Sps89{K5~u{$6mB zsTUaPu~fc}yxreHTZq)l59Mx4=-J&a;KUTJ#P$h#q%3sneZF6Ph!AWtop~0K7*{`g zYgvPmKV&jc^HEAVnzkeL8^E2jUy%*qQ$k)AiZvnoSJa{HD2|=7+Ov4} zw#8eXhAdZN2j6yQ=%fr?5{59S7C$K=`;(MQ=Mi#N`Kxdh)sr068-SLdqiYl8OMJn` z8^DotLVN4;vL_fj$}pl*GN^*ITyKP6&GL?_s@8yC>@5_dPocBsnmfdr>TwyeH-HP- z!fV|5+ex82EzV8i?|;~<&yaW^2_4_@RJj-$kxi7fFHAopTZZG>w`6HI0*v{)N@@d+LhJVjf6B*fBbrcY4P^tVMdBv((6D_?}RoNA@4o1=ApUk`@ zhnzye7;~M#iObI~V>t{^Fm!+FbKkyngDSMJ_u@7S5j_Y&%#x*Uu%W!h9#dHt_WriG zAheE@Z6j>>FyaR@3wdXJA)AM2d@S~Nk21H%8@9-P;}M?gaGh{c(zg7RW1}(dQQ))# zeQSjA(ZdkLs;*%$K^|dE%#TdR@_zFXp4Quz|5^F3e}GZ$JGKBc%GfkHy7p zrm$GECS29k{+$c)54V3PrXs5~J!Cl(VR`qM3Qb1GuLz?580My<&2^W~3mHPZvFInZ z!E5$?eWKM9PgTM@bnrlkdqMlZ{4KfX-6Yg$6(6I6Qbs8KFNwfNuO`j8?bG;=lT#UP z(}*&$E2`hQyS)cc1~y~mrga_Yxu2wtpWXTEm3i;+AR{_ltR}l?<2>FsM1+G3IK)^v zHy58$tqHiCSHbfCl?o+%pVQCty`MI7jR@67N zu>Yc1YtkCXj0^l^x0@{~z{oY5FDXR|ba?7zZwumKO-&~T-%jjG4tPI`X%01x8~qSX z?2`n2QUjmf`^uHXC6uxfE8ujA)n*`zuz%jzQF*OL;CWo-@;yjCW^KL+#{Fmg0NP|d z>$+9nwDk!lx8~tJ2UG}9loh{BB9N;AIJ@*%NJU5G66=IKUx70$msSe-Y1hsZ`RVnk z#RGr!G|w#tCCHO$lQ!U%AWPAd%;<4w`fQ56(F-mVfrE>9y{n;?yFFZ<2_r zluHiOSovu5(UmQzj}_Zxu7$d$6&>F0g*7?3igvdfTK^PX$P!G?iBMKa9;QFoiuNWX9x1>1m zX>5g<^Kt;GBv_6{Cd1O4UDUTAlO&I9w)^KZ=ec)zSt}#)t@1q06n&^M%IgyGXUF7l zn@fdh$Yipmg*79mbq*2OX=&K>h=NulsrD$(~8&fPlvyyW#}r1 zJ(uYHJe;e3)o+>mgY&HH>l*;|Rqs0Rao z`-4R-o@x0@Wb;16ft7neitAO@1?<;+&dPv#igLOb}r(@g=5sfVTCBu0J zfnO>;C`%!d{0urrHvqHP5?N-WHM_{epDW{ys^bsBzip)r_Q9GO2i7sGbBz+9th8ae z)L?a70Yb7bsYEu7LHAF%=dOtu(m}Q&%UpOd1Ow;pQam8x6LoFpoUgC##1y&H z%JbT+Gn0r_K8)(z^?a8`s3I{@-y2p+_CGj#%c!=3F5Vl8wZ%#)#ex+m1qv-z2m~v| zCAdQ+xI=I)P@qsqAh=W9tw?Zd3GNWwA-GG?-aOB}>#n=*x?kS+V`iP1>@zcG&Y3;G z{of@+17x{n#Mam#xbQ6z=>bbWne;RyGd48=Z@sPZ$zX^Y`%G|piO>Vlhbv@zzM zw`CUhhMV>VojL!q-=wd0+k050dM-`vBg4fweQRGgI^6 zx?1j`{chP!D!mWO3iD&SllPJvq6UU*9&OjGufr)rEJwW$Rc)=f%*Ls$Y(sz#bVFN( ze*rsqJjpsbI#7Wp($=z=rx)m%b<;|+iL>&vCnPs7VwQuJhasdd)D*60Pqz^TLK$si z*WAe4g659*SKV8yPObPCID4 zpz)sNuU^{a<3hPupR+g-cF~Rq22WM5-z0iZ*?UG1HcDCrEz7`hb1g+M+2ks+;7WIR z?%@S--p;6ZMDdbc)VNMdl>!4X-Pr0Ht(E`VaTu_pTlZYIs!GeyPMEW#PUGXtpo}FB zm(!(Q0gn%S^*r-LdY{Mv%vCRrZ-ni2t$nm740U%+RPoiPwC46-idsj;Q>Im0fR+R6 zj0FLLkhGXScbz$%RKt(u?`%?bEauG`CQ#O)j}20{pQ$)pC}2dM0HnN_6V9%fvo7#W zy~QAVw~KdLR~oY0d3Q_lmp;GXYwp<952$35F)COdhwPOud_$q3Bd@?6=?IfaQc0g? z4vk)GVzugTc7~}N#c0E=4AreJcEU`zLqbqi#bOQa3Ul@J^-g|imLXNyLfvUo6Xycf zKBXRnS_yTZXf8y>XSxlK9uir1bd!-Ih`IjnfT;g}Xf)&Z5F*TyRrx=hV-CIgzGGea zC2?&o+B!WiDyx0=IUkM5R=Goc$*Wgn3@mZ$t(qcwk-9H>xPKm3w7Q+9}Q!x2I8 z8mx7CV^SaG>qaCS6jn^QUzgONX+F~56s_e`cxW;@8PX?`n>TEC49PuT$R4)I5mHB2 zXJ_Y3TI9=rMZJCCm%}JW{Iwmc=CbeFSunA?U2Fj}sE7;IpS|Fh+Dg%9h?-_LW5nsf z^cQ!imZ=KHjmdcD*~J|v$`}cuHn|}3c(cUV zYru&16q`Y@4tKck3JM=A*1ONIT1UFCb%m{U#A^?e@CwY7xz7!jU0l~UdLHm~u|4g7 z24i))_-fe;py(NvAZ~iCd)+tJ;x?AApS%m?oU2xtrgKqreglF#Vc<-ULo8Yo>XB!u z3-mYPsUZIe8QZy$Bk?;?-Z;YpLt3tn%D(wglTT^Q=+~gia82B0Mqg^`y}O*I7HSD! z2=H(i^m1Qu$5u8!V?oczrKlt$Jw6}Cp|N*SDbO^#7EJ^WKkD@i8fS$48U$$7RqIMZ zx{Sh*;!T%nW`RRX9y%u3XqS%7ficnKiW}y zf0Xj-&*txzT4yqgjp-o@#%wl95F6<9*%r6ze7Muq4Et~ z0WWMI6d7MGpdq-t4*cYj^+3%hMrBhesT-uPCtY-9Y!h4gYqN#TOMwn#@}}RIUPnUZ zOVCg~qd`)WlN3Ws!rG28IYpcx@$!Zq00zV)RCNW_(jv-H4k(C$eQ(z{i%b-1e?T4% zas!>88lT(k=eW-sH9j`E9@{7itjI10!AYxUklsb-%TMK{ zf2vp3vP^+bX^x^Vvwq8nEpI**#W)DS3-N|QR@?n??#bM_;#&wCy)OFf9W>&t_xdMz znX^Vf!^G71WWWBY2KZJh1y9Dm9pudf!fA4}KCc%NQf;gP>jB)r9u6E>QMOHMAL~X# z1N>UTgc{}OZ5m8XrKMPELbMv_7+&R3CtI-axuM74BXfA=WwnGz*Q_#TD#!$UU0k zLt1-Kvwpjed~#!k-4%x(tOKXF^kR~H56;At?(uxlPJUUSAhd&tFmq`n2U|2WK5~+n zO5Qf5z~7Nri(6b#j4v47YrA~K6oh)~C~uqg(?m^PBcxl`6ki4W((@DsCboHto)9X4 z4!mfiH&FjidRxCCBD zA8)dp*z$e9_*4JaZRXSKDI23;F39{M!|D<{lOFIjFMLCOU+^wMbd5VJh3jl@SAWhf=2z-eXsIg|!JpH)#Xa1> z9uypSeR^KVqIrVb)3Nc{&s-HSSehG+0$GZsh{9Pn>o9<%*RIqzy4e!p&LMTFbJPiPBIO>qBf(T+Fc{R__BAZ>{%6~X1dcwqU+JeIwmQ_vC zv*>0)k+snEt1}JZzRzGSW?m7;v8;s&+o~cx?E$}{Ga2I)A3CSC9J*SQ7uUhMmRt@~%d4OP!Qa$y=kYX7Z!^7i z0+xHy5)3g&=AQN*_YLn{gEmT`()3P@zMhi5xIY+`vr>fHE#+&!oA7Y1>VA81n`z6E zdz_KM%A(NWTvmc$A$Um9BXvki-(z(;WzR(~%?_*6@s0p`A=0z7 zyPu?-Jf+y>gnxC6aBbC#z+7;WX)IQ7*iaPFJhbv8>?tn7Q0?I<>cHrIma7NRPG@wz z5oaM6lb~aYd`pu6Yhe53CxR*su&Rhy60U?X+jMedZQm<}@zsX;Ca^u!<&(eP?=ojq z{lzN0`?rSqlj@O8iDHSQ1%)WSfV8E>rfbl=4^s{2=;XBMflB#mg63irlMS7s^KE8? ztD8Gnvaz}OnSnQnuO8!%H?XDul#zH{qv;bqE3zbR58$8vM# z#$tY9e_}?NmN$LD2YT5Rm7h5>z1JkE(raL>i8Z`_PXd1jOKM`TC-u$ueU8e0DjDh6 z;k*^b)J-1rpH_(ChLnalaREI72gI2l@b2|)mo5rq)u)DmQo5*Y;q8FIe>gVYub57< z0)E_2dUJ(Vf?j$WF~VtvwxJiyL2vTzzik!MU9IR8_aKg0h(x?-ufuMrPz_<3L$^*v zQ7o6hwDD+TjG3RUTL~0Q`vhHofb8Lm$`Zb?yhbYy%{ocs!CK}H1f1bR&u_`7ZGP;cr}IE=B)aI6SKg**)$dZcmwEe*rn<7r@}=3Uqq+qqaMuI(n%m@T-}|Mis1dtzQ- zuQSL|K#-fg^2rojAdWI_4cFy#()m%li2jC0HCTl?tVwbf2in1Ii~7DVKO_&iyC*Ii zyz*(-{#vagcS=GbH@06k?|gw1EQBS=^I;F$BE8x%G{=3-jm2UN53_!H3Wz0}oq$|V z?kj5btX@Wp$~H7l4J@_^253&2h02@tJQ8>D&PomX0%lj}cn8vEkl6eB*1v#!N0S1$ z?1J`vqALGRikQcE+I=YnM8Zudc2V{{U6TZ+$-$iFR^*6f0y6m1i7-kvH8GATT!~dm-(wPC5oSm%f>-i6bfxJ zq1`_DJrKK1ZcXFfIkg5W5ckrye|D4qbDv%Zr5uoOr{g*r{~%#`SG_Jg&77h#l!O{* z4|cSC&OrD08XF#t&&0ILW01cqSvAJMsccgO*D%b^H`fu{GVPM(HnTNLK4iu7>h}bS zZ}LqVimBNzDZBT2v`yOBqzl+qQ=Oo8g&#|*Pi)wZygy%W(lY?Ns9UI=$JL;YV7eIMc9+cj^)j6roUHplb zGP_Y}YgynJF7wNG7&2#?g;4kd7h~t~dYf5p4;zyN-TAHDvYdRsKI<1SO70Z;XY$Rn zKrz1NwKU<7{jFe($VX}`!-^W^#qiwp3-2;+pqz6wo%tEQ8dWlfwITiLs& zTvts@>TaoohRO*(2i4$(k{ONMR$*c+_F_$|BSuRdy%Uak{1fU`RT*ApWz24w7eT7W z&_ZSNN2rD@0OdZyQ-ty8y9fhVr|7RbK6O1P#rsb#52xIh%nErClLhB)Q`6|@sqs{K!}%i1 z>A!D-X4Ux%YjaU(Hg#| zT3Q6=mp80t`SFNu9>L=SNVV|0Pz$6V%$jJ&V9)TysMQ`>o2H=l#7Em2yO@4GA(^G` zCQ6JiY#+@|)!X8<57AE&wPjy*^GGsA?BVR%;+3#Z*3x+=u$o@2`(y{HttV6^&rWsE ze+pf<8}cr8_4d#(+SfJ=Q{M6_(^D{Ekl(;h>3bZijUyf4jTYe>bn0RLBvFG1C9K`aTD)-Ze?w1U|--Ba=+uWTeAQfCwOMr@JE!(@MN&7}s z{XDQ}EhEkrmlt6^xugp?&<1C=bz}w@jwqj8+PUG)nM@&EWV9{Lw@WdI+A+{Q8SDOs z6XfN5nRN}M@{rmt_G8Mi*X7a#%!ij}1ooZEqo9FZJG^^RCecsQ@B#dcm?GhzAssSZ!Y;7EpH7#$@)G4;|$1O|HC5Kx~ zuUJ+6`f=L%NAZR2gW0tjzt0SFvJ*CFqjK`RyaLgvx{J}yMVig7F4#(#Ble4ms;%yh zFmfbL6#Idc{iB9Ugmcx;R|g>ru4#yA)$i?3MZ%n%aNF^jul-8mPeN8x_RDVMrYII% zP2|en?FMgiS`THLH`F*`HQc(Q*N~s*t^rp;zoc%?>dIJhYFk_{O4vxXgG_RT`K^={GU#+1)G%u#_cDapqBQBDj3SSPO%c`lV+ErZF`qn{3j z@R1g=k*11$|I5auR$cj%x-^Ktx94Y1cGyC3jqHKV92wj{wyxKBmu#xC$$G6;%gp==M^hNO@fzWU#li#ko`>~&G6OF_qslMDcRn%2KPD7UH-K8YnOk5u19@4 zt--MF8eiuvftj$}k0TvYk*$Z{OVitUY--0y_Vu4?Ss^pNmar?S<_8kla z!EG+yKmTV9Z&hDG!MeuTxe$i*O1Yyx%TX0G-Xsym{grYjJd0Im@c3hi;)o@Ar>3dr zVMZ(kl$v3T3`_8V`e9~~*n866?>YcOhO^^a@&mAT)Arh5ruovExX5gzroXy|o{XyG zv7M_0?@dfQG)zrSp?BTSMz^7E*PvA=MW2hFbYQgW*`FJlCA-+YXfP>`U#p0URQ7-G zrTu>Wzm^8x^^Zl7CcuibVZyVS2JF@_8VB;E=*}r%@Tn&r`)~7k=kr1yc2aS!k7cuEJTMH{DMTHxN$8ux1zU&wLN6 zb`t$S0eCmD|EuXYGRQx6g;`~O*(nP;GS5ub!3D{k#ZUP56;Obf$b&UJAQ7(K*`Ob* zL(Pb)s%kmv_E_n|gxrSN*_h^QRNP+8r&yT;5^dW)w++nf^02ivR6U?!o7X!qU19E!ra9!jRKWBc)5(8cW=;^t=6RLwLyAePz_Ur;YtJ&GQ^*(7B zEYjm%&&u|dNd4_t61(!d;QzK5G~%D0iFXsWJnaD^o2tHdA8(64%W(A zuI+T(ITqVlX-s>Oqf#(aH^EQWWJIW)lNk6zH*3)Ee8CBrUkbxI0KmEgL9}W1Hcwg10$Nj>o})pVZFF%h zx*J(;{!Bn+GqTB1Og>oxZ?Q_}kCwdpU#?_90f7y^?Vw z6B;d@IbZk0znVq!OE2I4jM?A>QD~cnq}m0Q7YDXRQ5gj$AaoH%k3dd_W1{2Fq=huN(hK zZu(a?jwc$ae%vfM6Hi9o%C!^cIL86YCHwAQyPZk^xSypzyC`Bz@C^c`jB8S-KkEC%0vGsWxJ%Z|soew!&njC@HcPrHJYR zOQWfMix!yq5>{G=2t9Wj+_q||tlwz4i#A-MjKwY-@>|HVQzx9iV;HJHYl9ll3^YZ{ z5*4~RVAuooctqv-j!oaFL#V=xRetfeq0S57p(~FU?ecO<7XuNCjfv&Y(9XF5^-j`` zm_Hr$cyGlI%#-w;#IsJd^H4wPzT<L!q&Q%H9y0;2vWoC*$j%Uv z*Ou2%=I~ITc@b;nj&^dAlSVZ^srv6|m4v1x5a+ehZ5I_Fbta}1xRp6+fut8s0E~Fc z2s82kZ#Yfpi>u(tc2RCY_LD9KP<8lbV72^9bedS3Z8dtCa1Tg}O44)DwFlc2nx2r? ztsV6B5?^-FHye+5`^4#$(g*L|PqMz>pQxl*qX+MqhW7muu6;I_(EwMgFQ{@oEt=G@ ztb>e~WlGrUmR1fjEL(>bNH`Q>wO zN)DYH6=dodZX4Pd+YW=0jQb|-k)v{AjS=psZv0aEjdH`==@1Hn(n(VUqax; z6TXYr0%J0IYFuTS;a{AF<}oW9=TtuxoeHxPUBOWD_vA7MucBc8a2An=ce`T6R=lJy zRWv4im-)LcUNykoPZsu_j(C6sge#d6oJ&+c7jMuEhb{PFzR1ItU8(*gTP;2zVkuv{S zt&XZm4o>6b+2L@z|GL{$MOOL}L4^=tbUhI16;!j(5JpDBZG0#da~`iZ-h15-*Vq0# z%&|+w&_MiG3vLy29tHk(;$LMf+M4?hr@#ODkG!Mm_HW0=I$tQLtyGUO8Tbz;A@)3C z^bMAf-`sQLEEyRW5+BM^F}=fKg$|kxE46#03BIFKPmP+nw)jriX7+C8iB-66sg2X<9cj z8ERPSpZ(&Lh`L)t%)7^io;%xhBEWK( zBE*VzONyK|2>5svpU+oPmTCUi<;%bR5t2yD16@jKhtLl7L4-s(#L?BIrTyW+am(~} z``Un~U*q}nCO?^Sb;G>OG5hg4T20X z<&AO{dklq%#(P%pQ-6gr3Jl44lkhzVo7beK_6E_Op1J#P%#9YA?UIV%rKPwt?da~B zGvuE`^3L!CpS;V@S2R)I>bgKtGSqv`j;6uDc%Tg_n^%SQo#|(_uYD{(L$mEw+{nT^ zraN5Cf>FSBarvNTe4o#`44lhY_EYcEeI5&`&zJB>2pyihH2s6v=8xjCMv9Iq0R*qD-?2 zIm;?Yq2C>OcN2o|xWjpI_jsW6u(m(-mz+k}gFw%Mp!`tpq@vmFIpJK1w+a#O+E`Ge z4$I3x4n}i#1ll~5E~U44-A(XWMl|;5=x6$#hj-6K!(PAFBAF9;6AW73&;Trk^29Hc zZy1zAUvW%!Pc{6BUiS1*z3bOFKSrM7%kPF~HdtxvN_`lzc5=Xex$MHX4Xe=O;dEwX zu0ElgHOm=Zv`5>M&I{#*B~Q-J=!}GBB1&MK@;dLm$EEy{1~&-CRj+q-8A*)IokN)f z4W%W8->a3Cl^NKyjAoAkUaWs-2o*uGD7Jq%Rnj9 zrffwj=}Rl1Eshw~Kac z%*<+BtKLub;)?(m0@Dj-+MRpxJetoxue?ZAM?IOUX2}#uzKJ-pIpB;5w;Qti zGAF3q(<0Gqv}FJ)F7xU|>dTMauijg4M&nQ}sQQEniMLDS?5 z(@~v5p{W$C(^cLx7a~))YUv>_sa2_Px%OBs=pT+Xa&Ugccx%TT2U$&Jn1|$=l)nhAw8LLA=$q8pNlc_ZbkOW>;$_9ZaI7k6Msi;524>Pn zlD&j`TP#yyIQLpW_+X)adLa!$#Aq(qa#=%Mc9I~r7@1u;o7yyHf!OIQV%SU1epl(d zZ$IQKuom*Z!P+mtHh-TUtX~=@R9B{`W#kmP!EURsZwV(0YXl_%?C_&U)D%03buMd@ z?Q2p9mHfmsK1!5k`>AN3o#Xkwd4gg!=yzIH3Cu%TSrMRmodfnI4hxoYtsQ3h^Xh+K z!xn@m&(2Gek0byd5U5e@%1w%5zYH!LhFC33e(6h#I}a$1O}4;3{@JClN2vsywQwz} zZ288(M*-{gxhx^99={ZW+bpCnT5bFE+ZRkpq`vVSUGS(Bin(E1Uk@Guc&-qpkJtQY zY0VgRaEBGA8q7ly95p(ODF1*|ysQvP@Mt=@hax-96VS2XTF$$VMcHlJjj0mZRdZ&I zjdMK8Z1x{`Y`?og-+qd$w-#B>WYp%cUq~D*7Lu*k)SR(8C(qGL;rgMYY8Dr=zi5g^ zu>#&Mn=Z>BJGPX*j@_lA$7XAxWq0Ws+g>H5R0)6ScTrQrplU%o3+1M|nuK#uFx;D1 zC$^5Rakk|R`?!Lh(QEIJQLQoK++s*aVN3(bK|9&3nvAJ4(uGj;!?uY*naNy2L)|a6 ziFuyL(w{+cy&e!qos_;*dQ4iFN964`$#ot{|}*(_KN0S?vut=nQyAO@MBwl&R&ID|}8WZ9kbl*5SB>z;c!I71rzae3Q! zBbm<_3_NZ#$Iw59oovKSQtJdh`yc<|3_4T~U()@$|GC?}Wp{mP=&qMn<2vQz zD(aFC3stPJFU3#Mtpn0^kO@D+A;mv=M3e=T-kLqFp}$Bhtw4~HIwSRY25ol^>`GuD z;ZM+Xfc$K$47LsAJwHz}L$v5Qc=x*rVRz!Q$E!{`V6I^?3Q&qa&X2?|)trsPrLL zxqI%T+n)$iVg zJ=hGuivGPi=5Xq{*I*=G61}Rxt=hU%wcLX!>+^~}Mi;T?3t7}*k)vlW?=fna4}Wtn zlKYMKmNC(w5$}udE%Oz1VH2jM0@EdsxZgY0mS!tmw#JOTv|Y0v5Q$G$T&>mnFYEqP zWRK~V@oD%VhwZ2zibW)#8WwhwtL8#!M(9kMGm!LNCQXmVF74TKxL#E_%PVb{Y!(;% zgh2(Yviuh+!!nR8D4@81ZIbm(!O?{fQ#N+z-=*r^HYQwu&$n%KVLx;jJLC-aCRJ{; zruHmh$Y!Df| zq@(4rv61;OXiT@jfFF^$aOig9><`B1I%}gm_U_PKX*mbPR7$w@KyT}~#CLK>;Ob?gNEis+RzVfCP~pa5 z(@3weLn^FlS!WpH>e9vF>h|=5S+JE)8ecTV9=D8$Ud_A0+A)Gmhtzocnue)n+j6=YfhAjcITK`Fz-Qw^R~q<#hfV=*_<)A^v3k?Dt)(? z-^N7|UGnD5Gut~naXzvjoJPKfR%#!d2V zihN4=8H1voHZ=a=K;-UX>|04)>G?#Ix!CYVbgZtCdy=PdluAf^Gda#}RF<{NJUk|8 zcHZH_FHz*_JY^aJ%=Piad*+J!3b?g&B>eNbZL|p$K=G?-rb(<7OgrQY&Croowk;8F z`!z=}`wyoi**$1Yd*_uSd6pZi4ZACXu%?@6vz>%zeouJ17gSnvS7}A}L&vR;L0Q52 zRmSwDvsqxr(9j5-QNv8f74z9E-e=E?x&06+qsnTd_6318RqZFHqm+hpG#+M1dm0Sz zSlhy#b*A4zB1N!_CDVOBUs0^QP0r*O7O~!GF}Fdw8yOV67Om!1#XYz%g=7o)p)mSm zB=}~r=}2aZCW*%_#bP$UtR1FoTsN*8QxJoyc6QanTfZc9r+~|Kl4eizKRbDl?l?C| z^pPvoTi=-1-MBYvj3piDIbgIcY%i`gVOe7Q z+MHke0+zR#=k~vl=R~>Q^*3MiJQ(hM7R$xz&2CHAK%aHLjH6prXE!9WCK6upOqGH9 zzS~=lC5!DcUM{Q2$X6}|vy`ttElnw?QRU9#FlEeKWORmU4 z&n*8T020racTP~DZSb>k+LpB}D^-l$LQX-18Jp-2_5O+CO}7qRMYRd3K@meh@pxRd z$w$ug6Y4hGTn_djxO=A}kgdKrWzu^XY^{_+BSbaCMKo1y*|AtVXZpg*HDd(-0WJ-G z5Ht``D>!T=s;6bheNbn#fX#D&r@XVyGMYq(%RX$|?nGmap%IZ#c)QCxP~%@!YHylT zr8PN;L%$T($`LI}1pG#MQGVu^wk^u7(>SMS5&D?hts_y%bJb_At|*u^I(n};5LKff zLQ8}z=x9wRuaDN&ur8UWs&x`^E`6b;7 zmxR8=s{aY)CC!cVS}mP`GYJSyATt@TDV?a230*Gl#{92~x8ld3z!Bg8bF}y_n@Q^S z!_oUQ(gle2&?*2;7DE~T^=U)|B7Ilxrn03E)T<6hSEM7)|HK6*1?&qfX^ zh<-|9pvDb`a``p)T5#0JL6x*5e8@NSlfYNwRg-Q-z>%8VW-|OMzQL zK2(cc@X)ut&v5FH;DDEilz}{Ks>=F);>;lnvDh!W)+YQonUgbZ#~{acBPz-#xnTf@ zp~9NB8yXlJFZr>s%>CxB8l|OEx9w~P&o7{8*x3KnAI|(_gy_e2{IlU#%z_2xqTGrL z^e&b9EP3UhoXidr6paUh$i^-KW>5L~I#~Z$4Ng~BBIpA}P2=eH9tE?-q!AJM&^R4j zSzXbrvHmpfn$xpHqbN zxlyFw1pD@Mvc(ni`-^HJC@3KQQ&SI_N-e!E_VX(Enc{WMWA8^2Y6qM+dHx&$@m!8p zL%W`Ac<0AYBt+@h*!P3ySt_!jKYV&l_mFP3fgRTCPEw#U2FG&O#qS0AsoEwlvdpEO zz5(Grnf3IQQx6nqY1e*xWnq&mq*&dl&DlD-(;0@&tx;%(9(q{q1WJU= zbjOO?>=*p`8Tre^Cd%G~`(;cSLQ{V)h#?`ed)Pb|w?1DW<>k zI6;JGQ%*u5FS>2cnv^++rWefish+`8n3SsYwc#vU2&IDdwtuEY=g~Xg`<#&u{d{Ga z5oSHaH#`-jc5eH#Wsa+?-bPnPeWDWenxCW=%RmJ%x$AKJrP;fkp0jjM3!l2smMDsJ z`|xKlW*=fKb9sRCeI_Q&hc$$|^hR#Xkhd-au4RhNkW^@e5c$F8^FxtYBvf#v!J1YC zz%4{zFVq?Ic<0etVQvQBYt7#tLi?;N?XaAOf@iJiHQTly+?xnUv<3MPD*#B5xUu5K z?<)lOv4Q7(A$H>D`4|?Bd+hAk7zqhgRrgEgs9hQ9V}e*OqzOW)iOhtHt_)TTU!5}u zG3KM+AZ@@3*}tU08scpu%HldqPMC&;W!h9vYkxvz=Wo>Cw8cDZ4WDngL@X&5y-L^N z5h=F)*b;TnFE(VnOgBc~YYn6U0;o80+zyhb97`OMnq-_1ae)GKXuiQAC#U5{00`^1 z=W(V!!gk&dxTk9*wKX0uo;Gcr(zrVZ^Dgc|H#h3ss7%^wr9W3BDLOP7weT(~8k*n~oYA1w>Ugl5{;4UCwJ`VrJ0Ty7HjfQK>yCFux-LmB+cU_G zcIZg_FY88n^D$U!`beXVL9!Tr*bJ|2@K-DyR$ze7C&(}Ih13yH^VIK(`%7rlWNpn^ z+)<}RhTQLV!_h>Muaee}=9L~}ow4k%sbAq1ATnA~Uq%=w1g8&r()K{X%$VOWm!>Hj z;Le`5dvZE>>#UrY3?P1s{JNGQP;qd#C6EL=s#FIH^a= zwOz=~Qc-kP#GLBh@zPi(#c+A$Bu#WVcx{DUR+imfTYJJa+h9=&LQk*Ux+v*5QUAG8 zyI0GA$W4(pH?|@96c|%g(Tm%Z{uNBbq#=$gP5Qh#ag0>foTsijS6j54)6$xdlL3}$ zjO&OKiljiPDQG0@uGdftqpOaU)h|>~v}({rxlNG_=;-gefVu_3^wOAGGGA@i)ki9C z&XQkXG0`6S@4bv0C0OA-=L&lULG4XV#=RyhD^hD`vF|6=8c&|zDQZYN_yL~2hfq;W ze!ws}JTmk*!Y2I@0YUI~x;Nx1pgF~7qTKeRs`_&pS}Fj*aauI4mo2}%nBmfnR{Xoi zNt|;ayPV=5&2~mb9|6BbZlh(qEs1DNc4{_EctB&oI88cVkK;dVj=si$iMWWjPU5KI zhg@Y}YzVZ=vg$gVN+3CfW#2)H%${9$h?DNb2QD)5_=Q|_$MObXEy`?uX;w2U=jDX7 zJHLQay~Y+H17)xvLRQW!FclL5kL;)Pq=jOMWL61NZryPkzac0IVJMIvhf+M|fTP`# zc7wobY5nB^7%Onl88s(tDk(bSm*GOT372FlwJe*YqDt5tRop6zr27IG2(x$&jKYYl zi~qh#gD_AfG=V2HA`r*Y9618MowPJ}!9E7Tk!!O~8Z42hV`u-I0GFJIbm!Lx>77f~ zkYXDHJx!l_u`xD>!#K1^B*Rb-4Xp%Gd{pC*oc7!T0S}4mgnfL>SeW=|47YnP0+Z+> zveHGfmR34Pd**zfb=S{>6(HX{D9VaDv4TcNziDg@EXma^U9= zKIh!4NlrWzv8eZ9%P)*rur}|^c(}b<#;_d|7)en({pR&N9g&!KnW&%MYjqj$YeBbX zcDc`BL8{X}_~mhwVGjU+gDm(g)JoJ8`5s+c^Co5_A_mXmM+;wq!_ZJ0M?AHbEW4oV za0*SZ&5OgFF6n*`V5_Me>)r>eHhl@x6Rt)vH(3gb@7oN`^5pIhEyfrbM$*>P)?;J) zRvFCo=+{KDq4Yu@Dt=hdzDnY&h#JHvP5RVM!&>eQ`4oD7uy!YXlkhtZ3=5^Jm!WnR zgh#<<7meG;JW<&2&tmL0TXAv7tNVaj{pj-Pq9M^o0^8Z8oFDt2Bqy>RHTd%25V|pF z8j0ne;!`>+>=y7CyI%e0^jC|EL)F<5e#_Q&4$~a4a_(UE>6M;|dLv?`krD{Ab53&_ z?`3>!a#9;LL;dH|)yFn29ksL1QQC)cRL>{m9=?zZhNt%})S8;urYIH-0+UA@q7Y!~ z(WiV3t!j8!DF#!j@Vsv~jt&yFiw1KGs~o}-UWVRe7w|BYVd|3nS>)euhdI}BzVE9a zhPx}zoNp+|vuSkGp?|>xw70~D!wxlX{@%xAKFNq4pjfOY>T;<|Bzmemms!Ry;UmF0 z;*m+dSVX(V@wa>J=HQ3>ikF+KV082NA1Xl~T7VQT!mofym~!IIlt!1N9?M=QI}Tg^ z5hXiaxxvB>lDU?@IsBN$1Xii)d9L>U<{O>P9IFL4|Mfpt(SGY1lUa(Sq6pnTG^)SZ zupD^WD7FRRrVa^!m_q&Fg0$ z_$QFlr*T)by{Gy&cBc^H*VM)`LIp6RRT zc_gnsw`D+!aG8B?17Y{s;q%t@`CxBYosvQDsypc65o=Eo*Q^bLteWyHYmwE;g2D~x zeFZh|vC7{JCi)-7qECXQlwHP!N%K(TfB?=4CNw;vM#H$!jl@qZV&H+H8hB;~$9+7c3w_lnG3przb1~LDdO1@?YdO3Ub1j%dK`l zkX@``(`{nUNH6~K5c3v3#Z`909h4aMmRg&KpNG;k!hN(t%Ma~cxHLp2SOyz`?= zX{J_JU`++IpTdJ8(h<@uW&=i@)Zg6ylm!`LoGpeK5%{%GbHgR zVZ$WSq7jl-Bbz?@jNasZR0wFo4 zBe@)KNMPM9o603|_zWS3`Y^U%z(!VV@v>5G%%A}?4Dx+$_?+o(W0X>tQaVc8i?8}yaI3DwiA0y4u%#JflxV;np;dthoy@od< zUS+v)8}QJ?lz(sYf&{0AkWvH+I;HIf`|z%VfQa?bQqU6}XZCE_e!K4O#Xs`kckt!3|#t)u+QyhPGm$o%)u9B z!*6&>*w^X+S(v5Dlm|x`QYaTgyDrph zN$k3G=r_--s6ExW#e|L4Gae@<{=yvk4~IRyDM>C z=l{iwCot|;iXWOejZ}+Vg6#bbr*LG#@EKb~dFbPZR-mq5@`a!O9*jXTh=fGa_I4TK z$tm`p9_v1tM&169bUZY+hi~QFwY5mR$mo^e%IK9Hu~A-N06ozPI#~Wf)c;|IEi5CZ zWq{XeH+e$y#5>F41_~qc2J?R)zk86;(*R8B3qZ&WuMP8h4ejTu+&NJG!7^JU zM_T5Vo}S?WPnkV^*|@ic!!eWl{-0LJfX^MO*JiSVhh1j5IR7C3b63(uv^=fBxD97o zy$M>+B|PVGscFo!0Uzd6DB$7ks8bK{gt_R)P*(F|GBdIRP#!av$<0$G&k9e*ipt-W zcq$Odz4iN1?|+yw95lNsHCI^7mekz+cY3OcP`aKi(usVk)-2R>-f+k3bYwrWY1vmN zr_E!~vBQl&b`sk|+3#%6SABen*q+j)(|_@qQ^JQwA!ktv^euxl0Lo<$j-lYQ*a>Zc zQ%4A$Od1xAAwr|GD<6q;cSCl#69x=U42OdrPaF*c%E>~thWrw!$)~F|b#%wx<<($M zZ?bterRQTCLfY37GM~dDIuiV;d^?-8Nv^Uf^@v?fW?B9oo0qh;xpV)pUCL^tI16JxlmHZbQf*dl-(( zLlEBbGyTwF>$fbaJ}?jQkQ@oKc#A{ue`t+x$qy;F?SJO)fT&azq=hCR0s?|`2#QD(0qHdq0V$y) zy$J{?B|vCOmrm#q0wGk9E;ZB;iu4wG5fJ=x-_N5%w%U~Uz5x= zd;d!GN9$2h>udl^$T2Cs>vo)`?hh7?%|0a}L=CSz**rcp*jaMDnS)-PSwT-3;~r=; zsWdjB)rU8$sk9pqRxPl5kpDHs*N7{^K>E$iUVsnaDNL5O(+LbBeUvOVPJ_X8iJZOl zv0?%(@7-%Rlc^{l!* z4_(3Tj7tb=y!GuLEj!O@_s<-ju1rD4l&}2AFNMC5s~XkqFo>ARbg4e+FTy`LF@jXJ z6#7jV@6sl_Mydf{w|ZO@f4+hH21?C{z2Xx1QXze+eNtK>x|%(fbm9*#9X9KW99Gui zdY~e4Pq>JveGsSWD~S~zf76avX|bDNsn*rqk~ywR+lf=sHg?EXrhPlW9Z;uf*)g|- zs4K_a0CD4^H7mSi|6acb$0eC%0Ndx&!a zMWWYQ`u+8aEAaQi)KyD2JY!h~c{BP7jk8@+QVgfe5eS6XfQRvpl7@0*j6gluD}mnX zWNrlFNl9@eT6=xWWPrqSJmFmHBWhHX5=s*Be)u}mO{s@+nSA`3o8)hEj#J@$ft=&V zFq6$z@l|h+?%3^<_k$u*jAU)e52?x5KxEF761TEOps}sP(*%DNy)GrBvC`lsss`7! zxWj2d)bw7%G$1~Z%%@&^7O$5w^8tKJXDw8e1?ogE`Ky`YVs6K4awdnuvgV6Ke~a!* zOY^HEKMNNcJ?`O%{mh)TG*a%ul}!O_N>uks_8v=h?s*%bG&)Mqt`4dxw006mdFfMi zgNt6&1(E^a3?=HDn3O2RuVkVOJ0}}*5hnKLD)Y**vpAQ6fW%r!lGBg^6j#blPZy0p zx8CNY+FPeN_?jYRel;v=ng?R}$d}oai^rJ-)gZOTIiLtprz{ey1Bpr(PSdp~bq;<& z?ONp#%+;jwX{fF%1(3y?%Ryuw6ct=`TI#utw`4lOqQ+%K<;tT3SE(($Sr(+c5x>Aq zhi4hVk1Ah`Nl8AV_VhAO?NZa<=6}uqilL7V$4}W6RlIF91Y=jH=yD zP>Pdab-&)k<#6eysP$D$y>HFMGfa0hY@Ee`SJ4 zNQU(Gk`-waZ+MdyZ1D*hpI1%jM5nrK$bFitZ{DeQ+7%BdPj8sT$O`ckp|;9{OX_%* zTfXLDyiB;isabiy7O61)l1JUEYXY~3G0^A*uDPPlijy@CA)(9S!)=}9o*bjvwc9&2s1b( zG!W*t6#l45lVD-#i7|jq+7|mm9wN5&hYYk)u@I|(eT$U=qVM!6iHXBBkL&8_h7c7) zW$(`GwKiouS7(4#=Y3=S{v0$l%5@()`8C$!O$pMHqO6RIK>#sF`T5_anWp4a`Qx3NSU9cY_f(?Y_9a+eYJx@pEbC z&iIvB*AM%VDGk|=h~mT6Kj@luRq9Dxa-Cz#mDP&7^HB+t@+$UVgjmb>>R|4lGmUPD zIG2yc8r%5xXAns;$}U(~C&s|?X#&1l7e&-pQFU#=a~%mIWbuNH&*7f9VB3XF=z|DFs;Vr> zsga24TzEQw8c>N{(wceq)a9r#Os8LfC9U*T+KtWccV2c#!gs~}0U7xAjm73Vn&(@5 zeCU+;me(`c$VPaC5AS@&8)c;hOg5E@x%8Exz139eUeF`Y*5o;YdvMXQ|HaU&uDJ^t zuiveMwo>NW_o>N8k)L?cKA5D`LS@jm`J5cc+#U<^?U=WVE6g(NuNCO3!)QiBtn)%PQq(r~N9cohGk0uwWjq1@aR`G&?jFu=o6wQaQib ztpWkfJDOV?WBqbjIqST8@#{k{zw1mr>E9SHac$(sswusL}lj~C-p?C`yZ06evVB*(rB;#mQbmMM_c?|W{*h880QY<5CUVN zV+LB;I4#zhGQ%>R<}fWr3lrJj3^wdJi{7)J!U3(tppsi%exy5gVaugpx-Rqu^`A&#^lzg`c1Q7BRMM`kbD?MzkXUlt@@;fsIIa^_JsBOcAq2rTI`RjZN@^B`2Zngmug z$cG-tYU7b{_46s7DJIac=}(k=R{Pcd01nO!T63v0!~}A2JH2SCPh+~PycH*2J+ood zcfNz!<^1D#1~fO*9ghRi=If6-5yy4dTlz|?mSHVo*Tp5Xg}bOx{-Nx@T3}_Pc3<8%c>2M$36U0#l`brEWI@%L9WnXTJ-4HQ(O1@o1_{; z&X5QtYrL;3S3M62s|Gz1El2(wHlm>JS&r%eI0Zti91l`aodXse<$w%;$PR#*D=R;z zjP(a1`&4-T_p8=V$~YNL%=i;B9qF2cuV}UVNi>?-h?|!UOSwm`(KVT0;d#lu$EjbH z#wSMpn%5KL#}}M?&prE(r+?9tRioM2_P0{Ex_=oI=MJ4@RbDOEUe;C+G=>THzU`VN zg*j!&xMxz*%E~u!;f_UxE)4)R|rCg@B#DuSy8ClQJF1y6a zU{wD5^=R<>xXah2_0*UACX>Iq2;zI!J5%v|d6|vD`=Ob&W**{%tEB5*qRulBkl-t* zoaWQbvU7(uI=Q;q)=>tmxWThEbwQ?y+9u~k)jeSG!*Vf=*ouJR>On^Af+`#7{P^9g zM6yjOyVjCIyiB!oS^%&y(}sQ{>dm<5>35C5Nsi)@Ej)b#uVuaQ4uIap>LZ!S9qK3#iT9Idpw?Dc@1js#h?BqpuWYRIsut0vL?A8>de?Hr>035 zDMAd|V?s6yoO>IUT80k$IEH^HbvNQ9UHKI23)w+H35J(?Hdjy1K#Lyfh>u8fN9~-RNbRFSTqTv%KI# z(=_>S2TGPVY{tu3tt~1|_6=)fV%#ez+%>75da#bJms4i5g`{a7xYd*DixuXi0nj!9@=DjuN!_o%sg z;H*u1t6H4EzIj{WQOV_f$r(Y0t3yX9M-kcEZ8p1@10r5k|J-Ap;sMVar~xBW-crNW z8p)e9@rxY?#=oV?y_tgsWq1EAu2y@4#!ZrXPN)>QenrV44O^)6{*Fly;bJQe*6P>y z;~DLt*o7R946MU=-XUxzeEOkGTuH%)zEj7Emv4tMsA4SEM;EGZW5=mB#-9-Z#@YH9|5`E{TB4`BY57p2@N_N|_22`}HK z;baF%dW%{$0@YqnHWZ=x%9c^LRWo={zYo5pz6po@H1Kv}AP}g){9k>OK2J^Dy~kwi zeLcq6!);M=mA^ne3(os64=SN4X8J&1kz5T2@Sl#M_P^CmO2B9@hcZcjv5i~l>d9D> z*kb6>(Pb(eV~2j0dk{Gj2$U|b*|xgmJ#h4mrdkO{2`qt>O}$gKjW+{%0zDa%2{4?< znv$el3ab!T>=Gvq7ZJLMiz6B#0pykns|n?4yotQ8d}>SC&e+=}tK4ZFNIY#Hx?noD zV>AzN`6vLnDQDi#MvATw(-V6q6g6&m+R5Do|B9#daPJlu_z)Iz6x?JrSI5h52SF5w z0Z*fhZ#6*Pen$Ef5W4^ODch}p($#YW6s>ddXN-6XFWe?g@DvS|fC1c`r9Ci&YX5N$ zyEk;i_#zPO;(oPCsLBf(`?w96$qEmp-cpLwdR?8Al>1ZZMA`Ys-b9OHcC3OJOsJM=v~_iwBn+B@%&*NVI+9B zZjwEJt)Wx@Zop_o%2(?I9?9g878$zQb%XWyHI=LIYNf?<71kxxpp`1m_a*qz&efWN zB8%s%AHS4u_PSQKPQvU6-sSST{Im%Xlo|-Cjx08+_S-Y)S zZBgO=#We8K5R8iO>i+qmRG*DoDB)!mD$gEA_r$r8evzrn{V^~gu=DvsA@#)vmR+o) zC1xfpPA2ol)6MM7eeH9(NdsloIsIPF7a2(6k-Q&a!xyaw^n?APAC4158uxHo$3-Da zsRW?g{J;S#$j|dwI#U2rdL{Ci;%MgEw6lGohk&;|ytq?{IeaA#xWBYo`zbE%=nO$u zDrNZvb>KHzGMp5fP{<)TBrx5#9jh*=IyyOVxVYLvf9*%Zk=)DcyUH3SEoIj!7G6@_ zkoyA=+m2uFdpI@wBYx>@>*;c5UA0tPE>sE4@l8JdImQc5*L{6PyfoKmh-^>{L0z~K z=UDywB)PBxl(XI|x?&!z0_Lulme#1`jW1riMrVGi#f8OOjCj-$)3`Q(Pacf1P*IcESi;iiJ)PwWYHM-n)UY=s z9_8ClxqoRlzKI>t9YgzYHg=y47@qhi6@)jW1wCCRO!P>ita!rQ>h1A$2`vDU5%)<8 zAe&r(?g_kMytkNtp5-yz`>Q-xrH5KSlVwcm^2MNp|G2|XmlS)MsjN0?hJ>kKuKGo# zd@X@ObJ;l5X0C@UP|UdW$w%WO8%M{I(nkHelwvIc?b~k;9t77iQ1&cK?sO^l@CE30 z=y4f1++@)rnSl2^NZ8*79qA4-3iNiFR2@q#SBf3m7z`C$bO$Z}v#=t;Qx)y`!irq3 z97Vv&()+TmhYK)g5UsJsF|zYBr@!-Rq4!eS)nWSjT2S(8(n;JSbSLA<^vq2nMY_x`EgyM2Eg9QPsu2{poty3Le;SX*ZGUY|BT9kiCtv#lGW;dIfg zdmU)E`}rQRBYdc@@B;J8;QEZ-n)+$cUjEFN&6nkRAoVz7nN^bGycP@Nx$@G(zxL4? zuM2uN?-zWlJ2$I~g%li{{m(9jq&3CIfsfBuo`!pDHfHDNUv&J^$<6A>DXmVQfS!eb z{`xL9z41V9p*gm14gWfGLcrXtZ;$k*er)AMt4v90r&*g;q<*w32Oxbdz19$Sk@tTz zEL_v9(IigH0O&rf8X)bOEZDKcUU$p7 z@k^kk$N7$_ZG+mA)7Hrpxd6aXN871uP0{8t1buYYjo#ivk-tZgtNDEVDCr$q=oOOl zb6m${hc=ZDEpUzluX{7SqOX!!5gw2QMfP0nIe!crK|wIGy61|@>x$i6tbD_fiNk zB{%N4OFEfPI*FE2D6bAod6L$ubrJ&hD=HG2R_eP^!Wm?2ayIZGbxDeK@75<5>o40v zzod>Q{{X&&2(}f*yMF-D^H)NBrx&TE_o*`Wmz#WNP?4S=UJv4<9U1oxG)%~CPC#;S1>m)Ba#n%s{cLHujFV65{5 znJAKFUm@)mtRDIPG8OfkDGp$h5_p}!>J2a{=W?NqsO}H%z8Pj!<~a2^<)WxzmIQ*E zD*bQZIYFUlk(EG}D);^a=p>|%e#M_4@W65czk-eH8t0o`n$x`sDnSi7WVb?08V!*< z0_}3WxW^jQC=!CsuP(ETtywsM43<8T{s+JZfo#d_DtG7k=@5%AdDqu74w_`Ur);AQ zg23x0&Ur^d@<(&07v{~oUXIE8zsvKarn9mn_48SSJ+^l-qR6mXKaA~iofD~T;QHB7 zwxZ?RS#)#k^q~8;FI|!E_S_cT)laYC^KX@}djHo85DB5wQz&Rw-MRs{KCT;N)@A81 z#@F+B@>p_KD^nU=^wnZ3O8xCiOY#eos;68bSYy|KJ%gmzUQgadWvlC$iZ$yw z-OEDh7-(sy2e>IsEpnaOLP9*^04l0&L$!S;ALLgioqz09J3un$6(LLm;({>mx}$+S zD4f^2iyX`9+Rb+7>6DCv;DGbELA3go#ugJ={UmB)=GAzuR=1%;E+nkxq$#8U&6O3@ zxv?HLUL9L9PHSAlr;=aj=+B~#dtnG9SMCIk(3v<*A&igjQ zmA=Nm{&7l;WrSPoFK-rYOS_nioA8yJ#k1(K5OYEE)p!$U!gn|Y28o8En|>YZ%4=^A zDJkbVdg=yMrL7p57zuouQD&6m!+v~U3M$eaQl4%ph364OZ7dPv zy|mSmb^A@v7lETvBs4cTjFN*9GJ$$C&o)h*S_IFLHPbqpB>rLEJ-;$0Vqkz?PMB-h z>dug-+JhE5m7_{KY3N~Kc^Z*Fau%M+E$Wu?*0qDvB$YURcyuvTBBKa^cFMRULPW<4n??l-dQR3HDo3;;S?>reaC1Vky1}w(=FN5?#HOYAb5& z72$WwKDuP*S_^1AAuZt{#83q*FB6@iOv!%DwMa&9I}HMDEgz?`f2j^ubB%h?FE23o z@@7s#ECsGR@_I^2#Ij5V6!dcwlm$`R?5WT__UemP+?;$I+BpAuVePr8#N$XR;3QQf zF7W%rg<_+*3pmI4h&8=Y?g#hRz=jwW$cJ0xb5=WY^vEfxfBT}D3G%<&r`P1%dD_&px8w{@T5Eim9sfuAw;#gs104j z=xkS^y+$wk36W?}Ua4kv7 z0&g$UJnP5eC(sjg=Q;|eE`IJ22A$jk$!?u#hTk9d5=;uFow-(m?q)L68JysM4(;A7GHb5uL0z*Q;*g zS~rGuSjKVZ7IO@J8gO$KnY$s`!&%J!tCG58_`ERsnf(muyu$P`!8<#XG0P;(A`51q z%886b!@8=z&s&G3WK#&~ZA05VFf18U+mo9iT5bg&Ym_5X-;?83tL~188g8ZLPy@s@>~PPJzNIkVP0^pd~WlKxsDr_Pq&2y#Se1FS&m23?&!E|5ms}Z%Z<^=r*39`kWJ$9OZ!+6}K-IHbWceysDNfg| z?VmfugkID&v!lS1qGu;+&Y@wRHhDwcoi6(se9#A z+4F~QPQFb2vxYGGFvu>Bf>= zBMxXh{4N$n1}FQh`xqYHZ?YBPHP>Z?CR#4WjxKaCVfZFphm;(TUzK$1>#=eSau?lU!1m)Q1XH46xgiKh_^7F^5;c6 z4i^&RLprZD;MYLZ+4srdO&bG|@bibx6ooYXbEg#^Z0swj1)sf8h?!Sd;OKbW zX#3Y4dX}focCd=ozJ|OGuSltp?}0@TVZBT7yF|&lcp;-rNwnHFR-MDCxN)X*eG~q* z5W0*t+)*4}uKS6j!lSuJ+tz}v-{96g9p0HtiwW@cO#e(4{xI8Skl^tgdOfJPKhh~_VphP&z_m(W z$KjUD2mRi%gCAWf>ilYX56ly1QRQy)aa5mI^kklGBU_H)gO%_R(X(}zzXtZB{B!8R!jmX&E4YBnWJEd}GZtJG2%xn`M7 zC#BL|$w<$Z#mL}Z{w2Fi&|5|3qCX~h@853W@w4`H9TU4iSy%6=%=GN_9O|zu&xYAE zcYR6K(KE#h8$J~Dysf5e6ID5?_+TRb)EVgi0-7z+X6e^=?SHs;{Q3hhe=%Jbloz{1 zFl1L#kyBE>)}+)zCjV$ymSqHn$#y@vblrwHDf|I6IXvA0Hf0-NP9@KqI>>XGUN z5|mADJLgE|5ODTHZ0BF)^LFj{UsJLOIfp_Y_72m7JKv~GgM(aRjj>@&Fh)`X7b+fD0U0t zOzY*<&fLM9ttcGdXtCg5AAxG4O#d`U{p#U4fw9T*ZP(D4#W5m7{Uy-HJLsv%yzKi$ z&0i9HEG$cE~L2&dq`MhpX*jAb=-SD#;-Lah1L|+ zjxOo_-i>gB`puV76TI?EJf7ryLL9cpbO#eG8SG=s{ zRj;p=T8I=!UZ^e|rB7a2QOTzfM)rgnQOP|uji8p+vz(*?3Kco`0a1q!cA+y$cF4EF;=vGDpDHKhM!osJ-f%4 zb@<)D{5(XO&!w!o9+&WsU*8qKhV0kjm$NjepWr$H&JF@kR}LzDTHtxQnO&Jc%j! z8V8(DRMoZU8b|xXWp86Tjb$*L#0;E}Dl?-7Q7W%v<9Fv3hB*;ghIX3|r&V}aNYblL zZh{~3Q2nLhBhQ9d7Vt3QwdWnMaq6v}F`qrXt4!okFn5#Kl9S{*T6RB%qCCZjcNKH3 zIk9tntWNAvNqLOafd8`(N=%sEUbil{F_@m>dHca>g5Jms{NcwKWflCQq<@uyc>LbZ zhc&J>u8b@Lnk~MDdB)DWpQqv60Va=oU$n;(06pxE9oGTvEFKtIucHRH?;*=-N2lBPD~m$A zPq%-+?5EvVB7mb4jwxK%cc(%LhLNqgXhO$3aTpS;6ueb`S}NhocGyBBGxZ0Mxp#wK zF3jZo$sYi?wHb7+{>b(U9ek(OyZR46X5nsg+}S)Jw051YHSg*13?Tyl-x2otCH((i z5kmeW!l(aV5rUq!x-9BDpFCX)xV92!l?9;gJ$+PM2!ZoLkzU2=$(^)^U+h$sUq4FF z5w1oW0c8e*G*qR|yNR5iwbS12!o*KR#8p|o&C(~sbKo8YZUNfk>RQdUXZh0L8+GF<`Uj|htMi*-K zyNQSIyWGOEOWDVE1VxXu`-u9LLk=a)LZ%16q^QE&TyQM`O~HPVh=ZqVh0(jfIpLsa+|SyRf>ATJTT&Ja(AVfLgubXbTLQIgBcTGCad&O-xL&a z-Kk$i&p`2|2cqfj3J2Rn)96MiqKe#`*QH0|zk zgJzMpv6b$)x4M)^2~7pOONX zJGg05H*i(Gc;k?TK6;Dt(If5ZBaF1M_mLZWO2UH5Qm5az9yY9rWBlDdemQhOvt385 z?h2Y4;b&|(%kE0Gt0G|6EyeoqAtIH&x_Mm3e?5+jGdT@nP3I&sGe^|j!|i~4^xiET z#{MgVg;BuuK>jQDqXZep7y-@!&)aO=7M`vt0?DHI)H#;$oL_0CUWkxojn~Sj%Dpmq z%k>w@Uy@>7d(*@(;uUYi!MqjK&VfNsy7ze3UE|KYu1e(Z+~=L8d&Fz8pK%#udJcLT zQ+cU*lJn^{9fxfUQg!I?=`Lw{L*dy$AmK6IVLBIj{d9IZQ6@mSiT|dceYWC8xdboQ zk(bzaqzG}wGf6w1LXGRLt|I!!oAas^x{1&J0A9QsEBrb(ekW4W-x`1kIfz6MF>Z}N zYd2T5AH%~NUNfy*ksyiLEd)8k`c0{*B{|7}XDt4mqw}uiS^3&H3XJefesTGoh8~rU z8cr96AvT21YHY=RHYl5Rm-7t&3%Gi`?^UXvr*83U2YcGqXUr~AN z=y>^^Lljrja#x-~@*?EeMXq1NH?bNoxVpQ_6Hbt!GzOtR7!_owl`a8u0 zAaG)9Ax}MvFN4WHI4Y@b*AwN3#Q>K&;P0V^ilRSYyeu-&{`H?8Pk7>PbW8Q@Gkm+b zLr7l9obut!zTUvxLHf`ay~ow33BON%>-?RdmUv$SeJl?YMg`YE4o^yARtBs0~YJ-b@ni^PMj zgJ4xN)rt={@U-&~oiY9cND?PL-Ya8yAAFl2gw*=T{G{f;ItM$C|Fd&I>XYr9IJ4`Q zhAGG{*s4?PMYvC%lX#mOv`uB~4esv}W(kJRSQ+IY*x3cRUw@mu23lv)6sp@ARzG!Nzm9hwfBEK zQZof{95pPNg_MJKRe!#Pxn6xV{f^tiuYthbSQGBjbYp}I- z9fb#L)=#-^a(0c9eeq7Ce(3Wt*vcGo?bhU^!rAM~WS5{djk&8-YQcR$;M!a>Blb<= zbFZbZAT=#h>#@hU`;9GrsXY#}wD*;I7F3C5pgwII@983+d0CRMq?w9dAqonMJvWhR zv4PzDnZQR0Ly&Z4aus$7w5MUaH)yRdK4*I^XYueca4+yxTg(00}t*O<27 zld)gK2V`5+&mAw*GY?EYpV*Y?hrhkv+z6MJ7*1(;-}NjwnzEay?HB83{ZbIi+qyA7 zwwEVg_0M?k*Jx^=`)q~SIGK71eI!%8ds%$0q3ohE=LcXSFGBgC=j&|!uqVi=Dd)E?sTxFwf|Hp`60tE&jxH%>Why9%J7!3$kD47ZEs&Y*wN&)T_(5(izb6)2a;j#Y z-(vT3XSz|UYH@LN%?2fBcD#a|6;gG+>N0U|DJrgT&PV>>%KNO_B%axlVf6^|1R=UI zC~FN1pvR;M)z0$gX388jr`=+F%WVG8BR{@gY6i8OiP|H(`I~JcuE)G*UO)I0awKRc0Y>Z80Mzoom05L6Z zJju#MHNvJJr$hy-`Z!V^EiuNH4Gv>qOI_}MOX0!z)f}D(zY*+LDd5htLV6b*itY zV4Y^iKuh^EsLq{}3^l0fqOY8simX(cj^-BCJo;6=gYQb9j8*-QzI)@+_kJioX8DPg zcYCWO)i&oY&4+I}Q#Z)5f0yjUGNfO99)*nR*JSA)QS=m(xh^w(ctGYKPeuj_sA}ez zP0@1D7_GZ>uB}!yc-tU{yLdO43dvY6!Sy~iTsV2JLP9VdG35`RuT^LB#vtzTT~Izs zfs@heJR4oV$o2aeziqOU+^y3z-H9m;Vf(OQrQKj-&j40M34n{krUKaY#Hr{4?p+{*%b|Y zfk3un#4iokjSM_;9jS{lheVIBOJ?+Z;Z$Xpz;;v-NpUS#a*Z~pn8H27VOBZ#Mrn+5 zg-u_szUig71IlX1Yl2mcv0)jp;B!nwLi)GMhw^`O`LMSi%yVk~H)IU~vM zq`wqONAZ8C()oV=tCTA$8v^W-GwdZDz$r^g0v4{(BCEFhl_5;X@lAd@5ZL6Iea7F? zNA!;o4b*<=qkeA&^2^Q2G00zb59_~BxY=TT0rZkERY`z##vaY9-2dHk=YJHv?*A|Q z{W=885NH+WkpwF8Sn!0DmRPcI*3>kXYMmt`Br&Z0D({59qREwMP0RKoPwNlBaK*eB z!e?I)z9f)PkRRyqO)CEn;N$2YzS0RHu`?@Lvij_`eiT zZjns>7&S=<`Ia(rs&lWrMpfsL*0a8K7A_c2EcT9sAlDJ#{)5><_(}7KU!x`CHH}TX zEGyD>lq)aR?~CVVH;F`wL=5FX#_*U=hXp_;A@WK%TjnQF(mJY%n0NU!kL;v$^|L!b*p^pxD~2 zmwt`N!)z%m266c!p6V9GvQ9M&TJm?Gr9=fbYk}QfWn;XmW~_fIx%n7_v%f(%au~QbpoIv4V2Rwk}>)MX#L4 zr>JoJK&|n?Fp{rjTf-}qLd4O28JLK$l3g26pp1$peMO7U64x46oD&xqtAxG*2B~o5 zFG))F?HUyEZ4kWue&ohumRg{^oc=!T z%yDc|sv`NG@#j}UqV;@6*uF2z-Bm1i!5LY^^$4rPEUAL23TK;xxihmaCG5xkjHUM@ z4Ypio_aBKh2Ia=+rbaP>7}Hm2db+onu|I&eteDV`SR6$++or@RuOImN=F4VFkeKPC zfkC&FHsCVRkB(`R5nYW%!z3$ENWQD+fp-x!NPl=~l804x z{99#Rwldo$HLg}$Tdu-+Gwr&ZdPNX1^GHrZcGWdKzhfpEKWIr zy03^+=UlQv)~7xeMaQ@uV9Ul0Y#Y-Iw@=9f4EA`N`GQrT;{6d%n`Ssa+P6=m$*`QV z?_X-0tvBm#J^?=$^w2lBhVS%Sj(jQta;8?H|GZ04AiI#`-hrny1oyb*q+mHrvu?sr|+&|?-$>FeX; zdkHUQqZKoW;a(zbZ|H4b148vvC-UJ!cXg-BnE9-Y8c5^n zcTIM5$)U8KctaiHCX48%B0Ef2cv^JYku2;wrr&=_+JWBX<>M$hT339v&5nql>|_P( zO}X`QWceC5Zf=om`xL-K9cOp$1Udbj>&U#eH=bn*0ZDEz|hxp*2ywCG4V@4jnBZ zX_5bYlMA~f&F=E@GAnJtjIOepL+QP!U$MG(UXLQZZnx;yFe=R94(nYZ9xLzta^Uv| zO1FM`6`>kG?KNg%P(Oq%s=|gCme>q#v0<_gBipsOq9p!a01*rTBm-zv1){`PpKsgR zz5c7wHI4l8i#8lDt&WFPeS>ZTgloZXG|}80`mEr?2RGlO-2u9;Lc7cd)c* za7zLMUX{DKQF+KlIt11M>*yYSaW}1SHqi4JwB_}?ogi^akQRI1=@#d)#JU!&z1nvu zdRI0h>nQHf7|CbU=+k`&zT~i!{ha5YJmj7)lkL8&uw%&g6m=^2LT=?g2jPWv`S$D( z$^&7VVshC1aHT*9Gf{NtaQ*@FctzQ))K3arajAsq|4aNiC*pg}~h zK7M%Cx9Z|(<>n$c8NUS5Ak(C?gAJ*%@ABE%MktGtHQtTaAd@`Y+ZeoCru}Bout$3Y zEl9@Tx~{CpJ}X5O?@fQtCJ%(G#&i7+Xr3c?YYej0V^}E3i?6a-YU1eF2K)iM{Bk?g zp89v`*`b@6lc)dpLFUYuERkkE6FP{g;Z&Xv3y@X#!c|Yhd8ks4O7J$umWMHY{+Lhp z*BzBXy&>iI_HS`>3Zd~u+kNN1ckZ27tqtx3QSfyaAwYwnSzZ%E&nM}xwUgt1UKl?u zCt!Jyu&zE`i9e8zKJ?Nrz>W1eGTlC0|yx>jyrt=Kj zz-|G3tON`!lHrlf%3`5$R&|cZy_XU&%yi5MB46-gos*?b>u{)mWr*!t{s`ud{5k}y z(^e;aXV$Z~5(&T65GF^?Mftb~$S~=jfh)nLzZF^cWs~T&`;1!l*p*L?$*W-SX9gC1 zce~Kf)PoxbG*IrJg{L>Ns=23BsJKr0J8tyd5M0A$4xx-@mDP=BhiSUctj?316ls%o z?ki;k{9Fv>CyX_P+zPuD_?4X~VQ2@`SVx3T^Uj|ST7mPNIa4p@xAdk8D@p29!8MRn{H^xMq3Z)#*lfrcTq|sWTr%*b-zfNost@B&8%T4 z+aIAM>k%$ovdL#vP=BL5f|1eLJ5c$F+Po@5(v@ps4^Bf#nYpQ|R?)km;PO`D&U0_t z*00)uJz8@FFlij_Z%FAYu0Yn*BR);k4c?95=lK^odCdd_>dn94qzX5Q)m6{wgr;ds z{kVD7b?3eAMg9X(ytd_+)8UfV*Mf7gYB7HQmO__vfxicX{w+qkzJN|>hK5h( zzdjl-iuiD-sCH_}to{;{qTSZ*Tlbmo>0jF$JO_UL43TFk2eMfTo( zT|*-bA>G~0%+L*$?3{yoQXs8pr&5 z*Of#rARiTf*$;}-&D;^xexnouOPa==mR+6iXh{t1bUSGwq(}>ey+`?a$aAI2tJB{o z1>+{gwruZ_uXrx+7pg&TpO)NSdl!tS=CFqb`Lcu%I$i8r_7s`!oCt>mI>}SX$>(<+2G-lHIFylx4VeijB~d2Ex>fGhE$F^c7n>(d}*th);k#s5y@+-%)m@#KK$t) z;HeJE)JDKB-Jj41(igYd80YzCr7o24qqT|#*?oc#vY36_rn?JUW%t7_u#Mxa!RP#|Cd{&hNV_S;ty{T2=)1OK7-(}zJ_;!^@;V*f~EHaNbS5S&L%R{V+Oe9)Iv| zpsW|wnn&t9Hzd0$8r?g7{Qvl2JeFk(T#*Iq2>OvXZQwk^D zNfJpyZewBcwvykUs&!ZGfE`)gCKL(=4m#8$Jo{`Upbyafs=f-ZPl+M4{n*x^nC&<( z@aml&UnOjP(yc)w5gG(O918V0u(CMa8%%u739pj6-1$>G)O* zAum@X%r*Q;28<>g{2kpoH~3O!BQ;1$PmFx+SByyR z2X{@?LEP9;u5zKnz=Q{h_Cq#BL@(dyn?J(+_8@DK$%Up}QofE4c1*xbaZXteVQw2(DsFhWwIe63fR@T` zV-TI=A!4TIYhUe0PRqJkXpY{zF>TWuX}o~D&j`2{$6~MIQU{?cc^TTGhC70^Pp_cg zJ1AsU4-YW8H}f1=I=V1|nhcm9nUExzF9TfBvXdh%N6w_a%r%ci8WJ(47rz9g4zS!v z{big~Ds3*N2KN*PoKv=R{67~Dr>=a$vp$kqwxDztZ?oIc@sII8uV-5m$zif`+u$*d z@f5p!R~C%bUnIRFa84VMJJn}oOLkS3t!r9L_e$%X$JHd|RZ(}Z^Bjxf=(`Q1lb5m& zHY!bB1_}yI1`6RuX6?rjb<8b>Alofl6%2W&hIbo&Hi8580WtKqc}4pPu}JcB<*^fQ z8R;|dHG^`aDPWH%(0%Lf#gHt1nf_xNB)ot7>_kX?MDb?%?)bkov}f!g-2YLHK!lVv z|Hym_y$(gv7ek%zYDFJ=smHl8_`e|m%}JP?fe1q)u%$HrKQ*(=ICVg65_7lvuk58! zB;dn;m6-w+^$LnFKPWVc)Y}63lnj}(pfh@_{|-Pmb|M+ngQ~rvbpyM+Kd5S+Aj_Zp z3mXMn%64?2HoV+74REh6HlMhBK_grlebYfr^KTJSfw--erl8;+sDzwcR_JE?rkk0- zH0Dz0H%fp=fZLlw<^`~YEZ1A^uc{3Tv=8Ksu`!$$h(vMM>tT_6idv!LDXmrJ>>fcW2M?PDbnfC}KyBijRq z)%bviCziNX8Pk`}}5o!adG5GK~F_~N()Pzf!~Ff{NTFXuxh z*H)LFwfs|*!{KwcT?L-4CHeEFMr2jQ8m$VG0b8EQ(OaGV5w(4^8n0f={uxHs`eXM{d;%mmaJ0r$jmdtvUgPjql&1 zy?^`v*Pqt`80}42Q1VQ3@0)E^Kqj-UzmN}Aw053(m3!#eo4a^D$xw5mXdyf%OJQ4k zdB0%Ndz+*M*$SYKMH4VDbCG?^-+(X-8c=wsB5ZE>#J-!wVos9E5b$Zc-~ZUa-p}Kq zlHa&CVEK%92)V|pEw;ee3c4)xhSUXgZ}AH_c~_HO1QMCNSlQqYbDj-#HrjH7H;gThep*&%7lWEl z76S|fyRg3tmfS*05A*KyZ{y?5DtF>8+$8xhgM^(uhrBCe=Vjd{O&t$W*Y#FT1USE> zeO5OzR_+XP&Cn%*ov&KK?6`Ts+2V$5uc#Q-6QuXLSPW1s>RK|k+q5JGWYKl_J~K)l z&`qyr+@vKzv{eyj#A)ZxQnL7hVJ)`3JN$*ur>vL&_FyLFv*#4bzUTiuFMRVKoUg$4#nKVCj^` z&%<0+#mVNUnFaj6QtHxD@m5JWi&oH2R zW-oF3ck$b&zF~OoR>m8MH{py>&>la!ND|Rptj89zTYgW!lsuwMzg!Em@^dj4h)x_Z zjA*r{o}v92(X6xDX{A%JUF3+1Ah;x2B(f^7Bg#&BLfzo!?2YWAHw0 z1CuPVBFUm-1MuuEikQc^;*L3Q;Ns5$v!P!fRBbiX0+ z7Q@&TIAbs{7@R!KQ}vz%cHjX!=pYQues{rSlQh`tdw;lX6mPw_arRmtgqXKT`k%~S z#l9j$QRf4`tGcRQkr=yx@>IxCjqg~49DyVgvBH1Z5npZY#P}Pf2YO>ta7o;$%W2Q` z%^6oqQtUu!LgKlO4XQ|}bFY=8+SQ2b<5*lG-P(W(gBkWA>D8!-aIen!^7?`KdN@%l zsg^x*fUtDSIK&(yVERW-`|LD*xG!Vn=!MAG6eG4Cz;s;i&afa_jTv)fMT{ElXwU55GR;7BR7d5uK5_ zzqPSn?!jW58GaG|phjZ<9=Z4DUCn2EwVXk8;Ur;GTD>X#a&P8mUV ziK+922?XfuU^Mka?Sp$7?c1MRZ1o+{a0eB0w@|kg8nE8JZ*5~JbR6Yd5m z(&IcIv@=;{b+dE!%5C~ezV6|dXyu=W)0B+5Q5;p^bn1M)>|M1mQcbJMp%K;xHALDJ zD6MF?F8it^SIh*qz5|QT9rk~tm|{@5xW8TU{NSQeca`u2zbV<2u-p{X?Q5|MN$|^w(dIyH zwhfLFE|1O#P5Z&Byd!d=KqS4GVCV11~4D~UhQA;h?6PgW{O)KqFcSvI;K=;H2W9C*N>MJBRh@7zL6 zyf^1I@G>4-EuT_6YE#5f`GV9`Txgd^i$JART&22-gloTJl}7UnAfm+TTe2ZD=y#@y zblEDQCeIOZm5UkYni$L<(d8l=keN!T^+PcA5abxCt$?R%4 z12BL@iP}wMIsGZzK3oG1-OfmDPNue`#HUU!spntawS=u_)XkYNNL}=;>#yzUgo>c)|V!vaz=05+t=1$aBtdf zyompN>~@FJtQT$_-=RW%itG@iura{sDbb7kgWFWwfC}-hdlUD9(b#_g46D0C6d?d2 z#Iu7A%Tl}zP`LC}evPyFEAMDS)kg`~0iYRn^dOOUxmRVG@$Rli^gtMczu3o+sLUOf zH2?MQRFv!`!eM`R9BbX-Kzj_vy7v40@qFf`d6jyF`Sk!-Y$f=~y(re_g!`^QTalhN zBHqpJJ$4e8`38P1CxQNwHf`CjI^c$riIR4oDM& zr?OW18F)10d(q{!WZ0jAj3^7u7T+k&=cj0b*1z~hcPb>;I)5>1TZGkYI?{pdVZ8Vh z-@lD|;*FIMh(oW+k&i8*4Q1m zGo&DqBXR^lL72(vwSQ<)YLwytG?s{HUmd0wd6#!pRv7R7pPW1!^ZBF*j1m0zucc(Kb4VhKJz;#FHR2T@ zb0+F!^y~oY;83;a{LQdUyf3h-!VmQgx(|lwTt__PG}hTj@8ODU;w;lo*XL?$Uj0RQ zic%ZfOP_`3*2}Ao+q^3?X7a9RUEGUK$;$MZ3|iFlY_AB}L>ePSOrRN(sqW3aSW$IY zQRP-o{=380lgIyGfArv*DO)V9#t%}{*^vZ1CVFFZ;l{dGQZFu%DiV^t^{RNaO?H`$ z8I+vj%{(Trz1u2pK0==}J<0ebcKZ;}WMu2wAG^vbzNc}an9!}_nIAd=dyQ8=4d{zl zFvp(XxFHc~774K3b!`!kL`E(vzjSwU(IvX3v|)Ix_v(i5?x2tbN6W_W&A~N51DqT3 z?2CTAzg4_YTOe|z=6P^UziaLfT-M!Sbyg-kW_!^A!smiU0oc|AI7G*02e(AG1RX!{ zO+z)B0i``em6hyU98c+n4J-==ys1HiK-|1}e+IvFglMAP>@>4ff<6CSl#ngYR{336 zCiDwkXUC6vb>EIPZqIL@@r3-nSW#{r-zyIl;zqekPHzwIN2?P@lowTZTV+hLNiKo$ zQDbZ^w5d1dmAfE-qD*)fMmJ#Pi+88t)#|xwFOx*+&rg<=pW83e5fBkIl_${tOQyTw zOaJ7B-QctR+>Qy^@$#1uRrh;8h+*RDmK(Oj)>&P4UP-qEztlrIB2P>1#>9qbXp^hi z2KwAbQc^ux?JaWK@gDvR#8I2)I<=nhh`DK4#=TDIUQ*FN>JT7arc&8!>ycOGgMA^j2}{!`IMT zTEvG5W9hA%5%5r4jIcA9ydzRLtawPbLss~fI+PjSg@c;`f2>g+Tq&d^h$uOqF{wVJ45FyJO}+bI@56GUqcYkKQ?~QlJuU=){3o{@hl2L8-sB=U(($Td=H8 zP^C+Gp?j*Ybh=rm|{wo=tAP@R2R0)=P_(Xv=CrDd^} z_hYWV-a(!$(p}+%Ui~HC4?M#p8$LR^fKcJ{sQ^hKuFU}SWOctR<9E1<{0cVq>?C+y`Op~3_m5g>pYn> zpEi2`Q$s9-%BS4yraMHrXBN^<5e z!1)-nn`&Q$JK4YSl_}?^C`2=AOU;~K@V+iSjjq)<;ldC3TtrR2C(pO) z+qNvPxz*V)FDF6k(N6f_ERv7qNQA5;y1??WA$gzn4U%#QDrphXgxzsn9JkP_-MVf! z;a)FR|E%v5E}G0okzTKpIBkyTZ34<4!%}v5;t9e{`1n6zhVlZRXzNqHU)K{XKnpk_rXrwpkTQ;zU0!DR|o# z#nZO>RGmL3cl1_;SF4fU5QxiKfm2M+6b5xDgqw3H%iWI(S5y3?QiT$0(cBXgETA&z zGhX61&*c-ODEr9@H}@L)xgb`jGZjE+bN6}Ql$6t}_`an+HAVLI(1 z)-w$atBO_k*vxLt)U|Kp9F5S#53u&S^A|+*sjShT|;Hsv1 zMxJoNF9{UiTG#WtBkxy>qv7&BVSN!G*#z@dBJ|TSq01Y*YSYk^{}k)tE+H|3*-icP zafLJ*UI6l|vl1`L)@5zMdd|@)WoR#7&f)v*%bj3H0ZnOuCGs}(W4HbbQx{n)BBHen zDn2?CJ2m%BcNsZ38g3`0i9U%7MtUqAq~xcl2Yo?LH;fDm&yE?M9)S|f!MDVQASd?e zhh!Ii&n!w#jABf(=?0r@f1@^}vlfXTo3W6&SS?9XW*|7+|Wj`q)3Z|OUj^0mR@ zzhj4{0hA2@F|T6B3A}|9k$B5uxc^qnSkeprgL16`NBQrd#*ZCPh&3}6E4>Wo_&7ni zvi1W8Bj3(apgIaNp!NS%XJiQDRg|k#sq>|&f}4UT5h6o`{g!!>^*{2WBP`yUJtcEk zvOh79j_(-SHA>OuDA+DA&aZEt7$&ctcIY=W7fZ!B1TV>)uJU4ZJZdT0WyreEAprxr zSjI5)==^GU$ZgY(Tuc4*WMf2-Kx)Q%{Gvj*nblf`8OZ`fUAI~5H|arjS&9b8RcQ( z`hZ^);Ls%eXAT$dM?}v57GoVwg#L5%{;+21^AX=o06q*P{$n!~G`Co_>@TD)W>!4d zmrH$3f6Z9sIHo+rBDp#kr87DffZF#8Ob`y42L2u~~*R7S6l0g!=)fN{8!nX`vrD!Mvz`B|py> z9HVJ$V?opvp2(Yyf?^co&;D8fQCKlm1wA1jSSDo(H?q6bdHbuqhinMO^NF@Kkq6Bb z;znOSb|TvQ52+pGlb%!NJ0h;S{n?K}AB7T0br) z87xhoKINxS&94HyG0r23g5oEB+}7_DtM-W=z7BgY$@=%z7F~@;rzq&1k+ra1hsvCX z7{>W4@1kc+U>vBdRQFTP=vzj$pV}`ghu*bz$WN1Du(&!&-v&f!n_*m!yg6!d8|R^` zirTm@iI#u&eP-ou(iU5mehzeJ*|~f(OnnYLE7kv}8jt_5vwCNTa+q4gqQx!wItYS* zE-K1Y5-(QIdR&j&Pgq^}YJwP(Zl2#OxEIBbAf*oScW+i`BfzvAqdAhM9EaOpsZ*4E zzj^v5ti|nEZB)5oRhj&7T29Og+{{}*gN^tmfR)OP1lkMO$XvjZdSP;CgEgc5E)`0n zy1LBDpe5E|=vfV6(u`)8XO@jfyzivo0A^;VNp1{Z4%inACJd5VhT@?4#ttTiX5n?1^a1JP{oMu8ffdI0q@cg+|^>-6OrA(CcKgk0+VlYLx(BE$Jp|^g#OukK!SSExS z)einp@D>kjQINDw71y>z7%}6TMe!QBJQ<|+E1Ae!eBGT>;Fn(H{IQYr{h&($BHSk- z(1#l;JY{9?BhS|co>1U?=2SAO_OS^b%e@0bc=C3y*gKE^|xQ$VO*&G))>f3>0wXX&w! z$Cy3+@y_8=_YLWZ_4qVd19#t9$EkeK}=-&G&>Q~dmbQg9W&h@f2QQVI=P3^(=hrP|_n&j6hnT4X;MfxID ztF86(v$I}?d8)uLkKjiR$n*`Mqb)|Diw>qiL44CSOJc_quk)0Rccv*g&YMw$Ao53s`Q+>)mNUKyKH z!l2nFn5`Y1NKe{V?}ExON9Q~@x=fYOMsNIifyV7r_)eX1LxZ&bGY3`q_=p9KsZ^bb zi|Ft?>}pR{^Ba;)K)?HNr&xV!Ql!OnNeO?Z=yP^%QhDbIzBH-rfIM>G>w9+n3Mj2pmI8pN|(-ik~q0!2H`hq>h3KDA#oo%zcf=?c{ zQj@V|*D;4AVxl{IbVP#8bXvt%)5+vCBWFrP3tLG#LrZ&4>WmzzJTtMYaq#0VP^>PgEOA;>k#0t@T=!5zOX>*a{6(U^(u~K;I`0GQ-zeK9 zRi{vFYups@GAp@;`OJ`41@&MDrPlcVs$b0u7LO-T$Z3$*&zHIgYe!4zSfh`ucl}B! zI!Jg?Ty9)<>^#)maWYTNs7Z}yw6W4M4pKx)4J;)1>HEo$=Vmc`xa%F)8ztszy?nLF zxi#1IX&Lqj9QoT}P5Fb-D+?Jzr6%k~-CO)*C9=7*EqFF`QB}s}_i)p5U1!cjoPC_p zO(SJL!UbvsTCt%;$;VFXKUi#Sb}EARm+aeil39Pqzu?P9LEx~O?M$}EUw&>3j z5>YO~53b_+764`d91VenCrns6zP>_48e`16*@|u$s(@)w+eIv^GZ7e+>ND&^dctDP z9H$y1aap8c;*M#rvvFTSP;KDB66uglwj+6-MKzhNvbvl&lQoi*#><7uG>gyL2_A#0oJ!vzYC;BQF zNC>U-S`N395=P?B=Y=vFW0&c$SjMUK({R9K8Zt*?-?(6V4sRxVN3lg>zoFKwdNuB# z{A~Qhc3IF6zpu7u#o{zy)M@_NsQUO55vGH11^V4XHzSQX!f|bZ8F~#q77&r1u|>Te zd2vaZxTaS@X7osCxw<*R(Bi#3^DFu70N{n!H}wJ>G?v8|_I-f0Nr2}ioK5FFEE1#i z^QN2?V{j7q{O6@iNA|1qigdmQ3}L zXO7PznNm0sqBqyF&CN2K+INcWNy+UWnB-#ITivWY-LEOC6%JIZo}vxHphTvJau2J` zG)NVfB44TrRwe9IdRCn2NOr1MrY^eOdJb6O9{XZ?K-cy*I*e(_oX&5ImM z2k_K7Gzkc;4rO0D$T@Yd_31dr`bWmDj|Jd}Gj8M>#dH}&UFRX@tNg=F?-?hNPvfV~ z`3)mpIHXX6>n{BUhBo{oI#LhS#Hivvb*whP}^idb7p5O&K9Zvgz^xEFC_K^m;PNa$^O~bg6Gbjk?Id zhuC27>kP(kq(1ik_ju9vAMz6K?=e{e7+yWpV2%^EB4AL$w`EZ+QrGE5%Yy; z!^W;~R*L$2V?Pajv~sK2W}dR@DPfHCI>FT)tuw|>a#bNA8ct=Hv<&L14}Z4(Pq5d@ z+2bL+gdq$HA^UoWHaWnW5dO=G0A$F=fMUDw{}aXWUv^7<<3$`WC6UI}{}3ls`+>T| z>c+?RpWB9a{D+fLs6$-ZF-3&~_^X7>w}+(Zdq6i?*;M-h!O(*GbF!FR`l6TL>%?~- zDM$x3Or3|-#Mal*=C`$``ulfpskB4Ru!Ncukk&wRw}Q`wzLnC%FHNfwACrurU{ImP zw)T)qvZ<#?(X%*f7^J`Ilue6G*WEG$TcBo zI}x%&WLnK<|r&gD9Jx{MN2{mlHHg8{;BT2oRi{jP3u4z zrs#jA!v4R>$q|qf*dKn1{2%@e8}j8sh2qF;$6^)=KX<5(WnfijvKl2QH{=(+@i_bGJSsu3IDmv1IL+Y0wyjLMNobim6UFb|wp10;H^;6e| zKg-KAn{h>Nef+=<_u&Ah5T@>Hce$(|BQq&*IWy?UxJE&Srcm>??2fb)w)+gbD3Q=? zpoES8kfJJ6L&COe)(F9|8u{t$_~Vk2g5$18bwoe~;I?L>J78<|mZ zXUP!=K&T$vbLbQSwFT!3xu{j$QDAfg;G(?@w~^y2{P~k!KSJ|FROU9S6&9;Y=b5yf z`ReGHPXiyeoiX0OGpb_9%N}pepVX2Bf_nl^rm{eEr!(@O?||rt`BX=u-Cis$7Sh%D z-un!dx=}iIO|1|}NjL&0nHr}yC z-J;49{0%+yd|UaH~gbQaT;ctwi!x8 zGbgk&%i7FWXrjclz8ZcrJTP}%$|9E+huc~7)xXTF^xYZugQCNo;pOfHR~V5b`YXjcO}Py z=Ag9LdQvyVg&s2b@I|${j`+wtIj7Jl-2UWx)|Vd3=Y zm4avWh8=dx*QqBAi=K@ZIO;Q8n=)Hh{oLu<<)ZSJz0{PIa)M{u&EXUE^HE?gFJh#@~#k$SA9V zihu3bq?hjH8Oy3NS@+D74)EZ9Yed=d^DThBA3xO_6cEe$QIcm>GBP^MRm)&TTwzv3 zV*(?Z!x9U_s$lDqjH&#n=LpGwE6dGri7y1MTaT5E^Yfd#iDG_FAo>{);mqQ0^L7rQ z5T(g*MH*UM*)N&D-aIzw+|o}V?zocm_^kVU&9L=J5H=4E70#TMh*IqiIgK^Rrqqsz z9Kus<+k56_04arBd2(IaVKrx(IarSoX?EjWvQynpi(5PvUamt2K{SbK8!`E5d`)`E z0LksFpHVd@N;hqV5FyYV|>Sy2N$ppoG_o;j& z8y!T~v_dy$)J-S&J+%u?$QzC$Gn^oU=ZLpZ)FG-hj|< zKbKsr@|<_Y=OO{z(i2YPs9ZXIlQw~*BT50b1F4S0UN`o)L23cFH!6EjsoQs3+9s*T zi}J@TXIF*|h+1U)p+_2wXc62@{BdUWtqzjECQ*4iLV+c%5%$jV@WbouVxy?DZ>Mlq z6!K|4QL#XO)j4-_xDpPfTW&=+>6aL-LXh^yO1m9L8-dX+wIl#buNL8(Bv|~@RzAZpV;cW-_7EE2n&MAQJ! zA_z%6I@JJTznfS(rjLFDHutU zidTEa68ql3WV60*fWM?@`Z9%nu_z?i*xuNJS&@fDJ1H2h9#8|UFMHk#*ZYxL0u`N@ z;2ULhZlix$yaZiG75*oV-b1jneg$>)8*F`#alQqPHu&H~{_$6*hO0OSuH(brZJ975 zaJC5whHDWRtF5(<- z+4u&{Ec$$VXnZjASlRrZ9Wg7;&EkmT*@~he5ud<$`R;j9h63_)-t^gYlv*npa^t;3 zlM2!}veC_I$~`Zh@`caWPj!hz?HT#m4x=j}c60mpo#T$9I?z1FSUae&BkEaN4+QIC zq-i#Hw1goLDlaQ0@4!cg^8&nJ$%ecrX>7TIl#C{!HCw0^E+$NpCp?B@fY2PyD?U^6 z$Su@`ieO}TBs2um0b)_^>l;bvxAL}U$Io|X2ALIxO!1r7!FyCI%xpfyVeg$tSo;TW6NkEd? z8~l#iKFhw_o#a+)g$<5Pxt2)Jc;c5rnrp=A$T@bbVr40?LznzhSUFu--kA(wg0-z< zH*RScw{?dy{YDAIWInr>DoJ#9)}}|C&u}$L@O~_=qQPDPpEi;F*q@BkM}p6q4mG-W zSH?V)u)-pz#6pJxU4YDeZYeMZr9)zg{UI9I){n4H&7w&~*@}btl=IAyppy`^kiJeg zK7QUBN+k&0C>c9-+omy#j)qaV+PXOJk*nN($`eVoc|(EG_Bp0RgxX!q!&fiP?D$e+ zVO%w(dC$x4)KDyUsLOHOyu@=%#j_;IN3s4dFo&i*F+aw5V4GXA#KNb$XQ zOiz%A=7IJd;rc&>YONoZjEVGf)ueH!k{cUimfyyQho*yTCFk>lN{-^_iY=PKPi{4s zNg6=QNskiX!bE(O1Rx|a;C-a1J~B;A1j4|DW$0fgrU|CYYxB$BV{UkIopxx7B+K2j zNzmam$o9#uTH7DhpawK{((TH2|qgv2HLI@m{@ z67I9%wjZ`uA2>mw!h^1ri?!>I*}y6hx6(!QX>VsPgY!bFa6L5x)t$izT%x5R9m)ai zC_(%1HzK*!<0JCZAeJ|Q2Ezwzzih6=Dk{Xp^yN5XI$S)IrGG}6Y}8NhJj7jN#83K# z1z%P9sAvvaE=YrTI3^M;Y*wEK_mIgNrd47PTeQtM<9g-Fjo0R>)XXc$aFO|?)3J3$ zS3bb5OUoSPt#36ILg}G$Ey&lTOucll8q^1X))gJM(0Aih;8I@=}@;q$M<3`-cOos@6Ekc&osYO&?~t$Z4H&%ak3B=|Q9;3NJMDrTC_mvV05Zv^Vo>F%~yNIGpOqAO-8tC_~Z zvhGiJ9+y!u?=ZgqD!~xMJ72$9fJ)A{lXYCW9LHlSr^(~|JZlV=`V=)y{*=>(<1m=g zI%ezyAEvb>dWh%&gk^Onq(RrG)F%K3DFl6`v$V9oMpUT(kQ+{}%K8mwexZ|MpLP({ zUCf715RL))@M8f|E|#BFTd^@4FJ0^?>DET|abBdSDt*j@RXVWB1URgzQ93qUxqfkz?cKWng`9|@@(j7}8SK8xvGeimMUiSx zyx^qGD1K0aO+!<_0E;!*r~Qhv7sK|ckpz9({;QF$S}&@zvF)F3G}gBsci7aVVw#Zg z<7Se799ogyUIrIKQKEDEQ7K-t5x(E3f=0RU?)qhx4p{1rWSI~)yuJzU-tt_XbGs?h zTVm3L-P&QQ2v|zFHJ%0YsEZ?`YpP9}g z1g7JuzsI09(Hm?=zgik6r!sMm#^)2?)Mfzm8PF7+s7Hktl2SCQ@uFc^TvPsnZTs=k z7mS~)t+=j~=KX$W&&8`A9er#5kuY5FBD3I2xS!PQi)1*ineEQd16~Xmtt`2rjDn+O zP3A8yG{9ar!4FSffwCIC4cw7nFv@^Fnc}h&Aed8;O^l5u^wZrRsFbxRXcN43wx`z7 zKJ?iUE?@F{PZqG504l=G&CGIyYz(X*^*J_UqTydzL;Xf5!wu$_P~rPs*3nW@?Z^cb zwc-R2l(S!dlrJ!>!R?KzoT|6%=HRW2asJGscNoS=ip+87Q0#?4)#|3rn;*k9AKY9| zp-!vB%!kxBVZTcGO#tU?3rckCD?G`TX$mjKDX7e+gih*)day+hjB=t1{=8tT(Io?8YTXrQWsi)48sY4UT4f5(k zDAb}C*1whDhIMnvda~<++mG9+>#{Iz zMcK`##~Zy^PGAfl)h3Ru(_(o0*PcDq?wx{^RiB4lZ?EjU#sg=aj83L}D%!|tkd(2@tt)#zrku*jHPt5#qK3~9rl~>_##Njus@2wAb+~c|v>u3Ye98(; zj)ZwL8zya2z*}okP#z5M11?&tPqp5Xi&}G@WcfXmr5bAB5!(1DWixkZ+uHZGZ3*m| znx?C3;CLDWcwax^VE?JHXHA=1N99|!luGFwgcTuV0?DcFK#O1t_29}$K-f^6t`c1~ zk2G2m)}(-fp@OdbR#RygDLSg7!ZDf0C$ng_spF0<2WHm`M{gz zqwTw7_x;OLy_}f%NqP|Rvv4HkLKY zvVFp|u729;;hJUB(4=nmHfC0k4Vg#hYqt8Q zw%If@I+J`Ll_s=4-@*s)jN)qs5B^GRHK%*ZA3ktPJvJxso*ANe6IFZmdJ!lG!w`Qu z3l+p5Kz9=Hgxj@$Hr7f1m3BX5+4!R)w?@eSv!U4hkKCE+e>s#$+L`kY1=-u~-;IcW z84TDo&_8nW^_F_uIi=eG>9ZG-|B@g4;Ey4cf$l91e8_s#>VsGdI;#pe861bWMC z>f9LP5ftj{*x#A+<=%%G)6zmnV9FFqp{GDil?W(0_iGX?*`^y7`Ce^t?RX(=%PZG3 z2fjET>g9BeNE1n|HZLt#8WVn0{Dt+`06AF{+}^{LvKFo`{hCGH&^k9KujqS3!lA|M z4sx2ZpVJ`}gT1!yP2Wc&$B7A=6!h)z#~+r&DvplA(5O^?x_29*)Cksrv3%%+cw3iV z2WJ4>U|c{p?*@pu9sVlo|Mra{AiV{M(d0byU+;*~+s%8-c>h%7AODqpw>Uk2l@N83 z1+c8MZ~hhQQ;#aOO zn1b2l(VxLA!oqqMaZPpZ)(P6u(5o}ep zxS<(W;|<{8X_gBz>vFR?P@WGLV-{doP3M78HESGFV2T_Jx@jjZcDWoFxNi-5xHper zMKuWc6!S-FYwY1UI95kEDvQ2Mr_#G#B74jW;v<>|=P%?ItIiiY&B+ehL;AlZ?#$K7 z{yJl3l-PC1tOnZI5kx6<$q#MkV542wueL3_ic2()U1nVAOKH&t3azKdy!DoS($hg? zJ4SZ0+GeQ@WrZ}TH$XLY^;KDrE19-b;hUsj?%G6mW>n(t7j7bzg_ST>9p!m4^W&W( zx9Ez((XP{)HN~6qt{+m%6n6dYaPts|BLEkrH|HX-Ly!g*WKyd*7xH|qv%cxB+i48$ zYAxgOwqrWQITcEu_(}shzZ$u)<@VkwF4j7&($jZkk_MshEOV@D~ zQqT+4?v$RGu1s;5xZYV6$)VL2Q~3NUjlAGDimE>6rCns_>U_kwlJ?1@*+gGzIjoSj zNjS4KDX@p@g@t=W{dzyD5Wf|L`SMJJG3R{BZi(URu)!{FaMvj5lKHq=8{opAyt+)fsUQKIz)h3NX@lI_xn)*0wn$fp zJ!X5S`t{Bmiaq--dDg}OYYLYmSI^?#D7|m??0%!nRRfltZ$iwRKslV7X8b0#YP;?M zIw=_=`NzpkpU%n6nWEcDKH=W;;k?gt|ABgqcy`IhvF-ZR%$K?XSle(gGUs+OVmNqi z&g%5A%Qw;JAic3bX40sE@XX6`V>@q~uCD%Ob#3mnM$)w@!p0&peR(hx@99MCZa{HO zsi(E^mkA4kiM(++hvxSqo5LK#@)Q2oeupy7$5zir_$4|(qi$X?)A`#ge)IVE!X*a) z2?i7N;{6F-r-g{522E+pxSS&Pf{tZLI6a} z+}6rRF}$o~?nryPJhf=-K%=TYGH+VsSM9g*I!)_32Xz+y#(hR{)?hVtPKSy^WAnhnF8kAvmL54dVLYJ=ZP|Mr!|b$yIL^f9 zF=Q*cX#=(cb{y?^WP9zM1)PJR8t-=_Z$`AdYUr~{vSSs+^?K&0-$d+%LtSi`*J=gv zhwfKHaYo`Cbi;;s3$h9!V`Ir(yu28GymQDwJZQxuImb}dNnhw*TL+_wE`$DH zvher*+&ru#Dk`oZEsjN%n;%gw{>;!qqbvM@4=)Nf8YR!EX7(4g4-~^Ev?*gEuaDX`8`Qe* zlr8+QX@X_oIEQ4sp@#Im?apHzq>NDo5A81|`!Lj+r&=rQ+UXu+pZ4qlCV=kc$d{{&r{#jCD1R=;r>#=AwN*SFpD?e%8 zV4_D0U7!X>s%ZaUcdqC@Lwt&P>QoP25|j%@eT}D&)~ zrxf#T+-+K;n0H3PR@nApk&Wvz!&{zw;zE8}0y-+l@`tllh|~@4R9QB<3S2TBegsBr z93{&X^I568f?eah1Fcn7V?*Ajor5C7Y)>rz;3pNR*Lri<7=Sx>R*g1wodwoL;D~PC zT#n`A%0a=hPQ8)Y03AoXV2KMuTRfYHQfJ(5fyy4n$rB!<6jG&mO1sAG8PINyKu&y& z^uwr&Mz&Vos{yt3(Mn57hfxP7l38?8xQcjJ3SkgOJqw@HBxewIY^*=<6rqAUSN6a7 zQf>Cl5!+7AnxrNjtYHL+5tYN^xb>Xg^-t!MzdmE;B4}n&fVjju)yKTng!K5 ze?;1!B7mRz{HLpM-gJe?N4UbjsvNW=U=bNT^^U#lm_H9)Km-6{n`C0Mt zkgv0#EHlK0p_tERYz!t11s_Acb&jL+si2dXH2M26NQRm?zG=Wz%*&n7?_{G(5_ZD5 zo^UaVc`LV>yj82ciGJ6j7wJJR3F~vgsYJucOLR{Y>c|{V-#*&S7T~Ixad;3ndR8#2 z%M5l>@1&-2Cz+|KA6#G+wZU~SBX1*r_vpEqn_7R~u7g_m_mrZ++&7a9A&`+8h}`(o z8p1DzIrbs<-=R?Zb^+(~eA)YrQi~(-d6)~o(+a9MF1&5Q^(KW^pvEfn3vbLM-@<_X zGE8;1A>+=iHc!U#){o?pE^75zc6N~DeLm1`_qzDjz@P&p)B!O{X!hDT)zSl+LEXI@ zfu!+83_SKY;<9AYpOTo-G=FI+9oPDjg%sLmv!ER*^gY$p4sv-21C4o4(@Xwul)ZO6 zo9+MiAEmUlI*cNeqSUIrMb(I{YRBFq_TIBql-PUK3St$BO{o%FiM{vUv!z^jdR?FK z{r>KM?%zLo9668VIL{n8AIW(h@7L@3vi&;NPfM(tO3Z&eWO`P^mLnsB41) z-gQ4g0njCnI0V?>iPJWU1*6q-@u+X!qf%Oxs*r<-N=Su>O?j~XKtj6A3;F({$V!oA z7{Gk@n0<`eCV)4gf^sCI8+3qoXaqKap8lf zp11FFUG%S=e%K7&moClN+F@;eQ-EF9ne5VI(!5qmr&*8AYHW_!Bme*bZ%B)08jV?v zURKU5A{|U=CuPU%FpdqNgp{nE7y6lC!ayl|5fZU*+OK)TY3%%@UzO}esm1gs)$D4t z7TI6g$v1(;D?;MI%o6;y-K)KBa|_PS)Xw-110GeKYmr2add!6Gk}HpC1}u8_S)oR0 zPXxknhH%TeeYSH;b!k@GT=qL_D_G!SG~+~=<32Q|S5|ultli6QyLRYTO%Kgd^5WH# z8YaMv#s+>*mM1mQO&9UEMWFiWa$D!Da+*?TO5x=1?oClql_n2OP2yn0_uAJ!UrA~C zsgEzlWl*e_+z?_~37c*wu>#-gb&DW&+is!F;&94P-Tj#|8KaGgFI$(}V)iLb7*4W` zaP}~^7nWjcA4a+jo4x%2!t)&x_?mRJqZyv5*T9u=%}Kjb0pbNVYi-r5$*-6q_h|Qc ziT6u;&MYBW-4a`%b|=}soi>Y6YCgrC8Q7TRIOY9<0Q`amB^nyttxOrhud6tpgB50@ z8y@{aK2y#A^^SdcqKW0r^s5ZV^)e5_io}Vg)QPr`CwWiO()kk}3w?b=WWD*=_qhBz z+0yBP6`BF*WVNh0VYOXNDAa6X%~V(3Krg_a)%)Odh7tfx2}XUfSC((LDp(9lxT-Y= zWx?~8(Qv3C!y=hZ)?icy+3Zpr#0tFGbP}k$N&T`Qizx3@ z$N5ZM{!6naSW^adMrLhM0V1af4%cJK@a&(zgx#G5*NS%naQ6K|9?utSv(rV7LR7<) zMjnVUT{VTmQK7cX&lWWAUp&Z6+?sD_{jSN63`xLoG?$6K_Ks@}$Q%DcKQXZ19quZQjXU(TXCWVPi zZ#mhh$Ga1hK>hL478@dB+teS^GnHqqly%umYy(VCO9;!<+nzE{02}QeK&cI+Uyz8q zwPU@PuJGNhrK*CA1cbzqawjlmhg8`WK*p7Q0N@|1(u30`nJOGNYyX zSJTn{N5t7ToNpC;zv>&;FL0gcRPFp!Hxd^M(>G)PNG zt$=?|omX(0bG^dG=2fuxF`DT_t)+5P-gZffLd@we0MX)HeHY|uF1$+jhF1StNMx?k zfBS~)a2eJkxgqpw%z9PVYCn)ID#D~@Y8Uz<(2Zt}`T*aXm}Hm=L`zwMenQPX!H;ub znAUwKAm#Uy75;c}PUWBDS2BL_h#wjvTQB^fxqXcD8)3w*rar|sr%PTzb$2=4 z+z=cn+aNg`D|tlBjazKee%NC;oVIAZ={AM1?2T$EN;{#K8*yXrAX7YbLihUB=$?{-sMdZSADk!2Pks*&EQ#f~ z9{47Qi85cWmhn-(9_Z|+wb|#7raAwbyMYY4VGfV2ZB^qS_OSX=9vZ=$I<6DIm<@d&bV3MxYc`q_H6p#yrX1 zeV&5cLBilKz*w$knLV^@(=)(j50e8geB8-^i~AY3-G^=7(8HWdK$%=4oM*|r#cRO! z7G+fy>mZGed-el?D#rqD$_SKu7J_K&ecj7kUU)h*KQa$iY!3rcif1J>`!;<%lMiw_guvIe0^V&_?)Tjy;BWo@PJ}2O z)=>|PB>m$Iz{;H&{vgbbpvyo80<5K*vAD9WxVgh{-s@)KaPV+83t3-Dnw#*qraJC7 z>7l;%zW8j?P*mu|OeFQ_rJ!H}WF#b~RRnim)(o}t0OBjk>d60COElC=O?5-l%RIXf zwS=0@ObOeI^8xwmIb1feg-iQ1_bM^lYbHOUtSg4r3(HeuNJb3~?M;_woqg6=X<%9B z&;o~m5{=X~q(q@LtxF%~kEHw0?xn0Vb{%2U&J6=swp;>9Jg=XTE4%=2aKP4(6hQ6+ zra1Wv-wOF_skp&++s_-ifXTHwU|QO)v(?keIrF&i>(}O?f;no+#}8*^`AW0j&fL2W zZ{Zp4Xm=q1oE}Kt?W`c%D~5T!m1Bq>GB=Xy{NxfRax}LXWzsK)@y!T5-34?H7#Y2Y zdZT1%5yP<0lpxRW-6HEW*Eg+h2WpvLlafDf758)}zchYai!H;8 zZvttb>5Tk6?K^UbiYj^v+x&GpN;pGw6Ji9kE<TJM{`p9%+o${90`;&5qAo|#c2Pi|$-Z2G2_tgIblKXA_c8kTBgt#wReb*0 zEw$gHzyR=N;g3aAvdi<_+D zsk1BKcuQfDDl2MU~>jh};(RA_Cn@<|Ja1!^fgVVCGo zoMo9S#5@J?%H~s3FuvOXI%?5^{8fFwx|*^q5fjfSPI$dIfak)wmGuV%Bj=Iqa$Vi+ ze@!B^IibRH8v;ur#VPS|zGsZN zD6@Z`X-1x|#~W@UNp#r67%U0E?T?p08VdoGFqXYy!cOU!F#Tn&z<5J~V#bcufL?|x*eu&*`uHN}`>nE=0WLq)`$T}A22q%LR@nL_y#SGMc% z9o!82_AdULCw%v}l#0e&@d!Kp0&1e)TkM~gZ zKnnPbi0ecTx>}NR|78xk{dVW|CJw5r(sORjIy@1bkX3KI#mZCwKiDk&94_Sa%3ODw z&S;t@d=n>cz-Bj#GC)an*SEOw-CMNAHjy91P=^sRY7xiH^ZpJv42v6F7egq^z_m&Z zI~aSRa^Eh)Eek+g!ng~m;1qR5Z#);YR9_`^B*=9)qDweD>Xb)V53%yFZ$n@<9A`e- zn(?NLM!}uOEvp(qv23_FCMw^bF<9Y*nq>I=Z05l>|FDxgPWwUnEdr807jxj?DbytD z_3NmwpIF>A9CmhDY3oV7fY0la3!8RmSoa6C`&9>}s{#1XT1+?W(nU5v5h2poG8|s9~G~PA3-O-Ys9hN#6z; z*=D6L8wY^sM`J->C(4j0;>WS_uMT<`Id@1yE?0Z48zv(&2^syX4l*DXai&AP!(T&k zB}26Y+^Zk;R0YAK172D+G(A;dS`V=f&ul49(V@+&=m&pl#Jw7K%(o7CNFv$Ack{O1 z_K^7tNW>&^G5sKIi8Pn$qKUmEGqYN7P)Dixi6hM(lk#iH9?w7qtD^VAV&-_!Ye&4^ zn^(!6e?EJ(e214Oe)HVBBK1W@@BC)?Z1Zel^DrT?@|%~q z`U^0e->ZUIH;U-#O(8it*Bv95^Xj+k(2Sp-qbOSkA|4tYhpwmw{0{hfH(+mki1MDn zMB+_RLcp}yq?4~h_g?@$rLT=NzZX7{IhbQ@a(GLX<E+voC$>x@ury6O&QWmgJF*PK8@RlMV3G!M^FDyad8|JY$#AC;U2Axg;jDB zs@T2ujc!M5(&~>_kLwJXQbGn|)_*8}o8+g{j}Hr5YR%LVwQKOy$hBi30QkG~KC30{ z^00&}vVEMl-!R%fe34H?`SjUXVsJomT^cl94;e5$v7v-}@K}lPiy6$QoKF1bPk-_i z!bE0A;F8o1=^M&0jFDM#L#ZjWI%cpN^uP?Zr3=oV5GfW1>;-luQX=N|w6DvFU~iT5 zeu&IgpIZxGCCOssL0EZh0(b8-qNJEY(&tj!7iz)86{N}$<^UBE?^~s> zzISJpCdUVfr5Rt;;YW0K9vMwU6K&!>8fMT(jyo7#)EoeNGil6vpZ2aL-aL3f>_9=_ zLl*pNRq{t&Zdu6-8(u7{!IO-#PK=Iqn_KJI$jnlj8-bg6`%9`GTyC8`e%h2E^e)`K82a;7 zP&gP6>otZf?fO>Pp>tP7^B|$lc{7j#Hp-OtRH@><+o=2tuqj3r z5>ri-BzjU)lb7PB%wK(Je^4+rL12+veuJpz3Gn##z)Mj@MS7075{MU#q~EJZaxLx0-a9 z4;cBcmG$xGfT29!*1m8*#(z`h>F2^xEI1RM0(x;7k7^IA{T}e~N~;nM<`3;YAVB=& zw2Z{eWw7n|X_tLUlIeU0k5Clrsi711CvB9+7<{hCKM%MSA=H%=&>Tta_K$^86tFO+ ze0&C?5a}f@C%qq9;HMtNNW)x=MCwfjp-3p@~KD^p%1I|YCy z0^ANN0tTO(z_{kEc@<7eTp9^leL}yj2y>?B&6rkvQD;#A0pJxp0^SgnZ{(mZHutWZ zga2C3_VNT-Mbt%#JURf2tlK}lBtpZ)`TAlSC_(Ayo?x&tXVR(OTH)f}K~Bk-l(@26 zn}!9G+W~{jRZ7`*NgLL9ZosJ-H!lF>cWYdaCGC8=1YDt(w_$q7`zpuk66DasvWQwO#0oM^OvoLEOwl&TkJT*SSNeQ@Go#6Im-gyX6?VC zg!$PhK`$Z8r|0h}yYnq=ue%KLwzHD8U58~;u0WRKO* zy7}h?M*kCy$&&&JU1G{f<38tbak=@-Ih&k4sc@&JiHm6&u zXSFEe>)2&c+>-HeGh=kiqUn^9;B^@mK6%L&EErYeYFYR%%YOsb7yggQ|Eta{=NKim z{AMxYkj*xe!`)0faY1A~53cN=UEqcLtIZO;!){M88)LwuJT*&bCNVHfyY$M$#fA}Q zR*j0*8^p>6D*gxV`9VTW=PW4~>p)M&%C2VqnaMwstS!0zFZk%6o&JB}qo4kBEUW*a zm+JhNPD-wv--;ay$*Q3DF1`r!@>cb7MV;pJmi4iP@jim=$L{c4IxrFOG?so5%wAuuQXcm{szR)UcMWClt=vAf}&g`h=Rk z=vYmCNI(~4`aZ=4sD3HUfDZMq&fU?beTq8^OyCz;xwM8FfI0E2(*f5*(drfkCuW!t`++XpybG)oAi9;$OmqUkvI6vv*48>Z4xn z6@RQUz+U}c?!X;py2v~=o}TBp?MxPhvf1bn^V>(g;1`HC0q~Oq<1E#F=z9h7K2A;M zY7qBYyxGhtC*X!XA_v$gasf^1?6_uF1&$O1XfVem$ zt?;p2)wgS&Kr~J@3!@;L6sZx=N-tZw8Bb+7KR7A}6G1D#X(Ca?d75%sUj;O5Y`KTIw$ncahki)$9oGk@qxuy*k4L zBnk`8V{;PSng8sOY*bQ+R5x&#=tbB-9bB7q*Zj=l7oSVTK_H#`7PJd18A0lr6Xy6JaWndfnf>w)9wE+wi$%!g89daC1iESQ&q`W4?So=&MfTlLfyMlcY3Zdu^@W|LM zWnF4O-ONs-4(uI|Nxf~MYB?+1NaR5!;`XthQbFsSISg%P*{0~iu18}#%Pf}5@T#5Z zG2i}^SiHv**aCzH4DDJw%fUaQ@2Emt7CGb}Zo-Fk{Tg;F0FPAV9;{4Hr@-pAqbfv{ z%!)ly;BFes{D=PS*vtCEy9ZnZ#I&RzCyJ5d7mKA159c{B3KDorX@v>*85YFb{iHZg zggcIyeJV2RGR0dFcAPIgE8(H6(3ce#1+*O9ijngv%IGYLYu@G0%LTv_5h?4@>?G{! zqPs(1he>!!V@OA0n;x?p?>#Z4IhQ#39yDGod4Z5wYmU4l-nQ>s=$98n33ARr+C9_G z=JkR#^Jv%y`$aLsA1Ums`$8%TO2prUyj-!<+)2B(i7KjKL^GLp8EzLxAyQs$7g~H# z{DJj5gk@aB$4SvjJr$?#$9!0s(XZZBnF!DVwP1b>ieIJFwS`Ly0(X1}2^Dx+oaI@d zP1vG=?OZ#g5;t0Nk$}~K7Y`?DV(zK|=p^b-})p6^+3oN?xUOzZY4Y$`*BFmN! zUOD3rdD<^9Q8F<;T4PH+&CCqzVVJfVu)l!3rtviw8Ey8g&vOvW^yqF@AFWGR8ojcX z>t*KUe?02RQ`AmyM+7$xoUuMrv*`O~mtt~h zSZ}+>Szl&Id@!x$(EP3j5ndE7Vj5>z<#he?x&|R#v(KlL$JO+1P;NJ%sdd9lkA2&3R#Q}p=#^m4uNC6>j_g^bocWHTqE3QoyaYL( z9E$T{qzb!TL9LbnR^y>zWSgre%~9QQKi|R(ES%leJF^i-8|n(^UB+)K-kVh3#gPV8 z*J;c<@*mYb(Zn#3c=D?CIEyK8i75#8>OZvk6d-ZisjoQoxn6hMGBk9NOka;I!9-ML zdTswH?z29Z-eH=nSGu|$*>#FHe6CS#DI#LUjTLT$w9!kb_D4rrsx!@sA8V_NF8h^- z^$e!T)q;p(r{xw`*Bpn}h1|V?o8tUSOI%>JSxGkhf-|R|)<0T}w`o_gab}BOt>*TB z8EjHrmU^DCC9BWCJ{657i6-RV;Avy!0Lalc5nMQj3$zYh@6%!XjHQ3zWdKb%^0qcF zrAm38zCrp)n8g&KA(e!XK)bMYCu0`blb^2}Wq@37{+qzYAa!C?OEsZ$>+%=io@UTQ zqg*%On9Uf%^EE|iRQ}oQIj!0aW0Hn5!QCQR>B+wU-Pq{Spt~9fhI&LknD$h1%nYTI zyWb1?x}!zC`l-nF#82&4jQ-PN;=%T%FBX4uWo)~o3^^QvT-$-XLM{BcfufbS6_r=4 zfj`+2rvD=Vg8J4qZ{=P8$oaeLj4jO`%cYScudSVlWH%1{kn}{mVb(xaLgcxEqy(w* zoq!v0a`ti5BA9d$@7%#_r1P?ae2XluDdmFLGo!Tr8>`)hy;j%I<0fIF|ev16QO*v{MMWV29Q?zf{$G(U(G+2)Se6gO8QeipEn|reopY4 zTQ}CA39Y5#)X3X!1A|-lIwiH+O4p@Iy*PP}7wl#6kQZMq6(}m^w#&LL{nU0=%Z0m( zjv3#o6Nku#3+JbcFy3jfxX+1{LnXm;;SlU9I3)*4r(wBT#@{=Mqa?p+(=%{%=ojTQ&3LMVGO{$r z1kevfqHW@U?rz2n@sn9FM6-gGIrsJZyh91dq@N_+{i74Zo#INHgZ;CkuBTh8jBcCl z+mq~LF?UpDR%Q^6^SyvuJdUDvI2H;< zd#UuhEXOiK{+#2SPTG_HJ%K;57-Fmmz(Uer(zU?+KlG%koxZu>5!l|fb4$lSnLoXy z;pjj78{0{(^rJ}tPtWnU-krXYKQH3c!_t#euPyV6fdE$!J9Y8HYM@4jF9m3r;$kh5 znKoz}Sd=DM4=}k)1^)|hCKI&G{1>3yHJLEHG^_r*DH_C{W%>ZQZO0y9nDTWZnW!iP z?h!Uk?*DMR@loPa+I3+eaAoR!L(y~y1C|&mPKSj zx9)F>oO^8iQ`<1l!M6l)oU6a*s@|OGi|u><1n%VbItq{-4L)_;Pm3UEj)hX;3Biiv znue{4L(^!YF(Sw$d^36|j$7-?5eEWV5`|v8=%2xW-G2Sybn{|phC~M; zJ;(6Uj-h#);BLJTbbDEaN5;Ig{Lb`RSpZWg4&hS>9frxT*M&Zm274i?mi8{SOoCZu zLc0x&R%CM|oh76ulu_roaY@WcW5MkNCiQl$clX}=3y@kuuupE_G5-2d z1f6(M_NlyX@wLMb(W)O3&)T>ToP3Qec~(7nV0_tSZ*IWSQjB`I2qVi-s+CuqPe~nD zXpaHr3+d0f5i~%m726r{5Zk{1&B^^7$ieucQ5E`MmGsz8kVH>*mDmm=7QMD7=YnP# z(^SU{wBP2V49$bhpNv^!598hUHEUMdmG{oJnAy^$$YWGx;4RR=Rk7V(bM08*_2r!f z$-#HQ3A~h?y-uO`O3K{_ow*Wh0U|S-M1k$(o3+0`?S*{C*{Xa>@M}P;1=jNNhTtXa zT&y0|01sj*?lbFdQ&JNucsh5_ldoH}puYh(EZPGC%K%HvO4ps=wSL^dQ#3UkJJvXB zc_nVHQHujkSP}6xd;aA)KYn{@o+Z z`+7Wx0PRaO(?{p{Fe;GIZ%cVi9hpHbV+D7M$|6hqSekoiE(vhN&HRJ29bt!58ja^4 zsx{wyJs8FK5jo{)3t)yk+~)&?#s zsNa>cnWI*S+#GQ5BmkbVFO(rIVq5}hJVgrEz$|#y;%t&&A&$#Imbr?Xa%lnf>>zg+jtd!-Nr40xGy%B)30bnK%eY-Vy4jeA>xGZ{AM} z>I#K-scG(y^4{-RqOzS@0nOoFxIXl8Zc~7nnO?ytT>?BMN%@ohNt-;Ve01%E}hlY#psSeA!>?6m!LRtPL@|3)V0u=MJ!N zOxibj%rkZEESaaLKNVf*_;@0qC_;R_zIw8e;J4+3((Zyp8U$1yRPC#~XChGGSN5sp zdv(asjJBO4nh_cqr;1gWXE+o5ssMgI0WTmV6X(OuIU%1=28}kUHXtd#@3e{fCeOhb z%txWY!$9w2yk&VKBylCWc>6%`m)?R3edISbE18P}TbGMQafj1;Am3ut{B9UspJ*ea z*K;s;xOr6{BORO3Vj+Ts_zclw&SiVSa61(U4u^Q2ZZ`U=*J~V*q{F>p*A-VzuU(6_ z?32%#D~j{HX{EE~V}51@4&=H%a41vla7a>;R-Lk>A}-0E-}`LMh`SaR0(*brqdh2K zlCt`CVgJL}pr7BbLYMxQZr@b%D{uzt$5z7(QmO%UbSvGfWiz zBGydM*}y;enB}H0nuVdbB=;_-EZ!_uW^KXEGqp+L2^79{JdDanzorKMxDTQ-GFS5| z8>5C#E)aj|6!HP8-|@9r`<25T(0(Lh^wkz6>lV2uKs#>CT-{i>764tZTW@R(jAGsV zSWtjq&9{O)5=nRxN5Gznf3TY6&6&aG`$9*QFs$f(SiLhXY5FDCq>@HO{k`jNzidfJ zmbi_?Q$JB4<`;HgPv%$lGFDg~eyS|CFBfC%tnNA0+tcwx<5qatdG$N_bo2Z+Zg~m0 zVkK@xT@*_k!I;g5lq9gQ;YTI5-(k?EO{#U@CKV4~(fsl0K`y_P{5>m};}xu5-Hx-g z(9MqXdl;Fc0+)wnQjq3R#vPlSunpGtsHF6Hj zM>*-}%GwWpG&v0j2yip0BB?^aV4{LreX7)*l->#; z=|S+sY!}%ETfZSc@2ck{1}6@iV0f*4WmQ?1t|jD$!IrLi=QRSuWG{(tdgn3!H2S%o z*Z;%SsPS^g<{JleV%7PY|7y69xBi3uPHl!uo>ISRa5|8pJQYcnQ!7%4kvwnIC}+ z4vp}&EqYj-RzK_A>a@;YChxnkz$*Ocrto55%kaJEc&=6;r&Ix~!VgubcTfdptidu8%nI`1~bXzez#Kf!)5d^h+ut4`IBp zA0Zz`5uu`rk@Tf?m@a;6=+xG0PLL9lwvb;Rmad`O`o9wPQV{7My#C>UoAICh?R(G| z`8#_r4z66*{CD-ejIv<#kJEwEa2l+7t1pFZeH;4ZF_%5_+{!Q0L9fxbqThXB*qt5w z|16iVi67mN1E6D@U}c>SljfeO(h zDM~;m)165n2IwW(pM%C|{Tu}4hG#?%I~W9r<^|bo^ZWCA)=K)e@oo1#I@du&!k&NU z6gO?j;1>U!Fki)q8!TdQC3MA4f{|X9LV5eJZ?0m>ZrwgDj>Rh zRXVt{5ztE83G5Snp>Q%oO`9uGq|a~shiJ8!;&g4UWe4^e!ALZA_BbEkDrjfZPYOQ0 zB(nNt{THB4z-@$w++3oPW`s}GZ*~4$cq`=28mG#)e?uMrdw2H#(juu6Hlnc|L(a$V z%o~Es>C53Y3yul%Ta_akZ8i!?#K&K4uq0@kc69o7Xu!xrAFXS{Y1CKCj9V2D^hIG& z&DdW62PMUyW=T!=y-mIEes|b}36TnDp@M!%-@uHoQ?Oe4_2XATGS7rBtjo?et*`9r z6`+0r2EKnp^l1S`zvew&#dlTN5;H6zk;LC|Kj2n6=&&tJqi%-SSQhLl5SdykGyOE5 z4E3JnCrkoB#-7sIUyk;!Q^zAhDdmm#MKje#4f)SyG-lx@kM>rrM3MEsnB38!C(Wvb zb+)heLMO(WLTzo<#$r)mC|4+0uxK!%`?Z@C;Lw>$nC^VPCu}2tunaj7GD4}sP+8$& zoYZpzW7u78l&~{IxMz7)52M?ovn%wKQwtTebUONADZXD-rz5iBDs$~;b&Jh8Jw$`l22Xe=?F~{Q(Lu3P;@Bz+ALsdUZJkNN0{42zbLO`EN`I@%+9u*i{ZxUBTc@ zuzDon=h5@pCOrp-!cT!{F_#FnlQ4qU+}^9n+Y?v1HYJ}6i%eiS_h!kIX{o!T0TNU9 z#5-%{r%4@dD!K@1fch2h>}}fTcC0CZK8d|*dyzhcHMTV6@dG>Ts_?w3@&wlYfwz2t zn@e}Rdwy2w$UKwWk&Q@~zNz=!rnMLslV#u4JoCc=1& zn)%9$#tmzYQJ(3AIkf!On(k@{f07TVal?ay;|gcINX5>-{4Y^Z+95{~|wO6Dhc>BdJa^kF~*Ii+m)6xv~h6qd1kz zxE58y=lH@8pBe&|`wOtvvWorp8&vbF)0}nS_n5Fl^kv*zq@ksC?3O2rO`Nfb&Ji;I zi2F@OMI*|)2A+;^0cu0TQxn+WqZm=4K;O>~K8i1)X`cSx!;KbLI!>thvrj9Ma46{Ys{W4vUi~IjMGPg(JW#g zfo|l2MWK-C!U|Yrl{0<+;=Yg9YuAlt@u07vXIs<9c4>`>GEXr{gn!O_YrIN^*+yGy zPmcOf>B-KiBek!0L3~1ERh&Gom3^A2&5#_B01It_;jAV`>e+knfQcLqR?;z=V0s^% z>be)zLq5(+(UOuTyU7GPh>GN-)6sD~O9u{EvG+r*ODAZ)`E1su#pC_89MNBod6Jth zicnuPALz*Gb1DS6h?w#W^h{Bs%{e(AMT_P5i*Ae~pN~1(vd+U6z8e3if?~{GEQH4N z>~CuRI`0P@Kz`c4-_brQ2JM@ngN>acE|l z;~{E>Luxu)J>)^B0bgQo&uVu;sZ(W3ugbm-#hY*KSAA$r`4v?KE_$3LZoraTLcRHz z=dXFNmOHWyv8+VHNa~>411AFTwOV~s1=t9?xdMjS`?0K3H@>bFEk4adEs>nFIbT=X z&&4@xP4s=?An(q#ndK)+VTH~eI0d%Hmqe9R#n#@ub%^MZd(jIiz*UO*>p;i719}sr z$JXarL}Y1!|Cj@Jmoz8QG0$@LDwBUKbAwYg>=bs72KF?+ja1zvUanp^p=1(*NErK|!}oVunBKQP7l>)C-Q}U4 zDZP6XEn@3p(^M|QFp45jWlD;#&vxnaaCxqGbC8KFZh~-9m#Ku3;D>wz{I9K8;IgO7qXDl?sGnuyK zSGgMY*YHWO$hU7_i;{V|OfWv@|6Z<1vJvTv!GLe?#r|gcdJcQX<#KB9WUw(&e64&0 z>mMLH8%%WIue6ADB;azC_Sqd7`gx>d%T|?R*{p1k<-Oxgx*7A4bFfi5`rnj zLNdYV-D>5ZmQmIOxYdorsds&S4Ox_o)`357AEgX(o z8U1|q8rA5=PNZ`+)nQW#le0G$RKlg3<7w7)hRD6%I%qrpKDqmTv`qo(C2^3J>SdnD zhsz`(nFQFzbhs6~d|rh>lm;**pPg~18>`V6D8pEwG<&CGn>)7p9(BHc9!Bt@>|zfN zo?g|>(0kC$2!Zd<9#5X;21PmZaR`1|%twON`NLnlF^lFE6y~NpU>I;_SQQbLAQ4a1 zKi`|%DRPsye+6Sby5Mh!m_-6tr-xZ^akIQ%iWz0+ITpj>Q3I7^UiV6&&v{aWND>_( zZaqC6+hgVun#$TyqT%ZOVAsQ?3|o2^vV%Fg?vJJwz=nr%qSom9?E?k8!#SY4)EhY1 zWD!#h0nZF}fzi3yva)9?TF<318yV2=rX}_gR$h!KlZGez4q{s{RdV?*7@O!Avm-QlS!XOO^9?XVbII zYE$DEny0?3-c+VBoxq1W+O3u5Q;ch&BD&w(d-NG=R##!43fQPw=Eq@|T>gS}4x?T$ z4)3FG?#7Vi$^;I;YvE;R{T=JaubIwhoof`A$*n8o!s#+KR!C- zoWFrW(0&yKvl?Kg_&a=!S!;gi*r-j^3sDJuefBRh9kBp!KzIG^PO+Aq;7kQ4j7YS4 zX~~=0C;7upWf#xLDdc4_U&}>5sLh9y{0ExdHJ}8B!So#YHM0mSX%ZA-VN@vOV`@Q(t7A4&yq+} zm8ME7+vwIIKMw?Ie${sS1(QV^Hzv*(80$Lem|7>vP@aKh+q_J85?dy6`(c&WDEG}q z@4H1X{n77~)y}G!BF>D_{D%_MtAYz8V(rJ9Ba4t(70pR1xULExaG}s$*%fDQvNgvq zpJX`o4JFs!1vrk%Ic5;8K|y-em#H+v-1j2xDlK=oFX2({>Fe7M%qlY;-d1xzdfYnv z9SLqsYGC5=jp_wE<&y}}VfjLT9_4SBkC!|TaOTV_Ni)vOy7!G7Kn)oP0#U>R9pO+y z^F*53gWlWZTEVu|I979;BYf$&&|?n9%5}s>u;zLt2cO@dIA-; zKwoweUsSOq^7C1@^n$Z5Yg4lpf3kg4ML5Ju%yU$prbRTsE_C0)c}~6(#_c^bA$0XE zvdvB`-6jFjyFd^|2O*I^x-Wh&x;4tCLa^@Oc~sn^6WGLKp3SkJB^mRER`8)-<`Pf& z=YsC1yTO42Rm9CZFH2uCm1j`$0)N+gFx>>Ql~N!YjM-Q7>SSaRnrVtei0PO@*1mi~ zDyyiAGo-Am3+Fi5j?sQr-9J`GCACMBuJ;6$xO`X_@J;X=*MjEpK4o|=@**kW7jP4w z-))FnVKawf0#Q|rsk4{!>zmH35fZ+ZSxvo3*F^>tVrE{_Gd}4%R7_eGK6U~Hu`KD_ z742rVmwXxRZXV)!Z($ZRDEud)nYYfaYw{=%;SWg*PG6ZM2c{bf4@@DaO#p4 zX73o}6&4GSzi}e>E=pm0hudg+)VDEnMVBM02r983HJbZnx0Y1e*w%XUd-#dH{cOn=){rrF=GyyqrUdPWCuaoQ_zOV4 z`T4~8RBQG;UjY##qaimbMw7|Fm@6Kv2`xu~X9W0VetE_ICft8+X8!8A!5@Hvr0btY zN;){=I3xD&=wOtj3iwZSaGKkHunwzOb<*D(U+&md!3(jmrRu;xwZp%oCmOIxA((eq zJde27z%s~i4JfTJNmr;pOJU}84w*v-czgf?3W$St@`2z0?@ya5nRL> z{}x=aa*Y3Ze^8Rw@@tP?EX)BH#0D9c@KEvRzZi)s#xz5vFVd-X6--WD<694iL-qnO(BW-UV*I*`*iBu=*I?JnofDuFd< z*0{x5eGX}Z4Ocdi4@DSD0IV@S8XThGzisoQ5NXPtoM898Z`f3Emn~HimyT~GG!lAD z=_S3Vhgbn`Q-k2YCg`mvwkBorH!?#It$QH7Eq^J0_^r;?Ubeu)y}~IjW}5CmaUZkw zYKM^@(^=;YF8eXMSD}g!Dk&zr7`}I&@}*JYJN|dVSO7_p{3u$FyFcGv<#;hJ;5Ugj z+Oto$y}nDO*_Niz2hYbHFE5lV6c$gz7I3v+IwYOW$fI zV#8O|u<6HGIoh*ts7Vx;x$AdFjrrjrAJqJ;&PMhizigA=%Vm(;kYUWofruLp=uF8?_UgPOs&n>b8kgQh!>lhxQV9K2Oa{DjDbI5Rxllv?2nMby@`J_iS9X@*!a6qfPY?v3goJ2dnJT27M|$X`+~bmKuwkIYhBo7Y+@{`KOew!=j+`Jj7Su0 zX|cqCw?8sY{BCxdI)kb;w{N5s2<@`L9DCU{Z&r~Cz?kKBI#S@1)xMd1N`0vUTZcW% zHu$zzqsrEq;FUeWz!I;j8nF$Y#ZL=17PBilef*NrM%eJySrTbM0O-(A!B`yj$~?Gx zrG3#PC$okomfT|BSY?s@z}NiU_6rS7BjnksM3M*BR9^(##3F`di#C`iNAx62?r_HA zQf`~^sD=8OQ=fb zv%SRVr6Xr>glf;(`B1w@aYbnWa85wL;alcuOpuS-i^13ng>GkWVaD%x4@W)Ad>cSD zW%4#kF;^W5j4J_MsQ8YBl*d5RnD(aE_k_^~KIN%7liMqfQ7Ii(h*ntyW2pz9Ssa+d zDYAm$L*b+TY}EG#{9sjiBkhClo0xHOe#gC;Pr4eHRUQ&usoSg;j}nyhIV{^L0WN#6 z*K}-u0Ze|RW_n!LM4DBP>TlT_)d_qV)k-fYJe1kW1RO3K z5@%pYE>USEnilcWeNZ4#Yr7kAH$Ncr9ltnhYZf&H0%!lVW?qdI9+;a;3V zn~)?7xSZ1lbS?FLK{J6U*&jKPQW6;21QP>YMwOpY25lvLdBY@Z%Q@Gb>dcqeF6CYA zS*4+0{9^1fn^VVjv|3-*y4(^GbC6Gdl<3pt^>eFD)u#g7xcXX4E$QO%-h%?SU zG<>(v!o^@w2UwJOD_s-;*y`vR^7R`lLcf`?BWW)=b1=`8bv>8mhB24foXv8{;WN^D zJ}=}R?egzo;!an?=;LAX3kQedYt6CLfLAtojr!*t{1pKzvbyizDiK+6Uka^DG%zg} zu)yDZouO`1vz)~j>Zo0s%1XZ-%n5e(B_Z%@+ z4~r!^o+mRm$+dCv3ifpeRFE6hKN}~GcPxcH46Ry0s8wAhYoop%Wm{ja-pG|%x&hgl z@!Wp=Cf7!NobWJ@K6JW@F{Bw0e-62{<`DOx$L+z&>a)(*JuPI1h#i%(UIRQ{lFJ-@ zh_dpQadB@yd3JY(HJiQjd35V$f$m%ae2f2Vl&`hI8y-RYo$l-2s$@e2+JN(-t}$gx zrq&h19`P4I9~~!Z^6K5f@I0K$4l!5!HS4GJbZs>Pp4MDmR#5QgDI`&K-!x;L@#P9F z7OZ|5XDMHvE&ad<0cDW-d2)OSy^-d&FB`wYtC~tYh%+K6rih9)F zKtDMyxE(UGPgnHx+d)k4Rcfm14Ysm^aN|98)G?faHz%g25LaM7a1Yd<8boOEeR+&O zpk!-q;y?m~dOtbW=~4ca^aR}D`kaJbAWZUI|LV6M7n-1)AhT?y%3ZQ(bGhy>E@P`* z?vG;AKsXi#A4K(pbiYe?Rs3XeU(8qx?Roohw6|&Nxl>}`{ki%ce~Q zI=g241@HtLz1no z$y}y8omc(*G=7cFqxd3JL)hSOx8p}?JGr*LVx-Tg=*WZWG>5Jv3$44ve%{9CKCEbr z4%y3{FhFuQ=9Rm+hyxD3R{IPy;F2H6+n?y?xvO_Ft>lBhEFW;<2^4NVrHKRvu~uNI zR5OvRnF>M$67cjS)y$mZkvgls1ut{@dMb49YCp}s4a0Yt)B1Jb+0CbDbZlIZ9)8!N zkw8XDO&E?uf9ozMfJ z7ePT0LX!?bdIv#z@1Y0?gx+iDy(2hr?|a{KKQqsKn0enX>sZICSy$Tnuk*alAK?ol zhCL&HQG%c)wh~CL*W&`z@QX<+Jta=MEO_Ftl|?y1(Hd(4N3j5$`7rWkG9FF$Qhqmw z5mBWIL1Z0GTSN3->n(%W458~{tAG#`JHUXz(Y}+Y_nR9yx|>aOU!O`mwUAp#`@7gf zF6EMhh2RMi_$RQA(T{WFmBR^JnbaeZdxOyf!7VrCo5FFuD&&7nDXMEyh)5axmA|ht zj>`08%%Kk__HWP0`NaWNS8#{5Pu+$ z{GkX@Y>I`YwdsYb>Vq?ICd8wN;-xzMUqy4?bm$t!kZay9<-fgeT= zJKuJhdLF%O>k(J`it>?H9*;kz{RjZg5(P6_Jb;NyRCUAPHt}Y;(UZ6zl;LIQ+)xA1 zP(Q_|O2%%>q$JDt?BJ>{(N|My4MQ-GWO@(Sv$21CUR2&|W8o$1~0JE+)a>z+*crle{a^dmP2L9B%x3!7+{9-xEQLzW6xo(nu9JIxnD(Xt<{ZV!0+Rmt~ z*jhd72>}*w4_iG>7~jC?x1{$E_W0BD7Qt^U)ZxpZ(5DU0-___F zdEw}OQKv==);wJO0Bp{9(d45Qa+%{j_^{6MiVWuTqDaBT%9P?T8qGtzXn!gAfjnf7@6a># zb})EHe7vvGq_A?5NQmODR%GqBN~UM<(qt^#qQ?Pti|&ypWgy);))z7hxcW?!+|&M+ z7cKpI8Y26c0qrsX*65FA8WIVH&p%KoO#4jma@pP2C7CN>CpAjFa?Z@};T-^M~?{^H)CcU#%F0K7-=)zwWR$9}p9*<~W0u zuSu?CmkChST{kS`wPQ!gsW{jr7-x{Ke$!?vsFg zD<;05N<0duEZEmsuD{5rNn9P())GcNLexGds(iP@xO@CGq*uEvYRNU)ZtZA4s zC59VH0akfE2uvcEVooup2;RL_a;ly?Hu9gWb4;yQf}SpgSR(g=0~~n?9ivh1!|hMZyp2Hp~Yd)BsZK|Y^X_wO$FMAtJz#>4jYC%0-s=8tP+s}H*M7-W4PZP zUCyb2wjPVR-J_c|rN+_Im%tFDAUE&Ou<~go)o`c&nDEo(n`g{{UG`F&$u6y-sp?ZJ zIL5}vlQeJWAk3x-T8G$PxI`RLcm6PCF5!57?4DCYUK#b`{mTwDMe*%c@HmN^qeyfz zc4EKzVC$@bJ9X>GLCx-U#$cHJX9ctp%+vSS?~8Aq$S5)tt}oH3gU^9WL<{g)(f!*x z<@|co7^Ak!o^awZS(KJH((j-vFf+1NdK&rbutvrI*YA+y zx+&n&4js;3SA8DSmf5_VTF`g1mdSYX*^U~GkI%utZ-A{$?&SEw+Fd_V zV!VmNyX@OJ6P33heScQL-hR0|x(k+Xx`56b@axow82esY;;xmK63`$-~*1dAEz-r zFGp$B{=w0H!qECoF;xYdk1UEB1SU^lIsL$JcP(4D zC#RwEOw8F--G+l395vu{zvTuS?x~rN0~Gcfk_&hI@y=iMrB*{A{o~?(ThvZwZ6qv}@-K?2UQtL(cJ*h{J2Qa3%)u zX|X-OXUn^on^R)jW=NAuM>$XT+a%AL~qWE$8a|0AL7=P=!q97s*s;%f3iBkb_B2{}0rRQ^BnI>=CY<=B# z=VMKyo@~p8#TksQXVGPJ!mcdRlk@#4?vv*CGn?KrEkM#bDnSjrJGb>4kX&)4F6UXM z{2LJLx2V5}sc?97UEX!5(b_BLDf{#y+i%gRL0Z{w*%E!GAbH>A@d2YF^hN8+!EWc$ zaEr1hGQt%pb=<#y#jW@D+e^aJXrY<$&5*d{%WCJ|^j(pNFh^67x{?DO0VX!K-vA-O zOBI6f0XLp%x80?ggE(EiHSi5l-z!}HvvCNy2U*i}_1uo;;{hoY4bNQDX)#n&`bgvI z5*O$1qE2{}R+S2|B~T^;R_aRkChg^yWWp7cw{O$HJ3izBuwlWiyrij4(8fi$1~~FAh`AD9gLRKx~1;>&LJ zE;G;GMKb-mrQvR}#$WnPsEF94&7hgO84uCbGsfTDJvBy8S!AwhJ4_G)eVBag&q#=fkxoTmEdKaY5RcyXwVtFwDnd!UaeeBo z+D5#w>&X15hHO2ph9J;6a9QG$36S~=Y(?YLCloLLQa_>7JM?6M zHWimNml4$PxMCnL=bGJ8J6H^IJn3fU^I86y%qsb<UWzJT_|78{6jJ>1Sx(H{ zVoU`^Y)w0!toX017-tk#@7>zfemDL&%n^D;$)=_4=9OKTyhGE1m`)8a>8X=8sRl-F zR7D=9w4N(hnHAfHalus~A0PT8PM$nBe4J-uvhr0a%C|{!^YxPsi_97ugOoCZq;(E+ z-znPxt0RvrQiL8G&CNC|YIL}!Kf)l#(}`H@GiD;)UblzVMdVJc1|xZIGPsw%bVmO2 zDx^=kaKp5Xz4WmHexv>EQ~aOTvuQd{Y_*TcYs;@(2LO+rCc-+>GvN?B(X~B;OWj~Y8zU9N)pmR- ztA)%^C#3&UTQ^g~kG`)BcW;rU z0OL0d&vt+(_*WeE;+HhRa;tGzhPGa{ZM?fYu18EmqwUbRZn{L$iK{z>`g)FGZA{c% z1GvxV$+P*B7blSirQ)jcu_DfObSs?2uotXt?faL`_fU{g(bp>4N+6*Knl_qxGZWvA z_p){$gXQhti`y?$-(At2bM{}pg(Ht}&aF>Zq&kO)0$fxWt`^46%$4O0z%@pEA7dgH z#=OdP&NiP~u@rpj`*3_0K7JlF6KP&dC*oyzI1IR7tFMPhdimLhMGK=#Yh~uDEK~&l zVQ*z+MfakMb%|uXDsq_cMrqDVH*>k*X50+rb$cnz1fYs`S36jp*TIKa^Rc=$h_=U~x`E4%O zK32^KBdw-ozQ(zz>oe>aF^oGaaodXG=LJ16JquUVl5<|zK#<5bur};n%K%~#Jk#8~ z(teYOyD={+gsoScDP~`=`vKV!>?4+7842&yrL9aPN&$V*GnC02wRXurrMXC`dp!YYkkr1=ageUd z{*%jcB_?aAscs7FWt8lN`&%aEEo`7Fz!+@4br6ILA{%>tMraG7PHyXkuQGhbf+yXAv_UVGi;szkj$@9cb+bgg(NPXH+MT48k`G?S66#h4P2#+BSQS|XF zBjDN2hr#a`ycO()7}aFA(Mb`xc_n{q;MT*oiwB8soHGpUl~dAbKqBv2r@cCPeIKf# zt-gzC{ss{K=mvD{WFh?e`zbZ8zj~`U78d3>f$1{L0yp}9O4^*y7`M*V2mqqTu~2V8A|2f^&8LSg+8m8e5i`HxZer+tgH4Gg9@){CTu`;^3G{4JhB zd^2{4XLnNtk%jUMVBg5Jxs@b!jgTFm3x!C>%*xepE|*QZ3MK8As3 zwgK|g`vl%PcM2+0$~G8@q-`D{^cV5Jc?J%IU;ExcT=^AdjBzF2zJ+>`2j|iCdWo(M z@E95c2CQHvXFy%VOcd)_GM@T?vi04cAnpUdw$iuvXd;>2` zwwSPj8ok#POGm;^xck*t@iwreF@@Kt{rNkyPi)f4JLOt_X2e9{^8YJ*fgsLF>4Ji7 zI()kN$n!74M!xtzy{Ye8GkqAMk7(6uY&@ZCxYN0e(Er;Y@koAfT@uIJ$j-^o@C{Zt zRZ*Y)#~i`VLM-&x=9mXZf!F2=r&99&Hf02;L=Jau4-O6U&Dw?HUsCoyJpP;(z%HdN zSYH|hU5;MPFjd!L=qS?V#p@?0 zlanKZBevqUslmWx_R2z(r?mx{IvJfwwh(a~zu2dh95Q=IRoeUkU*I5te8!M3uGvLJ zO%BJzh~7!eXt3Cg|I1*K&+?}{>}s|DO?hrJ%Hwz!xXo+sY4|@&&%pLm=Ki6TwEl6m z+C072U=Dd-AmgPyT=dB&3{^?}Va{JQ^48@@|ZoOe%!=$DS`3&n? zE#`!^{K(2Nt)HR>o;(@&bL53F5j)AGTb!|2H{62<#vax=N>QV2=6gfG0lU5OSEc!3 z=DzE>AYMFsr|XBh1qM~pN;{2{lG~vgsRbipyBYn^ImMe@hBv$Pr(|%%SeZZA*#EyL z&;36K=o+3a09{9x@uHsRY(l+Y!^AEQZdtm{HwC%r5)sP|=NXZ!9`hgy+5U=cg0o56 zD5u4rtBi-4y+%84&;h%p-**f%GK=4acv&7GosW(#*|#UfVBa68Pf31(r?RDN-a~I( zP9arcSoFthzTP7G#PsyQ;T+D)uPha1-M^}wwkjG7eXjUW@}WnbZ;51$%uZWR)rZws zc+p`cg>aBTgk;nYWaDo@`I=EN1(o7E&PzQy!tu25Aep(u!R1*p!XNpff+?g+ah zAA;D}b!v=9yTLgx!M*C3%9X-lCf^2i3_ox{aR?l@g|9hppNsAP28f4mzyA%;3@Eiz zDKJp1JD0?b-%_4ScGc|{8<-@6Dl5stuMAEbUQN)U=0}D4-TbY3R$sj)s_dm3->HT> zCPW$t--&{+?_18OTqdVRANx{KUPYvK7DjfOdA(|hV*qI0pEL=Hr|QT3yvaw#1};N- zEM#x3PsX`c2OhWj(Qcj#iG;cMIr`oI9)XAZCx3USXKlSwkQZ_XLGw6r>eb+)=A%1( z>Fo9~KEvF+9ptoTiI&aMZ%sB9-H@Mk>?B!s-O@(`U!Wd(_OJSs?xi&; zVafp z5z()ke^hT`$;bN*2yZ)meKy851Sb!4`si-f>_=M{0y9AjJLZBnE5G9GKabdEW&%^a_{5;qkDWP){Y6WuN$pldeS0}v4&rx6G4!D_kG|&12ogr( zCXv?Q`*q~WMIv9@6Pkg6$T`gOJ>lY^{26uokymID`y@3Axudpz)ey)2&F{{@wVeIj z8khF0>%Nxvq*pjh3GGoq*yt19&X?*t5Ku74+fe8FV^%&!`=GQ`V_2hgx=}~H(bV#XUvI{-5O4U;j^Ci5*OX}#=`e{w(5y2 zKbY|l>_;y2{MZ2uu-)+;!^l6Cxc@=s#0w8-cOY+yvYRKp7)oCmBHKl9o4s4KF1;ev zz36`bK+TcbiGjgKvPdVxopaJ4i1hBci}4N`V}y~_<#5{A9+c_e4X}uuiMzA9G^grE z{mP~=ys~{FMIBV+!HHK&d3ksc9vAgpOzza3o45ywxi56I?~ers@GZ^jj@l;XEODLH zA~@yI`uo-jnc4P;X{O(R1%clHAHt{t*0d@@XGg@4%WnYGV7u~j11vORuzwZkT{aVj z4rcrCHdtX4nzG_*2Nm~xQ_Nq75+jkcna{^PiuZ_VcToBv$y{(-a<7h%(C;HU{B$$5 zD?j*!zWt9A&uCRY+T$K04p?wBtDRRD2x#Z9HE@)7Yhvv~C!LU>8H!;vxZ3N$IomuO zh}1;bIp)Ejw57xMB_m}PCB!jb=);YYw+5VYau}SS@k=!Sy6)I`eqzMtst4Kc{0RWq z(V!cwM{Ve2h@(Ur<-4m^1T7`i50$$=FfgF;gDfzmcU`BREnO;STu{Cl$1+KK-p59$ zPy(;sqEcU~sM9>KjeSh=jG5&MW}NsN;F1|yZgSY|afPB*IV66J5aFdc?%-wEfTUh@ z3>o*Bg|(m>tPZaSn;CzNaB(eSHK4UEbZT;?Z69)=f-%H|HdS42W^sxyu0AzArr7B3 z&s!8X%F6=*{js;c>&6{>~Sj zcO1GuN=d5RFr;xNxLkL-y8rY_*xIGdh*N8;pdg+wA+-~LCC1O`fa9mnN;fL7Q5$Fo zll~~}gCyUezx*{wV7xZ_evgKtBBLM8iSR%snzBNX{kmKG{pAcq=jMAaX`z+ilmdn-^4h@7BKR z8I{lgUM8~fg|LxeW_jRUyG|0)iq!9$#x%J_T7nm?SdzTL{On3qwAOGfDw(nl-py1k z)R9%w$+x@Y?^E4P^cE7}{meldd(o*#5~_Lcww_hqnT^3L*} zmm&ADG9oKZTbk9*)rT4xv-j-v12d{cVe*4#tjNO?XP-h#dh>(CT`L!n8n)vV0+y*_ zm3Kp8d0&46I-|eLQ7D6ViISyy&`cMh+;LgS3Dsp8kQqf9o!+J)Cs1(%DB& zz3V%!@im*w5ep{HbYDRTYU8EN3|HdfP|tuDw_d_l_{$_vI)XKW)q)^$B%WLg$2h1H zf)i$joPEpb@ze<5L?HcnDIftO0s0n;%goK2og3p0RA9TMFDV$y9g(eQe+DN+GAS4nam|Y-OKPhtO#;V>p3ug%acL@2suFe26W3VvfEc95v zYDtZyff65u(i- z336wRqcXo5TDF0)O97d51va$$%-O*RF@JeUYwfO727s5b8cNssEbx}CsKi0iQ1vIn zC$8d*jM$=Wr)z@*W~0kHL1U+h`cu+$)H}1RKv<$2Aq0H~puENkTeKn`VD3X;%F4W? zU(?KYfe#EtT-~Wx|X7oI%z zZu7V?XMAiec!S+Q?e@aZJ)?3T>5|JMjW{uwQ02KcQJ*sAM*!O}x}neo38&t*n)ipM zI|bqxVaIvNonD5~t&UlAP#r&H<|WQ#K9FZqZ<+pQ&K4uQVRNU(;BMb%Gbbo!xa)2q zd@8CxkToZ;)6+6J*B;kNR`B@Apn2Y3uVTSS1(nOdnklLEzeIoXhfsQ^dqhS2@wKOY zAHi=g58jBlrr?;B$7N3b9q}2YZj3WT;{qxFHbnmwQJLk{b^Q;~Shj})bL?@=kMlY2 zsA*|mvEuC3)Bm}FOb^Ehg&)oz9em1`&;FMo`rpx(%;(!@Xgk z|H^_Q+;hbXJ!)EjJqvif8N1Os;Zo}FQ~670rdCn)g7j6b{BvfO%KIYVr662S!V=19 zS>5^Fv5EzJb_fgg8a~q{9Mn-&{*ohkl(ScGWmgsyv?;B|dQ+=xv>DAGQz2DshV-z) zyCj)^2Ao!fJh1;7FhSvCV5f;o)}ri``3@A5Kdk-^Fs}i&%`N#;@MvlOx_JF3{q&z1 zjXy-^zqPwhUv&R*dH*q+|GE0s|GawXCnf*v^{?F}KPdi(_LuiX7grP?p4rq^R4%U0 zuN(gB`XF_Q+=BC?CQrXRTT@WIO;+6P0=wUxFS~zAm*c@W;L!2!Q%HVro)S_*vc#qo zLX}=uFKsmcodiqK63a_kIqiNBpg2aSXCO~!NIM#ZyVreC(2@K0j+#~V#laxP^cvA2 zTaIf${RlpQN8`qRpQRCPO5KusD;Xu%=@JNhG2!z|_;UgLj?m3Mn~KLd zVo-6`={j#r*hsulEFXDM=+`$-hZ1w$b0A=NF#y&A8dp>{^m2Z~`6Xs7NVx{i zmCX)@p#FTxj6#+}GjV#`56h;X)oOeEn3fYevXpLNobmBy;Z|y+f>vPbZ7Iy9-0@qV)EZPjF9dd8`B#XYyGPdQWc?&Yy=`u4^Z;F zzZ}J{yDmhv6fJ)0ZtBKYlizs+Gz%K?OEMdDEU!H!>_=nBwQcJ1aw7+JHnPGJAVO)& z0ErIb3Z;$G-+)AB8DWX$M&2AQNhIcOaDx@Uf)RA9d z4dT-q#ak01FSB<70y~pN5#4N@5+bL2%A`dZT)hOHQcJDR?Je@i=lby8jciXiJQj{A z63vOSre}$wYM4>=EcOQjPQZ2S4H<)EUGH6 zoGm@Kr>vfa6Ix3+9l*4G6>?A>8!%RWO#k(PwFJDe1Q*rp4xkj^Os9T3MI>$7WwqBc zQ0KIKP+J9xas)<=#;P0;3b3IRTcWLp%K>!Z2py@%bU3G^P!ZxPDJ9h0Y=*f}iLaHT z8eV%CI8TKDcI|bNT2B)=wHd@NG{alJln=*NHNt%|non<{i!q(Cm@&vjy#eP`Qp}qM zH7Zvk({*I^J_k!wRC7fGV-l;&Kyi7W&+hxtETi6s*Z@w{8%%y%%VZ6@4 z)<*Psc1tLu9R)DXd$nq1cV|4IYLo)xHNzatw#A4kn2B8<)^u_0%nKY`Z+r$N`gPsk zbdz!NX5U!d<}8|ANiBW>A5E_|>6hm-BiK><_Ti#hALQk|Zk8c_-rs|qB%F4 z!)y;AMgZoW%eMtnrY+?CII_KO#OzRyR>4bCS@)+bHAQw^Tn=)sl}3luYg8?hzr`O& zB3q1D##_)2?FgUYEhlpcFH=#)nu;<|6QNzD$)`nDibf6yc_%;}j{btyy^0C;88@E&c+PXpN;g>8{uHpn7C|EeVTO1y&b*bvsgrX{d{RW`1 zDI2Bp%O$TFhwr$m5c~Wr6L(RK$B$aAV)7|y5dKu;SE{S0rs{McT~&W2Rqy+=_?Tb2 zUtbB;S+&9s@gKapbHBJYF$zAXe1#?`PbS}8+A_Y5Q<00EHpuF5-kMJCrKnPvq&=nS zGuLVB@@2-gcX~ogCNsp<1A>Ufm3wHPtfR9;oNV2lP8d7YSe3d9tgTyIcpK$$L#8mc z^z6;LUt=(DCneRc#EHOaNV4F&D~^c?N!zN$BVnGYqO%6RG3tE$Nt+qEV5HpbOZY(D z2c$t*)Z@1v@B631tvj#_U7!-dD31+Ruk6SH_{HHR6(1ELd9VCy3hW5P9IMMHSRAqO z%KClb*ASI=<5nK0@WpiQ#DGS}F&cVmNkNy>CzLM`O`H$EdR$&@mctdd)3#Y_=HHmc zf^9L1d-yHfEc2fOx)NilW0*8(70~{51At_UdyxYYLj1&R2Z|)ZExCv$2b2}~p zpO{x(@6~Zr({x`xpXXbK59XAhw7g^P$IE1E&@Kcb6Qo$5v52tNc|QD7A;jjcYKBWk zeqIbyRKF?Puodm4=6;(2IH93+Ai51F*~x2FM9%-4@3v^QT)v$Z8{(g*gFAW^4?=5BNIc?1pBxMxzS>gR9@VH3hXI2Pl*) zDo@FnXP867-w=1stAP(07#KJNrpL-f-;2IC&%Ea>Q6U(uiv9J=;3NpS6ScZMj{Wor zOHNy_b`yC@ zG%*7`))1S=o(6%t$$~5+t000d*pem)jwYKPR69mcK~^&)8pb*`v$Dg1a@CThyHagX z4cLj@m4?%e58Un-&uLIisUU?VzJWVmo!xcQj-|=hQ|+QtRibu-)7AV2c$df|DH<3K zRt%%V6ZZ$&88@^IJ`iY4B2n*<@cGEPWTUZ@r*dU8-pPj+xw_c_=^m-f3%=N>r66&} zinm94hK{3*RpIN#se}oY4fSPerOTWH!VHDm?z4yv!Y)89J znLk4<{zq@8{ez-%ZT`e`yt$fpXHF#ZQ37a8&O=+WVWG4SBP4)8)I00Vv?gs{zn=mZ ziqT(@QTjcvxZUo2wgZ)l3FDMA(MV+_84H!RAn&g)&@5)}dUi?$5b>xQ=ec|?nGr}@ z!P90|LvipI^!ogLe&+RS{*oc<&oRc?K1eLbc7@>4f#Rtwwb$d7BGYlBk@v~xd-{$Z zpfyq0;jupDVx1UO^8J{F4gJS1RfMjpq*2U-{U6v&5)h5L} z;fI#gD`?SvzNutaD7QLCH&b$|P&=OjH|;z@U^c0Ck&UaS-2?6-MvH#A(;Y*GY- z6vO5a3C1A9+Wa96o5l>`V28%rcikg%7~JD!<5H3HL7GG6AKmf zJ-E3ahRr00dYGcwCEe-^gj5>Y_2zD>RHB~7BO1c}f%v;bjQ`Sqbe|Oe$$v}bFEkE+ z;kW9N>Vi44`CF+;pqTkPQSS5KQE9O`fA1q@{HX5ll)7&he-yDM7b^S3IO+#le$E)> ze^~#L z?1U&;<{T#n#QtO2{Pigj( zzavxH{mq-CxAw`DwQ8+rqp4?$#8!bc>Z0`dp!;RwZi0sd6LhwF24q8Z=-({ z(?15XUFCQD>tIF+#1MNDWNgY`5c%6if^S{5YuT}4AQ4!msT*ZPt0)7cU>kb3+(}(@ z7f0M})c2|}MXWYag!V&!9Y7#)$y3QjdM{QZyV+8A6&v(Ehe4l!n;Z2>@CJTue^MLS z=sX?7GVErxE_35T-R#o;-yD=T{tvrx-yuBx#HnYV4uzDYsmu^3^0?ZQ3@8;}Wyz3C)3_D4PT|$9J`~hTO0X(+6n7 zy>MOMXp6ZKxhuX9(-h5C=7A$mlI)R69}&8+&b)M=x&(Y^9%D-Cs#b8 zKkD&Ru!wvuSLrjOh8mNLsGnT2Xb#MIAv7TC2yH=Zr&nz=S)zvn!qxG>6K_GNzz5fW z`A}ETv2lWe8inB9Ak<@7a$4F^zB=h=^8g5yngVV-#Vw{-XSsfWY!b0lN&mT5p{DfO z_DVv1Z1vDbXu^n?GrdY(bu$GP?!F3+WLT79IcrKj28*sWFvQ-<%UcTh*CBcBV1Eut z>0+oKrahx#FlIBbvOp@XUDQ-i;CZZf5`JrilumA%yL2uH%zIm|EfL%t15gk6+nbt+YL^rcQ+LR?rK0vY1Ky`es;9|W+B4Po5f z$QWp*7_5vp#FYSWcrv}aX03mpw>L;|2~^0li(e^_t?53aC>Awyd)&S-auzxQL0(5t z@g@mUs3#_dtS?UAMv7T{cdKJvzV4uSa9^}Nx}wn+#=Pz?G2G3nvTi7Rd=oob#c;J( z30|U~CJWrc<%Qn}g;xPy%)1vKbdCZ@fE@lL&qx4X0ciH-r8>53T~9fshw#HK7knZ! znc;)pZ$MTAtid0^3_rPR zq8HtCDJt<1Bypn~06g&&(bm=JAYiK1Ls9<(FUJh6h-7Mm!0{8!SDQb*Sjz+s<9aF= z!IK6g`%Axayd^VBGAG0&gDVm)@|Sodwc);n@=ug)YCEmD=x$ad(6!M*S*Pm)Zk{pXo8rm%*y`avkvk?Ya0(bVkMn4ZigB9m;yxiLO7wJJvXB;-E5NG3ouj`2VIxwb8y7X* z=CvPX+M1(`n@rTn6BCyj7c^PkyW$4ycd|*y&tt6}Q++06AMq=hxb1>6DKtuw%}v#r>eXYfSA13A%@6TfiUz%<=$8$r zR6u#$Gi6FJHa)ZnZ!Hut>xT4gt;%QP27C4Mt!C_MP`wn1GMEj8FW)&5R-58FYf$-o zvg!M@tC^V1WZJ!jBP78PO<5XB&EP|s=9TT`NP>suXuxG6IGTD$a0Hd)8{56ssyjWb zWX28pC5UWdE1v`0!?`wlKIaAL@D<_{T*^P`N}hvB(Cct&9B4<()cJSq-2o@}Ut!^l z+i+~_+8#E7t}4`3a(B5Z;f3K$yT8*2S&>>K(@Z~o>n@{LuQZC^`_90FNBko97UA9 z0?mU5pRNsnf%WKv#(MUnI%^YGb0D_p;Km`y$MhQRGi%y>xJogsf&IBGZs@prpEut{ zUH)c%)H?BEP^y&$U`cxzhy)0|9tUk)aF#2ps*~xdP!T@IV&=KEIA1NV1!HeO>Wc*V0eZ*n*9` zPDK<;Z_qV)A*Dp#i!w(&GvX}XI1C?$1P4^F<@hxp;hr2;T~HXGAJAQ`>ll%2kG_I7 z-)u4mh|klfUTA80e2;*wvpsLq72>(_aE4mI6~ zEWfh*#cF*qL2=6!t|f>b55_}%#bL5T>8A^~pae6xpqN7`9W+QtyPS>EU9y4kXW@Z& z;4x>3kFz?6L9al;w>bK|(BvxNx}thejkPm`E=E?1a;$^R`|RoEbTV<;G>D`T2o(c` zaVc%vOos0oT;VA;bL|#>i0fuIfZ3|WzFJT7ntQprJw;-0AYJAGJ_mR8>(Lt$hBP&hVs*FYsM*_>E#5{i<5VE1iCs^ks&%b*hndR#ch9j>jX@Op77m zYX284%g)|fkT0%?yt)gK>TjThhUdx>#cV~+AtFG+T9M1M`JzsZw<=TmxA$13CyoVO z2ZOXKisEr_c8bT7aVC^I)>oemJLw)K+PF_H)btU!;<=hqW9{JnR#*w8YB*@7Q-sPi zwWRy4X}kv~b6fPFR6_RM2!*Nn-5VLM1j<#JyA=q^I=Kypcs3>FJ&0bQfz&mgDV*q z12>l7cug%J&(JPvfG?5i8-B}u`lg$C8;Q+wjEa&ysjXEN+_a-*X)zT%$WQ4H)fCxC z?XiR6b!~6C58IsjZ=)d}G;oPNCPq+oU6fhYW=^4SEF(C4ji#g!)K|<*?~Ive;!@hvVig6%O8nn z38$1v#Od$`Qzrh{pTD;Dv7xw&|{iYH{>sll6;%L<)ZvIGh=MA$-GYupt7#o zwpu4GAqh-~(co=-L8@&-Mzwunn+hCmr2NF$=?{t)~DTayl1Zk_Tt?7>& zs3|^%P1PL9ThNiYy=(LKSOP|9OOI$L40tH3rQ$AOeiBBiJCu5mvsak*=Mw&QL6%;m zmtcpk)_-xNYL2*fE1Y!s-O2lp61>JO{VPK04?)ler=sEX$p5lh+w^SX58Du@WR|oX z<@`$f_2fj+w)~NNV#xF;3jXeeH}U z+yTS7hk3q7*AI?m6&7}L?(R=sp&4~<-0sz^>XkW}zb_EJf2U#noRQ_h6_x+L+aqP$E*t~D z7{l_!6$^qjwb!?4vN?pHLmvf4Pqpu62gFyK7rK-X*yC;%#R3RUf-r7LyV)JNE=3lo zg6wf=^OWcgUc_!BGnmB=2P6v@q-=lrML)gewa^1CkzQ@(ik5*aGa;vXj8IY)b+cO~ zA=(U?q!zWj;YC_>rMcOwTO?w8B&ihMI1uNSjGcK;{-XRt&-)pu-ujo>vK=4hLGjVk zhEc?6l0cpPj)*CZezc7^ix$Pm(5zkQ;Ljh{`T2}mE%cDD{-%)=ZH7dN!cinI7@j;P zlU1K9qNo!4Y)3yD;PpYmYvWZu_4!*g5H8hq=~%nb+q8TgTW_q)5V^4-ntz#c>D9l( ze^vL*DW$rfRO|j){hT5qM?UwGy%t8RNW~Ac<2=L|q>7ZI(KHbPzO%S22l}dvT6YfF zBrSFAwF1@5S|t^mtm5>b(%DFH>4&@2^yLlXK$=eX{(G;;Np%%)774MKnxYkrP>q%YG{5@+3+S>Dc^-~U0{`1b8CSHjHY zJr!;ce};pI4H5KVe$9xi%B>|H1QAleAEJsk4{tpbZ?cX#^+X$#YuD;!J58>DgbiZ69duYc@}Bo7oZLC!>H(sTFpQmM}0L8_Uxe$E}U*%1H7d)JyRLKoFWbCh97TU zll45(O9qozG5Ep=?S&&|p&7e|!Zfv2apGUmvf)nnPDyOd+?as~NVKq8gVf9yIC-4w zfcB)me&`Ml%pla&XznHO=EOy8g-mf|HO;j9hClk_#G(gUHV&>7G_-Jhvv_r-$fOG& z-Dl4Auucw&?VSz;J90@3HlH4pikT?TA%O{om7paFBDONIx}1Z2LY%t3%i_*7fPJV&N>TX*bys6ThmM(-|#F( z#7{&_GqUKC^mfC$S4ER^eG`Y*zv#R%RoPm&yhS?On9oegZLVooHenNb>nXjixW_KLuiE&)tk&n7+U*q;EFmVl7LQ5IkYK<) z%7)Qnn^3!$*_fAeQC-0AsYOy+v-T9s=E6_XI)BnSZ~4Gvw^a(r5;s0t%H|g=+^fKh zO3945g@;INdFM!qhhqwcjJp$dvyuA2+3`c7|ZH-aQWouColTnkN$Wk87b zXrkae7bYY67({XRaNICxZC>kJInOVQ=AzXzDWD+YNI?yEq#!bo!l2LK!!83q0YkdE zv8x@2gFu@OIi;hLvQn0xdh>8zr&)M|%UmXqxX>?=U!|uPfeG%67R@dPeP}ji*yuKe zeKJ!uron~nrD*QMkQbd}v&8mbJLQYlHqfk$sly)JI(n8weZ(Nf`W@fY>?O09Tnqer z-|t92xyg!a`qIDtjjTc4V<1LFLCw9f&nw->k)Sp- zg&X$=`|>^^C#NZ5iA|A7W}X@;@{{0M73&@=D;OztC)A`<;wTEbh zQ=Ad=^A=Xb`etzD@os_rtF@UE10(IWT|VKHVYz%U^$X>vsaOJ+2Lpi4vTpFL>h!+L z2cpuuN4o;(h?pnt$sT&M==}+ydV`F&Q!R7W2=s4gErWQO4n697;(ZR1a`7riYQTBt zQ+il$+6bHl#|^u)6`%LOgC3n8Cw}32Gk_0GlHLX1RBSix#YPHY=g!|j8QX^0^PTpG zk6-kG*ZqK_pBn>7zxNoh{laGg@B}Fqj3_j;m{shh=yVX|inYtglJ| zhlU&hz1WlaCs|*knmtQBCf_ED^Kv~NPxlBG!)|Y!%W<`AjmZ}#b-Sw9D4en;@Ko-{ ziu5afk=~~yGavhk3`ed^Rd)q*&`00H_q$j=4o*!%B}rlz(D|j(I!f$a{pUf36_+|8 zp-=#QKBD-l6lSMUGmMXTlb(5`StC`E@7rNfhi}qLE{xh$xyVq#YinPST1Gw=H@+rN zJ7X;zmR+4KDd3r!&9mp{Y9I$*k3?r{oFqiK*$()#Tr%c$o@kAE7$?NvJzuB8drS8^Se!*}Pr5TrV;=vcL&D#_5M$MWA6b7H)fZZ3- zrbsRZJLsDB{;>+BdrjP#yC_&X)XV9lf6plhic_lZ*h8_hp7eM{z9nt~;!o3J;vlb? z7yj)RhOz*3Hgoip@ExBh#G&W;1={^1Wh!>*!^;S(Yge{{j%q#gla%C2U3&tR1s~tj z<>X6G!pkYvUF1{}pd^0aW`3WbPI*s;?4_xg009TrgnxHRd7!Luk8hHuxX3ecXh?J% z1URHLIuJ8#e7SHyQ--75sbRTMBkcDJ<7(T>hhI-}Kn$yzIkg}qB_cmceel+x+%SEX zHfon{$i?|S=&n~W^#`#-VYw^=O1cQ<2oS{;Ig*P^0M{i(^E&2}v_!fq^H$C~!nYT8 z!xSs`G%1QJ+=qXH$~IwE4nxK1KFI-Kfe8x^7*7d{w4Mi<(>%zi;Rj?_T7L^4@nJz8%f&G4QX-;r6NZ|Xl4^!8$$^$^pVFOu zmG=%WU{kLp<&hiy&QklL(wRS}dbm2A>)%ME?CU1j_0bYUj1Y><9KA-KiR+hEhs85c zcYRs)V*jj_8o_ua;-bIq1gare}?7_PTuj((-{I`Errf%rR;jb8)Qp zYw8O}r34!XQNcbzd7OTmlC_0fi86LNq%=kJ*KGD)Po7LgkOj@=2W&&kMDV@ zovgpz)tZrkikyz{zV#NfokTcQ?P(nD);Z#w>qX+rZdl!Q^948UP8T2p5ai5&uzWYA|3Le@K^HiUpY zPsSO6CoxZpp8Yrh9a1x^rdsIPbKxY=eC3p!@59NgK1M#C_7t$BT{;#del9pg9io!I zS-8kL)~@k!6CFQF(hvNZ;_lnhTu0`FibQoX)2Qg?)DAUN-ZzEZFCxd5_=O>e)h^_X zyA(Vu{Q6Ujx@y;zfJt_7L<9sN`5>aYGLIj0jXa{Y2PE>L03!)hzAe)3P;2x2gvxu; z#G)4S^A$OO0P4An2`Fd;xO8t3P2ZXL^SO)G54;pN2DASsdXD;kmmw2fhX1bjXU_kr zvLP{l!sP2+OR&QDSBjfrQuIMT$Qf>ASkF&xs$}$?M$~SWwT1+_?vjDf)D7031UIFh zMoL$tDEQ*Tc^pCm#mak4I^?`p1PID1*%@UojbQ&|WDoSm}J>%!>-4QpE}-EX%s zyfG=;dQro>sA_#B{k<}%aani!%LdtkIbHysfD^_Z6_#JOclUm`RclvonPw4Aq%8={ zyfw=SKyLt&ct3n7Z_eOai;!WmHYGFTl%hBF&#N}}dk+XaC(gB6*~PBA=B>=QYSa~a z|FzWB&h@AtceJ9SIkMbQfDFJmSX6%d@Y}Umq<7hI)pyUW9YRO=f@#Y&-*wVNExN@! zFI13HgNhfANN0a3FT8>)g&~~>(Zj2t1M?cgH+PO~v+D0twQ|Vko3+d}&(#BIJdZW-CwXYrI4lss z%3EkUKx^d=j~jtc%Dgl~%c+BJ46F6CF77pB$g8XGUT)LJl*h$YVoT%S{Q`DmTIjzY zEnYqE+@g+;0s9MHK&Sf+hY)DGPwG5+AETi-V4FI3bC)lIB}1|YGAWMTkt1@Zpgw3; zX&K+JWIo^xgHrU%7J})bvs2y4)*>{+UP=iV*9-|i67P9PknASOa3xlmW|&{wbuq_r zB}b{aLP8MFQqXC=Em|&v#-L*J7jsNZP$jr4TNl>Mu+TVV07st!cL_t=8LS zE5BDup<|u=;~gHE75IKz+mf+k@Ota84Z}~!-c+REAX855#b9(_^V=|4dC?7tZ|PK} zBVj$>ksaXC9!Xpecc1`}Bj?@txs{H7 zZz;(-U*q$3O-h9}W_qwYFT`n&hbJ-68AD*Rsn5J-Kwey)tv390>H_`@sPsPf^Khg| zbX0vOjx&+zT1DmH!k{rkB8$yT!tmgOj-gg9yEUy|rO+l+p1s!xeL}Rx6z90CM z&Na3C7@kM&4ZqCUaZOCG*T-{n&#YFT-VluwA##WpTO|BU9bmS5*_fKz=i9nS<7_sy ztwng>(e~?`!Fte)JDh5`XDSoiw&rb~IxcSUm1wG8rZ9_aIjRR0_)=Nb5x@wko9U^@ zDzO5;YQr$bXkxqI)v_NY($Yff<7tS2i-Np)H;Ys+X|0?xme>Z#tigYyq3GU-Jo23_ zdSzeGykwR-I~>qYjKg3*d{MoBXp=Fip%|lP=xH^l$2sz2?X_sJPdh?M6L&eJLT*L> zSTr}Tr2RxxK6XR+kW*ww*r|?sJay6Yt!rq;v5-p}i|}Wp?-zp9<&%3n_nN&}?Gp0C z1TwwRS9dAUxWOd3CJe*bOPD<`E2N8?0o4U-(R~2nf_i^h8z-s8N{@$6WSoTET{Cfo zPVrlAYpg=wlwT8J(O|UjctWqv_h@L`r;u>Ss$ecO*R2UK<{I6%>$zF0dWV z)y5m`w^Z)Ob|7RHr>uXVki@W0O1cGMes8H9Q(6o-a2+Nla|*$X_CDd}KH=0;0a;*g ztMIh7BHEf97sLH#FYF>#6-6~eQR^K`-bt=-D2}gN*`uWkl^y|8ZAXHc@)2#5FkaPK zJ~sxSWAp7=p&^cr6tbZ?On8-`fXN1r$w0?G@t~mC0FTja!MDsdx*0#1#nlnq?mfxH zwJu1{WVL@itbZqyvvZL&G02<18N~{g!MLL- zG)g7SBXeLj{1Stv!qV1Z=D-TF{~`LleI=*a_M-E!`yC7vwVcD_Pv+d`b;e$EO9CS; zV8OUa%m(lM$W$bGW=VQjlO=g2ee}ZWYji?+{QFpdsD8oJ>vORv z7?n$dMM(iKuNk!-4bbaMyO*#U#j?j|kW!Twc>?8NRMR}`+c(W8=J0ySN5U`m0(e+A zi}UJy0fVtnc=65gdoyK`YU4uGCJq) zAJO!|$+hi0iIf54v@Yi%b5*UA4m~3Ca~yk#-zKT|QW>j8tvj=O5iec#afIfdxCge$ zlH>JgW>87Y$qjXvVwPgXIB$u(azWnw4E@0-n7KZQ65XRH+n7fGseMV>Ov?M^(iGCv zZ|YG+hG*q)TCg6~CKM|(EC*;-@;by((%;J{4UZlG9>ri|!LYEiNh?Yz^TA3OTQzXt zb(iE`*=%1w$N-7{g?c*DfPq2j#*<{RnVYk z?{Zk@PRAK^f^C9FBy%2*mx1tG(_I11J0j)H`ITu2#5wAsc_<;{53kSnJyOWD{Ksor zqW5xH3fLy4bW_SHuskolZUzhr^K($bhPAEp+chc;PofDP=0;V%qGDtmVZqbJqvfq{ z->&K=8kHi$aTFN{f5(p1;@JjTwi+QV)&S)bk~t|M8j5qGKiC&|vSG22ll1{_&R#{ZL55o*lIvYJxmG~`T|M&0ivure%;Y2 zTIrJZ{s9&lJ%-Z}ivwv!`_p-12R36jMH2=~Ha4sq)!NN!Gzo@Vl679nfR1K+iFta> z&i9Knkr^sFCtD*Q1j} zu1=ClS8{@$(C1bn6N=V7<7;Qw_qP@0-?kk{vyr3Nt>|~1`r#V3Eoy2h#f+hu!J&du z`yS$L7#l_X!m6sAdb6&MdDf2<>481+y|eA@ZO6<_p4EKFt2AD{ZV3~*+%}T^Wf&m% z04IWZc5^4&DdR+rsuPoa_;l^pUWC8(^kpA+k$B=-keyW{A7r zq(VZPs^MrtHO$TlAEO@P^xa;BQ$Q1^M&XXdxaR9VIv3{$WVF`?4=2mtFtf4J z`k`C8r-l&8ik$2WQOO8zHx@L-#FbQtTj9EK#d67w=;UKj=E$*?;54wot+n(^T)l)^ zXV{Nmpl>1 zn=^pEi09RACm^vJX-!Sd34**qZK*vM0~fkNt$lde#G3KJyJr@CQzq^)9_|0g;!!Bt6VE zc7@fv_(7G^xKD5&_t7DC3E?<^Y&3pG{=!7w#(5hsjF5MEY8;wzW=q@jech3<3F)i{ z^<>Dz8rAee>#>hy{&vOwV}i}O`A2A0ctG&CarWVF)3X0ok=Q>H>xcQ^h=0R;{({~7 z8|L$TtD7E8qWLoBH-HX;{zLpJIQU0Bf8x6G53Z&-Sn-d=7n|l^+PUfd&p`sl36qDQTN8I`f&zss(8VPb{WnmPZ30_o%Z!uV}QPTTMBW@FrRU34c2`-jZ) zFehNtT1+DEx*YlmT?PL6kgR`I;oomtRsFM+|3O0veN6p(JjXot$ZyBEJerjBFKs*M zjkp}XBr)SW?_HwyxfEF}nk5~wyS_w!a6pbbY2|*QA4n*0e9zo?S|i|!3wM?%UOJU0 z*pI6S3ZMw?3QgDgMw-&hMX3lrENg5*n47p-f}_RTZ>KGI~RJE zzFj*DTi*Os&)GgZ|Em?W{{I>Tqz`hgcP8L1tw)~G*zl)OK{t47S*UVSOzqDj5V1aW ztuJ52O10PX9Ll%!Clpv;D^=~3KFb&Tuy8$nn}ptve`s+*)%99AZuqarn+9#B4D-DM zjR)@uw^`iS?1Xxk8k5Nk+Ycyb4yxI&j^_;2<~S^fCnnq;kE&dakJ-?N4@cvj4&g2= zqr-#lImM6Ol_a%N-9$vpVV}3&lsSAJyQq0GyK85a6E$c*B}3*O{b7UQTKiCwIeOCd zRM%#-;3;tpiC&1B)uIMa@lM3+y>FTLjxHF&k1@9n$dB=)zj9E3b+>gRMwXfN?538V z`SBn`OGqBw%A0>82d9mDyvBe_vPgr=>f9yV%4c1B@=~kR=FP%eTdfM>f;6RQG(e`W zBJVuFT$ox;kNYn24psKT8cnM1mbY(27MIqZI2N6f=^l}_vwcdsWA1-%3UgRm#OduV zymi#xdqDAfyIUg8lO&b#b_IWDjcVLSSWM7`4xk8byD)}uk07WHTq0c8g3t6U*;En=%D!i z06Decz8u%S=@eT5ov-e>{e|(Jm$cw|VP_f&^Z2qMm=zi*5c-@`o)GL+uQcq_zoi~lXSX`@U8Yf>~GS@)f*%F=Jq zk{n)h_5;Rob?36=xm{?gV6mNOQaRr&aleegqsECuZmzXO_H++lsFVTJ`H|ikUyJV* zztYaNzLvaS9_0tSf}kqGD@h=1KZDLxe>t+D%)~?33*?Ow)(Qg`hZt7xS`3&LR88u# zPb0SVY(GCyYkY#06IUs-Ueo4p%lC9iO6vYmui@&#N6>#8OcFjPD^%ndM9^21<+l#pCI_@p>S5(#FFe7yLea0aV!(3D=N!dTMf=59hZ5 zs*P*X0LAc}JNRN~A?4i|+lWL^pzGZ=+xbvX;%rG&XR<-e0lNFF!A;#B!-E};wgm3# ze!!drBrDEvvq7((284U;{KBYk*&=-MQ@#pK<-I0p#E{+kJRkgWmX{E7kbMI^v0Z(x zQ5h#BXjqgIeXb_SHy6hJdx522re2NDqqmVk=yS0jN`yR(?h+DS!zd_USKqDxb3W1cS0!0G}|3%^Z(_*uVQzU+M`uyHqYQ~g3= z<7YG=wTE(8N%lmyxIvPIXt0DhHBl}msmywqYTyV#w=EnmrrZAerR-M%P{nzZc4I2Uj)AZ7Mz?)3{j_2GCoZ? zs%}cvQo^4xt3DN4Qw{|U|H3$Dq5xNA#Tb8Z=^JQJnQ+y3!XrxdEDq+5R)rnsBT?^H z1z9Up)#bUDBcPUpgZq)3N&JBH7+hj_aT=+md$W?zJjuQyA-BR;#l2xik=~nkP2OjV zuNIOoC8g#H4fG7KS$(QlI-T#y01DxgBSC4QL$<}K#iOujQ@kE~+UlhE3MbIyyDLlnAo^B-M!%!>|-a9Ys$qBG*4JNEydX1b+Z$ z7fEj@u>ogp+vDuykUzQ;fJU>ukUAcgyJ?jzs)r82iJ79 zEd*rTcIR$iRW$79regqQSv@fG@%!NK1z1WI@yuL9y_oWC?-C4?^;$dtZcvGANo7iN z6Go`I@uIe!wsz;~KLDHe1p=-~)pR?=!s&kooU|xmeLf_hMJ~fn> zhChF@hK>oIsl@Sh))o;Z6&@m*pBQ9xr;x5Zd7l_vx&acyj!2Er(%;(52XC!Gq@+B` zgXX)8QG5M88InbXMI|?&5r_kRaSVosbhN+GHOa%GJkdlczNcf3E={6hs_{*FY!hr5 zkxdt8j!l*>o5S`p0`wkAAhCBJ(mqD)&LBQ{r=9QX4s!!nOsi@ZD~pCJr>}D6Yw+~h z!lO7XF|hWoTXP2!R2o9E(?c%-=-Yx-wd4I`gD{nZ#O&lPo1;wkDE$#-qsZ&J6wL)O zPTy9e>nCH`NE8xydKs{*D}njone}{V*IDdVs3QTEE)N6+_$O8LSATuNv)PfL#x3d#!rf`a@*d;B%9HB zjWt?D8|p=8iA6qsQ;{8)*sNuUr3;fbM;QP$y}+`flx_PSK^FG6Yx&l1j=HJuBOyhI zKD|bMC5q*AM@PZpuc@L#b*4->`d&!$c>14f0&kYH*DZ@2`|zqshY*CYYWC}*RkdS>{$V5k$cSlxRmH>n|B1TiSQp_`s-osdUHr0GU#zWyfV>jcO5GI$4_rLWx%rN+Sq?indNQ zO|Ld70HH*~AhP~k*UI*HS#EZiPf7M{Zw{&tFf*&68K5QnPs3#7z^a%0q?|&umxrYF z6Wz)>(rj$Xb-+@Dl$h1Uk1~pH-zgQ>i$2#kd)D1QajrDHT z6w3Dwn6%086Z4QmUe-z$(`*`e``^l2iQu%@&8ngoT_9&sL(HVO3QCyp3 zW#!FajJ;nvfBe~3_n)#gqg_v_>5D2;Nlk|wt?!d}JUptq_Oyy=JR0!Q5y8RE<4>&i z&5F)ajF4DuicsbZYBB7k%jcGZdpMm0dWw?45k++@@dFAW3v=}}Ll0+R$<`&2Y@1uD z<7dX1TbODk#E-hY^9l;FhXOC6Fi;3!@Hw@AcizU3fOjKB_GA(4jgv`PHPY%`gkA{n zbT>J6oCQZ#^ye{2tb;Q5?TywKBe%P5s#hX9KanNFw^44^&K(#h=49#ZzG zXmSmlP_0H^n&avCUL%@EBannzqwJzi{T0Ii$UfEWWJPbq1J0&eBkW?L$b<&dststC zIo4Hk>8_;*P&M zC{rsRyr!6}-6}HYer<|zwy^6&PTI?-1yO~ zpxmZ^6PP4kWTFv6+rP;{F6e<@f4kV#%l@E&gno~D(IDxaUAD#am&F-vKu6oKnYI4t z$r-BwBHxI)o~t|`)jHYwJ%A+QTc$jET7~xib^@q9HYY}(7=1kK@b?VRw4(nn0NSoCojBGSQIvm@ zvH%KB62SNlVrOi_geV7U4{;AE?9rbX_e~#Nrf$E=aqO$a zWG#6r+|P#t3yJn|YeRrpDooIbFu{ze15d1~{(gC%0InCxK}>g; ztZ2VlBRKF%Rk$nv5QdF*qO19#OJLM&Ib!4SJBH;gn)3g*@%~>1a``{6`~`VRPUxqf z3rZuCcc!V-roH2|AYdsZf*A=RbBCIgxAG3geoXSc^jMFodyQVxi6JHY#UV z*PJb7FvA2=3k_ zR$PD(z7F%}g$kYZ6F_!+Vp86te_y>JnPJjjqGGIE^hSVlKCbXZ3oC2L{>*Obb!q(& z5F79dLk0VGb2Q_W?4s=##%(rEac2Fh<(~GlSlnah!jXw-Ta&!7oqd`gQx&ZSvPc8z z3;dr}?9V*{7?!*eCIfqKl{CbrJtTUz*#kDwQ?giOkFv+wY+YWAGI4eSlF+&I;y8cb zc5=;gbLnJCJ=}nF9KPDH2k4_{Y`$EbZ=G!Vqldae(D=+Aeigr1p(7ac?$AuCOJuD= z59e8)4U4($S=@w5s){cBrEZwgWhy@YcolF7Mb;zCNy=Ul+B*O03Y_~!IXCDRmfYl%%t1B+W9< z$`-!=B1;kYWlhuDeH!>tpDm4Mo$ymx3Stx@XsPOH9a1jn~%u<@W#y< zMU}jxT?d4gs(CvUGj|ieDOXo?^j$7xx85J{l|hw-s)xZ|WOy|xfY+iS?ot@x(T`;$ zyep7)v@z89GKTy+I~BJYq)2p;{CwOlPsJS3|Epnprq)RyCGrk9K2^|(_-vl=mnnk zI%C_;R%19(m8a`5+%%L$QF&Y^NzP}EO>=X1yrUm;?tk~(FhruqZdQeDdOh zls^7Y^0r{)4|9ik^v&wd4RX+6%Rgq`hyDEA)I$ZXOjF^-Q3m@a7>54BPE)rw{=7ox z-Jo=LW=V=*_R662TP`t(z3LgBnt`(3GrEXMxdz=12LG|%z7gzF5qy9E>OCrf#WJa> zPKR1Sv5+8DP=zIZDx-@(mSQ(DlkcWQD-!)JTDfASxdPns)+wTWFf2Gs#k3(QNIgmh zE5_}|tQ@;3X*{#pUdl$9+wpJgyF^IVj2K9~aa_6kh~GT7+Rg@l#NycWB_KbcQqLW} zd3~TgQMn}yjhA~D9oV%iwZVhCn$hesK8RXGwYD~5WlR|TE_=g$+)1v zv8hS;DnBD5mOp@nCGBBEMZ^ZRKK=SKP^?k+N)%oo{}w*ua5m%N=2!}TY7Gnmnh7@RQ(iNkZtc)VXfN2f``BYy3xKP7w?=@>lr_Z5-@9?vb6r&|O%;^c?3I-6 z{lxc8&3=npAbr%Lt4%a?@{7FCbS@mpZekIk1N<(ZzOvaP=v%TMo{|o{S!dD48;3=bDfOTEue2u-R|wD`6f9U6m-b zAbTADnioa*&7L9m{$%m3pFj70J^rU+rF$C6(@Dx1lE3d$4oSksqJOT!^oFV3=!c!! z{A%)Nmdhh&%=N7Xg7(?y`z4Rt_PVyX-=n*xKa%`;D2rJHUkLg{4i!ZR=HTSSwZ9*& zuCD1?a&zisjHywoHpZ>@Ujx;4zg-?6)ajI{3X)qMGF7Hqw5fQ&+tE;DwjYI?%us94 zN#)sYm?AAukegeG=R(P9=V`r-40QBo4)LRv4Ezq<{0f#O7mmSp9Y3=z7(c(H-mUMN zhm-eF1=vjLI~m+;epEoU&@LsS-j5pZi-QfGtv3uGTBG-_AS<<&iezAZo-;t9oGeX4>E$b|?~cI^ zqbum9DZ$mIZ5<|g_bPX+mUcIPN+tIiIR2{r%}(y~p)U2?jB+&8yO)+m4}_)7o}^`>2%uCBJ<%uA zzdh;1n*9M|Xuw;Jj5@CWg~62n{(6Eldhh8M(Rl^HSmq{k(6pm;xR!_>m4KX1mk2RZ?@1w|)PJth1H+#R*T!y_DSi_5;+_!{B;t zM=CX}SvhGj);$0cHNFzx_Aw>>jg#(jy4;4{CaD)=G+WDVl!em04O7NG)h%}3ir2cA zWE-xJsl`sTGlVwceY)Z^(^0oS*@zb-JVg{m2VkxIjP4`@Ard|*Simuf2Rl8QxzMLP z6A>htDCj)d~alh|C+mBJoMj@|H@H`9tbov+td z5O6FwR<}aN+rHxBc@3Eh6)n|HWgfzz8dM`Lo{K?rLyT|`zRb~s`F2)?1C!|2UU$S} zL2$`B<$T71LO&6a_~wjA0$00y?xOqt3&r zoN&*P|H*VG@Gu)4$yhx-+ufQ|UsfZn%=di{B2m3`DqQM-*6i@nn%&cHe{+KV7Vn?8f4M6j+zPDMFI}8x#@IV8m~Dk<$tD zzu-lGORg4@Zew=j4A-Aad50VOG-;$6U0A*l3W!8`y2y}|Inoy#>+Oa@xf?!L?|P(} zw(C6Gw+so@HcfJzzwB8hs4zV-Hzl)KbYs1Uxb{;x;>v@(SV6Q+0Z1^D97iMLR-Mw> zgi8A4?@=|snK%9a6!;3Qj;eoi|6SnU??Ho@{(@tL{XT$}Nb67K&iojkvs0(w2WX5x;)W<+<{I%d)v2|;lp!4u19V>76{(@0j=27M zI->pabae0k1?u)+PU=V5w3h)o8eFN3$8b{1@w`p$m|g6MH|@s(qqp~k6xC<1n&2$FjniuS z{Yj&$yx+%qw#+@P5IxnF43~#r44xy3I)*WdGCO01rkU(md?09&TtT7jTfxwRni&77 z6kH`Ntie-i;ltX_2d+q&&GFk8dY|3M|Ma%Vj@oIw@324!qJH5?+4@F&kT=AOGG-p+Ro`&Odgq_Y0#-I zHPd8zQCLP?dm*pok{eseoV;enC1ucX;3I2w`N~uTD+cnu$%Y&zsF^6&pPUPeuGK^Z zo_ALYV*sQ!1gHQ4;$`qb%WVQ=3Jq^&k(hG`KY3N3L%WD6fAWv#be?&YqF^y~|5bs@ zk{j{s&m1KdCp34@A{R`Tl0U4Zw2Adv(hS-RSm*lnS3Z=pN_nP!@{yjPhyO7K@DL=T zPEhjvga(^83uc!;iSV~cc^7dHY3y1l99k3gxEdn6iE$*U{7qi#UjJsMU4gBVRZ>G? z_&TRPWkVZUs~KqK?*DF{U2!3phQ=`3Sbu0a^aQ{0n|Zbh4aUsBB1&50W$PIT$j=Fy zwQ9gHT99%?^kThtebur-uneR0e|y)>z#%m>1K})RDx%KOWJnv4m`zeo+CBdZ19(Az ze^|+gdxrdl@idQC;=8K4KKN-~b{_YHoMSJ_n4R%T`V^b)UM4KDvN63fkz10(g(qGX zr~p2GW##gb{28o``VG3BjlED5}AcgWw>HfF0kmdF0#&+J6I)1^z znxT)v@LIk`l?5M37#LsZn-$^u>%z@}Nw()T5WnxW3o~G!3e~-=A)ez~TxAYGYdJN0U?# z!v{0mhMar`tW{3|Rqp`pw=W~+4S+m+Bd;68c{`$k>qWGvT1^L+ba|1Ia_X-_+kpkO zjqelAcU^c`Mhf_`-R95HB7Smj-x957) zSjWOW{WfP#nGt=@QX#e?aJP79svOyBFP`mjCEIE`1`;J)jEAVGQk~Clp42X;J@vwS zhJa*678k_dD*Lj!E1{z1W_x7OmbcTr(W7k~(+yvzE<{24Mg0;FAQIv$?43tDSdxSX z(s{#t4Sy@YS+Xb)s=dY)eN?gZ9@WqpqE{3Sk;Px<%^kr=j5G`Q7So_(bw*zRcI#GT zv*qglF~3=cf44ccK3eDGqy2`{2szbD{xg!VQ3&U((=%6xvQoZLQ8?F#)2Ww2K34hx z9zK27(y{7Yb6C4bPs-S6D{_h}cMYOU37m@l8axczR=3lqj(Yn;-+I+Wu$8UM`YK%z z#?y`Dy2w|TClWuu{9w|BH!RR8n{aLc4oY>dh1op~*z zq||g>OXT{a<@uj^z@$5CW>xEh*+5>vVdqL@&xOu=6nlhB|LHvQwh}at>=5Etn zyG;;N+=eecpA^^XR6>h&R%*=|e!eZO+H1?tO<>2iSHefb`U2bj%>L6}+4dP(v&hDD zm0p&o5EPKjbz!mp13I!PrmDJ50F^gZ+{nB;)4f;25qvUryU#^8*U)3ts!Y#-8w=Ws zhiXZsTBJ=3x_9PFs*e}csk_6Qtk1n?GvpbFN)u{gT;8!ER`fab2@KG7HK5aoCN|Z=ZWFYPWjtNR%1?^;C7O^Y+#*pm*zl-p8>iWQ>|22=#hL7jNvN zWPu|t)`vLYeITiHtzJIl*gB>nyTx@s3RqG^ixtoE!M;<%lU_I-wNML2QKZFDRqfB$ zJf+uhr$10`V(WlwNGe=~d7~Y`%RpE@1msf(ToR%Z1X8E7vrfrhU8=bXd$AYWs-&H*YBP4CH|}_{&YMwoX=*&dw5EDELPMLbrW45uyY& zNg`S?4xieZ2GhWu1Js_r{k=20Ja0K`MyH%avV~sc55qnTm(GtsHvtos5wQN)SZ}YW zoy}a;wqTk&q@F@BPeS)<+wMJ#YQ3$mj^xJ@)t9)Fij~r;ZErc2`I^r))plPJFL@FS zMy;uajoBEf$RR7j_ymxg-r`qwzHAQSDl|7%TKAdOOKf{c9{188n9)-Yc--5_^a;FH z&-h$Bjt!%TNaLwl$Q1e{A}AKSnPVz%W=$8vAY{#m*@hMJ4pLDuWndb#D%78*4QMI& z^i-VQ87?rw zwQykE2Hn)7ogA~Owfy&_JfWaNZPf5|j2TIN-7LDh^Wd)W9&%p_gahdb6Tnw;uBqj0 ziHhrP5%xS?|HqotCVUfv!7H`<0w#Pn7@uu|Cqve{$iusOa7gESeWI z&t|(kSQ!gMMOjMH%-jA```m;I8AITFWYo|= zTKtm#@F(8827_Exu&KbB{V|G9r6OY0lr*)v0r4>eJJ*`mQs_`buhVfNc>fV|@rx*l z=e@eOeqq6I!{WQDnyty|b_LNd`OTMGMDv}SY`9Yy37$R-^ix!*zCpGr;)L~iyslX& zDtgCn8Ejtkw4|%YoSy0mBJ2LJQMx(ZmJPtTjpOWHr>52@n-hIM?Ad-`H9>Vc^BOQ# zFaL?!+)9MLsgL$}O!2_30nBZ;ao5gGH~}+1w0_CIJ4A~)HT$V4mF>#lip%5l>_%w= zI&(BdO#n9zXoB?nq^ghKu565ZTKfxg@<2Ya=bkU&z`$6?^`Gf9j;JfabnNk_N23PY`${%R z2?F*$>C-;q`|a2233!&C)79x>*5G8X5lCNN3ADN-&VQd`(|V7{RSMHp%h#ckn<6I$!T zNHtEm3*&uZ48I>oDjwv|<2h1#w6NL^9VUoy`N^0Zcfq^KxU zWe@w8TQqd`{VWE@XVdg1;Db@onA{$M3Ym0EwJT8-oaRWM{uMcuCN^}?(!=Z7MT^Sq zM84W($MDZ=9yLG)a?#P{vxE?yAz!*l=QTm?g$AIyuHeJ8AyX#1&yY!VfuoAA#b=h5 z#EEQtEbNntrzudfr;%oy#!!Rrr-z2iHr3jv2`T&8cDy1ifEq4G@{0y|+4T|!>zlj?5LRe%HpX_clCqUo1akEbG$%%`nZj||+g2t%SQ)=VuD9O~7_InGrSi52v zOQ_&r)Gv(8plW?HQl;-JLDfmGHt7lq{QYt$t%#DE)V833b~$$@SBs(fn_=$joA;yRc$=&^!$WV`GBn1!X!->)4-u zD}8AP0W;9TziClie`ryE{Jrl;QvZ@|VTyTw%ZPdZ26bt-sG(6(t-n!Hiblh~Rlv8M z9RJvVaY&17es2AKkuP;b@VA0^&*&eEGzp>gU#g*&gSw{gA1U``3G|<+R91g<1kA*5 zJ{VfZ-S{KlI*5mP=%UVy?r;L zE<*spSbRLaFZP{e$h=7QzMs$x*;MFzv@9#Y@}P)29`ZImQdum;|0g*zS0DBcBY2 zt$8MCH1b<}eyjU;pbgCAKLB89f4{2skJ75;eNXvcpI_`xNDjItA}Tt6U|ef1_vrr3 z_xdzR3}w%wSySHEp|U8#`oltl{bbGqUi}O5<(*fBmURzqiF>QjVz|n!`Ykbt{XdrG zM&)mX`=4p5{f$_|3DZYP_u|kLfrbBGot)!&42N*=1<+6XVYU)->9P8=~cZvG$%(O?B=1FA5lxCP*g~A3zkO_b#Fo>AfQeNC~}HrAUX+ zq(kT}G(kd@-g|F>&;o?sJAx~zr;;($9aA@uLOF3U|;YVmZ`(8qFPru6I~=#xyxxdSG(#?8e$>-Z+hq86?WVC_|0uNf~?p zs!;g|sRa})s*getdu};$<*lZeGRKy~?fma9y&qq>sr_{Jxkg=eJJn=!bV5b5s_M~) zO+6&_JbHz)VoprFG!5{n%HIF_)um>ZwP>eHQ#4*Yqq9>Nwudk3pH>iaSoWTlyE!Gg4@3E@-8wJgUOv zPQ@9HbEA>`n6@zfw61xtZ`<>;e8fKDW+s28LrNZ0R#vAvH;-kHm+wo`{d!Bve}91r zg~4yfEGWjAyIoXv>WIXx3?$?v+b zyWJj>lkH~>VqV84b>W@(g+bOM{o$Y<2oQ8xGmC`COy`5r>|kl@y7>Xw-xh{|Tng_i zqt5%p`>+m20rSWphj8-WVc|fBMOnS?TI2Wc*u*B1uj%iay!zt_U|d1cc&weaKdSieHvcu=ny8SZRXG8$^Kg)>CZ4K$tT@EtQPHa&7z5Brnx`=m zZw-k3euD2bs$oKskB?2Cg$d04j6g)vjev7yMEow4^{){D^k}QBH;F?q5?VQT=J#06 zihjyzqS=@-R4>X+ee@2;_DIC+TV-c0DbaUEa$q{KsBqDIM(`tRArO9F#-MV6i$tnW zTC*u+Eb{P`m4rq3BmeIT1T^YTlw++Jy~EKH>+ezQK7KYy7>vY2?}-rP=O<=Y$<5}#m%(Vh~y-M>_&!!~Y|9WjkxLUMs)xox~3A<5whuo_`t6J4hD z`b%_Y^29?^>N+GEUNx?l4~A0Gs1xCN8~U~L1PE$d<1?%4+Y~@8^6ZL(Cc3H;hC_Mn zT3vF3>-Lt7&nSCvm1VgTtBnlKJ6M-%8!T@+{AS!^YZ+pALVyIGC;BdEmyg138Y*Sf z7?O5-YI>gW?6?;mIy+-J_mUZi#)6_JOvvvElQXWOxBWEhw5D34h9$K)g*qc8D=fc* z@$jKD?UF^S*-3vW_{6--2d_LUI3cPivf-Ur$79sI6#+9d4WW^!j{xXy%DLMYL9M-4 z+cKryko!-|6aUQnlG{6B89f$jt72Ox^&W;du3B4tMAdQp{XN7-5KdWOnIe(4l&X7h zZ~-{3IG&t%OR5%+GdA+Eu>bNWSog_f%RkE>`1?>`cu{m6S8GWpv7Vh9)%JCZOwEO+ z#u04tNbILjT-@mR0Zmq%vh;0;Nvamvw3NK23s?wM;flp(!?dz*_0hnSf+B|2@do;% zS+=pEpWpOO@98g$!AEc)H5s8eg$|pS`Ap&bwrQ!^>vuEXcx&08@mDDb#3ljJTOOoP zNZ(s!rVZgas0dt-OGIFzK|p%-98V|@EbVn)MreeBn@qE;&<+_O<8LSl5Ipx?#C8HQ z3Nhdx;xhj%?%)7SF+bxE{bw^o5{A+X_~*2HC^ zF{O;t@8nc7M-BS! zUJFN64@=@Nc=0+;?A!&dH$e9JXtRszWepkG+oaJc+pM3S*gcKv z#lWK@Xi~mec{L_$Ma2vyu1a;QA9S(B60DA$Kh*jB2h{@>N(981 z?33#!SKrB;{8X<3%zF7IYvFfABUVL|#C8mBhpw0_&Pw8mI0#C@Dh;3?OdL&_yd@pl z=mjGaU~;N_FCLJ`h}$`lC7$pp#5D?eM?}Nr?qF3NelV@`mkJX^oSAt)xYZ~*zM*Sk z&tA+cZbN4@`XhV|zMj;^=&Xvfj-b{<#K=7`(oA{nBU3;5cd0ZI-Q;s^~*XWvD(8=MX*j{qy^JI2a;Uy}if+5&<+$X{ylc zhomzziPKvII*H3~fk1S(%GB;gtsRX}baVdB;uie}NYa1gE=l3i{kIO2rT*{qF2#Q$ zTK(I5$PE>p$V&f=JtU;$Y8Z`Uh+Fl+pk%znR(C#}=u`We^lqL_ z>sm;pI0GZBZ4lIv`ijw{72LcYd7=Zxh52IVfKNz>s8Z|l^Mhq6fD~JK9#-dJS8Q#} zG(Mue48{LC5Nkpp`Z7r7@jt3#s9PPyfoev040?XL0<)YvvC*$wEOC zcAxy)b`<~rXSCG-tr zk>K+OL~iw@*66h6gnH-Z3n_&{kR;`ZByu#<0qc_GuWi13h4FWH8v$Gl(8Z0)ayY(% zNt`Jh4YR_3GCL!z45ar!K3xd|b1;D@o1iK#(TiN)a_^K=O{1z* zz1?U-p4E%IeuUjk2ov7JoGqkE(3qr)tf}i*;C9ytAxx+r0(~kq$&Ieqty!=+8EpgZ zlf zMrWj_-6!K~vIA6illa+Qc3pl(9z~v;u&o33kNZ^1GBiR@ zrS&V~Mh%vXdb-%8=6HbSLL;8k$*Z0tGEdI#=6$HVYNRKHj>aY~h?C!Mad#2W0_g3~ znOMD=d6!zM^Ko?<<;9o_^BXCL>7*y|E5Qla=uWXbXB){4kX87QBV3e@+-qZ19xwp} z$N(aZeRUR!ruJQ2jY8hqW*3)GTeDaN210n^FgVyg%A!E}x9^+^IyA9GETX<9sJcf* zxbh&AL+IjgtOSP%xErUo;Qe}@dCt%CcrOo-;j)XD!LJ7V(Axxn-ZM#T%~Hiz(1dET zS$0wz7gy3sKo}z-#pfy`o$+NQSDXJ1@3BxJb(~+C&kE5>I4SRNPr#Xcp{P zS#8AWY~e0{yjn3ux>O4ICvgHJiFwvnVQl<`2xhKVmbvjyvlP($C%I)jUoM1_0`ex zLP)4ev&eVhHAkW)ba`OKKyTe)o@lE!ZO~Ru?5KH^6*pgAwdvCbK{fk3_66=@V|=^^ z1)qLK^34tlA+u1i`)V4g4SLpIZlTZLYb!pjs zl>#1xr5aq$Iypwo8%7OxZ^ZHJ<34~iHUt+~nsC->RaTFaI|pBse$o$|c}e4p+{owu z=7{L(iKqHpY_C^#tS#;?3B*u;yVPqywZJJzP`8sr_&E+ycxNllxjFt>d@0f!#tPFk zZ!U*G1k^WzO&Phx>Yeq@F)pu`yLXQ{z0zslP1{w*B~(U;u{BSHrKp@J{|Taeb9L6&^@_R05O|^)Aro8uHGJS;mUlG`TJ651 zM?*C-K)yozu){;qlXgVKjphjDg^TU`n#Erjnnv3Qw<56Dqf~1V->QZFoC%ff4?laU zr2Nhy%VTwz!OJceY`API(-B|!CO63C$sA~%gs^~qGNK6%72hUR)y1<{gDrC%!0O73 zP8W7Ut!|4M1cXZDWFV3mciTMP`wDwR1B^C~t$nSckb9^cr02GeySt19WC8El!$NR& zPf0CTg(U`xqBA7YqVVavY0x`(`1QNNac-}7Gc(dU52+D|HDG4^RlyZ)v-O9X5jG~# z_{P!vU?EECOx!to0uM*b$hDOq=?1|CTtgBwT5)+z>1ue{?GTV?u1s}|yQtTyv9`XP zdk+LQI9_(RheZ@XGI^boea1~bp)L$i^Lp$*KR`{pd=%K|Ce>7KATt;AwhlkxX%wbq zQ8Zoo)Q7_S)RHEjmy5F>4$MTo@fWBwBhcy7V6~O+sOUJKB=#grAqnFnz2SRxM_9&u zu2%4UCFNM%zc|!HLstOQRgP;C@S0Q8Jhxn8v0R^+Bx8?L%G(GjRRQn6+C+(EF&VKl zmE>w}tvqOSzZst`N8U}9m%q$0DtzW<=ZK`xp+W|eyL1cc(!6l-K#a8H^i;2dnVK1b z^3$qUayY&^Ln0nK4B&_&dt&Op20S37xxc-!${*m2=GKsQ`h`jN#7y*wsp(Sl;-3Rs z1v^5RAw_!Q?)TzrsiOndhuAH#;se3yEJ05{W3{{-p)|MvQ-?4E{Hk7WIE^tFNcI3& zQ>bu58J60^w-G~*$T*&voY8vOIViTsv7V_AmLr(wmPLLJ0%~qVJw(0 zgh6QAsYx+9Ga|Poq-1IqrU2UObR8D+5J={K186LaYaceMQrZQ+WOJ~SGjMhGn7UPq zoFsUb`2OC+c^QalQBTB&>%!K@RPgXfoRw|+)h45*=pN&WTBZg=%AncA>)mK;0XrJe zXgcijI;iKn3Es}5kX#xWc~wGZ-M5RMpQgrzGkDEGOICK&lQ?P7!3SO^vpd$Q z-0)2^L1a@1<#n%G^#w(z!a+XTxJl$5!*2gfL{nKxt!TD=lOfv$4*c3n=xLEv_pTpK z&+GevF(Q^|a)AOi4cqDi-c_X^-cKd9X2S9kTE)?IBo7Vib1~am&@6I(YiQYa{#V0- zRClYOaFJ57{bM~{k;Tj7?#8EUpJi@H1I9e^>$*q#q&{wcaBKr0AT4{UR19)7nl`0z zR4tdfRnho+a6O}_nE>d9M#SvQ3yDlNL#{@I0K{w@_8d@r} zu$>Enai~Lm?~VAhvbszf@7;*-(eV@AW90364a+uYA)d#S35{v}cZX*NoB_7@gRD zk(sEMAb#&-bTB%#Yyl8!(VGL{>8;NwY?uf0T&)(^v|0PV-qx~nDN5Awh zW$Qme*5B};zl~}FKmY3@kg)&22YT}_tPm4gIQu`bLOB0i3pevOc_?YWJ^Ht~&7X87 zR)leZ$wI%L8y)|5Y%_1;)Mu3RV8ae~)Pq+yB=Y4-^f&huw)(g4IfTvp4OXK1-(aPL z$O+2+GvP^nhQip`Nqv*31CY^l1Fft>FTHm+j)BI!Nq$k>qcm4hb!oRIaOnMswQ~28 zC@k${PzeVo)rozfuV{3D+T!82PYx@EG2AjVj*w)|hT{SqSNzL~x1^e!DZzT+t+}8c zK|ADVIuIEci4&i4kfTLMXvlftt!D0jF_suyRL1TTW>4Hfcdh>Xn6UrBUpkWe6Y?+r z`f=C@|4B`vaan(NgZyPc2AIJ7Z*j54e*u<0^AmsIEFp~z@J@IpjjnwK-1M+^6{L;L zDZ}QIch)m0wu{Q@u!a%{hW3%;-{CLVaH1toQ<^TC1FvNpHT&!UJ7e>%huav_6#aQEr;?k~{ z^x{eVJh*8ImVWcCoGR`>(fHd8q6ASB7Y>+|l`-JUTlOC26uW%Sio)Jhm{)w?s63`^`|*-42V`Rh zSp>h3J z?x-U)+oN2gKc|FIls9iht1P-8-lnc>8SZbFoso*o`)0m@yS0G)4|viEVRG8r5!el@ z1HSE7p!{;rdtWD}dVt^&1>W?NGYjKJ&d@{g~z`XT}t#(i{T?rI3T*iqHIq zYB^sqzj;`Y2-F+yU6L1^d*#T_xfvJ|Iy-wQCZow97Tkv4Q-k1BH>6FQ@GfJwiRB?u zYt{l-ST6I8z;Tw1FR^H^%qQLCS7LNI$abP#e_G^da@%GajXR!~r44nbj#!n|Ym3Ur z%iy9C78OBq%**6KZscOv%vJ)pG`zy^kZf#)P2h{dEFu7Bf9vMQ`CXwNd^b-98c%v1 zi7M_DLw!)Sb%9xbRpoLozn~-0$|`_t|U{uOKcbg64j(-Z zT204=QD;2cc!vsX#B-oTL|!?!`ijsNej9M-FFJ6mUFfL!bD@#ML6pRYi3x$!l&ym^ z^0cU6o#*8|9l*q^fix_4^O>^>1m9z_KkXLMx+IHqIv@35Cm#1PM&VdpSEN>Y1#JsZqyC-C;TS*Lfv zD>AZzkS+#YhMX-T^waOmXmPt`yh*#ZZX{R4qW9b#>E`2DD~|g*P;Pb~PFJ%7>z`BB zbS(I>=pD9h?3}$nx5)b~GtQmXaRyWDvF}sodKI`OLffS*KPTVr9(vApw%zfB;^vnh z*foxM85XR_7|O?qTwA5Fa!aI-zrJ$T8*(lx-mS@5+Y@0bFyz5p{Zx36@fw6nWyU_& zeLR%Bw0m~c9#K|Uuda7?vYX`lWKl~eu%O23VS$Uct}5A8`T|+)iE?Zq0gyKHdDg|P zJzPu-ur{*>^Uc}Xx(<#T(?tw2@0%ul+O=_j|H80{nxpYx9ZOqnHkfK@Ybo`9`P2W* zqTu>&sb#dXrG7yox<}-smio3LA)54z+Hv@?)9*U;f0jpat?4%z?|m>&(KZY_k1Di= zQr-QJr6ux}K<>L!Nuy&)UOqoRe|0L?ly6R0!0^~QE4A9_M;lg0zpQ(=a{VUv=LKu< z*QP!a7+NgI|C~lj9bFeeWyU3lN60hkanhd8D>S9f=a)nkhJiWaskSE|)vXEQC9bU0iwKY&Y^TNN z!IG&s4n+|({De-g{L0r+q=Nrg>`ZNDh6vwk(kdzE~*owzdqm@6});*U6Y-P%(pTt zEe_Y)+%dNkB(%|IXvJ``bM_x~4tjs~<`+g@+cnt0D<}6fSwgkHb$Q|A2vf`7MGTF& zqE{PGyw4tM{GLBpvL*C^P~q!td#*!eouLhJ+)ND(k4f~0B`q^gi_o8C4RlBw^dTva zsK;?t1nY&FhCi5TH;Y|+P?;mW-U&&jyoJ7)_KNi8Q;EOb3E9(m!S;O+NOj)*TPi_E zx5Y|X0>|JywtoC8U0gcIfb;c?rO}meM zGwt;(^rlh>j>FkkSs3G_G!}W1$!G9S_r#PXwp2c4tGq8wtqQAlA&m?VUwFR%c)(De zTrc#(o4ea+byYV$@xB+TwMeMwy>vf3ym1Pr5aWWQAS1p{O^$*ZvzFI1zL5gib5Gm% zcVlS40>b_24&5}Jr^i|KEs5XGJk?MahIEzZ{C~( zs2uh-TX3uW=ym%JS30RNSoqkQDV**6Dz)|a0g9&1azy<`Gkn6$J{ykMs^*%bls;d0 zvBZOk5U9-@im%@nAD+Q*+~9P4MdlSF)(}c{Km_XnTogi?Z=a#(2%%DN(|Cu==RCFM z&H)>x@TdxVZ_2@^9gSBCLhRT*l#IsdK~1*x{qU=8&_4ea8(P4K&y&WA6F__c`4m=% zIp>BmKkB5NHX^p4%J}Oe?f>b7wCkaeCC7SJ#7UC{TNx&6Prn+}&dv7Tl_a?uR$> zb9vj!FaJDiX^fP0+jmUmi0|z~-wVCWPzirV2RiEIx>jt?Z#D72#eT48P$*pbmH1gh z=jxu&UWjz!2aYkZqx}{&#Mah_tf-ks9`tO`Jcs}W9o})L)U(#}^g*(K&+)KDYvS;X z^J0_K72mv^`0)=!R6@EMuK>@qaS*}5hti%xJx!8^W#5(GGnPS~@wFNYE?zsV^E0aH*VXmW%n{>+;QNFp85b9vpe) zaVRJ*KY*U_=#@4%iLhE@PsG}oc>olETlTfbI$)mkt!C;wq@l_lBz>6bAI-fWQyzo{ z9RAMhh{kn;MLvs7h%cw=~Kpj%$<<12*v7 z`w0+-Vpx>ilg4kljwpV$Ql+x2AQI0O^y=K}B}{T$0K2PB9Dpk?pj9PTIqVk6zMgCa z3d44odjnv{q&SjR>JK4qe~6j&);%av2rhRhWXJ-1k>mVk7klBpkJvym_X0{#q7pRS zdX-5#V`_DDgu^|-FW9{yjowFCCtCe3K`68U0J4A0B{J=yST{!Jnm@i0Mdswf#s&*> zIlNQ3x%N)QO?SFA-8yk|T!ydI>Kb={Vfd6b45QUeZpT#57CyCp_R<};T>gdeVByxo zD0na>O7VwVN29qWS2--YiFU8}7==NWuhA}gg;9g@i29Ol7Ku$Vor3DS!V?ldhFLR^ zL%~-Uj@y?;!e=JTbB75E1mVZq7Dz4@2Rc%?>ldxR3IxLxd8+l_`kUj=XsNsiJV%k*Cab%500!l5}r9goTsxrn1W zLV$s5>ItU#1q7k?=g}tt=s&`5e^$0&k4~4?2>kH7$7(GMSZ+}D2SZqVI;V-LFlb-B ze9{zY)$c@&NS#rXDakTZ_SR>udSh{&RN$7)M}xh$>nmabF6STKNLAS#1{J*>WACQ&;V>6%LtWNox4(jNp6!YPEhOxm#Je_B4Kzzqa=%J5 zO>sr2HVskm5#i61vQmgX@L~r~@&Td;zwfH}&h~_%#I#MHJiq}tPFf6kaifCI%vYue zOwv2AsC)wv0g@N2?CC|mnlNy(d28anM1R|M$+WPZbuj{O@9FTGpkses2bRkbx8OW1 z%cGdP63;JYEim3OHrg%C2^TN>Hg=Dhgz^V{rwHEvW z8Ll1pjFylR!vc#a^Cdg)86T6T#`ps5iljVIsx$SsU59D^HTm?h^8{h*E6%Nbi%0K^ zS%3V|G@miKXZ*&7RVaNM*pW}5FD?uhe!3`bl^J|tR?YYGzLGm{beWl3YD%PcrlFm^ z`xEBa0`FCVoF317ORO(!{gO8G^x5s~M#aB7V{6CsNZ|3a0sUy( z(Fd1%pOA;Gh8s1C{B%k>6d3j>8vpiGmr{IYZ;y*|w(4VT4M}<2ltn>TXFvS^QjRoC z^;LXncxec2wtRy2r9S;f-~Y!Ydu;v#%xhI=j&(gJe2GSfTZ22j7xlo^`_htW{wvLP z*w+M2{8>1EH-$dd6kEap0VM$_6~o~OZD_Wz*)zEZ!`ru|Pyw3Ihq(C>c+lav)yg6;1pMwi_C8>^;GkjOdiF0h)+J!G0R zW~bqS1Dwq39A^X0HGoss`sl4rQ*9eZ}m32&7cHl|JR-8mY=XR6& zBi^!A-TGAIV@&l}Wb^%%#K3@N$pAggbx(uyYOLq+#TNTiKISE{t>;&m`gf#mK&1Sa zf68Fd&sNQrkv)^6K|870fz^QLV-r=6ksEIQ@%@84hPeBY_08caGtXD|^|d}&C6qEV z`Cl$jLmZ&O6V(IaiA_=#yzbsztFkx0FkV%wd7&Ypf(t7#7&p#Gx@EVydLYng2GFHe zaAOjZ_~Okd&LDdMR{vb;Dy}jX9%k<$FsoX7{<$5ox_AScfOuNV&r7IMwefF@BJjbBX?$Q3$B&`} zHI?FJ)u~yPkkX9Ju!t~KLDqimL&MRk=iRe`*1pR!8Yz?bW9tLCeB0*OCdh(uax;(N+c9efV;zu8XK|Ykt z&J*-ai7cwNCPPBoAs3u8S7cjFI?m4m%J*#=9UDaXq|0T}-G4>vA(@}$EzmT!^GHz= z`kDEKzHP8h**QY&-KG`NC+i`Th#yl|F0DAN{KSVU_$nHv7(Vy99~8J2SM{uQv_Gkr z^Fo#@B#Gdm(8%i|cr@&WDOzReWi)JQr(DY)7Zn~HsbtW{a3IpXvcTsT)iv)R+pPhx zx`hr%8IKBN{56kWq&IdRCQMe_ejQK}^yQ}+w}``h)h0H7DE-)LaN67KylBsP-ZHPI zySuwzrgZ{WZ!EZ)hXR8DqX(BJQ(3n(wvQ%p%&wMOGNdLhB__nzB+J}&{35d-7oTrr zs#e6pxA8`89pJ1=J41G3)7R}7J3=403MFrz-X+UW)->m>4WAj^BY)IS#ly!(AnnZB zHsBz<3^Yc?IFP0KG8AmpJhGLr2<6UBu-)IxwVRvEsEQO=k4zUS>N`=7Ix@0lwh?xs zd1x{_qdPNu_>34 zDD#sR;fh+f_w&2QV#I4N3-4qaE%H9oE%;>IeA1R+Eo}Kh`z1WER7Bq>AyQj5!SuP)*nz^rA?xiZq2*10`#R2V*0w)cGs9;Cpn{>~VhR}#?xfk;kO zd{h!=bVUUOj7C%#l>}^nTxDPQLL-m+et$Uxe1Y8#`jW~fBkw{ z-yycA%h{MB-b*(BDrp)tQMo})PRLE}q_vgKdZBod?}_jdVuVI8J1q9~Q%6e*rkjRL z%epw_>ADKdx0-|VkuqjKn%-(b>v=w=6hMknMpm2WHaDMDO(=>gayN*?Itl@})GLR2 z@2nV$hJ>GI;tw|zmlc7RFwGw)k%iQcfT-g*9dN(5QMP|6noi)6W4%em=>(T}r*=15 z@^J;rMS~(AtP$SVFo&GpXv%N+wK15P=A=@-@@9%W0|k3hViwZ-Il*|F9?dDrK&?V@ zr4%K#`g>nQWP>8@ZMs^`^B{WqE8vI6{UHr%s^jy<<+&B48pjIP?oWt5&Q$Xr_4SGb z69NXYpZtFjP(J+pE^zCicTO&(C6+kD(@J|5b#hb#r;=E&f#G&rzYA zOiB|lj@^{o#ix}E8=tg|qYB@IpVO@a#Ij)O-j_WhaNpLl627tX#voFczj*i<_lk^@ z63Nj@NjkUJ-4Qu3tn3jfY?&>iC8+Y!;Lpyi8=KRP{Ia z$-UY~cg%QKtyPd6jYn6BS8D*`&u#T8n+L~gZBBu_$LcfRZN~cIMxE;`Fog)L)_|9> z!`fa$GGd0|;0d1MTiS%KwvLdNq{l$#Ub_qAfaAr7HQnMDly4pKerDyA2d92so!uNX zykPJ{5u``P#`j)NmO0x_fA=Zj{ieZBost{;BI2B@d5(FG9zun20x=dDJ3OmB&nD%L*z!MKlrcUz($Fm|fCVVmJ5)#+S*Q?zceNEB96qo;ff7==xo3Z{n3gj?VF$6p{3WXfr(E z8idpudSO`sNJxwmdVVXXDrx5nBz|p5N;LHbMQ8U= z?~^``D6ycZDdu+fx^#teF7#BG)fQh-XI@oZ0SG)wkGbaw;+7H7TiRAZ6D9Rop0mEU zEU48~=_2=hvbEs={etJM#?`}UDpJ=vEQv0y;CU}QU&i}HU2Uo=M+fZCqYuj**z$4hvmqhlLkA`u|vI z7h>~67_pVncHB!vu5w6O_Vcn!U_v(amp?`dzGJ>XgdX$O=BD=`bGnLR{_Dw&pNs7FbTIoM*9M#n>OMt?_`Iy6kl?1*5pspvY0?=EwahKF<#~@eB*o8@SOmfWH6K02)pje|Y8DvwxDjzYiV}tD{hOqD&(dt!-y&G#F~t?z9wwS%nyFzhKeT=}qGU%~IAnhlQ2K<55zlJ6973sTXue;VWf_ z*I36~>pht4q*L02^teY-ILlEmxCt^krym9C3B!6ui*vr~<>r{H#*a1D1A$xedaLpf z0|E^C0Indu_r=z9h76hV@3uXk`x?=UoY#ombQA2&5p>i$UYf{iT5^)%0UzH-dc$Qg z9WU5R9obr!!TA^j%XmB^LuR2RSA&jZ0k4>um#eL4n!!a+2HfiKJWznlfVgHNY7=)M zte^3L6GPGuJN`;C)!AF-jlorJ1Vd1wx_B7>9W$W5PS+Jo1Bzzq5h+aDon{MC5g!S|znywMf4@f-~D zKj@{jlIZK*Mw_wp9qGFsMJe_kWV#I%5-C;f$}DEOorg|MQ5h8h$f;ypF*8ag%O&FA z$H8P%Z*hv;e}0z+E?m)JuRg$E!!wuHr;p2g0I2`syqnHJbr;UAbo(Sc{rteLn+1tG zHBebhNqI0|o_nBbQBt%=SJ%FN&E~-egSq`2mx$ zbJ{UIGacRMdSly{r?9`&u!e^DQEP;?L6yAwMFjf-{A54tm3Ynw32T30@IGFyl5^a9 znC{tkuYSbf7lv9TT(>HA5H5*-MA1_%O6oYy*VWNzH|%GO#_fh(U#d@ck6@%!Jz>Po zCAd>r|3Nof_2w*iUCyRaO5N}c8lX@7^Z@goo1iGH6VEJ zJl71{`4T78wzB7K#6ZzzxsB5%zD{Rb%U}PETUcFF^~Hb=m4S~3hOfL``Os#<%fez9 z_lxugvxtWS{#%h}eMnXVc>1B!Q1Qq^t3~!vgFNph(xV4GBqUjijSW$OSR!-h3qF@? z5K(~l#~dh3k2${vT^5nDVG}pm^9-mn9YYy?FNs*m6Inp+xk(@3`4kfTK%P2+c7hhi zK{ROMHx;(<=3AlEOD{@P;@+pyxQ1{y%~z=DN!2Q_bvy^h9FG~Ox5t22prU2LLDO1F zeTQT3!-zt5LGB&TW%Ew`c>^A*VXIrfRS@+sAB~>PJiGs!p8BTn_N^DCQF!@u)Ar_0 zf;UTQ&#R3#tXF_F@cy%&Iv_!#^Er~a+o(`Yf13qWFK@ZzmQucWF-)V})bT)RvsMTt z$j&wr5-^IU)Q-JCTN3;hOTPO&sh;(9(*jn>Ucg>jUPRKUsMt*Pl2Tl{yAy#nd~(fb z8Qy7+OVXX-uJMA)8$=ct)xC8}?^CbOKWZ9=k5!xG)txaGy+?~ni8IfB16%)eld4fW zrv%1hKOF$h9Qy#?qG8nJfRL##L^6h$zKnrEMthh2Ci+la8ihqZCw;8weVd4A#$(TI zIp)3fcfTc-Uw>f~{j0TCd2=bx21kUX{szYuyhWcz*YX!VMhihhl&}4j0(5=~lcMRk z?D{U+*7IV@o^PLrYfB-12%+J)N)OR++>So`Yd#)Nb6z%vuF^J1e9;)L@%BFXrix)a zznb~lI)vRKlCMMaty^*ABHLan*|^L*k+@mNjDS6gLdt<#|5%m*%YQldKs%J(Y&A~y zi%OUBJCR$&f(<}q_`wCSGekU}WdN;S>Hnw;-wydEJKIS+W0E(4lf8nT#^A&;Gw?d+V?^x`y316m7B6mSVvgC@tgxX}vT%|-|8T*L~4hk`hb4}TFtCM1N_lDUUI_7jiW)n*7 zz1_plDKOUP)`_44u3l&~(|zC7w}eUubSK+6S~~>PFKjn91Vj{ge4RJa8s?s|Y`Gh~ zsbzh$%KB#i|C_os&Gjhq4ss~CH)lTYf9cpZHZjD+RQ&o%buxJ>!T<<)8oYyTHi(Ak z^ke-f;ydl(CpE8~STL5@OmJ&iQj`Wm#T$3L$jh;Fw1w^Fjx?M(v14QUp+Qw5r<)9| z?3ZH>9u3$S%ca+jdYsjZTU*c@p=7xI? z^3?(xoHotzpl=83W9|U3P9wi%R@Wpdr^#WGV@AK^ zbxC2~hzFRvESYaL&S_Pap9b1W^nsdZp9SPOp+BQOsZB7RTfgM+#PD@K>fzb+Sb!y& z*<7F?W^NM=8a3sEUE`f0Zzz^I$*ok%8o zBvr>Il7rsdd3g9Jc9zhPo4=u(=ILaGog}r$f;HQ<$JLf|=|qEq@8>Uy_}K-?4~%(V zZCTkm;XrIhz0(mJI=1*1t?G2Jt@3YF>67OoRGK{sP)QBlf>LP6-Xq})=^B&k? z{Lw<#fQ_tPoizQ6%lp_{>RSP)%Ei2jO5=@YErU>@FB(gn*)C!+vjVh7G-h!w?J1Iv zZ{D3bUNPEcl$2|u@)$j?@&*XDvxWH^7A%yxqM_bI+pS?!27ZUP>bAD#Y0`ThVV97! zJt?Pr6Yklh9A@|%v4~QH#_~(=gZ}~$6OZ$+@PM1Q4P>;3kIHPL#At#$1gtx8giB=SnaYhmT!ATB+VjgQ z_X}-o$eytVc;FNjvHF}4kfM<>Ky~u3x@}t!{$umiBewBp+;>vqMGc+ME7|R6_O`%F zh;y9aW`$Jsg4N-4vw?jzmd2QR?`&2?YPUWXU?<_~tU=XtDBGa7{m4?q29)nGjSCJ= z%WFHDC&IW?SL_%{pQSsp+7SR9F?}!RZmy24WcqAzIHt2#{_H7A>$*3XnZ~C0B>auE zB9tzuE+;H_-ILbO0u>I7JKf;jLUJYB>6}}w{np@l;sYD+m*K;+Lk3~H^Rmn0^Xvpp z>%PyoLyMc|&1c#&ja(#Ya6HY$r z8FtMiJT{aaq4X{ZW-dpKzzh=`W@ziUmscOYYpF9sgy*P-t;k6z&c52q3dXWTg_`r^ zFfagohP8(QyDcv^Qd2iL*HY68IDZ=G)R4E|7|IQ~{<19C0hTnp8t7U;a+qXnJljb_r?Kx$LkC39UY)r{WuPE|S7LE>mTUKvfl3nOVj7y2n zt(>g$aiOjZU4UUE^i7WQ`)`|W7ZEbwkdKb@*j!}jUA2gnBC%B`<7WE9{tHbU@$yL* z=}30e0TO{UsCAEwoF^Y>_O?pLe`TGtppS#i-*LLD()hsl8H-YH!)Rg4+?uacIWlFY zwkgE9&xwqszkkb+g*`P$ z#et7Ss~oM$t4@Dh>VG4}>lKn@3-Ss=k2@hzA*9o_c%S)U0PIvoZ}J-h`^VWNjIUch zd6;~vVGj>c>?At)mCb)H>^4wgZIELgdE^MsX4GRU`k<;pJ3o5Whd5&B;OCBpqjiBS zHq4X5aQ3MwfsN7G1OwJuX@8+lg=s6G=K?v+s zqfK%p-0WkOAm6(7$W7_;%G27EXY4c25N#%YW;|p9=yn~Nr}1Xr zs>nPIM}HvYcK4+BSNgCcf|+sd{UogSDt(FYs6g~AGMvx)He@#T{TDIzPq!Y| z%SdDGn85k3iHDlUSbWvx@LcV}IH#NC(t#-Qt*y(Ui<9RWrfKAr`S=ql9kpd}0}ddn zmEtxF*fftLj28rR1MRExN-vZX7M27{e?x`VRR=e3U^o^f?xYXT@}fnbW}wZy$QH~F z)@90&;bD?epk7M3tu!=(nH3112;VQ8GhQrdu?Ua13%$-?=Aql4&yBR5i|M$0Zlk5*Mt({gTA6$vdkw@Ay1Z!aYw z;H_Io!|A7=MYNs-3z>;TvQ0W7-}K!_vb8uOb()!4?c2kbki2vD$Yzb^WeRR{DH5;G zK=hOp&}ul^F#pEKgXiVR7JFI7#)?7*(N)^lp&`#!QfVvpKHe2^{DQX|N@?-RT&VfY z-t||DW=EkeL2Vz40`AG_VvDKqdNhk--%@8&tW5H7Y3fzuWJE1B2efrFt2OegWU1eP zs4lK7=V4(aS#F}Huvr@_u?2)DLKp3(*;TTH_|xd%n++Mfiok1oQ`a)<+0lm>XBG1q z>W|17=Z=UcyP9=I-;XKwQ^VKQXcq<7IJ3369GnLh9!lPPlUUL;+;G!lr-6?@vrNiu6*HTn zofoEtFfN%4%mbuImSPtxR~U1H%VJDPIYK6uQN}b>paAAdo&O93aprB{cy#R>Ald%s zyF}geuW!KsXqw9_HrV^OF8{61fWqP5zbBswA{ib~;?bdEx1Rp_?Qn8im5@H+|DOd5kUF_oTZ|j@jc;OmQmv67Xf~Txe=)ps^hFAc<*i~lOi*S1Jf7+ZAsm7*u6fkA5q9D!!k9O= zhTJWobp}-Xi%=hG_lJ0+H^Ot6G;6|1J&(0nh5BSDQ$A`g1(E z00JwIiP+ryN=Lvoz{sQ#e9PUjiPiWt1SS)RhO#H#59Kzc7bv8`tI~SR zsXUQ!8XQ;?F04@xBuO6v{CEoW+(9oA0T4HTUoT8~Rczg)h|ugBe1;|8D|-cB7quc< z|8;tW=j&9W^RVYyuwjEVu7-N~R&=sFQ9KVyK=a_xY)G}7#SM(Ci{1T+7cFA%JRD$i zG@oJLc;UW-@3!)MiydRLDALg6)vJu!2YIh8cN^czyYQKoP$~qW#;y8rfaNuDA#Z%m zH*gK>EECTv6G<2O^)>hw)*J<7X5>K@zHjh#gqyaI`$&H#m`lyb8*8gqdHpZ6u`?QA z{!^uh_aTdw=7++`L&Z5`B{>0Skl;G;9j1ht*Fn37o)C%fH(Xb*hSX?-hg46*Ko$?L z8wn4T__X$(v6yZhuHGq7)jJ6~xZj!%yV_ej8XjYqt>*Jr501RDSW*FMeqRz{-&kFi zyY(*RBlRPzLOMg*vd>VtNS$V3ypxI;6T{kvm*z$duT}(TA5^J|RGp2i@I;%&1`-1K{Vy@)Ik@Nq@K9hk1Ud{g@>Mz7 zbp8;wsz=aSSFk1YX{6~r@Y@$T&JE}0ZgI=LG+8($NL>yK%N$CgkyqAXKt}V0o0H7i+?kM zQ6c8Tx~21J&3O%N@@6^aiKjDd)rxxX-RszS^j5Br%Qc-gi{q5%Y+Bl06R23%*T1U; z{Lg6N|NS}?G#BxketUn760_nh|JzW@EP~SQ72K};V#@f_{PF!WGCzysoQJ<1wYn&< z^o|NDD7K)u1XUA7HU7U@M=UL42p2~SQnW6<^=yce`-4X^y5l@byS(t z#dDWqJ##3(;-^C(9|FbR^?lIKQ*Rw&j1p90iSj$&YEqRL>-Sq$AP3p_$iINO=Flah zxgca72~e53u+_B!{w>W*^YaM>_Q;PP7ce;r?V3JKs<7}!Id8QQVtPL#2j{cpDOrIO_zmF&MGT($ZJ|6?9T{1f2%uL$1!)3E=U zU;HN(7OeI+0h*XE`ghBJ8@sE1YbAeY&i+aL{T;8HulT>L{jK_Zy`R?ltJt^#)qk4i zzdhWnln^iLZoqYU*o5BdpXQzHiFL150FKZZB>zq2V*^(wVm<}y-o?6=eF1OKTs0#= zny`XJ^s1Llc#KBIqk*TX+apleU*dD#G;CsiDVWQ*&h0P20!Y7XDW#=pA;Y{)+P>!+ z(X!mN$@*ZEarU32*8hi}aMF$3++yXIS-;1&xnTmQ-igA^Ox;Bm*M5ca1b& z6C_w$Ll#98&@e7{+eD=dS`>1d)Fg@>1>N&UWM_C#stL9{ty>H}FL&}~1w#ez4JyW@ zY#*vgeeyxm@(Dg%H<6S#==*iqD!pkLyolIOX4(pN(njD8`-_@!A<9B)uVF{ zf6ZEZdG>AMw^Heh6M2NaBuktAYQ<(t8Ak{u!18Y;tnw^}9agAyXCc!wj7tuycXuWR z=E>76bd_B`bTra8RB;;{F#v1{L$_LCJ^wDg3Lv9r>)iYFfWJqweMI z9mug(v)z`avEJrdcDn2S?mPWfL9%J4J-QGKoJst0YYwXg3^#P8Z~tlf3ufLcPjDJv z??rC;xz?=Y{>ssbRr;j=(Bu1?z1$z5Yyrdf&HL? zj#B1yI*%v0&5!#Sg*C50(nj=_QFc>&N#8hx@Q>OZGKSz>H+Tu^W}@UVc6noyEf~@B zu6^SznPjhN=P;Y;)klbg6QKr@NkYcm1E2V1QQlM{@0T{75w)qeMcK(js(o`bRu0>3 zji}%#0rAQ6BX!ES&6e$^uxtdw6wc_(nuNp_4Y@wmUI^n0sn~jFS}j~<7DdS$(`4m5 ztx9H0Rai^x>kU()xXWA=7-j{&OOikA%JFjVkygp;woy&1Gi#RX*oD~P(zc|NjKxIxvl> zI-Wm4qjjhdD)DSv>N#i&j*ST z0!X}1iDSvF((aq_DrD%;M)AF)n;FKJa|a`Dm+s#0uc+T!PPO&^1(5y8&~{vN_^Z@@ zVQnUf`QNT;RL=L7{ktw6w~K^$+ntWT0I#+TTGs_1jLpy_9BUg{xbGjVG2Hu!h@2Ep z^*&^LZP-^yIg>DD3S@|Sy?O4jmE?veVB0g|E*#_xx+2aPr$cD}BCa@dsLl#HpZ~(@ zO_DNl(ZW=)S-P?)>;L$ke&lWaq+*X2kmAKR2w7Lvimb2RiD(-oH{AXQ^>UfgxW;OR zT6b(Qbx+-X?ZS?L%ymABNLvi5X&R85PNo;=E_l^W_eo_p`uaep~znS{hg%gu1U z+lQQa-GNm|_7OjlS`^)l-J8@O&HM2@s}u?&A$KC2H6*dnf9nT&+e;!SZFbvzJ6(_` z>u-r_!flHDoq`)GlIfeuv+raOeOiwr>_@;^9N_$m^F5Mv#T4<#)Q9&nsFDj`6MlY0 zznw~^Wa3Jp+?Q?IbS6}p))S?FNhXqu(!&w18)_YtNv<=7{iu2?z_@e)r$-f^d1?8x zW;MXO=3ag%`X-+3gJ=Xr-b*?(vyTbL@Ka`gk(HIuU8X~Ayb913cR*xw{hR5v0_t~l zLUP{;z;c9Cq~WKmG2=D-8Wj@(Pw^ zie79ik*piu%MXivi)YSoHI6WjZMa_DWjxfDJToitN4a8i<+fLXP#E~1APt!JpS^kS z04-t}DO^KjYzI8?AFV@`XFAl3KJ)s$*Bf6^TR|Oj!U(#RGPYs<#So* zONk$eFS8xAfVa;M^&XkOQkK~d#+b-}4SdE%`DE7L% zh40;#(3n72@ot(Wj-y<{&kWQ_5=mk>N9|tGC$mAw{>Rh1L*q6VX32|MnVYKn%LcD7 z`iFb!0bFbMQ)A<8!x(TG#n&^s-OBj+qEo0APiJu>zGZ`Yz3hzJ_@d=;H2Z|bZ%ITF zXn%LtiOBPPaNO8Q}s_k9R~H0;f-SW_OE9cN8{{XL25q?@ih3DwJFPj@OE&hj zjUcVw65$ff=YU6ZCJNhnxW^g5hdSd8%l0ab+8je!@0Cd@nmSW~39(i?->fNlK+5=V zR`8fV{ZgIfj~2LS!uW!-D76RTLPtt7V+eKiG+h*lenIttaunL4O!146%L?i`H%E^6Y$aD{1BIGC9LcFs63c&uA&;>^B)@qU?^qd^p#xq5*W6Kb8~w2@&C z3xIv%z@o=)#C8C)H!d2A-Gz6`a5h!AlT)|ATV$w-TXE-?Y5hg&&u_K$KJ+xgu@txK z)_MYEo%m@^*R%8`icVypQ9icF$JIh%#hgFahMhybLkkL+%QDUAGg4ulhcF*XImFk@Tfw5&1an3$ zVQ_C&^fPhmyOLL{Rozjg*v;|U(7@GKMmjb;Yf0P%w>Cr#j>C?Ier6ewDIW!f6Sk;) zpCjB2v79K8ZajESf9nPaa>nHE21*yrko^O^^_1AfdWS90v?fNysfpXFrwA! zs33%Dsv-k$)rp2#ezi@U9(}XV~>vq6V&>3GB{@Bqobf+ zazF=qry1t}ExupDMH)k0CepE%m?sj<8_ zq72xuSgwf-myCQ0p;fPLanhTv^3iK4J2vapC;e1qY<{K>sy5a>gEjEnw`VFEOImFaQ4-L@y$*@F4xk#Bz{zBFwV@~8N0 zzZTj)irIv6ohnXT3o6(zKWe^tYW&RP6IvV>YiDP_Z4kncCC5{8 z?;>3pKbC%IvcN;^R@-P&3<4|}vc4Tmi*Id(_LGyuF7;$zp7*W$6cxmg>FzYpr(-Fo zU`Jn!2&gV?i1=u}@2y@@y+LVawR(T@CJWkBy|&(LYz*Ubcj4HI1s2{dpZ)(p^6o+` z%bYKqDxZnMS0c+%x(PmN&ameU@*U$I4YA&{brW(%EIiE0mY!=W)kLn{fH`EPNEc7CK3+pZ57CUAPvO1i)6gild#Ec*HG)k)anvUpdOhu;-{_ z(fIFx=I@`2{5e>UPrt5yX+i#ERVNOd{x_KJ{}%F{6&m};0NUtU+Ih8bs024AH3*-L0L}0gn6~3Et$!_N=tz8>X23k@qCRCvcg(OLEVWhc0c96;5_g-v>H3y! zuew+V_Q)Jl;4d&w{~mAgW`-Y+Blp6rsh3~>hRJ9z-Tv9}__bBZ9T0jM6dQ9m@<#uJ zGS;7%;g)WvD8J6i`sf0lu18gx<@>B{H|lE~ulls3Fdqs!y9X;>g3s3Rcvv@pZHt)` zn>~l@?dutFic{5pa?p4s%T(Gk1deS$IS{m-qvXZm2G)X<;x>`_jEqBf3yk{HeY~>U zl%2UjgDSC#e)3)ICSy8`3y!8>XxgLsG;y^O+5%W7Q_iueo0jtKO30uxmiX$LH|5QS zZ$g7mdUn54QtYp&cyAkP`j_cR{_*<#z>x&FK3DV_cKNFzDc}0N1e#Zky{z%eNh4!h0EC}YM42S{*0sGFYX}mgJE;yn|G|O zH>6|eRez)^h3cB4N#HP~JPuDBVo*>VThn{QU z8zE{1N*`-~zm~P4@pA0zztSJYK@a2unyhBt$jL01*0*eNSs!c9Gkw4p`rzhzl$!Z- zts`_pq_oWnIVU7keXqOXa8|P*o*j8bF`(->jMeKDMJRzZ&>r&td}P% za`abrzcL(q$f#;eOva6TuN5^rk2hNgs|yTVv0B~15s7V3Q(q_ofwTydwlKp@=?$lHRyqS zew#KUr)`pyK8@u1j(>WEou3xedzL`9acB! z)iNJ2TR98G0{7I6E?FvVVLO2Np0M{~1T&+x6BJpcDgdfrMc za+B0uG3oj|-+QY?#nHcgR~~7rk1h2*oT@|kk||frZWsX=)^1})7DATlW|z*L+EMQn zhkPJMnuIInQ~VgneMhC_uew>Z9_L`^TWxFXGcO9S>-VON9j8Yj>(znVwJoc)1&KX} z+ydkLCl3Zlf5P!#VNik2kqhR0IF_D!+)~e)dqn5(>V@u*$Q9+Lqet3oL`5WJCOZ)V z9hVCGIlBto387e{&!z_uD>S__xdt-Kv0BXwvm*pP9T7oO>{`p-d+5)(fsk61790Gy z>C}Kr5gpTXGSG2y0?saVUc;tiSyogAS@>?lNB=y^#**2XKVIO1T;!C$b2w(dlWc?_b26 z5dyuUHiO-|;-n*OkR?3iF~P7f%r7PxUCZ>2^|0jn~KzEF03UO2fcWY zLHK?WC^^=Goh`fiYwJB!*!66`*~9*c%Q4}TkTCAXXy({XJO=@U7Qz>_RF}g-#=s;k zA9jJxO0{LZ#$G%8lDzhU^J`m)q&Hf%YI{Dcaa*Z?4L(m zn8PKm0{l`hXvl9#MgfeI4^^e8&J3&Vrc?%wjZ_=TBEH5Fc&dk}7`?ORcII!`&1FH% zs!-8eBoCo8B9jYHfx0Y_Me$#)QL^!MZ{PE+(JcsgxcZX9zP_Nfrx$BPL+Li z(61%}3t?nBxy_rOp1qG1_K~6SzsytJsoQkKhDbmsCO^TbOY()M&JvUjG7E?XiQqDP z1U?ZMu#itsSZtX_9cDX|ThBz-jtDrY<15+D-Cux}hd~?#b98*SR<`pLV0IR#eXMb> zk+!dxtSmFQW+*+L=35hs*&u-pn)8!KMeiF0am#A!MNF_*RR$J!fT-xH*eY+gwYH<= zvQn~_d``lrW8#gTAV;b1mYjjw>C9!WkL`py&16M<-3*)?!&e{I)pIsFFaTYe`H$$$ zeK=1bt4&V50&0{%G!qe9+$}rZ#nnX^-p{h|*rAXNV&f_21ZhODr%NS$zEC~Pllh5U zT{j?>$GB!058qsiu37lRHz`?pT@2AnzUqa+)ED8JPd9Kci(!6NKd)f$+1wJ*X_AM} z^dzE@ydkglf;o@VN65fskr&UTR(_zNdns25z>M=msXNbCG zI&BSYUt~rPGE9;elThSI*&*0iVz+Bo**G=|4v<$@rqx*AWiZS@`&$z2TW{p%Z1S$3 zQUtgJdAk34T-|zvxL^u;jk*1bo&aU?7Am#9>?ScZ1=z48=h zPH8zY7>I50fSQ5KsLodXWrqc*aDCk{ZL~D1y>#c$VOT5XmVt(xp4S-UmD(Q_K8z{u z;fgKZD|6gpxm0>&%P*Y_nAoMut!{ji^T5Ihs7*s}aA0xf2X*EQ9^6bvTcjTs#@F&d zMf*KeeLc_b_Os<*N~uth9oF2R8BS5_utrKMaAxo_FvL^-QAtV@Gd#>fcQ3r+*i@6RZ8tG_!cyZel=| zhJU8Y-z|5I{fBLhb)BttAF6b13Vss%8?~)3^6!aj6k=On`)oj0_xQo|Y7R|7JeHuY z9*2i0j12uy4cXLMyB4IdSA5`OyY4nFyH)@NfiO@r(LSe#b)A_o%LIg&Oe7PtJ9fYN zZ?*s4a_1{c=Y+~=p0*QX)89ot31~Ecm?s`NVic+7;4|XfCYBXw_+j%CmEmmH6RN` zt=<_$VbCS=@1#&*YTphx>Uct>umA3Vh~Gst{O12Te(|rrZ2}s9+XM(uHi6OqoErAB zzW^xj!0&~>offYD6&L=n8%_!S)~B?mXdCz5k) z^<`grxgz_{?`TzBS?t|-kip*aDXXqd&0^QwK#La=UfA&j*wbyC=X$Qi!Gj0hpSaT9 zYDOpkfF8P%=p!e9=`1>}m#bbrPwfmM@rTQ2qocj?@7n^1Sbm?BKd+IyO&|UbnLHT( zYdP`mR+8jNcNSCPq$hL8`Q&eMYP9hNe#Ps%ui+}jX4rtA4*(|}Z*#Xa#`R;{$KBJ8 zl)NS!%gR$GsfTCj zk3g~-aVV>eB@4~7`MiXz`9;=?z$I6o6!Kj~GMlUiL*eb$Hb{@LW>YqgW~&YG2I32*Azm2FhfdeTlw6uTJ1QmD;kjPp!;>BRy=iJ#t{NW^mEqR{fSqgM?-lB4&~ z(gW8zExG5Qv$p=yj!$)cLYgt>xMr(H=<7Qi+yKkxHn?GlCHZMop9$;y>Q_cg64p~`v8oda>iY}FIo=9%5JfvAh}oh80HQgM_u31sK9VuN z?5Mq2Upi13ZF`-L8gj7oIMh-ouz9YaVjaIHRAy8k_NpwnS$_XZ$O~I~POM0m8MN@{ zkME6OR4H4SQM%Uplp6agx(XW9#STtOCP?5kGMQyT|1c!^R))spcJdgJMB<6UVpHVU zBhMWg1dZ3f8EMe6-GqD`7;UG@&MA3NWPXtCHt89%}q)N)v)C?J!ihNQ-C3#Tcufe*x z_z;P-H6)}_09f*f=6ne>=a!>v^L*ufR6f`aiFcA#)+x*;gbA^ayERZv+Rf}9 z>9;2@ye}vuET2-}uFjVuTdIHA&>4-{L$t1}LhF4=5LlhFeC#gD01^N{szhm-6Ev1(+$qxLY7Q^K z8%>PDRe{``B9KYUQ|~1i1^1$&Bi)7;Nz<{lbE2h9?#p?OTW!HP3}^GrIQB)@mV<|b zErHmg-`z7FyP)$Y3hoVo<--%cQp>_QsfA5rW6Kj9!N?qj_$uC)NRKxUz8m7!LxqQ* zqGxWhRrFFx5IO&3aGx6Fy%?z$&;ts99MRrkM8{1@+q{aA((MqEVc6IBG0eUgG=ZzU z@GuguWlJ=^0eI5;GwDo7MPp)V395QoJKgYV#I~g^f9>mlFw*d2+IK3>#+Y&^s=oku ztRuD|RUuoj3cjZCUh{d+;Z@&eR^7KdPtK1G1z+>7r7n8M*VL!qjam!meixhkw2+IL zLweeEIBgH$zttPjY9OX17#ty8WnPZ%j)pbCy)N!R z1%03xsV;1N#%0<6D<;&XGy%y9W#_zh@j5YDCh%U%G9|PHT6p$KV+od5q=1_+XZHqD zIAu>}%$yiHSQKKU2Xu%gZ<*Zr_!24uvELjMlX#_%Bt=`HTMcupx77QUC*N^@ciNsP ztZ-i(;N_}aZE-$bv%|jV_GHowZ$dz7;Ej5+9UZL3wrs?6XNQ=}453io@Zd9Th8kx; zbjY^0N#`>$G^p>GG)KW_yz(A_PmLR-xF013&x|_3&*f%!xPoyQfUiIi{(>;#c=l@_ zfsWm3A%{at{tYH3-ecek!GRekVUFPESnOeO!>Ma_O+&21&p8ht$UK6^_2}VV3n#$a z6+RYa+sX~^c*a+I#NYw2KEq+9O1@#@jWJ)<2~N4m7)Ti~Hr92lmcm^G&|E+K1)#hP z?ephCh}cfdFY<7$QH@^K&&=<1Wn6XFTFzfJ17WN|9gTR-$9hG*>+5SU9@kIdt!Ocb zRHpA`})aFel0fJ``9UDE-8{LJc2D&eO{i}g^=h~##THZAd^rVo6;Du zEh&t?5!$vgGup%fiRhv3WS0VIM&d#;bd|BQCHl>;mmEXJaz35aXO%zTbpW9)25sEm z%iGv~1M`R#Bm(?C#d{4ln>POb8unYT@TM_vQ?I8H_@0KgkA)!Bu1I1vH6AQ__@rJQ zIXn0-S{|v>onU9A>Kl;F8?^cOSM_AH^#WP$u8%p1e&S`#xb| ziIiz=iz(saw%&&~gHBSl*ob4xOT2{HsUA$&D(G#K&_Ub%NNC=}J|%5;_qryUSduXj z_5XZ}%ajfa8FSj+${A9N$zcGjS;Pi~152GZsjar$-LYxbu+#>fCs|`qE^BJKj~gJS z0)aCsS!QyFw$qVC@N#z}nXa3XP)^~on2@)*t6E|;=}t^{XQyHLv##b@7wMy>fvC`@ z9vKo{$Gz9*@55&kn=R zn_MUQt~?A)u4?SqZ03A4HZ(KxpwR`I;&nnWzE_robp~q z6!TZf&~RboBPv15W;oYM-*Sp$;D}a>V!HR~!Dz(0%c#v~hh{JXB9sS%j{E5Z13EuHHls`Vko?a= z^N;;f7`45{c?rV86TLv`!&RrX;8AHgC*UUYY+=~cZ}IHc9~x6yaFp)J2Nlp_P)Cf( zgSot?q9R0r&%Cri#&p*ZvbF7dUq`gewNt102bY;~9B@(&*7&=!CgL9+=d1UGD1j$iOMw``Zu?7vVw4YTh4RZU}x=il2@{4-yq@uygr>ixg!p=7B4YAIi+@7~A% z^`F@^$pPwrD*pGoKyaY-mS9JWVqO0Zar2<>)@}l@@7DrYIBKD;lS?&27g{(q(B9Y4 zR#K2t-gbm|u{z;f0h@Y$p!G9!&{RZeS*ltiei~oV)@ggDLGE?#qQ(lU_18;^eX;V( zlhao4HQrg{$E)83CUkcDmGzhv0AH0!*+3U~xBF{zF359AKNAGFFng4nHXHSj0q_V06|I`F#QJ9{zpHQE`c&`nz7rIg9;zS+Iz zJu%CFnSo?gqbe@_3ovzmefN=t=L3~>_zc_av#j@hqh_Y)zKH%Lzi!giYQ)10$~CpF{_Omg=8qO z{3O%Mn1a$^oFRMeQHOTDtLsvhk*f{JB%#YH;*@&>W!iR|`o*J%{0rbJQj8ndh#S|u z*!5qZ(EfQ=`#<=^mSC@`Y8X(pQ8iEA+cbG8SpSL+?OSf$6tP$|R0gA>)X;hKy`&V1 z@u51V`pvSwIx@^uO%B~!mrUgqT?EL1edfUqWe0k^*A{lP;bG~7U*&$3e|UD}0=;r* zS}~*ds~&qd4NK;j&aw?KHUh!)-OcgD`7gj+*UEl?j=%Ob_uVlhR^hmzq5U`@sYd9u zWo~%UldTeL@W!FNhTHYN8tF$dew%;YHhr|T{L5jXCB2PnASOe0uW3ntul5qIVHB&t zmi_TYoPdDhY{hXNa1Iv(zaiw9ew*=2a0RT?GM&+RaUW5$<*}T2lyZ&i3O@{VSNaLc zYuPX(&uJ?-1~X7)?AseXe7tm*hOghK&Ykd$5Mmv z(J*HnS-zc8%a5{m7A*<}^P2Uv9r)C*r zy;p_(pL(3oJQzG`LJ&ea)wbkDAf>zb7k=-R-a(hN^3hucbDeSWiir6!Qo#u{F^w4K zwP+K#(>vqjHXho|_F&7TsaayF3$+BbaBPBemaEEDLJ=Bj%o?AGE8BB3`>QdBCQeYw zxA$Bx@feEGI@YiUXDnu@Cf#ZrGdlZ9{d`(723fCLFAU#NZT^b+!Z9&F3|Va+wLVaC zh^^Bwa+{6|%b)W=!6KhFXwEMpII%@wsUhNcY#1&`>UBtL;jzB^pdV4x5`4)8*-N&U zSo+0rsu9SVMEyS z+)tXvy9V?ds;Z#(yzm&OdC_kpWN!=WjxIFo_ht92UT5Xye>9EjCN(1!4iN*eeE7eN z5}<&;n5bLfBiWw^8n=SbL$S@N!TTmPmZkU|!XkzJaG^8k{xaaA$r*7z5XC~@0{2U< z2x@uCXM;k}`(aW`szBasFr|{&$}au|n0=7~ev!FLgZ3i+0&$zp(mrcoZ8w zzA^dbXDTsl*qVaAHLrLWQQKmCBX3yA+TnMEz~)Lp!&hThUIPjz-so~N++1f?eg{uI zi}}88^iGdM-JT|V2dsd1KYo303mbevMM{O6`>o8=7Mv}t!~EHb!3urIjE%+A16T^; zVw|%W6(Dn#qbEZES!DB%aibKVW4AiG&aa(El#3n6>_10`PWF)^o@Y2_j-<`7q7@X4 zNV<=XawV)+N16;WvqH=$k$jdgRyn&=5H11grDZhS{0aYl`BT=3AAE)AOgW@Zo`}e` z@wLsMPCd{di~~*tY-#}kPT|EZ+8fN{{M3n_jBhv8!upQc%wOSe!r7I*uGz9?-JOYz zGO#nsDx%c~NfA)P2fK#Hn{Fc33BeCI3VJHCoJh(=l2aXY{yPhv&{ zdY@4$q&EQKeA%lbfFN4}2-Kwt+sBN7VUYxzesd?b44W0h7iPA!+7!DL@3rO}EPz`g zj$Aa_4yma=c4jKqCzXj!kq&`9Xqv0t3B{JFOSKkWWyN9m6pYPO8yGBiwq_D11aUW` zR91d2!E8AfM-619Y&_}0ZY_VodQ~6y5G-pns~|^l&41o?QQt6c+4Wn#RZ%w*DtZ*= zIk;g4-L^-3E#76I{SgO+ql?zLj4G0PL<~PdE((+p0?ggsnhm^j&^-)~PJrvky?-JL zLA0_I>5e0@0dD&AE&4m$*pPKC>F=1?vJ1a*2BM~1c;PnIo@lXbqL?6bXCa_6mLQ4k?-kO4$ZC+-Qf%|A-Mj^m$88;3S-Q5zNbd?7#S9)AHa^1ZC$5 zVyWYlf(yot8799o)SU~to71aGs!mJpmr%FSmC0=c_FXq2;05tcIvmq_d+-f>VP*yx zf|Ppfs@TcjmoV*+KA}W^?Cz{d*3dX0-;p^K(eo-Q?>!4jN;84pQ-!tGau+Z2Mq2QE z`zSODX#&P^0HtW6%4Jd9Vy*e=ZDd5P>LUtY zyQ`@FMX$brghev49fE_Tay<#I%3gpV`gS9o&+``+1^Zp5|n%l9v1HbS6zn&}<;o|G!V7e&}KCPeE+ z&B4q2@&#?Bzb1yYRpSq=oZaeIyZmB8JA4L}RSxx^U2QQ{e4sJNYzLnoV#@-(! zT3fSh#Cl)yG^O)I!27Sg|3`c89Te5JuKhL=m82p$3y6Y%48$KpyozR7KT27nU#mdF~UxqtZY53)cTHtZ1-UX!7_@r_sx zns~;Yj0e#_sl`Bq>^Au}(NGibr4k@h&d;WVtY+RlmXpl}K1}gFvf&2{wcY4@%iwZb zo_vSp0|y#?E`pSa?{wmgD%(!^&-bF@+3xY_2!v(m8}NtvAL*}-=r#eyC14g>J`b;!E{Bby}3Ev`KkLl3n&rMyBl=+O$|Jrw+qnTQpnI2W9H|+|(j+=&= zB)`1^>(;W@XV{m)UQLPARmWjHMJ4>Dk9&RtLh!9Qa-}G&=fEnFcjR+>0T#|` zZ~j4P-ht5@2)iHu22?5KI*G$jkS#*_a_+2w#Ag%nI9GzLBtoM$IZV`x{9Zm>>rMd?bSb>Oy@?kty}p=}cvpY#tIr1`AZ zxPIi2X01ql4|b!C0bI7onV1;T0|tIFU!)= z6jn;lM#yl<*n~3V=Gx|jU+M9dvrN#s3`P6*jsA8h-!zLFazHJSV)7?OYYLq|#$c<&DGaqwl)!h$6HeY_m(t@hbg<5lU zg8M_f{Qi0HM1SCK@K97k;my6ceUqj%6T#mAfuidinOu_c>!DPQjUT1h1VsLyKq~5g z0E6V8GX4Ws^pE7ktCK$=M6KF?f1>+GIpKfEP+*f7T+JJyQh5cg=T5VdE2?6zbj8WG zmVY>Ryu)Q9!wc}|!KNk(-Jch}kNwHx&do!LLaft(3WR+hX7H!0eUz3ZXS(mAQDJWE z6;{-gCO0=KkXn`hMOU?3NK}A-z@8SZNW_L0_c-q$rDT6>;5q!LPPS*I_{S`=PRQy2 zGwa=y*e!<1xcgD4^ObLOA+*c*^;s%CZ82+SetGp;yNNzkgQI;ArO0MpnqZ{j#ZQx< z_NBEQ9PFOw#ntPzD5rmPMA1~7`}rZZvpI8EJcecKxkcddgd21)iIUuC-|k*N$l zH_`6hv_`moz<0~N#`&PA`UgX4`5cY4<9(B;aJCd?5^e@|p@*LFlF9TwckTsc*@Q^? zSDx~bbf`ESvNI7*x5zkdzkPi2-7EI~=}Fy{xS*5^0Is~^WfmCL7!-Pc;g2IRbB6T> zcPq{v;z#^hKYLl{==TV+8qJJ+Y+EMx{iCx7-Zk7f7g`7+it&7URRh8w^Rjt*4z7g< zBo{!xc@BD2f51R(vq9+y7>j>W!i)={_XltgRe?Js%gji*Z*8>kI~LRDRnetr2b5NC zSQ3Q>8NAqAJ&xB5Fh|ylFok zpyjgh)}#Z{92sHO2531K4AGmeJ_gTbijsv2Iq+8_6vSiU--yPpk8RI z_QMH6#fBs+WNi|^?f&!wcmd^NZu>(S9`TX_ImKRz89$CgF9qAmy&v>UB;<~%=w+JR z^{Q$hs{WVLx z{9$LM93I0G?{`t+W-H)Buf}$;l7f;UT*!(X-=iin5KnVZ30f*a*qvi={bYv6Gorc6 z#LFW<$KauDEKW1UDmD1K#f!iSJAX|4!wn{2+jiaKFP;(iJ+lm+XR71zU*ZBcsTJ$J z%>thfmZDdf7V=BE@dALe!4GdL#YKiFRf{4gHULoHD$~mWPy<8 zyh4=A+E{b5(Ai4~&;R)b5I@KMDp?c?!Ue7#Q7Y&RFnm6Lw)|Fh21*`F&ODlPo|R?B z-3)KjyOL!{-jz8x;{ww7#igD4QV8bNW}#a-VP!vdcPOL~Z#CE2M3cHa2dQ0ivXnY) zaHFlP1L7EC3J13`c-es-gkk>X)rbo_FGKtKEYt&|`TMI04RMb?w)FP29~~Q;h95Pj zIQesUqdpY84Z`(*WzB;=48=8cl-80T`jqf#z*6v?twh@~J3cGH7Z^m#e{&|`vl5KbQfXTCyh)J@ma%tOqV%H|G8KNJfVr{;2zd~MGdyS4&*nod} zMp7gRwVm^K0p~Wb20*rE*V4@nXo62_8A6cRBO7n|q0`bEOZ1b>oSFgBN|y6xS9d=$ znZg&g%iwh3!GmC?DEE@o&bj4=w&OKJQzb*=pbA?SYnxcSfd=bHj)v|mOmr~n1uE*5 zbI)E@!gG;h_I=E(2Mz62N`wffzK9CQ!DfW2@ubVWx9q8K}gX7JT(vmG}&?>C4pTexqzo%`<3$sLs(yyG7_&oj%T32M8 z??`q>ZqH|V=8#azP?fH$1D7>|2SLvA@H`^Y-zIVSdZG<(221YOPb+fHI2{5S{!;fg_;gh0?R6G21DkYM$T(a%y2S~ zCj3Z3YS9;>ull%+cuJE+4>uP#+_Wgb8^I^48gt9GZ#^^oHEM`q8}uD3(R*T%^+;mPZ-+DRq0 zr{(-|e=KSFHLTW4{#21B%&WM<@&KNmbx6!M5M3Sz-1L7fEa_HmHM^x$7sav`{-z(8 zNXKZeQSW4bs}-5mTMr|lkr|R{)FqAkr=*4IfphtB_~|@0!0Y=K8{qX1xtIE4;9oF- zDd?<0mzz{O(?<5UuYr=c+HV_wJ^S)v@m~TChpXp*pWGa~RJhtW=dwoq>%$`_CgIC} z-n-$%3$LimKB`@NHj3B+WV`!(a@}Bvxsp5y!7>SH1`=m z&RRNTn$kG-S(&TwZ>DXyWHOWCqnY&Yv&!z7I_9_N4-+=c4XmxfO5A&$Kl<}J%-4%` zsBG#917qYm-k-hVp-_7*`S`~B;5 z<~@n%&A$fvNwVkPoqaUH^ye@=wQl{_NDQAi#XZG7nMWr9zw-XPc1Osh+trJ|bTdUy zw~2c8wJtV(RtDcIZj-;-_*wFX{_UTVnvP0M9yY5@1g3sMd1=^+aN+pEKncy2CYvyf zDDJFeza4&PPe3()XX$zX(T0D1 z#uH&nIF0vSkCuYAqr2}`o0X@Hus&`VAt~-y?v3+WBbz6UW4{t~&gQudMsl5F>kgmxjT|h=KU) zpFHEY6?cJxh%xiCDt}Xe$y*N(3<{_pU-GKTNZ!?gyw;gFs%V4jNcouoq zV&$xykT1smvk?~X5lYdH%j|Ro!R>iM2XJRW#A_i^H`cbc1s_E+H$hsWZ)0ci!W8dv_&;GdU0S6B0__vo(O1q zcSEmcD0~)zpl!HqoH)Lpg`i4lSId8%i53Y@T&ht7heulnJAG_&msTT0xBC&-ekHkaR>L#D+{-szJ;LA-I(~d#0+lnjo;&yLcd+D{rNw9 z?zRfkR3*H#67cP6;?ENSAQijPXlHkgA2%O?htFwI|r9T9h7AYQ^5)1rBdvn~N^I}UpG4{+KEeVdU zLL>wnu<^x!Muq0>OCTSPmR+ujM$~1*O_UF@sk*>x{0GcTX|s$hXA;qIY1jbo%gNG- z$!)us1R&Id2!MZP!g5h&Zgt-9$)CPEDg$9No^-T|7=ecfx1xeuKJi-K)$oO-vrg!M zdL)>K5o(L99N3h^ajfCOW`re<>vIopO|roEKTanEd(fhNU>DXFrV$3_PuGW(N}VQN z$wlpt*Sdas#^4;*4b(huH(=VR(ipTE~;@8erxTNn)c%e>2 zJ}}IQWX46l4Q%{_e=Yzby}OY&6Q|HM1@W!)dCRkZc8*!L~xGCI3h(%zvhi zKjQuzK=MwxX{av^N8`c@=0MCcm#F%SS*r{rg5p=}low`XCd>SZOsfp)?Yq2YrEgR; z4)bE4U{!3i>xOZgT)mW8bB7V%&uwg&uC%_l^eX^UgIt~`FOh8)$gCCoQngo`ahafW zFDffe=v-vGexp5KG`_g`s$yRN)8jzH1@pp3-Oe=J6Yd?u(0w zWVHa?`#s95w*kL?12US@c_?fNM;7OieE~q3ik2S=o>E1Y4Bd8h`|T03LD8dcPk$uS z5yY+7w699EBp&irYx83p(292|vJd$^8R9+N$euK|w5g9DWsMKG4gL-I7##ocJQ!sSlcgu06 z`h*kSk4Z6d-M3qpewTssC7CY^tII3r7dt$I19+Nrbt4Y9)znzN@kU1^! zAp0UkamL{;TT`Ogl|A;}ft(cK7=GK_IT>LV>EPpwoANO@X{7S@J$X6r`o?;KSO%_j z`flXxHtO=>8~Z;}yE%sprP#=lDuVQWMs#yNPfwwad#u9Q=>r0{%l)~wO3Pefs7Gkj z$vM^?&)nrow$9fl|9jqy|1QJx|LC051CLcE zbI@L%v|ISX*?0)0RFa(-INZ;hiF{8ZS3teeh!8pg3F|BD?E}81q-vH6NAD8{V0VZoa zl@UI!*eCcV{pMw!1U(ocQ%}x`T?kCpHg&T@v$pfm7KMU>wN7ydac6zIAEJf=-u%D0 z`S@?_PyX*T$=%6x7D=0G5*TAE$%D_QT5`B5D9Y!$N4uYl-N8O+x|_GkWMbO5K}I-3 z7+12=T6p~`P9NOONRZX6U|zUbG~f{nMDy!#A!}54$nivD3f}F@?GQCz*JsLkkD@+X z@`=!8D>UkyGyXu$TGsm$Lo=9!k56eD@koRi zb(NgF$Lg@p!~muSIY2_uKd^$WSR(1Cybh&%d-SS|!j7%!NMrk^iF;hC#hq+)mugw_ z#XS84pb+>H9sd-KG2E?XjBeyKdW_n^c~Mz5HQM>h`UVhdMina_E49g^R*sz*ax`YC z?GG*S3$L<17`X3WNq%R{uiuhtqXMEZ8Yo_woT9x@x>@F=xS7x6J*OnQLPthF zmH4iG}_|H{hxbLM;bcpEz-dxY2U zh?~ZcY6QEI3fl@HK4X#nSz;zzEDHhydxSi5VzgZ^=l-#hm;qVVsNyP0Zd|vA)Qe8z zJpWX~*Q569T@OTpVCfC>W8A*EgirrX7yezh{s+zxcOW5SdVwAA%7N#iqRM?HUFK<) zv>jj8$EpWBt}=!_G4J=EhHtf~U5@pBwzb$np2y z=IzbgR;S$*J+l-%b$tPEp&1mJ19VC@9HW)HkG0Z9_uSP-HW&IOfYl-~Q#6jkj6@}2 zB5uB*ehvY^*f^?l8tZ(xb=vf#as$oCo7-$zP>z_Lv#mo*QAXPe6}{+|?1gTT_jwTJ z`Y}>2H}=XMC*5K+&>;?R=$S90Y;aSrR}rjA=%Coy@;L#Jm17B_5ilS3Ht60*@eZ|+ zJGix2R}_O=!$9&}V$t%|1AIG?^O@QDwd;UE!*ML)YER+qICxJ^D}P_K^|cy)+9xQr zf|cu_^N-Bo0~+Fp7wmivy|`lMFm65mxog0#TN)~+q&VB49WS9Z{^G|e50CV&=lfGH zmczk0NV;O)FkS4L0*7L1t^Ux~-Y2G?vX(S1I>{tIyYB=qIz8G58aZdJ_&hOK@Mx&&9n8aK-|A4Ze%p!x!{yW;QnQKDM^nZb&2kkZ7xokN zMil!*)!l?fh5WSn+Y2C)vC4qNRm0)^pBCOQA(5h%x$;cssVQQGqDGj@32A<;Yrd8B z165_804(BIMf$1an*j|hSKx*@~F=oz~Epv~`2E&jgC!>-_PIudd`(W&9s39*H&oYS;`HX44 z@*VQ=cN>4IlkP?c*W>>rqQ$DvE;lKcyc}Q&5;`1p(y-RR1$U6jgFxOHfJ<3s{B3{2 zD(QOyy;k)m+|Ju2&wl7mHmgX~H_pyOy~8}jJU5#v7NfwGrrF!w%VOZIQz3LUcpRHh zRFo{{dw$!OZSYpjk*|;ZhWJuLWowc9A_jV%&4#{|Xwi~3D;fNjYU}5aG6N9~wqGT7 z-35KGOhKO9T>hF)nZ4z!4AM%bE&yj2miub0W|yxO#Z8D_sa4!uXUvZ%w0gMV^rLb^ zJ*0MYs+0_e&+^sE;Nzd;btk_$R{7L4{y2$<1tq1M$R(h}x@5Z)Ro6Tv_ubI$h5_8% z@Cl3X{Mxa;GkJ}`rgMFSt992p97uEy3jO8(tO#5cFcCBMNGcP(w~sV0VfHHVom4u1 zlpr8aQCo}lJfK?-lYG}L`3hNGJ`k3dm#sF7lxZ@tNjm!OOIp%WmH|xsDitHqHiW-u zC|krhQ&(0yP<#-mvs~OFJ(_qQNmzkwy1uN*{KCxhHu`|7)`#P9Zl6(yvE-VCS94&@&`|TwFbRyleSsK z`1w8V7@;5OqihZ8=KPL?&K(&hCc9SABw>2CcJL`b>5)^nq)~%@+*yYcrEX(S9~g-K zIqSZ2$6Y>8&KWcSr*hC=2OP*dY124dbLl(!V)k)rZ03p3v2*~241b{G=VS^=bZqLf z>Xtc=x#J$Q**0COW42Pz3A3V&o1g#S%ERshJb-`}4JQ_gXk0RxhSA=p-($9~Lq4dR z;WC$(GG9=UD=Bd}o1uv-5+KlG6rcFT}kGM|CPwz;_!$HFs};>h(`XSd)?^DhNzpD2(U_Xck&qA>X>UBg6^wv=5($xeOfOE(IESV4ySO|m2N-^mqYnmxo%1s(iK3tcq3FTSb*NM<548bQMdX9k?`K7z?aF3YjpU_D24Vq3xPa_aEHd=;$O& znrr>T@^(1-)P6OkN``%9ev2t#bABpl;ha7gHh+85!nh!~XB+%zVx117vfY6u<^4K5 z0p>U3iI~vV@^e9r#Gwx4(?A>GgH4O9`(7VD{10q*|F3UJ9BCiTYe;te_B#`GA;J#( z)f8Vx4@l{HAZqF&Xz8wzc;FslB8nPOkNv~!%;#=IY=oRi+?>w!CI?!TqfJz6kg?A? z(qe8dWw8`bhLSh)Sej&Cc!m!({H*P8nMm`llalj8Y+Y2INvU2D4C!#E;+B{aOVmqN z&ox`6Sff1SC<%*QQH9_TP_~NWfT(-3>6>JCLvu?Ho5xhj=aPOSKsQhPZXobH`~K-X z_uJeFy1=k=hlHVA*atOQZ;$0A6QwU=cmZL}QL5YX4*PSy1Bf(m(XxxJEs22ed4!0B z4Swt$u;M||g5YssOgo;{YL&`vy(;q6Cb391)Ke1f2~=Uj>B!m;+wTez1-{D$h;w}w zK^YcH*tE{?rM=}wMd?Vts~xXvj2D0ZwHE2!&-f$b;jU<6w0}L|u0u z?S=DDg{=V;&@HyX*89>}DEKTz_N>-5Ez;KYY{RdlzI&kya;A0PMTvFV4b#OKCh1Yu zR9{28G#TcaCcBy*vFAK4O`fw=9Mu%G}_^Sm7gAy*z$bp7}|@A)$nQ^cZ1=w$|h zO7AiZ5S>l({?)Ffe81HMr6~W*4HNX;iF@(N&J*ADa7nk`#5#3g)JDe~j!ZC8s} zW7VsR)!4$CKDIMkkTQN_FU=uSkclr9OeEO5z-KAz(%$&~9Pl zbcvce=n_}b%2@xE%2>ayEtc5@22dmtAdLKgR*}p}8M`T-KP4+_G;u)-6y?#|ZmXHQ zI>KTSjk3TAsF7sbulh5m`Vpyz<0JRh_utjLNRW8q07$O& z2_@5P!&#+_ZO`Qs**Uj;*a<4AAD%|JI9nH#3o5BB!q2V5mD~f^kE53ohpm;7uNJt4 zm0b9e3EGuP9iBP5o{}XLD6fx7b3$==9mqTw-er^IeBKqmF6B$(o!ip@B}V}FP9oA; zOvAady~yIwNo^2yPEt=Y_RL!=SWHM&nb6JEZ1FDDy%_lt?mS<4N463h(paht>J}xB zxr}$+z%C`)ooNh0fj70N#t8-Nmxb%-j*RIEG>Jz{M!finbPlk?HSq}CKY!{ryw?;l zf%eTebmXFw=mhOSO}1UV4Fu9uSRdXM?bjGSk9s8A)~Lq!x-(6%sa8|?6Zo_IxZ~R6F1;?s5p&AXro5^cgfZg zJXY>{hg*1%4SR@^XrHKy!t}Lg^H;-?oihhx>42DmFVfh6%Ls?nAIcu1rr7$%C40_L z6agmJS(wmDFHod|Nw*881~o=`=11f= z2T9KjER22ii#(PTCG735)%3@oy=)Hty$t63zkkS!foL@jM`|| zMD6Vz4xWf`t@hV_Mvp68b+>I(-^GI0PwYn8fGn7*&_GN8tyxLtGjs1oBge9Xx;S04 zg87BvD>WyH3aPfYo;kuZ4rG`j&!xin|A0dKUr@9^kM8HOV2I;Cghoa3(IPwjr{*iR z8G*vW=ytoYlas;yJ)IBsWl%f!1)FvW(=nQEtw&6QQQeiUNXM2@$dhWd5?(_h4pF=D ze#ycj80-&m)~AHd{Q>}XU)pWG;I3;Q>ivZo#zDA(D?(T0<>a`;qbebR#=)p;s}vIG z97A-@`6CNzD}+VKHEq?zIiq<mg zc2|EsSKmo(VC7giHnn?&>+`}|0=4p`VjN>Kzgr(H_}vj8ryVruKpRYB~GE`U|%ANzl)1Q>)Hf;|m6>q&Mb#;v!L2(=j z=ZT&lrqo*FC5DRiFkF`3xxC8Om~@JrhrG@&9#2tY6r^{7S{kUbX4zkf(C#h8x2M>U zHM&c3q3j*5urCwNV_L9g1O2GI;JmyIhe8U2aXD3*r8kbih5h3-dlo^-j8*AOq-lxU z_(N@Thf=IvX?K8@E`@E(1xqwMjEsn|_%*@@hB*rB)bKv_?VDNLza4Lsn;T-9qPkY^ z?ea_*VhL+js+sM|FW7sy=vGv;M^~(A(DAf9(O@KFOnH*JdiRSxAl?+d1d*?zd7szn zq&oOb;(1BYIQ7#iY91{{_M}nGOLmC4l$yK^`?}&a&zX5bL}>Wds>K5h4-`0{%GW%1 zYPK>rH%d*d#G2X|vPCQ8MYW3ungL3ZkYyR`lUgd3!7{^d&1&KFzfvSVKboMt|0(k; zqNe8?J&^-}s3^4m zrXzo1ehab6z45D#dSa@S*8Svm75m_6?UV#YeWl>}(4W!kCDOP|tvoT}gVXvD6fbbsH_?Rq$O8nbY&L6#W* z;>9RAyL|`upnH9cb=kFI^Hwmkf6>^u0gxrw)#tNoS+emHw=>}i&)Iqh$*Y#`FXW-@7c5t-DAn<@hT$>8k=Nssx(dd| zts|wYNib+|IN$WB*Is^N^b%LAy~~8YP~!Y)u!}~p=R;j|>6Z>l68q$E7W#q!hD4}< zKk*R69tfMLGO!_W0+z)?PH1oHw#%p|`N2Bw1?4<<%}o8E?r)(w@eEsZW^WsAZ${WUwMw zSYbzNh?v<}eIUBzlL2+t(ITN0!@KqSfdU`L>B44;Z%lUrvz1QY+kmeu2O4iykL*EG z@mO}KCg6}&TS9i6E)8ip3s;PW6(aQ2+~ z=(w_u!MV)~sTG?sl!p0%g6wC^UsbzSaa+OQ!+NHtQa^bO6CGyvi)+rZeMSTOF4g?P zC+?i$J3AVy&3#pyZ+s8KFlwqui63{~=|-=8%eHX55_O)nDEYKu$w+Emmppo9r;|!H zd{M-6hGu-%yCEeh8~h@wlWSl6TKg=$%I7wH+@~&$Uf#jx-O+Hj1jZ-cjXxR_iS*^lFdK7i`C9=OM)kt2I>I$4v@P`FqVS{)m3}x$~PLA~I}+KvvS1=_k`gxyhou zBg$P%gRB(MY0>v)7`zdc}Hh*WMi5q`fyjHsL_ENmv! z9Tgzdqf(avE(w_Iy1Na7mvEz#Hpuq6_Bg&ShWsI+Zg_u8(5I(beN*ehhw;6^UC#`R zG;ob@oX%9!L!-iS0Px0+ci4^uJx+|Xs+xXqH92Co(JKO->Kn0_-$m9<3Rp0mh2WHN{ zPq&jXp51)<2$K+kJEf0{h8z3UE2TE&Wr`J#MR2+do-GrxVB)euhC9g zDye^3Un4SiD+j0lvc6uY^XLGI!wTzwvNy#&eVK-hrBDZh3uOOL9$?6ZMN8^p`^Cd>%$KCNd&S*;wti z8sm`)sAj>n{_f*-#Zi4FeygDmj=<~J&Tmy;-^$)9pHEo8PVLK(0|N)h%AKY`&zRYO zLH=wKkD8IKbXV!P!ZAU`?S8#S>N))5)?LbJZS6<^NxXQd*w%Xl>G~88N3gn~IQ5w6 z!o?1U%ii;%AP}ERB+%MnHB3>`;NFdfb^Wl;cJoh}gZ;xKt<~$bmeb*zx=HdNCbN+6Ia(+p!yki(q-Y2z;RlzKWJB(SquI z#~9Ri+vsTko(+?imeh*^F23Y4XHz#{QE?jAK|o!ZYJ><|)|UX_O*v2Aj$8BSy>f+M zj$nQuh0c!|Bduf;WjSScn=_o5PNd@bIh&k&_Nb%N9|NxHI_Giml0YGnuydTS)Ut(CDkbIJ|trpizQ;Y z?rwCx)i%b@tPe4pMd_``J8S4lgvqh2sPAnP?TkNqgp!+KOg=7k7k^i8degG!z5l9q zwj2_vIE^8h{ziXfhU-UYpB!!N#?KH6Tsoyi=IGfH3kMoHZP~o;oSW*UC)eA_3;V{ye z6M{_v+|14*er+pbxH$rTe8b5Tz`m;}gZ?6i|XZ%YBDkm3y ziYv7#kpuDW1h8aywS@1w>rXkm4Pb5FcPNGQlQPf!`|KL4V-lspaRxm%M^*xK@-QaC z2jx-%{o4lyfm(Tfm8X%Ag}nn2pM8--WaTOqRiz%K2y84#KwBW~H^3qFG$&25+n6Fo zk--G=l^hW^3OvN~f7X?=_Tc{i;GXE;-`qoA5Y9-bQJ(D%3tKjJXfe&$(4H$9+F+Y| zv7RvULz?aElwk9NY{%2r%_uHy&syY}C&M)F*m12-nL2{W8-2Y1})3a?VIHM*I? z0a;Y-hU`8+NbF(HMbj)Zsw z1Q!5u02zPMmU39q%w!yFMDNsK`oL@MxkRmdVM*vY-1SQO+^=qAiCB)wnb`qNSFUep zRGAFft>d0gQ^`~@>a!aMa5y-(gFXjS}IX;^dUZL z_frOdJQu|8fDzx1+kp%?D;12H4qtqHh1-wjxZLU?pXYCUzZDR)_`M4iiKQDBe3uxV z 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 literal 0 HcmV?d00001 diff --git a/doc/source/addons/AGExtQuickStart2.jpg b/doc/source/addons/AGExtQuickStart2.jpg new file mode 100644 index 0000000000000000000000000000000000000000..7e98dc4cd13a551e00a0289e85d9c90f15f39603 GIT binary patch literal 59285 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 literal 0 HcmV?d00001 From d4297b3a24f2d7d2e400186e081a2a63351545c0 Mon Sep 17 00:00:00 2001 From: SirDiazo Date: Thu, 8 Jan 2015 13:14:11 -0700 Subject: [PATCH 078/446] Update AGX.rst --- doc/source/addons/AGX.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/addons/AGX.rst b/doc/source/addons/AGX.rst index 2b94638e2..c552e64d1 100644 --- a/doc/source/addons/AGX.rst +++ b/doc/source/addons/AGX.rst @@ -17,7 +17,7 @@ Caution: Sometimes, AGX will return an unexpected value for a group's state (On/ **Basic Quick Start:** -http://members.shaw.ca/diazo/AGExtQuickStart1.jpg +.. figure:: /AGExtQuickStart.jpg http://members.shaw.ca/diazo/AGExtQuickStart2.jpg From 327392a7e0d5f10ed5a037362c0bf5b1bf79822e Mon Sep 17 00:00:00 2001 From: SirDiazo Date: Thu, 8 Jan 2015 13:15:43 -0700 Subject: [PATCH 079/446] Update AGX.rst --- doc/source/addons/AGX.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/addons/AGX.rst b/doc/source/addons/AGX.rst index c552e64d1..125830643 100644 --- a/doc/source/addons/AGX.rst +++ b/doc/source/addons/AGX.rst @@ -17,7 +17,7 @@ Caution: Sometimes, AGX will return an unexpected value for a group's state (On/ **Basic Quick Start:** -.. figure:: /AGExtQuickStart.jpg +.. figure:: /develop/doc/source/addons/AGExtQuickStart.jpg http://members.shaw.ca/diazo/AGExtQuickStart2.jpg From efed20b85d3d0d0f81483d058923f7b5b71c0995 Mon Sep 17 00:00:00 2001 From: SirDiazo Date: Thu, 8 Jan 2015 13:17:53 -0700 Subject: [PATCH 080/446] Update AGX.rst --- doc/source/addons/AGX.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/source/addons/AGX.rst b/doc/source/addons/AGX.rst index 125830643..1afbf8140 100644 --- a/doc/source/addons/AGX.rst +++ b/doc/source/addons/AGX.rst @@ -17,9 +17,9 @@ Caution: Sometimes, AGX will return an unexpected value for a group's state (On/ **Basic Quick Start:** -.. figure:: /develop/doc/source/addons/AGExtQuickStart.jpg +.. figure:: /develop/doc/source/addons/AGExtQuickStart1.jpg +.. figure:: /develop/doc/source/addons/AGExtQuickStart2.jpg -http://members.shaw.ca/diazo/AGExtQuickStart2.jpg **Overview Walkthrough:** (Video, imagur album, animated gif, something) From 3428a10b160193d95f65a13e43c2adb011554508 Mon Sep 17 00:00:00 2001 From: SirDiazo Date: Thu, 8 Jan 2015 17:39:19 -0700 Subject: [PATCH 081/446] Add PartsInGroup and PartModulesInGroup --- .../ActionGroupsExtendedAPI.cs | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/kOS/AddOns/ActionGroupsExtended/ActionGroupsExtendedAPI.cs b/src/kOS/AddOns/ActionGroupsExtended/ActionGroupsExtendedAPI.cs index c3e6ee473..141679c0f 100644 --- a/src/kOS/AddOns/ActionGroupsExtended/ActionGroupsExtendedAPI.cs +++ b/src/kOS/AddOns/ActionGroupsExtended/ActionGroupsExtendedAPI.cs @@ -59,5 +59,30 @@ public bool GetGroupState(Vessel vessel, int group) var args = new System.Object[] {vessel.rootPart.flightID, group}; return (bool)calledType.InvokeMember("AGX2VslGroupState", BINDINGS, null, null, args); } + + /// + /// Gets a list of Parts with actions in the specified group + /// + /// The vessel that will catch the action + /// A ActionGroup number from 11-251 + /// List of Parts with actions in the group + public List GetPartsInGroup(Vessel vessel, int group) + { + var args = new System.Object[] { vessel.rootPart.flightID, group }; + return (List)calledType.InvokeMember("AGX2VslListOfPartsInGroup", BINDINGS, null, null, args); + } + + /// + /// Gets a list of partModules with actions in the specified group + /// + /// The vessel that will catch the action + /// A ActionGroup number from 11-251 + /// List of partModules with actions in the group + public List GetPartsInGroup(Vessel vessel, int group) + { + var args = new System.Object[] { vessel.rootPart.flightID, group }; + return (List)calledType.InvokeMember("AGX2VslListOfPartModulesInGroup", BINDINGS, null, null, args); + } + } } From 8f709995f2319645634f8cfb1c7421b5a34d6513 Mon Sep 17 00:00:00 2001 From: Chris Woerz Date: Fri, 9 Jan 2015 11:30:53 -0700 Subject: [PATCH 082/446] fixed build --- .../AddOns/ActionGroupsExtended/ActionGroupsExtendedAPI.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/kOS/AddOns/ActionGroupsExtended/ActionGroupsExtendedAPI.cs b/src/kOS/AddOns/ActionGroupsExtended/ActionGroupsExtendedAPI.cs index 141679c0f..3722a77b5 100644 --- a/src/kOS/AddOns/ActionGroupsExtended/ActionGroupsExtendedAPI.cs +++ b/src/kOS/AddOns/ActionGroupsExtended/ActionGroupsExtendedAPI.cs @@ -1,4 +1,5 @@ -using System.Reflection; +using System.Collections.Generic; +using System.Reflection; namespace kOS.AddOns.ActionGroupsExtended { @@ -78,7 +79,7 @@ public List GetPartsInGroup(Vessel vessel, int group) /// The vessel that will catch the action /// A ActionGroup number from 11-251 /// List of partModules with actions in the group - public List GetPartsInGroup(Vessel vessel, int group) + public List GetModulesInGroup(Vessel vessel, int group) { var args = new System.Object[] { vessel.rootPart.flightID, group }; return (List)calledType.InvokeMember("AGX2VslListOfPartModulesInGroup", BINDINGS, null, null, args); From d08ea1226b83a511ec7890bed732e7edd0289a1c Mon Sep 17 00:00:00 2001 From: Chris Woerz Date: Fri, 9 Jan 2015 11:31:20 -0700 Subject: [PATCH 083/446] fixes #500 --- src/kOS/Suffixed/ActiveResourceValue.cs | 8 ++++---- src/kOS/Suffixed/AggregateResourceValue.cs | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/kOS/Suffixed/ActiveResourceValue.cs b/src/kOS/Suffixed/ActiveResourceValue.cs index 458b2e821..8fe8c13c3 100644 --- a/src/kOS/Suffixed/ActiveResourceValue.cs +++ b/src/kOS/Suffixed/ActiveResourceValue.cs @@ -18,10 +18,10 @@ public ActiveResourceValue(Vessel.ActiveResource activeResource, SharedObjects s private void InitializeActiveResourceSuffixes() { - AddSuffix("NAME", new Suffix(() => activeResource.info.name, "The name of the resource (eg LiguidFuel, ElectricCharge)")); - AddSuffix("AMOUNT", new Suffix(() => activeResource.amount, "The resources currently available")); - AddSuffix("CAPICITY", new Suffix(() => activeResource.maxAmount, "The total storage capacity currently available")); - AddSuffix("PARTS", new Suffix>(() => PartValueFactory.ConstructGeneric(activeResource.parts, shared), "The containers for this resource")); + AddSuffix("name", new Suffix(() => activeResource.info.name, "The name of the resource (eg LiguidFuel, ElectricCharge)")); + AddSuffix("amount", new Suffix(() => activeResource.amount, "The resources currently available")); + AddSuffix("capacity", new Suffix(() => activeResource.maxAmount, "The total storage capacity currently available")); + AddSuffix("parts", new Suffix>(() => PartValueFactory.ConstructGeneric(activeResource.parts, shared), "The containers for this resource")); } public override string ToString() diff --git a/src/kOS/Suffixed/AggregateResourceValue.cs b/src/kOS/Suffixed/AggregateResourceValue.cs index 1c43195dd..d9d562627 100644 --- a/src/kOS/Suffixed/AggregateResourceValue.cs +++ b/src/kOS/Suffixed/AggregateResourceValue.cs @@ -25,10 +25,10 @@ public AggregateResourceValue(string name, SharedObjects shared) private void InitializeAggregateResourceSuffixes() { - AddSuffix("NAME", new Suffix(() => name)); - AddSuffix("AMOUNT", new Suffix(() => amount)); - AddSuffix("CAPICITY", new Suffix(() => capacity)); - AddSuffix("PARTS", new Suffix>(() => parts)); + AddSuffix("name", new Suffix(() => name, "The name of the resource (eg LiguidFuel, ElectricCharge)")); + AddSuffix("amount", new Suffix(() => amount, "The resources currently available")); + AddSuffix("capacity", new Suffix(() => capacity, "The total storage capacity currently available")); + AddSuffix("parts", new Suffix>(() => parts, "The containers for this resource")); } public void AddResource(PartResource resource) From a77265799ea150e321ddbaba4c8b589805863ef5 Mon Sep 17 00:00:00 2001 From: Chris Woerz Date: Tue, 6 Jan 2015 09:22:57 -0700 Subject: [PATCH 084/446] adding gimbals as well known structures --- src/kOS/Suffixed/Part/EngineValue.cs | 1 - src/kOS/Suffixed/Part/GimbalValue.cs | 35 +++++++++++++++++++++++ src/kOS/Suffixed/Part/PartValueFactory.cs | 3 ++ 3 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 src/kOS/Suffixed/Part/GimbalValue.cs diff --git a/src/kOS/Suffixed/Part/EngineValue.cs b/src/kOS/Suffixed/Part/EngineValue.cs index d80d5d807..a0d973cbc 100644 --- a/src/kOS/Suffixed/Part/EngineValue.cs +++ b/src/kOS/Suffixed/Part/EngineValue.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using kOS.Safe.Encapsulation.Part; using kOS.Safe.Encapsulation.Suffixes; -using kOS.Safe.Utilities; namespace kOS.Suffixed.Part { diff --git a/src/kOS/Suffixed/Part/GimbalValue.cs b/src/kOS/Suffixed/Part/GimbalValue.cs new file mode 100644 index 000000000..2d1639115 --- /dev/null +++ b/src/kOS/Suffixed/Part/GimbalValue.cs @@ -0,0 +1,35 @@ +using kOS.Safe.Encapsulation.Suffixes; + +namespace kOS.Suffixed.Part +{ + public class GimbalValue : PartValue + { + private readonly ModuleGimbal gimbal; + + public GimbalValue(ModuleGimbal gimbal, SharedObjects sharedObj):base(gimbal.part, sharedObj) + { + this.gimbal = gimbal; + InitializeGimbalSuffixes(); + } + + private void InitializeGimbalSuffixes() + { + AddSuffix("LOCK", new SetSuffix(() => gimbal.gimbalLock, value => + { + if (value) + { + gimbal.LockGimbal(); + } + else + { + gimbal.FreeGimbal(); + } + })); + AddSuffix("RANGE", new Suffix(() => gimbal.gimbalRange )); + AddSuffix("RESPONSESPEED", new Suffix(() => gimbal.gimbalResponseSpeed )); + AddSuffix("PITCHANGLE", new Suffix(() => gimbal.gimbalAnglePitch )); + AddSuffix("YAWANGLE", new Suffix(() => gimbal.gimbalAngleYaw )); + AddSuffix("ROLLANGLE", new Suffix(() => gimbal.gimbalAngleRoll )); + } + } +} diff --git a/src/kOS/Suffixed/Part/PartValueFactory.cs b/src/kOS/Suffixed/Part/PartValueFactory.cs index e6a6f8044..9bddea423 100644 --- a/src/kOS/Suffixed/Part/PartValueFactory.cs +++ b/src/kOS/Suffixed/Part/PartValueFactory.cs @@ -34,6 +34,9 @@ public static PartValue Construct(global::Part part, SharedObjects shared) ModuleEnviroSensor mSense = module as ModuleEnviroSensor; if (mSense != null) return new SensorValue(part, mSense, shared); + var moduleGimbal = module as ModuleGimbal; + if (moduleGimbal != null) + return new GimbalValue(moduleGimbal, shared); } From f18963100a49447c55e78a7cb44e7820e526f74b Mon Sep 17 00:00:00 2001 From: Chris Woerz Date: Wed, 7 Jan 2015 14:39:05 -0700 Subject: [PATCH 085/446] forgot to add file to project --- src/kOS/kOS.csproj | 1 + 1 file changed, 1 insertion(+) diff --git a/src/kOS/kOS.csproj b/src/kOS/kOS.csproj index e1c4f7d61..0ad827025 100644 --- a/src/kOS/kOS.csproj +++ b/src/kOS/kOS.csproj @@ -97,6 +97,7 @@ + From 4f844c7523cdba4197afda93e3c4e6225f4f4d7c Mon Sep 17 00:00:00 2001 From: Chris Woerz Date: Fri, 9 Jan 2015 17:17:51 -0700 Subject: [PATCH 086/446] changed my mind on the caps --- src/kOS/Suffixed/ActiveResourceValue.cs | 8 ++++---- src/kOS/Suffixed/AggregateResourceValue.cs | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/kOS/Suffixed/ActiveResourceValue.cs b/src/kOS/Suffixed/ActiveResourceValue.cs index 8fe8c13c3..75c19b526 100644 --- a/src/kOS/Suffixed/ActiveResourceValue.cs +++ b/src/kOS/Suffixed/ActiveResourceValue.cs @@ -18,10 +18,10 @@ public ActiveResourceValue(Vessel.ActiveResource activeResource, SharedObjects s private void InitializeActiveResourceSuffixes() { - AddSuffix("name", new Suffix(() => activeResource.info.name, "The name of the resource (eg LiguidFuel, ElectricCharge)")); - AddSuffix("amount", new Suffix(() => activeResource.amount, "The resources currently available")); - AddSuffix("capacity", new Suffix(() => activeResource.maxAmount, "The total storage capacity currently available")); - AddSuffix("parts", new Suffix>(() => PartValueFactory.ConstructGeneric(activeResource.parts, shared), "The containers for this resource")); + AddSuffix("NAME", new Suffix(() => activeResource.info.name, "The name of the resource (eg LiguidFuel, ElectricCharge)")); + AddSuffix("AMOUNT", new Suffix(() => activeResource.amount, "The resources currently available")); + AddSuffix("CAPACITY", new Suffix(() => activeResource.maxAmount, "The total storage capacity currently available")); + AddSuffix("PARTS", new Suffix>(() => PartValueFactory.ConstructGeneric(activeResource.parts, shared), "The containers for this resource")); } public override string ToString() diff --git a/src/kOS/Suffixed/AggregateResourceValue.cs b/src/kOS/Suffixed/AggregateResourceValue.cs index d9d562627..51c8185ec 100644 --- a/src/kOS/Suffixed/AggregateResourceValue.cs +++ b/src/kOS/Suffixed/AggregateResourceValue.cs @@ -25,10 +25,10 @@ public AggregateResourceValue(string name, SharedObjects shared) private void InitializeAggregateResourceSuffixes() { - AddSuffix("name", new Suffix(() => name, "The name of the resource (eg LiguidFuel, ElectricCharge)")); - AddSuffix("amount", new Suffix(() => amount, "The resources currently available")); - AddSuffix("capacity", new Suffix(() => capacity, "The total storage capacity currently available")); - AddSuffix("parts", new Suffix>(() => parts, "The containers for this resource")); + AddSuffix("NAME", new Suffix(() => name, "The name of the resource (eg LiguidFuel, ElectricCharge)")); + AddSuffix("AMOUNT", new Suffix(() => amount, "The resources currently available")); + AddSuffix("CAPACITY", new Suffix(() => capacity, "The total storage capacity currently available")); + AddSuffix("PARTS", new Suffix>(() => parts, "The containers for this resource")); } public void AddResource(PartResource resource) From 6829056713bad88aaa5d38b3c15111e75e4a8b2f Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Sat, 10 Jan 2015 17:59:20 -0600 Subject: [PATCH 087/446] Temporary commit so I can work on bugs in develop --- src/kOS/Suffixed/Config.cs | 22 +- src/kOS/UserIO/TelnetMainServer.cs | 41 ++- src/kOS/UserIO/TelnetSingletonServer.cs | 372 ++++++++++++++++++------ 3 files changed, 316 insertions(+), 119 deletions(-) diff --git a/src/kOS/Suffixed/Config.cs b/src/kOS/Suffixed/Config.cs index fab656c28..61d798532 100644 --- a/src/kOS/Suffixed/Config.cs +++ b/src/kOS/Suffixed/Config.cs @@ -189,12 +189,11 @@ private enum PropId public class ConfigKey { private object val; - private bool valChanged; public string StringKey {get;private set;} public string Alias {get;set;} public string Name {get;set;} public Type ValType {get;set;} - public object Value {get{return val;} set{ valChanged = (val != value) ; val = SafeSetValue(value); PostChangeTriggers();} } + public object Value {get{return val;} set{ val = SafeSetValue(value); } } public object MinValue {get;set;} public object MaxValue {get;set;} @@ -243,24 +242,5 @@ private object SafeSetValue(object newValue) } return returnValue; } - - private void PostChangeTriggers() - { - if (!valChanged) - return; - - // I don't like doing this this way, but I had to put the catch this low-level or else some - // cases of changing the values skips past it: - if (String.Equals(Alias,"TELNET",StringComparison.CurrentCultureIgnoreCase)) - { - if ((bool)Value) - kOS.UserIO.TelnetMainServer.Instance.StartListening(); - else - kOS.UserIO.TelnetMainServer.Instance.StopListening(); - } - - valChanged = false; // reset for next time - } - } } diff --git a/src/kOS/UserIO/TelnetMainServer.cs b/src/kOS/UserIO/TelnetMainServer.cs index 937881458..191745e99 100644 --- a/src/kOS/UserIO/TelnetMainServer.cs +++ b/src/kOS/UserIO/TelnetMainServer.cs @@ -8,6 +8,8 @@ namespace kOS.UserIO { + [KSPAddon(KSPAddon.Startup.Instantly, true)] + /// /// A single instance of the telnet server embedded into kOS. /// Presents clients with the initial choices and connects @@ -26,14 +28,33 @@ public class TelnetMainServer : MonoBehaviour private Int32 port; private List telnets; private bool isListening; + private static TelnetMainServer instance; public TelnetMainServer() { + instance = this; isListening = false; - gameObject.SetActive(false); // Should prevent the Update() from triggering until we turn it on. telnets = new List(); + + DontDestroyOnLoad(transform.gameObject); // Otherwise Unity will stop calling my Update() on the next scene change because my gameObject went away. - kOS.Safe.Utilities.Debug.Logger.Log("kOS TelnetMainServer class exists."); + Console.WriteLine("kOS TelnetMainServer class exists."); // Console.Writeline used because this occurs before kSP's logger is set up. + } + + public static TelnetMainServer Instance() + { + return instance ?? (instance = new TelnetMainServer()); + } + + public void SetConfigEnable(bool newVal) + { + if (newVal == isListening) + return; + + if (newVal) + StartListening(); + else + StopListening(); } public void StartListening() @@ -53,7 +74,6 @@ public void StartListening() server = new TcpListener(bindAddr, port); server.Start(); kOS.Safe.Utilities.Debug.Logger.Log("kOS TelnetMainServer started listening on " + bindAddr + " " + port); - gameObject.SetActive(true); isListening = true; } @@ -62,39 +82,34 @@ public void StopListening() // calling StopListening when already stopped can cause problems, so quit if already stopped: if (!isListening) return; + isListening = false; - gameObject.SetActive(false); kOS.Safe.Utilities.Debug.Logger.Log("kOS TelnetMainServer stopped listening on " + bindAddr + " " + port); server.Stop(); foreach (TelnetSingletonServer telnet in telnets) telnet.StopListening(); - } + } public void Update() { - Console.WriteLine("PROOF UPDATE IS CALLED A"); + SetConfigEnable(Config.Instance.EnableTelnet); + if (!isListening) return; - Console.WriteLine("PROOF UPDATE IS CALLED B"); // .NET's TCP handler only gives you blocking socket accepting, but for the Unity // Update(), we need to always finish quickly and never block, so check if anything // is pending first to simulate the effect of a nonblocking socket accept check: if (!server.Pending()) return; - Console.WriteLine("PROOF UPDATE IS CALLED C"); TcpClient incomingClient = server.AcceptTcpClient(); - Console.WriteLine("PROOF UPDATE IS CALLED D"); string remoteIdent = ((IPEndPoint)(incomingClient.Client.RemoteEndPoint)).Address.ToString(); kOS.Safe.Utilities.Debug.Logger.Log("kOS telnet server got an incoming connection from " + remoteIdent); - Console.WriteLine("PROOF UPDATE IS CALLED E"); - // Perform something akin to a 'fork', but in Unity by making a new MonoBehavior to handle this - // single client and talk to it, while the main server goes back to just listening to new clients: telnets.Add(new TelnetSingletonServer(incomingClient)); - telnets[telnets.Count].StartListening(); + telnets[telnets.Count-1].StartListening(); } } } diff --git a/src/kOS/UserIO/TelnetSingletonServer.cs b/src/kOS/UserIO/TelnetSingletonServer.cs index 2169563c3..323c84ebc 100644 --- a/src/kOS/UserIO/TelnetSingletonServer.cs +++ b/src/kOS/UserIO/TelnetSingletonServer.cs @@ -1,8 +1,12 @@ using System; +using System.Linq; +using System.Collections.Generic; +using System.Threading; using System.Net; using System.Net.Sockets; using System.Text; using kOS.Safe.Utilities; +using kOS.Module; using UnityEngine; namespace kOS.UserIO @@ -16,129 +20,327 @@ public class TelnetSingletonServer : MonoBehaviour { // ReSharper disable SuggestUseVarKeywordEvident // ReSharper disable RedundantDefaultFieldInitializer - private TcpClient client; - private NetworkStream stream; - - private StringBuilder inBuffer = new StringBuilder(); - private int inBufferNextPos = 0; // rather than inefficiently shrinking the buffer from the left end, requiring a new buffer, just track where we are in it. - - private StringBuilder outBuffer = new StringBuilder(); - private int outBufferNextPos = 0; // rather than inefficiently shrinking the buffer from the left end, requiring a new buffer, just track where we are in it. - - private byte[] rawByteBuffer = new byte[32]; // use small chunks to spread across multiple Update()'s - private char[] rawCharBuffer = new char[32]; // use small chunks to spread across multiple Update()'s + private volatile TcpClient client; + private volatile NetworkStream stream; + + private List availableCPUs; + private DateTime lastMenuQueryTime; - private bool closeWhenFlushed; + private kOSProcessor connectedCPU = null; // when not connected, it will be on the local menu. + + private volatile byte[] rawReadBuffer = new byte[128]; // use small chunks + private string localMenuBuffer = ""; + + private Thread inThread; // ReSharper enable RedundantDefaultFieldInitializer // ReSharper enable SuggestUseVarKeywordEvident + // Special telnet protocol bytes with magic meaning, taken from interet RFC's: + // Many of these will go unused at first, but it's important to get them down for future + // embetterment. Uncomment them if you start needing to use one. + + private const byte RFC854_SE = 240; // End of subnegotiation parameters. + private const byte RFC854_NOP = 241; // No operation. + private const byte RFC854_DATAMARK = 242; // The data stream portion of a Synch. + // This should always be accompanied + // by a TCP Urgent notification. + private const byte RFC854_BREAK = 243; // NVT character BRK. + private const byte RFC854_IP = 244; // The function IP. + private const byte RFC854_AO = 245; // The function AO. + private const byte RFC854_AYT = 246; // The function AYT. + private const byte RFC854_EC = 247; // The function EC. + private const byte RFC854_EL = 248; // The function EL. + private const byte RFC864_GA = 249; // The GA signal. + private const byte RFC854_SB = 250; // Indicates that what follows is + // subnegotiation of the indicated + // option. + private const byte RFC854_WILL = 251; // Indicates the desire to begin + // performing, or confirmation that + // you are now performing, the + // indicated option. + private const byte RFC854_WONT = 252; // Indicates the refusal to perform, + // or continue performing, the + // indicated option. + private const byte RFC854_DO = 253; // Indicates the request that the + // other party perform, or + // confirmation that you are expecting + // the other party to perform, the + // indicated option. + private const byte RFC854_DONT = 254; // Indicates the demand that the + // other party stop performing, + // or confirmation that you are no + // longer expecting the other party + // to perform, the indicated option. + private const byte RFC854_IAC = 255; // Interpret as Command - the escape char to start all the above things. + + private const byte RFC857_ECHO = 1; + + private const byte RFC858_SUPPRESS_GOAHEAD = 3; + + private const byte RFC1184_LINEMODE = 34; + private const byte RFC1184_MODE = 1; + private const byte RFC1184_EDIT = 1; + private const byte RFC1184_TRAPSIG = 2; + private const byte RFC1184_MODE_ACK = 4; + private const byte RFC1184_SOFT_TAB = 8; + private const byte RFC1184_LIT_ECHO = 16; + public TelnetSingletonServer(TcpClient client) { this.client = client; stream = client.GetStream(); - - enabled = false; // don't start running the Update() until StartListening(). + inThread = new Thread(DoInThread); + } - public void StartListening() + public void SendText(string str) { - kOS.Safe.Utilities.Debug.Logger.Log("kOS telnet singleton server started listening."); - enabled = true; - closeWhenFlushed = false; - SendText("\r\n\r\nkOS telnet server connection established.\r\n\r\n"); + byte[] outBuff = System.Text.Encoding.UTF8.GetBytes(str); + stream.Write(outBuff, 0, outBuff.Length); } - + public void StopListening() { - kOS.Safe.Utilities.Debug.Logger.Log("kOS telnet singleton server stopped listening."); - SendText("\r\n\r\nkOS telnet server signing off.\r\n\r\n"); - closeWhenFlushed = true; + inThread.Abort(); + inThread = null; // dispose old thread. + stream.Close(); } - /// - /// Buffers text to start being sent out to the client on the next Update(). You can - /// make multiple calls to this to keep appending more text to the send buffer. It will - /// start going out to the client as soon as the next Update() hits. - /// - /// - public void SendText(string str) + public void StartListening() { - outBuffer.Append(str); + inThread.Start(); + SendText("Connected to kOS Telnet Server.\r\n"); + + LineAtATime(false); + + // The proper protocol demands that we pay attention to whether or not the client telnet session actually knows how to + // do those requested settings, and negotiate back to it. But nobody makes telnet clients anymore that are that bad + // that they can't do these things so I'll be lazy and just assume they worked without paying attention to the responses sent back. } - - /// - /// Get the next buffer chunk of data from the client stream, or print the next buffer chunk of - /// bytes out to the client stream, or both. Update()'s must finish - /// fast, so don't try to consume or print everything in one call. If there's too much - /// just leave the remainder for the next Update() call. - /// - public virtual void Update() + + public void LineAtATime(bool buffered) { - // Detect if the client closed from its end: - if (!client.Connected) + if (buffered) { - enabled = false; - return; + // Send some telnet protocol stuff telling the other side how I'd like it to behave: + stream.Write( new byte[] {RFC854_IAC, RFC854_DO, RFC857_ECHO},0, 3); // don't local-echo. + stream.Write( new byte[] {RFC854_IAC, RFC854_DONT, RFC858_SUPPRESS_GOAHEAD}, 0, 3); // send one char at a time without buffering lines. + } + else + { + // Send some telnet protocol stuff telling the other side how I'd like it to behave: + stream.Write( new byte[] {RFC854_IAC, RFC854_DONT, RFC857_ECHO},0, 3); // don't local-echo. + stream.Write( new byte[] {RFC854_IAC, RFC854_DO, RFC858_SUPPRESS_GOAHEAD}, 0, 3); // send one char at a time without buffering lines. } + } + + private bool CPUListChanged() + { + List newList = kOSProcessor.AllInstances(); + bool itChanged = false; + + if (newList.Count != availableCPUs.Count) + itChanged = true; + else + for( int i = 0; i < newList.Count ; ++i) + if (newList[i] != availableCPUs[i]) + itChanged = true; - OutputSome(); - InputSome(); + availableCPUs = newList; + + return itChanged; + } + + private void PrintCPUMenu() + { + SendText("______________________________\r\n"); + SendText("Available CPUS for Connection:\r\n"); + + int userPickNum = 1; + bool atLeastOne = false; + foreach (kOSProcessor kModule in availableCPUs) + { + atLeastOne = true; + Part thisPart = kModule.part; + KOSNameTag partTag = thisPart.Modules.OfType().FirstOrDefault(); + string partLabel = String.Format("{0}({1})", + thisPart.partInfo.title.Split(' ')[0], // just the first word of the name, i.e "CX-4181" + ((partTag == null) ? "" : partTag.nameTag) + ); + Vessel vessel = (thisPart == null) ? null/*can this even happen?*/ : thisPart.vessel; + string vesselLabel = (vessel == null) ? ""/*can this even happen?*/ : vessel.GetName(); + + SendText(String.Format(" [{0}] Vessel({1}), CPU({2})\r\n",userPickNum, vesselLabel, partLabel)); + ++userPickNum; + } + if (atLeastOne) + SendText("Type a selection number and press return/enter.\r\n" + + "Or enter [Q] to quit.\r\n" + + "> "); + else + SendText("\r\n"); } - /// - /// Consume a small chunk from the outBuffer to the client stream. Update()'s must finish - /// fast, so don't try to print everything in one call. If there's too much - /// just leave the remainder for the next Update() call. - /// - public void OutputSome() + private void DoInThread() { - // do nothing if outbuffer is flushed out. - if (outBuffer.Length == 0) + // All threads in a KSP mod must be careful NOT to access any KSP or Unity methods + // from inside their execution, because KSP and Unity are not threadsafe + + while (true) { - // If we were being closed but waiting for flush first, now it's time to close: - if (closeWhenFlushed) + // Detect if the client closed from its end: + if (!client.Connected) { - enabled = false; - client.Close(); + inThread.Abort(); + StopListening(); + break; } - return; + + if (connectedCPU == null) + { + DoMenu(); + } + else + { + int numRead = stream.Read(rawReadBuffer, 0, rawReadBuffer.Length); // This is blocking, so this thread will be idle when client isn't typing. + string cleanedText = TelnetProtocolScrape(rawReadBuffer, numRead); + // TODO - make this better - right now I'm ignoring the inBuffer and just echoing this out + // to the out buffer to print it back to the user for a test. In future this should attach to the CPU: + SendText("["+cleanedText+"]"); + } } + } + + private void DoMenu() + { + + if (System.DateTime.Now > lastMenuQueryTime.AddMilliseconds(500)) + { + lastMenuQueryTime = System.DateTime.Now; + if( CPUListChanged() ) + PrintCPUMenu(); + } + int numRead = stream.Read(rawReadBuffer, 0, rawReadBuffer.Length); // This is blocking, so this thread will be idle when client isn't typing. + string cleanedText = TelnetProtocolScrape(rawReadBuffer, numRead); + SendText(cleanedText); + localMenuBuffer = localMenuBuffer + cleanedText; + int firstEOLN = localMenuBuffer.IndexOfAny(new char[] {'\r','\n'}); - // If it got this far, it has to be because there's at least 1 char to print out. - - // Write the next few chars out: - int numToWrite = System.Math.Min(outBuffer.Length - outBufferNextPos, rawCharBuffer.Length); - inBuffer.CopyTo(outBufferNextPos, rawCharBuffer, 0, numToWrite); - byte[] bytesFromChars = System.Text.Encoding.UTF8.GetBytes(rawCharBuffer, 0, numToWrite); - stream.Write(bytesFromChars, 0, bytesFromChars.Length); + // end of line hasn't been pressed + if (firstEOLN < 0) + return; - // Track where in the buffer we are: - outBufferNextPos += numToWrite; - - // If we printed everything and it's all flushed out, then just empty the output buffer entirely and reset the counter: - if (outBufferNextPos >= outBuffer.Length) + if(localMenuBuffer.Substring(0,1).Equals("Q",StringComparison.CurrentCultureIgnoreCase)) + { + StopListening(); + stream.Close(); + localMenuBuffer = ""; + return; + } + + int endOfNumbers = cleanedText.LastIndexOfAny(new char[] {'0','1','2','3','4','5','6','7','8','9'}); + int pick; + if( int.TryParse(localMenuBuffer.Substring(0,endOfNumbers+1),out pick) ) { - outBuffer.Remove(0, outBuffer.Length); - outBufferNextPos = 0; + SendText("Connecting..."); + connectedCPU = availableCPUs[pick-1]; } + else + { + SendText("Garbled answer. Try Again.\r\n"); + availableCPUs = new List(); // resetting the list forces it to recalc and reprint the menu next time. + } + localMenuBuffer = ""; } - /// - /// Read a small chunk from the client stream and add it to the inBuffer. Update()'s must finish - /// fast, so don't try to read everything in one call. If there's too much - /// just leave the remainder for the next Update() call. - /// - public void InputSome() + private string TelnetProtocolScrape(byte[] inRawBuff, int rawLength) { - // do nothing if socket has nothing coming in. - if (!stream.DataAvailable) - return; + // At max the cooked version will be the same size as the raw. It might be a little less: + byte[] inCookedBuff = new byte[rawLength]; + int cookedIndex = 0; + int rawIndex = 0; - // TODO - make this better - right now I'm ignoring the inBuffer and just echoing this out - // to the out buffer to print it back to the user for a test: - int numRead = stream.Read(rawByteBuffer, 0, rawByteBuffer.Length); - outBuffer.AppendFormat("[{0}]",System.Text.Encoding.UTF8.GetString(rawByteBuffer, 0, numRead)); + while (rawIndex < rawLength) + { + switch (inRawBuff[rawIndex]) + { + case RFC854_IAC: + byte commandByte = inRawBuff[++rawIndex]; + switch (commandByte) + { + case RFC854_DO: rawIndex += TelnetConsumeDo(inRawBuff, rawIndex ); break; + case RFC854_IAC: break; // pass through to normal behaviour when two IAC's are back to back - that's how a real IAC char is encoded. + default: + rawIndex += TelnetConsumeOther( commandByte, inRawBuff, rawIndex); + break; + } + break; + default: + // The normal case is to just copy the bytes over as-is when no special chars were seen. + inCookedBuff[cookedIndex] = inRawBuff[rawIndex]; + ++rawIndex; + ++cookedIndex; + break; + } + } + // Convert the cooked buffer into a string to passing back: + return System.Text.Encoding.UTF8.GetString(inCookedBuff,0,cookedIndex); + } + + private int TelnetConsumeDo( byte[] remainingBuff, int index) + { + int offset = 0; + byte option = remainingBuff[index + (++offset)]; + switch (option) + { + // If other side wants me to echo, agree + case RFC857_ECHO: stream.Write( new byte[] {RFC854_IAC, RFC854_WILL, RFC857_ECHO}, 0, 3); + break; + // If other side wants me to go char-at-a-atime, agree + case RFC858_SUPPRESS_GOAHEAD: + stream.Write( new byte[] {RFC854_IAC, RFC854_WILL, RFC858_SUPPRESS_GOAHEAD}, 0, 3); + break; + default: break; + } + + // Everything below here is to help debug: + StringBuilder sb = new StringBuilder(); + sb.Append("{"+RFC854_DO+"}"); + sb.Append("{"+option+"}"); + kOS.Safe.Utilities.Debug.Logger.SuperVerbose( "telnet protocol submessage from client: " + sb.ToString()); + + return offset; + } + + private int TelnetConsumeOther( byte commandByte, byte[] remainingBuff, int index) + { + int offset = 0; + StringBuilder sb = new StringBuilder(); + switch (commandByte) + { + case RFC854_SB: + while (offset < remainingBuff.Length && remainingBuff[index+offset] != RFC854_SE) + ++offset; + + // Everything below here is to help debug: + sb.Append("{"+commandByte+"}"); + for( int i = index; i < index+offset ; ++i ) + sb.Append("{"+remainingBuff[i]+"}"); + kOS.Safe.Utilities.Debug.Logger.SuperVerbose( "unhandled telnet protocol submessage from client: " + sb.ToString()); + + break; + default: + ++offset; + + // Everything below here is to help debug: + sb.Append("{"+commandByte+"}"); + sb.Append("{"+remainingBuff[index+offset]+"}"); + kOS.Safe.Utilities.Debug.Logger.SuperVerbose( "unhandled telnet protocol command from client: " + sb.ToString()); + + break; + } + return offset; } } } From 5b3e6afaaa5b17d4545f78158ff118ec5a00f4b2 Mon Sep 17 00:00:00 2001 From: Chris Woerz Date: Sun, 11 Jan 2015 10:39:02 -0700 Subject: [PATCH 088/446] added basic docs and made p/y/r respect lock --- doc/source/structures.rst | 1 + doc/source/structures/vessels/gimbal.rst | 131 +++++++++++++++++++++++ src/kOS/Suffixed/Part/GimbalValue.cs | 12 +-- 3 files changed, 138 insertions(+), 6 deletions(-) create mode 100644 doc/source/structures/vessels/gimbal.rst diff --git a/doc/source/structures.rst b/doc/source/structures.rst index 9506f61a6..dee323023 100644 --- a/doc/source/structures.rst +++ b/doc/source/structures.rst @@ -27,6 +27,7 @@ A general discussion of structures :ref:`can be found here * :struct:`Engine` * :struct:`AggregateResource` * :struct:`DockingPort` + * :struct:`Gimbal` * :struct:`Part` * :struct:`PartModule` * :struct:`Sensor` diff --git a/doc/source/structures/vessels/gimbal.rst b/doc/source/structures/vessels/gimbal.rst new file mode 100644 index 000000000..7115f07e1 --- /dev/null +++ b/doc/source/structures/vessels/gimbal.rst @@ -0,0 +1,131 @@ +.. _dockingport: + +DockingPort +=========== + +Some of the Parts returned by :ref:`LIST PARTS ` will be of type :struct:`DockingPort`. + + +.. structure:: DockingPort + + .. list-table:: + :header-rows: 1 + :widths: 2 1 4 + + * - Suffix + - Type + - Description + + * - All suffixes of :struct:`Part` + - + - A :struct:`DockingPort` is a kind of :struct:`Part` + + * - :attr:`AQUIRERANGE` + - scalar + - active range of the port + * - :attr:`AQUIREFORCE` + - scalar + - force experienced when docking + * - :attr:`AQUIRETORQUE` + - scalar + - torque experienced when docking + * - :attr:`REENGAGEDDISTANCE` + - scalar + - distance at which the port is reset + * - :attr:`DOCKEDSHIPNAME` + - string + - name of vessel the port is docked to + * - :attr:`PORTFACING` + - :struct:`Direction` + - facing of the port + * - :attr:`STATE` + - string + - current state of the port + * - :meth:`UNDOCK` + - + - callable to release the dock + * - :attr:`TARGETABLE` + - boolean + - check if this port can be targeted + +.. note:: + + :struct:`DockingPort` is a type of :struct:`Part`, and therefore can use all the suffixes of :struct:`Part`. Shown below are only the suffixes that are unique to :struct:`DockingPort`. + + +.. attribute:: DockingPort:AQUIRERANGE + + :type: scalar + :access: Get only + + gets the range at which the port will "notice" another port and pull on it. + +.. attribute:: DockingPort:AQUIREFORCE + + :type: scalar + :access: Get only + + gets the force with which the port pulls on another port. + +.. attribute:: DockingPort:AQUIRETORQUE + + :type: scalar + :access: Get only + + gets the rotational force with which the port pulls on another port. + +.. attribute:: DockingPort:REENGAGEDDISTANCE + + :type: scalar + :access: Get only + + how far the port has to get away after undocking in order to re-enable docking. + +.. attribute:: DockingPort:DOCKEDSHIPNAME + + :type: string + :access: Get only + + name of vessel on the other side of the docking port. + +.. attribute:: DockingPort:PORTFACING + + :type: :struct:`Direction` + :access: Get only + + Gets the facing of this docking port which may differ from the facing of the part itself if the docking port is aimed out the side of the part, as in the case of the inline shielded docking port. + +.. attribute:: DockingPort:STATE + + :type: string + :access: Get only + + One of the following string values: + + ``Ready`` + Docking port is not yet attached and will attach if it touches another. + ``Docked (docker)`` + One port in the joined pair is called the docker, and has this state + ``Docked (dockee)`` + One port in the joined pair is called the dockee, and has this state + ``Docked (same vessel)`` + Sometimes KSP says this instead. It's unclear what it means. + ``Disabled`` + Docking port will refuse to dock if it bumps another docking port. + ``PreAttached`` + Temporary state during the "wobbling" while two ports are magnetically touching but not yet docked solidly. During this state the two vessels are still tracked as separate vessels and haven't become one yet. + + +.. method:: DockingPort:UNDOCK + + Call this to cause the docking port to detach. + +.. attribute:: DockingPort:TARGETABLE + + :type: boolean + :access: Get only + + True if this part can be picked with ``SET TARGET TO``. + + + diff --git a/src/kOS/Suffixed/Part/GimbalValue.cs b/src/kOS/Suffixed/Part/GimbalValue.cs index 2d1639115..1116c1175 100644 --- a/src/kOS/Suffixed/Part/GimbalValue.cs +++ b/src/kOS/Suffixed/Part/GimbalValue.cs @@ -24,12 +24,12 @@ private void InitializeGimbalSuffixes() { gimbal.FreeGimbal(); } - })); - AddSuffix("RANGE", new Suffix(() => gimbal.gimbalRange )); - AddSuffix("RESPONSESPEED", new Suffix(() => gimbal.gimbalResponseSpeed )); - AddSuffix("PITCHANGLE", new Suffix(() => gimbal.gimbalAnglePitch )); - AddSuffix("YAWANGLE", new Suffix(() => gimbal.gimbalAngleYaw )); - AddSuffix("ROLLANGLE", new Suffix(() => gimbal.gimbalAngleRoll )); + }, "Is the Gimbal free to travel?")); + AddSuffix("RANGE", new Suffix(() => gimbal.gimbalRange ,"The Gimbal's Possible Range of movement")); + AddSuffix("RESPONSESPEED", new Suffix(() => gimbal.gimbalResponseSpeed, "The Gimbal's Possible Rate of travel")); + AddSuffix("PITCHANGLE", new Suffix(() => gimbal.gimbalLock ? 0 : gimbal.gimbalAnglePitch, "Current Gimbal Pitch")); + AddSuffix("YAWANGLE", new Suffix(() => gimbal.gimbalLock ? 0 : gimbal.gimbalAngleYaw, "Current Gimbal Yaw" )); + AddSuffix("ROLLANGLE", new Suffix(() => gimbal.gimbalLock ? 0 : gimbal.gimbalAngleRoll, "Current Gimbal Roll")); } } } From 5830a8ebf9c23375a68ea42f431434aae6523dd2 Mon Sep 17 00:00:00 2001 From: Chris Woerz Date: Sun, 11 Jan 2015 10:48:42 -0700 Subject: [PATCH 089/446] uid is string and element:partcount is now element:parts:length --- doc/source/structures/vessels/part.rst | 4 ++-- src/kOS/Suffixed/ElementValue.cs | 3 +-- src/kOS/Suffixed/Part/PartValue.cs | 2 +- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/doc/source/structures/vessels/part.rst b/doc/source/structures/vessels/part.rst index a544a8271..629968d5a 100644 --- a/doc/source/structures/vessels/part.rst +++ b/doc/source/structures/vessels/part.rst @@ -40,7 +40,7 @@ These are the generic properties every PART has. You can obtain a list of values - scalar - The stage this is associated with * - :attr:`UID` - - scalar + - string - Unique identifying number * - :attr:`ROTATION` - :struct:`Direction` @@ -146,7 +146,7 @@ These are the generic properties every PART has. You can obtain a list of values .. attribute:: Part:UID :access: Get only - :type: scalar + :type: string All parts have a unique ID number. Test if two parts are the same part by seeing if this is the same between them. diff --git a/src/kOS/Suffixed/ElementValue.cs b/src/kOS/Suffixed/ElementValue.cs index 7056e7fe1..23c78266a 100644 --- a/src/kOS/Suffixed/ElementValue.cs +++ b/src/kOS/Suffixed/ElementValue.cs @@ -18,8 +18,7 @@ public ElementValue(IEnumerable parts) name = vessel.vesselName; AddSuffix("NAME", new Suffix(() => vessel.vesselName)); - AddSuffix("UID", new Suffix(() => vessel.rootPart.uid())); - AddSuffix("PARTCOUNT", new Suffix(() => parts.Count())); + AddSuffix("UID", new Suffix(() => vessel.rootPart.uid().ToString())); AddSuffix("PARTS", new Suffix(() => PartsToList(parts))); } diff --git a/src/kOS/Suffixed/Part/PartValue.cs b/src/kOS/Suffixed/Part/PartValue.cs index 53ecab4be..913f3b51a 100644 --- a/src/kOS/Suffixed/Part/PartValue.cs +++ b/src/kOS/Suffixed/Part/PartValue.cs @@ -31,7 +31,7 @@ private void PartInitializeSuffixes() AddSuffix("NAME", new Suffix(() => Part.name)); AddSuffix("TITLE", new Suffix(() => Part.partInfo.title)); AddSuffix("STAGE", new Suffix(() => Part.inverseStage)); - AddSuffix("UID", new Suffix(() => Part.uid())); + AddSuffix("UID", new Suffix(() => Part.uid().ToString())); AddSuffix("ROTATION", new Suffix(() => new Direction( Part.transform.rotation) )); AddSuffix("POSITION", new Suffix(() => new Vector( Part.transform.position - shared.Vessel.findWorldCenterOfMass() ))); AddSuffix("TAG", new NoArgsSuffix(GetTagName)); From 2e4449a913f4caa2de3c5007bb804870e58d286c Mon Sep 17 00:00:00 2001 From: Chris Woerz Date: Sun, 11 Jan 2015 11:14:53 -0700 Subject: [PATCH 090/446] structure can now == and + --- src/kOS.Safe/Encapsulation/Structure.cs | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/kOS.Safe/Encapsulation/Structure.cs b/src/kOS.Safe/Encapsulation/Structure.cs index ecb38cfb9..a1712b05f 100644 --- a/src/kOS.Safe/Encapsulation/Structure.cs +++ b/src/kOS.Safe/Encapsulation/Structure.cs @@ -123,7 +123,19 @@ public virtual object GetSuffix(string suffixName) public virtual object TryOperation(string op, object other, bool reverseOrder) { - return null; + if (op == "==") + { + return Equals(other); + } + if (op == "+") + { + return ToString() + other; + } + + var message = string.Format("Cannot perform the operation: {0} On Structures {1} and {2}", op, GetType(), + other.GetType()); + Utilities.Debug.Logger.Log(message); + throw new InvalidOperationException(message); } protected object ConvertToDoubleIfNeeded(object value) From a41e58d76227ad369da5f94eda8ca89f379b3be7 Mon Sep 17 00:00:00 2001 From: Chris Woerz Date: Tue, 13 Jan 2015 09:32:35 -0700 Subject: [PATCH 091/446] ignored ide cache --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 9c608bfa0..4f721b922 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ bin/ obj/ *.suo packages/ +/src/kOS.sln.ide From cdd3d91401fd127000d46053d323a987ea832f64 Mon Sep 17 00:00:00 2001 From: Chris Woerz Date: Tue, 13 Jan 2015 10:18:29 -0700 Subject: [PATCH 092/446] actually saved the docs :P --- doc/source/structures/vessels/gimbal.rst | 123 +++++++---------------- 1 file changed, 38 insertions(+), 85 deletions(-) diff --git a/doc/source/structures/vessels/gimbal.rst b/doc/source/structures/vessels/gimbal.rst index 7115f07e1..b83a83718 100644 --- a/doc/source/structures/vessels/gimbal.rst +++ b/doc/source/structures/vessels/gimbal.rst @@ -1,12 +1,12 @@ -.. _dockingport: +.. _gimbal: -DockingPort -=========== +Gimbal +====== -Some of the Parts returned by :ref:`LIST PARTS ` will be of type :struct:`DockingPort`. +Many engines in KSP have thrust vectoring gimbals and in ksp they are their own module -.. structure:: DockingPort +.. structure:: Gimbal .. list-table:: :header-rows: 1 @@ -16,116 +16,69 @@ Some of the Parts returned by :ref:`LIST PARTS ` will be of type : - Type - Description - * - All suffixes of :struct:`Part` - - - - A :struct:`DockingPort` is a kind of :struct:`Part` + * - :attr:`RANGE` + - scalar + - The Gimbal's Possible Range of movement - * - :attr:`AQUIRERANGE` + * - :attr:`RESPONSESPEED` - scalar - - active range of the port - * - :attr:`AQUIREFORCE` + - The Gimbal's Possible Rate of travel + + * - :attr:`PITCHANGLE` - scalar - - force experienced when docking - * - :attr:`AQUIRETORQUE` + - Current Gimbal Pitch + + * - :attr:`YAWANGLE` - scalar - - torque experienced when docking - * - :attr:`REENGAGEDDISTANCE` + - Current Gimbal Yaw + + * - :attr:`ROLLANGLE` - scalar - - distance at which the port is reset - * - :attr:`DOCKEDSHIPNAME` - - string - - name of vessel the port is docked to - * - :attr:`PORTFACING` - - :struct:`Direction` - - facing of the port - * - :attr:`STATE` - - string - - current state of the port - * - :meth:`UNDOCK` - - - - callable to release the dock - * - :attr:`TARGETABLE` + - Current Gimbal Roll + + * - :attr:`LOCK` - boolean - - check if this port can be targeted - -.. note:: - - :struct:`DockingPort` is a type of :struct:`Part`, and therefore can use all the suffixes of :struct:`Part`. Shown below are only the suffixes that are unique to :struct:`DockingPort`. - - -.. attribute:: DockingPort:AQUIRERANGE + - Is the gimbal free to travel? + +.. attribute:: Gimbal:RANGE :type: scalar :access: Get only - gets the range at which the port will "notice" another port and pull on it. + The maximum extent of travel possible for the gimbal along all 3 axis (Pitch, Yaw, Roll) -.. attribute:: DockingPort:AQUIREFORCE +.. attribute:: Gimbal:RESPONSESPEED :type: scalar :access: Get only - gets the force with which the port pulls on another port. + A Measure of the rate of travel for the gimbal -.. attribute:: DockingPort:AQUIRETORQUE +.. attribute:: Gimbal:PITCHANGLE :type: scalar :access: Get only - gets the rotational force with which the port pulls on another port. + The gimbals current pitch, has a range of -1 to 1. Will always be 0 when LOCK is true -.. attribute:: DockingPort:REENGAGEDDISTANCE +.. attribute:: Gimbal:YAWANGLE :type: scalar :access: Get only - how far the port has to get away after undocking in order to re-enable docking. + The gimbals current yaw, has a range of -1 to 1. Will always be 0 when LOCK is true -.. attribute:: DockingPort:DOCKEDSHIPNAME +.. attribute:: Gimbal:ROLLANGLE - :type: string - :access: Get only - - name of vessel on the other side of the docking port. - -.. attribute:: DockingPort:PORTFACING - - :type: :struct:`Direction` + :type: scalar :access: Get only - Gets the facing of this docking port which may differ from the facing of the part itself if the docking port is aimed out the side of the part, as in the case of the inline shielded docking port. + The gimbals current roll, has a range of -1 to 1. Will always be 0 when LOCK is true -.. attribute:: DockingPort:STATE +.. attribute:: Gimbal:LOCK :type: string - :access: Get only - - One of the following string values: - - ``Ready`` - Docking port is not yet attached and will attach if it touches another. - ``Docked (docker)`` - One port in the joined pair is called the docker, and has this state - ``Docked (dockee)`` - One port in the joined pair is called the dockee, and has this state - ``Docked (same vessel)`` - Sometimes KSP says this instead. It's unclear what it means. - ``Disabled`` - Docking port will refuse to dock if it bumps another docking port. - ``PreAttached`` - Temporary state during the "wobbling" while two ports are magnetically touching but not yet docked solidly. During this state the two vessels are still tracked as separate vessels and haven't become one yet. - - -.. method:: DockingPort:UNDOCK - - Call this to cause the docking port to detach. - -.. attribute:: DockingPort:TARGETABLE - - :type: boolean - :access: Get only - - True if this part can be picked with ``SET TARGET TO``. - - + :access: Get/Set + + Can this Gimbal produce torque right now, when you set it to false it will snap the engine back to 0s for pitch,yaw and roll From 24e7ad699f5ef29bd58ba80a793505d8982be30c Mon Sep 17 00:00:00 2001 From: John Vanderbeck Date: Wed, 14 Jan 2015 23:14:44 -0800 Subject: [PATCH 093/446] Add new PART:GETMODULEINDEX function Adds a new function to get a PartModule at a specified index. Allows accessing PartModules that share the same name. --- src/kOS/Suffixed/Part/PartValue.cs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/kOS/Suffixed/Part/PartValue.cs b/src/kOS/Suffixed/Part/PartValue.cs index 913f3b51a..2fb2a0919 100644 --- a/src/kOS/Suffixed/Part/PartValue.cs +++ b/src/kOS/Suffixed/Part/PartValue.cs @@ -40,7 +40,8 @@ private void PartInitializeSuffixes() AddSuffix("TARGETABLE", new Suffix(() => Part.Modules.OfType().Any())); AddSuffix("SHIP", new Suffix(() => new VesselTarget(Part.vessel, shared))); AddSuffix("GETMODULE", new OneArgsSuffix(GetModule)); - AddSuffix(new [] {"MODULES","ALLMODULES"}, new Suffix(GetAllModules, "A List of all the modules' names on this part")); + AddSuffix("GETMODULEINDEX", new OneArgsSuffix(GetModuleIndex)); + AddSuffix(new[] { "MODULES", "ALLMODULES" }, new Suffix(GetAllModules, "A List of all the modules' names on this part")); AddSuffix("PARENT", new Suffix(() => PartValueFactory.Construct(Part.parent,shared), "The parent part of this part")); AddSuffix("HASPARENT", new Suffix(() => Part.parent != null, "Tells you if this part has a parent, is used to avoid null exception from PARENT")); AddSuffix("CHILDREN", new Suffix>(() => PartValueFactory.ConstructGeneric(Part.children, shared), "A LIST() of the children parts of this part")); @@ -64,6 +65,15 @@ private PartModuleFields GetModule(string modName) } throw new KOSLookupFailException( "module", modName.ToUpper(), this ); } + + private PartModuleFields GetModuleIndex(int moduleIndex) + { + if (moduleIndex < Part.Modules.Count) + { + return PartModuleFieldsFactory.Construct(Part.Modules.GetModule(moduleIndex), shared); + } + throw new KOSLookupFailException("module", String.Format("MODULEINDEX[{0}]", moduleIndex), this); + } public string GetTagName() // public because I picture this being a useful API method later { From 8a4f5fefd78153f4e87870242ab6219eff66648b Mon Sep 17 00:00:00 2001 From: Brad White Date: Fri, 16 Jan 2015 13:06:27 -0500 Subject: [PATCH 094/446] Update built in autopilot features Compiler.cs - Added pop opcode when using lock or unlock to call toggleflybywire(). This prevents a stack memory leak now that the toggleflybywire() method pushes a dummy return value. FlightControlManager.cs - Added a little documentation surrounding the modifications. Also added all of the built in autopilot options. Restructured the code to properly clear any other autopilots that may already be enabled when new autopilots are called. Made the paramName value accessed as lower case to match the case-insensitive nature of the language. Added a damping parameter as well to enable the SAS's built in damping mode. Misc.cs - Push a dummy return value after completing the toggleflybywire function. SteeringHelper.cs - updated the SAS lockHeading integration to prevent constantly setting a new heading in case it was affecting the built in PID. This change may be doing nothing, it is hard to identify if this issue is really happening. --- src/kOS.Safe/Compilation/KS/Compiler.cs | 4 + src/kOS/Binding/FlightControlManager.cs | 139 ++++++++++++++++++++++-- src/kOS/Function/Misc.cs | 3 + src/kOS/Utilities/SteeringHelper.cs | 3 +- 4 files changed, 137 insertions(+), 12 deletions(-) diff --git a/src/kOS.Safe/Compilation/KS/Compiler.cs b/src/kOS.Safe/Compilation/KS/Compiler.cs index b6e8d580e..0cd35d6e3 100644 --- a/src/kOS.Safe/Compilation/KS/Compiler.cs +++ b/src/kOS.Safe/Compilation/KS/Compiler.cs @@ -1573,6 +1573,8 @@ private void VisitLockStatement(ParseNode node) AddOpcode(new OpcodePush(lockIdentifier)); AddOpcode(new OpcodePush(true)); AddOpcode(new OpcodeCall("toggleflybywire()")); + // add a pop to clear out the dummy return value from toggleflybywire() + AddOpcode(new OpcodePop()); } } } @@ -1604,6 +1606,8 @@ private void UnlockIdentifier(Lock lockObject) AddOpcode(new OpcodePush(lockObject.Identifier)); AddOpcode(new OpcodePush(false)); AddOpcode(new OpcodeCall("toggleflybywire()")); + // add a pop to clear out the dummy return value from toggleflybywire() + AddOpcode(new OpcodePop()); // remove update trigger string triggerIdentifier = "lock-" + lockObject.Identifier; diff --git a/src/kOS/Binding/FlightControlManager.cs b/src/kOS/Binding/FlightControlManager.cs index 22f3b1fee..63892f471 100644 --- a/src/kOS/Binding/FlightControlManager.cs +++ b/src/kOS/Binding/FlightControlManager.cs @@ -41,8 +41,17 @@ public override void AddTo(SharedObjects shared) AddNewFlightParam("steering", Shared); AddNewFlightParam("wheelthrottle", Shared); AddNewFlightParam("wheelsteering", Shared); + // Add built in SAS targeting functions AddNewFlightParam("maneuver", Shared); AddNewFlightParam("prograde", Shared); + AddNewFlightParam("retrograde", Shared); + AddNewFlightParam("normal", Shared); + AddNewFlightParam("antinormal", Shared); + AddNewFlightParam("radialin", Shared); + AddNewFlightParam("radialout", Shared); + AddNewFlightParam("target", Shared); + AddNewFlightParam("antitarget", Shared); + AddNewFlightParam("damping", Shared); } @@ -59,49 +68,157 @@ private void OnFlyByWire(FlightCtrlState c) private void clearStockAutopilot(string enabledMode) { - if (enabledMode != "maneuver") flightParameters["maneuver"].Enabled = false; - if (enabledMode != "prograde") flightParameters["prograde"].Enabled = false; + // Use the cpu ToggleFlyByWire method to ensure that we properly unload the autopilot from the other parts of kOS + if (enabledMode != "maneuver" && flightParameters["maneuver"].Enabled) ((kOS.Execution.CPU)Shared.Cpu).ToggleFlyByWire("maneuver", false); ; + if (enabledMode != "prograde" && flightParameters["prograde"].Enabled) ((kOS.Execution.CPU)Shared.Cpu).ToggleFlyByWire("prograde", false); ; + if (enabledMode != "retrograde" && flightParameters["retrograde"].Enabled) ((kOS.Execution.CPU)Shared.Cpu).ToggleFlyByWire("retrograde", false); ; + if (enabledMode != "normal" && flightParameters["normal"].Enabled) ((kOS.Execution.CPU)Shared.Cpu).ToggleFlyByWire("normal", false); ; + if (enabledMode != "antinormal" && flightParameters["antinormal"].Enabled) ((kOS.Execution.CPU)Shared.Cpu).ToggleFlyByWire("antinormal", false); ; + if (enabledMode != "radialin" && flightParameters["radialin"].Enabled) ((kOS.Execution.CPU)Shared.Cpu).ToggleFlyByWire("radialin", false); ; + if (enabledMode != "radialout" && flightParameters["radialout"].Enabled) ((kOS.Execution.CPU)Shared.Cpu).ToggleFlyByWire("radialout", false); ; + if (enabledMode != "target" && flightParameters["target"].Enabled) ((kOS.Execution.CPU)Shared.Cpu).ToggleFlyByWire("target", false); ; + if (enabledMode != "antitarget" && flightParameters["antitarget"].Enabled) ((kOS.Execution.CPU)Shared.Cpu).ToggleFlyByWire("antitarget", false); ; + if (enabledMode != "steering" && flightParameters["steering"].Enabled) { ((kOS.Execution.CPU)Shared.Cpu).ToggleFlyByWire("steering", false); } } public void ToggleFlyByWire(string paramName, bool enabled) { Debug.Log(string.Format("kOS: FlightControlManager: ToggleFlyByWire: {0} {1}", paramName, enabled)); - if (!flightParameters.ContainsKey(paramName)) { UnityEngine.Debug.LogError("kOS: no such flybywire parameter " + paramName); return; } + if (!flightParameters.ContainsKey(paramName.ToLower())) { UnityEngine.Debug.LogError("kOS: no such flybywire parameter " + paramName); return; } - flightParameters[paramName].Enabled = enabled; - UnityEngine.Debug.LogWarning("kOS: flybywire parameter " + paramName); - UnityEngine.Debug.LogWarning("kOS: parameter enabled " + enabled.ToString()); switch (paramName.ToLower()) { case "maneuver": if (enabled) { + clearStockAutopilot("maneuver"); + if (!Shared.Vessel.ActionGroups[KSPActionGroup.SAS]) Shared.Vessel.ActionGroups.SetGroup(KSPActionGroup.SAS, true); currentVessel.Autopilot.SetMode(VesselAutopilot.AutopilotMode.Maneuver); currentVessel.Autopilot.Enable(); } else { currentVessel.Autopilot.SetMode(VesselAutopilot.AutopilotMode.StabilityAssist); - currentVessel.Autopilot.Disable(); } - clearStockAutopilot("maneuver"); break; case "prograde": if (enabled) { + clearStockAutopilot("prograde"); + if (!Shared.Vessel.ActionGroups[KSPActionGroup.SAS]) Shared.Vessel.ActionGroups.SetGroup(KSPActionGroup.SAS, true); currentVessel.Autopilot.SetMode(VesselAutopilot.AutopilotMode.Prograde); currentVessel.Autopilot.Enable(); } else { currentVessel.Autopilot.SetMode(VesselAutopilot.AutopilotMode.StabilityAssist); - currentVessel.Autopilot.Disable(); } - clearStockAutopilot("prograde"); + break; + case "retrograde": + if (enabled) + { + clearStockAutopilot("retrograde"); + if (!Shared.Vessel.ActionGroups[KSPActionGroup.SAS]) Shared.Vessel.ActionGroups.SetGroup(KSPActionGroup.SAS, true); + currentVessel.Autopilot.SetMode(VesselAutopilot.AutopilotMode.Retrograde); + currentVessel.Autopilot.Enable(); + } + else + { + currentVessel.Autopilot.SetMode(VesselAutopilot.AutopilotMode.StabilityAssist); + } + break; + case "normal": + if (enabled) + { + clearStockAutopilot("normal"); + if (!Shared.Vessel.ActionGroups[KSPActionGroup.SAS]) Shared.Vessel.ActionGroups.SetGroup(KSPActionGroup.SAS, true); + currentVessel.Autopilot.SetMode(VesselAutopilot.AutopilotMode.Normal); + currentVessel.Autopilot.Enable(); + } + else + { + currentVessel.Autopilot.SetMode(VesselAutopilot.AutopilotMode.StabilityAssist); + } + break; + case "antinormal": + if (enabled) + { + clearStockAutopilot("antinormal"); + if (!Shared.Vessel.ActionGroups[KSPActionGroup.SAS]) Shared.Vessel.ActionGroups.SetGroup(KSPActionGroup.SAS, true); + currentVessel.Autopilot.SetMode(VesselAutopilot.AutopilotMode.Antinormal); + currentVessel.Autopilot.Enable(); + } + else + { + currentVessel.Autopilot.SetMode(VesselAutopilot.AutopilotMode.StabilityAssist); + } + break; + case "radialin": + if (enabled) + { + clearStockAutopilot("radialin"); + if (!Shared.Vessel.ActionGroups[KSPActionGroup.SAS]) Shared.Vessel.ActionGroups.SetGroup(KSPActionGroup.SAS, true); + currentVessel.Autopilot.SetMode(VesselAutopilot.AutopilotMode.RadialIn); + currentVessel.Autopilot.Enable(); + } + else + { + currentVessel.Autopilot.SetMode(VesselAutopilot.AutopilotMode.StabilityAssist); + } + break; + case "radialout": + if (enabled) + { + clearStockAutopilot("radialout"); + if (!Shared.Vessel.ActionGroups[KSPActionGroup.SAS]) Shared.Vessel.ActionGroups.SetGroup(KSPActionGroup.SAS, true); + currentVessel.Autopilot.SetMode(VesselAutopilot.AutopilotMode.RadialOut); + currentVessel.Autopilot.Enable(); + } + else + { + currentVessel.Autopilot.SetMode(VesselAutopilot.AutopilotMode.StabilityAssist); + } + break; + case "target": + if (enabled) + { + clearStockAutopilot("target"); + if (!Shared.Vessel.ActionGroups[KSPActionGroup.SAS]) Shared.Vessel.ActionGroups.SetGroup(KSPActionGroup.SAS, true); + currentVessel.Autopilot.SetMode(VesselAutopilot.AutopilotMode.Target); + currentVessel.Autopilot.Enable(); + } + else + { + currentVessel.Autopilot.SetMode(VesselAutopilot.AutopilotMode.StabilityAssist); + } + break; + case "antitarget": + if (enabled) + { + clearStockAutopilot("antitarget"); + if (!Shared.Vessel.ActionGroups[KSPActionGroup.SAS]) Shared.Vessel.ActionGroups.SetGroup(KSPActionGroup.SAS, true); + currentVessel.Autopilot.SetMode(VesselAutopilot.AutopilotMode.AntiTarget); + currentVessel.Autopilot.Enable(); + } + else + { + currentVessel.Autopilot.SetMode(VesselAutopilot.AutopilotMode.StabilityAssist); + } + break; + case "steering": + // Must also do this when using steering, so that the steering doesn't fight the autopilot + // We do this regardless of whether or not enabled is true so that "unlock steering" clears the autopilot mode too + clearStockAutopilot("steering"); + break; + case "damping": + currentVessel.Autopilot.SAS.SetDampingMode(enabled); break; default: break; } + // this needs to be switched to true only after any other active autopilot settings are cleared. + flightParameters[paramName.ToLower()].Enabled = enabled; + if (!enabled) { flightParameters[paramName].ClearValue(); @@ -229,7 +346,7 @@ public bool Enabled get { return enabled; } set { - Debug.Log(string.Format("kOS: FlightCtrlParam: Enabled: {0} {1}", name, enabled)); + Debug.Log(string.Format("kOS: FlightCtrlParam: Enabled: {0} {1} => {2}", name, enabled, value)); enabled = value; if (RemoteTechHook.IsAvailable(control.Vessel.id)) diff --git a/src/kOS/Function/Misc.cs b/src/kOS/Function/Misc.cs index 4a16c1fa9..1b24079e1 100644 --- a/src/kOS/Function/Misc.cs +++ b/src/kOS/Function/Misc.cs @@ -48,6 +48,9 @@ public override void Execute(SharedObjects shared) bool enabled = Convert.ToBoolean(shared.Cpu.PopValue()); string paramName = shared.Cpu.PopValue().ToString(); ((CPU)shared.Cpu).ToggleFlyByWire(paramName, enabled); + // Work around to prevent the pop error following toggle fly by wire directly. + // The VisitIdentifierLedExpression method in the Compiler class purposfully throws away the returned value of a function. + ((CPU)shared.Cpu).PushStack(0); } } diff --git a/src/kOS/Utilities/SteeringHelper.cs b/src/kOS/Utilities/SteeringHelper.cs index c0c9b060d..0fb3021d9 100644 --- a/src/kOS/Utilities/SteeringHelper.cs +++ b/src/kOS/Utilities/SteeringHelper.cs @@ -40,7 +40,8 @@ public static void SteerShipToward(Direction targetDir, FlightCtrlState c, Vesse if (vessel.ActionGroups[KSPActionGroup.SAS]) { - vessel.Autopilot.SAS.LockHeading(target * Quaternion.Euler(90, 0, 0), true); + target = target * Quaternion.Euler(90, 0, 0); + if (vessel.Autopilot.SAS.lockedHeading != target) vessel.Autopilot.SAS.LockHeading(target, true); return; } From 09f45a24ee093e63de59d0d037645e2fd8c8e2e0 Mon Sep 17 00:00:00 2001 From: Brad White Date: Fri, 16 Jan 2015 13:54:52 -0500 Subject: [PATCH 095/446] One more paramName case change FlightControlManager.cs - modified one more paramName to lower case for to make the entire operation case-insensitive. --- src/kOS/Binding/FlightControlManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kOS/Binding/FlightControlManager.cs b/src/kOS/Binding/FlightControlManager.cs index 63892f471..2a884e7e3 100644 --- a/src/kOS/Binding/FlightControlManager.cs +++ b/src/kOS/Binding/FlightControlManager.cs @@ -221,7 +221,7 @@ public void ToggleFlyByWire(string paramName, bool enabled) if (!enabled) { - flightParameters[paramName].ClearValue(); + flightParameters[paramName.ToLower()].ClearValue(); } } From a55cbbb2106ce1df8ee7518106b64d22c02b2522 Mon Sep 17 00:00:00 2001 From: hvacengi Date: Fri, 16 Jan 2015 21:48:46 -0500 Subject: [PATCH 096/446] Add Exceptions and Refactor FlightControlManager.cs - Small refactor to consistently reference "currentVessel" instead of "Shared.Vessel". Also added exceptions for each of the built in autopilot modes to give an error if the pilot or core cannot use the mode. --- src/kOS/Binding/FlightControlManager.cs | 63 +++++++++++++++++++++---- 1 file changed, 54 insertions(+), 9 deletions(-) diff --git a/src/kOS/Binding/FlightControlManager.cs b/src/kOS/Binding/FlightControlManager.cs index 2a884e7e3..e8ce93589 100644 --- a/src/kOS/Binding/FlightControlManager.cs +++ b/src/kOS/Binding/FlightControlManager.cs @@ -91,8 +91,13 @@ public void ToggleFlyByWire(string paramName, bool enabled) case "maneuver": if (enabled) { + if (!currentVessel.Autopilot.CanSetMode(VesselAutopilot.AutopilotMode.Maneuver)) + { + throw new kOS.Safe.Exceptions.KOSException( + string.Format("Cannot set autopilot value, pilot/probe does not support {0}", paramName)); + } clearStockAutopilot("maneuver"); - if (!Shared.Vessel.ActionGroups[KSPActionGroup.SAS]) Shared.Vessel.ActionGroups.SetGroup(KSPActionGroup.SAS, true); + if (!currentVessel.ActionGroups[KSPActionGroup.SAS]) currentVessel.ActionGroups.SetGroup(KSPActionGroup.SAS, true); currentVessel.Autopilot.SetMode(VesselAutopilot.AutopilotMode.Maneuver); currentVessel.Autopilot.Enable(); } @@ -104,8 +109,13 @@ public void ToggleFlyByWire(string paramName, bool enabled) case "prograde": if (enabled) { + if (!currentVessel.Autopilot.CanSetMode(VesselAutopilot.AutopilotMode.Prograde)) + { + throw new kOS.Safe.Exceptions.KOSException( + string.Format("Cannot set autopilot value, pilot/probe does not support {0}", paramName)); + } clearStockAutopilot("prograde"); - if (!Shared.Vessel.ActionGroups[KSPActionGroup.SAS]) Shared.Vessel.ActionGroups.SetGroup(KSPActionGroup.SAS, true); + if (!currentVessel.ActionGroups[KSPActionGroup.SAS]) currentVessel.ActionGroups.SetGroup(KSPActionGroup.SAS, true); currentVessel.Autopilot.SetMode(VesselAutopilot.AutopilotMode.Prograde); currentVessel.Autopilot.Enable(); } @@ -117,8 +127,13 @@ public void ToggleFlyByWire(string paramName, bool enabled) case "retrograde": if (enabled) { + if (!currentVessel.Autopilot.CanSetMode(VesselAutopilot.AutopilotMode.Retrograde)) + { + throw new kOS.Safe.Exceptions.KOSException( + string.Format("Cannot set autopilot value, pilot/probe does not support {0}", paramName)); + } clearStockAutopilot("retrograde"); - if (!Shared.Vessel.ActionGroups[KSPActionGroup.SAS]) Shared.Vessel.ActionGroups.SetGroup(KSPActionGroup.SAS, true); + if (!currentVessel.ActionGroups[KSPActionGroup.SAS]) currentVessel.ActionGroups.SetGroup(KSPActionGroup.SAS, true); currentVessel.Autopilot.SetMode(VesselAutopilot.AutopilotMode.Retrograde); currentVessel.Autopilot.Enable(); } @@ -130,8 +145,13 @@ public void ToggleFlyByWire(string paramName, bool enabled) case "normal": if (enabled) { + if (!currentVessel.Autopilot.CanSetMode(VesselAutopilot.AutopilotMode.Normal)) + { + throw new kOS.Safe.Exceptions.KOSException( + string.Format("Cannot set autopilot value, pilot/probe does not support {0}", paramName)); + } clearStockAutopilot("normal"); - if (!Shared.Vessel.ActionGroups[KSPActionGroup.SAS]) Shared.Vessel.ActionGroups.SetGroup(KSPActionGroup.SAS, true); + if (!currentVessel.ActionGroups[KSPActionGroup.SAS]) currentVessel.ActionGroups.SetGroup(KSPActionGroup.SAS, true); currentVessel.Autopilot.SetMode(VesselAutopilot.AutopilotMode.Normal); currentVessel.Autopilot.Enable(); } @@ -143,8 +163,13 @@ public void ToggleFlyByWire(string paramName, bool enabled) case "antinormal": if (enabled) { + if (!currentVessel.Autopilot.CanSetMode(VesselAutopilot.AutopilotMode.Antinormal)) + { + throw new kOS.Safe.Exceptions.KOSException( + string.Format("Cannot set autopilot value, pilot/probe does not support {0}", paramName)); + } clearStockAutopilot("antinormal"); - if (!Shared.Vessel.ActionGroups[KSPActionGroup.SAS]) Shared.Vessel.ActionGroups.SetGroup(KSPActionGroup.SAS, true); + if (!currentVessel.ActionGroups[KSPActionGroup.SAS]) currentVessel.ActionGroups.SetGroup(KSPActionGroup.SAS, true); currentVessel.Autopilot.SetMode(VesselAutopilot.AutopilotMode.Antinormal); currentVessel.Autopilot.Enable(); } @@ -156,8 +181,13 @@ public void ToggleFlyByWire(string paramName, bool enabled) case "radialin": if (enabled) { + if (!currentVessel.Autopilot.CanSetMode(VesselAutopilot.AutopilotMode.RadialIn)) + { + throw new kOS.Safe.Exceptions.KOSException( + string.Format("Cannot set autopilot value, pilot/probe does not support {0}", paramName)); + } clearStockAutopilot("radialin"); - if (!Shared.Vessel.ActionGroups[KSPActionGroup.SAS]) Shared.Vessel.ActionGroups.SetGroup(KSPActionGroup.SAS, true); + if (!currentVessel.ActionGroups[KSPActionGroup.SAS]) currentVessel.ActionGroups.SetGroup(KSPActionGroup.SAS, true); currentVessel.Autopilot.SetMode(VesselAutopilot.AutopilotMode.RadialIn); currentVessel.Autopilot.Enable(); } @@ -169,8 +199,13 @@ public void ToggleFlyByWire(string paramName, bool enabled) case "radialout": if (enabled) { + if (!currentVessel.Autopilot.CanSetMode(VesselAutopilot.AutopilotMode.RadialOut)) + { + throw new kOS.Safe.Exceptions.KOSException( + string.Format("Cannot set autopilot value, pilot/probe does not support {0}", paramName)); + } clearStockAutopilot("radialout"); - if (!Shared.Vessel.ActionGroups[KSPActionGroup.SAS]) Shared.Vessel.ActionGroups.SetGroup(KSPActionGroup.SAS, true); + if (!currentVessel.ActionGroups[KSPActionGroup.SAS]) currentVessel.ActionGroups.SetGroup(KSPActionGroup.SAS, true); currentVessel.Autopilot.SetMode(VesselAutopilot.AutopilotMode.RadialOut); currentVessel.Autopilot.Enable(); } @@ -182,8 +217,13 @@ public void ToggleFlyByWire(string paramName, bool enabled) case "target": if (enabled) { + if (!currentVessel.Autopilot.CanSetMode(VesselAutopilot.AutopilotMode.Target)) + { + throw new kOS.Safe.Exceptions.KOSException( + string.Format("Cannot set autopilot value, pilot/probe does not support {0}", paramName)); + } clearStockAutopilot("target"); - if (!Shared.Vessel.ActionGroups[KSPActionGroup.SAS]) Shared.Vessel.ActionGroups.SetGroup(KSPActionGroup.SAS, true); + if (!currentVessel.ActionGroups[KSPActionGroup.SAS]) currentVessel.ActionGroups.SetGroup(KSPActionGroup.SAS, true); currentVessel.Autopilot.SetMode(VesselAutopilot.AutopilotMode.Target); currentVessel.Autopilot.Enable(); } @@ -195,8 +235,13 @@ public void ToggleFlyByWire(string paramName, bool enabled) case "antitarget": if (enabled) { + if (!currentVessel.Autopilot.CanSetMode(VesselAutopilot.AutopilotMode.AntiTarget)) + { + throw new kOS.Safe.Exceptions.KOSException( + string.Format("Cannot set autopilot value, pilot/probe does not support {0}", paramName)); + } clearStockAutopilot("antitarget"); - if (!Shared.Vessel.ActionGroups[KSPActionGroup.SAS]) Shared.Vessel.ActionGroups.SetGroup(KSPActionGroup.SAS, true); + if (!currentVessel.ActionGroups[KSPActionGroup.SAS]) currentVessel.ActionGroups.SetGroup(KSPActionGroup.SAS, true); currentVessel.Autopilot.SetMode(VesselAutopilot.AutopilotMode.AntiTarget); currentVessel.Autopilot.Enable(); } From d6312eb2eea15e84eabafb28c8886198f192aad4 Mon Sep 17 00:00:00 2001 From: hvacengi Date: Sat, 17 Jan 2015 02:37:27 -0500 Subject: [PATCH 097/446] Enable SAS icons kOSProcessor.cs - add SetSASUI method to allow toggling of the SAS icons. FlightControlManager.cs - include toggling of SAS icons when enabling and disabling SAS modes. All credit goes to SirDiazo, since he showed me how to do it in "Actions Everywhere". --- src/kOS/Binding/FlightControlManager.cs | 18 ++++++++++++++++++ src/kOS/Module/kOSProcessor.cs | 6 ++++++ 2 files changed, 24 insertions(+) diff --git a/src/kOS/Binding/FlightControlManager.cs b/src/kOS/Binding/FlightControlManager.cs index e8ce93589..96543d4d0 100644 --- a/src/kOS/Binding/FlightControlManager.cs +++ b/src/kOS/Binding/FlightControlManager.cs @@ -100,10 +100,12 @@ public void ToggleFlyByWire(string paramName, bool enabled) if (!currentVessel.ActionGroups[KSPActionGroup.SAS]) currentVessel.ActionGroups.SetGroup(KSPActionGroup.SAS, true); currentVessel.Autopilot.SetMode(VesselAutopilot.AutopilotMode.Maneuver); currentVessel.Autopilot.Enable(); + ((kOS.Module.kOSProcessor)Shared.Processor).SetSASUI((int)VesselAutopilot.AutopilotMode.Maneuver); } else { currentVessel.Autopilot.SetMode(VesselAutopilot.AutopilotMode.StabilityAssist); + ((kOS.Module.kOSProcessor)Shared.Processor).SetSASUI((int)VesselAutopilot.AutopilotMode.StabilityAssist); } break; case "prograde": @@ -118,10 +120,12 @@ public void ToggleFlyByWire(string paramName, bool enabled) if (!currentVessel.ActionGroups[KSPActionGroup.SAS]) currentVessel.ActionGroups.SetGroup(KSPActionGroup.SAS, true); currentVessel.Autopilot.SetMode(VesselAutopilot.AutopilotMode.Prograde); currentVessel.Autopilot.Enable(); + ((kOS.Module.kOSProcessor)Shared.Processor).SetSASUI((int)VesselAutopilot.AutopilotMode.Prograde); } else { currentVessel.Autopilot.SetMode(VesselAutopilot.AutopilotMode.StabilityAssist); + ((kOS.Module.kOSProcessor)Shared.Processor).SetSASUI((int)VesselAutopilot.AutopilotMode.StabilityAssist); } break; case "retrograde": @@ -136,10 +140,12 @@ public void ToggleFlyByWire(string paramName, bool enabled) if (!currentVessel.ActionGroups[KSPActionGroup.SAS]) currentVessel.ActionGroups.SetGroup(KSPActionGroup.SAS, true); currentVessel.Autopilot.SetMode(VesselAutopilot.AutopilotMode.Retrograde); currentVessel.Autopilot.Enable(); + ((kOS.Module.kOSProcessor)Shared.Processor).SetSASUI((int)VesselAutopilot.AutopilotMode.Retrograde); } else { currentVessel.Autopilot.SetMode(VesselAutopilot.AutopilotMode.StabilityAssist); + ((kOS.Module.kOSProcessor)Shared.Processor).SetSASUI((int)VesselAutopilot.AutopilotMode.StabilityAssist); } break; case "normal": @@ -154,10 +160,12 @@ public void ToggleFlyByWire(string paramName, bool enabled) if (!currentVessel.ActionGroups[KSPActionGroup.SAS]) currentVessel.ActionGroups.SetGroup(KSPActionGroup.SAS, true); currentVessel.Autopilot.SetMode(VesselAutopilot.AutopilotMode.Normal); currentVessel.Autopilot.Enable(); + ((kOS.Module.kOSProcessor)Shared.Processor).SetSASUI((int)VesselAutopilot.AutopilotMode.Normal); } else { currentVessel.Autopilot.SetMode(VesselAutopilot.AutopilotMode.StabilityAssist); + ((kOS.Module.kOSProcessor)Shared.Processor).SetSASUI((int)VesselAutopilot.AutopilotMode.StabilityAssist); } break; case "antinormal": @@ -172,10 +180,12 @@ public void ToggleFlyByWire(string paramName, bool enabled) if (!currentVessel.ActionGroups[KSPActionGroup.SAS]) currentVessel.ActionGroups.SetGroup(KSPActionGroup.SAS, true); currentVessel.Autopilot.SetMode(VesselAutopilot.AutopilotMode.Antinormal); currentVessel.Autopilot.Enable(); + ((kOS.Module.kOSProcessor)Shared.Processor).SetSASUI((int)VesselAutopilot.AutopilotMode.Antinormal); } else { currentVessel.Autopilot.SetMode(VesselAutopilot.AutopilotMode.StabilityAssist); + ((kOS.Module.kOSProcessor)Shared.Processor).SetSASUI((int)VesselAutopilot.AutopilotMode.StabilityAssist); } break; case "radialin": @@ -190,10 +200,12 @@ public void ToggleFlyByWire(string paramName, bool enabled) if (!currentVessel.ActionGroups[KSPActionGroup.SAS]) currentVessel.ActionGroups.SetGroup(KSPActionGroup.SAS, true); currentVessel.Autopilot.SetMode(VesselAutopilot.AutopilotMode.RadialIn); currentVessel.Autopilot.Enable(); + ((kOS.Module.kOSProcessor)Shared.Processor).SetSASUI((int)VesselAutopilot.AutopilotMode.RadialIn); } else { currentVessel.Autopilot.SetMode(VesselAutopilot.AutopilotMode.StabilityAssist); + ((kOS.Module.kOSProcessor)Shared.Processor).SetSASUI((int)VesselAutopilot.AutopilotMode.StabilityAssist); } break; case "radialout": @@ -208,10 +220,12 @@ public void ToggleFlyByWire(string paramName, bool enabled) if (!currentVessel.ActionGroups[KSPActionGroup.SAS]) currentVessel.ActionGroups.SetGroup(KSPActionGroup.SAS, true); currentVessel.Autopilot.SetMode(VesselAutopilot.AutopilotMode.RadialOut); currentVessel.Autopilot.Enable(); + ((kOS.Module.kOSProcessor)Shared.Processor).SetSASUI((int)VesselAutopilot.AutopilotMode.RadialOut); } else { currentVessel.Autopilot.SetMode(VesselAutopilot.AutopilotMode.StabilityAssist); + ((kOS.Module.kOSProcessor)Shared.Processor).SetSASUI((int)VesselAutopilot.AutopilotMode.StabilityAssist); } break; case "target": @@ -226,10 +240,12 @@ public void ToggleFlyByWire(string paramName, bool enabled) if (!currentVessel.ActionGroups[KSPActionGroup.SAS]) currentVessel.ActionGroups.SetGroup(KSPActionGroup.SAS, true); currentVessel.Autopilot.SetMode(VesselAutopilot.AutopilotMode.Target); currentVessel.Autopilot.Enable(); + ((kOS.Module.kOSProcessor)Shared.Processor).SetSASUI((int)VesselAutopilot.AutopilotMode.Target); } else { currentVessel.Autopilot.SetMode(VesselAutopilot.AutopilotMode.StabilityAssist); + ((kOS.Module.kOSProcessor)Shared.Processor).SetSASUI((int)VesselAutopilot.AutopilotMode.StabilityAssist); } break; case "antitarget": @@ -244,10 +260,12 @@ public void ToggleFlyByWire(string paramName, bool enabled) if (!currentVessel.ActionGroups[KSPActionGroup.SAS]) currentVessel.ActionGroups.SetGroup(KSPActionGroup.SAS, true); currentVessel.Autopilot.SetMode(VesselAutopilot.AutopilotMode.AntiTarget); currentVessel.Autopilot.Enable(); + ((kOS.Module.kOSProcessor)Shared.Processor).SetSASUI((int)VesselAutopilot.AutopilotMode.AntiTarget); } else { currentVessel.Autopilot.SetMode(VesselAutopilot.AutopilotMode.StabilityAssist); + ((kOS.Module.kOSProcessor)Shared.Processor).SetSASUI((int)VesselAutopilot.AutopilotMode.StabilityAssist); } break; case "steering": diff --git a/src/kOS/Module/kOSProcessor.cs b/src/kOS/Module/kOSProcessor.cs index 67458b139..85ae5da32 100644 --- a/src/kOS/Module/kOSProcessor.cs +++ b/src/kOS/Module/kOSProcessor.cs @@ -530,5 +530,11 @@ public void ExecuteInterProcCommand(InterProcCommand command) command.Execute(shared); } } + + public void SetSASUI(int mode) + { + RUIToggleButton[] SASbtns = FindObjectOfType().modeButtons; + SASbtns.ElementAt(mode).SetTrue(true, true); + } } } From fb065580bc35baa5490edd7cc8db39c94a2634d0 Mon Sep 17 00:00:00 2001 From: Chris Woerz Date: Sun, 18 Jan 2015 14:41:45 -0700 Subject: [PATCH 098/446] changed suffix name based on code review --- src/kOS/Suffixed/Part/PartValue.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kOS/Suffixed/Part/PartValue.cs b/src/kOS/Suffixed/Part/PartValue.cs index 2fb2a0919..d6be7fd65 100644 --- a/src/kOS/Suffixed/Part/PartValue.cs +++ b/src/kOS/Suffixed/Part/PartValue.cs @@ -40,7 +40,7 @@ private void PartInitializeSuffixes() AddSuffix("TARGETABLE", new Suffix(() => Part.Modules.OfType().Any())); AddSuffix("SHIP", new Suffix(() => new VesselTarget(Part.vessel, shared))); AddSuffix("GETMODULE", new OneArgsSuffix(GetModule)); - AddSuffix("GETMODULEINDEX", new OneArgsSuffix(GetModuleIndex)); + AddSuffix("GETMODULEBYINDEX", new OneArgsSuffix(GetModuleIndex)); AddSuffix(new[] { "MODULES", "ALLMODULES" }, new Suffix(GetAllModules, "A List of all the modules' names on this part")); AddSuffix("PARENT", new Suffix(() => PartValueFactory.Construct(Part.parent,shared), "The parent part of this part")); AddSuffix("HASPARENT", new Suffix(() => Part.parent != null, "Tells you if this part has a parent, is used to avoid null exception from PARENT")); From 9f2355edbb01850ac43b2bc3c1af84fcba08a531 Mon Sep 17 00:00:00 2001 From: Chris Woerz Date: Sun, 18 Jan 2015 14:47:33 -0700 Subject: [PATCH 099/446] fixed remotetech api namespace --- src/kOS/AddOns/RemoteTech2/RemoteTechHook.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/kOS/AddOns/RemoteTech2/RemoteTechHook.cs b/src/kOS/AddOns/RemoteTech2/RemoteTechHook.cs index 15294505a..2d5c2b9a2 100644 --- a/src/kOS/AddOns/RemoteTech2/RemoteTechHook.cs +++ b/src/kOS/AddOns/RemoteTech2/RemoteTechHook.cs @@ -7,7 +7,7 @@ namespace kOS.AddOns.RemoteTech2 public static class RemoteTechHook { private const String REMOTE_TECH_ASSEMBLY = "RemoteTech"; - private const String REMOTE_TECH_API = "RemoteTech.API"; + private const String REMOTE_TECH_API = "RemoteTech.API.API"; private static bool hookFail; private static IRemoteTechAPIv1 instance; @@ -55,11 +55,12 @@ private static IRemoteTechAPIv1 InitializeAPI() { var loadedAssembly = AssemblyLoader.loadedAssemblies.FirstOrDefault(a => a.assembly.GetName().Name.Equals(REMOTE_TECH_ASSEMBLY)); if (loadedAssembly == null) return null; + Safe.Utilities.Debug.Logger.Log(string.Format("Found RemoteTech! Version: {0}.{1}", loadedAssembly.versionMajor, loadedAssembly.versionMinor)); var type = loadedAssembly.assembly.GetTypes().FirstOrDefault(t => t.FullName.Equals(REMOTE_TECH_API)); if (type == null) return null; - Safe.Utilities.Debug.Logger.Log(string.Format("Found API! {0} Version: {1}.{2}", type.Name, loadedAssembly.versionMajor, loadedAssembly.versionMinor)); + Safe.Utilities.Debug.Logger.Log(string.Format("Found API! {0} ", type.Name)); var methods = type.GetMethods(); var api = new RemoteTechAPI(); From 2f80e18c1ff78a4b860aa2ee8a60a69c0be228c5 Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Sun, 18 Jan 2015 22:23:39 -0600 Subject: [PATCH 100/446] switching out to a different issue - not done yet --- src/kOS/UserIO/TelnetSingletonServer.cs | 275 ++++++++++++++---------- src/kOS/UserIO/TelnetWelcomeMenu.cs | 175 +++++++++++++++ src/kOS/kOS.csproj | 1 + 3 files changed, 336 insertions(+), 115 deletions(-) create mode 100644 src/kOS/UserIO/TelnetWelcomeMenu.cs diff --git a/src/kOS/UserIO/TelnetSingletonServer.cs b/src/kOS/UserIO/TelnetSingletonServer.cs index 323c84ebc..ec5384e28 100644 --- a/src/kOS/UserIO/TelnetSingletonServer.cs +++ b/src/kOS/UserIO/TelnetSingletonServer.cs @@ -8,6 +8,8 @@ using kOS.Safe.Utilities; using kOS.Module; using UnityEngine; +using System.IO; +using System.IO.Pipes; namespace kOS.UserIO { @@ -20,18 +22,34 @@ public class TelnetSingletonServer : MonoBehaviour { // ReSharper disable SuggestUseVarKeywordEvident // ReSharper disable RedundantDefaultFieldInitializer - private volatile TcpClient client; - private volatile NetworkStream stream; + private TcpClient client; - private List availableCPUs; - private DateTime lastMenuQueryTime; + /// + /// The raw socket stream used to talk directly to the client across the network. + /// It is bidirectional - handling both the input from and output to the client. + /// + private NetworkStream rawStream; + + /// + /// The queue that other parts of KOS can use to read characters from the telnet client. + /// + private volatile Queue inQueue; + + /// + /// The queue that other parts of kOS can use to write characters to the telent client. + /// + private volatile Queue outQueue; - private kOSProcessor connectedCPU = null; // when not connected, it will be on the local menu. + public kOSProcessor ConnectedProcessor { get; private set; } - private volatile byte[] rawReadBuffer = new byte[128]; // use small chunks - private string localMenuBuffer = ""; + private byte[] rawReadBuffer = new byte[128]; // use small chunks + private byte[] rawWriteBuffer = new byte[128]; // use small chunks private Thread inThread; + private Thread outThread; + + private TelnetWelcomeMenu welcomeMenu; + // ReSharper enable RedundantDefaultFieldInitializer // ReSharper enable SuggestUseVarKeywordEvident @@ -83,36 +101,107 @@ public class TelnetSingletonServer : MonoBehaviour private const byte RFC1184_TRAPSIG = 2; private const byte RFC1184_MODE_ACK = 4; private const byte RFC1184_SOFT_TAB = 8; - private const byte RFC1184_LIT_ECHO = 16; + private const byte RFC1184_LIT_ECHO = 16; + public TelnetSingletonServer(TcpClient client) { this.client = client; - stream = client.GetStream(); + rawStream = client.GetStream(); inThread = new Thread(DoInThread); - + outThread = new Thread(DoOutThread); + outQueue = new Queue(); + inQueue = new Queue(); + } + + public void ConnectToProcessor(kOSProcessor processor) + { + ConnectedProcessor = processor; + // TODO: Write the part of the mod that listens to this telnet inside termwindow, and at this point + // tell it to connect to this telnet server. + } + + /// + /// Get the next available char from the client. + /// Can throw exception if there is no such char. Check ahead of time to see if + /// there's at least one character available using InputWaiting(). + /// + /// one character read + public char ReadChar() + { + return inQueue.Dequeue(); + } + + /// + /// Get a string of all available charactesr from the client. + /// If no such chars are available it will not throw an exception. Instead it just returns a zero length string. + /// + /// All currently available input characters returned in one string. + public string ReadAll() + { + if (inQueue.Count == 0) + return String.Empty; + StringBuilder sb = new StringBuilder(); + while (inQueue.Count > 0) + sb.Append(inQueue.Dequeue()); + return sb.ToString(); + } + + /// + /// Determine if the input queue has pending chars to read. If it isn't, then attempts to call ReadOneChar will throw an exception. + /// true if input is currently Queued + public bool InputWaiting() + { + return inQueue.Count > 0; } - public void SendText(string str) + /// + /// Write one character out to the telnet client. + /// character to write + /// + public void Write(char ch) + { + rawStream.Write(Encoding.UTF8.GetBytes(new String(ch,1)),0,1); + } + + /// + /// Write a string out to the telnet client. + /// string to write + /// + public void Write(string str) + { + byte[] buf = Encoding.UTF8.GetBytes(str); + rawStream.Write(buf,0,buf.Length); + } + + /// + /// Bypasses the Queues and just sends text directly to the socket stream. + /// + /// + private void SendTextRaw(string str) { byte[] outBuff = System.Text.Encoding.UTF8.GetBytes(str); - stream.Write(outBuff, 0, outBuff.Length); + rawStream.Write(outBuff, 0, outBuff.Length); } public void StopListening() { inThread.Abort(); inThread = null; // dispose old thread. - stream.Close(); + outThread.Abort(); + outThread = null; // dispose old thread. + + rawStream.Close(); } public void StartListening() { - inThread.Start(); - SendText("Connected to kOS Telnet Server.\r\n"); + SendTextRaw("Connected to the kOS Terminal Server.\r\n"); - LineAtATime(false); + inThread.Start(); + outThread.Start(); + LineAtATime(false); // The proper protocol demands that we pay attention to whether or not the client telnet session actually knows how to // do those requested settings, and negotiate back to it. But nobody makes telnet clients anymore that are that bad // that they can't do these things so I'll be lazy and just assume they worked without paying attention to the responses sent back. @@ -123,64 +212,19 @@ public void LineAtATime(bool buffered) if (buffered) { // Send some telnet protocol stuff telling the other side how I'd like it to behave: - stream.Write( new byte[] {RFC854_IAC, RFC854_DO, RFC857_ECHO},0, 3); // don't local-echo. - stream.Write( new byte[] {RFC854_IAC, RFC854_DONT, RFC858_SUPPRESS_GOAHEAD}, 0, 3); // send one char at a time without buffering lines. + rawStream.Write( new byte[] {RFC854_IAC, RFC854_DO, RFC857_ECHO},0, 3); // don't local-echo. + rawStream.Write( new byte[] {RFC854_IAC, RFC854_DONT, RFC858_SUPPRESS_GOAHEAD}, 0, 3); // send one char at a time without buffering lines. } else { // Send some telnet protocol stuff telling the other side how I'd like it to behave: - stream.Write( new byte[] {RFC854_IAC, RFC854_DONT, RFC857_ECHO},0, 3); // don't local-echo. - stream.Write( new byte[] {RFC854_IAC, RFC854_DO, RFC858_SUPPRESS_GOAHEAD}, 0, 3); // send one char at a time without buffering lines. + rawStream.Write( new byte[] {RFC854_IAC, RFC854_DONT, RFC857_ECHO},0, 3); // don't local-echo. + rawStream.Write( new byte[] {RFC854_IAC, RFC854_DO, RFC858_SUPPRESS_GOAHEAD}, 0, 3); // send one char at a time without buffering lines. } } - private bool CPUListChanged() - { - List newList = kOSProcessor.AllInstances(); - bool itChanged = false; - if (newList.Count != availableCPUs.Count) - itChanged = true; - else - for( int i = 0; i < newList.Count ; ++i) - if (newList[i] != availableCPUs[i]) - itChanged = true; - availableCPUs = newList; - - return itChanged; - } - - private void PrintCPUMenu() - { - SendText("______________________________\r\n"); - SendText("Available CPUS for Connection:\r\n"); - - int userPickNum = 1; - bool atLeastOne = false; - foreach (kOSProcessor kModule in availableCPUs) - { - atLeastOne = true; - Part thisPart = kModule.part; - KOSNameTag partTag = thisPart.Modules.OfType().FirstOrDefault(); - string partLabel = String.Format("{0}({1})", - thisPart.partInfo.title.Split(' ')[0], // just the first word of the name, i.e "CX-4181" - ((partTag == null) ? "" : partTag.nameTag) - ); - Vessel vessel = (thisPart == null) ? null/*can this even happen?*/ : thisPart.vessel; - string vesselLabel = (vessel == null) ? ""/*can this even happen?*/ : vessel.GetName(); - - SendText(String.Format(" [{0}] Vessel({1}), CPU({2})\r\n",userPickNum, vesselLabel, partLabel)); - ++userPickNum; - } - if (atLeastOne) - SendText("Type a selection number and press return/enter.\r\n" + - "Or enter [Q] to quit.\r\n" + - "> "); - else - SendText("\r\n"); - } - private void DoInThread() { // All threads in a KSP mod must be careful NOT to access any KSP or Unity methods @@ -196,63 +240,62 @@ private void DoInThread() break; } - if (connectedCPU == null) + if (welcomeMenu == null) { - DoMenu(); + if (ConnectedProcessor == null) + SpawnWelcomeMenu(); } - else + else if (ConnectedProcessor != null) // welcome menu is attached but we now have a processor picked, so detach it. { - int numRead = stream.Read(rawReadBuffer, 0, rawReadBuffer.Length); // This is blocking, so this thread will be idle when client isn't typing. - string cleanedText = TelnetProtocolScrape(rawReadBuffer, numRead); - // TODO - make this better - right now I'm ignoring the inBuffer and just echoing this out - // to the out buffer to print it back to the user for a test. In future this should attach to the CPU: - SendText("["+cleanedText+"]"); - } + welcomeMenu.Quit(); + welcomeMenu = null ; // let it get garbage collected. + } + + int numRead = rawStream.Read(rawReadBuffer, 0, rawReadBuffer.Length); // This is blocking, so this thread will be idle when client isn't typing. + if (numRead > 0 ) + { + string sendOut = TelnetProtocolScrape(rawReadBuffer, numRead); + foreach (char ch in sendOut) + { + inQueue.Enqueue(ch); + } + } } } - private void DoMenu() + private void DoOutThread() { - - if (System.DateTime.Now > lastMenuQueryTime.AddMilliseconds(500)) - { - lastMenuQueryTime = System.DateTime.Now; - if( CPUListChanged() ) - PrintCPUMenu(); - } - int numRead = stream.Read(rawReadBuffer, 0, rawReadBuffer.Length); // This is blocking, so this thread will be idle when client isn't typing. - string cleanedText = TelnetProtocolScrape(rawReadBuffer, numRead); - SendText(cleanedText); - localMenuBuffer = localMenuBuffer + cleanedText; - int firstEOLN = localMenuBuffer.IndexOfAny(new char[] {'\r','\n'}); - - // end of line hasn't been pressed - if (firstEOLN < 0) - return; + // All threads in a KSP mod must be careful NOT to access any KSP or Unity methods + // from inside their execution, because KSP and Unity are not threadsafe - if(localMenuBuffer.Substring(0,1).Equals("Q",StringComparison.CurrentCultureIgnoreCase)) - { - StopListening(); - stream.Close(); - localMenuBuffer = ""; - return; - } - - int endOfNumbers = cleanedText.LastIndexOfAny(new char[] {'0','1','2','3','4','5','6','7','8','9'}); - int pick; - if( int.TryParse(localMenuBuffer.Substring(0,endOfNumbers+1),out pick) ) - { - SendText("Connecting..."); - connectedCPU = availableCPUs[pick-1]; - } - else + while (true) { - SendText("Garbled answer. Try Again.\r\n"); - availableCPUs = new List(); // resetting the list forces it to recalc and reprint the menu next time. + // Detect if the client closed from its end: + if (!client.Connected) + { + outThread.Abort(); + StopListening(); + break; + } + + StringBuilder sb = new StringBuilder(); + while (outQueue.Count > 0) + sb.Append(outQueue.Dequeue()); + if (sb.Length > 0) + { + SendTextRaw(sb.ToString()); + } } - localMenuBuffer = ""; } + private void SpawnWelcomeMenu() + { + var gObj = new GameObject( "TelnetWelcomeMenu_" + this.GetInstanceID(), typeof(TelnetWelcomeMenu) ); + DontDestroyOnLoad(gObj); + welcomeMenu = (TelnetWelcomeMenu)gObj.GetComponent(typeof(TelnetWelcomeMenu)); + welcomeMenu.Setup(this); + } + private string TelnetProtocolScrape(byte[] inRawBuff, int rawLength) { // At max the cooked version will be the same size as the raw. It might be a little less: @@ -284,8 +327,8 @@ private string TelnetProtocolScrape(byte[] inRawBuff, int rawLength) } } - // Convert the cooked buffer into a string to passing back: - return System.Text.Encoding.UTF8.GetString(inCookedBuff,0,cookedIndex); + // Convert the cooked buffer into a shorter buff to pass back: + return Encoding.UTF8.GetString(inCookedBuff, 0, cookedIndex); } private int TelnetConsumeDo( byte[] remainingBuff, int index) @@ -295,13 +338,15 @@ private int TelnetConsumeDo( byte[] remainingBuff, int index) switch (option) { // If other side wants me to echo, agree - case RFC857_ECHO: stream.Write( new byte[] {RFC854_IAC, RFC854_WILL, RFC857_ECHO}, 0, 3); + case RFC857_ECHO: rawStream.Write( new byte[] {RFC854_IAC, RFC854_WILL, RFC857_ECHO}, 0, 3); break; // If other side wants me to go char-at-a-atime, agree case RFC858_SUPPRESS_GOAHEAD: - stream.Write( new byte[] {RFC854_IAC, RFC854_WILL, RFC858_SUPPRESS_GOAHEAD}, 0, 3); + rawStream.Write( new byte[] {RFC854_IAC, RFC854_WILL, RFC858_SUPPRESS_GOAHEAD}, 0, 3); + break; + default: + offset += TelnetConsumeOther(RFC854_DO, remainingBuff, 0); break; - default: break; } // Everything below here is to help debug: diff --git a/src/kOS/UserIO/TelnetWelcomeMenu.cs b/src/kOS/UserIO/TelnetWelcomeMenu.cs new file mode 100644 index 000000000..3fdfa326b --- /dev/null +++ b/src/kOS/UserIO/TelnetWelcomeMenu.cs @@ -0,0 +1,175 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; +using System.Linq; +using UnityEngine; +using kOS.Module; + +namespace kOS.UserIO +{ + /// + /// Handles the reading and writing of the not-yet-connected menu for + /// telnet clients that aren't attached to a CPU at the moment. + /// It is a Monobehavior rather than a thread, because it needs to talk + /// to the KSP API and KSP is not threadsafe. All its work is done + /// through Update(). + /// + public class TelnetWelcomeMenu : MonoBehaviour + { + private TelnetSingletonServer telnetServer; + private List availableCPUs; + private DateTime lastMenuQueryTime; + private StringBuilder localMenuBuffer; + private bool firstTime; + private bool forceMenuReprint; + + // Because this will be created as a Unity Gameobject, it has to have a parameterless constructor. + // Actual setup args will be in the Setup() method below. + public TelnetWelcomeMenu() + { + firstTime = true; + localMenuBuffer = new StringBuilder(); + availableCPUs = new List(); + } + + public void Setup(TelnetSingletonServer tserver) + { + telnetServer = tserver; + lastMenuQueryTime = System.DateTime.MinValue; // Force a stale timestamp the first time so it will print the menu. + } + + public void Quit() + { + telnetServer.StopListening(); + enabled = false; + } + + + public virtual void Update() + { + + // Regularly check to see if the CPU list has changed while the user was sitting + // on the menu. If so, reprint it: + // Querying the list of CPU's can be a little expensive, so don't do it too often: + if (System.DateTime.Now > lastMenuQueryTime + TimeSpan.FromMilliseconds(1000)) + { + bool listChanged = CPUListChanged(); + if (!firstTime && listChanged) + telnetServer.Write("\r\n--(List of CPU's has Changed)--\r\n\r\n"); + firstTime = false; + if (listChanged || forceMenuReprint ) + PrintCPUMenu(); + } + + while (telnetServer.InputWaiting()) + { + char ch = telnetServer.ReadChar(); + + switch (ch) + { + case '\r': + case '\n': + LineEntered(); + break; + // Implement crude input editing (backspace only) in this menu prompt: + case (char)0x08: // ascii backspace. + case (char)0x127: // ascii del. + if (localMenuBuffer.Length > 0) + localMenuBuffer.Remove(localMenuBuffer.Length-1,1); + telnetServer.Write((char)0x08+" "+(char)0x08); // backspace space backspace. + break; + default: + localMenuBuffer.Append(ch); + telnetServer.Write(ch); + break; + } + } + } + + public void LineEntered() + { + if (localMenuBuffer.Length == 0) + return; + telnetServer.Write("\r\n"); + string cmd = localMenuBuffer.ToString(); + kOS.Safe.Utilities.Debug.Logger.SuperVerbose( "TelnetWelcomeMenu.LineEntered(): String from client was: [" + cmd.ToString() + "]"); + localMenuBuffer.Remove(0,localMenuBuffer.Length); // clear the buffer for next line. + + if (String.Equals(cmd.Substring(0,1),"Q",StringComparison.CurrentCultureIgnoreCase)) + { + Quit(); + return; + } + int pickNumber; + if (!int.TryParse(cmd, out pickNumber) ) + { + telnetServer.Write("Garbled selection. Try again.\r\n"); + forceMenuReprint = true; + return; + } + if (pickNumber <= 0 || pickNumber > availableCPUs.Count) + { + telnetServer.Write("No such number (" + pickNumber + ") on the menu.\r\n"); + forceMenuReprint = true; + return; + } + telnetServer.ConnectToProcessor(availableCPUs[pickNumber-1]); + Quit(); + } + + private bool CPUListChanged() + { + List newList = kOSProcessor.AllInstances(); + bool itChanged = false; + + if (newList.Count != availableCPUs.Count) + itChanged = true; + else + for( int i = 0; i < newList.Count ; ++i) + if (newList[i] != availableCPUs[i]) + itChanged = true; + + Console.WriteLine("in CPUListChanged(): itChanged = "+itChanged+", newList.Count="+newList.Count+", availableCPUs.Count="+availableCPUs.Count); + availableCPUs = newList; + lastMenuQueryTime = System.DateTime.Now; + return itChanged; + } + + private void PrintCPUMenu() + { + localMenuBuffer.Remove(0,localMenuBuffer.Length); // Any time the menu is reprinted, clear out any previous buffer text. + telnetServer.ReadAll(); // Consume and throw away any readahead typing that preceeded the printing of this menu. + + forceMenuReprint = false; + + telnetServer.Write(" Available CPUS for Connection:\r\n"); + + int userPickNum = 1; + bool atLeastOne = false; + foreach (kOSProcessor kModule in availableCPUs) + { + atLeastOne = true; + Part thisPart = kModule.part; + KOSNameTag partTag = thisPart.Modules.OfType().FirstOrDefault(); + string partLabel = String.Format("{0}({1})", + thisPart.partInfo.title.Split(' ')[0], // just the first word of the name, i.e "CX-4181" + ((partTag == null) ? "" : partTag.nameTag) + ); + Vessel vessel = (thisPart == null) ? null/*can this even happen?*/ : thisPart.vessel; + string vesselLabel = (vessel == null) ? ""/*can this even happen?*/ : vessel.GetName(); + + telnetServer.Write(String.Format("\t[{0}] Vessel({1}), CPU({2})\r\n",userPickNum, vesselLabel, partLabel)); + ++userPickNum; + } + if (atLeastOne) + telnetServer.Write("Type a selection number and press return/enter.\r\n" + + "Or enter [Q] to quit terminal server.\r\n" + + "> "); + else + telnetServer.Write("\t\r\n"); + + } + + } +} diff --git a/src/kOS/kOS.csproj b/src/kOS/kOS.csproj index 37de40690..e73a57f12 100644 --- a/src/kOS/kOS.csproj +++ b/src/kOS/kOS.csproj @@ -131,6 +131,7 @@ + From 5dc5948d20b1115b78718fdb03a5e8ae11b522e7 Mon Sep 17 00:00:00 2001 From: Chris Woerz Date: Mon, 19 Jan 2015 07:07:23 -0700 Subject: [PATCH 101/446] gimbal is not both a partvalue and a partmodulefield --- .../Suffixed/Part/PartModuleFieldsFactory.cs | 40 ------------------- src/kOS/Suffixed/Part/PartValue.cs | 1 + src/kOS/Suffixed/Part/PartValueFactory.cs | 6 +-- .../Suffixed/PartModuleField/GimbalFields.cs | 35 ++++++++++++++++ .../PartModuleFields.cs | 16 ++++---- .../PartModuleFieldsFactory.cs | 29 ++++++++++++++ src/kOS/Suffixed/VesselTarget.cs | 1 + src/kOS/kOS.csproj | 5 ++- 8 files changed, 80 insertions(+), 53 deletions(-) delete mode 100644 src/kOS/Suffixed/Part/PartModuleFieldsFactory.cs create mode 100644 src/kOS/Suffixed/PartModuleField/GimbalFields.cs rename src/kOS/Suffixed/{Part => PartModuleField}/PartModuleFields.cs (99%) create mode 100644 src/kOS/Suffixed/PartModuleField/PartModuleFieldsFactory.cs diff --git a/src/kOS/Suffixed/Part/PartModuleFieldsFactory.cs b/src/kOS/Suffixed/Part/PartModuleFieldsFactory.cs deleted file mode 100644 index 3dca141d4..000000000 --- a/src/kOS/Suffixed/Part/PartModuleFieldsFactory.cs +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Created by SharpDevelop. - * User: Dunbaratu - * Date: 11/5/2014 - * Time: 3:13 AM - * - * To change this template use Tools | Options | Coding | Edit Standard Headers. - */ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Net; -using kOS.Safe.Encapsulation; - -namespace kOS.Suffixed.Part -{ - /// - /// Description of PartModuleFieldFactory. - /// - public class PartModuleFieldsFactory - { - public static ListValue Construct(IEnumerable modules, SharedObjects shared) - { - var list = new List(); - foreach (var mod in modules) - { - list.Add(Construct(mod, shared)); - } - return ListValue.CreateList(list); - } - - public static PartModuleFields Construct(global::PartModule mod, SharedObjects shared) - { - // This seems pointlessly do-nothing for a special factory now, - // but it's here so that it can possibly become more - // sophisticated later if need be: - return new PartModuleFields(mod, shared); - } - } -} \ No newline at end of file diff --git a/src/kOS/Suffixed/Part/PartValue.cs b/src/kOS/Suffixed/Part/PartValue.cs index d6be7fd65..93cc60d00 100644 --- a/src/kOS/Suffixed/Part/PartValue.cs +++ b/src/kOS/Suffixed/Part/PartValue.cs @@ -4,6 +4,7 @@ using kOS.Safe.Exceptions; using kOS.Safe.Encapsulation.Suffixes; using System.Linq; +using kOS.Suffixed.PartModuleField; using kOS.Utilities; using UnityEngine; diff --git a/src/kOS/Suffixed/Part/PartValueFactory.cs b/src/kOS/Suffixed/Part/PartValueFactory.cs index 9bddea423..f1ee5e28d 100644 --- a/src/kOS/Suffixed/Part/PartValueFactory.cs +++ b/src/kOS/Suffixed/Part/PartValueFactory.cs @@ -34,9 +34,9 @@ public static PartValue Construct(global::Part part, SharedObjects shared) ModuleEnviroSensor mSense = module as ModuleEnviroSensor; if (mSense != null) return new SensorValue(part, mSense, shared); - var moduleGimbal = module as ModuleGimbal; - if (moduleGimbal != null) - return new GimbalValue(moduleGimbal, shared); + var gimbalModule = module as ModuleGimbal; + if (gimbalModule != null) + return new GimbalValue(gimbalModule,shared); } diff --git a/src/kOS/Suffixed/PartModuleField/GimbalFields.cs b/src/kOS/Suffixed/PartModuleField/GimbalFields.cs new file mode 100644 index 000000000..39e522095 --- /dev/null +++ b/src/kOS/Suffixed/PartModuleField/GimbalFields.cs @@ -0,0 +1,35 @@ +using kOS.Safe.Encapsulation.Suffixes; + +namespace kOS.Suffixed.PartModuleField +{ + public class GimbalFields : PartModuleFields + { + private readonly ModuleGimbal gimbal; + + public GimbalFields(ModuleGimbal gimbal, SharedObjects sharedObj):base(gimbal, sharedObj) + { + this.gimbal = gimbal; + InitializeGimbalSuffixes(); + } + + private void InitializeGimbalSuffixes() + { + AddSuffix("LOCK", new SetSuffix(() => gimbal.gimbalLock, value => + { + if (value) + { + gimbal.LockGimbal(); + } + else + { + gimbal.FreeGimbal(); + } + }, "Is the Gimbal free to travel?")); + AddSuffix("RANGE", new Suffix(() => gimbal.gimbalRange ,"The Gimbal's Possible Range of movement")); + AddSuffix("RESPONSESPEED", new Suffix(() => gimbal.gimbalResponseSpeed, "The Gimbal's Possible Rate of travel")); + AddSuffix("PITCHANGLE", new Suffix(() => gimbal.gimbalLock ? 0 : gimbal.gimbalAnglePitch, "Current Gimbal Pitch")); + AddSuffix("YAWANGLE", new Suffix(() => gimbal.gimbalLock ? 0 : gimbal.gimbalAngleYaw, "Current Gimbal Yaw" )); + AddSuffix("ROLLANGLE", new Suffix(() => gimbal.gimbalLock ? 0 : gimbal.gimbalAngleRoll, "Current Gimbal Roll")); + } + } +} diff --git a/src/kOS/Suffixed/Part/PartModuleFields.cs b/src/kOS/Suffixed/PartModuleField/PartModuleFields.cs similarity index 99% rename from src/kOS/Suffixed/Part/PartModuleFields.cs rename to src/kOS/Suffixed/PartModuleField/PartModuleFields.cs index 58d2b9b29..ac1c56d6a 100644 --- a/src/kOS/Suffixed/Part/PartModuleFields.cs +++ b/src/kOS/Suffixed/PartModuleField/PartModuleFields.cs @@ -1,15 +1,14 @@ -using System.Linq; -using kOS.Safe.Encapsulation; -using kOS.Safe.Exceptions; -using kOS.Safe.Encapsulation.Suffixes; +using System; using System.Collections.Generic; +using System.Linq; using System.Text; +using kOS.Safe.Encapsulation; +using kOS.Safe.Encapsulation.Suffixes; +using kOS.Safe.Exceptions; +using kOS.Suffixed.Part; using UnityEngine; -using System; - - -namespace kOS.Suffixed.Part +namespace kOS.Suffixed.PartModuleField { /// /// An abstraction of a part module attached to a PartValue, that allows @@ -26,6 +25,7 @@ public class PartModuleFields : Structure /// Create a kOS-user variable wrapper around a KSP PartModule attached to a part. /// /// the KSP PartModule to make a wrapper for + /// The omnipresent shared data public PartModuleFields(PartModule partModule, SharedObjects shared) { this.partModule = partModule; diff --git a/src/kOS/Suffixed/PartModuleField/PartModuleFieldsFactory.cs b/src/kOS/Suffixed/PartModuleField/PartModuleFieldsFactory.cs new file mode 100644 index 000000000..0c817eb60 --- /dev/null +++ b/src/kOS/Suffixed/PartModuleField/PartModuleFieldsFactory.cs @@ -0,0 +1,29 @@ +using System.Collections.Generic; +using System.Linq; +using kOS.Safe.Encapsulation; + +namespace kOS.Suffixed.PartModuleField +{ + /// + /// Description of PartModuleFieldFactory. + /// + public class PartModuleFieldsFactory + { + public static ListValue Construct(IEnumerable modules, SharedObjects shared) + { + var list = modules.Select(mod => Construct(mod, shared)).ToList(); + return ListValue.CreateList(list); + } + + public static PartModuleFields Construct(PartModule mod, SharedObjects shared) + { + var moduleGimbal = mod as ModuleGimbal; + if (moduleGimbal != null) + return new GimbalFields(moduleGimbal, shared); + // This seems pointlessly do-nothing for a special factory now, + // but it's here so that it can possibly become more + // sophisticated later if need be: + return new PartModuleFields(mod, shared); + } + } +} \ No newline at end of file diff --git a/src/kOS/Suffixed/VesselTarget.cs b/src/kOS/Suffixed/VesselTarget.cs index 38328204f..ad5cc52f7 100644 --- a/src/kOS/Suffixed/VesselTarget.cs +++ b/src/kOS/Suffixed/VesselTarget.cs @@ -6,6 +6,7 @@ using kOS.Safe.Exceptions; using kOS.Safe.Utilities; using kOS.Suffixed.Part; +using kOS.Suffixed.PartModuleField; using kOS.Utilities; using kOS.Module; using System.Collections.Generic; diff --git a/src/kOS/kOS.csproj b/src/kOS/kOS.csproj index 0ad827025..3a03a0fca 100644 --- a/src/kOS/kOS.csproj +++ b/src/kOS/kOS.csproj @@ -97,11 +97,12 @@ + + + - - From f3e360e5b9502d47890d5bb2851f73bfd6f88997 Mon Sep 17 00:00:00 2001 From: Brad White Date: Mon, 19 Jan 2015 12:59:17 -0500 Subject: [PATCH 102/446] Remove Autopilot from ToggleFlyByWire FlightControlManager.cs - remove the built in autopilot from the ToggleFlyByWire function and removed the flight parameters. Implementation to be revised to help with script syntax. --- src/kOS/Binding/FlightControlManager.cs | 220 ------------------------ 1 file changed, 220 deletions(-) diff --git a/src/kOS/Binding/FlightControlManager.cs b/src/kOS/Binding/FlightControlManager.cs index 96543d4d0..54072c6c7 100644 --- a/src/kOS/Binding/FlightControlManager.cs +++ b/src/kOS/Binding/FlightControlManager.cs @@ -41,17 +41,6 @@ public override void AddTo(SharedObjects shared) AddNewFlightParam("steering", Shared); AddNewFlightParam("wheelthrottle", Shared); AddNewFlightParam("wheelsteering", Shared); - // Add built in SAS targeting functions - AddNewFlightParam("maneuver", Shared); - AddNewFlightParam("prograde", Shared); - AddNewFlightParam("retrograde", Shared); - AddNewFlightParam("normal", Shared); - AddNewFlightParam("antinormal", Shared); - AddNewFlightParam("radialin", Shared); - AddNewFlightParam("radialout", Shared); - AddNewFlightParam("target", Shared); - AddNewFlightParam("antitarget", Shared); - AddNewFlightParam("damping", Shared); } @@ -66,220 +55,11 @@ private void OnFlyByWire(FlightCtrlState c) } } - private void clearStockAutopilot(string enabledMode) - { - // Use the cpu ToggleFlyByWire method to ensure that we properly unload the autopilot from the other parts of kOS - if (enabledMode != "maneuver" && flightParameters["maneuver"].Enabled) ((kOS.Execution.CPU)Shared.Cpu).ToggleFlyByWire("maneuver", false); ; - if (enabledMode != "prograde" && flightParameters["prograde"].Enabled) ((kOS.Execution.CPU)Shared.Cpu).ToggleFlyByWire("prograde", false); ; - if (enabledMode != "retrograde" && flightParameters["retrograde"].Enabled) ((kOS.Execution.CPU)Shared.Cpu).ToggleFlyByWire("retrograde", false); ; - if (enabledMode != "normal" && flightParameters["normal"].Enabled) ((kOS.Execution.CPU)Shared.Cpu).ToggleFlyByWire("normal", false); ; - if (enabledMode != "antinormal" && flightParameters["antinormal"].Enabled) ((kOS.Execution.CPU)Shared.Cpu).ToggleFlyByWire("antinormal", false); ; - if (enabledMode != "radialin" && flightParameters["radialin"].Enabled) ((kOS.Execution.CPU)Shared.Cpu).ToggleFlyByWire("radialin", false); ; - if (enabledMode != "radialout" && flightParameters["radialout"].Enabled) ((kOS.Execution.CPU)Shared.Cpu).ToggleFlyByWire("radialout", false); ; - if (enabledMode != "target" && flightParameters["target"].Enabled) ((kOS.Execution.CPU)Shared.Cpu).ToggleFlyByWire("target", false); ; - if (enabledMode != "antitarget" && flightParameters["antitarget"].Enabled) ((kOS.Execution.CPU)Shared.Cpu).ToggleFlyByWire("antitarget", false); ; - if (enabledMode != "steering" && flightParameters["steering"].Enabled) { ((kOS.Execution.CPU)Shared.Cpu).ToggleFlyByWire("steering", false); } - } - public void ToggleFlyByWire(string paramName, bool enabled) { Debug.Log(string.Format("kOS: FlightControlManager: ToggleFlyByWire: {0} {1}", paramName, enabled)); if (!flightParameters.ContainsKey(paramName.ToLower())) { UnityEngine.Debug.LogError("kOS: no such flybywire parameter " + paramName); return; } - switch (paramName.ToLower()) - { - case "maneuver": - if (enabled) - { - if (!currentVessel.Autopilot.CanSetMode(VesselAutopilot.AutopilotMode.Maneuver)) - { - throw new kOS.Safe.Exceptions.KOSException( - string.Format("Cannot set autopilot value, pilot/probe does not support {0}", paramName)); - } - clearStockAutopilot("maneuver"); - if (!currentVessel.ActionGroups[KSPActionGroup.SAS]) currentVessel.ActionGroups.SetGroup(KSPActionGroup.SAS, true); - currentVessel.Autopilot.SetMode(VesselAutopilot.AutopilotMode.Maneuver); - currentVessel.Autopilot.Enable(); - ((kOS.Module.kOSProcessor)Shared.Processor).SetSASUI((int)VesselAutopilot.AutopilotMode.Maneuver); - } - else - { - currentVessel.Autopilot.SetMode(VesselAutopilot.AutopilotMode.StabilityAssist); - ((kOS.Module.kOSProcessor)Shared.Processor).SetSASUI((int)VesselAutopilot.AutopilotMode.StabilityAssist); - } - break; - case "prograde": - if (enabled) - { - if (!currentVessel.Autopilot.CanSetMode(VesselAutopilot.AutopilotMode.Prograde)) - { - throw new kOS.Safe.Exceptions.KOSException( - string.Format("Cannot set autopilot value, pilot/probe does not support {0}", paramName)); - } - clearStockAutopilot("prograde"); - if (!currentVessel.ActionGroups[KSPActionGroup.SAS]) currentVessel.ActionGroups.SetGroup(KSPActionGroup.SAS, true); - currentVessel.Autopilot.SetMode(VesselAutopilot.AutopilotMode.Prograde); - currentVessel.Autopilot.Enable(); - ((kOS.Module.kOSProcessor)Shared.Processor).SetSASUI((int)VesselAutopilot.AutopilotMode.Prograde); - } - else - { - currentVessel.Autopilot.SetMode(VesselAutopilot.AutopilotMode.StabilityAssist); - ((kOS.Module.kOSProcessor)Shared.Processor).SetSASUI((int)VesselAutopilot.AutopilotMode.StabilityAssist); - } - break; - case "retrograde": - if (enabled) - { - if (!currentVessel.Autopilot.CanSetMode(VesselAutopilot.AutopilotMode.Retrograde)) - { - throw new kOS.Safe.Exceptions.KOSException( - string.Format("Cannot set autopilot value, pilot/probe does not support {0}", paramName)); - } - clearStockAutopilot("retrograde"); - if (!currentVessel.ActionGroups[KSPActionGroup.SAS]) currentVessel.ActionGroups.SetGroup(KSPActionGroup.SAS, true); - currentVessel.Autopilot.SetMode(VesselAutopilot.AutopilotMode.Retrograde); - currentVessel.Autopilot.Enable(); - ((kOS.Module.kOSProcessor)Shared.Processor).SetSASUI((int)VesselAutopilot.AutopilotMode.Retrograde); - } - else - { - currentVessel.Autopilot.SetMode(VesselAutopilot.AutopilotMode.StabilityAssist); - ((kOS.Module.kOSProcessor)Shared.Processor).SetSASUI((int)VesselAutopilot.AutopilotMode.StabilityAssist); - } - break; - case "normal": - if (enabled) - { - if (!currentVessel.Autopilot.CanSetMode(VesselAutopilot.AutopilotMode.Normal)) - { - throw new kOS.Safe.Exceptions.KOSException( - string.Format("Cannot set autopilot value, pilot/probe does not support {0}", paramName)); - } - clearStockAutopilot("normal"); - if (!currentVessel.ActionGroups[KSPActionGroup.SAS]) currentVessel.ActionGroups.SetGroup(KSPActionGroup.SAS, true); - currentVessel.Autopilot.SetMode(VesselAutopilot.AutopilotMode.Normal); - currentVessel.Autopilot.Enable(); - ((kOS.Module.kOSProcessor)Shared.Processor).SetSASUI((int)VesselAutopilot.AutopilotMode.Normal); - } - else - { - currentVessel.Autopilot.SetMode(VesselAutopilot.AutopilotMode.StabilityAssist); - ((kOS.Module.kOSProcessor)Shared.Processor).SetSASUI((int)VesselAutopilot.AutopilotMode.StabilityAssist); - } - break; - case "antinormal": - if (enabled) - { - if (!currentVessel.Autopilot.CanSetMode(VesselAutopilot.AutopilotMode.Antinormal)) - { - throw new kOS.Safe.Exceptions.KOSException( - string.Format("Cannot set autopilot value, pilot/probe does not support {0}", paramName)); - } - clearStockAutopilot("antinormal"); - if (!currentVessel.ActionGroups[KSPActionGroup.SAS]) currentVessel.ActionGroups.SetGroup(KSPActionGroup.SAS, true); - currentVessel.Autopilot.SetMode(VesselAutopilot.AutopilotMode.Antinormal); - currentVessel.Autopilot.Enable(); - ((kOS.Module.kOSProcessor)Shared.Processor).SetSASUI((int)VesselAutopilot.AutopilotMode.Antinormal); - } - else - { - currentVessel.Autopilot.SetMode(VesselAutopilot.AutopilotMode.StabilityAssist); - ((kOS.Module.kOSProcessor)Shared.Processor).SetSASUI((int)VesselAutopilot.AutopilotMode.StabilityAssist); - } - break; - case "radialin": - if (enabled) - { - if (!currentVessel.Autopilot.CanSetMode(VesselAutopilot.AutopilotMode.RadialIn)) - { - throw new kOS.Safe.Exceptions.KOSException( - string.Format("Cannot set autopilot value, pilot/probe does not support {0}", paramName)); - } - clearStockAutopilot("radialin"); - if (!currentVessel.ActionGroups[KSPActionGroup.SAS]) currentVessel.ActionGroups.SetGroup(KSPActionGroup.SAS, true); - currentVessel.Autopilot.SetMode(VesselAutopilot.AutopilotMode.RadialIn); - currentVessel.Autopilot.Enable(); - ((kOS.Module.kOSProcessor)Shared.Processor).SetSASUI((int)VesselAutopilot.AutopilotMode.RadialIn); - } - else - { - currentVessel.Autopilot.SetMode(VesselAutopilot.AutopilotMode.StabilityAssist); - ((kOS.Module.kOSProcessor)Shared.Processor).SetSASUI((int)VesselAutopilot.AutopilotMode.StabilityAssist); - } - break; - case "radialout": - if (enabled) - { - if (!currentVessel.Autopilot.CanSetMode(VesselAutopilot.AutopilotMode.RadialOut)) - { - throw new kOS.Safe.Exceptions.KOSException( - string.Format("Cannot set autopilot value, pilot/probe does not support {0}", paramName)); - } - clearStockAutopilot("radialout"); - if (!currentVessel.ActionGroups[KSPActionGroup.SAS]) currentVessel.ActionGroups.SetGroup(KSPActionGroup.SAS, true); - currentVessel.Autopilot.SetMode(VesselAutopilot.AutopilotMode.RadialOut); - currentVessel.Autopilot.Enable(); - ((kOS.Module.kOSProcessor)Shared.Processor).SetSASUI((int)VesselAutopilot.AutopilotMode.RadialOut); - } - else - { - currentVessel.Autopilot.SetMode(VesselAutopilot.AutopilotMode.StabilityAssist); - ((kOS.Module.kOSProcessor)Shared.Processor).SetSASUI((int)VesselAutopilot.AutopilotMode.StabilityAssist); - } - break; - case "target": - if (enabled) - { - if (!currentVessel.Autopilot.CanSetMode(VesselAutopilot.AutopilotMode.Target)) - { - throw new kOS.Safe.Exceptions.KOSException( - string.Format("Cannot set autopilot value, pilot/probe does not support {0}", paramName)); - } - clearStockAutopilot("target"); - if (!currentVessel.ActionGroups[KSPActionGroup.SAS]) currentVessel.ActionGroups.SetGroup(KSPActionGroup.SAS, true); - currentVessel.Autopilot.SetMode(VesselAutopilot.AutopilotMode.Target); - currentVessel.Autopilot.Enable(); - ((kOS.Module.kOSProcessor)Shared.Processor).SetSASUI((int)VesselAutopilot.AutopilotMode.Target); - } - else - { - currentVessel.Autopilot.SetMode(VesselAutopilot.AutopilotMode.StabilityAssist); - ((kOS.Module.kOSProcessor)Shared.Processor).SetSASUI((int)VesselAutopilot.AutopilotMode.StabilityAssist); - } - break; - case "antitarget": - if (enabled) - { - if (!currentVessel.Autopilot.CanSetMode(VesselAutopilot.AutopilotMode.AntiTarget)) - { - throw new kOS.Safe.Exceptions.KOSException( - string.Format("Cannot set autopilot value, pilot/probe does not support {0}", paramName)); - } - clearStockAutopilot("antitarget"); - if (!currentVessel.ActionGroups[KSPActionGroup.SAS]) currentVessel.ActionGroups.SetGroup(KSPActionGroup.SAS, true); - currentVessel.Autopilot.SetMode(VesselAutopilot.AutopilotMode.AntiTarget); - currentVessel.Autopilot.Enable(); - ((kOS.Module.kOSProcessor)Shared.Processor).SetSASUI((int)VesselAutopilot.AutopilotMode.AntiTarget); - } - else - { - currentVessel.Autopilot.SetMode(VesselAutopilot.AutopilotMode.StabilityAssist); - ((kOS.Module.kOSProcessor)Shared.Processor).SetSASUI((int)VesselAutopilot.AutopilotMode.StabilityAssist); - } - break; - case "steering": - // Must also do this when using steering, so that the steering doesn't fight the autopilot - // We do this regardless of whether or not enabled is true so that "unlock steering" clears the autopilot mode too - clearStockAutopilot("steering"); - break; - case "damping": - currentVessel.Autopilot.SAS.SetDampingMode(enabled); - break; - default: - break; - } - // this needs to be switched to true only after any other active autopilot settings are cleared. flightParameters[paramName.ToLower()].Enabled = enabled; if (!enabled) From 9536152701d370cf7c7482f9bda20f21a9937400 Mon Sep 17 00:00:00 2001 From: Brad White Date: Mon, 19 Jan 2015 13:23:33 -0500 Subject: [PATCH 103/446] Add SelectAutopilotMode function Misc.cs - Added a new function "selectautopilotmode". This function will be what is called from the opcode to change the autopilot mode. Until the "lock sas to [mode]" implementation is done, this will also allow testing within script by calling the method directly. CPU.cs - Implement the new method SelectAutopilotMode which passes autopilotMode to the BindingManager BindingManager.cs - Implement the new method SelectAutopilotMode which passes autopilotMode to the FlightControlManager FlightControlManager.cs - Implement the new method SelectAutopilotMode. The string value is converted into the AutopilotMode enum, and then passed to the vessel's Autopilot member. Exceptions are thrown if the autopilotMode is not recognized, or if the selection is not supported. SAS is turned on if it isn't already. The steering parameter is disabled if currently enabled, but only if StabilityAssist is not selected. RemoteTech hooks are not currently working, and will need to be updated, as the autopilot appears to be disabled if no signal is detected. --- src/kOS/Binding/BindingManager.cs | 8 +++ src/kOS/Binding/FlightControlManager.cs | 65 +++++++++++++++++++++++++ src/kOS/Execution/CPU.cs | 5 ++ src/kOS/Function/Misc.cs | 13 +++++ 4 files changed, 91 insertions(+) diff --git a/src/kOS/Binding/BindingManager.cs b/src/kOS/Binding/BindingManager.cs index c8605bde8..96708a51c 100644 --- a/src/kOS/Binding/BindingManager.cs +++ b/src/kOS/Binding/BindingManager.cs @@ -126,5 +126,13 @@ public void Dispose() flightControl.Dispose(); } } + + internal void SelectAutopilotMode(string autopilotMode) + { + if (flightControl != null) + { + flightControl.SelectAutopilotMode(autopilotMode); + } + } } } diff --git a/src/kOS/Binding/FlightControlManager.cs b/src/kOS/Binding/FlightControlManager.cs index 54072c6c7..d3bc080b6 100644 --- a/src/kOS/Binding/FlightControlManager.cs +++ b/src/kOS/Binding/FlightControlManager.cs @@ -157,6 +157,71 @@ private bool VesselIsValid(Vessel vessel) return vessel != null && vessel.rootPart != null; } + public void SelectAutopilotMode(string autopilotMode) + { + VesselAutopilot.AutopilotMode selectedMode; + // determine the AutopilotMode to use + switch (autopilotMode.ToLower()) + { + case "maneuver": + selectedMode = VesselAutopilot.AutopilotMode.Maneuver; + break; + case "prograde": + selectedMode = VesselAutopilot.AutopilotMode.Prograde; + break; + case "retrograde": + selectedMode = VesselAutopilot.AutopilotMode.Retrograde; + break; + case "normal": + selectedMode = VesselAutopilot.AutopilotMode.Normal; + break; + case "antinormal": + selectedMode = VesselAutopilot.AutopilotMode.Antinormal; + break; + case "radialin": + selectedMode = VesselAutopilot.AutopilotMode.RadialIn; + break; + case "radialout": + selectedMode = VesselAutopilot.AutopilotMode.RadialOut; + break; + case "target": + selectedMode = VesselAutopilot.AutopilotMode.Target; + break; + case "antitarget": + selectedMode = VesselAutopilot.AutopilotMode.AntiTarget; + break; + case "stability": + case "stabilityassist": + selectedMode = VesselAutopilot.AutopilotMode.StabilityAssist; + break; + default: + // If the mode is not recognised, thrown an exception rather than continuing or using a default setting + throw new kOS.Safe.Exceptions.KOSException( + string.Format("kOS does not recognize the SAS mode setting of {0}", autopilotMode)); + } + if (!currentVessel.Autopilot.CanSetMode(selectedMode)) + { + throw new kOS.Safe.Exceptions.KOSException( + string.Format("Cannot set autopilot value, pilot/probe does not support {0}, or there is no node/target", autopilotMode)); + } + // turn on sas if it isn't already on + if (!currentVessel.ActionGroups[KSPActionGroup.SAS]) currentVessel.ActionGroups.SetGroup(KSPActionGroup.SAS, true); + currentVessel.Autopilot.SetMode(selectedMode); + currentVessel.Autopilot.Enable(); + // change the autopilot indicator + ((kOS.Module.kOSProcessor)Shared.Processor).SetSASUI((int)selectedMode); + // disable any kOS steering parameters when autopilot is turned on, but only if the mode is not StabilityAssist + if (flightParameters["steering"].Enabled && selectedMode != VesselAutopilot.AutopilotMode.StabilityAssist) + { + ((kOS.Execution.CPU)Shared.Cpu).ToggleFlyByWire("steering", false); + } + if (RemoteTechHook.IsAvailable(currentVessel.id)) + { + Debug.Log(string.Format("kOS: Adding RemoteTechPilot: autopilot For : " + currentVessel.id)); + // TODO: figure out how to make RemoteTech allow the built in autopilot control. This may require modification to RemoteTech itself. + } + } + private class FlightCtrlParam : IDisposable { private readonly string name; diff --git a/src/kOS/Execution/CPU.cs b/src/kOS/Execution/CPU.cs index 52bde84b5..155b327e2 100644 --- a/src/kOS/Execution/CPU.cs +++ b/src/kOS/Execution/CPU.cs @@ -747,6 +747,11 @@ public void ToggleFlyByWire(string paramName, bool enabled) currentContext.ToggleFlyByWire(paramName, enabled); } + public void SelectAutopilotMode(string autopilotMode) + { + shared.BindingMgr.SelectAutopilotMode(autopilotMode); + } + public List GetCodeFragment(int contextLines) { return currentContext.GetCodeFragment(contextLines); diff --git a/src/kOS/Function/Misc.cs b/src/kOS/Function/Misc.cs index 1b24079e1..12093668a 100644 --- a/src/kOS/Function/Misc.cs +++ b/src/kOS/Function/Misc.cs @@ -55,6 +55,19 @@ public override void Execute(SharedObjects shared) } } + [Function("selectautopilotmode")] + public class FunctionSelectAutopilotMode : FunctionBase + { + public override void Execute(SharedObjects shared) + { + string autopilotMode = shared.Cpu.PopValue().ToString(); + ((CPU)shared.Cpu).SelectAutopilotMode(autopilotMode); + // The VisitIdentifierLedExpression method in the Compiler class purposfully throws away the returned value of a function. + ((CPU)shared.Cpu).PushStack(0); + + } + } + [Function("stage")] public class FunctionStage : FunctionBase { From e10e675aa76be5d2c79bb3bc871042d48fd2cc7a Mon Sep 17 00:00:00 2001 From: Chris Woerz Date: Mon, 19 Jan 2015 11:43:10 -0700 Subject: [PATCH 104/446] fixes #515 by looking for remotetech in more places --- src/kOS/AddOns/RemoteTech2/RemoteTechHook.cs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/kOS/AddOns/RemoteTech2/RemoteTechHook.cs b/src/kOS/AddOns/RemoteTech2/RemoteTechHook.cs index 2d5c2b9a2..587393162 100644 --- a/src/kOS/AddOns/RemoteTech2/RemoteTechHook.cs +++ b/src/kOS/AddOns/RemoteTech2/RemoteTechHook.cs @@ -8,6 +8,7 @@ public static class RemoteTechHook { private const String REMOTE_TECH_ASSEMBLY = "RemoteTech"; private const String REMOTE_TECH_API = "RemoteTech.API.API"; + private const String ALT_REMOTE_TECH_API = "RemoteTech.API"; private static bool hookFail; private static IRemoteTechAPIv1 instance; @@ -32,7 +33,7 @@ public static bool IsAvailable(Guid vesselId) return false; } var hasFlightComputer = Instance.HasFlightComputer(vesselId); - return isAvailableBase && hasFlightComputer; + return hasFlightComputer; } catch (Exception) { @@ -48,16 +49,19 @@ public static bool IsAvailable() return false; } var instanceAvailable = Instance != null; - return integrationEnabled && instanceAvailable; + return instanceAvailable; } private static IRemoteTechAPIv1 InitializeAPI() - { + { + Safe.Utilities.Debug.Logger.Log(string.Format("Looking for RemoteTech")); var loadedAssembly = AssemblyLoader.loadedAssemblies.FirstOrDefault(a => a.assembly.GetName().Name.Equals(REMOTE_TECH_ASSEMBLY)); if (loadedAssembly == null) return null; Safe.Utilities.Debug.Logger.Log(string.Format("Found RemoteTech! Version: {0}.{1}", loadedAssembly.versionMajor, loadedAssembly.versionMinor)); - var type = loadedAssembly.assembly.GetTypes().FirstOrDefault(t => t.FullName.Equals(REMOTE_TECH_API)); + var type = loadedAssembly.assembly.GetTypes().FirstOrDefault(t => t.FullName.Equals(REMOTE_TECH_API)) ?? + loadedAssembly.assembly.GetTypes().FirstOrDefault(t => t.FullName.Equals(ALT_REMOTE_TECH_API)); + if (type == null) return null; Safe.Utilities.Debug.Logger.Log(string.Format("Found API! {0} ", type.Name)); From 7e84b035ad7f73dcb866f45f7783bce23415edc8 Mon Sep 17 00:00:00 2001 From: Chris Woerz Date: Mon, 19 Jan 2015 12:17:31 -0700 Subject: [PATCH 105/446] specify that the kosnametag is for kos --- Resources/GameData/kOS/kOS-module-manager.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Resources/GameData/kOS/kOS-module-manager.cfg b/Resources/GameData/kOS/kOS-module-manager.cfg index 6df8edc12..fcb68da63 100644 --- a/Resources/GameData/kOS/kOS-module-manager.cfg +++ b/Resources/GameData/kOS/kOS-module-manager.cfg @@ -1,4 +1,4 @@ -@PART[*] +@PART[*]:FOR[kOS] { MODULE { From d94cfa7b6cca28680a16f8e077b5026265aa74cf Mon Sep 17 00:00:00 2001 From: Chris Woerz Date: Mon, 19 Jan 2015 16:39:56 -0700 Subject: [PATCH 106/446] reving version and MM before release --- Resources/GameData/ModuleManager.2.5.6.dll | Bin 49152 -> 0 bytes Resources/GameData/ModuleManager.2.5.9.dll | Bin 0 -> 50176 bytes Resources/GameData/kOS/kOS.version | 2 +- src/kOS.Safe/Properties/AssemblyInfo.cs | 5 ++--- src/kOS/Core.cs | 2 +- src/kOS/Properties/AssemblyInfo.cs | 5 ++--- 6 files changed, 6 insertions(+), 8 deletions(-) delete mode 100644 Resources/GameData/ModuleManager.2.5.6.dll create mode 100644 Resources/GameData/ModuleManager.2.5.9.dll diff --git a/Resources/GameData/ModuleManager.2.5.6.dll b/Resources/GameData/ModuleManager.2.5.6.dll deleted file mode 100644 index 3642d17acf246475ff599714b1a5aaee94eda9b9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 49152 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 Date: Mon, 19 Jan 2015 17:35:44 -0700 Subject: [PATCH 107/446] also made inequality --- src/kOS.Safe/Encapsulation/Structure.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/kOS.Safe/Encapsulation/Structure.cs b/src/kOS.Safe/Encapsulation/Structure.cs index a1712b05f..014fcc3ee 100644 --- a/src/kOS.Safe/Encapsulation/Structure.cs +++ b/src/kOS.Safe/Encapsulation/Structure.cs @@ -127,6 +127,10 @@ public virtual object TryOperation(string op, object other, bool reverseOrder) { return Equals(other); } + if (op == "<>") + { + return !Equals(other); + } if (op == "+") { return ToString() + other; From c11c5e5e40117618bb0b7c2ebd6dd9eee842484a Mon Sep 17 00:00:00 2001 From: Chris Woerz Date: Mon, 19 Jan 2015 17:48:02 -0700 Subject: [PATCH 108/446] changelog --- CHANGELOG.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 91366eced..094816e8f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,25 @@ kOS Mod Changelog ================= +# v0.15.6 + +### BREAKING +* PART:UID is now a string. This will only break you if you were doing math on UIDs? +* ELEMENT:PARTCOUNT was poorly named and duplicated by ELEMENT:PARTS:LENGTH so it was removed. + +### New Features +* (AGX) Action Groups Extended Support! Thanks @SirDiazo + * Getting or setting groups 11-250 should behave the same as the stock groups if you have AGX installed. + * Groundwork is laid for getting parts and modules by the new action groups. +* Gimbals are now a well known module. providing read access to its state +* Added PART:GETMODULEBYINDEX(int). This is most useful when you have a part with the same module twice. Thanks @jwvanderbeck +* More documentation work. http://ksp-kos.github.io/KOS_DOC/ + +### Bug Fixes +* Fixes RemoteTech Integration +* Structures can now be correctly ==, <> and concatenated with + +* STAGE:RESOURCE[?]:CAPACITY is now spell correctly :P + # v0.15.5 The KSP 0.90 compatibility release. (The full thematic following of KSP 0.90's new way of From 7fa3cfdbdc4f1da600b69a0706a3897c2bb3d8c1 Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Wed, 21 Jan 2015 10:36:36 -0600 Subject: [PATCH 109/446] implement-514. This is the work to make a GUI terminal resizable. --- Resources/GameData/kOS/GFX/font_sml.png | Bin 3908 -> 3399 bytes .../GameData/kOS/GFX/monitor_minimal.png | Bin 107892 -> 104602 bytes src/kOS.Safe/Encapsulation/TerminalStruct.cs | 52 ++++++++ src/kOS.Safe/Screen/ScreenBuffer.cs | 95 ++++++++++++--- src/kOS.Safe/Screen/SubBuffer.cs | 112 ++++++++++++++++-- src/kOS.Safe/Screen/TextEditor.cs | 15 +-- src/kOS.Safe/kOS.Safe.csproj | 1 + src/kOS/Binding/TerminalSettings.cs | 2 + src/kOS/Screen/Interpreter.cs | 3 + src/kOS/Screen/TermWindow.cs | 97 +++++++++++++-- 10 files changed, 331 insertions(+), 46 deletions(-) create mode 100644 src/kOS.Safe/Encapsulation/TerminalStruct.cs diff --git a/Resources/GameData/kOS/GFX/font_sml.png b/Resources/GameData/kOS/GFX/font_sml.png index 5ee42ddae72760438f55174d821caa5f1bc8d137..4d454c8eb4202858097ccd2f27cb0483b316a64c 100644 GIT binary patch delta 3376 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 literal 3908 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 nIHnYGeE diff --git a/Resources/GameData/kOS/GFX/monitor_minimal.png b/Resources/GameData/kOS/GFX/monitor_minimal.png index efe90b9f78a4a968300733ddd4d5d1994de5958d..d8f5cdab7ef0075637fe7fa61008c937b88ae01b 100644 GIT binary patch delta 16996 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 Hu0mjf!}Dnz delta 20312 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 diff --git a/src/kOS.Safe/Encapsulation/TerminalStruct.cs b/src/kOS.Safe/Encapsulation/TerminalStruct.cs new file mode 100644 index 000000000..6cc0b410c --- /dev/null +++ b/src/kOS.Safe/Encapsulation/TerminalStruct.cs @@ -0,0 +1,52 @@ +using System; +using kOS.Safe.Encapsulation.Suffixes; +using kOS.Safe; + +namespace kOS.Safe.Encapsulation +{ + public class TerminalStruct : Structure + { + protected SharedObjects shared; + + // Some sanity values to prevent the terminal display from getting garbled up: + // They may have to change after experimentation. + protected const int MINROWS = 3; + protected const int MAXROWS = 80; + protected const int MINCOLUMNS = 15; + protected const int MAXCOLUMNS = 160; + + // TODO: To implement IsOpen, we'd have to make a kOS.Safe interface wrapper around TermWindow first. + // That's more than I want to do in this update, I'm leaving it as a TODO for me or someone else: + // + // protected bool IsOpen { get { return shared.Window.IsOpen(); } set {if (value) shared.Window.Open(); else shared.Window.Close(); } } + + public TerminalStruct(SharedObjects shared) + { + this.shared = shared; + + InitializeSuffixes(); + } + + private void InitializeSuffixes() + { + // TODO: Uncomment the following if IsOpen gets implemented later: + // AddSuffix("ISOPEN", new SetSuffix(() => IsOpen, Isopen = value, "true=open, false=closed. You can set it to open/close the window.")); + AddSuffix("HEIGHT", new ClampSetSuffix(() => shared.Screen.RowCount, + value => shared.Screen.SetSize(value, shared.Screen.ColumnCount), + MINROWS, + MAXROWS, + "Get or Set the number of rows on the screen. Value is limited to the range ["+MINROWS+","+MAXROWS+"]")); + AddSuffix("WIDTH", new ClampSetSuffix(() => shared.Screen.ColumnCount, + value => shared.Screen.SetSize(shared.Screen.RowCount, value), + MINCOLUMNS, + MAXCOLUMNS, + "Get or Set the number of columns on the screen. Value is limited to the range ["+MINCOLUMNS+","+MAXCOLUMNS+"]")); + } + + public override string ToString() + { + return string.Format("{0} Terminal", base.ToString()); + } + } + +} \ No newline at end of file diff --git a/src/kOS.Safe/Screen/ScreenBuffer.cs b/src/kOS.Safe/Screen/ScreenBuffer.cs index 0021eedce..5f3cdb562 100644 --- a/src/kOS.Safe/Screen/ScreenBuffer.cs +++ b/src/kOS.Safe/Screen/ScreenBuffer.cs @@ -1,4 +1,6 @@ using System.Collections.Generic; +using System; +using System.Text; namespace kOS.Safe.Screen { @@ -20,12 +22,16 @@ public interface IScreenBuffer void AddSubBuffer(SubBuffer subBuffer); void RemoveSubBuffer(SubBuffer subBuffer); List GetBuffer(); + void AddResizeNotifier(ScreenBuffer.ResizeNotifier notifier); + void RemoveResizeNotifier(ScreenBuffer.ResizeNotifier notifier); + string DebugDump(); } + public class ScreenBuffer : IScreenBuffer { - public const int MAX_ROWS = 36; - public const int MAX_COLUMNS = 50; + private const int DEFAULT_ROWS = 36; + private const int DEFAULT_COLUMNS = 50; private int topRow; private readonly List buffer; @@ -38,6 +44,12 @@ public class ScreenBuffer : IScreenBuffer public int RowCount { get; private set; } public int ColumnCount { get; private set; } + /// Delegate prototype expected by AddResizeNotifier + /// This screenbuffer telling the callback who it is + /// telling this screenbuffer how many vertical rows to scroll as a result of the resize. + public delegate int ResizeNotifier(IScreenBuffer sb); + protected List notifyees; + public int AbsoluteCursorRow { get { return CursorRow + topRow; } @@ -48,15 +60,18 @@ public int AbsoluteCursorRow public ScreenBuffer() { buffer = new List(); + notifyees = new List(); + subBuffers = new List(); - RowCount = MAX_ROWS; - ColumnCount = MAX_COLUMNS; + RowCount = DEFAULT_ROWS; + ColumnCount = DEFAULT_COLUMNS; InitializeBuffer(); } private void InitializeBuffer() { + buffer.Clear(); AddNewBufferLines(RowCount); topRow = 0; @@ -70,15 +85,45 @@ protected void AddNewBufferLines( int howMany = 1) buffer.Add(new char[ColumnCount]); } - public void SetSize(int rowCount, int columnCount) + public void AddResizeNotifier(ScreenBuffer.ResizeNotifier notifier) + { + if (notifyees.IndexOf(notifier) < 0) + notifyees.Add(notifier); + } + + public void RemoveResizeNotifier(ScreenBuffer.ResizeNotifier notifier) + { + notifyees.Remove(notifier); + } + + public void SetSize(int rows, int columns) + { + RowCount = rows; + ColumnCount = columns; + ResizeBuffer(); + int scrollDiff = 0; + foreach (ResizeNotifier notifier in notifyees) + { + if (notifier != null) + scrollDiff += notifier(this); + } + ScrollVertical(scrollDiff); + } + + protected void ResizeBuffer() { - if (rowCount <= MAX_ROWS && columnCount <= MAX_COLUMNS) + // Grow or shrink the width of the buffer lines to match the new + // value. Note that this does not (yet) account for preserving lines and wrapping them. + for (int row = 0 ; row < buffer.Count ; ++row) { - RowCount = rowCount; - ColumnCount = columnCount; - buffer.Clear(); - InitializeBuffer(); + char[] newRow = new char[ColumnCount]; + Array.Copy(buffer[row], 0, newRow, 0, Math.Min(buffer[row].Length, ColumnCount)); + buffer[row] = newRow; } + + // Add more buffer lines if needed to pad out the rest of the screen: + while (buffer.Count - topRow < RowCount) + buffer.Add(new char[ColumnCount]); } private int ScrollVerticalInternal(int deltaRows = 1) @@ -212,6 +257,7 @@ public void ClearScreen() public void AddSubBuffer(SubBuffer subBuffer) { subBuffers.Add(subBuffer); + AddResizeNotifier(subBuffer.NotifyOfParentResize); } public void RemoveSubBuffer(SubBuffer subBuffer) @@ -221,17 +267,9 @@ public void RemoveSubBuffer(SubBuffer subBuffer) public List GetBuffer() { - // base buffer var mergedBuffer = new List(buffer.GetRange(topRow, RowCount)); - // The screen may be scrolled such that the bottom of the text content doesn't - // go all the way to the bottom of the screen. If so, pad it for display: - while (mergedBuffer.Count < RowCount) - { - mergedBuffer.Add(new char[ColumnCount]); - } - // merge sub buffers UpdateSubBuffers(); foreach (SubBuffer subBuffer in subBuffers) @@ -258,6 +296,27 @@ public List GetBuffer() return mergedBuffer; } + // This was handy when trying to figure out what was going on. + public string DebugDump() + { + StringBuilder sb = new StringBuilder(); + sb.Append("DebugDump ScreenBuffer: RowCount="+RowCount+", ColumnCount="+ColumnCount+", topRow="+topRow+", buffer.count="+buffer.Count+"\n"); + for (int i = 0; i < buffer.Count ; ++i) + { + sb.Append(" line "+i+" = ["); + for (int j = 0 ; j < buffer[i].Length ; ++j) + { + char ch = buffer[i][j]; + sb.Append((int)ch < 32 ? (" \\"+(int)ch) : (" "+ch) ); + } + sb.Append("]\n"); + } + foreach (SubBuffer sub in subBuffers) + sb.Append(sub.DebugDump()); + return sb.ToString(); + } + + protected virtual void UpdateSubBuffers() { // so subclasses can do something with their subbuffers before they are merged diff --git a/src/kOS.Safe/Screen/SubBuffer.cs b/src/kOS.Safe/Screen/SubBuffer.cs index 2ab228919..30fb63865 100644 --- a/src/kOS.Safe/Screen/SubBuffer.cs +++ b/src/kOS.Safe/Screen/SubBuffer.cs @@ -1,4 +1,6 @@ using System.Collections.Generic; +using System; +using System.Text; namespace kOS.Safe.Screen { @@ -13,24 +15,116 @@ public class SubBuffer public int PositionColumn { get; set; } public bool Enabled { get; set; } + /// + /// Stretch/shrink the subbuffer to a new size, trying as best as possible to + /// preserve existing contents. Note that if the new size is too small to hold + /// the contents, then it WILL refuse to make it that small, and will add rows to your + /// intended size as needed to preserve contents. + ///

+ /// Example: contents are "xxxxxxxxxx\nxxxxx" and you try to make it size 1,5. You'll + /// end up with it being size 3,5 instead so it could store all 15 characters in it. + ///
+ /// Desired new number of rows (this may end up larger than you requested if necessary to hold contents) + /// Desired new number of columns (this will be adhered to faithfully). public void SetSize(int rowCount, int columnCount) { - if (rowCount <= ScreenBuffer.MAX_ROWS && columnCount <= ScreenBuffer.MAX_COLUMNS) - { - RowCount = rowCount; - ColumnCount = columnCount; - InitializeBuffer(); - } + RowCount = rowCount; + ColumnCount = columnCount; + ResizeBuffer(); + } + + /// Clear the contents entirely and set the size to 0,ColumnCount. + public void Wipe() + { + Buffer.Clear(); + RowCount = 0; + } + + /// + /// The default behavior is to resize the subbuffer's width to match the parent + /// screenbuffer's width, but to leave the height alone as-is. All the subbuffers + /// in kOS as of this writing need that behavior (they're used to edit the command line). + /// The way is being left open for other subclasses of subbuffer to override this + /// method later. (i.e. you might want a subbuffer of fixed size that won't change + /// when the parent resizes. If we start using subbuffers to enable curses-like + /// overlay zones in script displays we'd want that.) + /// + /// the parent screen buffer that is being resized + /// number of lines the parent should probably be shifted down because the subbuffer is now more lines. + public virtual int NotifyOfParentResize(IScreenBuffer sb) + { + ColumnCount = sb.ColumnCount; + return ResizeBuffer(); } - private void InitializeBuffer() + protected virtual int ResizeBuffer() { + // This method also is being left open for potential overriding in subclasses + // if we want subbuffers that don't behave this way. The reason is that + // this behavior is very specific to implementing a command line editor, and + // the assumption that the entire subbuffer was meant to 'flow' and wrap as one long line. + // That assumption may be very different for other cases, if any exist in the future. + + List newBuffer = new List(); + + int newRow = 0; + int oldRow = 0; + int newCol = 0; + + // First, copy everything from old to new, and perhaps enlarge the new if the old won't fit. + while (oldRow < Buffer.Count) + { + int oldCol = 0; + while (oldCol < Buffer[oldRow].Length) + { + if (newCol >= ColumnCount) // wrap to new line when cur line is full. + { + ++newRow; + newCol = 0; + } + if (newRow >= newBuffer.Count) // grow to required size. + newBuffer.Add(new char[ColumnCount]); + newBuffer[newRow][newCol] = Buffer[oldRow][oldCol]; + ++newCol; + ++oldCol; + } + ++oldRow; + } + + // Then maybe append more empty rows if the above wasn't enough to fill the new size: + while (newBuffer.Count < RowCount) + newBuffer.Add(new char[ColumnCount]); + + // Reset the subbuffer row size since the new size might have had to grow (i.e. shrinking the width of a 80 col to 60 col so wrap text added a row.) + // int scrollDiff = (newBuffer.Count - RowCount); - this logic not quite working - disabled for now. + + RowCount = newBuffer.Count; + + // Because Buffer is readonly, copy the data from newBuffer into it rather than just resetting the reference to newBuffer: Buffer.Clear(); + for (int i = 0 ; i < newBuffer.Count ; ++i) + Buffer.Add(newBuffer[i]); - for (int row = 0; row < RowCount; row++) + // return Fixed ? 0 : scrollDiff; - this logic not quite working - disabled for now. + return 0; + } + + public string DebugDump() + { + StringBuilder sb = new StringBuilder(); + sb.Append("DebugDump Subbuffer: Fixed="+Fixed+", Enabled="+Enabled+", RowCount="+RowCount+ + ", ColumnCount=" + ColumnCount + ", PositionRow="+PositionRow + ", PositionCol="+PositionColumn+"\n"); + for (int i = 0; i < Buffer.Count ; ++i) { - Buffer.Add(new char[ColumnCount]); + sb.Append(" line "+i+" = ["); + for (int j = 0 ; j < Buffer[i].Length ; ++j) + { + char ch = Buffer[i][j]; + sb.Append((int)ch < 32 ? (" \\"+(int)ch) : (" "+ch) ); + } + sb.Append("]\n"); } + return sb.ToString(); } } } diff --git a/src/kOS.Safe/Screen/TextEditor.cs b/src/kOS.Safe/Screen/TextEditor.cs index dea7d1bcb..e4793e500 100644 --- a/src/kOS.Safe/Screen/TextEditor.cs +++ b/src/kOS.Safe/Screen/TextEditor.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using System.Text; using kOS.Safe.Utilities; +using System; namespace kOS.Safe.Screen { @@ -128,7 +129,7 @@ protected void UpdateLineSubBuffer() { string commandText = LineBuilder.ToString(); List lines = SplitIntoLinesPreserveNewLine(commandText); - + if (lines.Count != LineSubBuffer.RowCount) LineSubBuffer.SetSize(lines.Count, LineSubBuffer.ColumnCount); @@ -159,7 +160,7 @@ private void UpdateSubBufferCursor(List lines) lineCursorIndex -= lines[lineIndex].Length; // if the line is shorter than the width of the screen then move // the cursor another position to compensate for the newline character - if (lines[lineIndex].Length < MAX_COLUMNS) + if (lines[lineIndex].Length < ColumnCount) lineCursorIndex--; lineIndex++; } @@ -174,15 +175,15 @@ protected void KeepCursorInBounds() { // Check to see if wrapping or scrolling needs to be done // because the cursor went off the screen, and if so, do it: - if (CursorColumnShow >= MAX_COLUMNS) + if (CursorColumnShow >= ColumnCount) { int tooBigColumn = CursorColumnShow; - cursorColumnBuffer = (tooBigColumn % MAX_COLUMNS); - cursorRowBuffer += (tooBigColumn / MAX_COLUMNS); // truncating integer division. + cursorColumnBuffer = (tooBigColumn % ColumnCount); + cursorRowBuffer += (tooBigColumn / ColumnCount); // truncating integer division. } - if (CursorRowShow >= MAX_ROWS) + if (CursorRowShow >= RowCount) { - int rowsToScroll = (CursorRowShow-MAX_ROWS) + 1; + int rowsToScroll = (CursorRowShow-RowCount) + 1; CursorRow -= rowsToScroll; ScrollVertical(rowsToScroll); AddNewBufferLines(rowsToScroll); diff --git a/src/kOS.Safe/kOS.Safe.csproj b/src/kOS.Safe/kOS.Safe.csproj index 6973a2350..dbc5c5da3 100644 --- a/src/kOS.Safe/kOS.Safe.csproj +++ b/src/kOS.Safe/kOS.Safe.csproj @@ -87,6 +87,7 @@ + diff --git a/src/kOS/Binding/TerminalSettings.cs b/src/kOS/Binding/TerminalSettings.cs index e30854edf..487c6c9cf 100644 --- a/src/kOS/Binding/TerminalSettings.cs +++ b/src/kOS/Binding/TerminalSettings.cs @@ -1,4 +1,5 @@ using kOS.Safe.Binding; +using kOS.Safe.Encapsulation; namespace kOS.Binding { @@ -10,6 +11,7 @@ public override void AddTo(SharedObjects shared) shared.BindingMgr.AddGetter("SESSIONTIME", () => shared.Cpu.SessionTime); shared.BindingMgr.AddGetter("VERSION", () => Core.VersionInfo); shared.BindingMgr.AddGetter("VOLUME:NAME", () => shared.VolumeMgr.CurrentVolume.Name); + shared.BindingMgr.AddGetter("TERMINAL", () => new TerminalStruct(shared)); } } } \ No newline at end of file diff --git a/src/kOS/Screen/Interpreter.cs b/src/kOS/Screen/Interpreter.cs index b94327d51..0b099b6e5 100644 --- a/src/kOS/Screen/Interpreter.cs +++ b/src/kOS/Screen/Interpreter.cs @@ -32,6 +32,9 @@ protected override void NewLine() // the command is present in the history to be found and printed in the // error message. ProcessCommand(commandText); + int numRows = LineSubBuffer.RowCount; + LineSubBuffer.Wipe(); + LineSubBuffer.SetSize(numRows,ColumnCount); // refill it to its previous size } else { diff --git a/src/kOS/Screen/TermWindow.cs b/src/kOS/Screen/TermWindow.cs index 9df1dd855..0a32a732f 100644 --- a/src/kOS/Screen/TermWindow.cs +++ b/src/kOS/Screen/TermWindow.cs @@ -6,6 +6,7 @@ using kOS.Safe.Screen; using kOS.Safe.Utilities; using kOS.Module; +using kOS.Safe.Encapsulation; namespace kOS.Screen { @@ -14,7 +15,8 @@ public class TermWindow : KOSManagedWindow { private const int CHARSIZE = 8; private const string CONTROL_LOCKOUT = "kOSTerminal"; - private const int CHARS_PER_ROW = 16; + private const int FONTIMAGE_CHARS_PER_ROW = 16; + private static readonly string root = KSPUtil.ApplicationRootPath.Replace("\\", "/"); private static readonly Color color = new Color(1, 1, 1, 1); private static readonly Color colorAlpha = new Color(0.9f, 0.9f, 0.9f, 0.6f); @@ -22,8 +24,10 @@ public class TermWindow : KOSManagedWindow private static readonly Color textColorAlpha = new Color(0.45f, 0.92f, 0.23f, 0.5f); private static readonly Color textColorOff = new Color(0.8f, 0.8f, 0.8f, 0.7f); private static readonly Color textColorOffAlpha = new Color(0.8f, 0.8f, 0.8f, 0.3f); - private static readonly Rect closeButtonRect = new Rect(398, 370, 59, 30); - + private Rect closeButtonRect = new Rect(0, 0, 0, 0); // will be resized later. + private Rect resizeButtonCoords = new Rect(0,0,0,0); // will be resized later. + private Vector2 resizeOldSize; + private bool resizeMouseDown; private bool consumeEvent; @@ -36,6 +40,7 @@ public class TermWindow : KOSManagedWindow private Texture2D fontImage = new Texture2D(0, 0, TextureFormat.DXT1, false); private bool isLocked; private Texture2D terminalImage = new Texture2D(0, 0, TextureFormat.DXT1, false); + private Texture2D resizeButtonImage = new Texture2D(0, 0, TextureFormat.DXT1, false); private SharedObjects shared; private bool showCursor = true; @@ -47,13 +52,14 @@ public class TermWindow : KOSManagedWindow public TermWindow() { IsPowered = true; - windowRect = new Rect(60, 50, 470, 405); + windowRect = new Rect(50, 60, 0, 0); // will get resized later in AttachTo(). } public void Awake() { LoadTexture("GameData/kOS/GFX/font_sml.png", ref fontImage); LoadTexture("GameData/kOS/GFX/monitor_minimal.png", ref terminalImage); + LoadTexture("GameData/kOS/GFX/resize-button.png", ref resizeButtonImage); var gObj = new GameObject( "texteditPopup", typeof(KOSTextEditPopup) ); DontDestroyOnLoad(gObj); popupEditor = (KOSTextEditPopup)gObj.GetComponent(typeof(KOSTextEditPopup)); @@ -179,12 +185,13 @@ void OnGUI() ); windowRect = GUI.Window(uniqueId, windowRect, TerminalGui, labelText); - + if (consumeEvent) { consumeEvent = false; Event.current.Use(); } + } void Update() @@ -318,9 +325,25 @@ void TerminalGui(int windowId) { return; } + IScreenBuffer screen = shared.Screen; GUI.color = isLocked ? color : colorAlpha; - GUI.DrawTexture(new Rect(10, 20, terminalImage.width, terminalImage.height), terminalImage); + GUI.DrawTexture(new Rect(15, 20, windowRect.width-30, windowRect.height-55), terminalImage); + closeButtonRect = new Rect(windowRect.width-75, windowRect.height-30, 50, 25); + + resizeButtonCoords = new Rect(windowRect.width-resizeButtonImage.width, + windowRect.height-resizeButtonImage.height, + resizeButtonImage.width, + resizeButtonImage.height); + if (GUI.RepeatButton(resizeButtonCoords, resizeButtonImage )) + { + if (! resizeMouseDown) + { + // Remember the fact that this mouseDown started on the resize button: + resizeMouseDown = true; + resizeOldSize = new Vector2(windowRect.width, windowRect.height); + } + } if (GUI.Button(closeButtonRect, "Close")) { @@ -328,7 +351,6 @@ void TerminalGui(int windowId) Event.current.Use(); } - GUI.DragWindow(new Rect(0, 0, 10000, 500)); Color currentTextColor; if (IsPowered) @@ -340,9 +362,8 @@ void TerminalGui(int windowId) currentTextColor = isLocked ? textColorOff : textColorOffAlpha; } - GUI.BeginGroup(new Rect(31, 38, 420, 340)); + GUI.BeginGroup(new Rect(28, 38, screen.ColumnCount*CHARSIZE, screen.RowCount*CHARSIZE)); - IScreenBuffer screen = shared.Screen; List buffer = screen.GetBuffer(); for (int row = 0; row < screen.RowCount; row++) @@ -364,13 +385,47 @@ void TerminalGui(int windowId) ShowCharacterByAscii((char)1, screen.CursorColumnShow, screen.CursorRowShow, currentTextColor); } GUI.EndGroup(); + + GUI.Label(new Rect(windowRect.width/2-40,windowRect.height-20,100,10),screen.ColumnCount+"x"+screen.RowCount); + CheckResizeDrag(); // Has to occur before DragWindow or else DragWindow will consume the event and prevent drags from being seen by the resize icon. + GUI.DragWindow(); } - + + protected void CheckResizeDrag() + { + if (Input.GetMouseButton(0)) // mouse button is down + { + if (resizeMouseDown) // and it's in the midst of a drag. + { + Vector2 dragDelta = mousePosAbsolute - mouseButtonDownPosAbsolute; + windowRect = new Rect(windowRect.xMin, + windowRect.yMin, + System.Math.Max(resizeOldSize.x + dragDelta.x, 200), + System.Math.Max(resizeOldSize.y + dragDelta.y, 200)); + } + } + else // mouse button is up + { + if (resizeMouseDown) // and it had been dragging a resize before. + { + resizeMouseDown = false; + // Resize by integer character cells, not by actual x/y pixels: + // Note I wanted to call this dynamically as it's resizing, but there's some weird issue + // with the timing of it, where the windowRect is temporarily set to a bogus value during the + // time it was trying to run this, and thus it created exception-throwing code unless it waits + // until the drag is done before trying to calculate this. + // The effect the user sees is that the text can float in space past the edge of the window (when + // shrinking the size) until the resize drag is done, and then it redraws itself. + shared.Screen.SetSize(HowManyRowsFit(), HowManyColumnsFit()); + } + } + } + void ShowCharacterByAscii(char ch, int x, int y, Color textColor) { - int tx = ch % CHARS_PER_ROW; - int ty = ch / CHARS_PER_ROW; + int tx = ch % FONTIMAGE_CHARS_PER_ROW; + int ty = ch / FONTIMAGE_CHARS_PER_ROW; ShowCharacterByXY(x, y, tx, ty, textColor); } @@ -397,6 +452,24 @@ internal void AttachTo(SharedObjects shared) { this.shared = shared; this.shared.Window = this; + NotifyOfScreenResize(this.shared.Screen); + this.shared.Screen.AddResizeNotifier(NotifyOfScreenResize); + } + + internal int NotifyOfScreenResize(IScreenBuffer sb) + { + windowRect = new Rect(windowRect.xMin, windowRect.yMin, sb.ColumnCount*CHARSIZE + 65, sb.RowCount*CHARSIZE + 100); + return 0; + } + + private int HowManyRowsFit() + { + return (int)(windowRect.height - 100) / CHARSIZE; + } + + private int HowManyColumnsFit() + { + return (int)(windowRect.width - 65) / CHARSIZE; } public void SetPowered(bool isPowered) From ec7b63e564892597aa76b8c4b16548ed7b1c6ddb Mon Sep 17 00:00:00 2001 From: hvacengi Date: Thu, 22 Jan 2015 00:41:54 -0500 Subject: [PATCH 110/446] Add support for "set autopilot to" FlightControlManager.cs - Added setter and getter for the bound variable "autopilot". This allows the syntax of "set autopilot to [value]" and "set value to autopilot". Modified the SelectAutopilotMode method to support a null or empty string to clear reset the mode back to stability assist without forcing SAS to on. --- src/kOS/Binding/FlightControlManager.cs | 121 ++++++++++++++---------- 1 file changed, 70 insertions(+), 51 deletions(-) diff --git a/src/kOS/Binding/FlightControlManager.cs b/src/kOS/Binding/FlightControlManager.cs index d3bc080b6..e99a94895 100644 --- a/src/kOS/Binding/FlightControlManager.cs +++ b/src/kOS/Binding/FlightControlManager.cs @@ -41,6 +41,9 @@ public override void AddTo(SharedObjects shared) AddNewFlightParam("steering", Shared); AddNewFlightParam("wheelthrottle", Shared); AddNewFlightParam("wheelsteering", Shared); + + shared.BindingMgr.AddSetter("AUTOPILOT", value => this.SelectAutopilotMode((string)value)); + shared.BindingMgr.AddGetter("AUTOPILOT", () => currentVessel.Autopilot.Mode.ToString().ToUpper()); } @@ -160,60 +163,76 @@ private bool VesselIsValid(Vessel vessel) public void SelectAutopilotMode(string autopilotMode) { VesselAutopilot.AutopilotMode selectedMode; - // determine the AutopilotMode to use - switch (autopilotMode.ToLower()) - { - case "maneuver": - selectedMode = VesselAutopilot.AutopilotMode.Maneuver; - break; - case "prograde": - selectedMode = VesselAutopilot.AutopilotMode.Prograde; - break; - case "retrograde": - selectedMode = VesselAutopilot.AutopilotMode.Retrograde; - break; - case "normal": - selectedMode = VesselAutopilot.AutopilotMode.Normal; - break; - case "antinormal": - selectedMode = VesselAutopilot.AutopilotMode.Antinormal; - break; - case "radialin": - selectedMode = VesselAutopilot.AutopilotMode.RadialIn; - break; - case "radialout": - selectedMode = VesselAutopilot.AutopilotMode.RadialOut; - break; - case "target": - selectedMode = VesselAutopilot.AutopilotMode.Target; - break; - case "antitarget": - selectedMode = VesselAutopilot.AutopilotMode.AntiTarget; - break; - case "stability": - case "stabilityassist": - selectedMode = VesselAutopilot.AutopilotMode.StabilityAssist; - break; - default: - // If the mode is not recognised, thrown an exception rather than continuing or using a default setting - throw new kOS.Safe.Exceptions.KOSException( - string.Format("kOS does not recognize the SAS mode setting of {0}", autopilotMode)); - } - if (!currentVessel.Autopilot.CanSetMode(selectedMode)) + // handle a null/empty value in case of an unset command or setting to empty string to clear. + if (string.IsNullOrEmpty(autopilotMode)) { - throw new kOS.Safe.Exceptions.KOSException( - string.Format("Cannot set autopilot value, pilot/probe does not support {0}, or there is no node/target", autopilotMode)); + selectedMode = VesselAutopilot.AutopilotMode.StabilityAssist; + // set the autopilot mode if allowed + if (currentVessel.Autopilot.CanSetMode(selectedMode)) + { + currentVessel.Autopilot.SetMode(selectedMode); + // change the autopilot indicator + ((kOS.Module.kOSProcessor)Shared.Processor).SetSASUI((int)selectedMode); + } } - // turn on sas if it isn't already on - if (!currentVessel.ActionGroups[KSPActionGroup.SAS]) currentVessel.ActionGroups.SetGroup(KSPActionGroup.SAS, true); - currentVessel.Autopilot.SetMode(selectedMode); - currentVessel.Autopilot.Enable(); - // change the autopilot indicator - ((kOS.Module.kOSProcessor)Shared.Processor).SetSASUI((int)selectedMode); - // disable any kOS steering parameters when autopilot is turned on, but only if the mode is not StabilityAssist - if (flightParameters["steering"].Enabled && selectedMode != VesselAutopilot.AutopilotMode.StabilityAssist) + else { - ((kOS.Execution.CPU)Shared.Cpu).ToggleFlyByWire("steering", false); + // determine the AutopilotMode to use + switch (autopilotMode.ToLower()) + { + case "maneuver": + selectedMode = VesselAutopilot.AutopilotMode.Maneuver; + break; + case "prograde": + selectedMode = VesselAutopilot.AutopilotMode.Prograde; + break; + case "retrograde": + selectedMode = VesselAutopilot.AutopilotMode.Retrograde; + break; + case "normal": + selectedMode = VesselAutopilot.AutopilotMode.Normal; + break; + case "antinormal": + selectedMode = VesselAutopilot.AutopilotMode.Antinormal; + break; + case "radialin": + selectedMode = VesselAutopilot.AutopilotMode.RadialIn; + break; + case "radialout": + selectedMode = VesselAutopilot.AutopilotMode.RadialOut; + break; + case "target": + selectedMode = VesselAutopilot.AutopilotMode.Target; + break; + case "antitarget": + selectedMode = VesselAutopilot.AutopilotMode.AntiTarget; + break; + case "stability": + case "stabilityassist": + selectedMode = VesselAutopilot.AutopilotMode.StabilityAssist; + break; + default: + // If the mode is not recognised, thrown an exception rather than continuing or using a default setting + throw new kOS.Safe.Exceptions.KOSException( + string.Format("kOS does not recognize the SAS mode setting of {0}", autopilotMode)); + } + if (!currentVessel.Autopilot.CanSetMode(selectedMode)) + { + // throw an exception if the mode is not available + throw new kOS.Safe.Exceptions.KOSException( + string.Format("Cannot set autopilot value, pilot/probe does not support {0}, or there is no node/target", autopilotMode)); + } + // turn on sas if it isn't already on + if (!currentVessel.ActionGroups[KSPActionGroup.SAS]) currentVessel.ActionGroups.SetGroup(KSPActionGroup.SAS, true); + currentVessel.Autopilot.SetMode(selectedMode); + currentVessel.Autopilot.Enable(); + // change the autopilot indicator + ((kOS.Module.kOSProcessor)Shared.Processor).SetSASUI((int)selectedMode); + // disable any kOS steering parameters when autopilot is turned on, but only if the mode is not StabilityAssist + if (flightParameters["steering"].Enabled && selectedMode != VesselAutopilot.AutopilotMode.StabilityAssist) + { + ((kOS.Execution.CPU)Shared.Cpu).ToggleFlyByWire("steering", false); + } } if (RemoteTechHook.IsAvailable(currentVessel.id)) { From 9d72f643c81d38795cf66af16e241b330733629b Mon Sep 17 00:00:00 2001 From: Andreas Grois Date: Sun, 25 Jan 2015 17:04:38 +0100 Subject: [PATCH 111/446] Fix for issue #389 - LOCK STEERING broken for RCS-only (no torque) ships. The RCS parts seem to require accessing their individual PartModule members. Also: Approximated torque caused by RCS modules better than before (but still not correct). --- src/kOS/Utilities/SteeringHelper.cs | 30 ++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/src/kOS/Utilities/SteeringHelper.cs b/src/kOS/Utilities/SteeringHelper.cs index 774a9b2b8..4b4f72f54 100644 --- a/src/kOS/Utilities/SteeringHelper.cs +++ b/src/kOS/Utilities/SteeringHelper.cs @@ -151,9 +151,11 @@ public static Vector3d GetEffectiveInertia(Vessel vessel, Vector3d torque) public static Vector3d GetTorque(Vessel vessel, float thrust) { var centerOfMass = vessel.findWorldCenterOfMass(); + var rollaxis = vessel.transform.up; + rollaxis.Normalize (); - float pitchYaw = 0; - float roll = 0; + float pitchYaw = 0.0f; + float roll = 0.0f; foreach (Part part in vessel.parts) { @@ -165,15 +167,17 @@ public static Vector3d GetTorque(Vessel vessel, float thrust) pitchYaw += Math.Abs(pod.rotPower); roll += Math.Abs(pod.rotPower); } - + /* + //This is probably useless - commented out. var rcsModule = part as RCSModule; if (rcsModule != null) { float max = rcsModule.thrusterPowers.Aggregate(0, Mathf.Max); - pitchYaw += max * relCoM.magnitude; + roll += max * (Vector3.Cross(relCoM, rollaxis)).magnitude; + pitchYaw += max * Vector3.Dot(relCoM, rollaxis); } - + */ foreach (PartModule module in part.Modules) { var wheel = module as ModuleReactionWheel; @@ -182,6 +186,22 @@ public static Vector3d GetTorque(Vessel vessel, float thrust) pitchYaw += wheel.PitchTorque; roll += wheel.RollTorque; } + int numrcs = 0; + float max = 0.0f; + foreach (PartModule module in part.Modules) { + var rcs = module as ModuleRCS; + if (rcs == null) continue; + + max = Mathf.Max(max, rcs.thrusterPower); + numrcs++; + } + if (numrcs > 0) { + max = max/numrcs; + //This is a rough approximation - assuming full pivoting of the RCS. + //To fix this, this whole function would need to be rewritten. + roll += max * (Vector3.Cross (relCoM, rollaxis)).magnitude; + pitchYaw += max * Vector3.Dot (relCoM, rollaxis); + } pitchYaw += (float)GetThrustTorque(part, vessel) * thrust; } From d8aed05a78745ae0675f89d4e99a3004c874c2c9 Mon Sep 17 00:00:00 2001 From: Andreas Grois Date: Sun, 25 Jan 2015 21:13:03 +0100 Subject: [PATCH 112/446] Fix for issue #389 - followup Now properly uses the absolute value of the pitch/yaw torque. Added checks for disabled RCS ports and availability of RCS fuel(s). --- src/kOS/Utilities/SteeringHelper.cs | 48 +++++++++++++++++++---------- 1 file changed, 32 insertions(+), 16 deletions(-) diff --git a/src/kOS/Utilities/SteeringHelper.cs b/src/kOS/Utilities/SteeringHelper.cs index 4b4f72f54..6e419c715 100644 --- a/src/kOS/Utilities/SteeringHelper.cs +++ b/src/kOS/Utilities/SteeringHelper.cs @@ -186,23 +186,39 @@ public static Vector3d GetTorque(Vessel vessel, float thrust) pitchYaw += wheel.PitchTorque; roll += wheel.RollTorque; } - int numrcs = 0; - float max = 0.0f; - foreach (PartModule module in part.Modules) { - var rcs = module as ModuleRCS; - if (rcs == null) continue; - - max = Mathf.Max(max, rcs.thrusterPower); - numrcs++; - } - if (numrcs > 0) { - max = max/numrcs; - //This is a rough approximation - assuming full pivoting of the RCS. - //To fix this, this whole function would need to be rewritten. - roll += max * (Vector3.Cross (relCoM, rollaxis)).magnitude; - pitchYaw += max * Vector3.Dot (relCoM, rollaxis); + if (vessel.ActionGroups [KSPActionGroup.RCS]) + { + int numrcs = 0; + float max = 0.0f; + foreach (PartModule module in part.Modules) { + var rcs = module as ModuleRCS; + if (rcs == null) continue; + + if (rcs.rcsEnabled == true) + { + int enoughfuel = 1; + foreach (Propellant p in rcs.propellants) + { + if ((int)(p.totalResourceAvailable)==0) + { + enoughfuel = 0; + } + } + if (enoughfuel == 1) + { + max = Mathf.Max(max, rcs.thrusterPower); + numrcs++; + } + } + } + if (numrcs > 0) { + max = max/numrcs; + //This is a rough approximation - assuming full pivoting of the RCS. + //To fix this, this whole function would need to be rewritten. + roll += max * (Vector3.Cross (relCoM, rollaxis)).magnitude; + pitchYaw += max * Mathf.Abs(Vector3.Dot (relCoM, rollaxis)); + } } - pitchYaw += (float)GetThrustTorque(part, vessel) * thrust; } From 05cf4ea1cd7ff263e0729ca3ca14f424ea42c83e Mon Sep 17 00:00:00 2001 From: Andreas Grois Date: Mon, 26 Jan 2015 00:23:49 +0100 Subject: [PATCH 113/446] Issue #389 - followup: Calculate correct torque from RCS. With a little inspiration from the RCS Build Aid source code, the calculated torque from RCS now is equal to the values displayed by MechJeb. --- src/kOS/Utilities/SteeringHelper.cs | 41 ++++++++++++++++------------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/src/kOS/Utilities/SteeringHelper.cs b/src/kOS/Utilities/SteeringHelper.cs index 6e419c715..114db194f 100644 --- a/src/kOS/Utilities/SteeringHelper.cs +++ b/src/kOS/Utilities/SteeringHelper.cs @@ -153,8 +153,11 @@ public static Vector3d GetTorque(Vessel vessel, float thrust) var centerOfMass = vessel.findWorldCenterOfMass(); var rollaxis = vessel.transform.up; rollaxis.Normalize (); + var pitchaxis = vessel.GetFwdVector (); + pitchaxis.Normalize (); - float pitchYaw = 0.0f; + float pitch = 0.0f; + float yaw = 0.0f; float roll = 0.0f; foreach (Part part in vessel.parts) @@ -164,7 +167,8 @@ public static Vector3d GetTorque(Vessel vessel, float thrust) var pod = part as CommandPod; if (pod != null) { - pitchYaw += Math.Abs(pod.rotPower); + pitch += Math.Abs(pod.rotPower); + yaw += Math.Abs(pod.rotPower); roll += Math.Abs(pod.rotPower); } /* @@ -183,46 +187,45 @@ public static Vector3d GetTorque(Vessel vessel, float thrust) var wheel = module as ModuleReactionWheel; if (wheel == null) continue; - pitchYaw += wheel.PitchTorque; + pitch += wheel.PitchTorque; + yaw += wheel.YawTorque; roll += wheel.RollTorque; } if (vessel.ActionGroups [KSPActionGroup.RCS]) { - int numrcs = 0; - float max = 0.0f; foreach (PartModule module in part.Modules) { var rcs = module as ModuleRCS; if (rcs == null) continue; if (rcs.rcsEnabled == true) { - int enoughfuel = 1; + bool enoughfuel = true; foreach (Propellant p in rcs.propellants) { if ((int)(p.totalResourceAvailable)==0) { - enoughfuel = 0; + enoughfuel = false; } } - if (enoughfuel == 1) + if (enoughfuel == true) { - max = Mathf.Max(max, rcs.thrusterPower); - numrcs++; + foreach (Transform thrustdir in rcs.thrusterTransforms) + { + float rcsthrust = rcs.thrusterPower; + //just counting positive contributions in one direction. This is incorrect for asymmetric thruster placements. + roll += Mathf.Max(rcsthrust * Vector3.Dot(Vector3.Cross(relCoM, thrustdir.up), rollaxis), 0.0f); + pitch += Mathf.Max(rcsthrust * Vector3.Dot(Vector3.Cross(Vector3.Cross(relCoM, thrustdir.up), rollaxis), pitchaxis), 0.0f); + yaw += Mathf.Max(rcsthrust * Vector3.Dot(Vector3.Cross(Vector3.Cross(relCoM, thrustdir.up), rollaxis), Vector3.Cross(rollaxis,pitchaxis)),0.0f); + } } } } - if (numrcs > 0) { - max = max/numrcs; - //This is a rough approximation - assuming full pivoting of the RCS. - //To fix this, this whole function would need to be rewritten. - roll += max * (Vector3.Cross (relCoM, rollaxis)).magnitude; - pitchYaw += max * Mathf.Abs(Vector3.Dot (relCoM, rollaxis)); - } } - pitchYaw += (float)GetThrustTorque(part, vessel) * thrust; + pitch += (float)GetThrustTorque(part, vessel) * thrust; + yaw += (float)GetThrustTorque (part, vessel) * thrust; } - return new Vector3d(pitchYaw, roll, pitchYaw); + return new Vector3d(pitch, roll, yaw); } public static double GetThrustTorque(Part p, Vessel vessel) From b89c53b4e85cecd04440b6002d898d4a8147d0c8 Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Wed, 28 Jan 2015 12:13:44 -0600 Subject: [PATCH 114/446] Fixes #523 and Fixes #524 Making waypoints a bit better. --- doc/source/structures/waypoint.rst | 27 +++++++ src/kOS/Function/Suffixed.cs | 12 ++- src/kOS/Suffixed/WaypointValue.cs | 121 ++++++++++++++++++++++++----- 3 files changed, 136 insertions(+), 24 deletions(-) diff --git a/doc/source/structures/waypoint.rst b/doc/source/structures/waypoint.rst index ba5250e71..12bc0e81a 100644 --- a/doc/source/structures/waypoint.rst +++ b/doc/source/structures/waypoint.rst @@ -41,6 +41,8 @@ Waypoints are the location markers you can see on the map view showing you where - `BodyTarget` * - :attr:`GEOPOSITION` - `GeoCoordinates` + * - :attr:`POSITION` + - `Vector` * - :attr:`ALTITUDE` - scalar * - :attr:`AGL` @@ -49,6 +51,10 @@ Waypoints are the location markers you can see on the map view showing you where - boolean * - :attr:`GROUNDED` - boolean + * - :attr:`INDEX` + - scalar + * - :attr:`CLUSTERED` + - boolean .. attribute:: Waypoint:NAME @@ -73,6 +79,13 @@ Waypoints are the location markers you can see on the map view showing you where The LATLNG of this waypoint +.. attribute:: Waypoint:POSITION + + :type: Vector + :access: Get only + + The Vector position of this waypoint in 3D space, in ship-raw coords. + .. attribute:: Waypoint:ALTITUDE :type: scalar @@ -104,3 +117,17 @@ Waypoints are the location markers you can see on the map view showing you where True if waypoint is actually glued to the ground. +.. attribute:: Waypoint:INDEX + + :type: scalar + :access: Get only + + The integer index of this waypoint amongst its cluster of sibling waypoints. In other words, when you have a cluster of waypoints called "Somewhere Alpha", "Somewhere Beta", and "Somewhere Gamma", then the alpha site has index 0, the beta site has index 1 and the gamma site has index 2. When Waypoint:CLUSTERED is false, this value is zero but meaningless. + +.. attribute:: Waypoint:CLUSTERED + + :type: boolean + :access: Get only + + True if this waypoint is part of a set of clustered waypoints with greek letter names appended (Alpha, Beta, Gamma, etc). If true, there should be a one-to-one correspondence with the greek letter name and the :INDEX suffix. (0 = Alpha, 1 = Beta, 2 = Gamma, etc). + diff --git a/src/kOS/Function/Suffixed.cs b/src/kOS/Function/Suffixed.cs index bd050a979..2e8320072 100644 --- a/src/kOS/Function/Suffixed.cs +++ b/src/kOS/Function/Suffixed.cs @@ -349,16 +349,20 @@ public override void Execute(SharedObjects shared) string pointName = shared.Cpu.PopValue().ToString(); WaypointManager wpm = WaypointManager.Instance(); - if (wpm == null) + if (wpm == null) // When zero waypoints exist, there might not even be a waypoint manager. { - shared.Cpu.PushStack(null); // When no waypoints exist, there isn't even a waypoint manager. + shared.Cpu.PushStack(null); // I don't like returning null here without the user being able to test for that, but // we don't have another way to communicate "no such waypoint". We really need to address // that problem once and for all. return; } - - Waypoint point = wpm.AllWaypoints().FirstOrDefault(p => String.Equals(p.name, pointName,StringComparison.CurrentCultureIgnoreCase)); + + string baseName; + int index; + bool hasGreek = WaypointValue.GreekToInteger(pointName, out index, out baseName); + Waypoint point = wpm.AllWaypoints().FirstOrDefault( + p => String.Equals(p.name, baseName,StringComparison.CurrentCultureIgnoreCase) && (!hasGreek || p.index == index)); shared.Cpu.PushStack(new WaypointValue(point, shared)); } diff --git a/src/kOS/Suffixed/WaypointValue.cs b/src/kOS/Suffixed/WaypointValue.cs index e9e249e5f..daed5f1f3 100644 --- a/src/kOS/Suffixed/WaypointValue.cs +++ b/src/kOS/Suffixed/WaypointValue.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using kOS.Utilities; using kOS.Safe.Encapsulation.Suffixes; using kOS.Safe.Encapsulation; @@ -8,47 +9,80 @@ namespace kOS.Suffixed { public class WaypointValue : Structure { - protected Waypoint WayPoint { get; set; } + protected Waypoint WrappedWaypoint { get; set; } protected CelestialBody CachedBody { get; set; } protected SharedObjects Shared { get; set; } + private static Dictionary greekMap; public WaypointValue(Waypoint wayPoint, SharedObjects shared) { - WayPoint = wayPoint; + WrappedWaypoint = wayPoint; Shared = shared; AddSuffix("DUMP", new NoArgsSuffix(ToVerboseString)); // for debugging - AddSuffix("NAME", new NoArgsSuffix(() => wayPoint.name, "Name of waypoint as it appears on the map and contract")); - AddSuffix("BODY", new NoArgsSuffix(() => new BodyTarget(GetBody(),shared), "Celestial body the waypoint is attached to")); + AddSuffix("NAME", new NoArgsSuffix(() => CookedName(), "Name of waypoint as it appears on the map and contract")); + AddSuffix("BODY", new NoArgsSuffix(() => new BodyTarget(GetBody(),Shared), "Celestial body the waypoint is attached to")); AddSuffix("GEOPOSITION", new NoArgsSuffix(BuildGeoCoordinates, "the LATLNG of this waypoint")); + AddSuffix("POSITION", new NoArgsSuffix(() => GetPosition() - new Vector( Shared.Vessel.findWorldCenterOfMass()))); AddSuffix("ALTITUDE", new NoArgsSuffix(BuildSeaLevelAltitude, "Altitude of waypoint above sea level. Warning, this a point somewhere in the " + "midst of the contract altitude range, not the edge of the altitude range.")); - AddSuffix("AGL", new NoArgsSuffix(() => wayPoint.altitude, + AddSuffix("AGL", new NoArgsSuffix(() => WrappedWaypoint.altitude, "Altitude of waypoint above ground. Warning, this a point somewhere" + "in the midst of the contract altitude range, not the edge of the altitude range.")); - AddSuffix("NEARSURFACE", new NoArgsSuffix(() => wayPoint.isOnSurface, "True if waypoint is a point near or on the body rather than high in orbit.")); - AddSuffix("GROUNDED", new NoArgsSuffix(() => wayPoint.landLocked, "True if waypoint is actually glued to the ground.")); + AddSuffix("NEARSURFACE", new NoArgsSuffix(() => WrappedWaypoint.isOnSurface, "True if waypoint is a point near or on the body rather than high in orbit.")); + AddSuffix("GROUNDED", new NoArgsSuffix(() => WrappedWaypoint.landLocked, "True if waypoint is actually glued to the ground.")); + AddSuffix("INDEX", new NoArgsSuffix(() => WrappedWaypoint.index, "Number of this waypoint if this is a grouped waypoint (i.e. alpha/beta/gamma..")); + AddSuffix("CLUSTERED", new NoArgsSuffix(() => WrappedWaypoint.isClustered, "True if this is a member of a cluster of waypoints (i.e. alpha/beta/gamma..")); + // greekMap is static, so whichever waypoint instance's constructor happens to + // get called first will make it, and from then on other waypoints don't need to + // keep re-initializing it: + if (greekMap == null) + InitializeGreekMap(); + } + + private static void InitializeGreekMap() + { + greekMap = new Dictionary(); + for (int i = 0 ; i < 20 ; ++i) + greekMap.Add(FinePrint.Utilities.StringUtilities.IntegerToGreek(i).ToLower(), i); } public CelestialBody GetBody() { - return CachedBody ?? (CachedBody = VesselUtils.GetBodyByName(WayPoint.celestialName)); + return CachedBody ?? (CachedBody = VesselUtils.GetBodyByName(WrappedWaypoint.celestialName)); } public GeoCoordinates BuildGeoCoordinates() { - return new GeoCoordinates(GetBody(), Shared, WayPoint.latitude, WayPoint.longitude); + return new GeoCoordinates(GetBody(), Shared, WrappedWaypoint.latitude, WrappedWaypoint.longitude); + } + + public Vector GetPosition() + { + return new Vector(GetBody().GetWorldSurfacePosition(WrappedWaypoint.latitude, WrappedWaypoint.longitude, BuildSeaLevelAltitude())); } public double BuildSeaLevelAltitude() { GeoCoordinates gCoord = BuildGeoCoordinates(); - return gCoord.GetTerrainAltitude() + WayPoint.altitude; + return gCoord.GetTerrainAltitude() + WrappedWaypoint.altitude; } public override string ToString() { - return String.Format("Waypoint \"{0}\"", WayPoint.name); + return String.Format("Waypoint \"{0}\"", CookedName() ); + } + + public string CookedName() + { + return String.Format("{0}{1}", + WrappedWaypoint.name, + ( + WrappedWaypoint.isClustered ? + (" " + FinePrint.Utilities.StringUtilities.IntegerToGreek(WrappedWaypoint.index)) : + "" + ) + ); } public string ToVerboseString() @@ -62,15 +96,62 @@ public string ToVerboseString() " altitude= {4}\n" + " height= {5}\n" + " isOnSurface= {6}\n" + - " worldPosition= {7}\n", - WayPoint.name, - WayPoint.celestialName, - WayPoint.latitude, - WayPoint.longitude, - WayPoint.altitude, // A location inside the contract range's altitude range - and NOT the edge of it. - WayPoint.height, - WayPoint.isOnSurface, - WayPoint.worldPosition); + " worldPosition= {7}\n" + + " index= {8}\n" + + " clustered= {9}\n", + CookedName(), + WrappedWaypoint.celestialName, + WrappedWaypoint.latitude, + WrappedWaypoint.longitude, + WrappedWaypoint.altitude, // A location inside the contract range's altitude range - and NOT the edge of it. + WrappedWaypoint.height, + WrappedWaypoint.isOnSurface, + GetPosition(), + WrappedWaypoint.index, + WrappedWaypoint.isClustered); + } + + /// + /// Return an integer to go with the alphabet position of the + /// string given in greek lettering. For example, input "alpha" and + /// get out 0. input "beta" and get out 1. If no match is found, + /// -1 is returned. + ///
+ /// This is used by waypoints so that you can figure out that a waypoint + /// named like "Jebadiah's lament Gamma" is really the 3rd (index 2) member + /// of the "Jebadiah's lament" cluster of waypoints. + ///
+ /// Because that is its purpose, it actually operates on the LASTMOST word + /// in the string it is given. given a string like "foo bar baz", it will + /// check if "baz" is a greek letter, not "foo". Thus you can pass in exactly + /// the name as it appears onscreen. + ///
+ /// string name to check. Case insensitively. + /// integer position in alphabet. -1 if no match. + /// the name after the greek suffix has been stripped off, if there is one. + /// true if there was a greek letter suffix + public static bool GreekToInteger(string greekLetterName, out int index, out string baseName ) + { + // Get lastmost word (or whole string if there's no spaces): + int lastSpace = greekLetterName.LastIndexOf(' '); + string lastTerm; + if (lastSpace >= 0 && lastSpace < greekLetterName.Length - 1) + { + // last space is real, and isn't the lastmost char but actually has + // nonspaces that follow it: + lastTerm = greekLetterName.Substring(lastSpace+1).ToLower(); // ToLower for the dictionary hashmap lookup + baseName = greekLetterName.Substring(0,lastSpace); + } + else + { + lastTerm = greekLetterName.ToLower(); // ToLower for the dictionary hashmap lookup + baseName = greekLetterName; + } + + bool worked = greekMap.TryGetValue(lastTerm, out index); + if (!worked) + index = -1; + return worked; } } From e9fee29f91e7ece0a7c5dbf8916c310a5754164f Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Wed, 28 Jan 2015 12:43:29 -0600 Subject: [PATCH 115/446] Minor change - renamed dump labels. The labels of the DUMP suffix were changed to match the names actually seen by the user. (They were originally for the sake of my debugging so I used the native terms, but now they're for the user so they use the suffix terms.) --- src/kOS/Suffixed/WaypointValue.cs | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/src/kOS/Suffixed/WaypointValue.cs b/src/kOS/Suffixed/WaypointValue.cs index daed5f1f3..4c8fa3cbf 100644 --- a/src/kOS/Suffixed/WaypointValue.cs +++ b/src/kOS/Suffixed/WaypointValue.cs @@ -91,20 +91,18 @@ public string ToVerboseString() return String.Format("A Waypoint consisting of\n" + " name= {0}\n" + " body= {1}\n" + - " latitude= {2}\n" + - " longitude= {3}\n" + + " geoposition= {2}\n" + + " agl= {3}\n" + " altitude= {4}\n" + - " height= {5}\n" + - " isOnSurface= {6}\n" + - " worldPosition= {7}\n" + - " index= {8}\n" + - " clustered= {9}\n", + " nearsurface= {5}\n" + + " position= {6}\n" + + " index= {7}\n" + + " clustered= {8}\n", CookedName(), WrappedWaypoint.celestialName, - WrappedWaypoint.latitude, - WrappedWaypoint.longitude, + new GeoCoordinates(GetBody(), Shared, WrappedWaypoint.latitude, WrappedWaypoint.longitude), WrappedWaypoint.altitude, // A location inside the contract range's altitude range - and NOT the edge of it. - WrappedWaypoint.height, + BuildSeaLevelAltitude(), WrappedWaypoint.isOnSurface, GetPosition(), WrappedWaypoint.index, From e48dff7a140e38c6c7e9fe30f5e809da3ea05bd3 Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Wed, 28 Jan 2015 12:46:16 -0600 Subject: [PATCH 116/446] Forgot about my own utility method to use. --- src/kOS/Suffixed/WaypointValue.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kOS/Suffixed/WaypointValue.cs b/src/kOS/Suffixed/WaypointValue.cs index 4c8fa3cbf..4e00e6cfb 100644 --- a/src/kOS/Suffixed/WaypointValue.cs +++ b/src/kOS/Suffixed/WaypointValue.cs @@ -100,7 +100,7 @@ public string ToVerboseString() " clustered= {8}\n", CookedName(), WrappedWaypoint.celestialName, - new GeoCoordinates(GetBody(), Shared, WrappedWaypoint.latitude, WrappedWaypoint.longitude), + BuildGeoCoordinates(), WrappedWaypoint.altitude, // A location inside the contract range's altitude range - and NOT the edge of it. BuildSeaLevelAltitude(), WrappedWaypoint.isOnSurface, From 19be0b236023a7637cb8577353f23cc43abe2ac2 Mon Sep 17 00:00:00 2001 From: Chris Woerz Date: Wed, 28 Jan 2015 18:47:00 -0700 Subject: [PATCH 117/446] removed code related to old part subclass structure --- src/kOS/Utilities/SteeringHelper.cs | 76 ++++------------------------- 1 file changed, 10 insertions(+), 66 deletions(-) diff --git a/src/kOS/Utilities/SteeringHelper.cs b/src/kOS/Utilities/SteeringHelper.cs index 114db194f..6b36e5557 100644 --- a/src/kOS/Utilities/SteeringHelper.cs +++ b/src/kOS/Utilities/SteeringHelper.cs @@ -164,24 +164,6 @@ public static Vector3d GetTorque(Vessel vessel, float thrust) { var relCoM = part.Rigidbody.worldCenterOfMass - centerOfMass; - var pod = part as CommandPod; - if (pod != null) - { - pitch += Math.Abs(pod.rotPower); - yaw += Math.Abs(pod.rotPower); - roll += Math.Abs(pod.rotPower); - } - /* - //This is probably useless - commented out. - var rcsModule = part as RCSModule; - if (rcsModule != null) - { - float max = rcsModule.thrusterPowers.Aggregate(0, Mathf.Max); - - roll += max * (Vector3.Cross(relCoM, rollaxis)).magnitude; - pitchYaw += max * Vector3.Dot(relCoM, rollaxis); - } - */ foreach (PartModule module in part.Modules) { var wheel = module as ModuleReactionWheel; @@ -195,29 +177,17 @@ public static Vector3d GetTorque(Vessel vessel, float thrust) { foreach (PartModule module in part.Modules) { var rcs = module as ModuleRCS; - if (rcs == null) continue; + if (rcs == null || !rcs.rcsEnabled) continue; - if (rcs.rcsEnabled == true) + bool enoughfuel = rcs.propellants.All(p => (int) (p.totalResourceAvailable) != 0); + if (!enoughfuel) continue; + foreach (Transform thrustdir in rcs.thrusterTransforms) { - bool enoughfuel = true; - foreach (Propellant p in rcs.propellants) - { - if ((int)(p.totalResourceAvailable)==0) - { - enoughfuel = false; - } - } - if (enoughfuel == true) - { - foreach (Transform thrustdir in rcs.thrusterTransforms) - { - float rcsthrust = rcs.thrusterPower; - //just counting positive contributions in one direction. This is incorrect for asymmetric thruster placements. - roll += Mathf.Max(rcsthrust * Vector3.Dot(Vector3.Cross(relCoM, thrustdir.up), rollaxis), 0.0f); - pitch += Mathf.Max(rcsthrust * Vector3.Dot(Vector3.Cross(Vector3.Cross(relCoM, thrustdir.up), rollaxis), pitchaxis), 0.0f); - yaw += Mathf.Max(rcsthrust * Vector3.Dot(Vector3.Cross(Vector3.Cross(relCoM, thrustdir.up), rollaxis), Vector3.Cross(rollaxis,pitchaxis)),0.0f); - } - } + float rcsthrust = rcs.thrusterPower; + //just counting positive contributions in one direction. This is incorrect for asymmetric thruster placements. + roll += Mathf.Max(rcsthrust * Vector3.Dot(Vector3.Cross(relCoM, thrustdir.up), rollaxis), 0.0f); + pitch += Mathf.Max(rcsthrust * Vector3.Dot(Vector3.Cross(Vector3.Cross(relCoM, thrustdir.up), rollaxis), pitchaxis), 0.0f); + yaw += Mathf.Max(rcsthrust * Vector3.Dot(Vector3.Cross(Vector3.Cross(relCoM, thrustdir.up), rollaxis), Vector3.Cross(rollaxis,pitchaxis)),0.0f); } } } @@ -230,33 +200,7 @@ public static Vector3d GetTorque(Vessel vessel, float thrust) public static double GetThrustTorque(Part p, Vessel vessel) { - var centerOfMass = vessel.CoM; - - if (p.State == PartStates.ACTIVE) - { - if (p is LiquidEngine) - { - if (((LiquidEngine)p).thrustVectoringCapable) - { - return Math.Sin(Math.Abs(((LiquidEngine)p).gimbalRange) * Math.PI / 180) * ((LiquidEngine)p).maxThrust * (p.Rigidbody.worldCenterOfMass - centerOfMass).magnitude; - } - } - else if (p is LiquidFuelEngine) - { - if (((LiquidFuelEngine)p).thrustVectoringCapable) - { - return Math.Sin(Math.Abs(((LiquidFuelEngine)p).gimbalRange) * Math.PI / 180) * ((LiquidFuelEngine)p).maxThrust * (p.Rigidbody.worldCenterOfMass - centerOfMass).magnitude; - } - } - else if (p is AtmosphericEngine) - { - if (((AtmosphericEngine)p).thrustVectoringCapable) - { - return Math.Sin(Math.Abs(((AtmosphericEngine)p).gimbalRange) * Math.PI / 180) * ((AtmosphericEngine)p).maximumEnginePower * ((AtmosphericEngine)p).totalEfficiency * (p.Rigidbody.worldCenterOfMass - centerOfMass).magnitude; - } - } - } - + //TODO: implement gimbalthrust Torque calculation return 0; } From 31e9f10c8db929f61688b19e76020056e01e9767 Mon Sep 17 00:00:00 2001 From: Chris Woerz Date: Wed, 28 Jan 2015 19:10:47 -0700 Subject: [PATCH 118/446] a bunch of work to make TermWindow 'safer' --- src/kOS.Safe/Encapsulation/TerminalStruct.cs | 31 +++++++++++--------- src/kOS.Safe/kOS.Safe.csproj | 1 + src/kOS/Module/kOSProcessor.cs | 4 +-- src/kOS/Screen/Interpreter.cs | 2 +- src/kOS/Screen/KOSManagedWindow.cs | 4 ++- src/kOS/Screen/TermWindow.cs | 19 +++--------- src/kOS/SharedObjects.cs | 4 +-- 7 files changed, 30 insertions(+), 35 deletions(-) diff --git a/src/kOS.Safe/Encapsulation/TerminalStruct.cs b/src/kOS.Safe/Encapsulation/TerminalStruct.cs index 6cc0b410c..dd5d673ed 100644 --- a/src/kOS.Safe/Encapsulation/TerminalStruct.cs +++ b/src/kOS.Safe/Encapsulation/TerminalStruct.cs @@ -1,16 +1,15 @@ -using System; -using kOS.Safe.Encapsulation.Suffixes; -using kOS.Safe; +using kOS.Safe.Encapsulation.Suffixes; namespace kOS.Safe.Encapsulation { public class TerminalStruct : Structure { - protected SharedObjects shared; - + private readonly SharedObjects shared; + // Some sanity values to prevent the terminal display from getting garbled up: // They may have to change after experimentation. protected const int MINROWS = 3; + protected const int MAXROWS = 80; protected const int MINCOLUMNS = 15; protected const int MAXCOLUMNS = 160; @@ -23,24 +22,29 @@ public class TerminalStruct : Structure public TerminalStruct(SharedObjects shared) { this.shared = shared; - + InitializeSuffixes(); } - + + protected internal SharedObjects Shared + { + get { return shared; } + } + private void InitializeSuffixes() { // TODO: Uncomment the following if IsOpen gets implemented later: // AddSuffix("ISOPEN", new SetSuffix(() => IsOpen, Isopen = value, "true=open, false=closed. You can set it to open/close the window.")); - AddSuffix("HEIGHT", new ClampSetSuffix(() => shared.Screen.RowCount, - value => shared.Screen.SetSize(value, shared.Screen.ColumnCount), + AddSuffix("HEIGHT", new ClampSetSuffix(() => Shared.Screen.RowCount, + value => Shared.Screen.SetSize(value, Shared.Screen.ColumnCount), MINROWS, MAXROWS, - "Get or Set the number of rows on the screen. Value is limited to the range ["+MINROWS+","+MAXROWS+"]")); - AddSuffix("WIDTH", new ClampSetSuffix(() => shared.Screen.ColumnCount, - value => shared.Screen.SetSize(shared.Screen.RowCount, value), + "Get or Set the number of rows on the screen. Value is limited to the range [" + MINROWS + "," + MAXROWS + "]")); + AddSuffix("WIDTH", new ClampSetSuffix(() => Shared.Screen.ColumnCount, + value => Shared.Screen.SetSize(Shared.Screen.RowCount, value), MINCOLUMNS, MAXCOLUMNS, - "Get or Set the number of columns on the screen. Value is limited to the range ["+MINCOLUMNS+","+MAXCOLUMNS+"]")); + "Get or Set the number of columns on the screen. Value is limited to the range [" + MINCOLUMNS + "," + MAXCOLUMNS + "]")); } public override string ToString() @@ -48,5 +52,4 @@ public override string ToString() return string.Format("{0} Terminal", base.ToString()); } } - } \ No newline at end of file diff --git a/src/kOS.Safe/kOS.Safe.csproj b/src/kOS.Safe/kOS.Safe.csproj index dbc5c5da3..d2c5e5da9 100644 --- a/src/kOS.Safe/kOS.Safe.csproj +++ b/src/kOS.Safe/kOS.Safe.csproj @@ -133,6 +133,7 @@ Resources.resx
+ diff --git a/src/kOS/Module/kOSProcessor.cs b/src/kOS/Module/kOSProcessor.cs index 67458b139..62ca410c3 100644 --- a/src/kOS/Module/kOSProcessor.cs +++ b/src/kOS/Module/kOSProcessor.cs @@ -509,13 +509,13 @@ public void SetMode(ProcessorModes newProcessorMode) case ProcessorModes.READY: if (ProcessorMode == ProcessorModes.STARVED && shared.Cpu != null) shared.Cpu.Boot(); if (shared.Interpreter != null) shared.Interpreter.SetInputLock(false); - if (shared.Window != null) shared.Window.SetPowered(true); + if (shared.Window != null) shared.Window.IsPowered = true; break; case ProcessorModes.OFF: case ProcessorModes.STARVED: if (shared.Interpreter != null) shared.Interpreter.SetInputLock(true); - if (shared.Window != null) shared.Window.SetPowered(false); + if (shared.Window != null) shared.Window.IsPowered = false; break; } diff --git a/src/kOS/Screen/Interpreter.cs b/src/kOS/Screen/Interpreter.cs index 0b099b6e5..721770eeb 100644 --- a/src/kOS/Screen/Interpreter.cs +++ b/src/kOS/Screen/Interpreter.cs @@ -133,7 +133,7 @@ protected void CompileCommand(string commandText) public void SetInputLock(bool isLocked) { locked = isLocked; - if (Shared.Window != null) Shared.Window.SetShowCursor(!isLocked); + if (Shared.Window != null) Shared.Window.ShowCursor = !isLocked; LineSubBuffer.Enabled = !isLocked; } diff --git a/src/kOS/Screen/KOSManagedWindow.cs b/src/kOS/Screen/KOSManagedWindow.cs index 3885b5284..a772a8bcd 100644 --- a/src/kOS/Screen/KOSManagedWindow.cs +++ b/src/kOS/Screen/KOSManagedWindow.cs @@ -47,7 +47,9 @@ protected KOSManagedWindow() uniqueId = termWindowIDRange + (windowsMadeSoFar * 50); ++windowsMadeSoFar; } - + + public bool IsPowered { get; set; } + /// /// Implement this for how to make your widget get the keyboard focus: /// diff --git a/src/kOS/Screen/TermWindow.cs b/src/kOS/Screen/TermWindow.cs index 0a32a732f..0b26ebd46 100644 --- a/src/kOS/Screen/TermWindow.cs +++ b/src/kOS/Screen/TermWindow.cs @@ -6,12 +6,11 @@ using kOS.Safe.Screen; using kOS.Safe.Utilities; using kOS.Module; -using kOS.Safe.Encapsulation; namespace kOS.Screen { // Blockotronix 550 Computor Monitor - public class TermWindow : KOSManagedWindow + public class TermWindow : KOSManagedWindow , ITermWindow { private const int CHARSIZE = 8; private const string CONTROL_LOCKOUT = "kOSTerminal"; @@ -43,11 +42,8 @@ public class TermWindow : KOSManagedWindow private Texture2D resizeButtonImage = new Texture2D(0, 0, TextureFormat.DXT1, false); private SharedObjects shared; - private bool showCursor = true; private KOSTextEditPopup popupEditor; - public bool IsPowered { get; protected set; } - public TermWindow() { @@ -55,6 +51,8 @@ public TermWindow() windowRect = new Rect(50, 60, 0, 0); // will get resized later in AttachTo(). } + public bool ShowCursor { get; set; } + public void Awake() { LoadTexture("GameData/kOS/GFX/font_sml.png", ref fontImage); @@ -379,7 +377,7 @@ void TerminalGui(int windowId) bool blinkOn = cursorBlinkTime < 0.5f && screen.CursorRowShow < screen.RowCount && IsPowered && - showCursor; + ShowCursor; if (blinkOn) { ShowCharacterByAscii((char)1, screen.CursorColumnShow, screen.CursorRowShow, currentTextColor); @@ -472,14 +470,5 @@ private int HowManyColumnsFit() return (int)(windowRect.width - 65) / CHARSIZE; } - public void SetPowered(bool isPowered) - { - IsPowered = isPowered; - } - - public void SetShowCursor(bool showCursor) - { - this.showCursor = showCursor; - } } } diff --git a/src/kOS/SharedObjects.cs b/src/kOS/SharedObjects.cs index e5325cfef..5c8f73daf 100644 --- a/src/kOS/SharedObjects.cs +++ b/src/kOS/SharedObjects.cs @@ -1,7 +1,7 @@ using kOS.InterProcessor; using kOS.Binding; -using kOS.Screen; using kOS.Factories; +using kOS.Screen; namespace kOS { @@ -9,10 +9,10 @@ public class SharedObjects : Safe.SharedObjects { public Vessel Vessel { get; set; } public BindingManager BindingMgr { get; set; } - public TermWindow Window { get; set; } public ProcessorManager ProcessorMgr { get; set; } public IFactory Factory { get; set; } public Part KSPPart { get; set; } + public TermWindow Window { get; set; } public SharedObjects() { From 1dcb98d7d0e414e4e7f0f216aaaed1b6bf6d4fac Mon Sep 17 00:00:00 2001 From: Chris Woerz Date: Wed, 28 Jan 2015 19:24:36 -0700 Subject: [PATCH 119/446] minor changes in encapsulation --- src/kOS.Safe/Screen/IScreenBuffer.cs | 27 ++++++++++++++++++++ src/kOS.Safe/Screen/ITermWindow.cs | 15 +++++++++++ src/kOS.Safe/Screen/ScreenBuffer.cs | 37 ++++++---------------------- src/kOS.Safe/Screen/SubBuffer.cs | 7 +++--- src/kOS.Safe/Screen/TextEditor.cs | 1 - src/kOS.Safe/kOS.Safe.csproj | 1 + src/kOS/Binding/BindingsUniverse.cs | 2 ++ src/kOS/Binding/TerminalSettings.cs | 1 - 8 files changed, 56 insertions(+), 35 deletions(-) create mode 100644 src/kOS.Safe/Screen/IScreenBuffer.cs create mode 100644 src/kOS.Safe/Screen/ITermWindow.cs diff --git a/src/kOS.Safe/Screen/IScreenBuffer.cs b/src/kOS.Safe/Screen/IScreenBuffer.cs new file mode 100644 index 000000000..97435a892 --- /dev/null +++ b/src/kOS.Safe/Screen/IScreenBuffer.cs @@ -0,0 +1,27 @@ +using System.Collections.Generic; + +namespace kOS.Safe.Screen +{ + public interface IScreenBuffer + { + int CursorRowShow { get; } + int CursorColumnShow { get; } + int RowCount { get; } + int ColumnCount { get; } + int AbsoluteCursorRow { get; set; } + void SetSize(int rowCount, int columnCount); + int ScrollVertical(int deltaRows); + void MoveCursor(int row, int column); + void MoveToNextLine(); + void PrintAt(string textToPrint, int row, int column); + void Print(string textToPrint); + void Print(string textToPrint, bool addNewLine); + void ClearScreen(); + void AddSubBuffer(SubBuffer subBuffer); + void RemoveSubBuffer(SubBuffer subBuffer); + List GetBuffer(); + void AddResizeNotifier(ScreenBuffer.ResizeNotifier notifier); + void RemoveResizeNotifier(ScreenBuffer.ResizeNotifier notifier); + string DebugDump(); + } +} \ No newline at end of file diff --git a/src/kOS.Safe/Screen/ITermWindow.cs b/src/kOS.Safe/Screen/ITermWindow.cs new file mode 100644 index 000000000..a571b5185 --- /dev/null +++ b/src/kOS.Safe/Screen/ITermWindow.cs @@ -0,0 +1,15 @@ +using kOS.Safe.Persistence; + +namespace kOS.Safe.Screen +{ + public interface ITermWindow + { + void OpenPopupEditor( Volume v, string fName ); + void Open(); + void Close(); + void Toggle(); + bool IsOpen(); + bool ShowCursor { get; set; } + bool IsPowered { get; set; } + } +} \ No newline at end of file diff --git a/src/kOS.Safe/Screen/ScreenBuffer.cs b/src/kOS.Safe/Screen/ScreenBuffer.cs index 5f3cdb562..3813abaf6 100644 --- a/src/kOS.Safe/Screen/ScreenBuffer.cs +++ b/src/kOS.Safe/Screen/ScreenBuffer.cs @@ -4,30 +4,6 @@ namespace kOS.Safe.Screen { - public interface IScreenBuffer - { - int CursorRowShow { get; } - int CursorColumnShow { get; } - int RowCount { get; } - int ColumnCount { get; } - int AbsoluteCursorRow { get; set; } - void SetSize(int rowCount, int columnCount); - int ScrollVertical(int deltaRows); - void MoveCursor(int row, int column); - void MoveToNextLine(); - void PrintAt(string textToPrint, int row, int column); - void Print(string textToPrint); - void Print(string textToPrint, bool addNewLine); - void ClearScreen(); - void AddSubBuffer(SubBuffer subBuffer); - void RemoveSubBuffer(SubBuffer subBuffer); - List GetBuffer(); - void AddResizeNotifier(ScreenBuffer.ResizeNotifier notifier); - void RemoveResizeNotifier(ScreenBuffer.ResizeNotifier notifier); - string DebugDump(); - } - - public class ScreenBuffer : IScreenBuffer { private const int DEFAULT_ROWS = 36; @@ -43,12 +19,12 @@ public class ScreenBuffer : IScreenBuffer public virtual int CursorColumnShow { get { return CursorColumn; } } public int RowCount { get; private set; } public int ColumnCount { get; private set; } + protected List Notifyees { get; set; } /// Delegate prototype expected by AddResizeNotifier /// This screenbuffer telling the callback who it is /// telling this screenbuffer how many vertical rows to scroll as a result of the resize. public delegate int ResizeNotifier(IScreenBuffer sb); - protected List notifyees; public int AbsoluteCursorRow { @@ -57,10 +33,11 @@ public int AbsoluteCursorRow } + public ScreenBuffer() { buffer = new List(); - notifyees = new List(); + Notifyees = new List(); subBuffers = new List(); @@ -87,13 +64,13 @@ protected void AddNewBufferLines( int howMany = 1) public void AddResizeNotifier(ScreenBuffer.ResizeNotifier notifier) { - if (notifyees.IndexOf(notifier) < 0) - notifyees.Add(notifier); + if (Notifyees.IndexOf(notifier) < 0) + Notifyees.Add(notifier); } public void RemoveResizeNotifier(ScreenBuffer.ResizeNotifier notifier) { - notifyees.Remove(notifier); + Notifyees.Remove(notifier); } public void SetSize(int rows, int columns) @@ -102,7 +79,7 @@ public void SetSize(int rows, int columns) ColumnCount = columns; ResizeBuffer(); int scrollDiff = 0; - foreach (ResizeNotifier notifier in notifyees) + foreach (ResizeNotifier notifier in Notifyees) { if (notifier != null) scrollDiff += notifier(this); diff --git a/src/kOS.Safe/Screen/SubBuffer.cs b/src/kOS.Safe/Screen/SubBuffer.cs index 30fb63865..fbfee04bb 100644 --- a/src/kOS.Safe/Screen/SubBuffer.cs +++ b/src/kOS.Safe/Screen/SubBuffer.cs @@ -1,5 +1,4 @@ using System.Collections.Generic; -using System; using System.Text; namespace kOS.Safe.Screen @@ -102,8 +101,10 @@ protected virtual int ResizeBuffer() // Because Buffer is readonly, copy the data from newBuffer into it rather than just resetting the reference to newBuffer: Buffer.Clear(); - for (int i = 0 ; i < newBuffer.Count ; ++i) - Buffer.Add(newBuffer[i]); + foreach (var t in newBuffer) + { + Buffer.Add(t); + } // return Fixed ? 0 : scrollDiff; - this logic not quite working - disabled for now. return 0; diff --git a/src/kOS.Safe/Screen/TextEditor.cs b/src/kOS.Safe/Screen/TextEditor.cs index e4793e500..71558e358 100644 --- a/src/kOS.Safe/Screen/TextEditor.cs +++ b/src/kOS.Safe/Screen/TextEditor.cs @@ -1,7 +1,6 @@ using System.Collections.Generic; using System.Text; using kOS.Safe.Utilities; -using System; namespace kOS.Safe.Screen { diff --git a/src/kOS.Safe/kOS.Safe.csproj b/src/kOS.Safe/kOS.Safe.csproj index d2c5e5da9..9540f3976 100644 --- a/src/kOS.Safe/kOS.Safe.csproj +++ b/src/kOS.Safe/kOS.Safe.csproj @@ -133,6 +133,7 @@ Resources.resx + diff --git a/src/kOS/Binding/BindingsUniverse.cs b/src/kOS/Binding/BindingsUniverse.cs index 3daeb33bb..3ab56d231 100644 --- a/src/kOS/Binding/BindingsUniverse.cs +++ b/src/kOS/Binding/BindingsUniverse.cs @@ -121,6 +121,8 @@ public override void AddTo(SharedObjects shared) var cBody = body; shared.BindingMgr.AddGetter(body.name, () => new BodyTarget(cBody, shared)); } + + shared.BindingMgr.AddGetter("VERSION", () => Core.VersionInfo); } } } \ No newline at end of file diff --git a/src/kOS/Binding/TerminalSettings.cs b/src/kOS/Binding/TerminalSettings.cs index 487c6c9cf..723c4a392 100644 --- a/src/kOS/Binding/TerminalSettings.cs +++ b/src/kOS/Binding/TerminalSettings.cs @@ -9,7 +9,6 @@ public class TerminalSettings : Binding public override void AddTo(SharedObjects shared) { shared.BindingMgr.AddGetter("SESSIONTIME", () => shared.Cpu.SessionTime); - shared.BindingMgr.AddGetter("VERSION", () => Core.VersionInfo); shared.BindingMgr.AddGetter("VOLUME:NAME", () => shared.VolumeMgr.CurrentVolume.Name); shared.BindingMgr.AddGetter("TERMINAL", () => new TerminalStruct(shared)); } From 5a466a2063c9cec035248173eb15ac3754e03430 Mon Sep 17 00:00:00 2001 From: Chris Woerz Date: Wed, 28 Jan 2015 19:30:01 -0700 Subject: [PATCH 120/446] moved suffixes to their own method --- src/kOS/Suffixed/WaypointValue.cs | 34 ++++++++++++++++--------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/src/kOS/Suffixed/WaypointValue.cs b/src/kOS/Suffixed/WaypointValue.cs index 4e00e6cfb..399060b84 100644 --- a/src/kOS/Suffixed/WaypointValue.cs +++ b/src/kOS/Suffixed/WaypointValue.cs @@ -18,28 +18,30 @@ public WaypointValue(Waypoint wayPoint, SharedObjects shared) { WrappedWaypoint = wayPoint; Shared = shared; - AddSuffix("DUMP", new NoArgsSuffix(ToVerboseString)); // for debugging - AddSuffix("NAME", new NoArgsSuffix(() => CookedName(), "Name of waypoint as it appears on the map and contract")); - AddSuffix("BODY", new NoArgsSuffix(() => new BodyTarget(GetBody(),Shared), "Celestial body the waypoint is attached to")); - AddSuffix("GEOPOSITION", new NoArgsSuffix(BuildGeoCoordinates, "the LATLNG of this waypoint")); - AddSuffix("POSITION", new NoArgsSuffix(() => GetPosition() - new Vector( Shared.Vessel.findWorldCenterOfMass()))); - AddSuffix("ALTITUDE", new NoArgsSuffix(BuildSeaLevelAltitude, - "Altitude of waypoint above sea level. Warning, this a point somewhere in the " + - "midst of the contract altitude range, not the edge of the altitude range.")); - AddSuffix("AGL", new NoArgsSuffix(() => WrappedWaypoint.altitude, - "Altitude of waypoint above ground. Warning, this a point somewhere" + - "in the midst of the contract altitude range, not the edge of the altitude range.")); - AddSuffix("NEARSURFACE", new NoArgsSuffix(() => WrappedWaypoint.isOnSurface, "True if waypoint is a point near or on the body rather than high in orbit.")); - AddSuffix("GROUNDED", new NoArgsSuffix(() => WrappedWaypoint.landLocked, "True if waypoint is actually glued to the ground.")); - AddSuffix("INDEX", new NoArgsSuffix(() => WrappedWaypoint.index, "Number of this waypoint if this is a grouped waypoint (i.e. alpha/beta/gamma..")); - AddSuffix("CLUSTERED", new NoArgsSuffix(() => WrappedWaypoint.isClustered, "True if this is a member of a cluster of waypoints (i.e. alpha/beta/gamma..")); + InitializeSuffixes(); + // greekMap is static, so whichever waypoint instance's constructor happens to // get called first will make it, and from then on other waypoints don't need to // keep re-initializing it: if (greekMap == null) InitializeGreekMap(); } - + + private void InitializeSuffixes() + { + AddSuffix("DUMP", new NoArgsSuffix(ToVerboseString)); // for debugging + AddSuffix("NAME", new NoArgsSuffix(CookedName, "Name of waypoint as it appears on the map and contract")); + AddSuffix("BODY", new NoArgsSuffix(() => new BodyTarget(GetBody(), Shared), "Celestial body the waypoint is attached to")); + AddSuffix("GEOPOSITION", new NoArgsSuffix(BuildGeoCoordinates, "the LATLNG of this waypoint")); + AddSuffix("POSITION", new NoArgsSuffix(() => GetPosition() - new Vector(Shared.Vessel.findWorldCenterOfMass()))); + AddSuffix("ALTITUDE", new NoArgsSuffix(BuildSeaLevelAltitude, "Altitude of waypoint above sea level. Warning, this a point somewhere in the " + "midst of the contract altitude range, not the edge of the altitude range.")); + AddSuffix("AGL", new NoArgsSuffix(() => WrappedWaypoint.altitude, "Altitude of waypoint above ground. Warning, this a point somewhere" + "in the midst of the contract altitude range, not the edge of the altitude range.")); + AddSuffix("NEARSURFACE", new NoArgsSuffix(() => WrappedWaypoint.isOnSurface, "True if waypoint is a point near or on the body rather than high in orbit.")); + AddSuffix("GROUNDED", new NoArgsSuffix(() => WrappedWaypoint.landLocked, "True if waypoint is actually glued to the ground.")); + AddSuffix("INDEX", new NoArgsSuffix(() => WrappedWaypoint.index, "Number of this waypoint if this is a grouped waypoint (i.e. alpha/beta/gamma..")); + AddSuffix("CLUSTERED", new NoArgsSuffix(() => WrappedWaypoint.isClustered, "True if this is a member of a cluster of waypoints (i.e. alpha/beta/gamma..")); + } + private static void InitializeGreekMap() { greekMap = new Dictionary(); From 312a77775dc747eb84624061f0974dfa7dd54cb1 Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Wed, 28 Jan 2015 20:59:22 -0600 Subject: [PATCH 121/446] fixes #522 with new suffixes for BodyTarget --- .../structures/celestial_bodies/body.rst | 10 ++++++ src/kOS/Suffixed/BodyTarget.cs | 32 +++++++++++++++++++ src/kOS/Suffixed/Vector.cs | 1 + 3 files changed, 43 insertions(+) diff --git a/doc/source/structures/celestial_bodies/body.rst b/doc/source/structures/celestial_bodies/body.rst index 343af4669..8897064b7 100644 --- a/doc/source/structures/celestial_bodies/body.rst +++ b/doc/source/structures/celestial_bodies/body.rst @@ -56,6 +56,8 @@ All of the main celestial bodies in the game are reserved variable names. The fo :attr:`MU` scalar (:math:`m^3 s^{−2}`) :attr:`ATM` :struct:`Atmosphere` :attr:`ANGULARVEL` :struct:`Direction` in :ref:`SHIP-RAW ` + :attr:`GEOPOSITIONOF` :struct:`GeoCoordinates` in :ref:`SHIP-RAW ` + :attr:`ALTITUDEOF` scalar (m) ================================ ============ .. attribute:: Body:NAME @@ -96,3 +98,11 @@ All of the main celestial bodies in the game are reserved variable names. The fo Despite the name, this is technically not a velocity. It only tells you the axis of rotation, not the speed of rotation around that axis. +.. attribute:: Body:GEOPOSITIONOF + + The geoposition underneath the given vector position. SHIP:BODY:GEOPOSITIONOF(SHIP:POSITION) should, in principle, give the same thing as SHIP:GEOPOSITION, while SHIP:BODY:GEOPOSITIONOF(SHIP:POSITION + 1000*SHIP:NORTH) would give you the lat/lng of the position 1 kilometer north of you. Be careful not to confuse this with :GEOPOSITION (no "OF" in the name), which is also a suffix of Body by virtue of the fact that Body is an Orbitable, but it doesn't mean the same thing. + +.. attribute:: Body:ALTITUDEOF + + The altitude of the given vector position, above this body's 'sea level'. SHIP:BODY:ALTITUDEOF(SHIP:POSITION) should, in principle, give the same thing as SHIP:ALTITUDE. Example: Eve:ALTITUDEOF(GILLY:POSITION) gives the altitude of gilly's current position above Eve, even if you're not actually anywhere near the SOI of Eve at the time. Be careful not to confuse this with :ALTITUDE (no "OF" in the name), which is also a suffix of Body by virtue of the fact that Body is an Orbitable, but it doesn't mean the same thing. + diff --git a/src/kOS/Suffixed/BodyTarget.cs b/src/kOS/Suffixed/BodyTarget.cs index 2ced3439b..31812047e 100644 --- a/src/kOS/Suffixed/BodyTarget.cs +++ b/src/kOS/Suffixed/BodyTarget.cs @@ -86,6 +86,38 @@ private void BodyInitializeSuffixes() AddSuffix("ROTATIONPERIOD", new Suffix(()=> Body.rotationPeriod)); AddSuffix("ATM", new Suffix(()=> new BodyAtmosphere(Body))); AddSuffix("ANGULARVEL", new Suffix(()=> new Direction(Body.angularVelocity, true))); + AddSuffix("GEOPOSITIONOF", + new OneArgsSuffix( + GeoCoordinatesFromPosition, + "Interpret the vector given as a 3D position, and return the geocoordinates directly underneath it on this body.")); + AddSuffix("ALTITUDEOF", + new OneArgsSuffix( + AltitudeFromPosition, + "Interpret the vector given as a 3D position, and return its altitude above 'sea level' of this body.")); + } + + /// + /// Interpret the vector given as a 3D position, and return the geocoordinates directly underneath it on this body. + /// + /// Vector to use as the 3D position in ship-raw coords + /// The GeoCoordinates under the position. + public GeoCoordinates GeoCoordinatesFromPosition(Vector position) + { + Vector3d unityWorldPosition = Shared.Vessel.findWorldCenterOfMass() + position.ToVector3D(); + double lat = Body.GetLatitude(unityWorldPosition); + double lng = Body.GetLongitude(unityWorldPosition); + return new GeoCoordinates(Body, Shared, lat, lng); + } + + /// + /// Interpret the vector given as a 3D position, and return the altitude above sea level of this body. + /// + /// Vector to use as the 3D position in ship-raw coords + /// The altitude above 'sea level'. + public double AltitudeFromPosition(Vector position) + { + Vector3d unityWorldPosition = Shared.Vessel.findWorldCenterOfMass() + position.ToVector3D(); + return Body.GetAltitude(unityWorldPosition); } public double GetDistance() diff --git a/src/kOS/Suffixed/Vector.cs b/src/kOS/Suffixed/Vector.cs index a2a6e7808..613bfc4c8 100644 --- a/src/kOS/Suffixed/Vector.cs +++ b/src/kOS/Suffixed/Vector.cs @@ -1,5 +1,6 @@ using System; using kOS.Safe.Encapsulation; +using kOS.Safe.Encapsulation.Suffixes; using UnityEngine; namespace kOS.Suffixed From ff60fdc6729c4e192d32a560e07bc86f5898165e Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Sat, 31 Jan 2015 05:20:12 -0600 Subject: [PATCH 122/446] Fixes #536 just moving the attachment point. --- Resources/GameData/kOS/Parts/kOSMachine1m/part.cfg | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Resources/GameData/kOS/Parts/kOSMachine1m/part.cfg b/Resources/GameData/kOS/Parts/kOSMachine1m/part.cfg index 85a3af7da..fa8a0c5bd 100644 --- a/Resources/GameData/kOS/Parts/kOSMachine1m/part.cfg +++ b/Resources/GameData/kOS/Parts/kOSMachine1m/part.cfg @@ -13,8 +13,8 @@ iconCenter = 0, 3, 0 // --- node definitions --- node_attach = 0.0, 0.0, 0.0, 0.0, -1.0, 0.0 -node_stack_bottom = 0.0, -0.14, 0.0, 0.0, -1.0, 0.0 -node_stack_top = 0.0, 0.14, 0.0, 0.0, 1.0, 0.0 +node_stack_bottom = 0.0, -0.173, 0.0, 0.0, -1.0, 0.0 +node_stack_top = 0.0, 0.173, 0.0, 0.0, 1.0, 0.0 // --- Tech tree --- TechRequired = flightControl From 34046b407371804d5749c706323d6ba003f8ee29 Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Wed, 4 Feb 2015 00:50:59 -0600 Subject: [PATCH 123/446] While I was at it I also ensured that sun's parent is always returned as null instead of looping back to itself like it does in the KSP API. --- doc/source/structures/orbits/orbitable.rst | 26 ++++++++++++- src/kOS/Suffixed/BodyTarget.cs | 31 +++++++++++----- src/kOS/Suffixed/Orbitable.cs | 14 ++++--- src/kOS/Suffixed/OrbitableVelocity.cs | 11 +++--- src/kOS/Utilities/Utils.cs | 43 ++++++++++++++++++++++ 5 files changed, 104 insertions(+), 21 deletions(-) diff --git a/doc/source/structures/orbits/orbitable.rst b/doc/source/structures/orbits/orbitable.rst index e7a42620e..3a887465f 100644 --- a/doc/source/structures/orbits/orbitable.rst +++ b/doc/source/structures/orbits/orbitable.rst @@ -20,6 +20,9 @@ All objects that can move in orbit around other objects share some similar struc ======================= ============== :attr:`NAME` string :attr:`BODY` :struct:`Body` + :attr:`HASBODY` boolean + :attr:`HASORBIT` boolean + :attr:`HASOBT` boolean :attr:`OBT` :struct:`Orbit` :attr:`UP` :struct:`Direction` :attr:`NORTH` :struct:`Direction` @@ -37,7 +40,7 @@ All objects that can move in orbit around other objects share some similar struc :attr:`GEOPOSITION` :struct:`GeoCoordinates` :attr:`PATCHES` :struct:`List` of :struct:`Orbits ` ----------------------- -------------- - The Following are deprecated (use :attr:`OBT`) + The Following are deprecated (use apoapsis and periapsis on :attr:`OBT`) -------------------------------------- :attr:`APOAPSIS` scalar (m) :attr:`PERIAPSIS` scalar (m) @@ -51,6 +54,27 @@ All objects that can move in orbit around other objects share some similar struc Name of this vessel or body. +.. attribute:: Orbitable:HASBODY + + :type: boolean + :access: Get only + + True if this object has a body it orbits (false only when this object is the Sun, pretty much). + +.. attribute:: Orbitable:HASORBIT + + :type: boolean + :access: Get only + + Alias for HASBODY. + +.. attribute:: Orbitable:HASOBT + + :type: boolean + :access: Get only + + Alias for HASBODY. + .. attribute:: Orbitable:BODY :type: :struct:`Body` diff --git a/src/kOS/Suffixed/BodyTarget.cs b/src/kOS/Suffixed/BodyTarget.cs index 2ced3439b..84ca484d2 100644 --- a/src/kOS/Suffixed/BodyTarget.cs +++ b/src/kOS/Suffixed/BodyTarget.cs @@ -23,7 +23,7 @@ override public Vector GetPosition() override public OrbitableVelocity GetVelocities() { - return new OrbitableVelocity(Body); + return new OrbitableVelocity(Body,Shared); } override public Vector GetPositionAtUT( TimeSpan timeStamp ) @@ -33,15 +33,26 @@ override public Vector GetPositionAtUT( TimeSpan timeStamp ) override public OrbitableVelocity GetVelocitiesAtUT( TimeSpan timeStamp ) { - var orbVel = new Vector( Orbit.getOrbitalVelocityAtUT( timeStamp.ToUnixStyleTime() ) ); - orbVel = new Vector(orbVel.X,orbVel.Z,orbVel.Y); // swap Y and Z because KSP API is weird. + CelestialBody parent = Body.KOSExtensionGetParentBody(); + if (parent==null) // only if Body is Sun and therefore has no parent, then do more complex work instead because KSP didn't provide a way itself + { + Vector3d futureOrbitalVel; + CelestialBody soiBody = Shared.Vessel.mainBody; + if (soiBody.orbit != null) + futureOrbitalVel = soiBody.orbit.GetFrameVelAtUT(timeStamp.ToUnixStyleTime()); + else + futureOrbitalVel = (-1)*(new VesselTarget(Shared.Vessel,Shared).GetVelocitiesAtUT(timeStamp).Orbital.ToVector3D()); + return new OrbitableVelocity( new Vector(futureOrbitalVel), new Vector(0.0,0.0,0.0) ); + } + else + { + var orbVel = new Vector( Orbit.getOrbitalVelocityAtUT( timeStamp.ToUnixStyleTime() ) ); + orbVel = new Vector(orbVel.X,orbVel.Z,orbVel.Y); // swap Y and Z because KSP API is weird. - CelestialBody parent = Body.referenceBody; - if (parent==null) // only if Body is Sun and therefore has no parent. - return new OrbitableVelocity( new Vector(0.0,0.0,0.0), new Vector(0.0,0.0,0.0) ); - var surfVel = new Vector( Body.orbit.GetVel() - parent.getRFrmVel( Body.position ) ); + var surfVel = new Vector( Body.orbit.GetVel() - parent.getRFrmVel( Body.position ) ); - return new OrbitableVelocity( orbVel, surfVel ); + return new OrbitableVelocity( orbVel, surfVel ); + } } override public Orbit GetOrbitAtUT(double desiredUT) @@ -51,7 +62,7 @@ override public Orbit GetOrbitAtUT(double desiredUT) override public Vector GetUpVector() { - CelestialBody parent = Body.referenceBody; + CelestialBody parent = Body.KOSExtensionGetParentBody(); if (parent==null) // only if Body is Sun and therefore has no parent. return new Vector(0.0,0.0,0.0); return new Vector( (Body.position - parent.position).normalized ); @@ -59,7 +70,7 @@ override public Vector GetUpVector() override public Vector GetNorthVector() { - CelestialBody parent = Body.referenceBody ?? Body; + CelestialBody parent = Body.KOSExtensionGetParentBody() ?? Body; return new Vector( Vector3d.Exclude(GetUpVector(), parent.transform.up) ); } diff --git a/src/kOS/Suffixed/Orbitable.cs b/src/kOS/Suffixed/Orbitable.cs index e62cf9ecf..b84b0099f 100644 --- a/src/kOS/Suffixed/Orbitable.cs +++ b/src/kOS/Suffixed/Orbitable.cs @@ -135,7 +135,7 @@ public Orbit GetOrbit() public CelestialBody GetParentBody() { - return Orbit.referenceBody; + return (Orbit == null) ? null : Orbit.referenceBody; } public Direction GetPrograde() @@ -180,7 +180,7 @@ public Direction GetSurfaceRetrograde() public double PositionToLatitude( Vector pos ) { - CelestialBody parent = Orbit.referenceBody; + CelestialBody parent = GetParentBody(); if (parent == null) //happens when this Orbitable is the Sun return 0.0; Vector3d unityWorldPos = GetPosition() + (Vector3d)Shared.Vessel.findWorldCenterOfMass(); @@ -188,7 +188,7 @@ public double PositionToLatitude( Vector pos ) } public double PositionToLongitude( Vector pos ) { - CelestialBody parent = Orbit.referenceBody; + CelestialBody parent = GetParentBody(); if (parent == null) //happens when this Orbitable is the Sun return 0.0; Vector3d unityWorldPos = GetPosition() + (Vector3d)Shared.Vessel.findWorldCenterOfMass(); @@ -196,7 +196,7 @@ public double PositionToLongitude( Vector pos ) } public double PositionToAltitude( Vector pos ) { - CelestialBody parent = Orbit.referenceBody; + CelestialBody parent = GetParentBody(); if (parent == null) //happens when this Orbitable is the Sun return 0.0; Vector3d unityWorldPos = GetPosition() + (Vector3d)Shared.Vessel.findWorldCenterOfMass(); @@ -244,7 +244,11 @@ public object GetOnlyOrbitableSuffixes( string suffixName ) // The cases after this point were added to Orbitable from either VesselTarget or BodyTarget: case "BODY": - return new BodyTarget(Orbit.referenceBody, Shared); + return new BodyTarget(GetParentBody(), Shared); + case "HASBODY": + case "HASOBT": + case "HASORBIT": + return (Orbit != null); case "UP": return new Direction(GetUpVector(), false); case "NORTH": diff --git a/src/kOS/Suffixed/OrbitableVelocity.cs b/src/kOS/Suffixed/OrbitableVelocity.cs index b9c622238..a94520ffe 100644 --- a/src/kOS/Suffixed/OrbitableVelocity.cs +++ b/src/kOS/Suffixed/OrbitableVelocity.cs @@ -1,4 +1,5 @@ using kOS.Safe.Encapsulation; +using kOS.Utilities; namespace kOS.Suffixed { @@ -19,13 +20,13 @@ public OrbitableVelocity(Vessel v) Surface = new Vector(v.srf_velocity); } - public OrbitableVelocity(CelestialBody b) + public OrbitableVelocity(CelestialBody b, SharedObjects shared) { - Orbital = new Vector(b.orbit.GetVel()); // KSP's b.GetObtVelocity() is broken - it causes stack overflow - CelestialBody parent = b.referenceBody; - Surface = parent != null ? + Orbital = new Vector(b.KOSExtensionGetObtVelocity(shared)); // KSP's b.GetObtVelocity() is broken - it causes stack overflow + CelestialBody parent = b.KOSExtensionGetParentBody(); + Surface = (parent != null) ? new Vector(b.orbit.GetVel() - parent.getRFrmVel(b.position)) : - new Vector(default(float), default(float), default(float)); + new Vector(Vector3d.zero); } /// diff --git a/src/kOS/Utilities/Utils.cs b/src/kOS/Utilities/Utils.cs index a5ee3a8c7..7073da4ef 100644 --- a/src/kOS/Utilities/Utils.cs +++ b/src/kOS/Utilities/Utils.cs @@ -247,5 +247,48 @@ public static string GetCodeFragment(List codes) return codeFragment.Aggregate(string.Empty, (current, s) => current + (s + "\n")); } + + /// + /// Meant to be an override for stock KSP's CelestialBody.GetObtVelocity(), which (literally) always + /// stack overflows because it's implemented as just infinite recursion without a base case. + ///
+ /// Returns the celestial body's velocity relative to the current universe's SOI body. It's + /// identical to body.orbit.GetVel() except that it also works for The Sun, which + /// normally can't call that because it's orbit is null. + ///
+ /// The body to get the value for. (this will be hidden when this is an extension method of CelestialBody). + /// body position in current unity world coords + public static Vector3d KOSExtensionGetObtVelocity(this CelestialBody body, SharedObjects shared) + { + if (body.orbit != null) + return body.orbit.GetVel(); + + // When we can't use body.orbit, then manually perform the work that (probably) body.orbit.GetVel() + // is doing itself. This isn't DRY, but SQUAD made it impossible to be DRY when they didn't implement + // the algorithm for the Sun so we have to repeat it again ourselves: + + CelestialBody soiBody = shared.Vessel.mainBody; + if (soiBody.orbit != null) + return soiBody.orbit.GetFrameVel(); + else + return (-1)*shared.Vessel.obt_velocity; + } + + /// + /// Return the parent body of this body, just like KSP's built-in referenceBody, except that + /// it exhibits more sane behavior in the case of the Sun where there is no parent. Default + /// KSP's referenceBody will sometimes return null and sometimes return the Sun itself as + /// the parent of the Sun. This makes it always return null as the parent of the Sun no matter + /// what. + /// + /// Body to get parent of (this will be hidden when called as an extension method) + /// parent body or null + public static CelestialBody KOSExtensionGetParentBody(this CelestialBody body) + { + CelestialBody parent = body.referenceBody; + if (parent == body) + parent = null; + return parent; + } } } \ No newline at end of file From 90add57f72bc06c1f5ca58b44e0b131225d612ac Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Wed, 4 Feb 2015 12:10:33 -0600 Subject: [PATCH 124/446] fixes 544 this was a lot easier than I expected. a one line fix. --- src/kOS/Screen/Interpreter.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/kOS/Screen/Interpreter.cs b/src/kOS/Screen/Interpreter.cs index 721770eeb..0829130a5 100644 --- a/src/kOS/Screen/Interpreter.cs +++ b/src/kOS/Screen/Interpreter.cs @@ -94,6 +94,7 @@ private void ShowCommandHistoryEntry(int deltaIndex) LineBuilder = new StringBuilder(); LineBuilder.Append(commandHistory[commandHistoryIndex]); LineCursorIndex = LineBuilder.Length; + LineSubBuffer.Wipe(); UpdateLineSubBuffer(); } } From afa7032d3b3eb826a93514c4b532ad4d57705c9a Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Wed, 4 Feb 2015 13:56:06 -0600 Subject: [PATCH 125/446] fixes #545 - invisible cursor The problem was that ShowCursor is normally set to true only when calling the interpreter's SetInputLock(), which never gets called the first time a new terminal is made, and only gets called when input focus switches windows. (So to make the cursor appear you had to switch between two windows). Now it calls it up front any time the window gets focus, even the first time. --- src/kOS/Screen/TermWindow.cs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/kOS/Screen/TermWindow.cs b/src/kOS/Screen/TermWindow.cs index 0b26ebd46..282dc311f 100644 --- a/src/kOS/Screen/TermWindow.cs +++ b/src/kOS/Screen/TermWindow.cs @@ -43,6 +43,7 @@ public class TermWindow : KOSManagedWindow , ITermWindow private SharedObjects shared; private KOSTextEditPopup popupEditor; + private Color currentTextColor = new Color(1,1,1,1); // a dummy color at first just so it won't crash before TerminalGUI() where it's *really* set. public TermWindow() @@ -111,6 +112,7 @@ private void Lock() if (isLocked) return; isLocked = true; + ShowCursor = true; BringToFront(); cameraManager = CameraManager.Instance; @@ -154,6 +156,12 @@ private void Unlock() GameSettings.THROTTLE_CUTOFF = rememberThrottleCutoffKey; if (rememberThrottleFullKey != null) GameSettings.THROTTLE_FULL = rememberThrottleFullKey; + + // Ensure that when the terminal is unfocused, it always reliably leaves the cursor frozen + // in the display as visible, instead of leaving it frozen as invisible. (Without this, then + // it will freeze at whatever blink state it was in at the moment the terminal was unfocussed. + // half the time it would be visible, half the time invisible.) + ShowCharacterByAscii((char)1, shared.Screen.CursorColumnShow, shared.Screen.CursorRowShow, currentTextColor); } void OnGUI() @@ -350,7 +358,6 @@ void TerminalGui(int windowId) } - Color currentTextColor; if (IsPowered) { currentTextColor = isLocked ? textColor : textColorAlpha; @@ -378,6 +385,7 @@ void TerminalGui(int windowId) screen.CursorRowShow < screen.RowCount && IsPowered && ShowCursor; + if (blinkOn) { ShowCharacterByAscii((char)1, screen.CursorColumnShow, screen.CursorRowShow, currentTextColor); From 58c08165bbfe0712697e56e962845bac306a3dde Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Fri, 6 Feb 2015 17:38:30 -0600 Subject: [PATCH 126/446] telnet Input side done, output side not done. --- src/kOS.Safe/Screen/IInterpreter.cs | 1 + src/kOS/Module/kOSProcessor.cs | 12 + src/kOS/Screen/Interpreter.cs | 9 + src/kOS/Screen/TermWindow.cs | 176 ++++++- src/kOS/Suffixed/Config.cs | 2 +- src/kOS/UserIO/TelnetMainServer.cs | 15 +- src/kOS/UserIO/TelnetSingletonServer.cs | 591 ++++++++++++++++++++---- src/kOS/UserIO/TelnetWelcomeMenu.cs | 36 +- src/kOS/UserIO/TerminalAnsiMapper.cs | 19 + src/kOS/UserIO/TerminalUnicodeMapper.cs | 189 ++++++++ src/kOS/UserIO/TerminalVT100Mapper.cs | 100 ++++ src/kOS/UserIO/TerminalXtermMapper.cs | 169 +++++++ src/kOS/UserIO/UnicodeCommand.cs | 182 ++++++++ src/kOS/kOS.csproj | 5 + 14 files changed, 1391 insertions(+), 115 deletions(-) create mode 100644 src/kOS/UserIO/TerminalAnsiMapper.cs create mode 100644 src/kOS/UserIO/TerminalUnicodeMapper.cs create mode 100644 src/kOS/UserIO/TerminalVT100Mapper.cs create mode 100644 src/kOS/UserIO/TerminalXtermMapper.cs create mode 100644 src/kOS/UserIO/UnicodeCommand.cs diff --git a/src/kOS.Safe/Screen/IInterpreter.cs b/src/kOS.Safe/Screen/IInterpreter.cs index 9b66e3cd0..29ca4513f 100644 --- a/src/kOS.Safe/Screen/IInterpreter.cs +++ b/src/kOS.Safe/Screen/IInterpreter.cs @@ -8,6 +8,7 @@ public interface IInterpreter : IScreenBuffer void SpecialKey(kOSKeys key); string GetCommandHistoryAbsolute(int absoluteIndex); void SetInputLock(bool isLocked); + bool IsAtStartOfCommand(); void Reset(); } } \ No newline at end of file diff --git a/src/kOS/Module/kOSProcessor.cs b/src/kOS/Module/kOSProcessor.cs index 62ca410c3..7d79d478d 100644 --- a/src/kOS/Module/kOSProcessor.cs +++ b/src/kOS/Module/kOSProcessor.cs @@ -15,6 +15,7 @@ using kOS.Safe.Compilation; using kOS.Safe.Compilation.KS; using kOS.Safe.Module; +using kOS.Safe.Screen; using kOS.Suffixed; using kOS.AddOns.RemoteTech2; @@ -110,6 +111,17 @@ public bool WindowIsOpen() { return shared.Window.IsOpen(); } + + public IScreenBuffer GetScreen() + { + return shared.Screen; + } + + public kOS.Screen.TermWindow GetWindow() + // TODO - later refactor making this kOS.Safer so it can work on ITermWindow, which also means moving all of UserIO's classes too. + { + return shared.Window; + } public override void OnStart(StartState state) { diff --git a/src/kOS/Screen/Interpreter.cs b/src/kOS/Screen/Interpreter.cs index 0829130a5..8c95e71b2 100644 --- a/src/kOS/Screen/Interpreter.cs +++ b/src/kOS/Screen/Interpreter.cs @@ -41,6 +41,15 @@ protected override void NewLine() InsertChar('\n'); } } + + /// + /// Detect if the interpreter happens to be right at the start of a new command line. + /// + /// true if it's at the start of a new line + public bool IsAtStartOfCommand() + { + return LineBuilder == null || LineBuilder.Length == 0; + } public override void Type(char ch) { diff --git a/src/kOS/Screen/TermWindow.cs b/src/kOS/Screen/TermWindow.cs index 282dc311f..5b760719a 100644 --- a/src/kOS/Screen/TermWindow.cs +++ b/src/kOS/Screen/TermWindow.cs @@ -6,6 +6,7 @@ using kOS.Safe.Screen; using kOS.Safe.Utilities; using kOS.Module; +using kOS.UserIO; namespace kOS.Screen { @@ -45,11 +46,18 @@ public class TermWindow : KOSManagedWindow , ITermWindow private KOSTextEditPopup popupEditor; private Color currentTextColor = new Color(1,1,1,1); // a dummy color at first just so it won't crash before TerminalGUI() where it's *really* set. + private List Telnets {get;set;} // support exists for more than one telnet client to be attached to the same terminal, thus this is a list. + + private ExpectNextChar inputExpected = ExpectNextChar.NORMAL; + private int pendingWidth; // width to come from a resize combo. + + public string TitleText {get; private set;} public TermWindow() { IsPowered = true; windowRect = new Rect(50, 60, 0, 0); // will get resized later in AttachTo(). + Telnets = new List(); } public bool ShowCursor { get; set; } @@ -184,13 +192,9 @@ void OnGUI() // Should probably make "gui screen name for my CPU part" into some sort of utility method: KOSNameTag partTag = shared.KSPPart.Modules.OfType().FirstOrDefault(); - string labelText = String.Format("{0} CPU: {1} ({2})", - shared.Vessel.vesselName, - shared.KSPPart.partInfo.title.Split(' ')[0], // just the first word of the name, i.e "CX-4181" - ((partTag==null) ? "" : partTag.nameTag) - ); + ChangeTitle(CalcualteTitle()); - windowRect = GUI.Window(uniqueId, windowRect, TerminalGui, labelText); + windowRect = GUI.Window(uniqueId, windowRect, TerminalGui, TitleText); if (consumeEvent) { @@ -207,6 +211,7 @@ void Update() // Holding onto a vessel instance that no longer exists? Close(); } + ProcessTelnetInput(); // want to do this even when the terminal isn't actually displaying. if (!IsOpen() ) return; @@ -220,6 +225,10 @@ void Update() void ProcessKeyStrokes() { + // TODO - switch this to instead send input through ProcessOneInputChar() once + // ProcessOneInputChar() is better fleshed out with all these keycodes. + // + Event e = Event.current; if (e.type == EventType.KeyDown) { @@ -234,7 +243,7 @@ void ProcessKeyStrokes() consumeEvent = true; return; } - if (e.keyCode == KeyCode.X && e.control && e.shift) // Ctrl+Shift+X + if (e.keyCode == KeyCode.X && e.control && e.shift) // Ctrl+Shift+X - TODO: Change to support sending control-D too. { Close(); consumeEvent = true; @@ -255,6 +264,111 @@ void ProcessKeyStrokes() cursorBlinkTime = 0.0f; } } + + /// + /// Read all pending input from all telnet clients attached and process it all. + /// Hopefully this won't bog down anything, as we don't expect to get lots + /// of chars at once from keyboard input in a single update. The amount of + /// characters pending in the queues should be very small since this is flushing it out + /// every update. It could potentially be large if someone does a big cut-n-paste + /// into their terminal window and their telnet client therefore sends a wall of + /// text within the span of one Update(). Premature optimization is bad, so we'll + /// wait to see if that is a problem later. + /// + private void ProcessTelnetInput() + { + foreach (TelnetSingletonServer telnet in Telnets) + { + while (telnet.InputWaiting()) + { + System.Console.WriteLine("eraseme:ProcessTelnetInput: now calling ProcessOneInputChar, with telnet = " + (telnet==null ? "null" : "NOT null")); + ProcessOneInputChar(telnet.ReadChar(), telnet); + } + } + } + + /// + /// Respond to one single input character in unicode, using the pretend + /// virtual unicode terminal keycodes described in the UnicodeCommand enum. + /// To keep things simple, all key input is coerced into single unicode chars + /// even if the actual keypress takes multiple characters to express in its + /// native form (i.e. ESC [ A means left-arrow on a VT100 terminal. If + /// a telnet is talking via VT100 codes, that ESC [ A will get converted into + /// a single UnicdeCommand.LEFTCURSORONE character before being sent here.) + ///
+ /// This method is public because it is also how other mods should send input + /// to the terminal if they want some other soruce to send simulated keystrokes. + ///
+ /// The character, which might be a UnicodeCommand char + /// If this came from a telnet session, which one did it come from? + /// Set to null in order to say it wasn't from a telnet but was from the interactive GUI + public void ProcessOneInputChar(char ch, TelnetSingletonServer whichTelnet) + { + System.Console.WriteLine("eraseme:ProcessOneInputChar( "+(char)ch+", "+ (whichTelnet==null ? "null" : "NOT null") + ")"); + // Weird exceptions for multi-char data combos that would have been begun on previous calls to this method + switch (inputExpected) + { + case ExpectNextChar.RESIZEWIDTH: + pendingWidth = (int)ch; + inputExpected = ExpectNextChar.RESIZEHEIGHT; + return; + case ExpectNextChar.RESIZEHEIGHT: + int height = (int)ch; + shared.Screen.SetSize(height, pendingWidth); + inputExpected = ExpectNextChar.NORMAL; + return; + default: + break; + } + + // Printable ascii section of unicode - the common vanila situation + // (Idea: Since this is all unicode anyway, should we allow a wider range to + // include multi-language accent characters and so on? Answer: to do so we'd + // first need to expand the font pictures in the fontimage file, so it's a + // bigger task than it may first seem.) + if (0x0020 <= ch && ch <= 0x007f) + { + Type(ch); + } + else + { + switch(ch) + { + case (char)UnicodeCommand.BREAK: Keydown(KeyCode.Break); break; + case (char)UnicodeCommand.DELETELEFT: Keydown(KeyCode.Backspace); break; + case (char)UnicodeCommand.DELETERIGHT: Keydown(KeyCode.Delete); break; + case (char)UnicodeCommand.NEWLINERETURN: Keydown(KeyCode.Return); break; + case (char)UnicodeCommand.UPCURSORONE: Keydown(KeyCode.UpArrow); break; + case (char)UnicodeCommand.DOWNCURSORONE: Keydown(KeyCode.DownArrow); break; + case (char)UnicodeCommand.LEFTCURSORONE: Keydown(KeyCode.LeftArrow); break; + case (char)UnicodeCommand.RIGHTCURSORONE: Keydown(KeyCode.RightArrow); break; + case (char)UnicodeCommand.HOMECURSOR: Keydown(KeyCode.Home); break; + case (char)UnicodeCommand.ENDCURSOR: Keydown(KeyCode.End); break; + case (char)UnicodeCommand.PAGEUPCURSOR: Keydown(KeyCode.PageUp); break; + case (char)UnicodeCommand.PAGEDOWNCURSOR: Keydown(KeyCode.PageDown); break; + // TODO - fill in the rest of the chars. + case (char)UnicodeCommand.RESIZESCREEN: inputExpected = ExpectNextChar.RESIZEWIDTH; break; // next expected char is the width. + + case (char)0x04/*control-D*/: + if (shared.Interpreter.IsAtStartOfCommand()) + { + if (whichTelnet == null) + { + System.Console.WriteLine("eraseme:ProcessOneInputChar: in whichTelnet=null condition."); + Close(); + } + else + { + System.Console.WriteLine("eraseme:ProcessOneInputChar: in whichTelnet=NOT null condition."); + whichTelnet.DisconnectFromProcessor(); + } + } + break; + } + } + + // else ignore it - unimplemented char. + } private void Keydown(KeyCode code) { @@ -460,14 +574,62 @@ internal void AttachTo(SharedObjects shared) this.shared.Window = this; NotifyOfScreenResize(this.shared.Screen); this.shared.Screen.AddResizeNotifier(NotifyOfScreenResize); + ChangeTitle(CalcualteTitle()); + } + + internal string CalcualteTitle() + { + KOSNameTag partTag = shared.KSPPart.Modules.OfType().FirstOrDefault(); + return String.Format("{0} CPU: {1} ({2})", + shared.Vessel.vesselName, + shared.KSPPart.partInfo.title.Split(' ')[0], // just the first word of the name, i.e "CX-4181" + ((partTag==null) ? "" : partTag.nameTag) + ); + } + + internal void AttachTelnet(TelnetSingletonServer server) + { + Telnets.AddUnique(server); + } + + internal void DetachTelnet(TelnetSingletonServer server) + { + Telnets.Remove(server); } internal int NotifyOfScreenResize(IScreenBuffer sb) { windowRect = new Rect(windowRect.xMin, windowRect.yMin, sb.ColumnCount*CHARSIZE + 65, sb.RowCount*CHARSIZE + 100); + + // Make all the connected telnet clients resize themselves to match: + string resizeCmd = new string( new [] {(char)UnicodeCommand.RESIZESCREEN, (char)sb.ColumnCount, (char)sb.RowCount} ); + foreach (TelnetSingletonServer telnet in Telnets) + telnet.Write(resizeCmd); return 0; } + internal void ChangeTitle(string newTitle) + { + if (TitleText != newTitle) // For once, a direct simple reference-equals is really what we want. Immutable strings should make this work quickly. + { + TitleText = newTitle; + foreach (TelnetSingletonServer telnet in Telnets) + SendTitleToTelnet(telnet); + } + } + + internal void SendTitleToTelnet(TelnetSingletonServer telnet) + { + // Make the telnet client learn about the new title: + string changeTitleCmd = String.Format("{0}{1}{2}", + (char)UnicodeCommand.TITLEBEGIN, + TitleText, + (char)UnicodeCommand.TITLEEND); + System.Console.WriteLine("eraseme: debug: sendTitleToTelnet is sending this:"); + for (int i=0; i @@ -42,48 +47,68 @@ public class TelnetSingletonServer : MonoBehaviour public kOSProcessor ConnectedProcessor { get; private set; } - private byte[] rawReadBuffer = new byte[128]; // use small chunks - private byte[] rawWriteBuffer = new byte[128]; // use small chunks + private byte[] rawReadBuffer = new byte[4096]; + private byte[] rawWriteBuffer = new byte[4096]; private Thread inThread; private Thread outThread; private TelnetWelcomeMenu welcomeMenu; + + private TerminalUnicodeMapper terminalMapper; + + private bool isLineAtATime; + private bool allowResize; - // ReSharper enable RedundantDefaultFieldInitializer - // ReSharper enable SuggestUseVarKeywordEvident + public int ClientWidth {get; private set;} + public int ClientHeight {get; private set;} + + private string termTypeBackingField; // This is deliberately NOT named as just a lower-case version of ClientTerminalType, + // so as to prevent accidentally typing this name instead of the property. It's essential + // that all the access even inside this class itself, be done via the property to + // force it to keep the terminalMapper updated to match. + public string ClientTerminalType + { + get{ return termTypeBackingField;} + private set{ termTypeBackingField = value; terminalMapper = TerminalUnicodeMapper.TerminalMapperFactory(value); } + } // Special telnet protocol bytes with magic meaning, taken from interet RFC's: // Many of these will go unused at first, but it's important to get them down for future - // embetterment. Uncomment them if you start needing to use one. + // embetterment. + // + // For documentation on how these telnet controls work, and how they're expected + // to be passed back and forth, do an internet search based on the RFC number of the + // constant (i.e. to see how the byte code RFC854_IAC is used, go look up "RFC 854" on + // the internet and look at what it says about a byte code called "IAC".) - private const byte RFC854_SE = 240; // End of subnegotiation parameters. - private const byte RFC854_NOP = 241; // No operation. - private const byte RFC854_DATAMARK = 242; // The data stream portion of a Synch. + private const byte RFC854_SE = 240; // End of subnegotiation parameters. + private const byte RFC854_NOP = 241; // No operation. + private const byte RFC854_DATAMARK = 242; // The data stream portion of a Synch. // This should always be accompanied // by a TCP Urgent notification. - private const byte RFC854_BREAK = 243; // NVT character BRK. - private const byte RFC854_IP = 244; // The function IP. - private const byte RFC854_AO = 245; // The function AO. - private const byte RFC854_AYT = 246; // The function AYT. - private const byte RFC854_EC = 247; // The function EC. - private const byte RFC854_EL = 248; // The function EL. - private const byte RFC864_GA = 249; // The GA signal. - private const byte RFC854_SB = 250; // Indicates that what follows is - // subnegotiation of the indicated - // option. - private const byte RFC854_WILL = 251; // Indicates the desire to begin - // performing, or confirmation that - // you are now performing, the - // indicated option. - private const byte RFC854_WONT = 252; // Indicates the refusal to perform, - // or continue performing, the - // indicated option. - private const byte RFC854_DO = 253; // Indicates the request that the - // other party perform, or - // confirmation that you are expecting - // the other party to perform, the - // indicated option. + private const byte RFC854_BREAK = 243; // NVT character BRK. + private const byte RFC854_IP = 244; // The function IP. + private const byte RFC854_AO = 245; // The function AO. + private const byte RFC854_AYT = 246; // The function AYT. + private const byte RFC854_EC = 247; // The function EC. + private const byte RFC854_EL = 248; // The function EL. + private const byte RFC864_GA = 249; // The GA signal. + private const byte RFC854_SB = 250; // Indicates that what follows is + // subnegotiation of the indicated + // option. + private const byte RFC854_WILL = 251; // Indicates the desire to begin + // performing, or confirmation that + // you are now performing, the + // indicated option. + private const byte RFC854_WONT = 252; // Indicates the refusal to perform, + // or continue performing, the + // indicated option. + private const byte RFC854_DO = 253; // Indicates the request that the + // other party perform, or + // confirmation that you are expecting + // the other party to perform, the + // indicated option. private const byte RFC854_DONT = 254; // Indicates the demand that the // other party stop performing, // or confirmation that you are no @@ -103,6 +128,11 @@ public class TelnetSingletonServer : MonoBehaviour private const byte RFC1184_SOFT_TAB = 8; private const byte RFC1184_LIT_ECHO = 16; + private const byte RFC1091_TERMTYPE = 24; + private const byte RFC1091_IS = 0; + private const byte RFC1091_SEND = 1; + + private const byte RFC1073_NAWS = 31; public TelnetSingletonServer(TcpClient client) { @@ -112,13 +142,33 @@ public TelnetSingletonServer(TcpClient client) outThread = new Thread(DoOutThread); outQueue = new Queue(); inQueue = new Queue(); + ClientWidth = 80; // common default for a lot of terminal progs. Will allow resize via RFC1073. + ClientHeight = 24; // common default for a lot of terminal progs. Will allow resize via RFC1073. + ClientTerminalType = "UNKNOWN"; // will be set by telnet client as described by RFC 1091 } - + + /// + /// Connect this TelnetSingletonServer to a CPU to start acting as its terminal. + /// + /// The kOSProcessor PartModule to attach to public void ConnectToProcessor(kOSProcessor processor) { ConnectedProcessor = processor; - // TODO: Write the part of the mod that listens to this telnet inside termwindow, and at this point - // tell it to connect to this telnet server. + ConnectedProcessor.GetScreen().SetSize(ClientHeight, ClientWidth); + ConnectedProcessor.GetWindow().AttachTelnet(this); + ConnectedProcessor.GetWindow().SendTitleToTelnet(this); + } + + public void DisconnectFromProcessor() + { + if (ConnectedProcessor != null) + { + string detachMessage = "Detaching from " + ConnectedProcessor.GetWindow().TitleText; + SendTextRaw( (char)UnicodeCommand.TITLEBEGIN + detachMessage + (char)UnicodeCommand.TITLEEND ); + SendTextRaw("\r\n{" + detachMessage + "}\r\n"); + ConnectedProcessor.GetWindow().DetachTelnet(this); + ConnectedProcessor = null; + } } /// @@ -129,7 +179,12 @@ public void ConnectToProcessor(kOSProcessor processor) /// one character read public char ReadChar() { - return inQueue.Dequeue(); + char ch; + lock (inQueue) // all access to inQueue and outQueue needs to be atomic. + { + ch = inQueue.Dequeue(); + } + return ch; } /// @@ -139,11 +194,12 @@ public char ReadChar() /// All currently available input characters returned in one string. public string ReadAll() { - if (inQueue.Count == 0) - return String.Empty; StringBuilder sb = new StringBuilder(); - while (inQueue.Count > 0) - sb.Append(inQueue.Dequeue()); + lock (inQueue) // all access to inQueue and outQueue needs to be atomic. + { + while (inQueue.Count > 0) + sb.Append(inQueue.Dequeue()); + } return sb.ToString(); } @@ -152,28 +208,64 @@ public string ReadAll() /// true if input is currently Queued public bool InputWaiting() { - return inQueue.Count > 0; + bool returnVal; + lock (inQueue) + { + returnVal = inQueue.Count > 0; + } + return returnVal; } /// - /// Write one character out to the telnet client. - /// character to write + /// Write a character out to the telnet client. You can pretend the telnet client is a + /// psuedo-terminal that understands the command codes in UnicodeCommand. + ///
+ /// This TelnetSingletonServer will run what you give it through a command code + /// mapper for whichever terminal type is actually attached to the telnet client. + ///
+ /// Remember that when sending strings to this method, end-of-lines need + /// to be expressed as "\r\n", because you are writing using the raw internet + /// ASCII standard. ///
+ /// character to write public void Write(char ch) { - rawStream.Write(Encoding.UTF8.GetBytes(new String(ch,1)),0,1); + lock(outQueue) // all access to inQueue and outQueue needs to be atomic. + { + outQueue.Enqueue(ch); + } } /// - /// Write a string out to the telnet client. - /// string to write + /// Write a string out to the telnet client. You can pretend the telnet client is a + /// psuedo-terminal that understands the command codes in UnicodeCommand. + ///
+ /// This TelnetSingletonServer will run what you give it through a command code + /// mapper for whichever terminal type is actually attached to the telnet client. + ///
+ /// Remember that when sending strings to this method, end-of-lines need + /// to be expressed as "\r\n", because you are writing using the raw internet + /// ASCII standard. ///
+ /// string to write public void Write(string str) { - byte[] buf = Encoding.UTF8.GetBytes(str); - rawStream.Write(buf,0,buf.Length); + lock(outQueue) // all access to inQueue and outQueue needs to be atomic. + { + foreach (char ch in str) + outQueue.Enqueue(ch); + } } + /// + /// Bypasses the Queues and just sends text directly to the socket stream. + /// + /// + private void SendTextRaw(char[] buff) + { + SendTextRaw(new string(buff)); + } + /// /// Bypasses the Queues and just sends text directly to the socket stream. /// @@ -181,50 +273,101 @@ public void Write(string str) private void SendTextRaw(string str) { byte[] outBuff = System.Text.Encoding.UTF8.GetBytes(str); - rawStream.Write(outBuff, 0, outBuff.Length); + SendTextRaw(outBuff); + } + + /// + /// Bypasses the Queues and just sends text directly to the socket stream. + /// + /// + private void SendTextRaw(byte[] buff) + { + rawStream.Write(buff, 0, buff.Length); + System.Console.WriteLine("eraseme: Just wrote the following buffer chunk out to the client:"); + for (int i=0; i + /// Tell the telnet client that we'd like to operate in line-at-a-time mode, or + /// conversely, in char-at-a-time mode. As per RFC 857. + ///
+ /// true = line-at-a-time, false = char-at-a-time + public void LineAtATime(bool modeOn) { - if (buffered) + isLineAtATime = modeOn; + if (modeOn) { // Send some telnet protocol stuff telling the other side how I'd like it to behave: - rawStream.Write( new byte[] {RFC854_IAC, RFC854_DO, RFC857_ECHO},0, 3); // don't local-echo. - rawStream.Write( new byte[] {RFC854_IAC, RFC854_DONT, RFC858_SUPPRESS_GOAHEAD}, 0, 3); // send one char at a time without buffering lines. + rawStream.Write( new byte[] {RFC854_IAC, RFC854_DO, RFC857_ECHO},0, 3); // do local-echo. + rawStream.Write( new byte[] {RFC854_IAC, RFC854_DONT, RFC858_SUPPRESS_GOAHEAD}, 0, 3); // don't send one char at a time without buffering lines. } else { // Send some telnet protocol stuff telling the other side how I'd like it to behave: rawStream.Write( new byte[] {RFC854_IAC, RFC854_DONT, RFC857_ECHO},0, 3); // don't local-echo. - rawStream.Write( new byte[] {RFC854_IAC, RFC854_DO, RFC858_SUPPRESS_GOAHEAD}, 0, 3); // send one char at a time without buffering lines. + rawStream.Write( new byte[] {RFC854_IAC, RFC854_DO, RFC858_SUPPRESS_GOAHEAD}, 0, 3); // do send one char at a time without buffering lines. } } + /// + /// Tell the telnet client that we'd like to allow it to resize its window, and if it does + /// it should tell us what the new size is. As per RFC 1073. + /// + /// true = client should send resize messages whenever it feels like. false = it should not send us resize messages. + public void AllowTerminalResize(bool modeOn) + { + allowResize = modeOn; + if (modeOn) + rawStream.Write( new byte[] {RFC854_IAC, RFC854_DO, RFC1073_NAWS},0, 3); // do allow Negotiate About Window Size + else + rawStream.Write( new byte[] {RFC854_IAC, RFC854_DONT, RFC1073_NAWS},0, 3); // dont allow Negotiate About Window Size + } + + /// + /// Tell the telnet client that we'd like it to send us ID strings when queried about its terminal model. + /// + /// true = client should send terminal ident information. + public void AllowTerminalTypeInfo(bool modeOn) + { + if (modeOn) + rawStream.Write( new byte[] {RFC854_IAC, RFC854_DO, RFC1091_TERMTYPE},0, 3); // do request terminal type info negotiations from client + else + rawStream.Write( new byte[] {RFC854_IAC, RFC854_DONT, RFC1091_TERMTYPE},0, 3); // dont request terminal type info from client + } - + /// + /// Read the input from the telnet client forever, scraping the bytes for telnet protocol + /// information, and placing the cooked bytes into the queue for the rest of KOS to read from. + /// private void DoInThread() { // All threads in a KSP mod must be careful NOT to access any KSP or Unity methods @@ -235,9 +378,14 @@ private void DoInThread() // Detect if the client closed from its end: if (!client.Connected) { - inThread.Abort(); StopListening(); - break; + outThread.Abort(); + + // If you add code to this clause, remember to insert it above this + // point, not after it. The next line probably prevents the execution + // of any code that comes after it. + inThread.Abort(); + break; // It probably never reaches this line, but it's here just in case. } if (welcomeMenu == null) @@ -247,47 +395,66 @@ private void DoInThread() } else if (ConnectedProcessor != null) // welcome menu is attached but we now have a processor picked, so detach it. { - welcomeMenu.Quit(); - welcomeMenu = null ; // let it get garbage collected. + welcomeMenu.enabled = false; // turn it off so it stops trying to read the input in its Update(). + welcomeMenu = null ; // let it get garbage collected. Now it's the ConnectedProcessor's turn to do the work. + // If ConnectedProcessor gets disconnected again, a new welcomeMenu instance should get spawned by the check above. } int numRead = rawStream.Read(rawReadBuffer, 0, rawReadBuffer.Length); // This is blocking, so this thread will be idle when client isn't typing. if (numRead > 0 ) { - string sendOut = TelnetProtocolScrape(rawReadBuffer, numRead); - foreach (char ch in sendOut) + char[] scrapedBytes = Encoding.UTF8.GetChars(TelnetProtocolScrape(rawReadBuffer, numRead)); + string sendOut = (terminalMapper == null) ? (new string(scrapedBytes)) : terminalMapper.InputConvert(scrapedBytes); + lock (inQueue) // all access to inQueue and outQueue needs to be atomic { - inQueue.Enqueue(ch); + foreach (char ch in sendOut) + { + inQueue.Enqueue(ch); + } } } } } + /// + /// Forever loop, taking whatever appears on the output queue (that some other part of kOS put there) + /// and sending it out to the client as soon as it appears on the queue. + /// private void DoOutThread() { // All threads in a KSP mod must be careful NOT to access any KSP or Unity methods // from inside their execution, because KSP and Unity are not threadsafe - + StringBuilder sb = new StringBuilder(); while (true) { - // Detect if the client closed from its end: - if (!client.Connected) + sb.Remove(0,sb.Length); // clear the whole thing. + lock(outQueue) // all access to inQueue and outQueue needs to be atomic. { - outThread.Abort(); - StopListening(); - break; + while (outQueue.Count > 0) + { + char ch = outQueue.Dequeue(); + System.Console.WriteLine("eraseme: Just dequeued (int)"+(int)ch+", '"+(char)ch+"'"); + sb.Append(ch); + } } - - StringBuilder sb = new StringBuilder(); - while (outQueue.Count > 0) - sb.Append(outQueue.Dequeue()); if (sb.Length > 0) { - SendTextRaw(sb.ToString()); + if (terminalMapper == null) + SendTextRaw(sb.ToString()); + else + SendTextRaw(terminalMapper.OutputConvert(sb.ToString())); } } } + /// + /// When the telnet client connects but is not associated with a particular kOSProcessor at the moment, + /// this will attach the welcome menu to it instead of having it attached to a kOSProcessor. This should + /// occur BOTH when the telnet client first connects, and whenever it detaches from a kOSProcessor. + /// (It should go back to this menu, rather than get disconnected). + ///
+ /// The purpose of the welcome menu is to let the user pick which kOSProcessor to attach to. + ///
private void SpawnWelcomeMenu() { var gObj = new GameObject( "TelnetWelcomeMenu_" + this.GetInstanceID(), typeof(TelnetWelcomeMenu) ); @@ -295,8 +462,31 @@ private void SpawnWelcomeMenu() welcomeMenu = (TelnetWelcomeMenu)gObj.GetComponent(typeof(TelnetWelcomeMenu)); welcomeMenu.Setup(this); } + + + /// + /// Tells the telnet client to send me back a terminal ident string. + /// + private void TelnetAskForTerminalType() + { + rawStream.Write(new byte[] {RFC854_IAC, RFC854_SB, RFC1091_TERMTYPE, RFC1091_SEND, RFC854_IAC, RFC854_SE}, 0, 6); + } - private string TelnetProtocolScrape(byte[] inRawBuff, int rawLength) + /// + /// Given a chunk of raw input bytes received from the telnet client, scrape it clean of + /// all telnet protocol stuff, returning just the cleaned-up string with none of that in it. + ///
+ /// As it scrapes off the protocol bytes, it will also interpret and understand the ones that + /// have been implemented in this server. + ///
+ /// Not every message in the telnet protocol is understood by kOS's telnet server, but even + /// the stuff that isn't will still get scraped away to clean the input. The SuperVerbose log + /// will contain information about what has been scraped away and ignored. + ///
+ /// buffer pre-scraping + /// how much of the buffer to scrape (which might not be the whole byte array). + /// The scraped input. + private byte[] TelnetProtocolScrape(byte[] inRawBuff, int rawLength) { // At max the cooked version will be the same size as the raw. It might be a little less: byte[] inCookedBuff = new byte[rawLength]; @@ -311,10 +501,20 @@ private string TelnetProtocolScrape(byte[] inRawBuff, int rawLength) byte commandByte = inRawBuff[++rawIndex]; switch (commandByte) { - case RFC854_DO: rawIndex += TelnetConsumeDo(inRawBuff, rawIndex ); break; - case RFC854_IAC: break; // pass through to normal behaviour when two IAC's are back to back - that's how a real IAC char is encoded. + case RFC854_DO: + rawIndex += TelnetConsumeDo(inRawBuff, rawIndex); + break; + case RFC854_WILL: + rawIndex += TelnetConsumeWill(inRawBuff, rawIndex); + break; + case RFC854_IAC: + break; // pass through to normal behaviour when two IAC's are back to back - that's how a real IAC char is encoded. + case RFC854_BREAK: + lock (inQueue) { inQueue.Enqueue((char)UnicodeCommand.BREAK); } // async send it out of order, right now. + ++rawIndex; + break; default: - rawIndex += TelnetConsumeOther( commandByte, inRawBuff, rawIndex); + rawIndex += TelnetConsumeOther(commandByte, inRawBuff, rawIndex); break; } break; @@ -328,24 +528,51 @@ private string TelnetProtocolScrape(byte[] inRawBuff, int rawLength) } // Convert the cooked buffer into a shorter buff to pass back: - return Encoding.UTF8.GetString(inCookedBuff, 0, cookedIndex); + byte[] returnValue = new byte[cookedIndex]; + Array.Copy(inCookedBuff, returnValue, cookedIndex); + return returnValue; } + /// + /// Whenever an IAC DO command is seen (see RFC 854), this reads through it and undrstands some parts of it. + /// + /// the buffer of raw stuff + /// the offset into the buffer where the RFC654_DO byte started + /// how many bytes of the buffer should get skipped over because I dealt with them. private int TelnetConsumeDo( byte[] remainingBuff, int index) { int offset = 0; byte option = remainingBuff[index + (++offset)]; switch (option) { - // If other side wants me to echo, agree - case RFC857_ECHO: rawStream.Write( new byte[] {RFC854_IAC, RFC854_WILL, RFC857_ECHO}, 0, 3); + // Note, for some infuriating reason, in my testing I often found that telnet clients ignored + // the fact that I am the server and I'm supposed to send the DO's while they are supposed to reply + // with the WILL or WONT codes. Some clients (I'm looking at YOU, Putty) sometimes take on the + // active side of the negotiation (the DO/DONT) and sometimes take on the passive side of it (the + // WILL/WONT responses to the DO's), mixed up all willy-nilly and not in adherence with the RFC's + // rules about which side does which part. Therefore even though I JUST got done telling the client + // I'll do these things, it sometimes won't listen and demands that I respond to it's DO's instead. + // That's what this section of code is for: + + // If other side orders me to go char-at-a-time, agree: + case RFC857_ECHO: + rawStream.Write(new byte[] {RFC854_IAC, RFC854_WILL, RFC857_ECHO}, 0, 3); break; - // If other side wants me to go char-at-a-atime, agree + // If other side orders me to go char-at-a-time, agree: case RFC858_SUPPRESS_GOAHEAD: - rawStream.Write( new byte[] {RFC854_IAC, RFC854_WILL, RFC858_SUPPRESS_GOAHEAD}, 0, 3); + rawStream.Write(new byte[] {RFC854_IAC, RFC854_WILL, RFC858_SUPPRESS_GOAHEAD}, 0, 3); + break; + // if other side orders me to allow resizes, agree: + case RFC1073_NAWS: + rawStream.Write(new byte[] {RFC854_IAC, RFC854_WILL, RFC1073_NAWS}, 0, 3); + break; + // if other side orders me to accept terminal ident strings, agree, and send it back the signal that it + // should tell me its ident right away. + case RFC1091_TERMTYPE: + TelnetAskForTerminalType(); break; default: - offset += TelnetConsumeOther(RFC854_DO, remainingBuff, 0); + offset += TelnetConsumeOther(RFC854_DO, remainingBuff, offset); break; } @@ -353,26 +580,85 @@ private int TelnetConsumeDo( byte[] remainingBuff, int index) StringBuilder sb = new StringBuilder(); sb.Append("{"+RFC854_DO+"}"); sb.Append("{"+option+"}"); - kOS.Safe.Utilities.Debug.Logger.SuperVerbose( "telnet protocol submessage from client: " + sb.ToString()); + kOS.Safe.Utilities.Debug.Logger.SuperVerbose( "kOS: telnet protocol DO message from client: " + sb.ToString()); return offset; } + + /// + /// Whenever an IAC WILL command is seen (see RFC 854), this reads through it and undrstands some parts of it. + /// + /// the buffer of raw stuff + /// the offset into the buffer where the RFC654_DO byte started + /// how many bytes of the buffer should get skipped over because I dealt with them. + private int TelnetConsumeWill( byte[] remainingBuff, int index) + { + int offset = 0; + byte option = remainingBuff[index + (++offset)]; + switch (option) + { + case RFC1091_TERMTYPE: + // Good- other side responded positively to terminal type negotiations. So send it the request now. + TelnetAskForTerminalType(); + break; + default: + offset += TelnetConsumeOther(RFC854_WILL, remainingBuff, offset); + break; + } + + // Everything below here is to help debug: + StringBuilder sb = new StringBuilder(); + sb.Append("{"+RFC854_DO+"}"); + sb.Append("{"+option+"}"); + kOS.Safe.Utilities.Debug.Logger.SuperVerbose( "kOS: telnet protocol WILL message from client: " + sb.ToString()); + + return offset; + } + + /// + /// Consume any other RFC854_IAC - initiated protocol message that isn't caught by something + /// more specific. + /// + /// the byte immediately after the IAC byte + /// the buffer to be parsed + /// how far into the buffer to start from (where the commandByte was) + /// how many bytes of the buffer should get skipped over because I dealt with them. private int TelnetConsumeOther( byte commandByte, byte[] remainingBuff, int index) { + bool handled = false; int offset = 0; StringBuilder sb = new StringBuilder(); switch (commandByte) { case RFC854_SB: - while (offset < remainingBuff.Length && remainingBuff[index+offset] != RFC854_SE) + if (index+offset >= remainingBuff.Length) + break; + ++offset; + byte subCommandByte = remainingBuff[index+offset]; + switch (subCommandByte) + { + case RFC1073_NAWS: + offset += TelnetConsumeNAWS(remainingBuff, index+offset, out handled); + break; + case RFC1091_TERMTYPE: + offset += TelnetConsumeTERMTYPE(remainingBuff, index+offset, out handled); + break; + default: + break; + } + // Consume the rest of the subnegotiation command: + while ((index + offset) <= remainingBuff.Length && remainingBuff[index+offset-1] != RFC854_SE) ++offset; // Everything below here is to help debug: - sb.Append("{"+commandByte+"}"); - for( int i = index; i < index+offset ; ++i ) - sb.Append("{"+remainingBuff[i]+"}"); - kOS.Safe.Utilities.Debug.Logger.SuperVerbose( "unhandled telnet protocol submessage from client: " + sb.ToString()); + if (!handled) + { + sb.Append("{"+commandByte+"}"); + for( int i = index; i < index+offset ; ++i ) + sb.Append("{"+remainingBuff[i]+"}"); + kOS.Safe.Utilities.Debug.Logger.SuperVerbose( "kOS: telnet protocol submessage from client: " + sb.ToString()); + } break; default: @@ -381,11 +667,132 @@ private int TelnetConsumeOther( byte commandByte, byte[] remainingBuff, int inde // Everything below here is to help debug: sb.Append("{"+commandByte+"}"); sb.Append("{"+remainingBuff[index+offset]+"}"); - kOS.Safe.Utilities.Debug.Logger.SuperVerbose( "unhandled telnet protocol command from client: " + sb.ToString()); + kOS.Safe.Utilities.Debug.Logger.SuperVerbose( "kOS: telnet protocol command from client: " + sb.ToString()); break; } return offset; } + + /// + /// Consume the Negotiate About Window Size (RFC 1073) sub-message, i.e if the client wants to + /// tell us the window size is now 350 cells wide by 40 tall, it will send us this + /// sequence of bytes: + ///
IAC NAWS 1 94 0 40 IAC SE
+ /// (1 94 is the encoding of 350 in two bytes, as in 256 + 94. The protocol sends + /// 16-bit numbers, allowing a very large max terminal size. + ///
+ /// the buffer to be parsed + /// how far into the buffer to start from (where the commandByte was) + /// is true if it was handled properly (else it should get logged as a problem) + /// how many bytes of the buffer should get skipped over because I dealt with them. + private int TelnetConsumeNAWS(byte[] remainingBuff, int index, out bool handled) + { + int offset = 0; + + byte code = remainingBuff[index + (offset++)]; + if (code != RFC1073_NAWS) + { + kOS.Safe.Utilities.Debug.Logger.Log("kOS: Bug in telnet server - expected NAWS byte {" + RFC1073_NAWS + "} (RFC1073) but instead got {" + (int)code + "}."); + handled = false; + return offset; + } + + if (remainingBuff.Length < (index + offset + 3)) + { + kOS.Safe.Utilities.Debug.Logger.Log("kOS: Telnet client is trying to send me a window resize (RFC1073) command without actual width/height fields. WTF?"); + handled = false; + return offset; + } + + byte widthHighByte = remainingBuff[index + (offset++)]; + if (widthHighByte == RFC854_IAC) ++offset; // special case - to send this byte value, telnet clients have to encode it by sending it twice consecutively. + byte widthLowByte = remainingBuff[index + (offset++)]; + if (widthLowByte == RFC854_IAC) ++offset; // special case - to send this byte value, telnet clients have to encode it by sending it twice consecutively. + byte heightHighByte = remainingBuff[index + (offset++)]; + if (heightHighByte == RFC854_IAC) ++offset; // special case - to send this byte value, telnet clients have to encode it by sending it twice consecutively. + byte heightLowByte = remainingBuff[index + (offset++)]; + if (heightLowByte == RFC854_IAC) ++offset; // special case - to send this byte value, telnet clients have to encode it by sending it twice consecutively. + + int width = (((int)widthHighByte)<<8) + widthLowByte; + int height = (((int)heightHighByte)<<8) + heightLowByte; + + kOS.Safe.Utilities.Debug.Logger.SuperVerbose( "kOS: Telnet client just told me its window size is " + width + "x" + height+"."); + + // Only *actually* set the width and height if the values are nonzero. The telnet protocol allows the + // client to send one or the other as zero, which does not really mean zero but rather "ignore this field". + // It's doubtful any terminal program uses this feature, but just in case it does, this protects us from + // trying to set a zero height or zero width screen, which would likely cause a crash somewhere in ScreenBuffer: + if (width > 0) ClientWidth = width; + if (height > 0) ClientHeight = height; + + lock (inQueue) // all access to inQueue and outQueue needs to be atomic + { + inQueue.Enqueue( (char)UnicodeCommand.RESIZESCREEN ); + inQueue.Enqueue( (char)ClientWidth ); + inQueue.Enqueue( (char)ClientHeight ); + } + + handled = true; + return offset; + } + + /// + /// Consume the Terminal Type submessage (RFC1091) where the telnet client is telling us the model ident + /// of its terminal type (i.e. "VT100" for example) + ///
+ /// the buffer to be parsed + /// how far into the buffer to start from (where the commandByte was) + /// is true if it was handled properly (else it should get logged as a problem) + /// how many bytes of the buffer should get skipped over because I dealt with them. + private int TelnetConsumeTERMTYPE(byte[] remainingBuff, int index, out bool handled) + { + int offset = 0; + + // expect TERMTYPE code char: + byte code = remainingBuff[index + (offset++)]; + if (code != RFC1091_TERMTYPE) + { + kOS.Safe.Utilities.Debug.Logger.Log("kOS: Bug in telnet server - expected TERMTYPE byte {" + RFC1091_TERMTYPE + "} (RFC10791) but instead got {" + (int)code + "}."); + handled = false; + return offset; + } + + // expect IS code char: + code = remainingBuff[index + (offset++)]; + if (code != RFC1091_IS) + { + kOS.Safe.Utilities.Debug.Logger.Log("kOS: Bug in telnet server - expected [IS] byte {" + RFC1091_IS + "} (RFC10791) but instead got {" + (int)code + "}."); + handled = false; + return offset; + } + + // Consume everything until the pattern IAC SE is found, which marks the end of the ident string: + StringBuilder sb = new StringBuilder(); + byte last = (byte)0; + byte penultimate = (byte)0; + while ( (index + offset) <= remainingBuff.Length && !(penultimate == RFC854_IAC && last == RFC854_SE) ) + { + sb.Append(Encoding.UTF8.GetString(remainingBuff, index + offset, 1)); + penultimate = last; + ++offset; + last = remainingBuff[index+offset]; + } + // If it ended properly with the delimiter, then we have the string: + if (penultimate == RFC854_IAC && last == RFC854_SE) + { + ClientTerminalType = sb.ToString().Substring(0, sb.Length - 1); // -1 because it will have the RFC854_IAC byte still stuck on the end. + kOS.Safe.Utilities.Debug.Logger.SuperVerbose("kOS: Telnet client just told us its terminal type is: \""+ClientTerminalType+"\"."); + handled = true; + } + else + { + kOS.Safe.Utilities.Debug.Logger.Log("kOS: Telnet client sent us a garbled attempt at a terminal type ident string."); + handled = false; + } + // remove the final two delimiter bytes: + return offset; + } } } diff --git a/src/kOS/UserIO/TelnetWelcomeMenu.cs b/src/kOS/UserIO/TelnetWelcomeMenu.cs index 3fdfa326b..33aef76ec 100644 --- a/src/kOS/UserIO/TelnetWelcomeMenu.cs +++ b/src/kOS/UserIO/TelnetWelcomeMenu.cs @@ -36,7 +36,9 @@ public TelnetWelcomeMenu() public void Setup(TelnetSingletonServer tserver) { telnetServer = tserver; - lastMenuQueryTime = System.DateTime.MinValue; // Force a stale timestamp the first time so it will print the menu. + lastMenuQueryTime = System.DateTime.MinValue; // Force a stale timestamp the first time. + telnetServer.Write( (char)UnicodeCommand.TITLEBEGIN + "kOS Terminal Server Welcome Menu" + (char)UnicodeCommand.TITLEEND ); + forceMenuReprint = true; // force it to print the menu once the first time regardless of the state of the CPU list. } public void Quit() @@ -44,8 +46,7 @@ public void Quit() telnetServer.StopListening(); enabled = false; } - - + public virtual void Update() { @@ -56,7 +57,7 @@ public virtual void Update() { bool listChanged = CPUListChanged(); if (!firstTime && listChanged) - telnetServer.Write("\r\n--(List of CPU's has Changed)--\r\n\r\n"); + telnetServer.Write("--(List of CPU's has Changed)--\r\n"); firstTime = false; if (listChanged || forceMenuReprint ) PrintCPUMenu(); @@ -68,13 +69,12 @@ public virtual void Update() switch (ch) { - case '\r': - case '\n': + case (char)UnicodeCommand.NEWLINERETURN: LineEntered(); break; - // Implement crude input editing (backspace only) in this menu prompt: - case (char)0x08: // ascii backspace. - case (char)0x127: // ascii del. + // Implement crude input editing (backspace only - map delete to the same as backspace) in this menu prompt: + case (char)UnicodeCommand.DELETELEFT: + case (char)UnicodeCommand.DELETERIGHT: if (localMenuBuffer.Length > 0) localMenuBuffer.Remove(localMenuBuffer.Length-1,1); telnetServer.Write((char)0x08+" "+(char)0x08); // backspace space backspace. @@ -91,7 +91,6 @@ public void LineEntered() { if (localMenuBuffer.Length == 0) return; - telnetServer.Write("\r\n"); string cmd = localMenuBuffer.ToString(); kOS.Safe.Utilities.Debug.Logger.SuperVerbose( "TelnetWelcomeMenu.LineEntered(): String from client was: [" + cmd.ToString() + "]"); localMenuBuffer.Remove(0,localMenuBuffer.Length); // clear the buffer for next line. @@ -115,7 +114,7 @@ public void LineEntered() return; } telnetServer.ConnectToProcessor(availableCPUs[pickNumber-1]); - Quit(); + // Quit(); - uncomment to make it so that the TelnetWelcomeMenu aborts telnet when done - for testing purposes. } private bool CPUListChanged() @@ -143,7 +142,9 @@ private void PrintCPUMenu() forceMenuReprint = false; - telnetServer.Write(" Available CPUS for Connection:\r\n"); + telnetServer.Write("Terminal: type = " + telnetServer.ClientTerminalType + ", size = " + telnetServer.ClientWidth + "x" + telnetServer.ClientHeight + "\r\n"); + telnetServer.Write(" Available CPUS for Connection:\r\n" + + "+---------------------------------------+\r\n"); int userPickNum = 1; bool atLeastOne = false; @@ -159,12 +160,19 @@ private void PrintCPUMenu() Vessel vessel = (thisPart == null) ? null/*can this even happen?*/ : thisPart.vessel; string vesselLabel = (vessel == null) ? ""/*can this even happen?*/ : vessel.GetName(); - telnetServer.Write(String.Format("\t[{0}] Vessel({1}), CPU({2})\r\n",userPickNum, vesselLabel, partLabel)); + telnetServer.Write(String.Format("[{0}] Vessel({1}), CPU({2})\r\n",userPickNum, vesselLabel, partLabel)); ++userPickNum; } if (atLeastOne) - telnetServer.Write("Type a selection number and press return/enter.\r\n" + + telnetServer.Write("+---------------------------------------+\r\n" + + "Choose a CPU to attach to by typing a\r\n" + + "selection number and pressing return/enter.\r\n" + "Or enter [Q] to quit terminal server.\r\n" + + "\r\n" + + "(After attaching, you can (D)etach and return\r\n" + + "to this menu by pressing Control-D as the first\r\n" + + "character on a new command line.)\r\n" + + "+---------------------------------------+\r\n" + "> "); else telnetServer.Write("\t\r\n"); diff --git a/src/kOS/UserIO/TerminalAnsiMapper.cs b/src/kOS/UserIO/TerminalAnsiMapper.cs new file mode 100644 index 000000000..55c6e6d0a --- /dev/null +++ b/src/kOS/UserIO/TerminalAnsiMapper.cs @@ -0,0 +1,19 @@ +using System; +using System.Text; + +namespace kOS.UserIO +{ + /// + /// Subclass of TerminalUnicodeMapper designed to handle the specifics of + /// the ANSI terminal control codes. + /// + public class TerminalAnsiMapper : TerminalUnicodeMapper + { + public TerminalAnsiMapper(string typeString) : base(typeString) + { + TerminalTypeID = TerminalType.ANSI; + } + + // TODO - this isn't implemented properly yet. For now it's just a copy of the default unknown terminal base class. + } +} diff --git a/src/kOS/UserIO/TerminalUnicodeMapper.cs b/src/kOS/UserIO/TerminalUnicodeMapper.cs new file mode 100644 index 000000000..15ac908b3 --- /dev/null +++ b/src/kOS/UserIO/TerminalUnicodeMapper.cs @@ -0,0 +1,189 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace kOS.UserIO +{ + /// + /// A base class for terminal-specific mappings like vt100, xterm, etc. + ///
+ /// It encodes common terminal control codes in unicode, using some of the + /// unicode characters that we'll never use, as pretend terminal escape codes. + ///
+ /// Subclasses of this need to implement a way to convert those unicode control + /// codes into a stream of ascii chars, and visa versa, that do things using the + /// terminal control codes for the specific model of terminal in question. + ///
+ public class TerminalUnicodeMapper + { + /// + /// This should be used when trying to get the exact match for conditional checks: + /// + public TerminalType TerminalTypeID {get; protected set;} + + /// + /// This is the type as a raw string, without any data tokenizing: + /// + public string TerminalTypeString {get; protected set;} + + // Note that it's essential that these remain private and not get changed to protected or public. + // Some of the derived classes of this class also use the same identifier name for their own + // fields that have a very similar purpose, and in those cases there actually needs to be two + // separate instances of these fields living inside the object. One instance tracks the state + // of the base class's mapping algorithm, and the other tracks the state of the derived class's + // mapping algorithm: + private ExpectNextChar outputExpected = ExpectNextChar.NORMAL; // must stay private + private int pendingWidth; // must stay private + + public TerminalUnicodeMapper(string typeString) + { + TerminalTypeString = typeString; + TerminalTypeID = TerminalType.UNKNOWN; + } + + public static TerminalType GuessTypeId(string typeString) + { + if (typeString.Substring(0,5).Equals("xterm", StringComparison.CurrentCultureIgnoreCase)) + return TerminalType.XTERM; + else if (typeString.Substring(0,4).Equals("ansi", StringComparison.CurrentCultureIgnoreCase)) + return TerminalType.XTERM; + // Add more cases here if more subclasses of this class are created later. + else + return TerminalType.UNKNOWN; + } + + /// + /// Construct an object of this type, or one of its derived subtypes, depending on + /// the terminal type string passed in. + /// + /// terminal type id string to make a mapper for. + /// newly constructed mapper object of the proper type. + public static TerminalUnicodeMapper TerminalMapperFactory(string typeString) + { + TerminalType termType = GuessTypeId(typeString); + switch (termType) + { + case TerminalType.XTERM: + return new TerminalXtermMapper(typeString); + case TerminalType.ANSI: + return new TerminalAnsiMapper(typeString); + default: + return new TerminalUnicodeMapper(typeString); + } + } + + /// + /// Map the unicode chars (and the fake control codes we made) into bytes. + /// In this base class, all it does is just mostly passthru things as-is with no + /// conversions. + /// Subclasses of this should perform their own manipulations, then fallthrough + /// to this base class inmplementation at the bottom, to allow chains of + /// subclasses to all operate on the data. + /// + /// unicode char + /// raw byte stream to send to the terminal + public virtual char[] OutputConvert(string str) + { + System.Console.WriteLine("eraseme: TerminalUnicodeMapper: Passed string = "+str); + StringBuilder sb = new StringBuilder(); + + for (int index = 0 ; index < str.Length ; ++index) + { + switch (outputExpected) + { + case ExpectNextChar.RESIZEWIDTH: + pendingWidth = (int)(str[index]); + outputExpected = ExpectNextChar.RESIZEHEIGHT; + System.Console.WriteLine("eraseme: TerminalUnicodeMapper: found RESIZEWIDTH char. Value = "+pendingWidth); + break; + case ExpectNextChar.RESIZEHEIGHT: + int height = (int)(str[index]); + System.Console.WriteLine("eraseme: TerminalUnicodeMapper: found RESIZEHEIGHT char. Value = "+height); + sb.Append("{Please resize to " + pendingWidth + "x" + height + "}"); // By default, assume the terminal has no such control code, but this can be overridden. + System.Console.WriteLine("eraseme: TerminalUnicodeMapper: sending string = " + sb.ToString()); + outputExpected = ExpectNextChar.NORMAL; + break; + case ExpectNextChar.INTITLE: + // Default behavior: Ignore all content until the title ender. Assume most terminals don't know how to do this. + if (str[index] == (char)UnicodeCommand.TITLEEND) + outputExpected = ExpectNextChar.NORMAL; + break; + default: + switch (str[index]) + { + case (char)(UnicodeCommand.RESIZESCREEN): + outputExpected = ExpectNextChar.RESIZEWIDTH; + System.Console.WriteLine("eraseme: TerminalUnicodeMapper: found RESIZESCREEN."); + break; + case (char)(UnicodeCommand.TITLEBEGIN): + outputExpected = ExpectNextChar.INTITLE; + break; + default: + sb.Append(str[index]); // default passhtrough + break; + } + break; + } + } + return sb.ToString().ToCharArray(); + } + + /// + /// Map the bytes containing the terminal's own control codes into our + /// unicode system with its fake control codes. In this base class, all it + /// does it just mostly passthru things as-is with no conversion. + /// Subclasses of this should perform their own manipulations, then fallthrough + /// to this base class implementation at the bottom, to allow chains of + /// subclasses to all operate on the data. + /// + /// chars in the terminal's way of thinking + /// chars in our unicode way of thinking + public virtual string InputConvert(char[] inChars) + { + List outChars = new List(); + + char prevCh = '\0'; // dummy for first pass + + foreach (char ch in inChars) + { + switch (ch) + { + case (char)0x08: // control-H, the ASCII backspace + outChars.Add((char)UnicodeCommand.DELETELEFT); + break; + case (char)0x7f: // ascii 127 = the delete character + outChars.Add(((char)UnicodeCommand.DELETERIGHT)); + break; + case '\r': + if (prevCh == '\n') // A \r after a \n should be ignored - we already got it from the \n: + outChars.Add(ch); // passthrough as-is. + else + outChars.Add(((char)UnicodeCommand.NEWLINERETURN)); + break; + case '\n': + if (prevCh == '\r') // A \n after a \r should be ignored - we already got it from the \r: + outChars.Add(ch); // passthrough as-is. + else + outChars.Add(((char)UnicodeCommand.NEWLINERETURN)); + break; + case (char)0x03: // Control-C. map to BREAK just as if the telnet client had sent a hard break in the protocol. + outChars.Add((char)UnicodeCommand.BREAK); + break; + default: + outChars.Add(ch); // dummy passthrough + break; + } + prevCh = ch; + } + return new string(outChars.ToArray()); + } + } + + /// tokenization of the many different strings that might be returned as ID's from telnet clients + public enum TerminalType + { + UNKNOWN, + XTERM, + ANSI // Add more values here if more subclasses of this class are created later. + } +} diff --git a/src/kOS/UserIO/TerminalVT100Mapper.cs b/src/kOS/UserIO/TerminalVT100Mapper.cs new file mode 100644 index 000000000..c8791e7b4 --- /dev/null +++ b/src/kOS/UserIO/TerminalVT100Mapper.cs @@ -0,0 +1,100 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace kOS.UserIO +{ + /// + /// Subclass of TerminalUnicodeMapper designed to handle the specifics of + /// the vt100 terminal control codes. + /// + public class TerminalVT100Mapper : TerminalUnicodeMapper + { + public TerminalVT100Mapper(string typeString) : base(typeString) + { + TerminalTypeID = TerminalType.XTERM; + } + + /// + /// Provide the VT100 specific mappings of input chars, then fallback to the + /// base class's mapping to see if there's other conversions to do. + /// + /// + /// input mapped into our internal pretend unicode terminal's codes + public override string InputConvert(char[] inChars) + { + List outChars = new List(); + + for (int index = 0 ; index < inChars.Length ; ++index ) + { + switch (inChars[index]) + { + case (char)0x1b: // ESCAPE char. + if (inChars[index+1] == '[') // ESC followed by '[' is called the CSI (Control Sequence Initiator) and it's how most VT100 codes start. + { + int numConsumed; + char ch = ConvertVT100InputCSI(inChars,index+2,out numConsumed); + if (numConsumed > 0) + { + outChars.Add(ch); + index += (1 + numConsumed); // 1+ is for the '[' char. + } + } + else + outChars.Add(inChars[index]); // dummy passthrough. Send ESC as-is. + break; + case (char)0x7f: // DELETE char. + outChars.Add((char)UnicodeCommand.DELETELEFT); // Map to the same as backspace, because Vt100 sends it for the backspace key, annoyingly. + break; + default: + outChars.Add(inChars[index]); // dummy passthrough + break; + } + } + return base.InputConvert(outChars.ToArray()); // See if the base class has any more mappings to do on top of these: + } + + /// + /// Return the Unicode (which might be a UnicodeCommand enum value) from the Vt100 CSI sequence + /// passed in. + /// + /// input containing what could be a CSI initiated sequence + /// how far into inChars is the first char after the CSI code (ESC[ or CSI). + /// how many characters (starting at offset) got consumed and turned into something else. + /// The UnicdeCommand equivalent. NOTE that if numConsumed is zero, this value shouldn't be used as nothing was actually done. + protected char ConvertVT100InputCSI(char[] inChars, int offset, out int numConsumed) + { + System.Console.WriteLine("eraseme: in ConvertVt100InputCSI. inChars[offset] = (as integer) " + (int)inChars[offset]); + char returnChar = '\0'; // dummy until changed. + switch (inChars[offset]) + { + case 'A': returnChar = (char)UnicodeCommand.UPCURSORONE; numConsumed = 1; break; + case 'B': returnChar = (char)UnicodeCommand.DOWNCURSORONE; numConsumed = 1; break; + case 'C': returnChar = (char)UnicodeCommand.RIGHTCURSORONE; numConsumed = 1; break; + case 'D': returnChar = (char)UnicodeCommand.LEFTCURSORONE; numConsumed = 1; break; + case 'H': returnChar = (char)UnicodeCommand.HOMECURSOR; numConsumed = 1; break; + case 'F': returnChar = (char)UnicodeCommand.ENDCURSOR; numConsumed = 1; break; + default: numConsumed = 0; break; // Do nothing if it's not a recognized sequence. Leave the chars to be read normally. + } + // The following are technically VT220 codes, not VT100, but I couldn't be bothered making a separate + // mapper just for them. (i.e. the proper way would be to make a VT220Mapper that inherits from this VT100Mapper, + // and implement these only there): + // These codes look like ESC [ _num_ ~. For example: PgUp is ESC [ 5 ~ + if (offset + 1 < inChars.Length && inChars[offset + 1] == '~') + { + switch (inChars[offset]) + { + case '1': returnChar = (char)UnicodeCommand.HOMECURSOR; numConsumed = 2; break; + case '4': returnChar = (char)UnicodeCommand.ENDCURSOR; numConsumed = 2; break; + case '5': returnChar = (char)UnicodeCommand.PAGEUPCURSOR; numConsumed = 2; break; + case '6': returnChar = (char)UnicodeCommand.PAGEDOWNCURSOR; numConsumed = 2; break; + default: numConsumed = 0; break; // Do nothing if it's not a recognized sequence. Leave the chars to be read normally. + } + } + + // There's a lot more keyboard controls that could be added to here to really get everything the keyboard can do. + + return returnChar; + } + } +} diff --git a/src/kOS/UserIO/TerminalXtermMapper.cs b/src/kOS/UserIO/TerminalXtermMapper.cs new file mode 100644 index 000000000..fe6bb830d --- /dev/null +++ b/src/kOS/UserIO/TerminalXtermMapper.cs @@ -0,0 +1,169 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace kOS.UserIO +{ + /// + /// Subclass of TerminalUnicodeMapper designed to handle the specifics of + /// the xterm terminal control codes. + ///
+ /// Note that because the XTERM program was designed explicitly to attempt + /// to emulate the already popular and existant VT100 hardware terminal, this + /// class can mostly be just a subclass of the VT100 mapper that lets it + /// do most of the heavy work. It's only a separate class to support the + /// few places where XTERM is more capable than VT100. + ///
+ public class TerminalXtermMapper : TerminalVT100Mapper + { + public TerminalXtermMapper(string typeString) : base(typeString) + { + TerminalTypeID = TerminalType.XTERM; + } + + private ExpectNextChar outputExpected = ExpectNextChar.NORMAL; + private int pendingWidth; + private StringBuilder pendingTitle; + + private enum CommDirection { TO_CLIENT, FROM_CLIENT } + + // These flags exist to stop the following infinite back-and-forth looping that + // was occurring: + // The client sends a resize message to the server, causing the ScreenBuffer to SetSize() itself. + // The in-game GUI terminal notices that its ScreenBuffer did a SetSize(). + // So the in-game GUI terminal sends a resize message to the client. + // Although the client's new size is the same as its old, it still goes through the motions of sending its new size notification to the server. + // Thus starting the whole thing over again. + // When doing an active drag, where the client tries to redraw itself the whole time, it got messy. + private CommDirection prevResizeDirection = CommDirection.TO_CLIENT; + private DateTime prevResizeTimestamp = DateTime.Now; + private TimeSpan resizeSanityCooldown = TimeSpan.FromMilliseconds((double)250); + private bool IsResizeSane(CommDirection resizeDirection) + { + return (prevResizeDirection == resizeDirection || + DateTime.Now > prevResizeTimestamp + resizeSanityCooldown); + } + private void SetResizeTimestamp(CommDirection resizeDirection) + { + prevResizeDirection = resizeDirection; + prevResizeTimestamp = DateTime.Now; + } + + /// + /// Map the unicode chars (and the fake control codes we made) into bytes. + /// In this base class, all it does is just mostly passthru things as-is with no + /// conversions.
+ /// Subclasses of this should perform their own manipulations, then fallthrough + /// to this base class inmplementation at the bottom, to allow chains of + /// subclasses to all operate on the data. + ///
+ /// unicode char + /// raw byte stream to send to the terminal + public override char[] OutputConvert(string str) + { + System.Console.WriteLine("eraseme: TerminalXtermMapper: Passed string = "+str); + StringBuilder sb = new StringBuilder(); + + for (int index = 0 ; index < str.Length ; ++index) + { + switch (outputExpected) + { + case ExpectNextChar.RESIZEWIDTH: + pendingWidth = (int)(str[index]); + outputExpected = ExpectNextChar.RESIZEHEIGHT; + System.Console.WriteLine("eraseme: TerminalXtermMapper: In RESIZEWIDTH mode, just read value = " + pendingWidth); + break; + case ExpectNextChar.RESIZEHEIGHT: + int height = (int)(str[index]); + System.Console.WriteLine("eraseme: TerminalXtermMapper: In RESIZEHEIGHT mode, just read value = " + height); + if (IsResizeSane(CommDirection.TO_CLIENT)) + { + System.Console.WriteLine("eraseme: TerminalXtermMapper: In RESIZEHEIGHT mode, just read value = " + height + " and decided it's sane to send it."); + sb.Append(((char)0x1b)/*ESC*/ + "[8;" + height + ";" + pendingWidth + "t"); + } + // else ignore it and don't pass it on. + else + { + System.Console.WriteLine("eraseme: TerminalXtermMapper: In RESIZEHEIGHT mode, just read value = " + height + " and decided NOT to send it."); + } + // But whether ignoring it or not, still do remember the attempt was made and reset the timestamp: + SetResizeTimestamp(CommDirection.TO_CLIENT); + outputExpected = ExpectNextChar.NORMAL; + break; + case ExpectNextChar.INTITLE: + if (str[index] == (char)UnicodeCommand.TITLEEND) + { + System.Console.WriteLine("eraseme: TerminalXtermMapper: Saw TITLEEND, title = " + pendingTitle); + sb.Append(((char)0x1b)/*ESC*/ + "]2;" + pendingTitle.ToString() + ((char)0x07)/*BEL*/); + pendingTitle = new StringBuilder(); + outputExpected = ExpectNextChar.NORMAL; + SetResizeTimestamp(CommDirection.TO_CLIENT); + } + else + pendingTitle.Append(str[index]); + break; + default: + switch (str[index]) + { + case (char)(UnicodeCommand.RESIZESCREEN): + outputExpected = ExpectNextChar.RESIZEWIDTH; + System.Console.WriteLine("eraseme: TerminalXtermMapper: Detected RESIZESCREEN, going into RESIZEWIDTH mode."); + break; + case (char)(UnicodeCommand.TITLEBEGIN): + outputExpected = ExpectNextChar.INTITLE; + pendingTitle = new StringBuilder(); + System.Console.WriteLine("eraseme: TerminalXtermMapper: Detected TITLEBEGIN, going into INTITLE mode."); + break; + default: + sb.Append(str[index]); // default passhtrough + break; + } + break; + } + } + return base.OutputConvert(sb.ToString()); + } + + /// + /// Provide the XTERM specific mappings of input chars, then fallback to the + /// base VT100 mappings for most of its work. + /// + /// + /// input mapped into our internal pretend unicode terminal's codes + public override string InputConvert(char[] inChars) + { + List outChars = new List(); + + for (int index = 0 ; index < inChars.Length ; ++index ) + { + switch (inChars[index]) + { + case (char)0x9b: + // 0x9b is a single 8-bit char alternative to VT100's CSI pair of chars, ESC followed by [. + // (In fact DEC referred to 0x9b AS the "CSI character".) + // This started appearing on Vt220 models, and xterm borrowed it, as a + // more compact way to encode the control sequences. When you see 0x9b, it means the same + // exact thing as ESC [. + int numConsumed; + char ch = ConvertVT100InputCSI(inChars,index+1,out numConsumed); + if (numConsumed > 0) + { + outChars.Add(ch); + index += numConsumed; + } + break; + case (char)(UnicodeCommand.RESIZESCREEN): + SetResizeTimestamp(CommDirection.FROM_CLIENT); + System.Console.WriteLine("eraseme: TerminalXtermMapper: Detected INPUT's RESIZESCREEN, passing thru"); + outChars.Add(inChars[index]); // dummy passthrough - just trapped this to notice the new resize direction. + break; + default: + outChars.Add(inChars[index]); // dummy passthrough + break; + } + } + return base.InputConvert(outChars.ToArray()); // See if the base class has any more mappings to do on top of these: + } + + } +} diff --git a/src/kOS/UserIO/UnicodeCommand.cs b/src/kOS/UserIO/UnicodeCommand.cs new file mode 100644 index 000000000..c1190c2aa --- /dev/null +++ b/src/kOS/UserIO/UnicodeCommand.cs @@ -0,0 +1,182 @@ +/* + * Created by SharpDevelop. + * User: Dunbaratu + * Date: 2/5/2015 + * Time: 12:47 AM + * + * To change this template use Tools | Options | Coding | Edit Standard Headers. + */ +using System; + +namespace kOS.UserIO +{ + /// + /// A list of extra unicode command characters we use to genericize command codes, abstracting away + /// the differences between different terminal models. + ///
+ /// These are all stored in the Unicode "private use" area in range [0xE000..0xF8FF]. + /// The Unicode Consortium promises that they will never make any official meanings for + /// these characters, so they are free to use for whatever local private meanings you like. + /// The only "public" standards for this character range are unofficial ones for + /// very specialized interest groups. (For example, by using this range, we have + /// precluded people from being able to write kOS scripts in Klingon.) + ///
+ /// WARNING: EVERY TIME you use these you must always cast them to (char). This is because + /// C# does not allow us to do the correct thing here, which is this: + /// public enum UnicodeCommand : char { stuff, stuff, stuff,....} + /// For some reason I cannot fathom, C# lets you pick the type of any enum EXCEPT char, even + /// though a unicode char is still a well defined narrow known number of bits and should + /// effectively work just as well for enums as, say, a ushort. + ///
+ /// If anyone does have the ambition to get rid of the need for all the casting, they can + /// go through here and turn all these into const chars if they like. But that means having + /// to manually type in their number value for each one instead of just letting the enum + /// syntax auto-increment it for each sucessive one. + ///
+ public enum UnicodeCommand + { + /// + /// Indicates an emergency low-level break signal. Often a telnet client will send this + /// character out-of-band immediately, queue-barging in front of whatever else is in the + /// input queue: + /// + BREAK = 0xE000, + + /// + /// Clear the screen and move the cursor to the upper left corner: + /// + CLEARSCREEN, + + /// + /// Tell the terminal to resize itself to a new row/col size. Not all terminals will be capable of doing this. + /// This can be communicated in either direction - for the client telling the server it has been resized, or + /// for the server telling the client to it needs to resize itself. + /// Expects a sequence of 3 characters as follows:
+ /// RESIZESCREEN Binary_Width_Num Binary_Height_Num
+ /// Where Width_num and Height_num are the numbers directly transcoded into unicode chars in a binary way. + /// (For example a height of 66, which is hex 0x32 would end up being sent as the capital letter 'B' which is unicode 0x0032.). + ///
+ RESIZESCREEN, + + /// + /// This character indicates that a string is to follow which is meant to be used to tell the terminal + /// what it should set its titlebar to. Output-only. + /// Example: To set the terminal's title to "Vessel A, CPU 1": + /// TITLEBEGIN V e s s e l A , C P U 1 TITLEEND + /// + TITLEBEGIN, + + /// + /// This character indicates that the string that tells the terminal its title has finished. Output-only. + /// + TITLEEND, + + /// + /// Begins a cursor move to an exact position. Expects exactly 2 more + /// unicode chars to follow, interpreted as binary number data (not as characters) + /// for the row num and column num, respectively. + /// + TELEPORTCURSOR, + + /// + /// Indicates moving a cursor up one row. Can be used both on output to + /// move the cursor, or on input to encode that the arrow key was pressed. + /// + UPCURSORONE, + /// + /// Indicates moving a cursor [count] rows up. Expects exactly 1 more unicode + /// char to follow, interpreted as binary number data (not as character) for + /// the number of spaces to move. + /// + UPCURSORNUM, + + /// + /// Indicates moving a cursor down one row. Can be used both on output to + /// move the cursor, or on input to encode that the arrow key was pressed. + /// + DOWNCURSORONE, + /// + /// Indicates moving a cursor [count] rows down. Expects exactly 1 more unicode + /// char to follow, interpreted as binary number data (not as character) for + /// the number of spaces to move. + /// + DOWNCURSORNUM, + + /// + /// Indicates moving a cursor left one column. Can be used both on output to + /// move the cursor, or on input to encode that the arrow key was pressed. + /// + LEFTCURSORONE, + /// + /// Indicates moving a cursor [count] spaces left. Expects exactly 1 more unicode + /// char to follow, interpreted as binary number data (not as character) for + /// the number of spaces to move. + /// + LEFTCURSORNUM, + + /// + /// Indicates moving a cursor right one column. Can be used both on output to + /// move the cursor, or on input to encode that the arrow key was pressed. + /// + RIGHTCURSORONE, + /// + /// Indicates moving a cursor [count] spaces right. Expects exactly 1 more unicode + /// char to follow, interpreted as binary number data (not as character) for + /// the number of spaces to move. + /// + RIGHTCURSORNUM, + + /// + /// Indicates moving a cursor to the home position of the row. Also can be seen + /// on input to indicate the home key being pressed. + /// + HOMECURSOR, + + /// + /// Indicates moving a cursor to the end position of the row. Also can be seen + /// on input to indicate the end key being pressed. + /// + ENDCURSOR, + + /// + /// Indicates moving a cursor one page up. Also can be seen on input to indicate the + /// PgUp key being pressed. + /// + PAGEUPCURSOR, + + /// + /// Indicates moving a cursor one page down. Also can be seen on input to indicate the + /// PgDn key being pressed. + /// + PAGEDOWNCURSOR, + + /// + /// Delete the character to the left of the cursor, and move the cursor left one + /// space, wrapping to the end of the previous line if at the left edge of the screen. + /// Also used for input to represent the keypress that does that (the backspace). + /// + DELETELEFT, + + /// + /// Delete the character the cursor is currently on, and shift the characters to + /// the right of it one space left to fill the gap. (Does not wrap because the + /// terminal doesn't know where the wraparound lines versus true end of lines are.) + /// Also used for input to represent the keypress that does that (the delete button). + /// + DELETERIGHT, + + /// + /// Abstracts away all that CR/LF vs LF only versus CR only nonsense. In the pretend + /// unicode terminal we are referring to, we'll map them all to the same character, + /// this one. This character means go to the start of the next line. + /// Also used on input to represent hitting either the return or the enter key. + /// + NEWLINERETURN + } + + // For tracking multiple-character input sequences to remember where it is in the sequence: + public enum ExpectNextChar { + NORMAL, RESIZEWIDTH, RESIZEHEIGHT, INTITLE, + } + +} diff --git a/src/kOS/kOS.csproj b/src/kOS/kOS.csproj index 8b5df9cb5..87309dfe1 100644 --- a/src/kOS/kOS.csproj +++ b/src/kOS/kOS.csproj @@ -133,6 +133,11 @@ + + + + + From 1b012d0eb1b216ec5aea7b14039eb45ff6b55531 Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Fri, 6 Feb 2015 21:07:53 -0600 Subject: [PATCH 127/446] Checkin so erendrake can have a look --- src/kOS/UserIO/TelnetSingletonServer.cs | 36 +++++++++++++------------ 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/src/kOS/UserIO/TelnetSingletonServer.cs b/src/kOS/UserIO/TelnetSingletonServer.cs index 4d7cdb742..9e330fae0 100644 --- a/src/kOS/UserIO/TelnetSingletonServer.cs +++ b/src/kOS/UserIO/TelnetSingletonServer.cs @@ -39,11 +39,13 @@ public class TelnetSingletonServer : MonoBehaviour /// The queue that other parts of KOS can use to read characters from the telnet client. ///
private volatile Queue inQueue; + private readonly object inQueueAccess = new object(); // To make all access of the inQueue atomic between threads. /// /// The queue that other parts of kOS can use to write characters to the telent client. /// private volatile Queue outQueue; + private readonly object outQueueAccess = new object(); // To make all access of the outQueue atomic between threads. public kOSProcessor ConnectedProcessor { get; private set; } @@ -144,7 +146,7 @@ public TelnetSingletonServer(TcpClient client) inQueue = new Queue(); ClientWidth = 80; // common default for a lot of terminal progs. Will allow resize via RFC1073. ClientHeight = 24; // common default for a lot of terminal progs. Will allow resize via RFC1073. - ClientTerminalType = "UNKNOWN"; // will be set by telnet client as described by RFC 1091 + ClientTerminalType = "INITIAL_UNSET"; // will be set by telnet client as described by RFC 1091 } /// @@ -179,11 +181,13 @@ public void DisconnectFromProcessor() /// one character read public char ReadChar() { + System.Console.WriteLine("eraseme:TelnetSingletonServer.ReadChar(): My 'this' is " + (this==null ? "null" : "not null")); char ch; - lock (inQueue) // all access to inQueue and outQueue needs to be atomic. + lock (inQueueAccess) // all access to inQueue and outQueue needs to be atomic. { ch = inQueue.Dequeue(); } + System.Console.WriteLine("eraseme:TelnetSingletonServer.ReadChar(): I am going to return the char with value " + (int)ch); return ch; } @@ -195,7 +199,7 @@ public char ReadChar() public string ReadAll() { StringBuilder sb = new StringBuilder(); - lock (inQueue) // all access to inQueue and outQueue needs to be atomic. + lock (inQueueAccess) // all access to inQueue and outQueue needs to be atomic. { while (inQueue.Count > 0) sb.Append(inQueue.Dequeue()); @@ -208,8 +212,9 @@ public string ReadAll() /// true if input is currently Queued public bool InputWaiting() { + System.Console.WriteLine("eraseme:TelnetSingletonServer.InputWaiting(): My 'this' is " + (this==null ? "null" : "not null")); bool returnVal; - lock (inQueue) + lock (inQueueAccess) { returnVal = inQueue.Count > 0; } @@ -230,7 +235,7 @@ public bool InputWaiting() /// character to write public void Write(char ch) { - lock(outQueue) // all access to inQueue and outQueue needs to be atomic. + lock(outQueueAccess) // all access to inQueue and outQueue needs to be atomic. { outQueue.Enqueue(ch); } @@ -250,7 +255,7 @@ public void Write(char ch) /// string to write public void Write(string str) { - lock(outQueue) // all access to inQueue and outQueue needs to be atomic. + lock(outQueueAccess) // all access to inQueue and outQueue needs to be atomic. { foreach (char ch in str) outQueue.Enqueue(ch); @@ -290,8 +295,8 @@ private void SendTextRaw(byte[] buff) public void StopListening() { SendTextRaw("\r\nDisconnecting from the kOS Terminal Server.\r\n"); - // Must use SendTextRaw, not Write, because we're about to kill the outThread before it has time to process the Write chars: - SendTextRaw(terminalMapper.OutputConvert( (char)UnicodeCommand.TITLEBEGIN + "disconnected from kOS terminal server" + (char)UnicodeCommand.TITLEEND )); + // Must use SendTextRaw, not Write, because we're about to kill the outThread before it has time to process the queue that Write uses: + SendTextRaw(terminalMapper.OutputConvert( (char)UnicodeCommand.TITLEBEGIN + "Thank you for using kOS terminal server" + (char)UnicodeCommand.TITLEEND )); inThread.Abort(); inThread = null; // dispose old thread. @@ -304,16 +309,13 @@ public void StopListening() public void StartListening() { - // Must use SendTextRaw, not Write, because the outThread needs to be started for Write() to work: - SendTextRaw("Connected to the kOS Terminal Server.\r\n"); - SendTextRaw(terminalMapper.OutputConvert( (char)UnicodeCommand.TITLEBEGIN + "Connected from kOS terminal server" + (char)UnicodeCommand.TITLEEND )); - inThread.Start(); outThread.Start(); - LineAtATime(false); AllowTerminalResize(true); AllowTerminalTypeInfo(true); + + SendTextRaw("Connected to the kOS Terminal Server.\r\n"); } /// @@ -405,7 +407,7 @@ private void DoInThread() { char[] scrapedBytes = Encoding.UTF8.GetChars(TelnetProtocolScrape(rawReadBuffer, numRead)); string sendOut = (terminalMapper == null) ? (new string(scrapedBytes)) : terminalMapper.InputConvert(scrapedBytes); - lock (inQueue) // all access to inQueue and outQueue needs to be atomic + lock (inQueueAccess) // all access to inQueue and outQueue needs to be atomic { foreach (char ch in sendOut) { @@ -428,7 +430,7 @@ private void DoOutThread() while (true) { sb.Remove(0,sb.Length); // clear the whole thing. - lock(outQueue) // all access to inQueue and outQueue needs to be atomic. + lock(outQueueAccess) // all access to inQueue and outQueue needs to be atomic. { while (outQueue.Count > 0) { @@ -510,7 +512,7 @@ private byte[] TelnetProtocolScrape(byte[] inRawBuff, int rawLength) case RFC854_IAC: break; // pass through to normal behaviour when two IAC's are back to back - that's how a real IAC char is encoded. case RFC854_BREAK: - lock (inQueue) { inQueue.Enqueue((char)UnicodeCommand.BREAK); } // async send it out of order, right now. + lock (inQueueAccess) { inQueue.Enqueue((char)UnicodeCommand.BREAK); } // async send it out of order, right now. ++rawIndex; break; default: @@ -726,7 +728,7 @@ private int TelnetConsumeNAWS(byte[] remainingBuff, int index, out bool handled) if (width > 0) ClientWidth = width; if (height > 0) ClientHeight = height; - lock (inQueue) // all access to inQueue and outQueue needs to be atomic + lock (inQueueAccess) // all access to inQueue and outQueue needs to be atomic { inQueue.Enqueue( (char)UnicodeCommand.RESIZESCREEN ); inQueue.Enqueue( (char)ClientWidth ); From be782fb8d120b0228d2ed879dc15a2e7e71f11d6 Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Sat, 7 Feb 2015 01:59:42 -0600 Subject: [PATCH 128/446] fixed the '== null' checks problem. (Turns out it's because TelnetSingletonServer was a Monobehavior and Unity, in their infinite "wisdom" decided to override the meaining of Equals for Monobehaviors such that they always claim to be equaly to null. If foo is a monobehavior, then (foo == null) always returns true even when foo isn't null. --- src/kOS/Screen/TermWindow.cs | 6 +++-- src/kOS/UserIO/TelnetMainServer.cs | 14 +++++------- src/kOS/UserIO/TelnetSingletonServer.cs | 29 +++++++++++++++---------- src/kOS/UserIO/TerminalUnicodeMapper.cs | 2 ++ 4 files changed, 28 insertions(+), 23 deletions(-) diff --git a/src/kOS/Screen/TermWindow.cs b/src/kOS/Screen/TermWindow.cs index 5b760719a..ece79d54e 100644 --- a/src/kOS/Screen/TermWindow.cs +++ b/src/kOS/Screen/TermWindow.cs @@ -46,7 +46,7 @@ public class TermWindow : KOSManagedWindow , ITermWindow private KOSTextEditPopup popupEditor; private Color currentTextColor = new Color(1,1,1,1); // a dummy color at first just so it won't crash before TerminalGUI() where it's *really* set. - private List Telnets {get;set;} // support exists for more than one telnet client to be attached to the same terminal, thus this is a list. + private List Telnets; // support exists for more than one telnet client to be attached to the same terminal, thus this is a list. private ExpectNextChar inputExpected = ExpectNextChar.NORMAL; private int pendingWidth; // width to come from a resize combo. @@ -277,8 +277,10 @@ void ProcessKeyStrokes() /// private void ProcessTelnetInput() { - foreach (TelnetSingletonServer telnet in Telnets) + for( int i = 0 ; i < Telnets.Count ; ++i) { + TelnetSingletonServer telnet = Telnets[i]; + System.Console.WriteLine("eraseme:ProcessTelnetInput: working on a telnet number ["+i+"] which is "+(telnet==null?"null":"NOT null")); while (telnet.InputWaiting()) { System.Console.WriteLine("eraseme:ProcessTelnetInput: now calling ProcessOneInputChar, with telnet = " + (telnet==null ? "null" : "NOT null")); diff --git a/src/kOS/UserIO/TelnetMainServer.cs b/src/kOS/UserIO/TelnetMainServer.cs index e0b970299..e3f5676ea 100644 --- a/src/kOS/UserIO/TelnetMainServer.cs +++ b/src/kOS/UserIO/TelnetMainServer.cs @@ -28,11 +28,9 @@ public class TelnetMainServer : MonoBehaviour private Int32 port; private List telnets; private bool isListening; - private static TelnetMainServer instance; public TelnetMainServer() { - instance = this; isListening = false; telnets = new List(); @@ -41,11 +39,6 @@ public TelnetMainServer() Console.WriteLine("kOS TelnetMainServer class exists."); // Console.Writeline used because this occurs before kSP's logger is set up. } - public static TelnetMainServer Instance() - { - return instance ?? (instance = new TelnetMainServer()); - } - public void SetConfigEnable(bool newVal) { if (newVal == isListening) @@ -93,6 +86,8 @@ public void StopListening() public void Update() { SetConfigEnable(Config.Instance.EnableTelnet); + + int howManySpawned = 0; if (!isListening) { @@ -121,8 +116,9 @@ public void Update() string remoteIdent = ((IPEndPoint)(incomingClient.Client.RemoteEndPoint)).Address.ToString(); kOS.Safe.Utilities.Debug.Logger.Log("kOS telnet server got an incoming connection from " + remoteIdent); - telnets.Add(new TelnetSingletonServer(incomingClient)); - telnets[telnets.Count-1].StartListening(); + TelnetSingletonServer newServer = new TelnetSingletonServer(incomingClient, ++howManySpawned); + telnets.Add(newServer); + newServer.StartListening(); } } } diff --git a/src/kOS/UserIO/TelnetSingletonServer.cs b/src/kOS/UserIO/TelnetSingletonServer.cs index 9e330fae0..3f6714178 100644 --- a/src/kOS/UserIO/TelnetSingletonServer.cs +++ b/src/kOS/UserIO/TelnetSingletonServer.cs @@ -18,7 +18,7 @@ namespace kOS.UserIO /// single telnet client, leaving the main server free to go back to listening /// to other new connecting clients. ///
- public class TelnetSingletonServer : MonoBehaviour + public class TelnetSingletonServer { // ReSharper disable SuggestUseVarKeywordEvident @@ -27,13 +27,13 @@ public class TelnetSingletonServer : MonoBehaviour // actually part of the algorithm: // ReSharper disable RedundantDefaultFieldInitializer - private TcpClient client; + private volatile TcpClient client; /// /// The raw socket stream used to talk directly to the client across the network. /// It is bidirectional - handling both the input from and output to the client. /// - private NetworkStream rawStream; + private volatile NetworkStream rawStream; /// /// The queue that other parts of KOS can use to read characters from the telnet client. @@ -46,18 +46,20 @@ public class TelnetSingletonServer : MonoBehaviour /// private volatile Queue outQueue; private readonly object outQueueAccess = new object(); // To make all access of the outQueue atomic between threads. - - public kOSProcessor ConnectedProcessor { get; private set; } - private byte[] rawReadBuffer = new byte[4096]; - private byte[] rawWriteBuffer = new byte[4096]; + public kOSProcessor ConnectedProcessor { get; private set; } private Thread inThread; private Thread outThread; - private TelnetWelcomeMenu welcomeMenu; + private volatile TelnetWelcomeMenu welcomeMenu; - private TerminalUnicodeMapper terminalMapper; + private volatile TerminalUnicodeMapper terminalMapper; + + /// + /// What order was I launched in? Was I the 1st TelnetSingletonServer? The 2nd? The 423rd? + /// + private int MySpawnOrder { get; set; } private bool isLineAtATime; private bool allowResize; @@ -136,8 +138,9 @@ public string ClientTerminalType private const byte RFC1073_NAWS = 31; - public TelnetSingletonServer(TcpClient client) + public TelnetSingletonServer(TcpClient client, int spawnOrder) { + MySpawnOrder = spawnOrder; this.client = client; rawStream = client.GetStream(); inThread = new Thread(DoInThread); @@ -375,6 +378,8 @@ private void DoInThread() // All threads in a KSP mod must be careful NOT to access any KSP or Unity methods // from inside their execution, because KSP and Unity are not threadsafe + byte[] rawReadBuffer = new byte[4096]; + while (true) { // Detect if the client closed from its end: @@ -459,8 +464,8 @@ private void DoOutThread() ///
private void SpawnWelcomeMenu() { - var gObj = new GameObject( "TelnetWelcomeMenu_" + this.GetInstanceID(), typeof(TelnetWelcomeMenu) ); - DontDestroyOnLoad(gObj); + var gObj = new GameObject( "TelnetWelcomeMenu_" + MySpawnOrder, typeof(TelnetWelcomeMenu) ); + MonoBehaviour.DontDestroyOnLoad(gObj); welcomeMenu = (TelnetWelcomeMenu)gObj.GetComponent(typeof(TelnetWelcomeMenu)); welcomeMenu.Setup(this); } diff --git a/src/kOS/UserIO/TerminalUnicodeMapper.cs b/src/kOS/UserIO/TerminalUnicodeMapper.cs index 15ac908b3..dca80b77b 100644 --- a/src/kOS/UserIO/TerminalUnicodeMapper.cs +++ b/src/kOS/UserIO/TerminalUnicodeMapper.cs @@ -26,6 +26,8 @@ public class TerminalUnicodeMapper /// public string TerminalTypeString {get; protected set;} + protected readonly object lockAccess = new object(); // to ensure that multiple threads use the mapper atomicly, to avoid messing up it's state variables. + // Note that it's essential that these remain private and not get changed to protected or public. // Some of the derived classes of this class also use the same identifier name for their own // fields that have a very similar purpose, and in those cases there actually needs to be two From 92c3eda1589674fff71c75f4412a968931055359 Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Sat, 7 Feb 2015 02:41:19 -0600 Subject: [PATCH 129/446] not nearly as many things needed to be volatile. --- src/kOS/UserIO/TelnetSingletonServer.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/kOS/UserIO/TelnetSingletonServer.cs b/src/kOS/UserIO/TelnetSingletonServer.cs index 3f6714178..c7cc99759 100644 --- a/src/kOS/UserIO/TelnetSingletonServer.cs +++ b/src/kOS/UserIO/TelnetSingletonServer.cs @@ -27,13 +27,13 @@ public class TelnetSingletonServer // actually part of the algorithm: // ReSharper disable RedundantDefaultFieldInitializer - private volatile TcpClient client; + private TcpClient client; /// /// The raw socket stream used to talk directly to the client across the network. /// It is bidirectional - handling both the input from and output to the client. /// - private volatile NetworkStream rawStream; + private NetworkStream rawStream; ///
/// The queue that other parts of KOS can use to read characters from the telnet client. @@ -52,9 +52,9 @@ public class TelnetSingletonServer private Thread inThread; private Thread outThread; - private volatile TelnetWelcomeMenu welcomeMenu; + private TelnetWelcomeMenu welcomeMenu; - private volatile TerminalUnicodeMapper terminalMapper; + private TerminalUnicodeMapper terminalMapper; /// /// What order was I launched in? Was I the 1st TelnetSingletonServer? The 2nd? The 423rd? From 3fcc237a4751a1e431d52baeea8eb7e0b186e02f Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Sat, 7 Feb 2015 04:00:45 -0600 Subject: [PATCH 130/446] Added telnet zigzag connect icon to app panel Now the terminal image will be overlayed with a zigzag symbol when there's a telnet client connected to that terminal. --- Resources/GameData/kOS/GFX/network-zigzag.png | Bin 0 -> 1712 bytes .../kOS/GFX/terminal-icon-closed-telnet.png | Bin 0 -> 1894 bytes .../kOS/GFX/terminal-icon-open-telnet.png | Bin 0 -> 1786 bytes src/gimp/README.md | 10 ++++++---- src/gimp/network-zigzag.xcf | Bin 0 -> 2922 bytes src/gimp/terminal-icon.xcf | Bin 142189 -> 8391 bytes src/kOS/Module/kOSProcessor.cs | 5 +++++ src/kOS/Screen/KOSManagedWindow.cs | 2 +- src/kOS/Screen/KOSToolBarWindow.cs | 16 ++++++++++++++-- src/kOS/Screen/TermWindow.cs | 6 ++++++ src/kOS/UserIO/TelnetWelcomeMenu.cs | 4 ++-- 11 files changed, 34 insertions(+), 9 deletions(-) create mode 100644 Resources/GameData/kOS/GFX/network-zigzag.png create mode 100644 Resources/GameData/kOS/GFX/terminal-icon-closed-telnet.png create mode 100644 Resources/GameData/kOS/GFX/terminal-icon-open-telnet.png create mode 100644 src/gimp/network-zigzag.xcf diff --git a/Resources/GameData/kOS/GFX/network-zigzag.png b/Resources/GameData/kOS/GFX/network-zigzag.png new file mode 100644 index 0000000000000000000000000000000000000000..47e62ba5632c8720866852efdd912ba4d1ba3a78 GIT binary patch literal 1712 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 literal 0 HcmV?d00001 diff --git a/Resources/GameData/kOS/GFX/terminal-icon-open-telnet.png b/Resources/GameData/kOS/GFX/terminal-icon-open-telnet.png new file mode 100644 index 0000000000000000000000000000000000000000..8b55d3e2094ba7da302b5430ed0bb78a74e55a55 GIT binary patch literal 1786 zcmV-){f_28T&R zK~zY`y_Q>SRM!=TzrD|yyY2A>-^MmJU>f2W--1I#fQm~DQKEnvDg_#eRP>_ep;eXk zp=y>t9Ro2^-MPUBJ4lmo8N2g>rV3mXrs%4T}v&?P~+QyB923 z+5wy?7Ut2Z>tY51JAmKvzp)pJh55u(hxy4J@u9(RxS$Y#gf)t?^=%=V9)plC8;xcn zm7EsMX#}o!cP$GS6e5s(_b1=r;^ofUBG9;W8P7fW5*CWV-tK$nBoOikYbF;BFJ6yt z#vku!{tB&Ue$SXSHhTo{PJZX-7F5kiK%?EcZndKFK8mu6cy7}#>HK#myW3x*ceHob zGrm4>Y_FJTcOIJJZkC@lq$?`#V`2V69M_?)rH1lwIsIe(vmer+{NPP{q(+AjToh7V z2Tquu75vWPJ6V{&h>cs;1CUH7P+HA?PyiBw3BMtP*n=kNY8Qdn`>7+aYQbt6%NnUK zsb}Ms^|b9h0>GFxjudnMMz|og6#hmNf0G#mf(WY2PjhR(>7yai$XzA1G;FA)_4R$E z9SeZUyh_|T(#Gs_Gvz#`qJFC(V@U-XF=x!jSwI zR84Ezh51Efhr$5(13@ZEt5{pLmQ@uiX>3^vz@hy|IX8Ho!Mp)(7HKFq|JXErNS;b> zl~O*dwJr-Zc>ox>>Y%bgh7D$t7#Y{ds7t8YWGt${)ySA8w8TU5oQ;|%5w=E^8Mr_i zb?bRR3h6?IUX$VVMQ+_OZ7Qj*rDQ6nRTo z6kL)?!v0}OmlxCX?p3ZtKVZVJdPYQi)BP3eIxY+MOQ(CvH0a z-1lZnG7*mq#fK(h!_jzIq-UOp@I9CuPXsCZW36uGP3RPKmPQ?*4EcBy(UsfJYEy+ zY7EoB<25i0i9hIJX>}bXc@aLpY9-x+A8~!ShrgdYf?*o?0v>`{euCM4vco=H?XqR_ zS7~lu&ar>K!?9Bb`10dVW!>FSJ-V-T|GNgj3%h={>cw5pzxCef_l>mWU|Tjq2&|Ms z0a^%@t+CS@DFyR_5&m-g03lx%J$*eKI&ly*IF>_t!bZD_RKg;iN|PM7xb)$_c=WOF z&~@%4v4J5@96!YNuYG?*?UJ%zi&tBBZf$vF`x`<^1YkQ3yLUaq$>XPRw2ja3Pj*qQ zU9<~AL*4wl>F7QQS|g3jb2T;J%hv7RL@5WM1^z$?X&9hg3~i&N52X~gHGxtN@mN%e z?&PTU2ZFa4WCWVI$8rHP?o!IZxY2Ixbei$_5FTFupFe=d>mxZnis*N3?bw;#ZWv~U c@&D2O1Es6J_K*8|?*IS*07*qoM6N<$f)l%3nE(I) literal 0 HcmV?d00001 diff --git a/src/gimp/README.md b/src/gimp/README.md index c3f2e356c..df10763e0 100644 --- a/src/gimp/README.md +++ b/src/gimp/README.md @@ -9,9 +9,9 @@ As such, the .xcf files were added to GIT because they are, essentially, the "source code" for the images. However, they don't need to be put into exported ZIP files for installing. -### terminal-icon.xcf +### terminal-icon.xcf and network-zigzag.xcf -This file is used to create: +These file is used to create: * terminal-icon-open.png * Make the layer "Ready?" and the layer "Highlight" visible. @@ -21,7 +21,9 @@ This file is used to create: * Make the layer "Ready?" and the layer "Highlight" invisible. * Temporarily resize to width 32. Do not save the resized small version. * export to PNG +* terminal-icon-open-with-zigzag.png + * This is just the merger of terminal-icon-open and network-zigzag together. Unity is not good at overlaying two PNG's into one Texture2D so instead I just did that work external to the code and made it a separate file. +* terminal-icon-closed-with-zigzag.png + * This is just the merger of terminal-closed-open and network-zigzag together. Unity is not good at overlaying two PNG's into one Texture2D so instead I just did that work external to the code and made it a separate file. -(As of this writing there is only one .xcf file) - diff --git a/src/gimp/network-zigzag.xcf b/src/gimp/network-zigzag.xcf new file mode 100644 index 0000000000000000000000000000000000000000..45a88a4ab456a7fd41860d25eadafe9865a506f8 GIT binary patch literal 2922 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 Xnm-#yUK)Fwe<3gZM87<#A}{?Pe)~!% literal 142189 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 @@ -114,15 +118,21 @@ public void FirstTimeSetup() const string LAUNCHER_BUTTON_PNG = "GameData/kOS/GFX/launcher-button.png"; const string TERMINAL_OPEN_ICON_PNG = "GameData/kOS/GFX/terminal-icon-open.png"; const string TERMINAL_CLOSED_ICON_PNG = "GameData/kOS/GFX/terminal-icon-closed.png"; + const string TERMINAL_OPEN_TELNET_ICON_PNG = "GameData/kOS/GFX/terminal-icon-open-telnet.png"; + const string TERMINAL_CLOSED_TELNET_ICON_PNG = "GameData/kOS/GFX/terminal-icon-closed-telnet.png"; // ReSharper disable SuggestUseVarKeywordEvident WWW launcherButtonImage = new WWW("file://" + KSPUtil.ApplicationRootPath.Replace("\\", "/") + LAUNCHER_BUTTON_PNG); WWW terminalOpenIconImage = new WWW("file://" + KSPUtil.ApplicationRootPath.Replace("\\", "/") + TERMINAL_OPEN_ICON_PNG); WWW terminalClosedIconImage = new WWW("file://" + KSPUtil.ApplicationRootPath.Replace("\\", "/") + TERMINAL_CLOSED_ICON_PNG); + WWW terminalOpenTelnetIconImage = new WWW("file://" + KSPUtil.ApplicationRootPath.Replace("\\", "/") + TERMINAL_OPEN_TELNET_ICON_PNG); + WWW terminalClosedTelnetIconImage = new WWW("file://" + KSPUtil.ApplicationRootPath.Replace("\\", "/") + TERMINAL_CLOSED_TELNET_ICON_PNG); // ReSharper enable SuggestUseVarKeywordEvident launcherButtonImage.LoadImageIntoTexture(launcherButtonTexture); terminalOpenIconImage.LoadImageIntoTexture(terminalOpenIconTexture); terminalClosedIconImage.LoadImageIntoTexture(terminalClosedIconTexture); + terminalOpenTelnetIconImage.LoadImageIntoTexture(terminalOpenTelnetIconTexture); + terminalClosedTelnetIconImage.LoadImageIntoTexture(terminalClosedTelnetIconTexture); windowRect = new Rect(0,0,width,height); // this origin point will move when opened/closed. panelSkin = BuildPanelSkin(); @@ -448,8 +458,10 @@ private void DrawPartRow(Part part) GUILayout.Box( new GUIContent(powerLabelText, powerLabelTooltip), powerBoxStyle); if (GUILayout.Button((processorModule.WindowIsOpen() ? - new GUIContent(terminalOpenIconTexture, "Click to close terminal window.") : - new GUIContent(terminalClosedIconTexture, "Click to open terminal window.")), + new GUIContent((processorModule.TelnetIsAttached() ? terminalOpenTelnetIconTexture : terminalOpenIconTexture), + "Click to close terminal window.") : + new GUIContent((processorModule.TelnetIsAttached() ? terminalClosedTelnetIconTexture : terminalClosedIconTexture), + "Click to open terminal window.")), panelSkin.button)) processorModule.ToggleWindow(); diff --git a/src/kOS/Screen/TermWindow.cs b/src/kOS/Screen/TermWindow.cs index ece79d54e..1cff0bd55 100644 --- a/src/kOS/Screen/TermWindow.cs +++ b/src/kOS/Screen/TermWindow.cs @@ -631,6 +631,12 @@ internal void SendTitleToTelnet(TelnetSingletonServer telnet) for (int i=0; i 0; + } + private int HowManyRowsFit() { diff --git a/src/kOS/UserIO/TelnetWelcomeMenu.cs b/src/kOS/UserIO/TelnetWelcomeMenu.cs index 33aef76ec..3c27fba3e 100644 --- a/src/kOS/UserIO/TelnetWelcomeMenu.cs +++ b/src/kOS/UserIO/TelnetWelcomeMenu.cs @@ -33,9 +33,9 @@ public TelnetWelcomeMenu() availableCPUs = new List(); } - public void Setup(TelnetSingletonServer tserver) + public void Setup(TelnetSingletonServer tServer) { - telnetServer = tserver; + telnetServer = tServer; lastMenuQueryTime = System.DateTime.MinValue; // Force a stale timestamp the first time. telnetServer.Write( (char)UnicodeCommand.TITLEBEGIN + "kOS Terminal Server Welcome Menu" + (char)UnicodeCommand.TITLEEND ); forceMenuReprint = true; // force it to print the menu once the first time regardless of the state of the CPU list. From cab7c0199409cd14c47a38fe26c569814ad02669 Mon Sep 17 00:00:00 2001 From: Chris Woerz Date: Sun, 8 Feb 2015 09:55:52 -0700 Subject: [PATCH 131/446] changed orbitable to new suffixes --- src/kOS/Suffixed/Orbitable.cs | 102 ++++++++++++---------------------- 1 file changed, 37 insertions(+), 65 deletions(-) diff --git a/src/kOS/Suffixed/Orbitable.cs b/src/kOS/Suffixed/Orbitable.cs index e62cf9ecf..fbf4c11e8 100644 --- a/src/kOS/Suffixed/Orbitable.cs +++ b/src/kOS/Suffixed/Orbitable.cs @@ -1,4 +1,5 @@ using kOS.Safe.Encapsulation; +using kOS.Safe.Encapsulation.Suffixes; using kOS.Utilities; using UnityEngine; @@ -14,6 +15,7 @@ abstract public class Orbitable : Structure protected Orbitable(SharedObjects shareObj) { Shared = shareObj; + InitializeSuffixes(); } /// @@ -203,7 +205,41 @@ public double PositionToAltitude( Vector pos ) return parent.GetAltitude(unityWorldPos); } - private object BuildPatchList() + private void InitializeSuffixes() + { + AddSuffix("NAME", new Suffix(GetName)); + AddSuffix("APOAPSIS", new Suffix(() => Orbit.ApA)); + AddSuffix("PERIAPSIS", new Suffix(() => Orbit.PeA)); + AddSuffix("APOAPSIS", new Suffix(() => Orbit.ApA)); + AddSuffix("BODY", new Suffix(() => new BodyTarget(Orbit.referenceBody, Shared))); + AddSuffix("UP", new Suffix(() => new Direction(GetUpVector(), false))); + AddSuffix("NORTH", new Suffix(() => new Direction(GetNorthVector(), false))); + AddSuffix("PROGRADE", new Suffix(GetPrograde)); + AddSuffix("RETROGRADE", new Suffix(GetRetrograde)); + AddSuffix("SRFPROGRADE", new Suffix(GetSurfacePrograde)); + AddSuffix("SRFRETROGRADE", new Suffix(GetSurfaceRetrograde)); + AddSuffix("OBT", new Suffix(GetOrbitInfo)); + AddSuffix("POSITION", new Suffix(delegate() + { + Safe.Utilities.Debug.Logger.Log("Position got Called"); + return GetPosition(); + })); + AddSuffix("VELOCITY", new Suffix(GetVelocities)); + AddSuffix("DISTANCE", new Suffix(GetDistance)); + AddSuffix("DIRECTION", new Suffix(() => new Direction(GetPosition(), false))); + AddSuffix("LATITUDE", new Suffix(()=> PositionToLatitude(GetPosition()))); + AddSuffix("LONGITUDE", new Suffix(() => PositionToLongitude(GetPosition()))); + AddSuffix("ALTITUDE", new Suffix(() => PositionToAltitude(GetPosition()))); + AddSuffix("GEOPOSITION", new Suffix(() => new GeoCoordinates(this, Shared))); + AddSuffix("PATCHES", new Suffix(BuildPatchList)); + } + + private double GetDistance() + { + return GetPosition().Magnitude(); + } + + private ListValue BuildPatchList() { var list = new ListValue(); var orb = Orbit; @@ -222,69 +258,5 @@ private object BuildPatchList() } return list; } - - public object GetOnlyOrbitableSuffixes( string suffixName ) - { - // This is a separate call so that it is possible to distinguish - // those suffixes that are in the base class from the ones in - // the subclasses. If you want ONLY the base class terms to be - // parsed, without parsing terms defined in subclasses, then - // call GetOnlyOrbitalSuffixes. - switch(suffixName) - { - // These first cases are an exact copy of what Orbit object did, - // for backward compatibility: - - case "NAME": - return GetName(); - case "APOAPSIS": - return Orbit.ApA; - case "PERIAPSIS": - return Orbit.PeA; - - // The cases after this point were added to Orbitable from either VesselTarget or BodyTarget: - case "BODY": - return new BodyTarget(Orbit.referenceBody, Shared); - case "UP": - return new Direction(GetUpVector(), false); - case "NORTH": - return new Direction(GetNorthVector(), false); - case "PROGRADE": - return GetPrograde(); - case "RETROGRADE": - return GetRetrograde(); - case "SRFPROGRADE": - return GetSurfacePrograde(); - case "SRFRETROGRADE": - return GetSurfaceRetrograde(); - case "OBT": - return GetOrbitInfo(); - case "POSITION": - return GetPosition(); - case "VELOCITY": - return GetVelocities(); - case "DISTANCE": - return GetPosition().Magnitude(); - case "DIRECTION": - return new Direction(GetPosition(), false); - case "LATITUDE": - return PositionToLatitude( GetPosition() ); - case "LONGITUDE": - return PositionToLongitude( GetPosition() ); - case "ALTITUDE": - return PositionToAltitude( GetPosition() ); - case "GEOPOSITION": - return new GeoCoordinates(this, Shared); - case "PATCHES": - return BuildPatchList(); - } - return null; - } - - public override object GetSuffix( string suffixName ) - { - object returnVal = GetOnlyOrbitableSuffixes(suffixName); - return returnVal ?? base.GetSuffix(suffixName); - } } } From 38a032208c8f7699830eefb2107bcdab4c5ffbeb Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Mon, 9 Feb 2015 00:52:27 -0600 Subject: [PATCH 132/446] Input side nailed down. Crude full-redraw output. Now next to work on the more sophisticated selective redraw ouptut. --- Resources/GameData/kOS/GFX/network-zigzag.png | Bin 1712 -> 979 bytes src/gimp/README.md | 23 +- src/gimp/network-zigzag.xcf | Bin 2922 -> 0 bytes src/kOS.Safe/Encapsulation/IConfig.cs | 1 - src/kOS.Safe/Screen/IInterpreter.cs | 2 +- src/kOS.Safe/Screen/TextEditor.cs | 17 +- .../UserIO/UnicodeCommand.cs | 29 +- src/kOS.Safe/kOS.Safe.csproj | 4 + .../RemoteTech2/RemoteTechInterpreter.cs | 5 +- src/kOS/Screen/Interpreter.cs | 9 +- src/kOS/Screen/TermWindow.cs | 258 ++++++++++++------ src/kOS/Suffixed/Config.cs | 5 +- src/kOS/UserIO/TelnetMainServer.cs | 15 +- src/kOS/UserIO/TelnetSingletonServer.cs | 220 +++++++++++---- src/kOS/UserIO/TelnetWelcomeMenu.cs | 65 ++++- src/kOS/UserIO/TerminalUnicodeMapper.cs | 20 +- src/kOS/UserIO/TerminalVT100Mapper.cs | 53 ++++ src/kOS/UserIO/TerminalXtermMapper.cs | 1 + src/kOS/kOS.csproj | 1 - 19 files changed, 537 insertions(+), 191 deletions(-) delete mode 100644 src/gimp/network-zigzag.xcf rename src/{kOS => kOS.Safe}/UserIO/UnicodeCommand.cs (87%) diff --git a/Resources/GameData/kOS/GFX/network-zigzag.png b/Resources/GameData/kOS/GFX/network-zigzag.png index 47e62ba5632c8720866852efdd912ba4d1ba3a78..5c7d986ccc18b1c3070ee380e3792cf4550461c3 100644 GIT binary patch delta 910 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 /// A list of extra unicode command characters we use to genericize command codes, abstracting away @@ -47,6 +47,11 @@ public enum UnicodeCommand /// CLEARSCREEN, + /// + /// (input only) keypress that means "please do a full redraw for me". + /// + REQUESTREPAINT, + /// /// Tell the terminal to resize itself to a new row/col size. Not all terminals will be capable of doing this. /// This can be communicated in either direction - for the client telling the server it has been resized, or @@ -75,6 +80,9 @@ public enum UnicodeCommand /// Begins a cursor move to an exact position. Expects exactly 2 more /// unicode chars to follow, interpreted as binary number data (not as characters) /// for the row num and column num, respectively. + ///
+ /// Note that the pretend Unicode terminal counts rows and columns starting from 0. When converting + /// for a terminal type that counts starting at 1, you may need to add 1 to these numbers. ///
TELEPORTCURSOR, @@ -171,12 +179,27 @@ public enum UnicodeCommand /// this one. This character means go to the start of the next line. /// Also used on input to represent hitting either the return or the enter key. ///
- NEWLINERETURN + STARTNEXTLINE, + + /// + /// Perform a linefeed straight down (the official ASCII definition of a LF char, + /// where it doesn't go to the start of a line). You can probably just map this + /// directly to a LF in most cases and in fact the base mapper class will do that. + /// + LINEFEEDKEEPCOL, + + /// + /// Go to the start of the current line. withiout line-feeding. (the official ASCII + /// definition of the CR character). You can probably just map this directly + /// to a CR in most cases, and in fact the base mapper class will do that. + /// + GOTOLEFTEDGE, + } // For tracking multiple-character input sequences to remember where it is in the sequence: public enum ExpectNextChar { - NORMAL, RESIZEWIDTH, RESIZEHEIGHT, INTITLE, + NORMAL, RESIZEWIDTH, RESIZEHEIGHT, INTITLE, TELEPORTCURSORCOL, TELEPORTCURSORROW } } diff --git a/src/kOS.Safe/kOS.Safe.csproj b/src/kOS.Safe/kOS.Safe.csproj index 9540f3976..857065b31 100644 --- a/src/kOS.Safe/kOS.Safe.csproj +++ b/src/kOS.Safe/kOS.Safe.csproj @@ -140,6 +140,7 @@ + @@ -157,6 +158,9 @@ Resources.Designer.cs + + + 4nQ>auZiT+1Zq8tRk2Pu#* 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

uW+$ZLLn8nTQ=-xAT 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%0DKnaQDlDziV&r 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

Gn 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%0D8HggME4-;SHE8;*F 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
  • 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ð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

    $;+lVi#G&blPahQm18u7oY zmnXGsU48jpu+JTCA_=0bFz%VWC2Hs;pNCmfQsVmgr7h=>`ypE{xH)N68| z_pM`^Yiuxgs~o}i2o-{rq%w-D@Jm5;Go<{ct4dK7sdT)2&pr3v`>HT4^^RPo;o{-< zD5`?m>&nUY<$HpAdL5>;3GSLRoLz5jgmP=k3dctdm(rfW`l{xBpSxU9f#~p_UNF7m?=+I6zvXFd4T+3tDalSN?uO=f zg^XGtTeOPshP-mHzF#V}8f9Mi=~84x>m4uOefK^0fNObAr&HjO_m`iTMjKZp;yPa4 z9o*d$Bjdo(FbYYuLN)}$s>!ajS&tgtElydp>lg)49B$~rHP%E~yK)64ssifJt4(sl znInV7iFKwKIRECYftk?PxY6EMnrw-Kj1z7Tn%tvkLvu6aURw_HrMtts!PHU(HXQ%C zX`Q8babUckS4ynO=B2yf5jT+H{gb;lrNHr5ykY527jKl}YPGE6rMvFB`))&(`NuB} znnOHzP#wWYCV@vb+C8dVM4{sJD6@<|Y#zKEk)=tv#-*3;3hv6#uKAa>q&?;QOfwHg zY{K^`%O$SSJ@ZP_!o_m^&3`dc(+xqxK$;m(3Q-BS@0BKISoxRodS<2v$SULaR1gad zo_eKefrVr~p$xT6%AQmQ)gw%GWi?Qj`l>;^7Z!rn(9f#I%v$XCntFT*TCIqAgl-aP z&`%|X<-f>J^U-o;RJ4IeV+E5d)3Ol5#$LFil=6zD*I!d^#E9NOPzeSJa8_5Xo~XxJ z8(ULbQ@tu!H6qkcmMW5$Xn5Cv@fL4@AQva1A%jamO4?=5ulYm;%yYt&w}nfp9yX-I zbRYkk<5am(=rvTl!>TnwLy(?mSQ9D%j>oldenO*e%-o3v!eGR@!rU!I<_&V4_!k9S zzJ#QGDZx2h(Fgq?GtJK^dhO%`2Dn- z)ZG{v$zHQio?dNzLsdhV?g34U4b>}`UN`^B($2<+wCen5+ElA!u(%N~lVL}*OBY>T z2^rB|?Va$TZXEf5*uxMoJw`%TC$Kqg8B?m3SJ=?g00^7<7tN~mty)Hsb{2cH;q%cg=zB+1x84ViN2DvfF#XW0@Q_)2^d z!3&oxLpX}9rZaLB+$+YZh}I(xEmCfbScNfH)zItWjY%;Xu0#w=nH>pK>ebhP07T2w9;`hsSVZm`|?@YxlS?ak1MnWU$0(pot8{%SF2;SbwORPY28wqy!um>a2aV=U489!OO}hZH3U?(P;1RD zy>7w$PgX)@oPm1%Qc#1H{U#VZmF3HpULRaPa^1qpG{d2*h&+X?R#y#T*vJN;w2Oj8 zqmy(P3oK;u7bUDwG>FMxu?)Ffzwnw*f2;zpXm>sXobg?=I#?alo~@}S*rmg6yj1M4 zcmlR2t!>7Ob zjcRpj&S_*4D)sqE=*d_DMj);*6uz31*c?Z@MU=+nF% zzm3=Iz>Cqexm%Y@44?k`*KhMLV_f%=lSu5=C|z!5cb9O|>gliF7Tl($*e@Q}rQPLw zdE%}z=}yh$JXJfYWmi6UT)P9OcAZ4R;e1f49Uv2@ZwswzHlf5->o7nav%)vm5!gEd z`(=B<4hILOa|_vTDA4HOl!k?x~|}UCcqpTUD-2 z4Zm~SZMUk5RjKSdx7`}ts@9RrJGX}KuNd4q_%)+QCy}{N@vl*J!L8$Z?pS+??Qgt{ z)^EM_Yq`f9BNiR3E1JjlYG)|D=;D5t>^rx9E%=(K%a=}0E-;oYlibCb2$vH`1UK={ z*TRzOOcoU(Vlf2B14uS&2D;C+Ep;Kiq{>ls-XECb|M8Lt*`bL*?0|+CJYu&eMw~xi zbQ<_?#E0RNfBBbR{_^uJi~?7D&KJM@R+iKq;Nt)J>JD487~x ziy;WQ?7pFVz^F!n>KZwYG1V{}KH1gvB~>N0RaGD0KV3JeY78QKvg=F1m$E+-NK}b{ zbPcI?CwIy4U^vkB?zWSF4&Mx{4*w8GIPFRO9^?2BjaW_$)RuqFjLJdA`>8NGC%*Kh zn}v?iIq{{NgPYYXs(<3-J;1`WLZA8ZiLHDImMZwMEdMBQK zNL`;}FNROteDfEh=Nz752h3J+<*|vx-!^-Jfo4zK{KeplA~}*vPA2d!s<9MI^1u*9 z023#^7#39H^O=>qdV#)^;{Sh}k z9q;L<#O3kM7o8mczWYUcsfb#m0q*bo)bQbL?lFE)yytY5 zcK_>gG~V)63rM_;k#K}4<0T!|S6jSfVvSMpV|b|(8+4+l4j0h54u`dE!9m8=I7lX9 zp6Hs4nW-K-(jfnE?(*#vf21Z$?9O_%JoAYJlUa9k34j+=ZLu&+|E~@1RB= zTx2#$4n~)qXm6G76*|7y%+wI(Mn@_f26%Y0pyOKS!WAr2%6S&E?Hq*(!Hozm-XORT zn)q5v&oEPm^&wN%$`gk-hf(oWo{n#FkMqjIud?dm9%oI9)qivx0^E2XOG|a7|Q_(3^dGONX(76=+WX7@J$_|h8VV0&f zW+Bd7Lyb9rOVI9?WarQG7XuTdPAIrSixgz(ejXir$?(Ue28DYyD6&_ZVGaLo~)`y33PKp%Qe=0P7kA&&bhx%8N1C1 zf!#z>u)B-VKLY}9Z3 z935<<>_7;p!~Z!vNkXr{^(A$04>5j!+?M&snAiV z$N>{nm?yjGKxU=5zEQEI^@{$Z zxpso070(I*Ihtjl*F1DVCReQ&V$9Pm7btYwF&Ht%-N zh>bcQf6xvgGrm=I&&s=9J_Ryo4x_ASIPc{QkIGm|f^Lu@HQKlF)(0d&HfKcu?FKocsb#cl~_s5I12QY#n7ZS^0I?tbht2e zs9z{<=e!2TZYYJ#<`+c&eo7-)nHr^ae5{|lfp$)Q3S(Fdbt#b?IJz=`)4>b=vjOk( zOEz}pVW?tXxn^6eb7VbcMH!7kupa4>EP%HH8k^E=2+ao!QyExf;*B7YG3x2AVaz2s z@+pwsz{1=Ww6HKQ%i#`@o!+hdN9Vjo$2G`-TQZj8eiO=NjDSkBIiv?4SI z8)KM*D-XrA0m?o7X3S`S=!u6#ND{c8gJm)>Pv)D+kS3y_NfGyqh5QCh_QuS2QY&5! z%`b)N4#N_CDvD}v9-RMBNMJ_OH^z>CWDph*di(iac}a#zVJN3x(A_yN9b1I8Ha;&- z4M(#$blXJclmIq!W}^*woAoRd#D%oES96fG!t9d9rB0D_Mnr?2l>-B_UfCjx293W6 zZ&otkbPkAQVBtgO*E672WRmk;doH}=vCrpWb}nR|bCb0nrq&aiw$VF3I{iG}Id4Ne zNY_f&FUifjx|K&mV?yaspv}gp*So}E@O>Oj&2E12`SiMFQW|+Qr&f7@0d%VV8n>V}7HZK81 zHWiek)vw!c?KEx(hyqfp9!AIuVW^>C%&U>Z%TNXHG7|<0 z07To(-Q}+YDZVCQ*>xHh7>>Ke9kv*Xrh=+ee}tnU<|)xokSPVgO}*Z;w#2YtQ2u`0 z+AbndrVGvQrX@BfnNo$_noAWNCfx5n*Gs_0IueNHR7_U)uw5Qy<6r}F`-`al=~ zyL?zA0FP{55cL|J+y)(A7LDk2hm?)sci}tKF>Ix7$RwKjj3e-y_iifVFC3<0YDh(E zqN*FW91Uga%c-yd(M1tr+Pq9k?&w+z~)`AXDP?c-9R; za|%6upeO1_(b zwFBqQoIJ``tnDYB3ZKdz-wD8Y;~~L~-;~*zzJOl`4)H77cqn~IdPv(X@_@tiL?bng zryFn2RAsV_2Qp!1;!wJZ#|hAjOYr|tPd<|#yD5{oDLt*Eh52+K@rC-yi%axRCOvCX zumQkeVB;a6LkAtC`;+-+_4Yf2%udI^vuaIz;@i*ro~r%}WB4cxH(89DEa2YQPGkZv zgY<-C1ot!IJ~9i^z6zw+u;xF$QvKCDnVoaBBPun~c>AIBjP!^jU@GXt9z8QnvOGY; zNHHu|Lt!7B(hT_;4y0$o98jY$`x4BsaV4IZ{?sX+{?Rn9GyEr=oQ459aq#)nTcsn?ih-kZk8m1TFH??sSG zWooA=i4-O76eUWc7E($nGs_iOhUP;Fs4p#`=aU=y$o|%22(xG~Oji%>!4%LKAY~6+ zJ=p*YMg!GmcN?Q_18HK~E{_}SYHuu;Ww&#@l+$)rl`55@7VgW;?|;s{FJ6!lFQ`UB{dw$=rZff!QCx98XHC3Ck3f75#e-uLFxxlMgro%_At{^nP>*!bdyzf$^@ zjqm&f*XyI!a^v28>LeR;cl3C4j;$)yMr6>p=H~7t$^E&~+y-5j=Qi&oMDw?5nqAF- zyy*3*Wc}XUoR()Y)P|FdTeWw=a9;o~GAjHaV{Nv;+hR`asN-{z+|NA^{nOlG;;LUJqp5F7}_-iy>`O42EU(4p> z*z1{SyvhLg?~s(NIJP?mZ=G9bP#6IVC_2=G-h#XHS(A0d#Ab;@9`-Xa`AkgA9Q=I~ z6YAAwC@4Fiy@i&AH850{%Fex(WNGIXhAJeoMI{NaMOlg$u{2fV{b`Ji4~^EFMbHHE zI?w&gCSVQf7^@84>_tQPhW4fyerGm^>W*WX%|YL5-P4-6CpWNV%<_tx<(gJ6>XGv8 zU%)%HCd(#IfnqE2!%1Ur3w3fl|K;0Ba`g)z{6gs$HvUNcZ`@X+jhWl546fgp84kCQuB;L0+?}D9;hFMG zdZT4#b6AnjUCCC~23h&k*Qb(nhVF=bvMxa5E=!KtcOr|sNBFmSgQ%zeqx8ngOmbUz zQXjuddAi^P(B*xX2f%E|o9T_6EPhF(a3;3VLne&e=JGs;4-+_CCzBjU}5BY~=rMPkE` z#lk%0s38 zT57U3z90y6X}(;cX!X8>+A>mD&YMjCW95k!uT&6YZAqV6H?xnA?e3?0`p96dN)~&z za-}aMK4ay~*W1*L(zPL}rAXoRZA0g_4@{}o(c&iPg;lUnau#&C@+Zt$Q+SYlzW=^z zTk7U^1W&b&NcSv*@wZ~MaqzIFMMX{DDX@YZ%VaCo!2_<+2enO%?5e#5knP{09OD|j z=Y^HgHLa{rZP(JPint7w>)?5YI#VfER`poRudG7aj6(-1D$}y8IS4+R5>th6PQdVV zGW`a{_DYA3)!XoT119Ybl;5po&-ba2B8T)?o^Kb}ZVHuw!j%2hg5slz3%%R(fR1XI zyR0i#8Q%dv@zWL@LqEB8Y2{gvNGJufTB6jU3A-!b%?1=6b!7f9G9R&SB;5bd#%~oW zlj(osmc;;C>m#;^#bu$vD{7<=hKE+QH-$%a zB{vhja8a#c=Q}A?7Qw^k0%IG4M^c8BcPWHTXAx>=;NR6fiSJfj4SdJ}vr7SXAcm^4 zzt7OtU!4P{B5?@P9 zY5%el%XV$Jc@T=bZU01dMD|fQs0mPJ!A$QfNMjXp4=V)5ulFmh^?_=wSfn8}{&KQ@ zXU={sYB~67H924R5`kB=S!B4EP)Abz;QpL;j8iQm%+zgSL0d4m&r-xHwS|z}rwNsG zJ+;C?tb(jF%$zMTOs3xqm626y>)}qdhxFcNGS@Pv z)f$m5y$3-Jp1;{wLY7h0`^(JN=oiPY-#n5fdz#LzC-<$txg`)XTte^Qysdc+?(B^N zmBdy!eAU9(AlwKUwH#DkX|k!rwFynfCw7Y;&-|&eiXYt3ng8vzYqqqD|NLZw2Y2QW zvcQp^KthSoD-asuxd7ft1`Sde@GFTqe&(-*5bsVmGg-1}℞Ip#04Dmg)hWKH% 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 z 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

    Pz4JO&(6oW>Vd;odH@$}bfhJm)_E? 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 literal 0 HcmV?d00001 diff --git a/doc/source/commands/terminal.rst b/doc/source/commands/terminal.rst index 13f250fa2..0d0ceef19 100644 --- a/doc/source/commands/terminal.rst +++ b/doc/source/commands/terminal.rst @@ -18,6 +18,14 @@ Terminal and game environment PRINT 4+1. PRINT “4 times 8 is: “ + (4*8). +.. global:: SET TERMINAL:WIDTH. GET TERMINAL:WIDTH + + Gets or sets the terminal's width in characters. + +.. global:: SET TERMINAL:HEIGHT. GET TERMINAL:HEIGHT + + Gets or sets the terminal's height in characters. + .. function:: AT(col,line) :parameter col: (integer) column starting with zero (left) diff --git a/doc/source/general/telnet.rst b/doc/source/general/telnet.rst index 25a55877b..848629500 100644 --- a/doc/source/general/telnet.rst +++ b/doc/source/general/telnet.rst @@ -6,6 +6,9 @@ The kOS Telnet Server kOS now supports the abilty to enable a `telnet server `_ inside Kerbal Space Program. +.. figure:: /_images/general/telnet.png + :width: 95 % + Telnet is an old network protocol designed in the early days of the internet, long before World Wide Web. Its purpose was (is) to allow you to get access to the remote command line interfaces of distant server computers, acting as if the @@ -43,14 +46,16 @@ For Mac You shouldn't have to install anything. There should be a telnet client already installed, which you can access by opening up your command terminal, and then running it as a command-line tool. To see how to use it, read - below in the section titled "`HOWTO: Command-line client`_" + below in the section titled "`HOWTO: Command-line client`_". The built-in + Terminal.app for OSX understands the XTERM command sequences that kOS uses + and in fact identifies itself as a type of XTERM when used with a telnet + client. For Linux You shouldn't have to install anything. There should be a telnet client - already installed, which you can access by opening up any shell terminal - window which reports itself as being an XTERM terminal type. (When in - doubt, try running the program actually *called* "xterm".) To see how - to use it, read below in the section titled "`HOWTO: Command-line client`_" + already installed, and an xterm program already installed in most any Linux + distribution. Open an xterm window, and in that window type the telnet + command, as described by the section titled "`HOWTO: Command-line client`_" Using it -------- @@ -130,6 +135,22 @@ Using it cause the in-game window to change size to match. (If your terminal type is XTERM, then the same thing works in reverse. If it's VT100 then it doesn't.) +.. warning:: + Certain implementations of the xterm terminal emulation and the telnet cliet have + created a strange unending cascade of terminal resizes when you have two different + telnet clients connected to the same GUI terminal and one of them is dragged to a + new size. Because some implementations don't wait until they're done resizing to + report their new size through telnet and instead report their intermediate sizes as + they are being stretched, the attempt to keep them the same size causes them to + effectively "argue" back and forth with each other, constantly changing each + other's size. If you experience this problem (your terminal window will be + fliping back and forth between two different sizes, resizing itself over and over + again in a neverending loop), you can try to get out of it by issuing a hardcoded + command to set the terminal size, such as:: + SET TERMINAL:WIDTH TO 50. + Doing this should force all the connected telnet XTERM windows to stop arguing with + each other about what the size is, and get them synced up again. + 10. At any time you may disconnect your telnet client from the terminal by hitting control-D as the first character of a new line. This will bring you back to the telnet welcom menu again. From 4599359432ad835b33e36b88181c1ff30e5c37e1 Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Fri, 13 Feb 2015 20:09:48 -0600 Subject: [PATCH 148/446] added more docs for the developer or hobbiest For anyone trying to make a custom telnet client to talk to our telnet server. --- doc/source/general/telnet.rst | 103 ++++++++++++++++++++++++++++++++++ 1 file changed, 103 insertions(+) diff --git a/doc/source/general/telnet.rst b/doc/source/general/telnet.rst index 848629500..dbe5d0027 100644 --- a/doc/source/general/telnet.rst +++ b/doc/source/general/telnet.rst @@ -333,6 +333,8 @@ and software developers trying to make interface mods that pretend to be kOS terminals. If you are neither of those two, then don't worry if this section looks like gibberish to you. It can be skipped. +**TELNET PROTOCOL** + If you wish to make your own homemade telnet client and connect it up to the kOS telnet server, the following is the required subset of the telnet protocol that your telnet client must speak, and the terminal requirements it must @@ -377,3 +379,104 @@ you are trying to create some sort of hardware rig. These days a small cheap mini-hardware implementation of linux should be doable, and could include the telnet client installed in it for very little storage cost. +**TERMINAL EMULATION** + +As of right now, the terminal emulation of kOS only really supports XTERM +or VT100 well, however the infrastructure is in place to support modifications +to map to other terminal types. If you want to try a hand at adding the +terminal emulation for a currently unsupported terminal, you'd do it +by subclassing the kOS.UserIO.TerminalUnicodeMapper class. You can +look at kOS.UserIO.TerminalXtermMapper as a sample to see wht you need +to do. + +If you have a project where you want to just work with the terminal +codes already supported, then these are the subset you need to support: + + + +*ASCII* + The following terms should have their normal ASCII meaning: + +0x08 (control-H) + backspace key + +0x0d (control-M) + Return key. On output it means go to left edge but don't go down a line. + A typical eoln needs to occur using its ASCII standard of \r\n. + +0x0a (control-J) + On output it means go to go down a line but don't go to the left edge + A typical eoln needs to occur using its ASCII standard of \r\n. + + + +*Terminal codes* + The following terms should have their VT100/XTERM meaning: + +Left-Arrow + ESC [ D *-- both on input and on output* + +Right-Arrow + ESC [ C *-- both on input and on output* + +Up-Arrow + ESC [ A *-- both on input and on output* + +Down-Arrow + ESC [ B *-- both on input and on output* + +Home-key + ESC [ 1 ~ *-- input only* + +End-key + ESC [ 4 ~ *-- input only* + +Delete-to-the-right-key + ESC [ 3 ~ *-- input only* + +PageUp-key + ESC [ 5 ~ *-- input only* + +PageDown-key + ESC [ 6 ~ *-- input only* + +Move-to-home-of-screen-upper-left + ESC [ H *-- output only* + +Move-to-end-of-line + ESC [ F *-- output only* + +Teleport-cursor-to-coordinate + ESC [ *row* ; *col* H *-- output only: rows and cols start counting at 1, not 0* + +Clearscreen + ESC [ 2 J *-- output only* + +Scroll-screen-up-one-line-keeping-cursor-where-it-is + ESC [ S *-- output only* + +Scroll-screen-down-one-line-keeping-cursor-where-it-is + ESC [ T *-- output only* + +Delete-to-the-left-of-cursor-ie-backspace + ESC [ K *-- output only* + +Delete-at-the-cursor-toward-the-right + ESC [ 1 K *-- output only* + + + +*The following codes are for the XTERM emulation only* + +Server-telling-client-to-resize-screen + ESC [ 8 ; *newheight* ; *newwidth* t *-- The height/width are in chars* + +Server-telling-client-to-change-window-title + ESC ] 2 ; *title string* BEL *-- where BEL is the character normally + used to mean beep: control-G or 0x07. But in this context it just marks + the end of the title and shouldn't cause a beep. + + +Any value not mentioned in the list above might still get sent, but you +should be able to capture and ignore it. + From 5f88ef69263c8d25c68ed9444b4b8b6b8ace6528 Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Fri, 13 Feb 2015 21:34:06 -0600 Subject: [PATCH 149/446] Added RgbaColor.ToHTMLString() so HUDTEXT can use it. Also added the :HTML suffix to use it from in a program, even though I can't think of any logical reason yet why it would be useful to a script - there's no reason not to let people see it. --- doc/source/structures/misc/colors.rst | 28 +++++++++++++++++++++++++++ src/kOS/Suffixed/RgbaColor.cs | 22 ++++++++++++++++++++- 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/doc/source/structures/misc/colors.rst b/doc/source/structures/misc/colors.rst index cd6823b65..25d83694d 100644 --- a/doc/source/structures/misc/colors.rst +++ b/doc/source/structures/misc/colors.rst @@ -51,6 +51,32 @@ Method 1: Use one of these pre-arranged named colors: ``a`` A floating point number from 0.0 to 1.0 for the alpha component. (1.0 means opaque, 0.0 means invisibly transparent). +.. structure:: RGBA + + .. list-table:: Members + :header-rows: 1 + :widths: 2 1 4 + + * - Suffix + - Type + - Description + + * - :R or :RED + - scalar + - the red component of the color + * - :G or :GREEN + - scalar + - the green component of the color + * - :B or :BLUE + - scalar + - the blue component of the color + * - :A or :ALPHA + - scalar + - the alpha (how opaque: 1 = opaque, 0 = transparent) component of the color + * - :HTML + - string + - the color rendered into a HTML tag string i.e. "#ff0000". This format ignores the alpha channel and treats all colors as opaue. + Examples:: SET myarrow TO VECDRAW. @@ -66,3 +92,5 @@ Examples:: // half transparent yellow. SET myarrow:COLOR to RGBA(1.0,1.0,0.0,0.5). + PRINT GREEN:HTML. // prints #00ff00 + diff --git a/src/kOS/Suffixed/RgbaColor.cs b/src/kOS/Suffixed/RgbaColor.cs index 47592be75..db994fbbf 100644 --- a/src/kOS/Suffixed/RgbaColor.cs +++ b/src/kOS/Suffixed/RgbaColor.cs @@ -1,4 +1,5 @@ -using UnityEngine; +using System; +using UnityEngine; using kOS.Safe.Encapsulation; using kOS.Safe.Encapsulation.Suffixes; @@ -25,6 +26,7 @@ private void InitializeSuffixColor() AddSuffix(new [] { "G", "GREEN" } , new ClampSetSuffix(() => color.g, value => color.g = value, 0, 255)); AddSuffix(new [] { "B", "BLUE" } , new ClampSetSuffix(() => color.b, value => color.b = value, 0, 255)); AddSuffix(new [] { "A", "ALPHA" } , new ClampSetSuffix(() => color.a, value => color.a = value, 0, 1)); + AddSuffix("HTML", new NoArgsSuffix(ToHTMLString, "Returns a string representing the color in HTML, i.e. \"#ff0000\". Ignores transparency (alpha) information.")); } public Color Color() @@ -36,6 +38,24 @@ public override string ToString() { return "RGBA(" + color.r + ", " + color.g + ", " + color.b + ", " + color.a + ")"; } + + ///

    + /// Returns a string represnting the HTML color code "#rrggbb" format + /// for the color. (i.e. RED is "#ff0000"). Note that this cannot represent + /// the transparency (alpha) information, and will treat the color as if it was + /// fully opaque regardless of whether it really is or not. Although there have + /// been some extensions to the HTML specification that added a fourth byte for + /// alpha information, i.e. "#80ff0000" would be a semitransparent red, those never + /// got accepted as standard and remain special proprietary extensions. + /// + /// The html spec string returned, using lowercase lettering for the alpha digits + public string ToHTMLString() + { + byte redByte = (byte)(Mathf.Min(255, (int)(color.r * 255f))); + byte greenByte = (byte)(Mathf.Min(255, (int)(color.g * 255f))); + byte blueByte = (byte)(Mathf.Min(255, (int)(color.b * 255f))); + return String.Format("#{0:x2}{1:x2}{2:x2}", redByte, greenByte, blueByte); + } } } From 5a1de105dc0a7f0b60a922dd284ac1d784e66c6f Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Fri, 13 Feb 2015 23:39:11 -0600 Subject: [PATCH 150/446] Added more images to the docs. --- .../_images/general/telnet_macterminal.png | Bin 0 -> 27653 bytes .../_images/general/telnet_welcomemenu.png | Bin 0 -> 51259 bytes doc/source/_images/general/telnet_xterm.png | Bin 0 -> 12687 bytes doc/source/general/telnet.rst | 20 ++++++++++++++++++ 4 files changed, 20 insertions(+) create mode 100644 doc/source/_images/general/telnet_macterminal.png create mode 100644 doc/source/_images/general/telnet_welcomemenu.png create mode 100644 doc/source/_images/general/telnet_xterm.png diff --git a/doc/source/_images/general/telnet_macterminal.png b/doc/source/_images/general/telnet_macterminal.png new file mode 100644 index 0000000000000000000000000000000000000000..06ea06b9eaba674eb4cfd1f75b2a04a59b5f5500 GIT binary patch literal 27653 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�#VR=mh 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 FV1l_VA~^s6 literal 0 HcmV?d00001 diff --git a/doc/source/_images/general/telnet_xterm.png b/doc/source/_images/general/telnet_xterm.png new file mode 100644 index 0000000000000000000000000000000000000000..94b7a9ce530acd00e0179991af58719330f408a5 GIT binary patch literal 12687 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 T`5f@E8c0=9>uH7j^SA#W4o(Nc literal 0 HcmV?d00001 diff --git a/doc/source/general/telnet.rst b/doc/source/general/telnet.rst index dbe5d0027..0b6524264 100644 --- a/doc/source/general/telnet.rst +++ b/doc/source/general/telnet.rst @@ -63,7 +63,9 @@ Using it 1. Turn on the telnet server by going into the app control panel and clicking on the green circle next to the word "Telnet". Alternatively, you can issue the command:: + SET CONFIG:TELNET TO TRUE. + from any terminal window in kOS. 2. The very first time you do this, you wil get a warning message, as per @@ -98,6 +100,7 @@ Using it -------------------------------------------------------------------------------- >_ + Or, if there are no CPU's within range, it will look like this:: Terminal: type = XTERM, size = 80x24 @@ -113,6 +116,11 @@ Using it This menu should match 1:1 with the list of CPU's you see on the kOS applauncher control panel. +.. figure:: /_images/general/telnet_welcomemenu.png + :width: 75 % + + The welcome menu, shown here in a Mac OSX terminal. + 5. **Pick a CPU.** Pick one of the cpu's listed by typing its number and hitting enter. 6. Your telnet is now connected to the server and should behave as the terminal for @@ -147,7 +155,9 @@ Using it fliping back and forth between two different sizes, resizing itself over and over again in a neverending loop), you can try to get out of it by issuing a hardcoded command to set the terminal size, such as:: + SET TERMINAL:WIDTH TO 50. + Doing this should force all the connected telnet XTERM windows to stop arguing with each other about what the size is, and get them synced up again. @@ -241,6 +251,16 @@ message the server was sending back to you just before the window went away. HOWTO: Command-line client -------------------------- +.. figure:: /_images/general/telnet_xterm.png + :width: 75 % + + Showing the use of telnet in an x-term window. + +.. figure:: /_images/general/telnet_macterminal.png + :width: 75 % + + Showing the use of telnet in a Mac OSX terminal. + (These instructions assume you use the default kOS Telnet server settings, of the loopback address 127.0.0.1, and port number 5410. If you've changed those settings then alter the numbers you see here accordingly.) From 0dce010bc769fda5e11501d26edef7bcd3feed2e Mon Sep 17 00:00:00 2001 From: Chris Woerz Date: Fri, 13 Feb 2015 23:16:16 -0700 Subject: [PATCH 151/446] generalized the SliderClampRound --- .../Encapsulation/Suffixes/ClampSetSuffix.cs | 10 +-- src/kOS.Safe/Utilities/Math.cs | 62 +++++++++++++++++++ .../PartModuleField/PartModuleFields.cs | 34 +--------- 3 files changed, 67 insertions(+), 39 deletions(-) diff --git a/src/kOS.Safe/Encapsulation/Suffixes/ClampSetSuffix.cs b/src/kOS.Safe/Encapsulation/Suffixes/ClampSetSuffix.cs index b72424817..327ea56d3 100644 --- a/src/kOS.Safe/Encapsulation/Suffixes/ClampSetSuffix.cs +++ b/src/kOS.Safe/Encapsulation/Suffixes/ClampSetSuffix.cs @@ -25,14 +25,10 @@ public override void Set(object value) { //HACK, this is assumes the value parses as a double var dblValue = double.Parse(value.ToString()); - - //Rounding to the nearest step - if (!(System.Math.Abs(stepIncrement) < 0.00001)) - { - dblValue = System.Math.Round(dblValue/stepIncrement)*stepIncrement; - } - base.Set(Math.Clamp(dblValue, min, max)); + base.Set(System.Math.Abs(stepIncrement) < 0.0001 + ? Math.Clamp(dblValue, min, max) + : Math.ClampToIndent(dblValue, min, max, stepIncrement)); } } } \ No newline at end of file diff --git a/src/kOS.Safe/Utilities/Math.cs b/src/kOS.Safe/Utilities/Math.cs index f01d81603..35be773ee 100644 --- a/src/kOS.Safe/Utilities/Math.cs +++ b/src/kOS.Safe/Utilities/Math.cs @@ -29,5 +29,67 @@ public static double Clamp(double input, double low, double high) } return Clamp(input.Value, low, high); } + + /// + /// Round the value to the nearest allowed value. + /// if the slider starts at min, ends at max, and has detents every inc. + /// + /// value to round + /// minimum allowed value + /// maximum allowed value + /// increment of the detents + /// + public static double ClampToIndent(double val, double min, double max, double increment) + { + // First clamp the value to within min/max: + double outVal = System.Math.Max(min, System.Math.Min(val, max)); + + // How many discrete increments up the slider gets us to the nearest detent less than or equal to the value: + var numIncs = (int)System.Math.Floor((outVal-min)/increment); + + // get detent values just below and above the value: + double nearUnder = min + (numIncs*increment); + double nearOver = min + ((numIncs+1)*increment); + + // pick which one to round to: + double remainder = outVal - nearUnder; + if (remainder >= (increment/2f) && nearOver <= max) + outVal = nearOver; + else + outVal = nearUnder; + + return outVal; + } + + /// + /// Round the value to the nearest allowed value. + /// if the slider starts at min, ends at max, and has detents every inc. + /// + /// value to round + /// minimum allowed value + /// maximum allowed value + /// increment of the detents + /// + public static float ClampToIndent(float val, float min, float max, float increment) + { + // First clamp the value to within min/max: + float outVal = System.Math.Max(min, System.Math.Min(val, max)); + + // How many discrete increments up the slider gets us to the nearest detent less than or equal to the value: + var numIncs = (long)System.Math.Floor((outVal-min)/increment); + + // get detent values just below and above the value: + float nearUnder = min + (numIncs*increment); + float nearOver = min + ((numIncs+1)*increment); + + // pick which one to round to: + float remainder = outVal - nearUnder; + if (remainder >= (increment/2f) && nearOver <= max) + outVal = nearOver; + else + outVal = nearUnder; + + return outVal; + } } } diff --git a/src/kOS/Suffixed/PartModuleField/PartModuleFields.cs b/src/kOS/Suffixed/PartModuleField/PartModuleFields.cs index ac1c56d6a..c80212e07 100644 --- a/src/kOS/Suffixed/PartModuleField/PartModuleFields.cs +++ b/src/kOS/Suffixed/PartModuleField/PartModuleFields.cs @@ -7,6 +7,7 @@ using kOS.Safe.Exceptions; using kOS.Suffixed.Part; using UnityEngine; +using Math = kOS.Safe.Utilities.Math; namespace kOS.Suffixed.PartModuleField { @@ -159,7 +160,7 @@ private bool IsLegalValue(BaseField field, ref object newVal, out KOSException e if (range != null) { float val = Convert.ToSingle(convertedVal); - val = SliderClampRound(val, range.minValue, range.maxValue, range.stepIncrement); + val = Math.ClampToIndent(val, range.minValue, range.maxValue, range.stepIncrement); convertedVal = Convert.ToDouble(val); } if (! isLegal) @@ -169,37 +170,6 @@ private bool IsLegalValue(BaseField field, ref object newVal, out KOSException e return isLegal; } - /// - /// Round the value to the nearest value the slider will allow if the slider starts - /// at min, ends at max, and has detents every inc. - /// - /// value to round - /// minimun the slider allows - /// maximum the slider allows - /// increment of the detents - /// - private float SliderClampRound(float val, float min, float max, float inc) - { - // First clamp the value to within min/max: - float outVal = Math.Max(min, Math.Min(val, max)); - - // How many discrete increments up the slider gets us to the nearest detent less than or equal to the value: - int numIncs = Mathf.FloorToInt((outVal-min)/inc); - - // get detent values just below and above the value: - float nearUnder = min + (numIncs*inc); - float nearOver = min + ((numIncs+1)*inc); - - // pick which one to round to: - float remainder = outVal - nearUnder; - if (remainder >= (inc/2f) && nearOver <= max) - outVal = nearOver; - else - outVal = nearUnder; - - return outVal; - } - /// /// Return a list of all the strings of all KSPfields registered to this PartModule /// which are currently showing on the part's RMB menu. From 3c55cc0ff1809d82c037d55561795d9ad5323555 Mon Sep 17 00:00:00 2001 From: Chris Woerz Date: Fri, 13 Feb 2015 23:29:26 -0700 Subject: [PATCH 152/446] removed dupe suffixes --- src/kOS/Suffixed/OrbitInfo.cs | 1 - src/kOS/Suffixed/Orbitable.cs | 1 - 2 files changed, 2 deletions(-) diff --git a/src/kOS/Suffixed/OrbitInfo.cs b/src/kOS/Suffixed/OrbitInfo.cs index 2d068b946..90ab06fdb 100644 --- a/src/kOS/Suffixed/OrbitInfo.cs +++ b/src/kOS/Suffixed/OrbitInfo.cs @@ -45,7 +45,6 @@ private void InitializeSuffixes() AddSuffix("VELOCITY", new Suffix(() => GetVelocityAtUT( new TimeSpan(Planetarium.GetUniversalTime() ) ))); AddSuffix("NEXTPATCH", new Suffix(GetNextPatch)); AddSuffix("HASNEXTPATCH", new Suffix(GetHasNextPatch)); - AddSuffix("TRANSITION", new Suffix(() => orbit.patchEndTransition.ToString())); //TODO: Determine if these vectors are different than POSITION and VELOCITY AddSuffix("VSTATEVECTOR", new Suffix(() => new Vector(orbit.vel))); diff --git a/src/kOS/Suffixed/Orbitable.cs b/src/kOS/Suffixed/Orbitable.cs index fbf4c11e8..e959bcbc5 100644 --- a/src/kOS/Suffixed/Orbitable.cs +++ b/src/kOS/Suffixed/Orbitable.cs @@ -210,7 +210,6 @@ private void InitializeSuffixes() AddSuffix("NAME", new Suffix(GetName)); AddSuffix("APOAPSIS", new Suffix(() => Orbit.ApA)); AddSuffix("PERIAPSIS", new Suffix(() => Orbit.PeA)); - AddSuffix("APOAPSIS", new Suffix(() => Orbit.ApA)); AddSuffix("BODY", new Suffix(() => new BodyTarget(Orbit.referenceBody, Shared))); AddSuffix("UP", new Suffix(() => new Direction(GetUpVector(), false))); AddSuffix("NORTH", new Suffix(() => new Direction(GetNorthVector(), false))); From 07f9c9af5f4beb652700ccba332eee530f0c7faa Mon Sep 17 00:00:00 2001 From: Chris Woerz Date: Fri, 13 Feb 2015 23:48:18 -0700 Subject: [PATCH 153/446] added :HEX to color --- src/kOS/Suffixed/RgbaColor.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kOS/Suffixed/RgbaColor.cs b/src/kOS/Suffixed/RgbaColor.cs index db994fbbf..df784c157 100644 --- a/src/kOS/Suffixed/RgbaColor.cs +++ b/src/kOS/Suffixed/RgbaColor.cs @@ -26,7 +26,7 @@ private void InitializeSuffixColor() AddSuffix(new [] { "G", "GREEN" } , new ClampSetSuffix(() => color.g, value => color.g = value, 0, 255)); AddSuffix(new [] { "B", "BLUE" } , new ClampSetSuffix(() => color.b, value => color.b = value, 0, 255)); AddSuffix(new [] { "A", "ALPHA" } , new ClampSetSuffix(() => color.a, value => color.a = value, 0, 1)); - AddSuffix("HTML", new NoArgsSuffix(ToHTMLString, "Returns a string representing the color in HTML, i.e. \"#ff0000\". Ignores transparency (alpha) information.")); + AddSuffix(new [] { "HTML", "HEX" } , new NoArgsSuffix(ToHTMLString, "Returns a string representing the color in HTML, i.e. \"#ff0000\". Ignores transparency (alpha) information.")); } public Color Color() From b47b3385d26ea3ce8944bf887ab367b79aae87a3 Mon Sep 17 00:00:00 2001 From: Chris Woerz Date: Sat, 14 Feb 2015 00:01:07 -0700 Subject: [PATCH 154/446] forgot to document :HEX --- doc/source/structures/misc/colors.rst | 2 +- src/kOS/Suffixed/RgbaColor.cs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/source/structures/misc/colors.rst b/doc/source/structures/misc/colors.rst index 25d83694d..013709501 100644 --- a/doc/source/structures/misc/colors.rst +++ b/doc/source/structures/misc/colors.rst @@ -73,7 +73,7 @@ Method 1: Use one of these pre-arranged named colors: * - :A or :ALPHA - scalar - the alpha (how opaque: 1 = opaque, 0 = transparent) component of the color - * - :HTML + * - :HTML or :HEX - string - the color rendered into a HTML tag string i.e. "#ff0000". This format ignores the alpha channel and treats all colors as opaue. diff --git a/src/kOS/Suffixed/RgbaColor.cs b/src/kOS/Suffixed/RgbaColor.cs index df784c157..8c196eb25 100644 --- a/src/kOS/Suffixed/RgbaColor.cs +++ b/src/kOS/Suffixed/RgbaColor.cs @@ -40,7 +40,7 @@ public override string ToString() } /// - /// Returns a string represnting the HTML color code "#rrggbb" format + /// Returns a string representing the HTML color code "#rrggbb" format /// for the color. (i.e. RED is "#ff0000"). Note that this cannot represent /// the transparency (alpha) information, and will treat the color as if it was /// fully opaque regardless of whether it really is or not. Although there have @@ -48,7 +48,7 @@ public override string ToString() /// alpha information, i.e. "#80ff0000" would be a semitransparent red, those never /// got accepted as standard and remain special proprietary extensions. /// - /// The html spec string returned, using lowercase lettering for the alpha digits + /// The HTML spec string returned, using lowercase lettering for the alpha digits public string ToHTMLString() { byte redByte = (byte)(Mathf.Min(255, (int)(color.r * 255f))); From 2638b3052f8065b3d663cc8922ff8a70fedf446f Mon Sep 17 00:00:00 2001 From: pgodd Date: Sat, 14 Feb 2015 13:39:22 -0500 Subject: [PATCH 155/446] Update Misc.cs --- src/kOS/Function/Misc.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kOS/Function/Misc.cs b/src/kOS/Function/Misc.cs index d5938e7e8..fd4336c4f 100644 --- a/src/kOS/Function/Misc.cs +++ b/src/kOS/Function/Misc.cs @@ -28,7 +28,7 @@ public override void Execute(SharedObjects shared) } } -[Function("hudtxt")] +[Function("hudtext")] public class FunctionHudTxt : FunctionBase { From a71029f6dc4e0ffdcaec841318738aef35afe2ee Mon Sep 17 00:00:00 2001 From: Chris Woerz Date: Sat, 14 Feb 2015 16:31:47 -0700 Subject: [PATCH 156/446] review reviewed --- doc/source/general/telnet.rst | 32 +-- .../Compilation/CompiledObject-doc.md | 12 +- src/kOS.Safe/Persistence/Archive.cs | 2 +- src/kOS.Safe/Persistence/FileCategory.cs | 2 +- src/kOS.Safe/Screen/IScreenBufferLine.cs | 5 +- src/kOS.Safe/Screen/IScreenSnapshot.cs | 3 +- src/kOS.Safe/Screen/ITermWindow.cs | 2 +- src/kOS.Safe/Screen/ScreenBuffer.cs | 212 +++++++++--------- src/kOS.Safe/Screen/ScreenBufferLine.cs | 27 ++- src/kOS.Safe/Screen/ScreenSnapshot.cs | 33 +-- src/kOS.Safe/Screen/TextEditor.cs | 1 - src/kOS.Safe/UserIO/UnicodeCommand.cs | 40 ++-- src/kOS.Safe/Utilities/TickGen.cs | 2 +- .../RemoteTech2/RemoteTechInterpreter.cs | 3 +- src/kOS/Function/PrintList.cs | 2 +- src/kOS/Module/kOSProcessor.cs | 4 +- src/kOS/Screen/Interpreter.cs | 1 - src/kOS/Screen/KOSManagedWindow.cs | 152 ++++++++++--- src/kOS/Screen/KOSTextEditPopup.cs | 71 +++--- src/kOS/Screen/TermWindow.cs | 100 ++++----- src/kOS/Suffixed/BodyTarget.cs | 88 ++++---- src/kOS/Suffixed/Orbitable.cs | 2 +- src/kOS/UserIO/TelnetMainServer.cs | 92 ++++---- src/kOS/UserIO/TelnetSingletonServer.cs | 171 +++++++------- src/kOS/UserIO/TelnetWelcomeMenu.cs | 31 +-- src/kOS/UserIO/TerminalAnsiMapper.cs | 5 +- src/kOS/UserIO/TerminalUnicodeMapper.cs | 49 ++-- src/kOS/UserIO/TerminalVT100Mapper.cs | 110 +++++---- src/kOS/UserIO/TerminalXtermMapper.cs | 36 +-- src/kOS/Utilities/Utils.cs | 6 +- 30 files changed, 685 insertions(+), 611 deletions(-) diff --git a/doc/source/general/telnet.rst b/doc/source/general/telnet.rst index 0b6524264..c6d1245af 100644 --- a/doc/source/general/telnet.rst +++ b/doc/source/general/telnet.rst @@ -3,13 +3,13 @@ The kOS Telnet Server ===================== -kOS now supports the abilty to enable a `telnet server `_ +kOS now supports the ability to enable a `telnet server `_ inside Kerbal Space Program. .. figure:: /_images/general/telnet.png :width: 95 % -Telnet is an old network protocol designed in the early days of the internet, long +Telnet is an old network protocol designed in the early days of the Internet, long before World Wide Web. Its purpose was (is) to allow you to get access to the remote command line interfaces of distant server computers, acting as if the keyboard and computer screen in front of you was a terminal hooked up to a distant @@ -68,7 +68,7 @@ Using it from any terminal window in kOS. -2. The very first time you do this, you wil get a warning message, as per +2. The very first time you do this, you will get a warning message, as per `SQUAD's rule number 5 about mods that run network services `_. After accepting and clicking "yes", the server will be running on loopback 127.0.0.1 (if you want to make it run on the non-loopback address, you will @@ -121,7 +121,7 @@ Using it The welcome menu, shown here in a Mac OSX terminal. -5. **Pick a CPU.** Pick one of the cpu's listed by typing its number and hitting enter. +5. **Pick a CPU.** Pick one of the CPU's listed by typing its number and hitting enter. 6. Your telnet is now connected to the server and should behave as the terminal for that CPU. You can type commands and do what you like, the same as if you had been @@ -144,7 +144,7 @@ Using it then the same thing works in reverse. If it's VT100 then it doesn't.) .. warning:: - Certain implementations of the xterm terminal emulation and the telnet cliet have + Certain implementations of the xterm terminal emulation and the telnet client have created a strange unending cascade of terminal resizes when you have two different telnet clients connected to the same GUI terminal and one of them is dragged to a new size. Because some implementations don't wait until they're done resizing to @@ -152,7 +152,7 @@ Using it they are being stretched, the attempt to keep them the same size causes them to effectively "argue" back and forth with each other, constantly changing each other's size. If you experience this problem (your terminal window will be - fliping back and forth between two different sizes, resizing itself over and over + flipping back and forth between two different sizes, resizing itself over and over again in a neverending loop), you can try to get out of it by issuing a hardcoded command to set the terminal size, such as:: @@ -163,7 +163,7 @@ Using it 10. At any time you may disconnect your telnet client from the terminal by hitting control-D as the first character of a new line. This will bring you back to - the telnet welcom menu again. + the telnet welcome menu again. Special Keys ------------ @@ -219,8 +219,8 @@ Control-H Control-M **Return** This is an alternate way to press the "enter" or "return" key, - just in case your terminal emulation isn't sending the officialy understood - terminla code for it. + just in case your terminal emulation isn't sending the officially understood + terminal code for it. HOWTO: Putty client ------------------- @@ -316,7 +316,7 @@ scope of this document. You can read more `For windows `_ or `For UNIX (both Mac and Linux) `_. -Example: Let's say you have a remote unix machine you'd like to enable logins from, +Example: Let's say you have a remote Unix machine you'd like to enable logins from, from there and nowhere else. You can forward from your own machine's 127.0.0.1, port 5410, to the remote machine's, oh let's say 127.0.0.1, port 54100. Then anyone on the remote machine could telnet to ITS 127.0.0.1, port 54100 and @@ -358,7 +358,7 @@ looks like gibberish to you. It can be skipped. If you wish to make your own homemade telnet client and connect it up to the kOS telnet server, the following is the required subset of the telnet protocol that your telnet client must speak, and the terminal requirements it must -fufill: +fulfill: 1. It must suppress local character echoing, and enter character-at-a-time mode, by implementing both the ECHO negotiation @@ -366,11 +366,11 @@ fufill: the SUPPRESS GO AHEAD negotiation `described by RFC858 `_. These are used in the following way: Your client must NOT ECHo (letting the server do it), - and your client must suppres go-ahead messages (allowing real-time back-and-forth). + and your client must suppress go-ahead messages (allowing real-time back-and-forth). 2. It must implement the underlying DO/DONT and WILL/WONT, and SB/SE infrastructure of the main `telnet RFC854 `_. It must send break (ctrl-C) as the IP interrupt process command (byte 255 followed by 244). - kOS does not use much of the negotaitions of the protocol mentioned on RFC854, other + kOS does not use much of the negotiations of the protocol mentioned on RFC854, other than those that are necessary to enable the other ones mentioned here. 3. It must implement the Terminal-Type option `described by RFC1091 `_. @@ -391,12 +391,12 @@ fufill: (For example, if you identify as XTERM, you will be sent the XTERM escape code pattern ESC [ 8 ; *height* ; *width* t, which is the XTERM escape code for setting the terminal size.) This is because the telnet protocol was never written to - accomodate the concept of server-iniated resizes. + accommodate the concept of server-initiated resizes. Making a telnet client from scratch that actually follows protocol may be a complex enough task that the smarter solution is to just use an existing telnet program, if you are trying to create some sort of hardware rig. These days a small cheap -mini-hardware implementation of linux should be doable, and could include the +mini-hardware implementation of Linux should be doable, and could include the telnet client installed in it for very little storage cost. **TERMINAL EMULATION** @@ -406,7 +406,7 @@ or VT100 well, however the infrastructure is in place to support modifications to map to other terminal types. If you want to try a hand at adding the terminal emulation for a currently unsupported terminal, you'd do it by subclassing the kOS.UserIO.TerminalUnicodeMapper class. You can -look at kOS.UserIO.TerminalXtermMapper as a sample to see wht you need +look at kOS.UserIO.TerminalXtermMapper as a sample to see what you need to do. If you have a project where you want to just work with the terminal diff --git a/src/kOS.Safe/Compilation/CompiledObject-doc.md b/src/kOS.Safe/Compilation/CompiledObject-doc.md index 051dd5f0f..30e35ceef 100644 --- a/src/kOS.Safe/Compilation/CompiledObject-doc.md +++ b/src/kOS.Safe/Compilation/CompiledObject-doc.md @@ -52,7 +52,7 @@ Goals and Ideas - Compactness The first thing to mention about the format is that it is designed for maximum compactness, NOT human readability, and NOT for simple -programming conveninece. The goal is to make a format that stores +programming convenience. The goal is to make a format that stores the compiled program with the least 'wastage' due to indenting and comments and long variable names, and lets users run code on their meager small local volumes with them crunched down into @@ -315,9 +315,9 @@ it as a kEXE type of file. The magic number is this pattern: * ASCII lowercase 'k', * byte value 0x03, // Not letter 'e', because something has to make it -clear to applications that this file doesn't have printable ascii in it, -as some will assume if they see a string of printable ascii at the start, -that it must be an ascii file. +clear to applications that this file doesn't have printable ASCII in it, +as some will assume if they see a string of printable ASCII at the start, +that it must be an ASCII file. * ASCII uppercase 'X', * ASCII uppercase 'E' @@ -803,7 +803,7 @@ This is a small example of a tiny program that shows it all. A very small example was picked because it's possible to see it all at once in one hexdump: -Original Program as ascii source: +Original Program as ASCII source: --------------------------------- // This is testcode @@ -925,7 +925,7 @@ larger program will probably have 0x02 here. Type code is 0x07, string, followed by the BinaryWriter's encoding of a string, which starts with a one-byte string length, 0x13, -and then the UTF-8 encoding of the unicode string (so it looks like +and then the UTF-8 encoding of the Unicode string (so it looks like ASCII unless there's some extended chars). **Argument at location 0x18 in Argument Section:** diff --git a/src/kOS.Safe/Persistence/Archive.cs b/src/kOS.Safe/Persistence/Archive.cs index d696a5bfb..018807edd 100644 --- a/src/kOS.Safe/Persistence/Archive.cs +++ b/src/kOS.Safe/Persistence/Archive.cs @@ -89,7 +89,7 @@ public override bool SaveFile(ProgramFile file) string tempString = file.StringContent; if (Utilities.Environment.IsWindows) { - // Only evil windows gets evil windows line breaks, and only if this is some sort of ascii: + // Only evil windows gets evil windows line breaks, and only if this is some sort of ASCII: tempString = tempString.Replace("\n", "\r\n"); } fileBody = System.Text.Encoding.UTF8.GetBytes(tempString.ToCharArray()); diff --git a/src/kOS.Safe/Persistence/FileCategory.cs b/src/kOS.Safe/Persistence/FileCategory.cs index 7ade5e729..bb59289be 100644 --- a/src/kOS.Safe/Persistence/FileCategory.cs +++ b/src/kOS.Safe/Persistence/FileCategory.cs @@ -18,7 +18,7 @@ public enum FileCategory /// /// The default the type identifier will always assume as long
    - /// as the first few characters are printable ascii. + /// as the first few characters are printable ASCII. ///
    ASCII, diff --git a/src/kOS.Safe/Screen/IScreenBufferLine.cs b/src/kOS.Safe/Screen/IScreenBufferLine.cs index 639add4b5..e3197eaa2 100644 --- a/src/kOS.Safe/Screen/IScreenBufferLine.cs +++ b/src/kOS.Safe/Screen/IScreenBufferLine.cs @@ -1,6 +1,4 @@ -using System; - -namespace kOS.Safe.Screen +namespace kOS.Safe.Screen { public interface IScreenBufferLine { @@ -10,7 +8,6 @@ public interface IScreenBufferLine int Length {get;} void ArrayCopyFrom(IScreenBufferLine source, int sourceStart, int destinationStart, int length = -1); void ArrayCopyFrom(char[] source, int sourceStart, int destinationStart, int length = -1); - string ToString(); void TouchTime(); } } \ No newline at end of file diff --git a/src/kOS.Safe/Screen/IScreenSnapshot.cs b/src/kOS.Safe/Screen/IScreenSnapshot.cs index 4e0c6c9b0..58d0764e3 100644 --- a/src/kOS.Safe/Screen/IScreenSnapshot.cs +++ b/src/kOS.Safe/Screen/IScreenSnapshot.cs @@ -1,5 +1,4 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; namespace kOS.Safe.Screen { diff --git a/src/kOS.Safe/Screen/ITermWindow.cs b/src/kOS.Safe/Screen/ITermWindow.cs index a571b5185..e73799385 100644 --- a/src/kOS.Safe/Screen/ITermWindow.cs +++ b/src/kOS.Safe/Screen/ITermWindow.cs @@ -8,7 +8,7 @@ public interface ITermWindow void Open(); void Close(); void Toggle(); - bool IsOpen(); + bool IsOpen { get; } bool ShowCursor { get; set; } bool IsPowered { get; set; } } diff --git a/src/kOS.Safe/Screen/ScreenBuffer.cs b/src/kOS.Safe/Screen/ScreenBuffer.cs index 7bd6c8612..973032e1c 100644 --- a/src/kOS.Safe/Screen/ScreenBuffer.cs +++ b/src/kOS.Safe/Screen/ScreenBuffer.cs @@ -1,5 +1,6 @@ -using System.Collections.Generic; using System; +using System.Collections.Generic; +using System.Linq; using System.Text; namespace kOS.Safe.Screen @@ -8,27 +9,17 @@ public class ScreenBuffer : IScreenBuffer { private const int DEFAULT_ROWS = 36; private const int DEFAULT_COLUMNS = 50; - private int topRow; - - // Needed so the terminal knows when it's been scrolled, for its diffing purposes. - public int TopRow {get {return topRow;}} - private readonly List buffer; private readonly List subBuffers; - protected int CursorRow { get; set; } - protected int CursorColumn { get; set; } + public int ColumnCount { get; private set; } + public virtual int CursorRowShow { get { return CursorRow; } } + public virtual int CursorColumnShow { get { return CursorColumn; } } - public int RowCount { get; private set; } - public int ColumnCount { get; private set; } - protected List Notifyees { get; set; } - /// Delegate prototype expected by AddResizeNotifier - /// This screenbuffer telling the callback who it is - /// telling this screenbuffer how many vertical rows to scroll as a result of the resize. - public delegate int ResizeNotifier(IScreenBuffer sb); + public int RowCount { get; private set; } public int AbsoluteCursorRow { @@ -36,11 +27,25 @@ public int AbsoluteCursorRow set { CursorRow = value - topRow; } } + // Needed so the terminal knows when it's been scrolled, for its diffing purposes. + public int TopRow { get { return topRow; } } + + protected int CursorRow { get; set; } + + protected int CursorColumn { get; set; } + + protected List Notifyees { get; set; } + + /// Delegate prototype expected by AddResizeNotifier + /// This screenbuffer telling the callback who it is + /// telling this screenbuffer how many vertical rows to scroll as a result of the resize. + public delegate int ResizeNotifier(IScreenBuffer sb); + public ScreenBuffer() { buffer = new List(); Notifyees = new List(); - + subBuffers = new List(); RowCount = DEFAULT_ROWS; @@ -48,29 +53,13 @@ public ScreenBuffer() InitializeBuffer(); } - private void InitializeBuffer() - { - buffer.Clear(); - AddNewBufferLines(RowCount); - - topRow = 0; - CursorRow = 0; - CursorColumn = 0; - } - - protected void AddNewBufferLines( int howMany = 1) - { - while (howMany-- > 0) - buffer.Add(new ScreenBufferLine(ColumnCount)); - } - - public void AddResizeNotifier(ScreenBuffer.ResizeNotifier notifier) + public void AddResizeNotifier(ResizeNotifier notifier) { if (Notifyees.IndexOf(notifier) < 0) Notifyees.Add(notifier); } - public void RemoveResizeNotifier(ScreenBuffer.ResizeNotifier notifier) + public void RemoveResizeNotifier(ResizeNotifier notifier) { Notifyees.Remove(notifier); } @@ -80,45 +69,11 @@ public void SetSize(int rows, int columns) RowCount = rows; ColumnCount = columns; ResizeBuffer(); - int scrollDiff = 0; - foreach (ResizeNotifier notifier in Notifyees) - { - if (notifier != null) - scrollDiff += notifier(this); - } + int scrollDiff = Notifyees + .Where(notifier => notifier != null) + .Sum(notifier => notifier(this)); ScrollVertical(scrollDiff); } - - protected void ResizeBuffer() - { - // Grow or shrink the width of the buffer lines to match the new - // value. Note that this does not (yet) account for preserving lines and wrapping them. - for (int row = 0 ; row < buffer.Count ; ++row) - { - ScreenBufferLine newRow = new ScreenBufferLine(ColumnCount); - newRow.ArrayCopyFrom(buffer[row], 0, 0, Math.Min(buffer[row].Length, ColumnCount)); - buffer[row] = newRow; - } - - // Add more buffer lines if needed to pad out the rest of the screen: - while (buffer.Count - topRow < RowCount) - buffer.Add(new ScreenBufferLine(ColumnCount)); - } - - private int ScrollVerticalInternal(int deltaRows = 1) - { - int maxTopRow = buffer.Count - RowCount; // refuse to allow a scroll past the end of the visible buffer. - - // boundary checks - if (topRow + deltaRows < 0) - deltaRows = -topRow; - else if (topRow + deltaRows > maxTopRow) - deltaRows = (maxTopRow - topRow); - - topRow += deltaRows; - - return deltaRows; - } public virtual int ScrollVertical(int deltaRows) { @@ -132,7 +87,7 @@ public void MoveCursor(int row, int column) row = RowCount - 1; MoveToNextLine(); } - if (row < 0 ) row = 0; + if (row < 0) row = 0; if (column >= ColumnCount) column = ColumnCount - 1; if (column < 0) column = 0; @@ -157,19 +112,6 @@ public void MoveToNextLine() CursorColumn = 0; } - private void MoveColumn(int deltaPosition) - { - if (deltaPosition > 0) - { - CursorColumn += deltaPosition; - while (CursorColumn >= ColumnCount) - { - CursorColumn -= ColumnCount; - MoveToNextLine(); - } - } - } - public virtual void PrintAt(string textToPrint, int row, int column) { MoveCursor(row, column); @@ -196,18 +138,40 @@ public void Print(string textToPrint, bool addNewLine) } } + protected void AddNewBufferLines(int howMany = 1) + { + while (howMany-- > 0) + buffer.Add(new ScreenBufferLine(ColumnCount)); + } + + protected void ResizeBuffer() + { + // Grow or shrink the width of the buffer lines to match the new + // value. Note that this does not (yet) account for preserving lines and wrapping them. + for (int row = 0; row < buffer.Count; ++row) + { + var newRow = new ScreenBufferLine(ColumnCount); + newRow.ArrayCopyFrom(buffer[row], 0, 0, Math.Min(buffer[row].Length, ColumnCount)); + buffer[row] = newRow; + } + + // Add more buffer lines if needed to pad out the rest of the screen: + while (buffer.Count - topRow < RowCount) + buffer.Add(new ScreenBufferLine(ColumnCount)); + } + protected List SplitIntoLines(string textToPrint) { var lineList = new List(); int availableColumns = ColumnCount - CursorColumn; string[] lines = textToPrint.Trim(new[] { '\r', '\n' }).Split('\n'); - + foreach (string line in lines) { string lineToPrint = line.TrimEnd('\r'); int startIndex = 0; - + while ((lineToPrint.Length - startIndex) > availableColumns) { lineList.Add(lineToPrint.Substring(startIndex, availableColumns)); @@ -222,13 +186,6 @@ protected List SplitIntoLines(string textToPrint) return lineList; } - private void PrintLine(string textToPrint) - { - IScreenBufferLine lineBuffer = buffer[AbsoluteCursorRow]; - lineBuffer.ArrayCopyFrom(textToPrint.ToCharArray(), 0, CursorColumn); - MoveColumn(textToPrint.Length); - } - public void ClearScreen() { buffer.Clear(); @@ -249,10 +206,10 @@ public void RemoveSubBuffer(SubBuffer subBuffer) public List GetBuffer() { // base buffer - int extraPadRows = Math.Max(0, (topRow+RowCount) - buffer.Count); // When screen extends past the buffer bottom., this is needed to prevent GetRange() exception. + int extraPadRows = Math.Max(0, (topRow + RowCount) - buffer.Count); // When screen extends past the buffer bottom., this is needed to prevent GetRange() exception. var mergedBuffer = new List(buffer.GetRange(topRow, RowCount - extraPadRows)); - int lastLineWidth = mergedBuffer[mergedBuffer.Count-1].Length; - while (extraPadRows > 0 ) + int lastLineWidth = mergedBuffer[mergedBuffer.Count - 1].Length; + while (extraPadRows > 0) { mergedBuffer.Add(new ScreenBufferLine(lastLineWidth)); --extraPadRows; @@ -284,18 +241,18 @@ public List GetBuffer() return mergedBuffer; } - // This was handy when trying to figure out what was going on. + // This was handy when trying to figure out what was going on. public string DebugDump() { StringBuilder sb = new StringBuilder(); - sb.Append("DebugDump ScreenBuffer: RowCount="+RowCount+", ColumnCount="+ColumnCount+", topRow="+topRow+", buffer.count="+buffer.Count+"\n"); - for (int i = 0; i < buffer.Count ; ++i) + sb.Append("DebugDump ScreenBuffer: RowCount=" + RowCount + ", ColumnCount=" + ColumnCount + ", topRow=" + topRow + ", buffer.count=" + buffer.Count + "\n"); + for (int i = 0; i < buffer.Count; ++i) { - sb.Append(" line "+i+" = ["); - for (int j = 0 ; j < buffer[i].Length ; ++j) + sb.Append(" line " + i + " = ["); + for (int j = 0; j < buffer[i].Length; ++j) { char ch = buffer[i][j]; - sb.Append((int)ch < 32 ? (" \\"+(int)ch) : (" "+ch) ); + sb.Append((int)ch < 32 ? (" \\" + (int)ch) : (" " + ch)); } sb.Append("]\n"); } @@ -303,12 +260,55 @@ public string DebugDump() sb.Append(sub.DebugDump()); return sb.ToString(); } - protected virtual void UpdateSubBuffers() { // so subclasses can do something with their subbuffers before they are merged } - } -} + private void InitializeBuffer() + { + buffer.Clear(); + AddNewBufferLines(RowCount); + + topRow = 0; + CursorRow = 0; + CursorColumn = 0; + } + + private int ScrollVerticalInternal(int deltaRows = 1) + { + int maxTopRow = buffer.Count - RowCount; // refuse to allow a scroll past the end of the visible buffer. + + // boundary checks + if (topRow + deltaRows < 0) + deltaRows = -topRow; + else if (topRow + deltaRows > maxTopRow) + deltaRows = (maxTopRow - topRow); + + topRow += deltaRows; + + return deltaRows; + } + + private void MoveColumn(int deltaPosition) + { + if (deltaPosition > 0) + { + CursorColumn += deltaPosition; + while (CursorColumn >= ColumnCount) + { + CursorColumn -= ColumnCount; + MoveToNextLine(); + } + } + } + + private void PrintLine(string textToPrint) + { + IScreenBufferLine lineBuffer = buffer[AbsoluteCursorRow]; + lineBuffer.ArrayCopyFrom(textToPrint.ToCharArray(), 0, CursorColumn); + MoveColumn(textToPrint.Length); + } + } +} \ No newline at end of file diff --git a/src/kOS.Safe/Screen/ScreenBufferLine.cs b/src/kOS.Safe/Screen/ScreenBufferLine.cs index a3cf0b458..25f5c68bd 100644 --- a/src/kOS.Safe/Screen/ScreenBufferLine.cs +++ b/src/kOS.Safe/Screen/ScreenBufferLine.cs @@ -1,12 +1,11 @@ -using System; -using kOS.Safe.Utilities; +using kOS.Safe.Utilities; +using System; namespace kOS.Safe.Screen { - /// /// This is basically just an array of chars, but one in which it keeps track of the timestamp - /// of the most recent alteration of the contents. It's not particulary vigorous about catching + /// of the most recent alteration of the contents. It's not particularly vigorous about catching /// all the possible ways one could change the contents. ///
    /// To keep it simple, not all the possible array operations have been implemented here, @@ -14,6 +13,8 @@ namespace kOS.Safe.Screen ///
    public class ScreenBufferLine : IScreenBufferLine { + private readonly char[] charArray; + /// /// A number representing a count that can be used to check which changed /// line is newer. It doesn't store the real time, just an ever-increasing @@ -23,12 +24,10 @@ public class ScreenBufferLine : IScreenBufferLine /// returns the same fixed value for a few milliseconds before updating itself, /// leading to a lot of 'ties' if its used as timestamp on code that runs fast. /// - public ulong LastChangeTick {get; private set;} + public ulong LastChangeTick { get; private set; } - private char[] charArray; + public int Length { get { return charArray.Length; } } - public int Length {get { return charArray.Length;}} - /// /// Return a copy of the contents array. It's a copy, not the internal array, /// so altering it won't change the actual values or update the timestamp. @@ -36,11 +35,11 @@ public class ScreenBufferLine : IScreenBufferLine /// public char[] ToArray() { - char [] safeOutputOnlyCopy = new Char[charArray.Length]; - Array.Copy( charArray,safeOutputOnlyCopy, charArray.Length); + char[] safeOutputOnlyCopy = new Char[charArray.Length]; + Array.Copy(charArray, safeOutputOnlyCopy, charArray.Length); return safeOutputOnlyCopy; } - + /// /// Perform the array index operator, updating the change time if a value is changed. /// @@ -70,7 +69,7 @@ public void ArrayCopyFrom(char[] source, int sourceStart, int destinationStart, Array.Copy(source, sourceStart, charArray, destinationStart, (length >= 0 ? length : source.Length)); TouchTime(); } - + /// /// Perform the Array.Copy() function. /// Copies a subrange of values from a source array into this array. @@ -89,10 +88,10 @@ public void TouchTime() { LastChangeTick = TickGen.Next; } - + public override string ToString() { return new String(charArray); } } -} +} \ No newline at end of file diff --git a/src/kOS.Safe/Screen/ScreenSnapshot.cs b/src/kOS.Safe/Screen/ScreenSnapshot.cs index fb2ebb5d2..fd4a61dcf 100644 --- a/src/kOS.Safe/Screen/ScreenSnapshot.cs +++ b/src/kOS.Safe/Screen/ScreenSnapshot.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.Text; -using kOS.Safe.Screen; using kOS.Safe.UserIO; namespace kOS.Safe.Screen @@ -30,7 +29,7 @@ public class ScreenSnapShot : IScreenSnapShot // This setting is how far apart diff sections on the same row have to be before it will // perform a cursor jump to get from one to the other, rather than just overwriting the same // string as was already there. - private const int joinDiffDist = 6; + private const int JOIN_DIFF_DIST = 6; /// /// Make a screen snapshot of the current state of the screenbuffer. @@ -52,19 +51,21 @@ private ScreenSnapShot() /// /// Make a copy of me for later diffing against. /// Almost a deep copy. - /// The new copy /// + /// The new copy public IScreenSnapShot DeepCopy() { - ScreenSnapShot newCopy = new ScreenSnapShot(); - newCopy.TopRow = TopRow; - newCopy.CursorColumn = CursorColumn; - newCopy.CursorRow = CursorRow; - newCopy.RowCount = RowCount; - + ScreenSnapShot newCopy = new ScreenSnapShot + { + TopRow = TopRow, + CursorColumn = CursorColumn, + CursorRow = CursorRow, + RowCount = RowCount, + Buffer = new List() + }; + // This will probably reset the timestamps on the rows, but for our purposes that's actually fine - we call this // when we want to get a fully sync'ed copy: - newCopy.Buffer = new List(); foreach (IScreenBufferLine line in Buffer) { ScreenBufferLine newLine = new ScreenBufferLine(line.Length); @@ -78,7 +79,7 @@ public IScreenSnapShot DeepCopy() /// Get a list of the operations that would make a terminal window look like this snapshot /// if you assume that beforehand it looked like the older snapshot you pass in. /// - /// the older snapshot of a screen to diff from + /// the older snapshot of a screen to diff from /// the string that if output in order, will give you the desired changes public string DiffFrom(IScreenSnapShot older) { @@ -118,11 +119,13 @@ public string DiffFrom(IScreenSnapShot older) if (newChar != oldChar) { // Start a new diff chunk if there isn't one yet, or the diff is a long enough distance from the existing one: - if (diffs.Count == 0 || diffs[diffs.Count-1].EndCol < newCol - joinDiffDist) + if (diffs.Count == 0 || diffs[diffs.Count-1].EndCol < newCol - JOIN_DIFF_DIST) { - DiffChunk newChunk = new DiffChunk(); - newChunk.StartCol = newCol; - newChunk.EndCol = newCol; + DiffChunk newChunk = new DiffChunk + { + StartCol = newCol, + EndCol = newCol + }; diffs.Add(newChunk); } else // stretch the existing diff chunk to here. diff --git a/src/kOS.Safe/Screen/TextEditor.cs b/src/kOS.Safe/Screen/TextEditor.cs index 089fa4c32..3406d4bc6 100644 --- a/src/kOS.Safe/Screen/TextEditor.cs +++ b/src/kOS.Safe/Screen/TextEditor.cs @@ -1,6 +1,5 @@ using System.Collections.Generic; using System.Text; -using kOS.Safe.Utilities; using kOS.Safe.UserIO; namespace kOS.Safe.Screen diff --git a/src/kOS.Safe/UserIO/UnicodeCommand.cs b/src/kOS.Safe/UserIO/UnicodeCommand.cs index 47c912c07..aac31677d 100644 --- a/src/kOS.Safe/UserIO/UnicodeCommand.cs +++ b/src/kOS.Safe/UserIO/UnicodeCommand.cs @@ -1,17 +1,7 @@ -/* - * Created by SharpDevelop. - * User: Dunbaratu - * Date: 2/5/2015 - * Time: 12:47 AM - * - * To change this template use Tools | Options | Coding | Edit Standard Headers. - */ -using System; - -namespace kOS.Safe.UserIO +namespace kOS.Safe.UserIO { /// - /// A list of extra unicode command characters we use to genericize command codes, abstracting away + /// A list of extra Unicode command characters we use to generalize command codes, abstracting away /// the differences between different terminal models. ///
    /// These are all stored in the Unicode "private use" area in range [0xE000..0xF8FF]. @@ -25,13 +15,13 @@ namespace kOS.Safe.UserIO /// C# does not allow us to do the correct thing here, which is this: /// public enum UnicodeCommand : char { stuff, stuff, stuff,....} /// For some reason I cannot fathom, C# lets you pick the type of any enum EXCEPT char, even - /// though a unicode char is still a well defined narrow known number of bits and should + /// though a Unicode char is still a well defined narrow known number of bits and should /// effectively work just as well for enums as, say, a ushort. ///
    /// If anyone does have the ambition to get rid of the need for all the casting, they can /// go through here and turn all these into const chars if they like. But that means having /// to manually type in their number value for each one instead of just letting the enum - /// syntax auto-increment it for each sucessive one. + /// syntax auto-increment it for each successive one. ///
    public enum UnicodeCommand { @@ -40,7 +30,7 @@ public enum UnicodeCommand // NOTE: Several of these are here for future expansion ideas but are not yet implemented // in the individual terminal-specific mappers (TerminalXtermMapper, TerminalVt100Mapper, etc). // - // To avoid the confusion of accidentally using the ones that are not implmented, the unused + // To avoid the confusion of accidentally using the ones that are not implemented, the unused // ones are commented out. But they're still here for possible future plans. // @@ -53,7 +43,7 @@ public enum UnicodeCommand /// /// Indicates that when this character is seen on the output stream, the connection should - /// close down at that point, after the charactes prior to it have been sent out: + /// close down at that point, after the characters prior to it have been sent out: /// DIE, @@ -78,7 +68,7 @@ public enum UnicodeCommand /// /// Begins a cursor move to an exact position. Expects exactly 2 more
    - /// unicode chars to follow, interpreted as binary number data (not as characters)
    + /// Unicode chars to follow, interpreted as binary number data (not as characters)
    /// for the column num and row num, respectively.
    ///
    /// Example: To move the cursor to the 33rd column, 16th row:
    @@ -161,7 +151,7 @@ public enum UnicodeCommand /// /// Abstracts away all that CR/LF vs LF only versus CR only nonsense. In the pretend - /// unicode terminal we are referring to, we'll map them all to the same character, + /// Unicode terminal we are referring to, we'll map them all to the same character, /// this one. This character means go to the start of the next line. /// Also used on input to represent hitting either the return or the enter key. /// @@ -183,7 +173,7 @@ public enum UnicodeCommand /// /// Scroll the screen up one line (like what happens when you hit 'return' when - /// the cursor is at the bottomleft of the screen), but leave the cursor where it is. + /// the cursor is at the bottom left of the screen), but leave the cursor where it is. /// SCROLLSCREENUPONE, @@ -194,28 +184,28 @@ public enum UnicodeCommand SCROLLSCREENDOWNONE, // /// - // /// Indicates moving a cursor [count] rows up. Expects exactly 1 more unicode + // /// Indicates moving a cursor [count] rows up. Expects exactly 1 more Unicode // /// char to follow, interpreted as binary number data (not as character) for // /// the number of spaces to move. // /// // UPCURSORNUM, // /// - // /// Indicates moving a cursor [count] rows down. Expects exactly 1 more unicode + // /// Indicates moving a cursor [count] rows down. Expects exactly 1 more Unicode // /// char to follow, interpreted as binary number data (not as character) for // /// the number of spaces to move. // /// // DOWNCURSORNUM, // /// - // /// Indicates moving a cursor [count] spaces left. Expects exactly 1 more unicode + // /// Indicates moving a cursor [count] spaces left. Expects exactly 1 more Unicode // /// char to follow, interpreted as binary number data (not as character) for // /// the number of spaces to move. // /// // LEFTCURSORNUM, // /// - // /// Indicates moving a cursor [count] spaces right. Expects exactly 1 more unicode + // /// Indicates moving a cursor [count] spaces right. Expects exactly 1 more Unicode // /// char to follow, interpreted as binary number data (not as character) for // /// the number of spaces to move. // /// @@ -227,8 +217,8 @@ public enum UnicodeCommand /// for the server telling the client to it needs to resize itself. /// Expects a sequence of 3 characters as follows:
    /// RESIZESCREEN Binary_Width_Num Binary_Height_Num
    - /// Where Width_num and Height_num are the numbers directly transcoded into unicode chars in a binary way. - /// (For example a height of 66, which is hex 0x32 would end up being sent as the capital letter 'B' which is unicode 0x0032.). + /// Where Width_num and Height_num are the numbers directly transcoded into Unicode chars in a binary way. + /// (For example a height of 66, which is hex 0x32 would end up being sent as the capital letter 'B' which is Unicode 0x0032.). ///
    RESIZESCREEN, } diff --git a/src/kOS.Safe/Utilities/TickGen.cs b/src/kOS.Safe/Utilities/TickGen.cs index a424aa680..37d5e84fd 100644 --- a/src/kOS.Safe/Utilities/TickGen.cs +++ b/src/kOS.Safe/Utilities/TickGen.cs @@ -7,7 +7,7 @@ namespace kOS.Safe.Utilities /// for a number. That's all. Its meant to be used to timestamp the relative age of things. /// Bigger numbers were returned later in the life of the program than smaller ones. /// It could potentially overflow, but only if the program ran nonstop without crashing for - /// a ludicrious amount of time. (Uint64 can store a number more than two orders of magnitude + /// a ludicrous amount of time. (Uint64 can store a number more than two orders of magnitude /// larger than the number of NANOseconds in a year.) ///
    public class TickGen diff --git a/src/kOS/AddOns/RemoteTech2/RemoteTechInterpreter.cs b/src/kOS/AddOns/RemoteTech2/RemoteTechInterpreter.cs index f12b651d8..d37eb6f9d 100644 --- a/src/kOS/AddOns/RemoteTech2/RemoteTechInterpreter.cs +++ b/src/kOS/AddOns/RemoteTech2/RemoteTechInterpreter.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using kOS.Safe; using kOS.Safe.Screen; -using kOS.Safe.Utilities; using kOS.Safe.UserIO; using kOS.Screen; @@ -131,7 +130,7 @@ private void UpdateDeployment(double deltaTime) signalLossWarning = false; } - waitElapsed += System.Math.Min(deltaTime, waitTotal - waitElapsed); + waitElapsed += Math.Min(deltaTime, waitTotal - waitElapsed); DrawProgressBar(waitElapsed, waitTotal); if (waitElapsed == waitTotal) diff --git a/src/kOS/Function/PrintList.cs b/src/kOS/Function/PrintList.cs index af903d5fc..e82c30bf7 100644 --- a/src/kOS/Function/PrintList.cs +++ b/src/kOS/Function/PrintList.cs @@ -324,7 +324,7 @@ public void AddItem(params object[] fields) BuildFormatString(); } - object[] stringFields = new string[fields.Length]; + var stringFields = new object[fields.Length]; for (int index = 0; index < columns.Count; index++) { string field; diff --git a/src/kOS/Module/kOSProcessor.cs b/src/kOS/Module/kOSProcessor.cs index 9c00fb6c7..5ce2fb32f 100644 --- a/src/kOS/Module/kOSProcessor.cs +++ b/src/kOS/Module/kOSProcessor.cs @@ -109,7 +109,7 @@ public void ToggleWindow() public bool WindowIsOpen() { - return shared.Window.IsOpen(); + return shared.Window.IsOpen; } public bool TelnetIsAttached() @@ -122,8 +122,8 @@ public IScreenBuffer GetScreen() return shared.Screen; } - public kOS.Screen.TermWindow GetWindow() // TODO - later refactor making this kOS.Safer so it can work on ITermWindow, which also means moving all of UserIO's classes too. + public Screen.TermWindow GetWindow() { return shared.Window; } diff --git a/src/kOS/Screen/Interpreter.cs b/src/kOS/Screen/Interpreter.cs index 83497652f..be0e1e987 100644 --- a/src/kOS/Screen/Interpreter.cs +++ b/src/kOS/Screen/Interpreter.cs @@ -4,7 +4,6 @@ using kOS.Execution; using kOS.Safe.Compilation; using kOS.Safe.Screen; -using kOS.Safe.Utilities; using kOS.Safe.UserIO; namespace kOS.Screen diff --git a/src/kOS/Screen/KOSManagedWindow.cs b/src/kOS/Screen/KOSManagedWindow.cs index 6bedd2f34..de2a8bb37 100644 --- a/src/kOS/Screen/KOSManagedWindow.cs +++ b/src/kOS/Screen/KOSManagedWindow.cs @@ -16,40 +16,119 @@ public abstract class KOSManagedWindow : MonoBehaviour // Give each instance of TermWindow a unique ID block to ensure it can create // Unity windows that don't clash: - protected static int termWindowIDRange = 215300; // I literally just mashed the keyboard to get a unique number. - protected static int windowsMadeSoFar = 0; + private static int termWindowIDRange = 215300; // I literally just mashed the keyboard to get a unique number. + private static int windowsMadeSoFar; // Keep track of the stacking order of the Terminal windows relative to each other. // surprisingly, the Unity GUi doesn't do this automatically itself: - protected static List depthSort = new List(); + private static List depthSort = new List(); + + private static int dragTolerance = 2; // mouse pixel movement of this or less counts as a click and not a drag. - protected static int dragTolerance = 2; // mouse pixel movement of this or less counts as a click and not a drag. - - protected Rect windowRect; + private Rect windowRect; - protected int uniqueId; // For the window attached to this widget. + private int uniqueId; // For the window attached to this widget. /// subclasses of KOSManagedWindow can use these to see the mouse position /// by full screen coords, or relative to their windowRect: - protected Vector2 mousePosAbsolute; - protected Vector2 mousePosRelative; + private Vector2 mousePosAbsolute; + + private Vector2 mousePosRelative; /// When doing a mousedown, and mouseup to form a click, this is the /// position of the most recent mousedown: - protected Vector2 mouseButtonDownPosAbsolute; - protected Vector2 mouseButtonDownPosRelative; + private Vector2 mouseButtonDownPosAbsolute; + + private Vector2 mouseButtonDownPosRelative; - protected bool isOpen = false; + private bool isOpen; protected KOSManagedWindow() { - // mult by 50 so there's a range for future expansion for other GUI objects inside the window: + // multiply by 50 so there's a range for future expansion for other GUI objects inside the window: uniqueId = termWindowIDRange + (windowsMadeSoFar * 50); ++windowsMadeSoFar; } public bool IsPowered { get; set; } + protected static int TermWindowIDRange + { + get { return termWindowIDRange; } + set { termWindowIDRange = value; } + } + + protected static int WindowsMadeSoFar + { + get { return windowsMadeSoFar; } + set { windowsMadeSoFar = value; } + } + + protected static List DepthSort + { + get { return depthSort; } + set { depthSort = value; } + } + + protected static int DragTolerance + { + get { return dragTolerance; } + set { dragTolerance = value; } + } + + protected Rect WindowRect + { + get { return windowRect; } + set { windowRect = value; } + } + + protected int UniqueId + { + get { return uniqueId; } + set { uniqueId = value; } + } + + /// + /// subclasses of KOSManagedWindow can use this to see the mouse position + /// by full screen coords + /// + protected Vector2 MousePosAbsolute + { + get { return mousePosAbsolute; } + set { mousePosAbsolute = value; } + } + + /// + /// subclasses of KOSManagedWindow can use this to see the mouse position + /// relative to their windowRect + /// + protected Vector2 MousePosRelative + { + get { return mousePosRelative; } + set { mousePosRelative = value; } + } + + /// + /// When doing a mousedown, and mouseup to form a click, this is the + /// absolute position of the most recent mousedown: + /// + protected Vector2 MouseButtonDownPosAbsolute + { + get { return mouseButtonDownPosAbsolute; } + set { mouseButtonDownPosAbsolute = value; } + } + + /// + /// When doing a mousedown, and mouseup to form a click, this is the + /// relative position of the most recent mousedown: + /// + protected Vector2 MouseButtonDownPosRelative + { + get { return mouseButtonDownPosRelative; } + set { mouseButtonDownPosRelative = value; } + } + + /// /// Implement this for how to make your widget get the keyboard focus: /// @@ -92,9 +171,10 @@ public virtual void Close() // DumpDepthSort(); } - public virtual bool IsOpen() + public bool IsOpen { - return isOpen; + get { return isOpen; } + protected set { isOpen = value; } } public void DumpDepthSort() // exists purely for debugging. @@ -130,7 +210,7 @@ public bool FocusClickLocationCheck(Vector2 absMousePos) } /// - /// Cause this window to become frontmost, AND it also gets the keyboard focus. + /// Cause this window to become front most, AND it also gets the keyboard focus. /// public virtual void BringToFront() { @@ -181,33 +261,31 @@ public bool IsInsideMyExposedPortion(Vector2 posAbsolute) /// True if there was a mouseclick within this window. public bool UpdateLogic() { - if (IsOpen()) - { - // Input.mousePosition, unlike Event.current.MousePosition, puts the origin at the - // lower-left instead of upper-left of the screen, thus the subtraction in the y coord below: - mousePosAbsolute = new Vector2( Input.mousePosition.x, UnityEngine.Screen.height - Input.mousePosition.y); + if (!IsOpen) return false; + + // Input.mousePosition, unlike Event.current.MousePosition, puts the origin at the + // lower-left instead of upper-left of the screen, thus the subtraction in the y coord below: + mousePosAbsolute = new Vector2( Input.mousePosition.x, UnityEngine.Screen.height - Input.mousePosition.y); - // Mouse coord within the window, rather than within the screen. - mousePosRelative = new Vector2( mousePosAbsolute.x - windowRect.xMin, mousePosAbsolute.y - windowRect.yMin); + // Mouse coord within the window, rather than within the screen. + mousePosRelative = new Vector2( mousePosAbsolute.x - windowRect.xMin, mousePosAbsolute.y - windowRect.yMin); - bool clickUp = false; - if (Input.GetMouseButtonDown(0)) - { - mouseButtonDownPosAbsolute = mousePosAbsolute; - mouseButtonDownPosRelative = mousePosRelative; - } + bool clickUp = false; + if (Input.GetMouseButtonDown(0)) + { + mouseButtonDownPosAbsolute = mousePosAbsolute; + mouseButtonDownPosRelative = mousePosRelative; + } - if (Input.GetMouseButtonUp(0)) + if (Input.GetMouseButtonUp(0)) + { + clickUp = true; + if (Vector2.Distance(mousePosAbsolute,mouseButtonDownPosAbsolute) <= dragTolerance) { - clickUp = true; - if (Vector2.Distance(mousePosAbsolute,mouseButtonDownPosAbsolute) <= dragTolerance) - { - FocusClickLocationCheck(mousePosAbsolute); - } + FocusClickLocationCheck(mousePosAbsolute); } - return IsInsideMyExposedPortion(mousePosAbsolute) && clickUp; } - return false; + return IsInsideMyExposedPortion(mousePosAbsolute) && clickUp; } } } diff --git a/src/kOS/Screen/KOSTextEditPopup.cs b/src/kOS/Screen/KOSTextEditPopup.cs index 9c8161315..7f05f4a46 100644 --- a/src/kOS/Screen/KOSTextEditPopup.cs +++ b/src/kOS/Screen/KOSTextEditPopup.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using kOS.Safe.Persistence; using UnityEngine; -using kOS.Persistence; namespace kOS.Screen { @@ -41,10 +40,10 @@ public class KOSTextEditPopup : KOSManagedWindow public KOSTextEditPopup() { - uniqueId = 100 ; // This is expected to be overridden, but Unity requires that + UniqueId = 100 ; // This is expected to be overridden, but Unity requires that // KosTextEditPopup() be a constructor that takes zero arguments, // so the real WindowId has to be set after construction. - windowRect = new Rect(0,0,470,280); // bogus starting value will be changed later when attaching to a terminal. + WindowRect = new Rect(0,0,470,280); // bogus starting value will be changed later when attaching to a terminal. } public void Freeze(bool newVal) @@ -64,7 +63,7 @@ public void Awake() public void AttachTo( TermWindow termWindow, Volume attachVolume, string attachFileName = "" ) { term = termWindow; - windowRect = new Rect(0,0,470,280); // will be resized and moved in onGUI. + WindowRect = new Rect(0,0,470,280); // will be resized and moved in onGUI. frozen = false; loadingVolume = attachVolume; loadingFileName = attachFileName; @@ -73,7 +72,7 @@ public void AttachTo( TermWindow termWindow, Volume attachVolume, string attachF public bool Contains(Vector2 posAbs) { - return windowRect.Contains(posAbs); + return WindowRect.Contains(posAbs); } public override void GetFocus() @@ -101,30 +100,30 @@ public override void Close() public int GetUniqueId() { - return uniqueId; + return UniqueId; } public void SetUniqueId(int newValue) { - uniqueId = newValue; + UniqueId = newValue; } public void Update() { // Only stay open as long as the attached terminal window stays open: - if (IsOpen() && ( term == null || !(term.IsPowered) )) - isOpen = false; + if (IsOpen && ( term == null || !(term.IsPowered) )) + IsOpen = false; UpdateLogic(); } public void OnGUI() { - if (!IsOpen()) return; + if (!IsOpen) return; CalcOuterCoords(); // force windowRect to lock to bottom edge of the parents CalcInnerCoords(); - windowRect = GUI.Window( uniqueId, windowRect, ProcessWindow, "" ); + WindowRect = GUI.Window( UniqueId, WindowRect, ProcessWindow, "" ); // Some mouse global state data used by several of the checks: // TODO: we aren't using this, do we need it? Event e = Event.current; @@ -147,8 +146,10 @@ protected void ExitEditor() public void SaveContents() { - var file = new ProgramFile(fileName); - file.StringContent = contents; + var file = new ProgramFile(fileName) + { + StringContent = contents + }; if (! volume.SaveFile(file) ) { @@ -303,7 +304,7 @@ protected void CheckKeyboard() protected void DoPageUp() { - UnityEngine.TextEditor editor = GetWidgetController(); + var editor = GetWidgetController(); // Seems to be no way to move more than one line at // a time - so have to do this: @@ -320,7 +321,7 @@ protected void DoPageUp() protected void DoPageDown() { - UnityEngine.TextEditor editor = GetWidgetController(); + var editor = GetWidgetController(); // Seems to be no way to move more than one line at // a time - so have to do this: @@ -341,10 +342,10 @@ protected void CheckResizeDrag() if (e.type == EventType.mouseDown && e.button == 0) { // Remember the fact that this mouseDown started on the resize button: - if (resizeButtonCoords.Contains(mouseButtonDownPosRelative)) + if (resizeButtonCoords.Contains(MouseButtonDownPosRelative)) { resizeMouseDown = true; - resizeOldSize = new Vector2(windowRect.width,windowRect.height); + resizeOldSize = new Vector2(WindowRect.width,WindowRect.height); Event.current.Use(); } } @@ -364,9 +365,9 @@ protected void CheckResizeDrag() if (resizeMouseDown) { var mousePos = new Vector2(Event.current.mousePosition.x, Event.current.mousePosition.y); - Vector2 dragDelta = mousePos - mouseButtonDownPosRelative; - windowRect = new Rect( windowRect.xMin, - windowRect.yMin, + Vector2 dragDelta = mousePos - MouseButtonDownPosRelative; + WindowRect = new Rect( WindowRect.xMin, + WindowRect.yMin, Math.Max( resizeOldSize.x + dragDelta.x, 100 ), Math.Max( resizeOldSize.y + dragDelta.y, 30 ) ); CalcInnerCoords(); @@ -426,7 +427,7 @@ protected void DrawWindow( int windowId ) protected void CalcOuterCoords() { - if (IsOpen() && term != null) + if (IsOpen && term != null) { Rect tRect = term.GetRect(); @@ -436,21 +437,21 @@ protected void CalcOuterCoords() // If it hasn't been given a size yet, then give it a starting size that matches // the attached terminal window size. Otherwise keep whatever size the user changed it to: - if (windowRect.width == 0) - windowRect = new Rect( left, top, tRect.width, tRect.height ); + if (WindowRect.width == 0) + WindowRect = new Rect( left, top, tRect.width, tRect.height ); else - windowRect = new Rect( left, top, windowRect.width, windowRect.height ); + WindowRect = new Rect( left, top, WindowRect.width, WindowRect.height ); } } protected void CalcInnerCoords() { - if (!IsOpen()) return; + if (!IsOpen) return; innerCoords = new Rect( FRAME_THICKNESS, FRAME_THICKNESS + 1.5f*FONT_HEIGHT, - windowRect.width - 2*FRAME_THICKNESS, - windowRect.height - 2*FRAME_THICKNESS -2*FONT_HEIGHT ); + WindowRect.width - 2*FRAME_THICKNESS, + WindowRect.height - 2*FRAME_THICKNESS -2*FONT_HEIGHT ); Vector2 labSize = GUI.skin.label.CalcSize( new GUIContent(BuildTitle()) ); Vector2 exitSize = GUI.skin.box.CalcSize( new GUIContent(EXIT_BUTTON_TEXT) ); @@ -462,7 +463,7 @@ protected void CalcInnerCoords() labelCoords = new Rect( 5, 1, labSize.x, labSize.y); - float buttonXCounter = windowRect.width; // Keep track of the x coord of leftmost button so far. + float buttonXCounter = WindowRect.width; // Keep track of the x coord of leftmost button so far. buttonXCounter -= (exitSize.x + 5); exitCoords = new Rect( buttonXCounter, 1, exitSize.x, exitSize.y ); @@ -473,8 +474,8 @@ protected void CalcInnerCoords() buttonXCounter -= (reloadSize.x + 2); reloadCoords = new Rect( buttonXCounter, 1, reloadSize.x, reloadSize.y ); - resizeButtonCoords = new Rect( windowRect.width - resizeImage.width, - windowRect.height - resizeImage.height, + resizeButtonCoords = new Rect( WindowRect.width - resizeImage.width, + WindowRect.height - resizeImage.height, resizeImage.width, resizeImage.height ); } @@ -492,7 +493,7 @@ protected void KeepCursorScrolledInView() // Fixing that would take a bit of work. // - UnityEngine.TextEditor editor = GetWidgetController(); + var editor = GetWidgetController(); Vector2 pos = editor.graphicalCursorPos; float usableHeight = innerCoords.height - 2.5f*FONT_HEIGHT; if (pos.y < scrollPosition.y) @@ -503,18 +504,18 @@ protected void KeepCursorScrolledInView() } // Return type needs full namespace path because kOS namespace has a TextEditor class too: - protected UnityEngine.TextEditor GetWidgetController() + protected TextEditor GetWidgetController() { // Whichever TextEdit widget has current focus (should be this one if processing input): // There seems to be no way to grab the text edit controller of a Unity Widget by // specific ID. - return (UnityEngine.TextEditor) - GUIUtility.GetStateObject(typeof(UnityEngine.TextEditor), GUIUtility.keyboardControl); + return (TextEditor) + GUIUtility.GetStateObject(typeof(TextEditor), GUIUtility.keyboardControl); } public Rect GetRect() { - return windowRect; + return WindowRect; } protected string BuildTitle() diff --git a/src/kOS/Screen/TermWindow.cs b/src/kOS/Screen/TermWindow.cs index a66241d52..b344ad4e5 100644 --- a/src/kOS/Screen/TermWindow.cs +++ b/src/kOS/Screen/TermWindow.cs @@ -4,7 +4,6 @@ using kOS.Safe.Persistence; using UnityEngine; using kOS.Safe.Screen; -using kOS.Safe.Utilities; using kOS.Module; using kOS.UserIO; using kOS.Safe.UserIO; @@ -14,7 +13,6 @@ namespace kOS.Screen // Blockotronix 550 Computor Monitor public class TermWindow : KOSManagedWindow , ITermWindow { - private const string TERMINAL_MODEL = "kOS-GREEN-ONE"; private const int CHARSIZE = 8; private const string CONTROL_LOCKOUT = "kOSTerminal"; private const int FONTIMAGE_CHARS_PER_ROW = 16; @@ -50,8 +48,8 @@ public class TermWindow : KOSManagedWindow , ITermWindow private Color currentTextColor = new Color(1,1,1,1); // a dummy color at first just so it won't crash before TerminalGUI() where it's *really* set. // data stored per telnet client attached: - private List telnets; // support exists for more than one telnet client to be attached to the same terminal, thus this is a list. - private Dictionary prevTelnetScreens; + private readonly List telnets; // support exists for more than one telnet client to be attached to the same terminal, thus this is a list. + private readonly Dictionary prevTelnetScreens; private ExpectNextChar inputExpected = ExpectNextChar.NORMAL; private int pendingWidth; // width to come from a resize combo. @@ -66,7 +64,7 @@ public class TermWindow : KOSManagedWindow , ITermWindow public TermWindow() { IsPowered = true; - windowRect = new Rect(50, 60, 0, 0); // will get resized later in AttachTo(). + WindowRect = new Rect(50, 60, 0, 0); // will get resized later in AttachTo(). telnets = new List(); prevTelnetScreens = new Dictionary(); } @@ -83,7 +81,7 @@ public void Awake() var gObj = new GameObject( "texteditPopup", typeof(KOSTextEditPopup) ); DontDestroyOnLoad(gObj); popupEditor = (KOSTextEditPopup)gObj.GetComponent(typeof(KOSTextEditPopup)); - popupEditor.SetUniqueId(uniqueId + 5); + popupEditor.SetUniqueId(UniqueId + 5); } public void LoadTexture(String relativePath, ref Texture2D targetTexture) @@ -124,7 +122,7 @@ public override void Close() public void Toggle() { - if (IsOpen()) Close(); + if (IsOpen) Close(); else Open(); } @@ -182,7 +180,7 @@ private void Unlock() void OnGUI() { - if (!IsOpen()) return; + if (!IsOpen) return; if (isLocked) ProcessKeyEvents(); @@ -199,10 +197,9 @@ void OnGUI() GUI.color = isLocked ? color : colorAlpha; // Should probably make "gui screen name for my CPU part" into some sort of utility method: - KOSNameTag partTag = shared.KSPPart.Modules.OfType().FirstOrDefault(); ChangeTitle(CalcualteTitle()); - windowRect = GUI.Window(uniqueId, windowRect, TerminalGui, TitleText); + WindowRect = GUI.Window(UniqueId, WindowRect, TerminalGui, TitleText); if (consumeEvent) { @@ -223,7 +220,7 @@ void Update() TelnetOutputUpdate(); ProcessTelnetInput(); // want to do this even when the terminal isn't actually displaying. - if (!IsOpen() ) return; + if (!IsOpen ) return; UpdateLogic(); @@ -239,7 +236,7 @@ void TelnetOutputUpdate() // Throttle it back so the faster Update() rates don't cause pointlessly repeated work: // Needs to be no faster than the fastest theoretical typist or script might change the view. - if (newTime > lastTelnetIncrementalRepaint + System.TimeSpan.FromMilliseconds(50)) // = 1/20th second. + if (newTime > lastTelnetIncrementalRepaint + TimeSpan.FromMilliseconds(50)) // = 1/20th second. { lastTelnetIncrementalRepaint = newTime; foreach (TelnetSingletonServer telnet in telnets) @@ -342,9 +339,8 @@ void ProcessKeyEvents() ///
    private void ProcessTelnetInput() { - for( int i = 0 ; i < telnets.Count ; ++i) + foreach (var telnet in telnets) { - TelnetSingletonServer telnet = telnets[i]; while (telnet.InputWaiting()) { ProcessOneInputChar(telnet.ReadChar(), telnet); @@ -353,16 +349,16 @@ private void ProcessTelnetInput() } /// - /// Respond to one single input character in unicode, using the pretend - /// virtual unicode terminal keycodes described in the UnicodeCommand enum. - /// To keep things simple, all key input is coerced into single unicode chars + /// Respond to one single input character in Unicode, using the pretend + /// virtual Unicode terminal keycodes described in the UnicodeCommand enum. + /// To keep things simple, all key input is coerced into single Unicode chars /// even if the actual keypress takes multiple characters to express in its /// native form (i.e. ESC [ A means left-arrow on a VT100 terminal. If /// a telnet is talking via VT100 codes, that ESC [ A will get converted into /// a single UnicdeCommand.LEFTCURSORONE character before being sent here.) ///
    /// This method is public because it is also how other mods should send input - /// to the terminal if they want some other soruce to send simulated keystrokes. + /// to the terminal if they want some other source to send simulated keystrokes. ///
    /// The character, which might be a UnicodeCommand char /// If this came from a telnet session, which one did it come from? @@ -373,11 +369,11 @@ public void ProcessOneInputChar(char ch, TelnetSingletonServer whichTelnet) switch (inputExpected) { case ExpectNextChar.RESIZEWIDTH: - pendingWidth = (int)ch; + pendingWidth = ch; inputExpected = ExpectNextChar.RESIZEHEIGHT; return; case ExpectNextChar.RESIZEHEIGHT: - int height = (int)ch; + int height = ch; shared.Screen.SetSize(height, pendingWidth); inputExpected = ExpectNextChar.NORMAL; return; @@ -385,10 +381,10 @@ public void ProcessOneInputChar(char ch, TelnetSingletonServer whichTelnet) break; } - // Printable ascii section of unicode - the common vanila situation - // (Idea: Since this is all unicode anyway, should we allow a wider range to + // Printable ASCII section of Unicode - the common vanilla situation + // (Idea: Since this is all Unicode anyway, should we allow a wider range to // include multi-language accent characters and so on? Answer: to do so we'd - // first need to expand the font pictures in the fontimage file, so it's a + // first need to expand the font pictures in the font image file, so it's a // bigger task than it may first seem.) if (0x0020 <= ch && ch <= 0x007f) { @@ -469,7 +465,7 @@ void GetNewestBuffer() // Throttle it back so the faster Update() rates don't cause pointlessly repeated work: // Needs to be no faster than the fastest theoretical typist or script might change the view. - if (newTime > lastBufferGet + System.TimeSpan.FromMilliseconds(50)) // = 1/20th second. + if (newTime > lastBufferGet + TimeSpan.FromMilliseconds(50)) // = 1/20th second. { mostRecentScreen = new ScreenSnapShot(shared.Screen); lastBufferGet = newTime; @@ -496,15 +492,15 @@ void TerminalGui(int windowId) IScreenBuffer screen = shared.Screen; GUI.color = isLocked ? color : colorAlpha; - GUI.DrawTexture(new Rect(15, 20, windowRect.width-30, windowRect.height-55), terminalImage); + GUI.DrawTexture(new Rect(15, 20, WindowRect.width-30, WindowRect.height-55), terminalImage); if (telnets.Count > 0) DrawTelnetStatus(); - closeButtonRect = new Rect(windowRect.width-75, windowRect.height-30, 50, 25); + closeButtonRect = new Rect(WindowRect.width-75, WindowRect.height-30, 50, 25); - resizeButtonCoords = new Rect(windowRect.width-resizeButtonImage.width, - windowRect.height-resizeButtonImage.height, + resizeButtonCoords = new Rect(WindowRect.width-resizeButtonImage.width, + WindowRect.height-resizeButtonImage.height, resizeButtonImage.width, resizeButtonImage.height); if (GUI.RepeatButton(resizeButtonCoords, resizeButtonImage )) @@ -513,7 +509,7 @@ void TerminalGui(int windowId) { // Remember the fact that this mouseDown started on the resize button: resizeMouseDown = true; - resizeOldSize = new Vector2(windowRect.width, windowRect.height); + resizeOldSize = new Vector2(WindowRect.width, WindowRect.height); } } @@ -538,7 +534,7 @@ void TerminalGui(int windowId) List buffer = mostRecentScreen.Buffer; // just to keep the name shorter below: // Sometimes the buffer is shorter than the terminal height if the resize JUST happened in the last Update(): - int rowsToPaint = System.Math.Min(screen.RowCount, buffer.Count); + int rowsToPaint = Math.Min(screen.RowCount, buffer.Count); for (int row = 0; row < rowsToPaint; row++) { @@ -561,7 +557,7 @@ void TerminalGui(int windowId) } GUI.EndGroup(); - GUI.Label(new Rect(windowRect.width/2-40,windowRect.height-20,100,10),screen.ColumnCount+"x"+screen.RowCount); + GUI.Label(new Rect(WindowRect.width/2-40,WindowRect.height-20,100,10),screen.ColumnCount+"x"+screen.RowCount); CheckResizeDrag(); // Has to occur before DragWindow or else DragWindow will consume the event and prevent drags from being seen by the resize icon. GUI.DragWindow(); @@ -574,8 +570,8 @@ protected void DrawTelnetStatus() { int num = telnets.Count; string message = String.Format( "{0} telnet client{1} attached", num, (num == 1 ? "" : "s")); - GUI.DrawTexture(new Rect(10, windowRect.height - 25, 25, 25), networkZigZagImage); - GUI.Label(new Rect(40, windowRect.height - 25, 160, 20), message); + GUI.DrawTexture(new Rect(10, WindowRect.height - 25, 25, 25), networkZigZagImage); + GUI.Label(new Rect(40, WindowRect.height - 25, 160, 20), message); } protected void CheckResizeDrag() @@ -584,11 +580,11 @@ protected void CheckResizeDrag() { if (resizeMouseDown) // and it's in the midst of a drag. { - Vector2 dragDelta = mousePosAbsolute - mouseButtonDownPosAbsolute; - windowRect = new Rect(windowRect.xMin, - windowRect.yMin, - System.Math.Max(resizeOldSize.x + dragDelta.x, 200), - System.Math.Max(resizeOldSize.y + dragDelta.y, 200)); + Vector2 dragDelta = MousePosAbsolute - MouseButtonDownPosAbsolute; + WindowRect = new Rect(WindowRect.xMin, + WindowRect.yMin, + Math.Max(resizeOldSize.x + dragDelta.x, 200), + Math.Max(resizeOldSize.y + dragDelta.y, 200)); } } else // mouse button is up @@ -608,25 +604,25 @@ protected void CheckResizeDrag() } } - void ShowCharacterByAscii(char ch, int x, int y, Color textColor) + void ShowCharacterByAscii(char ch, int x, int y, Color charTextColor) { int tx = ch % FONTIMAGE_CHARS_PER_ROW; int ty = ch / FONTIMAGE_CHARS_PER_ROW; - ShowCharacterByXY(x, y, tx, ty, textColor); + ShowCharacterByXY(x, y, tx, ty, charTextColor); } - void ShowCharacterByXY(int x, int y, int tx, int ty, Color textColor) + void ShowCharacterByXY(int x, int y, int tx, int ty, Color charTextColor) { GUI.BeginGroup(new Rect((x * CHARSIZE), (y * CHARSIZE), CHARSIZE, CHARSIZE)); - GUI.color = textColor; + GUI.color = charTextColor; GUI.DrawTexture(new Rect(tx * -CHARSIZE, ty * -CHARSIZE, fontImage.width, fontImage.height), fontImage); GUI.EndGroup(); } public Rect GetRect() { - return windowRect; + return WindowRect; } public void Print( string str ) @@ -634,12 +630,12 @@ public void Print( string str ) shared.Screen.Print( str ); } - internal void AttachTo(SharedObjects shared) + internal void AttachTo(SharedObjects sharedObj) { - this.shared = shared; - this.shared.Window = this; - NotifyOfScreenResize(this.shared.Screen); - this.shared.Screen.AddResizeNotifier(NotifyOfScreenResize); + shared = sharedObj; + shared.Window = this; + NotifyOfScreenResize(shared.Screen); + shared.Screen.AddResizeNotifier(NotifyOfScreenResize); ChangeTitle(CalcualteTitle()); } @@ -679,7 +675,7 @@ public void DetachAllTelnets() internal int NotifyOfScreenResize(IScreenBuffer sb) { - windowRect = new Rect(windowRect.xMin, windowRect.yMin, sb.ColumnCount*CHARSIZE + 65, sb.RowCount*CHARSIZE + 100); + WindowRect = new Rect(WindowRect.xMin, WindowRect.yMin, sb.ColumnCount*CHARSIZE + 65, sb.RowCount*CHARSIZE + 100); foreach (TelnetSingletonServer telnet in telnets) { @@ -755,7 +751,7 @@ private void RepaintTelnetFull(TelnetSingletonServer telnet) List buffer = mostRecentScreen.Buffer; // just to keep the name shorter below: // Sometimes the buffer is shorter than the terminal height if the resize JUST happened in the last Update(): - int rowsToPaint = System.Math.Min(shared.Screen.RowCount, buffer.Count); + int rowsToPaint = Math.Min(shared.Screen.RowCount, buffer.Count); telnet.Write((char)UnicodeCommand.CLEARSCREEN); for (int row = 0 ; row < rowsToPaint ; ++row) @@ -810,12 +806,12 @@ public int NumTelnets() private int HowManyRowsFit() { - return (int)(windowRect.height - 100) / CHARSIZE; + return (int)(WindowRect.height - 100) / CHARSIZE; } private int HowManyColumnsFit() { - return (int)(windowRect.width - 65) / CHARSIZE; + return (int)(WindowRect.width - 65) / CHARSIZE; } } diff --git a/src/kOS/Suffixed/BodyTarget.cs b/src/kOS/Suffixed/BodyTarget.cs index 25145af96..f6a4290f7 100644 --- a/src/kOS/Suffixed/BodyTarget.cs +++ b/src/kOS/Suffixed/BodyTarget.cs @@ -1,15 +1,14 @@ -using System; -using kOS.Safe.Encapsulation.Suffixes; +using kOS.Safe.Encapsulation.Suffixes; using kOS.Utilities; +using System; namespace kOS.Suffixed { public class BodyTarget : Orbitable, IKOSTargetable { - public CelestialBody Body { get; set; } - - override public Orbit Orbit{ get{return Body.orbit;} } + + override public Orbit Orbit { get { return Body.orbit; } } override public string GetName() { @@ -18,41 +17,39 @@ override public string GetName() override public Vector GetPosition() { - return new Vector( Body.position - Shared.Vessel.findWorldCenterOfMass() ); + return new Vector(Body.position - Shared.Vessel.findWorldCenterOfMass()); } - + override public OrbitableVelocity GetVelocities() { - return new OrbitableVelocity(Body,Shared); + return new OrbitableVelocity(Body, Shared); } - - override public Vector GetPositionAtUT( TimeSpan timeStamp ) + + override public Vector GetPositionAtUT(TimeSpan timeStamp) { - return new Vector( Body.getPositionAtUT( timeStamp.ToUnixStyleTime() ) - Shared.Vessel.findWorldCenterOfMass() ); + return new Vector(Body.getPositionAtUT(timeStamp.ToUnixStyleTime()) - Shared.Vessel.findWorldCenterOfMass()); } - override public OrbitableVelocity GetVelocitiesAtUT( TimeSpan timeStamp ) + override public OrbitableVelocity GetVelocitiesAtUT(TimeSpan timeStamp) { CelestialBody parent = Body.KOSExtensionGetParentBody(); - if (parent==null) // only if Body is Sun and therefore has no parent, then do more complex work instead because KSP didn't provide a way itself + if (parent == null) // only if Body is Sun and therefore has no parent, then do more complex work instead because KSP didn't provide a way itself { Vector3d futureOrbitalVel; CelestialBody soiBody = Shared.Vessel.mainBody; if (soiBody.orbit != null) futureOrbitalVel = soiBody.orbit.GetFrameVelAtUT(timeStamp.ToUnixStyleTime()); else - futureOrbitalVel = (-1)*(new VesselTarget(Shared.Vessel,Shared).GetVelocitiesAtUT(timeStamp).Orbital.ToVector3D()); - return new OrbitableVelocity( new Vector(futureOrbitalVel), new Vector(0.0,0.0,0.0) ); + futureOrbitalVel = (-1) * (new VesselTarget(Shared.Vessel, Shared).GetVelocitiesAtUT(timeStamp).Orbital.ToVector3D()); + return new OrbitableVelocity(new Vector(futureOrbitalVel), new Vector(0.0, 0.0, 0.0)); } - else - { - var orbVel = new Vector( Orbit.getOrbitalVelocityAtUT( timeStamp.ToUnixStyleTime() ) ); - orbVel = new Vector(orbVel.X,orbVel.Z,orbVel.Y); // swap Y and Z because KSP API is weird. - - var surfVel = new Vector( Body.orbit.GetVel() - parent.getRFrmVel( Body.position ) ); - return new OrbitableVelocity( orbVel, surfVel ); - } + var orbVel = new Vector(Orbit.getOrbitalVelocityAtUT(timeStamp.ToUnixStyleTime())); + orbVel = new Vector(orbVel.X, orbVel.Z, orbVel.Y); // swap Y and Z because KSP API is weird. + + var surfVel = new Vector(Body.orbit.GetVel() - parent.getRFrmVel(Body.position)); + + return new OrbitableVelocity(orbVel, surfVel); } override public Orbit GetOrbitAtUT(double desiredUT) @@ -63,24 +60,25 @@ override public Orbit GetOrbitAtUT(double desiredUT) override public Vector GetUpVector() { CelestialBody parent = Body.KOSExtensionGetParentBody(); - if (parent==null) // only if Body is Sun and therefore has no parent. - return new Vector(0.0,0.0,0.0); - return new Vector( (Body.position - parent.position).normalized ); + return parent == null ? + new Vector(0.0, 0.0, 0.0) : + new Vector((Body.position - parent.position).normalized); } override public Vector GetNorthVector() { CelestialBody parent = Body.KOSExtensionGetParentBody() ?? Body; - return new Vector( Vector3d.Exclude(GetUpVector(), parent.transform.up) ); + return new Vector(Vector3d.Exclude(GetUpVector(), parent.transform.up)); } - public BodyTarget(string name, SharedObjects shareObj) : this(VesselUtils.GetBodyByName(name),shareObj) + public BodyTarget(string name, SharedObjects shareObj) + : this(VesselUtils.GetBodyByName(name), shareObj) { BodyInitializeSuffixes(); - } - public BodyTarget(CelestialBody body, SharedObjects shareObj) :base(shareObj) + public BodyTarget(CelestialBody body, SharedObjects shareObj) + : base(shareObj) { Body = body; BodyInitializeSuffixes(); @@ -88,21 +86,21 @@ public BodyTarget(CelestialBody body, SharedObjects shareObj) :base(shareObj) private void BodyInitializeSuffixes() { - AddSuffix("NAME", new Suffix(()=> Body.name)); - AddSuffix("DESCRIPTION", new Suffix(()=> Body.bodyDescription)); - AddSuffix("MASS", new Suffix(()=> Body.Mass)); - AddSuffix("ALTITUDE", new Suffix(()=> Body.orbit.altitude)); - AddSuffix("RADIUS", new Suffix(()=> Body.Radius)); - AddSuffix("MU", new Suffix(()=> Body.gravParameter)); - AddSuffix("ROTATIONPERIOD", new Suffix(()=> Body.rotationPeriod)); - AddSuffix("ATM", new Suffix(()=> new BodyAtmosphere(Body))); - AddSuffix("ANGULARVEL", new Suffix(()=> new Direction(Body.angularVelocity, true))); + AddSuffix("NAME", new Suffix(() => Body.name)); + AddSuffix("DESCRIPTION", new Suffix(() => Body.bodyDescription)); + AddSuffix("MASS", new Suffix(() => Body.Mass)); + AddSuffix("ALTITUDE", new Suffix(() => Body.orbit.altitude)); + AddSuffix("RADIUS", new Suffix(() => Body.Radius)); + AddSuffix("MU", new Suffix(() => Body.gravParameter)); + AddSuffix("ROTATIONPERIOD", new Suffix(() => Body.rotationPeriod)); + AddSuffix("ATM", new Suffix(() => new BodyAtmosphere(Body))); + AddSuffix("ANGULARVEL", new Suffix(() => new Direction(Body.angularVelocity, true))); AddSuffix("GEOPOSITIONOF", - new OneArgsSuffix( + new OneArgsSuffix( GeoCoordinatesFromPosition, "Interpret the vector given as a 3D position, and return the geocoordinates directly underneath it on this body.")); AddSuffix("ALTITUDEOF", - new OneArgsSuffix( + new OneArgsSuffix( AltitudeFromPosition, "Interpret the vector given as a 3D position, and return its altitude above 'sea level' of this body.")); } @@ -119,7 +117,7 @@ public GeoCoordinates GeoCoordinatesFromPosition(Vector position) double lng = Body.GetLongitude(unityWorldPosition); return new GeoCoordinates(Body, Shared, lat, lng); } - + /// /// Interpret the vector given as a 3D position, and return the altitude above sea level of this body. /// @@ -130,7 +128,7 @@ public double AltitudeFromPosition(Vector position) Vector3d unityWorldPosition = Shared.Vessel.findWorldCenterOfMass() + position.ToVector3D(); return Body.GetAltitude(unityWorldPosition); } - + public double GetDistance() { return Vector3d.Distance(Shared.Vessel.findWorldCenterOfMass(), Body.position) - Body.Radius; @@ -177,7 +175,7 @@ public override bool Equals(object obj) if (ReferenceEquals(null, obj)) return false; if (ReferenceEquals(this, obj)) return true; if (obj.GetType() != GetType()) return false; - return Equals((BodyTarget) obj); + return Equals((BodyTarget)obj); } public override int GetHashCode() @@ -185,4 +183,4 @@ public override int GetHashCode() return Body.name.GetHashCode(); } } -} +} \ No newline at end of file diff --git a/src/kOS/Suffixed/Orbitable.cs b/src/kOS/Suffixed/Orbitable.cs index fbb5bf2a4..2f8130ef2 100644 --- a/src/kOS/Suffixed/Orbitable.cs +++ b/src/kOS/Suffixed/Orbitable.cs @@ -218,7 +218,7 @@ private void InitializeSuffixes() AddSuffix("SRFPROGRADE", new Suffix(GetSurfacePrograde)); AddSuffix("SRFRETROGRADE", new Suffix(GetSurfaceRetrograde)); AddSuffix("OBT", new Suffix(GetOrbitInfo)); - AddSuffix("POSITION", new Suffix(delegate() + AddSuffix("POSITION", new Suffix(() => { Safe.Utilities.Debug.Logger.Log("Position got Called"); return GetPosition(); diff --git a/src/kOS/UserIO/TelnetMainServer.cs b/src/kOS/UserIO/TelnetMainServer.cs index d5d098e35..a0971ce48 100644 --- a/src/kOS/UserIO/TelnetMainServer.cs +++ b/src/kOS/UserIO/TelnetMainServer.cs @@ -3,14 +3,11 @@ using System.Collections.Generic; using System.Net.Sockets; using KSP.IO; -using kOS.Safe.Utilities; using kOS.Suffixed; -using kOS.Screen; using UnityEngine; namespace kOS.UserIO { - [KSPAddon(KSPAddon.Startup.Instantly, true)] /// /// A single instance of the telnet server embedded into kOS. @@ -23,12 +20,13 @@ namespace kOS.UserIO /// and threading by having multiple instances of itself responding to their own /// Update() calls. /// + [KSPAddon(KSPAddon.Startup.Instantly, true)] public class TelnetMainServer : MonoBehaviour { private TcpListener server = null; private IPAddress bindAddr; private Int32 port; - private List telnets; + private readonly List telnets; private bool isListening; // For status displays for the app control panel to see: @@ -47,8 +45,8 @@ public class TelnetMainServer : MonoBehaviour private Rect optInRect = new Rect( 200, 200, 500, 400); private Rect realIPRect = new Rect( 240, 140, 500, 400); // offset just in case both are up at the same time, to ensure visible bits to click on. They aren't movable. - - private string helpURL = "http://ksp-kos.github.io/KOS_DOC/general/telnet.html"; + + private const string HELP_URL = "http://ksp-kos.github.io/KOS_DOC/general/telnet.html"; public TelnetMainServer() { @@ -82,7 +80,7 @@ private bool GetPermanentListenPermission() } catch (Exception ex) { - UnityEngine.Debug.LogError("kOS: Exception Loading TelnetMainServer.xml (maybe the first time you ran and its not there yet): " + ex.Message); + Debug.LogError("kOS: Exception Loading TelnetMainServer.xml (maybe the first time you ran and its not there yet): " + ex.Message); } return false; } @@ -102,14 +100,13 @@ private void SetPermanentListenPermission(bool newValue) } catch (Exception ex) { - UnityEngine.Debug.LogError("kOS: Exception Loading TelnetMainServer.xml (maybe the first time you ran and its not there yet): " + ex.Message); + Debug.LogError("kOS: Exception Loading TelnetMainServer.xml (maybe the first time you ran and its not there yet): " + ex.Message); } - return; // In principle it should never reach here. } /// /// Return the user's permanent ("don't remind me again") status for the - /// permission to have the telnet server listen to an address other han + /// permission to have the telnet server listen to an address other than /// loopback. (false = please restrict to only loopback.) The permission /// will be stored in the kOS settings file and will be presumed to be set /// to false if the setting is missing from the file (as it will be the first @@ -126,7 +123,7 @@ private bool GetPermanentRealIPPermission() } catch (Exception ex) { - UnityEngine.Debug.LogError("kOS: Exception Loading TelnetMainServer.xml (maybe the first time you ran and its not there yet): " + ex.Message); + Debug.LogError("kOS: Exception Loading TelnetMainServer.xml (maybe the first time you ran and its not there yet): " + ex.Message); } return false; // In principle it should never reach here. } @@ -146,14 +143,13 @@ private void SetPermanentRealIPPermission(bool newValue) } catch (Exception ex) { - UnityEngine.Debug.LogError("kOS: Exception Loading TelnetMainServer.xml (maybe the first time you ran and its not there yet): " + ex.Message); + Debug.LogError("kOS: Exception Loading TelnetMainServer.xml (maybe the first time you ran and its not there yet): " + ex.Message); } - return; // In principle it should never reach here. } public void SetConfigEnable(bool newVal) { - bool isLoopback = (bindAddr == IPAddress.Loopback); + bool isLoopback = Equals(bindAddr, IPAddress.Loopback); bool loopBackStatusChanged = (isLoopback != Config.Instance.TelnetLoopback); if (loopBackStatusChanged) @@ -190,16 +186,13 @@ public void StartListening() // Build the server settings here, not in the constructor, because the settings might have been altered by the user post-init: port = Config.Instance.TelnetPort; - if (Config.Instance.TelnetLoopback) - bindAddr = IPAddress.Loopback; - else - { - bindAddr = GetRealAddress(); - } + bindAddr = Config.Instance.TelnetLoopback ? + IPAddress.Loopback : + GetRealAddress(); server = new TcpListener(bindAddr, port); server.Start(); - kOS.Safe.Utilities.Debug.Logger.Log("kOS TelnetMainServer started listening on " + bindAddr + " " + port); + Safe.Utilities.Debug.Logger.Log(string.Format("kOS TelnetMainServer started listening on {0} {1}", bindAddr, port)); isListening = true; } @@ -210,7 +203,7 @@ public void StopListening() return; isListening = false; - kOS.Safe.Utilities.Debug.Logger.Log("kOS TelnetMainServer stopped listening on " + bindAddr + " " + port); + Safe.Utilities.Debug.Logger.Log(string.Format("kOS TelnetMainServer stopped listening on {0} {1}", bindAddr, port)); server.Stop(); foreach (TelnetSingletonServer telnet in telnets) telnet.StopListening(); @@ -266,7 +259,7 @@ public void Update() TcpClient incomingClient = server.AcceptTcpClient(); string remoteIdent = ((IPEndPoint)(incomingClient.Client.RemoteEndPoint)).Address.ToString(); - kOS.Safe.Utilities.Debug.Logger.Log("kOS telnet server got an incoming connection from " + remoteIdent); + Safe.Utilities.Debug.Logger.Log("kOS telnet server got an incoming connection from " + remoteIdent); TelnetSingletonServer newServer = new TelnetSingletonServer(this, incomingClient, ++howManySpawned); telnets.Add(newServer); @@ -294,28 +287,27 @@ void OnGUI() void OptInOnGui(int id) { - string optInText = - "You are attempting to turn on the telnet server embedded inside kOS.\n" + - " \n" + - "SQUAD has created a rule that all mods for KSP that wish to use network traffic " + - "are required to contain an accurate and informative opt-in question asking for user " + - "permission first. (We at kOS agree with the intent behind this rule.)\n" + - " \n" + - "If you turn on the kOS telnet server, this is what you are agreeing to:\n" + - " \n" + - " kOS will keep a server running within the game that allows a commonly available " + - "external program called a \"telnet client\" to control the kOS terminal screens " + - "exactly as they can be used within the game's GUI.\n" + - " This means the external telnet client program can type the same exact commands " + - "that you type at the terminal, with the same exact effect.\n" + - " \n" + - " If this sounds dangerous, remember that you can force this feature to only " + - "work between programs running on your own computer, never allowing access from " + - "external computers. This is the default way the mod ships, and the setting " + - "can be changed with the LOOPBACK config option.\n" + - " \n" + - "Further information can be found at: \n" + - " " + helpURL + "\n"; + const string OPT_IN_TEXT = "You are attempting to turn on the telnet server embedded inside kOS.\n" + + " \n" + + "SQUAD has created a rule that all mods for KSP that wish to use network traffic " + + "are required to contain an accurate and informative opt-in question asking for user " + + "permission first. (We at kOS agree with the intent behind this rule.)\n" + + " \n" + + "If you turn on the kOS telnet server, this is what you are agreeing to:\n" + + " \n" + + " kOS will keep a server running within the game that allows a commonly available " + + "external program called a \"telnet client\" to control the kOS terminal screens " + + "exactly as they can be used within the game's GUI.\n" + + " This means the external telnet client program can type the same exact commands " + + "that you type at the terminal, with the same exact effect.\n" + + " \n" + + " If this sounds dangerous, remember that you can force this feature to only " + + "work between programs running on your own computer, never allowing access from " + + "external computers. This is the default way the mod ships, and the setting " + + "can be changed with the LOOPBACK config option.\n" + + " \n" + + "Further information can be found at: \n" + + " " + HELP_URL + "\n"; // Note, the unnecessary curly braces below are there to help enforce an indentation that won't be // clobbered by auto-indenter tools. Conceptually it helps show which "begin" matches with "end" @@ -323,7 +315,7 @@ void OptInOnGui(int id) // similar thing because I think it makes everything clearer: GUILayout.BeginVertical(); { - GUILayout.Label(optInText, HighLogic.Skin.textArea); + GUILayout.Label(OPT_IN_TEXT, HighLogic.Skin.textArea); GUILayout.BeginHorizontal(); { // By putting an expandwidth field on either side, it centers the middle part: @@ -369,7 +361,7 @@ void RealIPOnGui(int id) { string realIPText = "You are trying to set the kOS telnet server's IP address to your machine's real IP address " + - "of " + GetRealAddress().ToString() + " rather than the loopback address of 127.0.0.1.\n" + + "of " + GetRealAddress() + " rather than the loopback address of 127.0.0.1.\n" + " \n" + "The use of the loopback address by default is a safety measure to ensure that only telnet clients on " + "your own computer can connect to your KSP game.\n" + @@ -382,16 +374,16 @@ void RealIPOnGui(int id) "If you want better security, and this is a public IP address, then it's recommended that you " + "leave the LOOPBACK setting turned on and instead provide remote access by the use of an SSH tunnel " + "you can control access to. The subject of setting up an SSH tunnel is an advanced but well documented "+ - "network administrator topic for which help can be found with internet searches.\n" + + "network administrator topic for which help can be found with Internet searches.\n" + " \n" + "If you open your KSP game to other telnet clients outside your computer, you are choosing " + - "to accept the security implications and take on the responsibilty for them yourself.\n" + + "to accept the security implications and take on the responsibility for them yourself.\n" + " \n" + "If you are thinking \"What's the harm? It's just letting people mess with my Kerbal Space Program Game?\", " + "then think about the existence of the kOS LOG command, which writes files on your computer's hard drive.\n" + " \n" + "Further information can be found at: \n" + - " " + helpURL + "\n"; + " " + HELP_URL + "\n"; // Note, the unnecessary curly braces below are there to help enforce a begin/end indentation that won't be // clobbered by auto-indenter tools. diff --git a/src/kOS/UserIO/TelnetSingletonServer.cs b/src/kOS/UserIO/TelnetSingletonServer.cs index 6a13abeec..2ab4ec5b6 100644 --- a/src/kOS/UserIO/TelnetSingletonServer.cs +++ b/src/kOS/UserIO/TelnetSingletonServer.cs @@ -1,16 +1,12 @@ using System; -using System.Linq; using System.Collections.Generic; using System.Threading; -using System.Net; using System.Net.Sockets; using System.Text; -using kOS.Safe.Utilities; using kOS.Module; using UnityEngine; -using System.IO; -using System.IO.Pipes; using kOS.Safe.UserIO; +using Object = UnityEngine.Object; namespace kOS.UserIO { @@ -21,6 +17,8 @@ namespace kOS.UserIO /// public class TelnetSingletonServer { + private const double HUNG_CHECK_INTERVAL = 10; // Seconds that a keep alive must have failed to give a response before assuming telnet client is dead. + // ReSharper disable SuggestUseVarKeywordEvident // I want to communicate the difference between cases where the fact that the @@ -30,13 +28,13 @@ public class TelnetSingletonServer private volatile TcpClient client; - private TelnetMainServer whoLaunchedMe; + private readonly TelnetMainServer whoLaunchedMe; /// /// The raw socket stream used to talk directly to the client across the network. /// It is bidirectional - handling both the input from and output to the client. /// - private NetworkStream rawStream; + private readonly NetworkStream rawStream; /// /// The queue that other parts of KOS can use to read characters from the telnet client. @@ -70,7 +68,6 @@ public class TelnetSingletonServer private int MySpawnOrder { get; set; } private bool isLineAtATime; - private bool allowResize; public int ClientWidth {get; private set;} public int ClientHeight {get; private set;} @@ -82,9 +79,8 @@ public class TelnetSingletonServer private readonly object keepAliveAccess = new object(); // because the timestamps can be seen by both in and out threads. - private bool gotSomeRecentTraffic = true; // start off assumig it's alive. + private bool gotSomeRecentTraffic = true; // start off assuming it's alive. private DateTime keepAliveSendTimeStamp; - private double hungCheckInterval = 10; // Seconds that a keepalive must have failed to give a response before assuming telnet client is dead. private bool deadSocket = false; private bool alreadyDisconnecting = false; @@ -92,17 +88,21 @@ public class TelnetSingletonServer public string ClientTerminalType { get{ return termTypeBackingField;} - private set{ termTypeBackingField = value; terminalMapper = TerminalUnicodeMapper.TerminalMapperFactory(value); } + private set + { + termTypeBackingField = value; + terminalMapper = TerminalUnicodeMapper.TerminalMapperFactory(value); + } } - // Special telnet protocol bytes with magic meaning, taken from interet RFC's: + // Special telnet protocol bytes with magic meaning, taken from Internet RFC's: // Many of these will go unused at first, but it's important to get them down for future // embetterment. // // For documentation on how these telnet controls work, and how they're expected - // to be passed back and forth, do an internet search based on the RFC number of the + // to be passed back and forth, do an Internet search based on the RFC number of the // constant (i.e. to see how the byte code RFC854_IAC is used, go look up "RFC 854" on - // the internet and look at what it says about a byte code called "IAC".) + // the Internet and look at what it says about a byte code called "IAC".) private const byte RFC854_SE = 240; // End of subnegotiation parameters. private const byte RFC854_NOP = 241; // No operation. @@ -237,7 +237,10 @@ public string ReadAll() /// /// Determine if the input queue has pending chars to read. If it isn't, then attempts to call ReadOneChar will throw an exception. - /// true if input is currently Queued + /// + /// + /// true if input is currently Queued + /// public bool InputWaiting() { bool returnVal; @@ -292,7 +295,6 @@ public void Write(string str) /// /// Bypasses the Queues and just sends text directly to the socket stream. /// - /// private void SendTextRaw(char[] buff) { SendTextRaw(new string(buff)); @@ -301,20 +303,18 @@ private void SendTextRaw(char[] buff) /// /// Bypasses the Queues and just sends text directly to the socket stream. /// - /// private void SendTextRaw(string str) { - byte[] outBuff = System.Text.Encoding.UTF8.GetBytes(str); + byte[] outBuff = Encoding.UTF8.GetBytes(str); SendTextRaw(outBuff); } /// /// Bypasses the Queues and just sends text directly to the socket stream. /// - /// private void SendTextRaw(byte[] buff) { - bool verboseDebugSend = false; // enable to print a verbose dump of every char going to the client. + const bool VERBOSE_DEBUG_SEND = false; // enable to print a verbose dump of every char going to the client. try { rawStream.Write(buff, 0, buff.Length); @@ -323,12 +323,12 @@ private void SendTextRaw(byte[] buff) { // If the client closed its side just before we were about to write something out, the above write can fail and // cause an exception that would have killed the DoOutThread() before it had a chance to do its cleanup. - if (e is System.IO.IOException || e is System.ObjectDisposedException) + if (e is System.IO.IOException || e is ObjectDisposedException) deadSocket = true; else throw; // Not one of the expected thread-closed IO exceptions, so don't hide it - let it get reported. } - if (verboseDebugSend) + if (VERBOSE_DEBUG_SEND) { StringBuilder logMessage = new StringBuilder(); logMessage.Append("kOS Telnet server: Just wrote the following buffer chunk out to the client:"); @@ -390,15 +390,15 @@ public void LineAtATime(bool modeOn) isLineAtATime = modeOn; if (modeOn) { - SendTextRaw( new byte[] {RFC854_IAC, RFC854_WONT, RFC857_ECHO}); // we will not be echoing the client input back to it. - SendTextRaw( new byte[] {RFC854_IAC, RFC854_DO, RFC857_ECHO}); // so the client should do its own local echoing. - SendTextRaw( new byte[] {RFC854_IAC, RFC854_WONT, RFC858_SUPPRESS_GOAHEAD}); // don't send one char at a time, buffer the lines. + SendTextRaw( new[] {RFC854_IAC, RFC854_WONT, RFC857_ECHO}); // we will not be echoing the client input back to it. + SendTextRaw( new[] {RFC854_IAC, RFC854_DO, RFC857_ECHO}); // so the client should do its own local echoing. + SendTextRaw( new[] {RFC854_IAC, RFC854_WONT, RFC858_SUPPRESS_GOAHEAD}); // don't send one char at a time, buffer the lines. } else { - SendTextRaw( new byte[] {RFC854_IAC, RFC854_WILL, RFC857_ECHO}); // we will echo the client's input back to it. - SendTextRaw( new byte[] {RFC854_IAC, RFC854_DONT, RFC857_ECHO}); // so the client shouldn't be doing a local echo (or the user would see text twice). - SendTextRaw( new byte[] {RFC854_IAC, RFC854_WILL, RFC858_SUPPRESS_GOAHEAD}); // do send one char at a time without buffering lines. + SendTextRaw( new[] {RFC854_IAC, RFC854_WILL, RFC857_ECHO}); // we will echo the client's input back to it. + SendTextRaw( new[] {RFC854_IAC, RFC854_DONT, RFC857_ECHO}); // so the client shouldn't be doing a local echo (or the user would see text twice). + SendTextRaw( new[] {RFC854_IAC, RFC854_WILL, RFC858_SUPPRESS_GOAHEAD}); // do send one char at a time without buffering lines. } } @@ -409,25 +409,24 @@ public void LineAtATime(bool modeOn) /// true = client should send resize messages whenever it feels like. false = it should not send us resize messages. public void AllowTerminalResize(bool modeOn) { - allowResize = modeOn; - if (modeOn) - SendTextRaw( new byte[] {RFC854_IAC, RFC854_DO, RFC1073_NAWS}); // do allow Negotiate About Window Size - else - SendTextRaw( new byte[] {RFC854_IAC, RFC854_DONT, RFC1073_NAWS}); // dont allow Negotiate About Window Size + SendTextRaw(modeOn + ? new[] { RFC854_IAC, RFC854_DO, RFC1073_NAWS } // do allow Negotiate About Window Size + : new[] { RFC854_IAC, RFC854_DONT, RFC1073_NAWS } // don't allow Negotiate About Window Size + ); } - + /// /// Tell the telnet client that we'd like it to send us ID strings when queried about its terminal model. /// /// true = client should send terminal ident information. public void AllowTerminalTypeInfo(bool modeOn) { - if (modeOn) - SendTextRaw( new byte[] {RFC854_IAC, RFC854_DO, RFC1091_TERMTYPE}); // do request terminal type info negotiations from client - else - SendTextRaw( new byte[] {RFC854_IAC, RFC854_DONT, RFC1091_TERMTYPE}); // dont request terminal type info from client + SendTextRaw(modeOn + ? new[] { RFC854_IAC, RFC854_DO, RFC1091_TERMTYPE } // do request terminal type info negotiations from client + : new[] { RFC854_IAC, RFC854_DONT, RFC1091_TERMTYPE } // don't request terminal type info from client + ); } - + /// /// Detect if the client is stuck, using some dummy sends. /// The low level TCP keepalive would be another way to do this, but .NET did a little bit TOO much abstraction @@ -451,7 +450,7 @@ private bool IsHung() // we'll use the terminal type request as a make-do version of a keepalive. It should force the // telnet client to send some sort of bytes back to us as it answers the terminal type request: TelnetAskForTerminalType(); - keepAliveSendTimeStamp = DateTime.Now + System.TimeSpan.FromSeconds(hungCheckInterval); + keepAliveSendTimeStamp = DateTime.Now + TimeSpan.FromSeconds(HUNG_CHECK_INTERVAL); // This will get set to true when we receive any bytes at all from the client, // whether they're the answer to our query, or something else like user typing. @@ -481,7 +480,7 @@ private void DoInThread() // This is blocking, so the rawStream.DataAvailable check is vital to prevent hang: rawStream.Read(rawReadBuffer, 0, rawReadBuffer.Length); // But still remember the traffic counts as keepalive proof, even if we ignore it: - keepAliveSendTimeStamp = DateTime.Now + System.TimeSpan.FromSeconds(hungCheckInterval); + keepAliveSendTimeStamp = DateTime.Now + TimeSpan.FromSeconds(HUNG_CHECK_INTERVAL); } flushPendingInput = false; } @@ -492,7 +491,7 @@ private void DoInThread() // As long as some input came recently, no matter what it is, we don't need to bother sending the keepalive: lock (keepAliveAccess) gotSomeRecentTraffic = true; - keepAliveSendTimeStamp = DateTime.Now + System.TimeSpan.FromSeconds(hungCheckInterval); + keepAliveSendTimeStamp = DateTime.Now + TimeSpan.FromSeconds(HUNG_CHECK_INTERVAL); // Process the input bytes that arrived: char[] scrapedBytes = Encoding.UTF8.GetChars(TelnetProtocolScrape(rawReadBuffer, numRead)); @@ -530,9 +529,9 @@ private void DoOutThread() // running fast without sleep again. // Tweakable settings: - int sleepTimeInc = 20; - int sleepTimeMax = 200; // Don't let this get too slow, because ContinuousChecks() needs to run. - int sleepTime = sleepTimeMax; // At first - will speed up once there's something in the queue. + const int SLEEP_TIME_INC = 20; + const int SLEEP_TIME_MAX = 200; // Don't let this get too slow, because ContinuousChecks() needs to run. + int sleepTime = SLEEP_TIME_MAX; // At first - will speed up once there's something in the queue. while (true) { @@ -562,8 +561,8 @@ private void DoOutThread() else { Thread.Sleep(sleepTime); - if (sleepTime < sleepTimeMax) - sleepTime += sleepTimeInc; + if (sleepTime < SLEEP_TIME_MAX) + sleepTime += SLEEP_TIME_INC; } } } @@ -602,7 +601,7 @@ private void ContinuousChecks() private void SpawnWelcomeMenu() { var gObj = new GameObject( "TelnetWelcomeMenu_" + MySpawnOrder, typeof(TelnetWelcomeMenu) ); - MonoBehaviour.DontDestroyOnLoad(gObj); + Object.DontDestroyOnLoad(gObj); welcomeMenu = (TelnetWelcomeMenu)gObj.GetComponent(typeof(TelnetWelcomeMenu)); welcomeMenu.Setup(this); } @@ -613,7 +612,7 @@ private void SpawnWelcomeMenu() /// private void TelnetAskForTerminalType() { - SendTextRaw(new byte[] {RFC854_IAC, RFC854_SB, RFC1091_TERMTYPE, RFC1091_SEND, RFC854_IAC, RFC854_SE}); + SendTextRaw(new[] {RFC854_IAC, RFC854_SB, RFC1091_TERMTYPE, RFC1091_SEND, RFC854_IAC, RFC854_SE}); } /// @@ -654,6 +653,9 @@ private byte[] TelnetProtocolScrape(byte[] inRawBuff, int rawLength) case RFC854_WILL: rawIndex += TelnetConsumeWill(inRawBuff, rawIndex); break; + case RFC854_WONT: + rawIndex += TelnetConsumeWont(inRawBuff, rawIndex); + break; case RFC854_IAC: break; // pass through to normal behaviour when two IAC's are back to back - that's how a real IAC char is encoded. case RFC854_BREAK: @@ -706,22 +708,20 @@ private int TelnetConsumeDo( byte[] remainingBuff, int index) // If other side orders me to go char-at-a-time, agree or disagree depending on setting: // TODO: maybe some day alter this to obey the other side's wishes. case RFC857_ECHO: - if (isLineAtATime) - SendTextRaw(new byte[] {RFC854_IAC, RFC854_WONT, RFC857_ECHO}); - else - SendTextRaw(new byte[] {RFC854_IAC, RFC854_WILL, RFC857_ECHO}); + SendTextRaw(isLineAtATime + ? new[] {RFC854_IAC, RFC854_WONT, RFC857_ECHO} + : new[] {RFC854_IAC, RFC854_WILL, RFC857_ECHO}); break; // If other side orders me to go char-at-a-time, agree or disagree depending on setting: // TODO: maybe some day alter this to obey the other side's wishes. case RFC858_SUPPRESS_GOAHEAD: - if (isLineAtATime) - SendTextRaw(new byte[] {RFC854_IAC, RFC854_WONT, RFC858_SUPPRESS_GOAHEAD}); - else - SendTextRaw(new byte[] {RFC854_IAC, RFC854_WILL, RFC858_SUPPRESS_GOAHEAD}); + SendTextRaw(isLineAtATime + ? new[] {RFC854_IAC, RFC854_WONT, RFC858_SUPPRESS_GOAHEAD} + : new[] {RFC854_IAC, RFC854_WILL, RFC858_SUPPRESS_GOAHEAD}); break; // if other side orders me to allow resizes, agree: case RFC1073_NAWS: - SendTextRaw(new byte[] {RFC854_IAC, RFC854_WILL, RFC1073_NAWS}); + SendTextRaw(new[] {RFC854_IAC, RFC854_WILL, RFC1073_NAWS}); break; // if other side orders me to accept terminal ident strings, agree, and send it back the signal that it // should tell me its ident right away. @@ -737,7 +737,7 @@ private int TelnetConsumeDo( byte[] remainingBuff, int index) StringBuilder sb = new StringBuilder(); sb.Append("{"+RFC854_DO+"}"); sb.Append("{"+option+"}"); - kOS.Safe.Utilities.Debug.Logger.SuperVerbose( "kOS: telnet protocol DO message from client: " + sb.ToString()); + Safe.Utilities.Debug.Logger.SuperVerbose( "kOS: telnet protocol DO message from client: " + sb); return offset; } @@ -765,18 +765,16 @@ private int TelnetConsumeDont( byte[] remainingBuff, int index) // If other side orders me to go char-at-a-time, agree or disagree depending on my setting: // TODO: maybe some day alter this to obey the other side's wishes. case RFC857_ECHO: - if (isLineAtATime) - SendTextRaw(new byte[] {RFC854_IAC, RFC854_WONT, RFC857_ECHO}); - else - SendTextRaw(new byte[] {RFC854_IAC, RFC854_WILL, RFC857_ECHO}); + SendTextRaw(isLineAtATime + ? new[] {RFC854_IAC, RFC854_WONT, RFC857_ECHO} + : new[] {RFC854_IAC, RFC854_WILL, RFC857_ECHO}); break; // If other side orders me to go char-at-a-time, agree or disagree depending on my setting: // TODO: maybe some day alter this to obey the other side's wishes. case RFC858_SUPPRESS_GOAHEAD: - if (isLineAtATime) - SendTextRaw(new byte[] {RFC854_IAC, RFC854_WONT, RFC858_SUPPRESS_GOAHEAD}); - else - SendTextRaw(new byte[] {RFC854_IAC, RFC854_WILL, RFC858_SUPPRESS_GOAHEAD}); + SendTextRaw(isLineAtATime + ? new[] {RFC854_IAC, RFC854_WONT, RFC858_SUPPRESS_GOAHEAD} + : new[] {RFC854_IAC, RFC854_WILL, RFC858_SUPPRESS_GOAHEAD}); break; default: offset += TelnetConsumeOther(RFC854_DONT, remainingBuff, offset); @@ -787,7 +785,7 @@ private int TelnetConsumeDont( byte[] remainingBuff, int index) StringBuilder sb = new StringBuilder(); sb.Append("{"+RFC854_DO+"}"); sb.Append("{"+option+"}"); - kOS.Safe.Utilities.Debug.Logger.SuperVerbose( "kOS: telnet protocol DO message from client: " + sb.ToString()); + Safe.Utilities.Debug.Logger.SuperVerbose( "kOS: telnet protocol DO message from client: " + sb); return offset; } @@ -825,7 +823,7 @@ private int TelnetConsumeWont( byte[] remainingBuff, int index) StringBuilder sb = new StringBuilder(); sb.Append("{"+RFC854_DO+"}"); sb.Append("{"+option+"}"); - kOS.Safe.Utilities.Debug.Logger.SuperVerbose( "kOS: telnet protocol WILL message from client: " + sb.ToString()); + Safe.Utilities.Debug.Logger.SuperVerbose( "kOS: telnet protocol WILL message from client: " + sb); return offset; } @@ -855,7 +853,7 @@ private int TelnetConsumeWill( byte[] remainingBuff, int index) StringBuilder sb = new StringBuilder(); sb.Append("{"+RFC854_DO+"}"); sb.Append("{"+option+"}"); - kOS.Safe.Utilities.Debug.Logger.SuperVerbose( "kOS: telnet protocol WILL message from client: " + sb.ToString()); + Safe.Utilities.Debug.Logger.SuperVerbose( "kOS: telnet protocol WILL message from client: " + sb); return offset; } @@ -885,7 +883,7 @@ private int TelnetConsumeOther( byte commandByte, byte[] remainingBuff, int inde offset += TelnetConsumeNAWS(remainingBuff, index+offset, out handled); break; case RFC1091_TERMTYPE: - offset += TelnetConsumeTERMTYPE(remainingBuff, index+offset, out handled); + offset += TelnetConsumeTermtype(remainingBuff, index+offset, out handled); break; default: break; @@ -900,7 +898,7 @@ private int TelnetConsumeOther( byte commandByte, byte[] remainingBuff, int inde sb.Append("{"+commandByte+"}"); for( int i = index; i < index+offset ; ++i ) sb.Append("{"+remainingBuff[i]+"}"); - kOS.Safe.Utilities.Debug.Logger.SuperVerbose( "kOS: telnet protocol submessage from client: " + sb.ToString()); + Safe.Utilities.Debug.Logger.SuperVerbose( "kOS: telnet protocol submessage from client: " + sb); } break; @@ -910,7 +908,7 @@ private int TelnetConsumeOther( byte commandByte, byte[] remainingBuff, int inde // Everything below here is to help debug: sb.Append("{"+commandByte+"}"); sb.Append("{"+remainingBuff[index+offset]+"}"); - kOS.Safe.Utilities.Debug.Logger.SuperVerbose( "kOS: telnet protocol command from client: " + sb.ToString()); + Safe.Utilities.Debug.Logger.SuperVerbose( "kOS: telnet protocol command from client: " + sb); break; } @@ -921,7 +919,7 @@ private int TelnetConsumeOther( byte commandByte, byte[] remainingBuff, int inde /// Consume the Negotiate About Window Size (RFC 1073) sub-message, i.e if the client wants to /// tell us the window size is now 350 cells wide by 40 tall, it will send us this /// sequence of bytes: - ///
    IAC NAWS 1 94 0 40 IAC SE
    + ///
    IAC NAWS 1 94 0 40 IAC SE
    /// (1 94 is the encoding of 350 in two bytes, as in 256 + 94. The protocol sends /// 16-bit numbers, allowing a very large max terminal size. ///
    @@ -936,14 +934,14 @@ private int TelnetConsumeNAWS(byte[] remainingBuff, int index, out bool handled) byte code = remainingBuff[index + (offset++)]; if (code != RFC1073_NAWS) { - kOS.Safe.Utilities.Debug.Logger.Log("kOS: Bug in telnet server - expected NAWS byte {" + RFC1073_NAWS + "} (RFC1073) but instead got {" + (int)code + "}."); + Safe.Utilities.Debug.Logger.Log(string.Format("kOS: Bug in telnet server - expected NAWS byte {{{0}}} (RFC1073) but instead got {{{1}}}.", RFC1073_NAWS, (int)code)); handled = false; return offset; } if (remainingBuff.Length < (index + offset + 3)) { - kOS.Safe.Utilities.Debug.Logger.Log("kOS: Telnet client is trying to send me a window resize (RFC1073) command without actual width/height fields. WTF?"); + Safe.Utilities.Debug.Logger.Log("kOS: Telnet client is trying to send me a window resize (RFC1073) command without actual width/height fields. WTF?"); handled = false; return offset; } @@ -957,10 +955,10 @@ private int TelnetConsumeNAWS(byte[] remainingBuff, int index, out bool handled) byte heightLowByte = remainingBuff[index + (offset++)]; if (heightLowByte == RFC854_IAC) ++offset; // special case - to send this byte value, telnet clients have to encode it by sending it twice consecutively. - int width = (((int)widthHighByte)<<8) + widthLowByte; - int height = (((int)heightHighByte)<<8) + heightLowByte; + int width = (widthHighByte<<8) + widthLowByte; + int height = (heightHighByte<<8) + heightLowByte; - kOS.Safe.Utilities.Debug.Logger.SuperVerbose( "kOS: Telnet client just told me its window size is " + width + "x" + height+"."); + Safe.Utilities.Debug.Logger.SuperVerbose( "kOS: Telnet client just told me its window size is " + width + "x" + height+"."); // Only *actually* set the width and height if the values are nonzero. The telnet protocol allows the // client to send one or the other as zero, which does not really mean zero but rather "ignore this field". @@ -998,13 +996,12 @@ private int TelnetConsumeNAWS(byte[] remainingBuff, int index, out bool handled) /// /// Consume the Terminal Type submessage (RFC1091) where the telnet client is telling us the model ident /// of its terminal type (i.e. "VT100" for example) - ///
    /// the buffer to be parsed /// how far into the buffer to start from (where the commandByte was) /// is true if it was handled properly (else it should get logged as a problem) /// how many bytes of the buffer should get skipped over because I dealt with them. - private int TelnetConsumeTERMTYPE(byte[] remainingBuff, int index, out bool handled) + private int TelnetConsumeTermtype(byte[] remainingBuff, int index, out bool handled) { int offset = 0; @@ -1012,7 +1009,7 @@ private int TelnetConsumeTERMTYPE(byte[] remainingBuff, int index, out bool hand byte code = remainingBuff[index + (offset++)]; if (code != RFC1091_TERMTYPE) { - kOS.Safe.Utilities.Debug.Logger.Log("kOS: Bug in telnet server - expected TERMTYPE byte {" + RFC1091_TERMTYPE + "} (RFC10791) but instead got {" + (int)code + "}."); + Safe.Utilities.Debug.Logger.Log("kOS: Bug in telnet server - expected TERMTYPE byte {" + RFC1091_TERMTYPE + "} (RFC10791) but instead got {" + (int)code + "}."); handled = false; return offset; } @@ -1021,15 +1018,15 @@ private int TelnetConsumeTERMTYPE(byte[] remainingBuff, int index, out bool hand code = remainingBuff[index + (offset++)]; if (code != RFC1091_IS) { - kOS.Safe.Utilities.Debug.Logger.Log("kOS: Bug in telnet server - expected [IS] byte {" + RFC1091_IS + "} (RFC10791) but instead got {" + (int)code + "}."); + Safe.Utilities.Debug.Logger.Log("kOS: Bug in telnet server - expected [IS] byte {" + RFC1091_IS + "} (RFC10791) but instead got {" + (int)code + "}."); handled = false; return offset; } // Consume everything until the pattern IAC SE is found, which marks the end of the ident string: StringBuilder sb = new StringBuilder(); - byte last = (byte)0; - byte penultimate = (byte)0; + byte last = 0; + byte penultimate = 0; while ( (index + offset) <= remainingBuff.Length && !(penultimate == RFC854_IAC && last == RFC854_SE) ) { sb.Append(Encoding.UTF8.GetString(remainingBuff, index + offset, 1)); @@ -1049,12 +1046,12 @@ private int TelnetConsumeTERMTYPE(byte[] remainingBuff, int index, out bool hand ClientTerminalType = newTermType; } - kOS.Safe.Utilities.Debug.Logger.SuperVerbose("kOS: Telnet client just told us its terminal type is: \""+ClientTerminalType+"\"."); + Safe.Utilities.Debug.Logger.SuperVerbose(string.Format("kOS: Telnet client just told us its terminal type is: \"{0}\".", ClientTerminalType)); handled = true; } else { - kOS.Safe.Utilities.Debug.Logger.Log("kOS: Telnet client sent us a garbled attempt at a terminal type ident string."); + Safe.Utilities.Debug.Logger.Log("kOS: Telnet client sent us a garbled attempt at a terminal type ident string."); handled = false; } // remove the final two delimiter bytes: diff --git a/src/kOS/UserIO/TelnetWelcomeMenu.cs b/src/kOS/UserIO/TelnetWelcomeMenu.cs index 8e68f4650..43e669983 100644 --- a/src/kOS/UserIO/TelnetWelcomeMenu.cs +++ b/src/kOS/UserIO/TelnetWelcomeMenu.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.IO; using System.Text; using System.Linq; using UnityEngine; @@ -21,7 +20,7 @@ public class TelnetWelcomeMenu : MonoBehaviour private TelnetSingletonServer telnetServer; private List availableCPUs; private DateTime lastMenuQueryTime; - private StringBuilder localMenuBuffer; + private readonly StringBuilder localMenuBuffer; private bool firstTime; private volatile bool forceMenuReprint; @@ -37,7 +36,7 @@ public TelnetWelcomeMenu() public void Setup(TelnetSingletonServer tServer) { telnetServer = tServer; - lastMenuQueryTime = System.DateTime.MinValue; // Force a stale timestamp the first time. + lastMenuQueryTime = DateTime.MinValue; // Force a stale timestamp the first time. telnetServer.Write( (char)UnicodeCommand.TITLEBEGIN + "kOS Terminal Server Welcome Menu" + (char)UnicodeCommand.TITLEEND ); forceMenuReprint = true; // force it to print the menu once the first time regardless of the state of the CPU list. } @@ -74,7 +73,7 @@ public virtual void Update() // Regularly check to see if the CPU list has changed while the user was sitting // on the menu. If so, reprint it: // Querying the list of CPU's can be a little expensive, so don't do it too often: - if (System.DateTime.Now > lastMenuQueryTime + TimeSpan.FromMilliseconds(1000)) + if (DateTime.Now > lastMenuQueryTime + TimeSpan.FromMilliseconds(1000)) { if (forceMenuReprint) telnetServer.Write((char)UnicodeCommand.CLEARSCREEN); // if we HAVE to reprint - do so on a clear screen. @@ -114,7 +113,7 @@ public void LineEntered() if (localMenuBuffer.Length == 0) return; string cmd = localMenuBuffer.ToString(); - kOS.Safe.Utilities.Debug.Logger.SuperVerbose( "TelnetWelcomeMenu.LineEntered(): String from client was: [" + cmd.ToString() + "]"); + Safe.Utilities.Debug.Logger.SuperVerbose( "TelnetWelcomeMenu.LineEntered(): String from client was: [" + cmd + "]"); localMenuBuffer.Remove(0,localMenuBuffer.Length); // clear the buffer for next line. if (String.Equals(cmd.Substring(0,1),"Q",StringComparison.CurrentCultureIgnoreCase)) @@ -151,9 +150,9 @@ private bool CPUListChanged() if (newList[i] != availableCPUs[i]) itChanged = true; - Console.WriteLine("in CPUListChanged(): itChanged = "+itChanged+", newList.Count="+newList.Count+", availableCPUs.Count="+availableCPUs.Count); + Console.WriteLine("in CPUListChanged(): itChanged = {0}, newList.Count={1}, availableCPUs.Count={2}", itChanged, newList.Count, availableCPUs.Count); availableCPUs = newList; - lastMenuQueryTime = System.DateTime.Now; + lastMenuQueryTime = DateTime.Now; return itChanged; } @@ -171,14 +170,16 @@ private void PrintCPUMenu() (char)UnicodeCommand.STARTNEXTLINE); telnetServer.Write(CenterPadded("",'_')/*line of '-' chars*/ + (char)UnicodeCommand.STARTNEXTLINE); - string formatter = "{0,4} {1,4} {2,4} {3} {4} {5}"; + const string FORMATTER = "{0,4} {1,4} {2,4} {3} {4} {5}"; int userPickNum = 1; int longestLength = 0; - List displayChoices = new List(); - displayChoices.Add( String.Format(formatter,"Menu", "GUI ", " Other ", "", "", "")); - displayChoices.Add( String.Format(formatter,"Pick", "Open", "Telnets", "", "Vessel Name", "(CPU tagname)")); - displayChoices.Add( String.Format(formatter,"----", "----", "-------", "", "--------------------------------", "")); + List displayChoices = new List + { + String.Format(FORMATTER, "Menu", "GUI ", " Other ", "", "", ""), + String.Format(FORMATTER, "Pick", "Open", "Telnets", "", "Vessel Name", "(CPU tagname)"), + String.Format(FORMATTER, "----", "----", "-------", "", "--------------------------------", "") + }; longestLength = displayChoices[2].Length; foreach (kOSProcessor kModule in availableCPUs) { @@ -191,9 +192,9 @@ private void PrintCPUMenu() Vessel vessel = (thisPart == null) ? null/*can this even happen?*/ : thisPart.vessel; string vesselLabel = (vessel == null) ? ""/*can this even happen?*/ : vessel.GetName(); - bool guiOpen = kModule.GetWindow().IsOpen(); + bool guiOpen = kModule.GetWindow().IsOpen; int numTelnets = kModule.GetWindow().NumTelnets(); - string choice = String.Format(formatter, "["+userPickNum+"]", (guiOpen ? "yes": "no"), numTelnets, " ", vesselLabel, "("+partLabel+")"); + string choice = String.Format(FORMATTER, "["+userPickNum+"]", (guiOpen ? "yes": "no"), numTelnets, " ", vesselLabel, "("+partLabel+")"); displayChoices.Add(choice); longestLength = Math.Max(choice.Length, longestLength); ++userPickNum; @@ -219,7 +220,7 @@ private void PrintCPUMenu() (char)UnicodeCommand.STARTNEXTLINE + "> "); else - telnetServer.Write(CenterPadded(String.Format(formatter,"", "", "", "", "", ""), ' ') + (char)UnicodeCommand.STARTNEXTLINE); + telnetServer.Write(CenterPadded(String.Format(FORMATTER,"", "", "", "", "", ""), ' ') + (char)UnicodeCommand.STARTNEXTLINE); } diff --git a/src/kOS/UserIO/TerminalAnsiMapper.cs b/src/kOS/UserIO/TerminalAnsiMapper.cs index 9b8fc388e..7554b136b 100644 --- a/src/kOS/UserIO/TerminalAnsiMapper.cs +++ b/src/kOS/UserIO/TerminalAnsiMapper.cs @@ -1,7 +1,4 @@ -using System; -using System.Text; - -namespace kOS.UserIO +namespace kOS.UserIO { /// /// Subclass of TerminalUnicodeMapper designed to handle the specifics of diff --git a/src/kOS/UserIO/TerminalUnicodeMapper.cs b/src/kOS/UserIO/TerminalUnicodeMapper.cs index 5adb51888..be97170fe 100644 --- a/src/kOS/UserIO/TerminalUnicodeMapper.cs +++ b/src/kOS/UserIO/TerminalUnicodeMapper.cs @@ -8,11 +8,11 @@ namespace kOS.UserIO /// /// A base class for terminal-specific mappings like vt100, xterm, etc. ///
    - /// It encodes common terminal control codes in unicode, using some of the - /// unicode characters that we'll never use, as pretend terminal escape codes. + /// It encodes common terminal control codes in Unicode, using some of the + /// Unicode characters that we'll never use, as pretend terminal escape codes. ///
    - /// Subclasses of this need to implement a way to convert those unicode control - /// codes into a stream of ascii chars, and visa versa, that do things using the + /// Subclasses of this need to implement a way to convert those Unicode control + /// codes into a stream of ASCII chars, and visa versa, that do things using the /// terminal control codes for the specific model of terminal in question. ///
    public class TerminalUnicodeMapper @@ -38,7 +38,7 @@ public class TerminalUnicodeMapper ///
    protected bool AllowNativeUnicodeCommands {get; set;} - protected readonly object lockAccess = new object(); // to ensure that multiple threads use the mapper atomicly, to avoid messing up it's state variables. + protected readonly object LockAccess = new object(); // to ensure that multiple threads use the mapper atomicly, to avoid messing up it's state variables. // Note that it's essential that these remain private and not get changed to protected or public. // Some of the derived classes of this class also use the same identifier name for their own @@ -60,20 +60,21 @@ public static TerminalType GuessTypeId(string typeString) { if (typeString.Substring(0,5).Equals("xterm", StringComparison.CurrentCultureIgnoreCase)) return TerminalType.XTERM; - else if (typeString.Substring(0,4).Equals("vt100", StringComparison.CurrentCultureIgnoreCase)) + if (typeString.Substring(0,4).Equals("vt100", StringComparison.CurrentCultureIgnoreCase)) return TerminalType.XTERM; - // - // The following condition isn't implemented yet: - // - // else if (typeString.Substring(0,4).Equals("ansi", StringComparison.CurrentCultureIgnoreCase)) - // return TerminalType.XTERM; + + // + // The following condition isn't implemented yet: + // + // else if (typeString.Substring(0,4).Equals("ansi", StringComparison.CurrentCultureIgnoreCase)) + // return TerminalType.XTERM; - // Add more cases here if more subclasses of this class are created later. + // Add more cases here if more subclasses of this class are created later. else return TerminalType.UNKNOWN; } - + /// /// Construct an object of this type, or one of its derived subtypes, depending on /// the terminal type string passed in. @@ -95,7 +96,7 @@ public static TerminalUnicodeMapper TerminalMapperFactory(string typeString) } /// - /// Map the unicode chars (and the fake control codes we made) into what the terminal + /// Map the Unicode chars (and the fake control codes we made) into what the terminal /// wants to see. /// In this base class, all it does is just mostly passthru things as-is with no /// conversions. @@ -103,32 +104,32 @@ public static TerminalUnicodeMapper TerminalMapperFactory(string typeString) /// to this base class inmplementation at the bottom, to allow chains of /// subclasses to all operate on the data. /// - /// unicode char + /// Unicode char /// raw byte stream to send to the terminal public virtual char[] OutputConvert(string str) { StringBuilder sb = new StringBuilder(); - for (int index = 0 ; index < str.Length ; ++index) + foreach (char t in str) { switch (outputExpected) { case ExpectNextChar.RESIZEWIDTH: - pendingWidth = (int)(str[index]); + pendingWidth = t; outputExpected = ExpectNextChar.RESIZEHEIGHT; break; case ExpectNextChar.RESIZEHEIGHT: - int height = (int)(str[index]); + int height = t; sb.Append("{Please resize to " + pendingWidth + "x" + height + "}"); // By default, assume the terminal has no such control code, but this can be overridden. outputExpected = ExpectNextChar.NORMAL; break; case ExpectNextChar.INTITLE: // Default behavior: Ignore all content until the title ender. Assume most terminals don't know how to do this. - if (str[index] == (char)UnicodeCommand.TITLEEND) + if (t == (char)UnicodeCommand.TITLEEND) outputExpected = ExpectNextChar.NORMAL; break; default: - switch (str[index]) + switch (t) { case (char)UnicodeCommand.RESIZESCREEN: outputExpected = ExpectNextChar.RESIZEWIDTH; @@ -146,7 +147,7 @@ public virtual char[] OutputConvert(string str) sb.Append("\r"); break; default: - sb.Append(str[index]); // default passhtrough + sb.Append(t); // default passhtrough break; } break; @@ -162,14 +163,14 @@ public virtual char[] OutputConvert(string str) /// /// Map the bytes containing the terminal's own control codes into our - /// unicode system with its fake control codes. In this base class, all it + /// Unicode system with its fake control codes. In this base class, all it /// does it just mostly passthru things as-is with no conversion. /// Subclasses of this should perform their own manipulations, then fallthrough /// to this base class implementation at the bottom, to allow chains of /// subclasses to all operate on the data. /// /// chars in the terminal's way of thinking - /// chars in our unicode way of thinking + /// chars in our Unicode way of thinking public virtual string InputConvert(char[] inChars) { List outChars = new List(); @@ -183,7 +184,7 @@ public virtual string InputConvert(char[] inChars) case (char)0x08: // control-H, the ASCII backspace outChars.Add((char)UnicodeCommand.DELETELEFT); break; - case (char)0x7f: // ascii 127 = the delete character + case (char)0x7f: // ASCII 127 = the delete character outChars.Add((char)UnicodeCommand.DELETERIGHT); break; case '\r': diff --git a/src/kOS/UserIO/TerminalVT100Mapper.cs b/src/kOS/UserIO/TerminalVT100Mapper.cs index 0d3253c19..718b44b1f 100644 --- a/src/kOS/UserIO/TerminalVT100Mapper.cs +++ b/src/kOS/UserIO/TerminalVT100Mapper.cs @@ -1,7 +1,6 @@ -using System; +using kOS.Safe.UserIO; using System.Collections.Generic; using System.Text; -using kOS.Safe.UserIO; namespace kOS.UserIO { @@ -11,80 +10,108 @@ namespace kOS.UserIO /// public class TerminalVT100Mapper : TerminalUnicodeMapper { - public TerminalVT100Mapper(string typeString) : base(typeString) + protected const char ESCAPE_CHARACTER = (char)0x1b; + protected const char BELL_CHAR = (char)0x07; + protected const char DELETE_CHARACTER = (char)0x7f; + private readonly string csi = string.Format("{0}{1}", ESCAPE_CHARACTER, '['); + + + public TerminalVT100Mapper(string typeString) + : base(typeString) { TerminalTypeID = TerminalType.XTERM; AllowNativeUnicodeCommands = false; } - + private ExpectNextChar outputExpected = ExpectNextChar.NORMAL; private int pendingCol; - + + /// + /// ESC followed by '[' is called the CSI (Control Sequence Initiator) and it's how most VT100 codes start. + /// + protected string CSI + { + get { return csi; } + } + /// - /// Map the unicode chars (and the fake control codes we made) on output to what the terminal + /// Map the Unicode chars (and the fake control codes we made) on output to what the terminal /// wants to see. - /// Subclasses of this should perform their own manipulations, then fallthrough - /// to this base class inmplementation at the bottom, to allow chains of + /// Subclasses of this should perform their own manipulations, then fall-through + /// to this base class implementation at the bottom, to allow chains of /// subclasses to all operate on the data. /// - /// unicode char + /// Unicode char /// raw byte stream to send to the terminal public override char[] OutputConvert(string str) { StringBuilder sb = new StringBuilder(); - for (int index = 0 ; index < str.Length ; ++index) + foreach (char t in str) { switch (outputExpected) { case ExpectNextChar.TELEPORTCURSORCOL: - pendingCol = (int)(str[index]); + pendingCol = t; outputExpected = ExpectNextChar.TELEPORTCURSORROW; break; + case ExpectNextChar.TELEPORTCURSORROW: - int row = (int)(str[index]); + int row = t; // VT100 counts rows and cols starting at 1, not 0, thus the +1's below: - sb.Append(((char)0x1b)/*ESC*/ + "[" + (row+1) + ";" + (pendingCol+1) + "H"); + sb.AppendFormat("{0}{1};{2}H", csi, (row + 1), (pendingCol + 1)); outputExpected = ExpectNextChar.NORMAL; break; + default: - switch (str[index]) + switch (t) { case (char)UnicodeCommand.TELEPORTCURSOR: outputExpected = ExpectNextChar.TELEPORTCURSORCOL; break; + case (char)UnicodeCommand.CLEARSCREEN: - sb.Append((char)0x1b/*ESC*/ + "[2J" + (char)0x1b/*ESC*/ + "[H"); + sb.AppendFormat("{0}2J{0}H", csi); break; + case (char)UnicodeCommand.SCROLLSCREENUPONE: - sb.Append((char)0x1b/*ESC*/ + "[S"); + sb.AppendFormat("{0}S", csi); break; + case (char)UnicodeCommand.SCROLLSCREENDOWNONE: - sb.Append((char)0x1b/*ESC*/ + "[T"); + sb.AppendFormat("{0}T", csi); break; + case (char)UnicodeCommand.HOMECURSOR: - sb.Append((char)0x1b/*ESC*/ + "[H"); + sb.AppendFormat("{0}H", csi); break; + case (char)UnicodeCommand.UPCURSORONE: - sb.Append((char)0x1b/*ESC*/ + "[A"); + sb.AppendFormat("{0}A", csi); break; + case (char)UnicodeCommand.DOWNCURSORONE: - sb.Append((char)0x1b/*ESC*/ + "[B"); + sb.AppendFormat("{0}B", csi); break; + case (char)UnicodeCommand.RIGHTCURSORONE: - sb.Append((char)0x1b/*ESC*/ + "[C"); + sb.AppendFormat("{0}C", csi); break; + case (char)UnicodeCommand.LEFTCURSORONE: - sb.Append((char)0x1b/*ESC*/ + "[D"); + sb.AppendFormat("{0}D", csi); break; + case (char)UnicodeCommand.DELETELEFT: - sb.Append((char)0x1b/*ESC*/ + "[K"); + sb.AppendFormat("{0}K", csi); break; + case (char)UnicodeCommand.DELETERIGHT: - sb.Append((char)0x1b/*ESC*/ + "[1K"); + sb.AppendFormat("{0}1K", csi); break; - default: - sb.Append(str[index]); // default passhtrough + + default: + sb.Append(t); // default passhtrough break; } break; @@ -97,21 +124,20 @@ public override char[] OutputConvert(string str) /// Provide the VT100 specific mappings of input chars, then fallback to the /// base class's mapping to see if there's other conversions to do. ///
    - /// - /// input mapped into our internal pretend unicode terminal's codes + /// input mapped into our internal pretend Unicode terminal's codes public override string InputConvert(char[] inChars) { List outChars = new List(); - - for (int index = 0 ; index < inChars.Length ; ++index ) + + for (int index = 0; index < inChars.Length; ++index) { switch (inChars[index]) { - case (char)0x1b: // ESCAPE char. - if (inChars[index+1] == '[') // ESC followed by '[' is called the CSI (Control Sequence Initiator) and it's how most VT100 codes start. + case ESCAPE_CHARACTER: + if (inChars[index + 1] == '[') // ESC followed by '[' is called the CSI (Control Sequence Initiator) and it's how most VT100 codes start. { int numConsumed; - char ch = ConvertVT100InputCSI(inChars,index+2,out numConsumed); + char ch = ConvertVT100InputCSI(inChars, index + 2, out numConsumed); if (numConsumed > 0) { outChars.Add(ch); @@ -119,11 +145,13 @@ public override string InputConvert(char[] inChars) } } else - outChars.Add(inChars[index]); // dummy passthrough. Send ESC as-is. + outChars.Add(inChars[index]); // dummy passthrough. Send ESC as-is. break; - case (char)0x7f: // DELETE char. + + case DELETE_CHARACTER: outChars.Add((char)UnicodeCommand.DELETELEFT); // Map to the same as backspace, because Vt100 sends it for the backspace key, annoyingly. break; + default: outChars.Add(inChars[index]); // dummy passthrough break; @@ -161,11 +189,11 @@ protected char ConvertVT100InputCSI(char[] inChars, int offset, out int numConsu { switch (inChars[offset]) { - case '1': returnChar = (char)UnicodeCommand.HOMECURSOR; numConsumed = 2; break; - case '3': returnChar = (char)UnicodeCommand.DELETERIGHT; numConsumed = 2; break; - case '4': returnChar = (char)UnicodeCommand.ENDCURSOR; numConsumed = 2; break; - case '5': returnChar = (char)UnicodeCommand.PAGEUPCURSOR; numConsumed = 2; break; - case '6': returnChar = (char)UnicodeCommand.PAGEDOWNCURSOR; numConsumed = 2; break; + case '1': returnChar = (char)UnicodeCommand.HOMECURSOR; numConsumed = 2; break; + case '3': returnChar = (char)UnicodeCommand.DELETERIGHT; numConsumed = 2; break; + case '4': returnChar = (char)UnicodeCommand.ENDCURSOR; numConsumed = 2; break; + case '5': returnChar = (char)UnicodeCommand.PAGEUPCURSOR; numConsumed = 2; break; + case '6': returnChar = (char)UnicodeCommand.PAGEDOWNCURSOR; numConsumed = 2; break; default: numConsumed = 0; break; // Do nothing if it's not a recognized sequence. Leave the chars to be read normally. } } @@ -175,4 +203,4 @@ protected char ConvertVT100InputCSI(char[] inChars, int offset, out int numConsu return returnChar; } } -} +} \ No newline at end of file diff --git a/src/kOS/UserIO/TerminalXtermMapper.cs b/src/kOS/UserIO/TerminalXtermMapper.cs index 802f65bab..59fbc360c 100644 --- a/src/kOS/UserIO/TerminalXtermMapper.cs +++ b/src/kOS/UserIO/TerminalXtermMapper.cs @@ -1,5 +1,4 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.Text; using kOS.Safe.UserIO; @@ -10,7 +9,7 @@ namespace kOS.UserIO /// the xterm terminal control codes. ///
    /// Note that because the XTERM program was designed explicitly to attempt - /// to emulate the already popular and existant VT100 hardware terminal, this + /// to emulate the already popular and existent VT100 hardware terminal, this /// class can mostly be just a subclass of the VT100 mapper that lets it /// do most of the heavy work. It's only a separate class to support the /// few places where XTERM is more capable than VT100. @@ -28,43 +27,44 @@ public TerminalXtermMapper(string typeString) : base(typeString) private StringBuilder pendingTitle; /// - /// Map the unicode chars (and the fake control codes we made) into what the + /// Map the Unicode chars (and the fake control codes we made) into what the /// terminal wants to see. /// Subclasses of this should perform their own manipulations, then fallthrough - /// to this base class inmplementation at the bottom, to allow chains of + /// to this base class implementation at the bottom, to allow chains of /// subclasses to all operate on the data. /// - /// unicode char + /// Unicode char /// raw byte stream to send to the terminal public override char[] OutputConvert(string str) { StringBuilder sb = new StringBuilder(); - for (int index = 0 ; index < str.Length ; ++index) + foreach (char t in str) { switch (outputExpected) { case ExpectNextChar.RESIZEWIDTH: - pendingWidth = (int)(str[index]); + pendingWidth = t; outputExpected = ExpectNextChar.RESIZEHEIGHT; break; case ExpectNextChar.RESIZEHEIGHT: - int height = (int)(str[index]); - sb.Append(((char)0x1b)/*ESC*/ + "[8;" + height + ";" + pendingWidth + "t"); + int height = t; + sb.AppendFormat("{0}8;{1};{2}t", CSI, height, pendingWidth); outputExpected = ExpectNextChar.NORMAL; break; case ExpectNextChar.INTITLE: - if (str[index] == (char)UnicodeCommand.TITLEEND) + if (t == (char)UnicodeCommand.TITLEEND) { - sb.Append(((char)0x1b)/*ESC*/ + "]2;" + pendingTitle.ToString() + ((char)0x07)/*BEL*/); + + sb.AppendFormat("{0}]2;{1}{2}", ESCAPE_CHARACTER , pendingTitle, BELL_CHAR); pendingTitle = new StringBuilder(); outputExpected = ExpectNextChar.NORMAL; } else - pendingTitle.Append(str[index]); + pendingTitle.Append(t); break; default: - switch (str[index]) + switch (t) { case (char)UnicodeCommand.RESIZESCREEN: outputExpected = ExpectNextChar.RESIZEWIDTH; @@ -74,11 +74,11 @@ public override char[] OutputConvert(string str) pendingTitle = new StringBuilder(); break; case (char)UnicodeCommand.CLEARSCREEN: - sb.Append((char)0x1b/*ESC*/ + "?47h" + // <-- Tells xterm to use fixed-buffer mode, not saving in scrollback. - (char)0x1b/*ESC*/ + "[2J" + (char)0x1b/*ESC*/ + "[H"); // <-- The normal clear screen char from vt100. + sb.AppendFormat("{0}?47h", ESCAPE_CHARACTER); // <-- Tells xterm to use fixed-buffer mode, not saving in scrollback. + sb.AppendFormat("{0}2J{0}H", CSI); // <-- The normal clear screen char from vt100. break; default: - sb.Append(str[index]); // default passhtrough + sb.Append(t); // default passhtrough break; } break; @@ -92,7 +92,7 @@ public override char[] OutputConvert(string str) /// base VT100 mappings for most of its work. ///
    /// - /// input mapped into our internal pretend unicode terminal's codes + /// input mapped into our internal pretend Unicode terminal's codes public override string InputConvert(char[] inChars) { List outChars = new List(); diff --git a/src/kOS/Utilities/Utils.cs b/src/kOS/Utilities/Utils.cs index 7073da4ef..400a31b4a 100644 --- a/src/kOS/Utilities/Utils.cs +++ b/src/kOS/Utilities/Utils.cs @@ -247,7 +247,7 @@ public static string GetCodeFragment(List codes) return codeFragment.Aggregate(string.Empty, (current, s) => current + (s + "\n")); } - + /// /// Meant to be an override for stock KSP's CelestialBody.GetObtVelocity(), which (literally) always /// stack overflows because it's implemented as just infinite recursion without a base case. @@ -257,6 +257,7 @@ public static string GetCodeFragment(List codes) /// normally can't call that because it's orbit is null. /// /// The body to get the value for. (this will be hidden when this is an extension method of CelestialBody). + /// Ubiquitous shared objects /// body position in current unity world coords public static Vector3d KOSExtensionGetObtVelocity(this CelestialBody body, SharedObjects shared) { @@ -270,8 +271,7 @@ public static Vector3d KOSExtensionGetObtVelocity(this CelestialBody body, Share CelestialBody soiBody = shared.Vessel.mainBody; if (soiBody.orbit != null) return soiBody.orbit.GetFrameVel(); - else - return (-1)*shared.Vessel.obt_velocity; + return (-1)*shared.Vessel.obt_velocity; } /// From 5fce4e096f15a162cb17941dd7bfee7a3460f751 Mon Sep 17 00:00:00 2001 From: Chris Woerz Date: Sat, 14 Feb 2015 16:34:10 -0700 Subject: [PATCH 157/446] Internet is a proper noun --- src/kOS/UserIO/TelnetSingletonServer.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/kOS/UserIO/TelnetSingletonServer.cs b/src/kOS/UserIO/TelnetSingletonServer.cs index 2ab4ec5b6..91f4b5af2 100644 --- a/src/kOS/UserIO/TelnetSingletonServer.cs +++ b/src/kOS/UserIO/TelnetSingletonServer.cs @@ -259,7 +259,7 @@ public bool InputWaiting() /// mapper for whichever terminal type is actually attached to the telnet client. ///
    /// Remember that when sending strings to this method, end-of-lines need - /// to be expressed as "\r\n", because you are writing using the raw internet + /// to be expressed as "\r\n", because you are writing using the raw Internet /// ASCII standard. ///
    /// character to write @@ -279,7 +279,7 @@ public void Write(char ch) /// mapper for whichever terminal type is actually attached to the telnet client. ///
    /// Remember that when sending strings to this method, end-of-lines need - /// to be expressed as "\r\n", because you are writing using the raw internet + /// to be expressed as "\r\n", because you are writing using the raw Internet /// ASCII standard. ///

    ^TchMWN_NK5FFIaM zEeP6@w1{1VO;2vgdCzkU3dUwgVzP*iqxc%`BQ{$C1A5>C}CyO># z8oB?EVZCSJK63J&?mn}6Ak18sfoVqBqr-^u2_PmyO0G0R1HpwjSF&9TfCteUsxI)N zhKZp%&UF9~a0|G$PDJb!{waJeOsQ2+im$UXD!UiNAna&1w?RN{qLa1oC!OJjcKz#E@cAdc;^pp_HKO~5IZAv4u;Y$iB66Rr6ZhSU9y>|+ zBjQ3Oi0cNNE3H{So)4(e#s++vtQ{^)690x_T z0dNbIDP1oD9Z>ey^a=LED*dE^(gcj;twb5>H&Bao;&Z?|d#!a)3oby*(K)N)7r_Zm z)`>Va#G}p|G_$Ghkm#k_4u}H5O)s6mm9~M3ENRrnci0+&;?2bUDRT?Ly)6pWzPnn zT*;PZ{TuNKA`J9u3HZVdE&=vKuV_Vx)jgQpZQxBB*A?%=$Q#_q8?+4(8kz&Tw(%6VNaI*}PKy74=>g_%32xeCF`@w>eY$!(ZA0;niTS#7_ zSM8A!m@nX56X_MDuQv4vQoJ}%dVgdSQ$rX}2be85V>JQwuB|l#NRmUZc?b_%RO?-F zbE2IO_gw%r_e04c>WVJFejI(m>)y`Z<7qp?_GCl&MB{h(<;YSFe;-}^&qs` z|2W%M%$SRa!iARO5OYpDRo8QLnIj8NWDo<@5_M^vy4uGELrgxFkAO>~0JWq)E{hT~ zrdOLrz?=sWQ)8sEP7&_?f^l}eGPE&NCW4*4LxDn_J?jcvzNO~&*wrl6H}Q7|>|rm+ zZO)7%IVpbg5N>F&b6lM+uP3PHjVXzfb!8gqW@@KV9C6yN25A@1y10o7L8+&3Fy1a1 zPCFHaNr7*sxfGrk{1b#`M_{?Z9c=Ny2a0rC(vxz8fwHUALENc(ORikFRV6#di|(K2 zP^rWYv!`sN0f+C1wJ-{TSQQE)7#w7Q{v>8aLc%f#VofLF%IWA9Xa9sr?17<+BU&da zjj;GNx1ZCQI3r&@66et>n8mgP!Z;_y*;oX&scAtvomaA{{1A@h8B*eJ9b@F$VhgzjJe^&;k3I2 zTJHJCnuq6>sm7q;bgqpMl${aRQi@n$_U4GDiJ%Sr#)L9g4Kc24J3V)#XzmtBZF?8_VHl2d-{<&kYIWr+oqrB>zXqDq+L zODQAqdE*OKMq9ypx;CqIWPId_MtXwN*d&5s#`B$P{z33H5ntRR<6u`oM%DWFHLj_~ zz!*>FF>FlRY`nU2mEI8d#oftHi&{{hNYrfBWW&c9H9EwUCBVP5lcSihoc>E)VINe_ zDCne8Kkf!g_#DW!9LN8%?Q3J>6`FN|Ky53|ANjQK7&m5h=8d zjI6Hm`0{$Sr{r`;oXG*M)&*g{XN!D0Vo5T>EHXtYvMZZDZk-}@-OOtq zIf8T|ekh`ICTi)7v2jNDJasykXOXD53;X{;10hB(1@si0A+g3ymCL7|w6-#!R61*PLg7zrlr8*zKbr@|#vkXp zB8Pob>dHehSxsPemGCUP68HmG`x7Gi5i4fP7Uwa7beyy3Q{4r9$ikqn43zu+f&N=K zLX835$viJYuHc!`Z-#~Fv`;2%t$sqxM8ou4pYCd75cGqh9A_>PY+9e??BjBFsxU8BaKZ&`d%G z%n<9@bLH9zxFoGp=lJ&u`7sJFsnU!nxxxaq@|2Uw8#xvE`qntdXhy0mGBRP!XqED@ zWe782;&O_US815nGwZ3^nFMfzX(4t*Ou)@DvHIF-pUHc zk1!%I^ROP*VfM^9m=jS9kzp%KhDl+D4gzEt0p%0Wx!TwQST!b0bgUa|6!^>w1|||H zvc;K90kLNfFj{=9;W9S9yhe8MZU$&ALsG@733wF*M;M}1H8Qf}965TR?BF@5d^sGr zn4H>JTzXKd z3FgzXI3QQWQ8YP4FIaCH%PeX_sy#TEvIJ(195hD7=b+TAWj)V=;?xT_%vIe6ltLDx zi}J}Tva$0Nn2lnLNghWA?R(C}7K=z?25mh<$IOYO%o`2l;0fi1#e;w2EMSELe#?|2Q%u$j=pS^Y>LSTdMnYhd{{EVqWtczC)|VtIAWoRTTzWkRm`)*~o6f~5T)xD3ui zsaj2qmB`L{QPp90N<*-te^A+RrN=2SJ1byzHicmdYAqzi_fE+cn9a@`2(1CY&@9Kg zKu)KVx5iek&N}N)tOM+9HX zv$33dJ%f->9FFxEsww1n0RcfNTAg|02MGdm^6-=b%41q@4jr?PdUFCbfl>j&JWs-$ z!U+?xTlw(uFh=YyOeH4UNs>*R08%l@L)RD)NK~G_(bQ_dda9OvqeT%_0PnT&I8P93 z@;FCtl>ew6K^4bTA~O=RfzJd#SM(Ykuw{{6J8fKO3vt5>tY&diJMjyQs(7w4tI9di z0Fd{BtyKVotIII)du2SvXl=rLtTK;2yDZ@_7yA$#+i18)M&Kf~W<$qA!^vuLIv6DO1rSOHBXYQ)*DI@KGV_oZ$v zMKC@P&1r`e77R@abP=JpvNX%Nj>rb&OmI3Z!!`sDw?-j(?UzUz_b%|;nI6)&-woz~ z;R=9u#*zX2A?Wy(%#>1*bD5m_7ZMDA)~s5UfG!R@DEG371(&{)?bMt?>X_iTCc;tu zoZK;ETqr}vIOnSpIVERcnn3WWR-#q=4m(w0Y#Iiu^tvGiVA4VG%oh_Zw)0g%MV;mT zXA|%@s87tCnp#+{sgn!d0f(NUcW(NG=Lb(2Zg_$DQR+-t!EL$XgC$%>=EQ!5hs_Py zb~Q2jIGM{t^H3R6It}2s2wf~0I9t>a)0y+;b#l>EA|4`_(0t3N$h<_)1ix{PO-bck z=42WT#AImTi5)U(LO_4?RCu0^9~Ymy)YI;gbJDGS)IUon#*Z!Y!1dpE*&QfhtbBjwF_^+d}5Ks$z?k>QO%*5dsAS^Qz?$by&fzaE9x5A6J^t2H+$?kuEdwi`w z3~bM04TR2&mOi<9bdexf3=;9gav($Ss~%dLsA@VLo$K3(J)+aI0rtd_MvkOKghiS% zCb4Tn!&A|=^o;tjzASd|&G+}tONKfDbifnxHY9a5S)xS-9lmUM=;O!+zwZh-4bY1~ zE0IAk$hr8T%5d66`CgP?;M{1H<|xb)cH2 z5uRJfvys)p7&fOW8S7S8sgA2g zOAB{z?3vKa@MwqgyVIq~5B}b|@BJw?w_!1Htk+YOo=j>d7)F#Jd==#03lSJBb0)C!hb zuqS=8A#~TWGi+q6c7-W0bLXGZaD zt|S~gr!M=`|&i= z;NL)IY~mqdM@B1TiW8K0ml3yS%EL=pnN08jV~s_?*V@Cq&bA&xPYVHme7-H;x+Ij` z39RDUHKlI(v}}0g?Gami!x|zhTftKKHi0}WUj;k5yHKHh;jxi}c*v$jRI6Zl_D~h* zg}JZ-Y-O8aFi-K_uILY}VVZc;6w@gMmd5p7!IL=uY z3OyDN8e-Yw;`Wi8Il*?}{nqhEZTigDwv%zqVGQ_DCR;XhJXzZ*=l2VQqtFspn{jMM zWycR-DMw(j?p)T~@S?KKr;jP^_&a3=U9}y@CzzZmcQ#hpaa7AKy!_-Yyqs|x5r{Ry zg5gg(5-|uOUuahhXY6i_=JLdNECgeJ^|-HRGk8~(nGGNHdb?$QZdX~9J2DSUlYzLC}$1~_o?G6O% zEJ!S>6_jP8m}APX2roi7;l^*v*I3Jeni#%n1SyFl`%Z!MD?<8qzI3aoA}RooAo*lA zf`XD;Jyp0secaJ7Ms+TXi9F6ozd*in-_gQ!*slX`9$!aQAT;4E2h zBZ2GImXN%77lVqr;+D>mN7vz6;#@Ko(|tKH!AtB&_2MKBOnwaJ1kBmK!&yBcv(3r% zN&d6KsuWgfdbl2CPTqfntYJb7tv47cB|4wlFcs{KU0>%Y3<_H{3>J+*p}Czr!Pt)N z^wP&p@qB_es+09R>>7kKJL~&Ss!Znv7Aj`un4WMX{q$6s%o>~IBQNLrqmki2H%tTv zx-vO8Ru11@D0^ z9g80&gh?9_qD)*X0)}X?til=8M#{)lP&5{=JK)?%^Q`aht&a*p*+tGUYtv>#%BM|a zwgs~#Q2*^hUf4adG301Idzd&AE<8i#bcTb(fb`lcKQx!MMJ`1>Ez}W{JnqH(Z09Ny zUrithjU2$YO$)L5$dk-4QElu-6qy8uZ1)USJym6VHvTZVLDLix$sNa5nf3|;M$it# z>~DTmziVWxW65p*3X`0D}0buLHebT%mwpNu6?HzAJucSe|U zJIR3M)`mzTme+h$9p%^uL^^Y!0L|?qNmIm>4a7iKiWD2eVJCvBxiz0&WHiO2=5bui zt4J%{!PH5jcLfsjPCvQasLEYVCK?yR#Rl9ZRiPH24OaDDDDUtej5^c%^vt1u-dE$^ zsEAC?Axeog?>#Um)=2GkVh4!^)pE{$Ftvc~j$nN+hZr$(dI;wB+AITrqQ@Br+$yb2 zbG^2O9%Zzl(%Lx3tp@r)aO%T*H%d5;l`a72Wz#_W%T~uNS0-qrmFX5C%oIi6y|6$t z!4CtZL_@GET4fYv#QEAB7h7=gnazb!zNogUoDHitHj(ZfHeFOxYY|&bAX3C4cay}9 zOx$5m!dB}GTg>ORc~Id7E=yX)Nl~T+RT2#la&x7NW-M_{0Epj9@#(m?A9)q1w?P=g zlwNIZc3U&GZH*WzSg?sYAaUCVX+kS{NU&{0X7QY1hT1XbxoI8sp_rLI$L^5ZPTtm% zQ>ZrR24;l2LmfsU**1hk=(Y#W%;+xXp0xR@dRTll+^ z=&e|MTi}jY6vTsu@L+Q%{mJ<~7QZRRh~ph3(cWA-H^~05`^Hqyh2-mRxK)Exw;!EcA@Hh^iN2(F&Z)RbkEK_o7JA;;Nea@6BeI=5 z?I3T}V;&5Jk~gK)B1Ps?A2eR}Tw{pVTKFD^f)_Q4G^xZ~K?Kmu@?1AnxZRpJHt}p4 zUl^I!6H_83CU=Z$j92myvJ;8i=9;*W^Q`%hbK^xye0oG?(GT0_O!7*-PUsZBowUr9 zvOFOLcGnPfFFfA(T_6QvK)1WPu&!z&?+nZ zV#+ER(LYSsb{d+GcWd+L#MEmqJ7FQi#4}W>2#(3V3!-@Z}10t_D>rN?11Mw?DhH7^uF^smdCf4R2MWyoDUhNXHs zq>BsBNcL`)c=jcbp#2g#&D=x|yWlKQi9u-_V-neG`76Ij1|}2 z@pmQW4Y(lE2Akb2r&x#`Gmg-a9;)F?6T-=YYU|Hta?sMM);$Sp*vOAk+lf7}Ntut3 zVfiOs*5h}M{PkNsrsb_+XhL|@NI+>)O9uG)F?6KPiA&M{Hvnm^3Du9`BQEG+jYe`c zFhzn#3J;TgDzH#ONO8W3Mb8_!dkRdd!F*EMn20v9cmfl(lSDaPloo@5;#mhtCJT~6 z54b23PU0Iv3`QF{DHUBjkTto@rVWxhpO24BNLVPLsE+mL7sf_N8tB`I=l>6Eq>~yo z%N%n4*vE}?DUH)ea-4Z18uFBVft&i7D{2AnuNM)GKqTlr4I%lJ6rr*A=YxiNs@) z=_-1H^*x9AEaoD`TYeMsS42s=D-~LSl(;P2jNY-ncJkE-i=PD*yE|!Fjgo?tAw{t- zqn!S%)&e)h4uCvBh9#^-lhVFk6wmYw1Wt=j!YPar43jv`n*)Np@JhjxID}Bt|B`H~ z?)LSH2sRZ?@iIV`%5VLTP)EFF-&qSC`6wt)s7vYMRto7e?G zSD^*g5t)bf5(J2a=SV8xLTsuGB6T=HE>Ufy*t~8co;(*IN=KK_+@W~pb~VZ<5Sz$a zASift8g|B#HL6LIEBe$66T*yu!Ns-EuKYOoS7S+bn^<@Hxn9B1Es&YaSfZOpLV3*AYmHnSy?Of z>qlw=ids*KFNE=FCRGe=?2$~lHv~yHk74oH8fSjISL}*p<+C)KxjhXIo0Ka76x2P9 z?%=~n00NkZG!^#6EZN97!lX!)v;Mt_;S+*#i*6P6o9GGLj2{w(&Wdse*)c)Sk`hcx zUC|ioB3T306z~%R#rfMg4(Wpx#B9>|Uoy zgY{SM)G|wA!!L{3nh+R#=7ZU00~@CaOM03P}f2-Le0`dBl{ zs!q6|A=JmRQcm}%>s(2jA|XM(%`Gl5Y5{{geG}hSq#JAUCH+ava$r~ftn|Dp|gCookMu$SnOgh((CWK#7+(>~nCYxp(a20E>vv_9NkO{lc zc2i9H*vV+|Yn>v<>9D^O*U&U%ONkE9Mmim=UrS#T9DppWQM#)naLD+~puV?YCgu~Ja<*bCc{`Gq zQBgSFy~vReM%62q$X#YKn6A|x0RmXGHcEL#BuJ!J8(oyLnG|ilWD9jsVTj#Mlr>$G zm5e8)`o0sjLZaVt;Tzncr2+ZyW9MEPGcKO>*k0nVe>-N`xA3bbdztofN1OtWcU8nacQ1oSm)+va3xI zkBw3!%k=c^KSTiD8Rw~WI-iZNe*A8XVw+W_W!uGEVOUk>DraG)$(=Mt z-;5L02FB$Pk*bnMiIU0`a4to>QN4r7E9Z2K3K-QLYxTl&q=wO%tqOFCdd3kgv5g!d z$W^f5uDLB_FK!)AqoBG!9ari7sYaT&V~2U4uu}o16e$jg2+N-?MQ{KtSBn0<%~67# z9RV}sh-Yq~NN6enls3rfA?rzu1&-kfzIDUw-h{wVCU8@%r3h68F?2LpH$bo<6cDhX z-G55lOr=S9cH2;%MOwNYPX4Wu+Dta;;2=pblLw@5E zi8MV4N|ZJNb5K*tX#mVgeF^|W{&rGM);fv7(yTZQgO!+C>Q)*ed_pb#7zQgdDC-zZ zPePdqB@WXtw_X0E(57xu+YpRT)uOjB+QeZB_%;k1@h?&n1RLfZ^2INpVVc57z0yUJ z0ED{rU~93Vl#qD|izmy#&ySdc zK$vbe=ZdCPHx)IvlLzz|awJ3KCK#q8*}uU4225ovP~A0cDCXyi{})g!f|ENyXJxQh zfIPXPZOG?pYDsWbSfg6NHVt7NFGCKU zglXc#Y*wI_A#(9s@z>fc)?@4~<5_bZ1|Uv}L;%d;Sxjj#jD2zv1j^+iG2u6_iDRy~ zKm#Gf_$Z4LhO-i0d$Hju}DbtUkk%Ktt50 zqw+u@LPTls;TLQ}6f zW~@>9^$GuQR+#O4ez+#P-Z+mxAZa#U%^&Acz#e|12J2(|a3=y~q(W&(eH(u}-gvI+ zJ5q7(;dD9g`0b!kFVCfdA=b!Gu*hjltdIs$ zM;8xOlItaUUwE%B}vH?6p*Y|Kj6x%n-0ZZ)xx&b_otAX%p4%!7E*O^GF%#lj?$e+#D+2U_#e z8+wasq7b2un*_-;;wsC=5LICR$J`m_tzRPZ=$P$O9MFrC3EtD*q2oUYbaCiT?1R_? zX)(!k#TD~9hF^yqfAo_)Ou@jjm>>nMySu#Y4c_vHw!M>6XP47b9a$#+R91G=I#n#! zad5FGIIFuk$Di2V5X0q>c&}az&gyGP!X&nA1*_(!64#<{olh|<{2lC!m;B?3brL8( zlx||>letoQ3c7_j4Nth474eE)%L`v$jfn}rBT?QfTm$3rw;|BsckE)ZZe`Fi{KH!s zGvQ^U4mhe0!qw;AFP2~wEh^D1{(Jg{u|Q9SYmM3~|1jOinv=GtV&_ zg(?;&2E(9NJGgYTmff5eDT=zPfE^U3FWetaP+4H<{A0JwJHs;0VoI&(;V$H+n_FUf zzBCYTM`AkuFPE?w`+V&|? z@oHkZIVQDbID)~WE~+4H@MM~@Q*=GlikO9v|3c0V>1^*1wZsiXBqlgpY7Vwsfnr`J zkfW(_VS^AIEk(9G8)0&)~M3Jw}FGA z)R4IHHU3EN^;9_Nbbt!DogHFVAr9Uabfu8N0RLM2jof2_BnMeP%X&jRW1g@*fZnK} zF%?HDNr|ecy9zQo;RwCM+;kK2TKrb9cT1c*^HJ}kfPz*~V_x6FGo>cAUZB5(4t#?# z3#Cgr1$Fd9Zi**_i6xfTTO=6Bv2XpSlpw?a1R?|cYEtK@1=qbT6=+mJK<+fD_H*{z zYP333Zb*(zJjbP3ZM>nGs?ga8K9CQZzv(VwT8{8h1Mz~x=K@i&nT)Y$TfY86ABG$Z zsc&qxYR`tjDWPC}BTd{GDFwGhFk(nD1+HojOew<7A~c08f*uOvqf9t}=?z_$P!xk4 zPK`nx(9)`-N3|>(Ipps4IlM5kB-EVn%dF^_yMxRHEJG)j;o&pTMu(w+o4N;cJ>&?Y838|L7SD4-i*QtXJb9^k&{$Ca(< zQzvqIjFuUZq%LsTdLNT8MyF;0d9;`RalE77K{=g}lk&td+DwlBE#xVJmfTx74fZ(p zMli6OkNAwimbVHA8W_-Lh41CDCQ`M^J63E+Ne0}BAJ{UhiBdccz%d1h>fYBHc#Mqj%0%Hr5dbFeNnlMixe2+v z4tX3$bF^WPu6r-s%F!|^exLn2%?CHbu(Z&DA_)higTV=L$3Matsnd2Dx@0Soshyzp zEUY!VvOf$UH&Fw=m}O^*?MSw-=BX3FAUVb7u(jAM)ujA&SPNNtl1eXH(h4a}PK5l_ z&0_A8CFnVjO^%dH#H$C~9SXOId+UDIM$K%dO^WRnVQoSvWw1?hlUR98K%Q<18pUt5 z1RfwYsW6H$cJIwCCW*z1fl7<7+NEGAQ?=NOqtD6FBgUf3p_3E1(|_osGn&WGH-_@k zqqZTK?3{O6p=ebT{0L_YCWQ!a3i#H>+b?gL8+7R_#|5!TExFvwV2^m=N=E%tp?8c8 z`Gr09HdIw^Nu@Mpgo;g5E_{}-lwOJvLwxBZaf$OF_d?srP%9Q`Y95&=4@h*m^sC2c zrXKfoD%-6;-d;-J06L`t$_93(Q==pZsgx%|#8Kv2@-gY8G@#T^)VdYz-y(g}ji(eP z>h{5uq?@fKJzzlTNWfprj)bx!NpInH-t)l#N~%WC0L_Cz&UnK^J7H~y7%B!A6oefW zlR|v1gz4sG%<1??PvEA;Bt29@jzf_oB_XMiX3%FzuS(Fx;u#I1m|uz=ENfRBrA6GM zz(3RznJV-scCtu;eWVz_0B6}1i`VRCs9X#{QWp^LS`c7q>*aOX=zoe#XhfP}Z=Lcw zip`GNw}0yaS_Cd(bWjJXiPvfi0Z94;V<7vG7Ptb;%#S);>G=%sj{_bvW z;eruaO;7xqNG&Q1^r$b`?HHU=cHNoIkA?t+7U{HDfcJJ_Ax$CVbI$k+Z;gmj221zGmB24=p$TS2eiAn^eE|}Xd zzH7?plPrvFrKcNfW+h^p<$*^sp>9o?b|S(`ktB0cyEQ`y{6k#0ubAA#im2qfR?7HY zc%_>$S_Zi(S`6b8PDrN|v~5gyXtBs>g?pJaT>C?I_B4mv2^vdElaY2pi2*YRi->pY zce=ZQpym!9E=+j8HTo95e12T|8nPes+F?le-eVH0^rIVI~xCjq2lg$WV z-Fph# zOS@18`=+nCnND}4$RB$=5EYT&R`m8z!-{`Iol|Xln38riNskht1!-jLBUrnET{y=2 zi&Y*f5F-J15&{1~P~mTnR+t^)GD5>>mQXqI{9;~d)KJb@@h3|WF(sF@92ASOO`tsw z%aVq3S}Jof(V2=T0h3ddX&FM41siM9bD&$|40&>v(CNsqIYO zZZ7tnVPOe;sD_|iMTWAM_3a+}I#BWxxjwjTPXZ;Jd89f0C@bWeh1oaDaW5miZKEZ) zZ+wF&U#nWABp~Tvc%0Qfm5NO^7GIj+>qsdoQ7^9}qe#);<|%>VAx7YZkyE^KExEp* zhnE?=TV?0if(9cPSAxHQrQuNe677=gQvo1#eh68rBlorFf~;3>^72~J`seMo~w z&k5NB^3widNi#pyh=QY2!INnks>TQ#LB?r3jXPn&|0n#EcA{W4H5i!tkH9Avzb=9{ zk!xS=dpddwh^BInX`{RqGTHf)5K5gOY&sQ2bpUAo*D#7;CJSXsA#N1lJQN^GU#0-( zg)x*2X=5k`(%|NQ6i5k&x|yR;g>(w(qx?18Xo5*CirPufjSN#Qwb7I-qm8D>JRVsJ zEag{eNee6$CTINPqW3V1Afyeb4BXS+UuhtphUn>_N;%Fio&;8Lev;`fx>AiKa3$F1 zT;(d?QBZ)U{k=go7O6{hTy#=vCnbD!++y3wdK86Mg()AtP(66c4Sze%Uc^$zBQAPS zCBuH@OdD=_Uw|8;&RNxII1<9&vo!`koKOL(*%xvt#Efu*hrg}I7>^Rq3W_A3bdtm# zOpQKjyX!#M%J~OZ`-pH?#4$pG(_sV*PeLzy>sYSHet(nTj$JI`KtgUS$gq>k+7un@ z8bh(fN6h8o6WSP65nrx#k6uK9(u6E_ggb!g$pR7}x~grvLB=lq*vYUXE*f!&rjmr~ zoeSp5hzQ<6ILDgN6Bw&Vaj1XO=CSOeF@>~pgCxChd=%X_%C#8oJozU+4Bk2%HX2FZ zVmru=rYO{~A9VU-MSc zn54KDQ4CBd!yjHv`c!Y6&9AJ!x3TP*L9Et&tdDcSA+8zvTOXy*qm3F%!BrqYb}E4i zsoxzN3QP&Qx8kA1RMHtHWpXLWNxcoa*3(2x&nXsIC923Evk=JBA1W;|xq^Kxw5(W7 zq2P1BpcU4TVGQu)f{6$3N8E&xbXj>?gHI;AV3?%--N)||0B-=X$|TiG%`|{`u$blI z@h}lda~YEs=lY3uf zU3lPQuB!Y+mF|p0MmnNUHdM$rrsiNIV^dP}sBBOv`(7Ku-dmHd1Gf~BaFL$+Anq@W zlkL2)z&va_=J!}Un5dHmX6}px>Sv1*vJzO;fYcs-3z@rtr5a)D?I|0$tN-}WZ6usu)om6Wv@`29_W&VN+F2U62D>!wTm`V;9UZkWp zEkKE=y{+WbJ|VJ`aN$U|1EexDkQi1A^pi5vS)<@IvIS|EUZ}}@K^bNVJ)~RJC?fl2 zmVm`f3cX;ab%eq=RlP<2ushnNJHyj7aMhkHy*){sAZnMQ$~dRV5GGyZ!bLvUbo#NX zwa~j5IXcGP9lTJ^^PuZcM|6l2y?dNKG9zqQo=cG~RbZe`^@au`S zl0MdBm8?MAJ~Xhi*^Mb+d`^XQy1kZ-QkTxLHCo=m47^_FZCBo z=C~UCl=kS&iebik_vj;_1O})^*?)r>>3!0k8yLr=IHQKP=CsM%oGi3OjcT`w-TKqj zCmR{q#Kr(v3e7U1twM>i;pGcyPzJ^gydB7uIEL*v?CnZke=$u?zvZlL$a-4i10YaOLxd_nGCFF-~Q@~Ea#m$I^;vzGQySe3-o(5sB8_Ydn z!FjM+w@Em#YmHtK75uuv@}&RaEA=S+P0VOUC(nvROZOi#7J={E!-*V)TJ^_X^|s}#c?RY-r5LHk`O?NLh0|QDMb?w zml0`pJ9?IozI>uBQlU|CHm>kDJIhTq0wo{?+wBx*#EdGsqJrhOXNDCT$@f9?k}wN@ zcPJ8TG?X(0ap?c}$8{HiGs$>56keMF3RE3we&|C{4aM3=Peno)upUr#l^aaKCPAjp zpSQBANC*~rLOQ$`9zR10>FWxOLwnVi`m5c=EMAB~RHU0(F7igKL8k*pd4+?#RF-Ml zA+>#>e@(+r5vD<&e14|MSm%vr9gWr!0vXLDCJqVD$r%z-srIrO-c#jnnh#Yxr|#`3 zBIHOd`Kf7v6IaM(+MvjZXIeE(#Dv>@+l$|!k&1l>-z4#bBZz7T0eo$Pc>v{LTuVQ{ z%kG-MnT@PLg$(7Es^zyq5fmb_H-IS69zDO6)f3mlz1>uAnsL*$R{vRp7t#lvY!$IZX+s@ugV zz<3vTu)>Vf`L1cHNyj!uv|WC?S_&l_emQty*t~oGu%F|=3-fUhN3W`;j)5NPXclud zor-X!QHifrZk>^{xM)P-+43~OU)GL%MH+?=LLtI- z3(at^DeQ3!4^!9XKm^GM2zgW5B2%<4=Z6)VCnu(k)05M|PVsR_Q`R%IdAT4Hn+V_w>nw9Qlth?5` zDK?oGvaEu5i7t7)L0X0G0mwhkUeP^5z7 zUEYx7*2ruW+KtqJ4Wl$P+<_2oK|C@L1@np4YK{gM(KFOc&KiXf?&Nx=0=(ok{n6ztcFSxjNw~X_lD|bKs2U2or5pEIOuU zHnE>)EpPqHawlfIgkA9hg&b@&N}Ov$=z{6;Ii-8F58_S|wICDEv$^f@?BbAQqDqSO55E*<_(n_!Oq2yJji$|RqSLA2xw^W5J$ zAOpl8S4xCTA%o=Maqf;nWNNK|v%qmk#1!#XAn1V_dy2mOMOkp$AEF}Y_MxpykyaE00VF;1pI#~ zdlUF5uk2n>U#TQEyKN+}v5`P~E!y{`w3N2eu0p#Il0XtjVi5?0z<@!3SZ(75gYgP> zyWMTvO^-Y2PTq4nzj=u}c`upFOvuvXH~l8D+i|{el2n=h|J<)cX)z=}8&%bJ z&)v>F_niMd=id7<4^{nqFmMT;-$Q`1AmAbg57Aae!DazKfJb0#dC2AXivJA$qhYjlDiSv{yA?hLW^MQf{D))hcKm!DD z$c`BV&dC>r^C~u2<7JL+whmjmg+#*#jO_l zR25iVKPC@#Fi40+EXV}`cM;QIJSJ!ft4?%jE*6BQxCaImFjQbr*$OWpIH_%JCG%AF>Bp8*P~JIFaNCZz59Hb^L*0m3Tk&>4u38d!iA2IO8U{elon zl|q&=-~7-J7ejG@1GNVx-h+i)h|Ph8g2YAJ5EjbXjNuH7fILJsR9FjvEUEI;I(?im zB(7PwBZ`gSK4Dq+Qr~c5Fh(cnkrDtGm|AxR%3*(oC?%4DyPc52eX=6W^mRaxW!lkS z#nm(RYz0cl*KCHUgNzAkxd&q&OK8e7XLQB06hzDfcq;Ls%SF!Y5eMPC-+f5wX@PjE zvfw_!s-FFqDw&2wgB;m~>p`}nA&nj$F=*5bIAbSkHlAlgGZgR8Fo|=46O<#m2*65S zH6RWzj=bJyA|fW^OrV!j_zzQvx*kQz+&Rik80yKS750v27vv@^HVVlzl4xfD ztLf?lEENA73>7RI&zRuiI&c%o3^tKv%nI-WLOC`;>^_|i_XHQ;n6E&j91VIdxKvOt z07cQ)DHU?gRwPgqAjnytPOi>w=src%OVfrV*+!uVIgfQ$2RD6FF%w`YZ;Y~lJRhcJ zv+m!(1wFAYsgmmlIk{#=2SoF6*ZQfKP*C_pq`0!gte1P>rfJYEwv$GXVHp8o0jwXcM4pC&R-aB>6nh66nZ8u~ zCx>NJD&3R92P=*~&_tt99!p`(azIM1i;`XW>?s|h{)pdkKMkpgYmj4!@^X1oh$8e9 zZYh=94;fIQK3R(VQn2@d+VhD*#H)uRe<+$}OJsn@)ihuYpNE{3WCtJ0rcy=8hYb6I ziDVQ^L-j)Q%??xlF~lf%iql_t;L!kRVp;TZ+c8(Glp&~Z z-M}nHK7CsY;f(C&qiFKfFL%)^kj1qIff!w(w7NvoR6Xjqx&VL%iGfJkds%+q`x5|C zl$LRbC8q|~WrQmD3J}`udnDZONs5IK+&3>Uuzm#eIj+itKP!}OJ!IeJQp6oJ?iu$!iddQV12S|Q#tssJjC1=OK1 z2XskuUmm&vPU}Eg^aS+}`Uj*yN+MPjE#&z(`XAU5Dr+Q3L+Bua`r?#8ar7*br-TtW zg+GUk_)A^pK(aaLrJ-@$t%FhtBLjGEBPOgI0jI>%tp_StbjS$%VUGpEel{lJ93qz^pTQ@FH{Jekfeo-5KIO_P0gX>Nm_7A(%E$3shBz}l-Vws zc>JK;(YXeEgO+ImCn&-c1KH0Q3zQ#uPIIA7Qb}YS0U{5rh4cvw z1VN6P&=^;Ss>Oit0%{b@`NOz2xIxXu%OM!BqY+@^Wy#6;vj8>?qpXAjs}7Dk{%}RW zwI}TlNrZWVYbYfgLkIRdOEzWif8V zq~J3R2slj-jVugxIbD0@b@k8+R>kyg@6+^VN@DT;Jx2+V3-w{jZOz?scJY zR0dv`VniIw`sNF6QO4zIC_KUJNf0}GdlV>8b zyf=vJPpa2u5<)tEO@kn2cLTTg+xxqb|vR_rLEG5yaK2R$ch$_WR znIkWSp@ccA)jXBY@B?33$jPV-F_}x`qr)J7@PX$o1!_`na@wFo>H{5(NqZES#qy09 zU8!o6gR=BB#6ze|mZd6YY_!}F38FZnH>y&RBSQ=7_j0Kn~M+gG=r#+_skHA^qB0P`ONr|6k>my|Fug#@6{<48 z;=YhrBTWzbPY1bJ0g!zMF=SkB!byk}*gV0q6Cs8EK)jt~G=^$>DAWWoGYY2HkfWcs~s=1Q<0lhDneT7o>8sTVE`b3LCsIo5a5)H1dZ; z-es{E0=fi zb79YCzDsg?Wr!XqqQWo1iBb`VPPw>f%|w7`e?i5$@2`})uGeLlF^qH->A^47LK6kO zua@-^ghJC5LSEoagegMZDiLC=pthJ9%}YX&M5TIZgp)$ZiG(jI#30Ql787qYYn5Ca zaQ-9I;7&{agUG9m&bm$m0m|ocOHD&gV|pg3GleHm-|#+=S^ymJ7B_rRtD=6+D1kXt zd9?E=OpyrBB;3b&D%E1@3Rh7gk07uhp<-Q}d*lVHqpMIlJxzgfDDyLkfblsT(tI^3 zsgtSu)oMdgs}(N+3}GF&%klDmy)cCl#o{l4`Nb_2Y#OnXs0Ny58aI}~9eyxDbU=YX zkIJaHFBAEmPs$hD3B4>`C92ddJbA@AtTeqenk;1nM6T37pr9fm^U)=8lN5x}f?r`s zp~{uTP@d{pl)8Igt>K{erbk;XjD?{rPs8~f+9ix39Y(aM=r0Tj*ur`h4MT7gSGFI# z5XqFrkU$uQ{Tir)VJt2l^=YpJZaSTgQffoNN7FLN9?KJnZkf?Cdczqk;v6SW*n1sQ zErQ~hnJC=TOI$3eoMU%nRWg9aq}A+%}9`P*7zg{Ib#_B(u(Pe z0do0(yD(JSxJc&vXLROc4Jlj^t3(R%K8QO3qD@ie4#nvaokd2k1Ph`VPE#rVQ&gD< zB_w^~xXE|n5P^iO+ovZX{Q!(4P*-TNxAk27V2Dwj(&dY+6pbv`WzPx+OlA=NaK(9# zlB2*>Zi^ENHcY&l_{0OIKsqo^EYpf>r(}nY5+Sa~nJ9%*Lcm+9TV0=1SJ9lZ${93r zQ$NiGrp0vAIJu>HJnh0Yf}9ziE6uon}x(G?)jnIp&*?+V&Jr10#s6e0s|1;$2` z7Grc-;9_qgCmo!9f`%x0q5=Ww&>%fKzW~9?4IwCj)*P}=MZ~F0ElFqsB&J-PKoCSe zba*fwEg%6g2?4nt9w6>f3rPw;*TcLhhEtDAK4Cva9MZ#7T-(NEJSIL-GjkD=Iq-|{ z_FJDMuIunWOO#UJD1{2+jWWVW6i(rjBpK6(IF^8mYE>jy5slz&L(_D;976idz@Wf7 zJdi67P!hc$QW^{!5~+ENZA`RaVAWW4+`9m?|4j=rW#icRF+8XVqRB#2zJMOr~ zM`$XRm=2HRopA(nU?lB0MG^NopwwH zR~5`;p897?XvUc+rkew+FZ0+azED6k4)8evg=k|vU4KuNSW?wbnk$Bc6fHCx*suiU ziXcb9WSv!^`sk9`OQm)#Hazp*%*d;1MbHd&T&ij8VG_ungteK@@~c7)lyB z2T?>mbY2liGyxilGA1Yji$BqG1Knv)q8-hS}g*0B+rl;v1JqzAcCL<|bq5BJ$DpRbfX^@|r$Kapl z=07T8sg&+;j38KnLgm~A38c@`Vs849&G3L>ERS2nW)M)(QEww83z-yyBkYkyd@SzR z;Ki=&KBp1&mqJN+B<5cv5j;g+{2z>lQRUq`iOK5@csCxrig@u8n#^P(Vuovx19A;s zDBA?h5U10yOVBvf)6^H!!^$=?)-7nuNbIZr6ZkMs4$3epRaszth(?wEpiaknPsCJc zs7R$A600Nk(hABty^adhdlS)UOmqE;Z`1z4N)wZhkX15W`O>9i8Vr|Ly$EbpQ_;x3vv#FIC4h``6L0j$55p@ z6ySX*(S12}sJ9rW3Z%7cF}E#>U8b^S0y~S!r3Jc?#31op4%1LYTH}7YJV{WPJM@>gHKK>O|#(R0Q{s4&Pv) zaYc*?3Z>48fjI&VjBc|%GS2KE{^6E=hO}Va)Wip=NR|>omdwH8yQ=tIq%BUFI(?M5 zseq7D38IejrA0n@^mh^I+m%@ky%>}mktq4&Pme1djH)WB8kUlzoD~X$F^i}LGM;R~ zMU%?Kqe~mbmKr7un>59Ek<+SeRL()F^LjJ&l@<+!zR005Q6aKexh+NkJ^}mawSMl8 z1ws`=?WpO>;IGVKC9PXi{gdoEK`>Ajy&O6T8_mv$1tT*s98_#5 zPw8oI=V#F4qIE^;wVR?4WVNk|W8mp*YfF zISpD}=tUFAETRquA%UdGgZB?y>>$T}5A;-ooUQ>zAXQufWN=Jrru+*;QM4WS%>g16{_y@F76f;wI6i5Wz49Zooi)nF)%=6#IV8_5>1;V zPEObXvKkU7Xw936{bihl9py}+zN74VJqc_kCZCxWL`EO*hbG*Bq9JP^5kLx|m;x^`yU$D8NXV^-G9?HQRV1H% zR8}L?jZ3YgbtARF}qlB_0I~RQF_8o)hZSatH?&{)1pv#~h_~y_Tsu&IFHl<*$`+6MUfQnp0XGRgtIc}WDWPZy&*kws$h_BXVOQx_V_ z>z#NU@QCczy%W?7D4r&h4g@i;v^w-q=+%-T4D-tDmy?`gfh8LhnedX0Q)X1)K33gA zJ;PVQ4$tsa!2TdAO9RBUs~{APztAv*NPh-&C}W#ymeTl8gV4L6;q-=V--brKmx_)m zhXth)!Sy^50hjjRN2d7NUt>SI2|=9V*g|VZi;*C=(EgP7h9LKdcQX z$lSZk*-bM%)%Dqjh7WIiUi~1AU9=T#qL=8p4-q=00|YD*MI%Cq z>4lBWpo68QLNRbPsT0COB(>i1CB%qfq@-z-U~YSyhf4NQpoI!Eay^A9HMcORG^vvW zlh(QEvUy*Xq65l#3y~JFss&SHmUBW z50AM0neagZPqC8hJ8+mO-gJnYB+nQ!r1Rn^fCWs4dAZ9O6lA$81EtEJF+_riCE$XQ zoR_P-z**uo^Q4MKmY303=1F}55drOzwC9$=#T+j%oF{1^l7#j2^3IdKSl{N)c>O%d%K#AnF`vPWG&u~<#b z9Rr3TR5IMGlI&~6(3V*15&|tY8Ge_!1qhe9LvhkPH*tEWfQow2`picp<3zV3rOK;& zX7yNT@P`g`h@Dsa%%GATgQ6D%9C87t`gGfe$+Fu8<`bJZFr_*_`Gw&Zw?3_$MgbT| zz8(&)MA^wN>0>_WFe2R21JjOw5E3Ey#)p85XStXlb^==l;{XC65Ob=5@B&70;|;b4 z$AOHITSa!$r!a99(M3iQ0F$^_x^qSpUywQXL^T~$Ic{)nxJ_4f_IJh7mQsGxVLn-6&umaB;qB(s-o*YO;Iew1SiX7>Y?Jf9GVUTat2STT6|{| zAcK^l!m(J(%tIneaZD7hf99=ZG1MxWAb)sDV4nW+!b#$N=teq~=wzISN{lT}*-tNv z;U1jZDa;eBWz@mz`G!EH)4jkY%eUwOC|!mLF>y%*BRi)(97W(mFUh=`LY!voJf_jN z=@PMq^r=y7=uT5r`RXOuJP{g2B@PZQ@aMKk-*62(^!j*Re(ln3M%4%Dk%m9G~{Yr_KR{Qdg;Y0ca7$%f$ zW^?-`J1}Fdi`9m-x#@g|^}K2f^)5!iK7!%f4M@w9*hM}J_nn=Bv|<-SgOc-7=WQQV zJdgjP@uRm5Z{PTJ(KK>F5#qm)t4}Rcl78JM9qbSu-SbFba|%?HMJUH+P|k8*h&NI% z@|G{*e9j9g?xqhF4464WH>0$f-ix{E^LQ`j5{aWyxj2;fVlK&IC`#p? zfaRQTV2iSPHRkfmnb0I5Oro5vJO#pY6x)QK+bSde6nI*O@W51TJN1uz;Jm-P>ZFOCqa< zMGS-SKgJ2?8EVD~7_^$(VLJV!d`7zF$;q<~z&4^t#YZ={1&hVj=oDB32*o!uB+~23 z;EF?V1pttceeFXw)8#?fsc2@goEHu)Cf-mpX@*E63)n=SVfil=%*w30gV`b7^??=r ze1r^Y3j8JLAXjMM(q{$(lfW$E|9id?(YRc% z&1K%S!vw$pWl|H(?GD($y=aO6zEmm3*LtEh-Ms@7A4>RvplsSqE zvTHv_;AHBvu4946#*ZF3v~P#^fqkWY9+J_cBL{Zghs6Kb?c>LekB%OGdiMjVjvYIC zX!yQV{>NR%Mn~>XqaD9{;`s4nhllQ4(tnQX{yj7vcaM(TzdFNl?U?)Mp?f@7YM(3| zJ8Tb_&C^l;(c8yHkBuHZeBeGMjs}i$aQ5G)T_ibj_|Q{o{3br@vcEs(KlU4Y;rs6w z{%UNj%WgkBh6bqLGlzaOVD#?MBO_1m84wnJ#k}v6@>j?_)`d^IX8(%KXYR4Cd2$~< zbYOU^^Oj#8k6&({36)u^*Y@1+5F<73%W7^o*`|``T-Cuv! zwR>o2V_bd5#@^oUjz-^hub45!pxnA;%lgCOyOBG7FGB4_O44x%E->io+kVF<*t=oz7rc{y_+_*%_94U zk3U=anJ*cnV$;TrYrSMiEB@&J_%Q6lSri+4de$bY`qGo3;bu{M`B_&_cXvzDGgW9& zRz_-U?a%({!__ki`GZdKa&3-{txk<9{@F)=`(fy8qVBG)<|IV~7NkVgHvaMFp`ZIU z=Znv}HmqOYM55fP;_R#fM@oEb?W$T|nqPj_wZ5~nG4UnPys*`lv-w;`THSLA@u|n4 z^!Mdit-ETi*7kO*HD|BYn(<7MHSuJE)kl6m|E#OCqoXD9g{rKa?{3M-=|7v9-f%8C zDdS9nmhkb>!i0najR^@oJqZci*7clt_Q=x*Up#&A z>C@-;?LBmE*Up`1whs)P8X6clv2S4D(4m2WT_*R8; z+V>3K)85qHxO@5a*Is$);)M(6weyd^;L9!0wyj;VR%_K-v}UboW#g>G)|Q7`49$l5 z5*}#@Xnvw;7JYM*)-=&jmXnrhPW4T?{aII2V`E+FW6Pg-^2sO1dtQBdpkqzalL1f8 zB5G`CC<|W|5f$@f%=p=V{)a!icqBI_AjX&I)@NNLiYh2~);D~o!Q)8O5px{w+|JAJ$%Ho7tyxoMeW5HXXIaj_{>9}3pXKCy`1{{zO zn*8$Dzj$ry{`S(pyMmv-okmk?s;f(M@^3(%``^BQ`r{AI+dj|D{qV*6P>1ABeDD{& z>A8Wk%d4)cDwgs>awnTUu;nh8O;A-?S!gNG&B+Bp;gP(#1eFyPg;q|*kld;IcXJoc zE}){k+-_m|lH95M#@vVJrz$TiEAUb|{>!{nn381?^rOd?CoaER=d7u6*egFp zIBx2b&S#C!-Z_2h*x>`adcBYQR{G6PG_rr^rUww690g46c`(saJGvi4boAif?d$&| zMC}hI+OvJ#e}t&*!9;tvcRYw_6iBaYnrNxtRO2RF z<8*m*21h5F9-PTfI{mKsU%PX`&+l4e!nJEZ^V9q$FI>CkXYjkp2Q$ZC&pkcHOM-N#sW+Pl9iLzuEZ>&)hn>XJbeE z+UEMIc}i#m>%5gW&dIDjbMtspRA@wGWJLI?nYrC;{{wUHO^-Cu!C;D#+&b^v!aKhJ zKhK40+O;v%i;{dB{`DuF2lnsZlGL=JZ*%{q_07Ijub45^pxik)xGCktmcA{08#|ls zOF6h>M^E}Wr@hdgpOb!H${pLccc)ht6_pg(b2Eh!b9vUpMb*F*U1?bb#Xe;J>&4EM zoxbxMWCPo_ZJ0&&fBvseR(|43_SGky+qQ1?lI3NEy!Xprg#BU`1@W{LR9u*!lTiQn zvnam&q;t#W&7JAb))$u)7Z%u3s{ZKz{>ADUh5SKCI?`WmDlSE<^K90_Kl=N>{6*+& zBI5BhAu2Ak=jK?e>VNua=%>ET`QnpKVr&qVlr~lu7nRrKq$gLds`RD#{F6=s?9`W< ziXAWREG^l7z96slOh#JHu@o)k5lh?0LPPXq$PR@HKGdbgAda}<9KmmZ> zooO%B7nQs)SX|5k)}GJK%zHjvOaFMZEG_L|Yg$@wZ(3T(k+ihJ3%0cEvsr0A1^n`p zP9XDvrqeZf_S60Lg3Zt6<+ePZm6>-YBR&0SS$g`@t?B8#z3J(tN7B>n7i{UspFT4` zaQo(G&m2E|4{LY<&r}qpFo;ol%c;v|7;O^7-_uZkvozL$a z^vMs2@9xsNCbyh?;|JOg3~y`Szx&pkZ(Mrq)t6to_{2qDUV*Y}!;%f!daYCIm;|zI zd!lVt`ufg?I}II%_Lb}ABs|g?(D6k3tj8VgTKnYMn*1zFmT$`KPdZV2Yu4kBhlD;E zI-XUPpOI);85$7kOLXg#&UI~VHBpf!Yh3&j@#D_k?iNRGXna8YT&h}gNljzR+V8CO zRKw1HI#`~WnYTN$$+^TCuzFQ_e`em!oJ=2{p#HV3t+nwd4vwCBNeuAIAokrn+)|EQ>Hz0R>c%`+!r6lBYhvTnao1Z$7 zg@-sMy4w;n9f7mUYpAcUkn%ztlT~dd$AZ}egyjjfB`jjHs=a6~0U>w-<{}8D+J5X< zIJ*FX?s%pzaZHuBJ06~&ieTGI<@~SnQejHg*3^{7aZVrYb2v7iayZssa5zA&IX*t$ z>TsOd>~QSe<8YuEj{3K&9hKj!^yM}R07x&3KaV+mez2ru*J~vuy+1A~sr{1@t>oh$ zwU?BeA&mFF%+HWnKR61Il{kRkrIvWvM>iqgv{x9au1%trz_--hSz2vhCu1cm}F~ zm+s4aP-rh{7hNxU2XXSFM!&26SMQYim0tDhx_Y$>C{MfUIe?EF@?_@lUNm03^U}o^ zFPuAbR60Mw?4Z3>deu~V^*|R&F|mXL24=_aS=j?F-hJ`H3ujM{_~bVDxv!R%UM(fa z^vPW6H#@W8;;r+CxA*t;Zt7~Ak$-~u{T4{IQ~0LMVIR7Dw!;(-kcj`UbxqZk z&ZeT=%%W9AzBHeI)JW)`{nEN>=gWI*Yj$5OEA4nb&t^ZKrDc8mba__Rp60Bq?w+iy z(*0RkMbG4A*-qKAe3%EW4{C#7Y|cL4T3Perp6aTh7t3JE?D-|n(_wO~#%3F7x7jws z6H;;1W^-I9vK5>wu=$jLCSXmmxASyEY58;8%gYANloYQ!TaaIJh6RkGfI}=`v$udk zoBiyJ0)F{XBbFMwFPuGn{KV@ooH%jr)uV?`UW6pQuy@b!nf=4V&m0~eK6Y$)c>i<5 z!%w}icX-daJ;Oc?fVgjm&6*rO_s&(rRqe;xkM3T1=Lg>h#Jqe-yY%?$zWf61z_umZ zw5={I65vJe)p}QKnnkd6%fnl=&04>q@5$adNsnwXY!2z4^>}l?)<3bS#bM7k=ldqz z{-_ak^c1XoGA#Vb@TuhwEio+dEDjF{_a(aZQ6tt6t!7hPQcCI*sh%eTw17#Yzkg~# z>O5p|Wp!)YJHFH5sV8C_b`}(r>?;T}YDPbUf9*g)$)3UjAJ(93dhJtA96J8Yv)_5v zv#U%i`}7~rmX+=PO_?3%c(hkzb7yt!05m59}i#p-CCz}CN+Kc zX$56MedVt~ed~A2NZr4!<)8itKYe?R!s*4=$-e=)^RKQZ1qK)mzjZqQ`i*(18-+T= zIq^h*A=?=^yF7UO8@v>yiyyC@O97vLeQINMwKK#y*^uXOE|^^eeD-x|n3f=z>i&sy z;p}v*EL8du=TzNB=fm?;VQH~ON&!{t`}0y^Zndpl>r7=`Cw4fUgU>mgy)QeRAlIB9 zU)U2%bhIeaf*8O=?P5qzM`;M+Epu2&y`^=8=^1<`v<(u9rFJJR+ zxmN!1n;qrluMC!#A3j`O-gddXy!q$O@|vGkm-`Gj3c#Xe{ju*J7~J*BsiC3MmxhLp z{$OZm@4G|V(8q5d8X9`@^w7`?FANPGd~0ZE-+Oz8hOh1(@+kmQwxwBXp6EF6+B;Xw zSA3-dNzF}(O%Hz5)R;KKWFTW>Lt=w(MkvCXq#EBRAPNmh3>ndWrGlC7+q1o2tSX$l z_yNDu?b;Xupo}7V-nTz$pF%{`Fs4m^diZnVS9Zi|4P&?QiF8Cw8E=(v@lyLgUqZx` zPrRQ9=Z+mlaMJsU=P2(m|LR$^_xa_pZB>Tp`Ywt6Z?300gwvYJzyS<>R;Ik3U@56%6 z3u?!#gT+?s`t??8{T8b=?I4iR*wHkrWqV>yaZyp8IXs%%*j;Z{m{THBivo&Vc1ufZ zB)9aBB|KH0kg%yYA)$3=LPF+oMB=`AE-OBEcXCl>d3jNCsk6B}Auz%9zd7S9ky+&d z<*w4W_KxUy(2d3KEsu}i)Egh)x-&jL<2Yh)-#p8#wk~INwIic#(?DxVV2bMl$Xu+g zI-uHBk9T?bg3ifFH*&W-qK7VdAW~#e9!IF@Ywjj;b^4_uc z67rk@PFHo(hOQ_!c-adR=T7uB)@$|d%B0w&^o&Ir6KP4-g8G1ZmoufSTY9y!(N&#M z*|^S`wIIu#nUNA}ZwzR3)upcQkusQ^zir>K%{hTNuAAAJH;W5Zdf2)!3%2a6Y;xD8 zCZuKC7T8?woGf=qQBy#ZyD=j(*&1VrS(ZAPQM9JXK%&I-97JziQ~&+1rb>mVAv-@S zGs}<_{G|Jd6~U&;My>H~O?K0U{%zYzbB(z!k1g9%Dz!D_{PhRNPMp+E2FH989T~PV zzrLZNI)CWsnHSDiPgB|(0vcTP*+0J0x(P;8OPoq!WbQ^?Rf)Nn^eK7+{=%01-|~gH zF8zmB8aI+SV=8wP5xE;j_dlOk3THrNGKm-Fx^3C%2?cclb*|dfciycdZE()@?2HS= zrSJ$;WR%ynI?*Y&tu`kie@(y|S52~)Ecd!CYbdt_j)C&rT}RIh3fVblLcSWJX|fx( ztQ2brJOkxP-a0{*TN_a8s!EzkRfL7T10hD$GEnJ~^1~~tWvnvADpYCCwyq{`mGhHf zjb3Wo|Ln!#X|k$-Dpz?tO6y@i(W|VgBs&)3?&1XBN-F~@U1f1Uc&DxhQKR788@8O+ zi|h!)&7jJu2&iy5;?7?vbVB}&xl@%@h`?PZZ2>}ZMad=A4OQNnv(;odbvm!IR;vZ^ ziIZO9d_?97v-g}hx64bMRTfa@Dv3LGBB#7cs~XEa-jbUO`rMuo#Ny5a8IHYD#%l5q zt+U5@8-CWAkmU$)xQb&BAI&U=FJ;X3T8GUxdfaB)e%@v)`w3!jV}DYSo%NEvsJyh) zCu41VW@$jFtH^rbU|KZh_w^mU*w?rH`{3gEJA-|F zFTT+W7mdqVwQKad7hcp}^i*aTGRBX+dZEbDUsqx*aTQvJb|++HYuUkXxG%qYyuB2m zICuHbYdiPsU9{J|XYYG^%ZiP~P*^(#V^iV54Jn!|UAuGdlD(6IEu~at1?H{W%t>$# zXYhOPW>aFamYh+D?{OQW(m2_yj)z3` ztU+!~K#i+1slCIJ0=lvEeYNT7{hQO%+jpm@=bwZWA!};N?)=`S`ueJz_RTxnX$d}P z&s>*mry;3L>0Ga}4xW5UIqMG|9~>Nd7K^{}GrI?OeD}h3Y{zidq$Xw9@)qQccmC0- zpQaTxHW`~-^{E@WEGem4>avRyFFrG{u2pMw*JY$+<=Yq9T?Khr$t5kV##UEjMpw6x zt!#5O*qm+M%|#1}T!jTWsikY%jBT#wjP*U1RJ4BOI#)x{_Jb#PlmwQzZWR~aEO)F6 zSm$od3SSqUVn|up?rzM=$SW>gQ0juAa#xnO2eiA|a&j{g=pb2^HEAnrZa1{Mo3b+V zOW*`{P5sSZPgRj>vMsM9Ps=mp2Zy>tRz7B}!wkRMnAg_3edn%Phtc8kloorc%21oD zE&p#mc#(d-p!l!jV$IR3OV+lv)fWw)ICt@4(=@50EuhV{Ht)w*wj3PMMzqYSoYu7u zuf5*dyrv?)f*CUPCj4b-@rNZs-J0{mD;u9Cb-`5W$y47sb>sNK=ZmUUVgnoR_Q&KKv^C)6c(hz)L35=S-O{&0ShlpIKI?)wwHE zeJZt!^-lT0J6-z^X@`OxH%f~yl{sj=eW?nR@jic{zJH6h#puu)9zyd#SxN(*UfI~z z=&e^b;HOU4_F#=~bWA<-EWG|gEM`3asnZvpnkH6u{Md==^*vh8nB$pFhXeGEEyv-~ ze~D)3^);-f7*7AP6mPT7H)rI@v`jpFw0vEs);U&kc~eQrsnaDTLobz-ta%T1V(d@r ziwj>aEhm0V&de{C;XmJ$o~O{`frF(j*nTx;Ki_G$k6?r4z!|%}`fUL8Z+=u=kawnR zGcs0WR=0F?b!*+8$`V7#_`0r_>eGtXR2u<5RaT(^asgGxZA_EzWfP_Gap9rnSN97#lj$64f6Ap!rcQWC)~P*tCRSIt9a5R9~1Z}y{h4c}QkLY4<*1m82~?H6r;B zrk(1#>IcJzd`7=dd|NW3=u*EfKP18|9k`0mN7z;Ljs9H2)qi78XEmnu>eT~&SVQ?0 zG!}dW)AV-1uM3LCvW9B2vNmqY%4*w@m1RE!kKov7VP^V{39ZT6;%&NvT#kX4}uKTak6oy{tJ|!$sRW+uIupI=AlbDhw=i{aIH*XGR${duvwb z`ixRIrpAV!d3t#G`0?T4Bd6f#dwy6O9{=uByLX>^WzPm}1MEXaUJ;DKc+bzz{Bd^W z`VGbnuJ-H=U75_g?DdJ)&h6>N>~*iRW!X#17nZxqN((ZpyL*g1uJyTH-5I5DSghRS z>L_gL>hG*vQ0b}wWUbw}$+*eYowvRx(*e0%+3V_b>^$=9aCKny_^qmnTeZ$jy~bWw zcR~2NWY)8?-@U#due7RmLG8G^rpmphuCL$N@7h>cn3I}--G#yV69vUI%Xd`6 zcjTJ-+rOQvtLqQwpWIYh3GNz-mxWKPUXip8kn(P4$@*h0~UfX;g5)lQI(3+WnZ+s4u#Ul}+&s*P#|p2Cht zI&QQz)uc3lz9U~XVElj7R{v#{>PS!F53lr%khpBB<}_S_H%^T_?`VRPaGg*ubh>J* zOY@vP8;u)X8}i?IcN2+&Ypz$7U94_`TX0=r{e|@RbH)PZ=RRVdA+vcfTIci zz_v0p_JGh`Y|pFd>Na+}I&-J#Zq!y5WjDeTxHgZCWVIlx-q2<2a&_2dk~P2s*kV&; zZjx244_J?(|KSzYI8=(l>PcmXso#i7g{*R3GPwVm%SO(=et4R!GoaJ84yA3Bt|D(` zYhGQ4*5Pi-@u{?;BcQ|8mi2>oHXb^v9SwHgsI9tGvj(2PMqetyDr>XOUufLAUE6MS zPPMPY4uI>Vb;2vykhf-Cce}UdasrXo%u}c9dTGv_Q_p|bOI!=*U_;3P?6mL_ml2Az zWE?wD%LUz-^Z8z<6ZFo((@tm0t8g-my|EV6RM)^^SeNb7aL3w!wXWv$!$&LE!-kC2 zyt%EW=D9O9HBY@-Q`7oWsPwTvZL6+$xw3v;YinIro{WaO_QiF%4uL4?2M#LZR{r9q z^77G9xB$XK$lLo49bRM#zTEU;^bC+=mU zAJBhn(X>}oQ{UV;apEnPz49L$(E?_;1aY-<{_-V{`ae3kI6WS(Idq#FTGNsqS^S9h zsJ3(}C^$$9GAx}630E=O`=qN*!D>58eB0&E|Y)nUYPR6oeoL&iwh(x-{6ccTT_K$MMSj~}V3j z?2ewCtO);ziO3k-$QNMpkGaiPG{uPZcx-rH_TQh#ac{O3raPZ#>^Iz38XPG zR;$SxYsm`E(lY*FE6wH09B{@ECF4jQj_hF(h0Cw3xV%vQ;X-Na$)J;WPMm!2@5^)f z;s=~5G=GU>%CR_$hnsCIX56WQd_3fgyV~NcF({}%sQ*@9*X4JcY{-D~cADi&WI%5H z56|GCH@L*hiYpOShP%BTm#@@hqy0R!Xuw^=c-5qO(}dhhflCoV7#kNKOHXKU|8IKR z-*~q&%ZyH%aVY}IBe50tKBAIX_TrY@_hMzo%rM*Ig;BPg@N_Zs%v+HK8eB@q%QWOV zL*7Pc_BY>P#j$*477K(joai+TZo}u~=7N}h|NdLdT%IZQVIhmt`l!;1&fH*A%+|y> zbQ8ViH4cXUshS?tJz?IwEfht3E_pM^Jl^D>*l3B32OAA$@`%rPT?EqO`}-@mAg?QC zbANwN9=wD%dfP8waioLT5}Uxw8RX?{%+2gyq19}QunA4?-{?f{sp!qr=OM`crOFNx za*Tz<@hv2{4+_H%VZuGsyemXrO>(P0vai3t_o1baMr=l(Jz>c2>RosFN@*I-d4Gms zKmn>0e43)7FpL-gwq00avGzs4zIh@ziSqi4eV$eL`PHU%m)2Eg9^o@egBX}_ zRWqMbxNx(qFtjcjzD&<@7O=eDSnsjo=k>bs=PnecvX3&jY%NOQwJ^9ymuI@=qE8AU zcu^Y)bKy>Y{P7j(wf?o9%vwXOtGeXK>HHKBPJrzR@Y|yR);huaF7cR02&xzrV7jO*Hx0Y|7dQKRLvO&0fo4tq3Af&g%+)uzK%wzaVbf$Ch)VUsBJ}Ik+Ep9 zFuWfhf3RooIhd1#Dv^PLgLhwGvf`>$C<7eEhP?8iDL4?DZ^*wp6cnGAX9*t656u4} zFJsrfoJ8(jR{2l_ZzFX<<&f>T@)P?aDY6*AY-6^;=E=!kn0+@ZWykKUM6{Fxgj=XN zYSLKp8AoW@1{5=8iA@hm|0*qE%V1^#MBi*eFVGEM)-?gWVun7NGF$P6#!2K)2~HW0 z>)n=-fF{TlrYKZcfSVf81<(hY$JLy+CI=ghUx}hvCPO9hNn9Qhx7y0oOml!U8+^fnKlMm(jbdlP44>u>Al-QwkVX=Hmoc^}TPrG*a0$i%tr%w;9 zkuKduLWBjb+O+SQPKCqwXV{dkUAQ&9Ghg@Gs&Z9525jBe_w6eWusB-v?fCS~!ZWOV zx-)Yr_p)}u<9AJ(;qT{4K%;cpZ_T8NlH`Scu50kvPUo1nada%JR-loKe4C?pf8n%? zTX%N5)&6^C!jqp}GmuFm*j3@{>oufI76vbR*#F_lg{i420V(ddhSrRY<` z0wEBBj4ypO1Q;YVL<`YECqhC)LedOrlZBPbAJHC}TD2ZAKzBlGM^@S+0grsiJj<6a zTZW8F1&4%%ul8T9g}GOUg{@wlW=wNe4(;BOi9BDXCaha;%RmOAkjIcII2cGki@F^h z0UQGG5FQ?(MQGt#geN>TDAkpcu&ygF>v6;5w;uy7VF*x!A;QJa$SCL?W0Wf*EHWxG z4Aj?C;yb$YZOfMFFa#PU#uFVC7&Q@XF-JrOL~79lA!$KrH&PQidh+v7UPMG>45U(v z`3le=I+|i^!rvHT9E22sMKED+#kXc-PYl%^rv#vg;1CKu=C+H_!b~M77tip$eJ+bB zEvu}6v?k4r*%4#LT(Ou@BA|=B*_Km=P$bTrAC&*QJe#esx)7y{QpNnj6vZT?dBSBK z_)Q%}n+XMGF~1u0>YZ0!eedsU3rR)A@F_DueQ*ZTu*mdB0r7w%7RyM`i0jZ(m)~7$ zM|lAj8hAnx{2^T6Z6NH{U1}YIBq1NVe5I}cHz<8gV$~d0MwP2Ukw9<9Q}e`v_^U&M zZ@gQRi|T#BkTPXddB^}wFRGJOj0B8~JIyv*r2Wu{5e-A;>ReH9xTpaw&`i9S#{$rX z%Vlt7Qmj?k8tB}SiG#8GkBk^bCJ*Jtjrfm@Gjmlg@8dQoAQH!Xw?yGtV4}e--oaoP zndqye-N@`Q!NWZ@ zRF1#DJ2ZItN@X^(TjCPp#gZcvA%Va7CfZI;;eRMvh{VYLI_8c+dp%De^Y2w=fv>Ug zWG?cdcD{RnsuisG0w3fT3K@wxG%|8<@pqO+fmxm~Yu^Lbps|e!?14 z0Z7kr=?8k=Y-qka6r9)CnEB|Q=D_AVO*Omr<)wLZsk^Cg0f+t`YuxvRUQ-6~7P~tC z`bBlO*Oc$rotq~7SK#WE9jSZji6zN#+WGMJOfnXKcESQJIv!5-or z1^A|CT~;|>)VnP^1s&Fr2YQck4JH(Yp74fx$$(i?5mezSFYMWznJl%!YNO{+U{ELI z^K~|d0>s6ah19pp3pbP{0~dmIPQgg+LzSRNr9|e?kb~+& zzs%Qkim z|8N7$cwJ;h`YQX;QRArV$j}?_))it|FZL}4r~)l8#1I|8ctwkX0;m|BIAYp=Y}7D1 zc_iJ6i)?N&-$)fRvrfQ0r{tTJ#E zT`X=YKYA+oT8qiigVo47g{+2A&m+kDdzBX&5w!zxN{>;yX8Da7Qb&K6YkQ;u%@boF-}Iqk>=C2=F+gp64q?B1}d+tBUV+3nvw)mDJNt_{umkCxa}-KY(Y5X+|uxY0?9Ngj>_V;ZZ%fz*lo|k;6oD` z#92d+37I4BM#87ZQWsSB)td4xg9U(=7V04kH`r-}{f6jJe8^4~!I{3ScD%HA8;+wY z#%VDCCWKO8!6Z1359tEk4wyd{GoT85Pd%G$nMmT0(xc%Kj;WR_*^*%ouDM-ZvY{*^ zQ?w>V9|M9xq2&ikiJpX~m<$3miot_rVK-MrT5TEVGgffq=4V#S9%@^T8Jdpzk%qRT z46OcKsVT`B`57qUy6P1&F{=P9w2Q-mMyeOwWG>76Dm%Y86PZE8=|iV8Uf zlZSB|6-v;V#3HdL8(Y6spasNg?>HVVwojnJ3<`Ov5p&^=Y}Cx~%9Lz6NB#clG2&A* z3(uI&==*JfU-68nj323-HUZ3UQeb1E~1j z6Sms0+7PC#z8khWJR)pW=xU&XDL@Miz7ND;3}J2rWg;TNmVgFNR);OZ6GT|TBmE_k z!e|Oy9r$O690MANS{;T!%<71!@bD;rhbjC(Qp9cKft!M;1o%XYa>H!_#i9XszzbrC zoQ#TA30mY`XdHxJq8P1#=fe=?&u|T0CB`UBcRYp9GlrfMBjYi2paAs8e1s%S7gJOW z0wgFCGdzkIC;^mV17U&;75RI3QsT{#j!C?r~~)`Eu%#nOt_Af zlix&yZ}OD6XJY}!Gzbxn4o1mg8O6c!YmWbn26l1aGzNJKy?J%Kx;-cMIDbn zycG~Mx|aZ@)67j^LYpiL@jd|!aSRw;^nmpEfP(3AMjSg*@)hmSzAuTf^czA{{ zXpi`Y@SBYO1|-(F1l2$p0KJ!Z2^pjV@u)F+rr9J^!eN%KegXD_S!OdlTkH+1mJZ3- z{T5F+B2fQiBrz5Kr-f&wxb76c*ee;_NyWym(J6vH&?6j3Hy=6xTnie^ClfkpuzpDf zqe47GUnrpX#?ck_z~Bl0Q8>(z>G$|W_Mu%6tt7|}oP4U0CS3Z8QYh~eNGFee4^g1h zQ=}N{L^W)`mA7~^%!HyaPEz4LFbcmFDZv*E6li#bCn9=`4v>=hDXacg_yIV>Q3~%^ z7wiGTJCGsdWV1OHIF+Zc64&1xhoa!0qiX>+mh%lSItP~_#a0BM?w}MlSvo|2>8A|t zNsVL*LI=nQ&I#K=#J3hAH{MW%M(_e)APGt-sW23HxiVWi$&LWzB*cNOTI^jUVg$iM z`~vk|QVDO23|Md!@k#@@YSC9U7=aL5Oeu7gPN}cRdHBQ-+$7>M$0k_OM@W_6b40(u z+`Gt0ap52^)IvF85B$w{Vc4m zAgD4yXjmBb#NUnOJmP2=(ONtN0Vp6Q)-Pn#Iny8!a49h_N5ab~tnti}$R+_4gQw^@ z-Cz z7LVZsA^(xhzoQJIah&WbJM+=JXy)Is@f0J}h@zCxlaXkRx=I#}f*K+>rh`#Z2&<<( zkoR(;$&@e1f?7c-xrj9{R{AsnM+-8&;=Duw-V*>g z9wSJ@8}D zX$p}o^kvx3Uq6u`(LLXiGp6hC{kGuWi)TctJRzZ4s1`DXIFx_L7YIVF3VGIQCLV!;kPmB7FJwHGerZPMH{2X zNQ7Ml@aW4b64Ur!u$H7FD3X3DZr9-yGQnL0hmr{^9dW$E1B!WsDL4n8@ztd&0Xi12 zZ<0`n6C8>Fb5@)*Cb()if$)^U{Kw*(1b=SRU@#TQa9bb){->jf|L8VRKoyD&1Z;yh4WTCSUW-xt zTIp}m_Y!Dek2FL&SR9L{V~=e@*W;7$TR@lUivojzz=2A;(OL2b=sc)305t?%loyB*hS(jgqbK3M5Cy|-!evPk6M$` zVp*&Opc;7HM1KP7Fj%hhL$wvUS|R^`!y_6i7#Ku;NFc;Cc(^`ZRI`i+a0(p|CPc8X zDli}-ho+zm6i6HZLr)$A;7zU4LW&`N!AHd6D9--e4MPg~@VERHKj=_Jr!ii1GD+wH z*(hvuIpTo@vxqASY!#!sj=iH?i+hHn{|(4scf`w~Sfpf1GyT6DcbF=W!=fc6flBb1 zDuCGtUdTN-K^gTzZAQy=Pz&lI`%oFYlyO+nKpd?`^KV36q+Hc%R4hzWZar{}V(Z2p z9@!4YADm+-3Z_o8U{=$=DW!gi`NkgN4_hTNh5RJPV*oI`NCmGEBeN+*Za9)r*+MCv z?832NzG)ZRJ(M)6%^q>UXk69B63eMc1RxiUp(f`MM8rhlctIhMsT5VB8&L}YCzQU= z*cX$TqJ?2Yow80r$0-_s8^}ty0jNd};SZ#XPz}Xlia{LUDg!#>iw`Kyf#(0oc$5sP z>Kb@siAxg6MXq>qKsbtlAnL(jP>L~120>ng(j0AI8xTfES`tjAcsZ1a@x2<&s?DOxzaM+*)t3IKw1U{!$S8_`wlBAUpG z&_3?jLCYjg$VakMkF#?M!i%6GrY(jPzg^@PXt@aoBQE$3i~%%6GlYgxIw4~R35(^s zl`RCZ=&ZaE+9cW*lkYQ3aumh3p*+;dB{z$v7~#z-OyWG`x^tYIV)Nx4+#G6@0+Do6 zXS4knKB+>~Ek+)UKoi*%pk$JuX-4b}BF<$MYMeP3C>W|7s*?uCV~O(vR{O0U*YX~% zS&6{eatXSrpw_qjj#5!7IbhSpV>5F4#1E%Wq9pWo+Z%GjXCR(L%hLew5f$8&WSD-6 zSQoGoPTKI%!-)1R_v0xThT6IiHq?*k@X->#2^?f8^;_oWl5;N%j!hwoh7g&Fh)5nH zns;?XdvwN0ms=}CLqnbn0gid{NdOu5$|pj@xC7@Fpv_9+9e(&@L(U}d4G27;Ap!X1 zk1wl@t0%DoSbR?tt3yLpAyzgO9tNit;Egft?&?*m!opS|ZnkK(d(~jl_v~d zrb$90e9+Bgh=AXUzYXDE(+d<1Vs0)b&LNS9Daf@jdnv^(8?PJySq5jHE>&6TR+HZhS@&7x_m4f8q1%$Y^+H zrHJS#c)=p0p}lU9h8}i0tQhpt;fx{rF7Xkt1|8i~0&yfL76^Y7_ZAcLxM6Z3fLOJe zJkiK|TVWpAfJ}dw+6!qgKMcSVV7iG^NUK;GGxiEW1xSUA=P55b6)^?hWWc1y3Y7(LaZUI3 zO*-7sQY>^)kbewz?a4+9W@m-+mU}q8kQYr9efkwtPD~UgG?)2iI1Z7~2)4^x-@W-X z6Tk@-05uGQ8>ke4wb+_nKsi`nI(n2==FVB8>5c$#js_Iv9mIVYBt>R}`FE5_eA7$9 z2%;EnHbeig10GtDpeI_PU+lL4F)<5%Bh&z($N^N2)GyIUmL!sd@@at49U3Dn!zBf1 z2JuJKObO$Nxl{-RjQAEj3hx21h1#>_NAiybtu3^Cs&VV7bOaP3MpSA`dlEL%^YDod-+%%M-P_al176t`| zoP1(n6Xo4hjt5~NAN#A;z+U1tmJljVQ4_wy5zD!bTfq2fEdmY{G3J;Y#M&Ulp~#UhFkHlMF32d`Oc|s=5&RZ4md_eAFW{Z99qaUrwO=E zA&425+Jt+EVqJWsG`Ec~%9-XjGQyF1&Og`Tv=F?;y#p>&%nS zr1w?nDzm)nuFR}%baz#nGEMjf3Wfp*PuPZKg9HH@Nfc*ADx}e_G}2OLC~2e>cOw?m z&g>|5rBKXnEEO^fX+}FkhRjGKilit(B1IA&ZOUa;X6)}fFRKj*DfYje0IKu7>+iYu zp7R~^-ebH9M`Mc{iRT2~Fii24KAkoP&z+gzQ3Jp_{U4{?U zIko56xenk*)S*WmF&03}vLoK1eMaNbRTX?huC})7+LqR;a{v!^7?Gfd&$5`dFSU)K zh*R67RnZ@E(w2=w&s)$PgCPWfPT&;cZFbn?Z4R?6{^6Hpw53NT$Rr2n1h*gbI9SZV zxNtD)Fv4o!9Yz`~YwAxcEndnZdGk`a_hEVUPlrBph2Lp!d~{-RJSxW$|2kElKWK1L5j{%&;?Sv-l5#$GW!IW~?ZV;^$_;(UL6Yz#{V^4^=otrT2v zCqLATgg8aUCMIVhGtRU-gQE)R?9Oh@5K1Et)06^aXWybJ1T*rQhk<72=cYguI|2jK zoI_{!oZLs#2y01fiSaHE0m0;)*`1j~hY`uT+>@Bb`Gf;#b_)hb5rj16k#jIC*74Bn z%;Cf4eEJqL{4mvMn=3`F;DVw9Jws%B`3nK@IX7hQ@DJ@_ zj?iIzd%k|+2n$F}E#5pnDh1x+p|;cL9(p4<20F;>cJ?2~$6eUeewMJXO?3fIC~hc; z!{!0!>#KR%F9%oyW68piMRpS!eXVXXf-qf*8$)4}p^#&v(HV5=U2R|)uk|@GbT7`c zJQ(I`fm6zmUH_KE8|fCqCiW>41!H2I8Ui0PWwbaCfXxgMU(BNPz}jnY==s{wz}29# zgrXji@*D8~^CANM$=E6$DWm)=_;GYBFcvexc^pV`La1#S#zhfrUlwrQseN0e7!sZ9 zk4a0f;zsuUZ=03bs2H@s6m;y3Ic>>#IM+}$%(6yGjw1|9o(N6|Er=S#yE1Amj*95i z>HO$0!YAgE|alw>+s>PYRR=6@H|^Rs7>35F%gg? zYT6tmg!9hF9U&X6D>mxOlYR*ZypvN zHCZGN==>b7yfQ|>_47@p=WVGEFfC4KpVz!sO8fH zWbPSADlL?jgbiQ;3oIM_h5!<7-!#i1{w6H%A^_!J@1n8fE-omMMeI>WKx-zz02s54 zDiR`s)4<5<{!Mq_2O+1hCZ&sy)c zf2={hDwZD6x*;p$W(J29YUIwpE)FBTfB|aG90$$dAJ~ev`(;$oa*7i$f1m>_g8&{# zz?z^t%HQ3i5oe}9#e7A6To-cp==hNUC8V^zMFTuSc!QDfnHHlrl)H$ zCamY=SnOTSrB13n6vX+It7VqP&AG|I&)dMo(qMG>hXY+$JzkLCgNSjCnm|!tv4Voy z)G!y@@n4goWO~uew78q?Fil+-Y&$xa0m-lw`%Y3ur!9m?-6jAL<1`%Cnc;~eiED-@ zagE#`Pyl9lsW9PKuZeM46kWt}%0dMQ7*mw;@u{Z@@|!2B%x&fD-H{VG|jk zCDPxV6X#~)C~4DEwqiKhjq^}gLB_%X2Kiq@yepbU3$E(yn8Wjkh#lBHeVd*s{<3SX zE)Dn`>(8=@4#FU^a_zA1YPH#E)*U0eogJPEH4C~LnH#yzk^N=rgQF}OJbC)hOH84;x3 zA~$FBP@^W!KCp;@`VPGh1ktO9k6Z=2o10<_9GadTRG$qI83JtMaTswhIKQIAjvwNbCx5kmJmnIbw!)CbGq5rswr! zu`{diUaS^eLkBi~SNm@Y`0?i$EEMZ<065@fW-9=Ga4@Nb8wExKx1pa|f7bYgH@B-K z_6{J)H-nw$L@3%bkCX;tiRZIa}~J4Tz4N`BzLa z)*j$b+6Axe9Jk=#1{61E&8jPz`2Os0owM};|*!dOlAQh+T>#0!#6 z$4x?y#$n!)*@XYo{emC|26+LUZ}23F&K3U)bwC+5B~w;)i5#7s;K<5iZD!{SI?x24 zAmKy~eKwRYm>MH8HgR~)oBJ01Vzk!7l-O$36-I2K4+#XP{tvW7BIKkeF?Dm3i=N`8 zf5XWz_yM9(MJ*Qp2DMdFQweaz-&nrr32_8KXi=wH4XJNh6a<6`SUn_#9_tbt)T1ge z56r>v1E4-806o0GMqqgk&#JCzEV$Ohbp#!FC>?w7(YoKjp!Tc*5ZPC3=~U4wQ`5(z$0I20 zOw`Rkro1avds+x42#z3g+ks-IG~vzZ8UIZR>t0e^^g{9p zPO|bQZUWmig+u@*q-B3yr6mZUwc!mmF4*8f*!KfPH}jRgmi2qfPTS|SvVXs%^!LhJO>1v zhlNgI3r6lRYWXanv^XCcmsQ5>Gl-SZ^4VUn%KGzg7hy#B z`~~Ts5<`=STc`eduVl@~h@!xeL~gALW78QhKK zLdGHZycut*JA*DN)`TAzI%o?zLK`BYmgBpJj~qn^fi}R(pbfT(PRulwHxYrz;VEqn zN3T-Q#F;&RCNH%0ULKHLM^#Pom>d#SqMQF`56xg{Ftl;;0igF@yN4%YVl)oeaK_!S zozcojMXn3L##nfCe;h|ec+{!(N2^X%UWDO2)7MbHoF@A-X)hHGcz{lh? zhYzp;1UUd3GdwqRm;(h8*N?0mfD69T3(nx6PXDEjiz0S)?rYoJt%n1MkCM(55j0o^0 zDl3PROL3DTm^0}sIDAs~d24|rhRnLSs{?AOTLXV^UV20>FgTqa*%*;Arfr#qF9!{6 zL7#IxqhV)20_f0uX#O=06Hri0*0=^0vE?fw7_Nn|RKvzn=Si((*|h*~~?jtoP^U>XY+ ztcZaf;t>xCM1`K(W!fM7V}apQI_|39*M3v_0jIG3Z!j}S2IkI)HBD`HR)e_)Q1I0&!ZL zGfa>`I*Dh!ObH7t1Hja;DO&@I<&ia$y?4-pomdz$Sc8|$=$Hsx8Q*ngb_2e1I3lgu zPJ&|GZN;3!-_!(|G5U|}NXT|O+@b*-3Ae2(&rE3y@?2TSfmYc+L{y37t2CH%a{%<( zyx!C#SP8?yDXUj0^rxxkEW~-~4_VAm8VKFl%bbkRfhpDq#;oZ~JnkG3byFIWDw*Sq z*?J4Cf?@dBp%Bhj_A|^#+g1E|YTBLNpQ4!jbZ|7S6@;QM7M3y0n_1uJ6nJ-mj!cpV zbaaaL^(2Ec6P`BTi#!Ks)s@!P9>5gU*nS$gnw24obPUXg5Qk<6H(3E-^YqZOP81tM z2kr2o2sOo&4N<^B=KQ&Db226oA8d{(;R&fKwzyhTUaVvLimDo#;)&ochoOv?gp~z> z%4&hsvPVg&KLt19AOuYL8e{_-#W;}~5pNoC2`-R`WGJS97o8Nik zE%&Y7+i$(?zTG{0?!SucoQC|54=p|PPi7}GWbfL<&TWP^ch6rot7MA2*DY`JDlqxl zQ$MwNd3N$*_PNcwANk}LesA;g+KEfqZ=Kux#J~A63wBv;%VyZ$eUrzw&Y$1>b+X?r z|FyTyx@Y$uE_%*6zkg-M{?0ewKIfh5oj-TpzdSF&kjXoD z-aFsBaQ=dS;ZnW0@_IYpypVjC#8*?V_6~MfJn`7lW4&Mc+hD)N6W?0;R_|~Bb8r`n zztnlD`=5R@6kL4eu4p{|Qv0Rdzxb`&zN+uKG#9oqEWm)3@=)l|ylVDYV z^2FH0gx>3;u1Bjhw9g0XN1PF-?3di)UP;xRq?>S)-xX4x9hd2EY8q|?J072441^WA zW4lBuQ61>+Rdz=zHh8bpEvM4yRMJlZsRf*4)4fSq1RaH4Usw|D6XM=aj&WKlj8`7mR8M;nM z)JjxII_f_uhR)>c3_hr@=y8RT+t7WexK}C`OJ%40b~>BQq~*vky;#cFo^c~*%AMR1 z)gT}5f8JHykt!tY2h=N-M?xciT^Zr^NpLiYFaEJBhA@q0N9Yym1=7r&xWELUHk2Q$ zR$O}Tl}A{Dt&z$I|5vi}b5UV=NdRb1RXKJs1bb7jV3eg_RShVom8XhZ>FT~Jktb2~ zEm*O*s64o^(n&>rNjaZn*o?Wy(4DGV>Cskb#I0;H6RM9L$gvAzDWXPp)86;1C>^hGq&@%)NW%pLJ6{gH}C zJN;2M=Fa$}Ml3;%8U(Sas2$^uZ?W1sC=gt|x)pcCQB|iBs&1ndR!!DAGoJc#C(j~u z=vmv;9ujcWty{fdM+_2)dQQcyp5>ZN1YPOYOv{9+X_rmT$Q|xX`r}<};ZQ21*^W5X z{YrVH8kT#$`qj}fwwR_UD~+fGb%T?^{?r~*u$~6YWCt^5tfD^u`=j4NPGX&5pi?t* zI-qonOCL>?-Q}>mY{JykTwVI_QPHWM)xn3#R+rsm4L*#9WW>GgSp7Dz~o&Le+kS<>4C#1U_om zgV4rtVjm`KF930Qq5_`);f-Q_Y(eJ9lx)1g^m>>Sysc3MOg=UeuGhKS*HA{w>44Y7orp!!l`(+2lQkx=U2vzV5;=A zCHe%Ak@!eGySvG11l83&@fl|45Z7c1esCnTKz$AM^$FUd0e0^U2Z@c$rf?>AdESN5 zF+)9dya$2BKneOB-zJqjI&~+%s{sRi4gKjIySujblRPZM zq$YYGPs7eEBxsfnFgPi)R+O|I=#8D%f-oaZO4g%Y4TyT)lp{&Qdu{bHU1#<^Gqdlx z0=)i*-}{qac=h3zzvzB(@9#GVY@Si}0eJoLAN|4aUY=dI?2F*_YXNw@SbLFdf!AM% z{er;j73trL5D&6zN2vDyQ+D>B?mM0PCx@0ull>0xdN8X*lDzK)ukVt5Ie2}S?90LH z71{3sUf-GjPVjn=A5R4Hx(Hsc$an{MeP`a~;Pr~U1Mqq=F-|We3cMbq#o`YyJ>2`; z*Mt2Qi@&_|a_{S3KDhg0=ZoDx_}>Aqy7;p@0k22>xl^oAAk(JKthQ>AR%J`7Z-}9l#}Ywh7=TsS7X##n}r@iPewn*@XO37i0>erY_F}>ZD^!hUg1X71!Xo5Y79Qmt4nV>wnXJ#l_hBSd7mD-2I6|~;*(<#%Kns$`!yq__sUC5x zV3wc>xGr5g6X&6!o*580lsFYg0@Cut{>*Ws;s8Ap&ak`zWlmr+1{U_44eRUoTBLigvj z4oU>r&Jq3Z18w)lxl z9!R_iQ42ZELK(OX0ge0GFm%eHAzd&PJFmf8d_wa&oy-?Fch)w!gf1F$8EW-Ivx_DFaouB%^;fj+t=) zciAY~VFBFLIbolHpDKG*RSj1CEYntf!3c?VF({p}0rC|n5)|tT>+P|sLZExL=>CY- z5E#fV0zYeP&?*4GuW~||1WRrQb&{wXYN~P7_bTTY0mPT~1@$0;2dLv1!phh!Gw#g! zxf#$XK*zdtNB0cmtEwqa@|?Y;!AL!q;$aY0#!@ESlDU^2DG7Bf0gJ#EuG0g(fZ9y((s#!DOi7rz_eR1eb3cuD( zdz}+aKLfRd7PR5^M>*!EXE1CHiLt;p^rZIKTZ|$AzZffcj#{kE@F3U~h{p`{u zsSpe;cjK2a4rwaeW5m6i< zf%Ii^zAZRzdxBZe0RQq2jS0K+thrW2q1xj*&pbbcC=wWcOKjaBG*ZE^FdDaYt$#yf z#CtOp_OHM%kYCC<97&@P?U?}jvIIkTLfsf=GuBKkZLG6KR5i^|O%(mrv_`K@4lCAN z0@vw9V5}{#K5bX-(>-(rU~7*f$lS?I9Tb@hXwjM2!%Cu|0gKsI=Bce3wY%J~QFwZu zu6egJbE8+6jUs<5xEF`$*O`U(d+=jxrh}#bZI|gs%en{EHAkB$daSPbngrWtcKSWj z1Jr!>jn`iJ+F$%D z{k_?s=C@vd{k6aO>#t+;{n8h%tbLiu_lj1(7Z(55ke$_p|M8*yBdGacFXp{F zYJQjO%Te>YWM7V&ugHEE)O?VCfQsLVn%|j!5j9_t@eb7d&b-S}^A&jqsQF^zWvKZe zEf&9P>8{>S{b{h@V)3smeWmxOzkP7`V&}!~Z~U*IW?lRNusHr=`^DYg{q<|X#4k2q z?EdB-{Q8Qa=C5u4n_I3m)O>C0+P4O%S!`E~RN~Vg@c}7)*?V`20Mrs_IRskXi6@d+ zed94F=EwVqu^3Sk_E@MSL~m>qWCkk5+$x0V6t`sb71B;5-K2-9n75MoSX%l}kmh=oPwwnOJsS%$oy9Y+OkUJ>cA8n}{e`n|nxV!P@=^L*8e= zKy};DHYzAfo9|YNS3zCBPGncW?0@%2?@*I=T5s*T^?dF&Vwi! z-4U-AjXVrr20=?u$Sd`dskD=JQUu$GNtkUD5N%u!{)+)e{6#EM+(v>%7)(TV%6lcK z3l{CCd3F6}8pkte4lGPOh}jH*{ZxjvAz`R2nFJs*7%Y_X8W0$iq<=?7G8yc%0-^5g zYr?~{0uV-Oh+=U40fWXSFHneaOf9(OUBfA5$k)pV2J--{Ud`46MF+Adhr^e8?`W5CX)yiXoQ9 z0%Z0^y6j7vv9;h;Frgwu=u}H3#LjGyD<&h%Fl6Q|nd8is99GXhm>(jHR}hB?CUqqQ z>|lTAhUp5tReNkokhdW}!+)yC#H;7o^uizkkU>mAqUmX1is1I1&K`EvEiDh53_^!0 zs3=@ktC-xV%K5CpSO(QY7c8JCvDR)QHzJ+gUfOnQ8Ld@6+O7qn)Tbb7pjWtENKRiw`E zYTd`hs-QPm&sPEZdj;Y!RDh4|A$CtNW>ZRZ=y1oFM*>ibbwI{Ih(GR3dsFA^sF<>@ zqiPSZyV8Q#?K-e-B}`W$4hn_1LV%Po#0p~?-~w)fJI3^Q{0=i6kXGzMd%~%7Il{JT z=C`0**$oA%JUs(XCb_h4eg$K=r)H%U%>6|PN{smZZvJ|eH(B*aOstq*XLYpsc2HN8h*mN|t0?auh? zK)ZRO_rc<#f^ePCILoFo#MIHBuf8C@2X#G6vR!Q>?T5_)HxlypM)w8VQ503h!_qz` zJzJfzRRo8nQv`UAYV3P=3hOX^qC04b7_1tQX&z4qwqpkC0jsg-sucTfn`+d9L>_zy zDZoHw&}VJXjyVAA3&|2XqdGMwtT0X`1sPC{W)#XNgsAxp)JVP8zzE}x%OMghJ`RK_ zy|77k;C&t>V3fGi1hg3{W0gA2&xYsndzI`<)eMrN6oorc8LnU8U^m=CKnhw7R;|Y3HmVrMom3UG-KjtgevXURhlu zKh$yCUdwH}9dE^3jjhC2{T04Sv=rn!6lWamev2=nIur>}B%#FicI%)}NZ&H@I}VM9 zS7OSfjm=KGeNe(#^Hv?&>94FNxNs@z*?3|rZhLpoj0(9cDe^t?U9O#u-|jM1rojig zuP7E#F^bsaU2EKHcU$c?lXe-!_HZzPHSYGI)k<{5XHdZ~ytdPF+6=~{WH&dQhZLUX z5TfHDYYch>McmcM%63XGduJFOjjS{%pf-AR=d4CoHZj2Eh6}|N?yG9aVf`3e#E91; z*U9YD(JJI$%g_Kz0XaiVRf9P%`&~Md<->Wat7}m!5rWt*t@te`<)+=tUN$#8yymVs z>uO;zShtgG2e`$}IBAOHhu6LJ{WXSa)OP94KUf`Y7ABDF;ylOb=cO-Xhw}OLwY622 zit^BH%|1(|rHpj^mG0`wN-_xqi>A-&`#Y3tu{S%6(XnyRJaf=K^|k6rHx&UuT}Z32 z*1`&g*4?!jV^|Hbi?j%{z<+@?gvw20Bt9kO?5LlU?-FI*JEpO z%_GwBK$I?19m)@{d29Xkwb)vC6|w}&Ob^KfJtR_ox@!a_pDno-(Et-pGOi(J_gIS} z?WR_vO|B-_*x2!elkk#!$S57kbaQzS+G>~_`gO>56Om+y zyhvt8waVqywe*^|9%Mz6UMigSGhVhkTmaauCD+{by^|uizv_U9os>sy^%>6Y=JG`Z z)LImfV9<*qjN4h%sY7<7Pv-oqVxet*ouB zht|D=GW){eYKYleA$O=tv5_j<#XG4z#R{hS$yAiZRx@rcG}J9Hq)|R}Mj6o}m3Gt0 z4+mdY2=i^o-2!UDXs~qJY|*qw7mwb<{~+lVo}JY#)z&NsZLs~>*}CZ?p%DtXkSkmiVAxRs*^jWpOge>rewgoNP}(0# z4Wm>tC?w^i1TUpzB*NY@IaMn1%`Pq7zSb}~9Le_!MZZW`z7T3ac@fLVE>Kf%yTl!DMI^As+4xLNE8xXbVxk zK=v{{VgZw}+!|72=Ji15Bl>kgYG9EzonpU`&!~9Oh+;Y=Z#KZ@j*CNKkQ66Ml(_Pd z9&LLCk8gzZ7*Hbb7Qr9x^ml~NW{An7 zot6?<}p2;DvF z$1A3^N8I9t%Bbk7cQecrYPGF5#u9WpcqJhb=NF6rE!@0RQJVW*6$6ujgVaUSS$3LU z%WH=^iFO!9PUm?vUY4ZzU^K!`xlw-fapkSpGHuss##LX{VWxx_1R^noi3AT(q;30=pDCEA4nN zj)XPeZ+8-%on#6@o-fd8Vr5@YMYXj`KqLkm;GbQ=IC@C0Kz3_AK@a;)j5{x*flyXL zYh~-*5)SgyKtiSjo@3G>fV&3((db#i4Akql2|^UI^HZB($D!dBvIMf-72phe1jHSO z{9Emo0UCxFPT?Y^Bzs|BsMrDaXdGHC53+_?Q9+z!Y8Pb12hkwCWU>c@1!roQS{4;? zQw~@l07!t5{@Q9xodV{1>|$tZz(b&77hIdCvjph5-)6FVOh_9b=&PSfhEz&W4ul+{ zD@{_nocU@YoP_X6G#N?l5c(+GwGtc9S44>ba=UER<569h>q0_Wp)8+m}OSe1{guEfG|O# zC=j7LT*NxSJUy@^x>5o#6iFpOAwGF|U=B3$EsyvBfyE?HO27?pSE(>{p=W<(KY*VA zA@GEk>*j%eRY0f|FcCBgkd(BC`+%I*LM%^sMF=y%RYEDdYOy*B!t~HB0?aB%<$=j| z872US`NdXxs{vjMKvZN1Bp_fjX1f!GCd~v6AXWr$0i2O{$!H^;2^_<=3ILm6SOj0FxUaIO+J<)p)hD z;9D;1QZohw>gSRBvSi?GWB?!+Fb=3@D4PrC;uP@mkpc(_YaEaU!ELT8AX1M`1j&St z!juS2l4Ea*#;8UlbpXUt!(r-Q1Vq@c@KDMgz$es)0cy&R78EQxDU+k8*bMycGfok( zNbeCr#(b|JcN-Q3EIR%Ss0wTBE+|NCIJBWsUcP7W#+~G|=w@a;hX4nNVDFtNm-54c zUS1)T-!Fj92!_TOI%$SZLpVeXQ;X+P08PU&uo@qD*KDTDt48dCu*chA5IrlZr=vedQ>RpbBtuCQZ?MjV=Cw6ZaBpAuzK)TkHG28ggj2eaW3YE1c#jB zYr;2r4p##J34&{Q%!W71DDZ}wb)M2be0ZeFI_A;bP&EW?7LOh~v9!#w@|HtO(Pek3 z%Ad1*DcxBfUUHY+W)?gWUfyj|!OAb9C5ZMk$Cqg0;j-9a^=2Pp{# z;**+cx)*btmd9PH8DT83~Ma$sTqZVTq)Y4tWReH=#gJ`$cd1nNqWoMLJX3NFtsG95mNo-{iOq} zf$;;JXvoiNCCLsqqY&dF(2(36l8w&*U8LC;K_W~!p+;nI0cOzt5cZ~hfyyvQ(Pw%d z({YmfDLV2F07j=nfk-n99aO+$ot$M4XyE`Yc4Sn_u~?8Buq9h!OEmVDGyDan5*Ziv zvDh$4L!2GAm7}TdlG#KOY6CM(vq?o8vD?a!?JNa2!b7lQrr|7-4_*_p0YHQ`DF=E5 zNFtmx@PdkNl!=iKCLUxXpre=alD#1H17Fu5|TfD?v<6Ho!j2Bd=SorK^~)R4lC07|7IkOxX%fmCej zc2GNnmB_#XE;Vh8mBG@3*a8Dk6cOB)z%f8k0bmUl!)vDuI`|kH3_8$4h1x6w2%Aj^ zj4|myhw zeC1;wVb?l(86hVj$2Y*8tY<}{ff;AFNTKmbwrzi`ssR5X>?BxmJh~i+b`P;9*nm`A zR-g?79|JZF@wLx>F6*1kC1S=4kOOiZ<35q=63hsHFNfU-=pcOH7x2f)r6DsA?f`Ir zK4A`?O`3d<6y7M~Sdb4wKHk9ogY0+ABqJ+Iq=4&Y>}}=B^dbB(j2*_1l0Zf%A1Vxd z7z)l(#35pODlppghe1h_;eLUaG*VlJk!de*9AGdoi;YK#D592dSW3xNZc#q|)D~c3 z8ZeQUl}%V6lgHs9e+N>Q$BqcD$3P*}QtTmBLja!P_;4=oDEePx!D7M-EX+}A{?b{b zky%W}843L!WbH z`o;L;7BKvPC%|i<6e7MTEJq7q!Jp%cVwBxIB;=7VgbGllz*jl+xQ$*PO{?eejWG>b zUijnvGl%d#mkMP}HEEDXU$3pwlgi#qm=~%9g5JI+iSU-)0h{lj=ypkvK>s__+X^&g zptIOCBKm+Kp9rI*p2y1w&s2C|mgiAiAl{bx4*u7pta{#yCvx{FT^f`oU;=B3z5?O_ z__p|5hdo>@LykSIthYKJI)uwy71H_MaK7La@M%|h4i~%zkib~PbLRjYJrHisEAt`% z0h>dIMk+xqnMyd-6V>-r(T~Hc38|9U5jr{Pm)zi<@m7;7ekUq^gEOGaHS8tuIG6{^ zTZvEtdn=kN3{JHpW<-F$qDM!`)KwH~2<>^MhdKlMLUc8?vM+x^q=QNv=&=-%Gb^@#r#7%*Xt`5<8qMb*Nj+oQO$4L@rr1}eyiW{htYR4FI40jeYl26R(WJvORDfEE+GTn; zaz`zt8O4}VVi2T@4FL0mFY^Q?3;fBc$8gL#1IuSr^3yr1c^fMAEXQ3*Ub023BpK`_ zDtYAD3d!rnMF^$ZaxpQeuLK>-hoe=3>H82hrcT=|Y7_&6{8Tn(k1oQiMGaPVAtS^f zLpF;^Dn&I4wW0(pF)S*#(ST&~9*Q{fw4tH;%uXf;b70~JBqsz>lMrZ-Sg<*!AiQ>) z*U_*<4|$uU{+mZpGR%5W36C6kFeMyQ>RQGsHj|u|QBoxp*_2k^EG(Lw#u~TvRX1+O zc6VR}qcUb5$d#}`KmojBvN{dSZfP<@m;^LJS@PmCCEcX8s$$s49K%`NcKLK=~2t#>joanPh$)MNw_+~`D@ ziMzJ9eiE}&*2XJamw*Pc9@5}4JISV`H(7*MWvH=J%SKqm-cS#+WSNoMl-{-9;;Yd* z_9!fBYz5z@i%AR0aRBQnQdv=dwW|tkK!F2AhwA+)t6+<*1z}sSmg?xaQ|t(NT7&fu zt&G;YG7(JCnU$i$sroJm0pWw`EYX>-;}QW?=w5~{7P9Wua=g_wQjgTIe3uAinV4i- zLiKvImaeDu#kN|gxLw97jNq%+GPQU;QH$`t6~fAj!^FU0M;RL{muk71>SV~l*D<_Z zEF->&n&88RBefi#ikB&Rw}i!^T1NQ$^-?Xr;1`Kc<{1Q;X?TTFzE)cBid`%sqa$Un z?A3F%3a_9y)aYv_^531!znHN{iEktYG z62Ti)>h%>?Hop+7?b!$j)+)K>Io%TlV!>NH4P7en(uipi@n$J4TyhW3E<|cPO3Pie z#OKuX&hqgEz9XrW7%6&v`Z#^31vUq0*KH=)C{fO20c;v+M&ZaY`Jg-fR%e)`B+#5A z6q9Wme9L82K$Go7rVmyQ%cQF_#!=*)ggbj?1jaJmV(X%L^refwqm11~XhF7hAI)GO zF@hH8I!a$oGuP@j<%(1DY_ZNB=J|Gq@oNB)=8$sY*o_B<@+gxb#Z@`%&}oJg4M2Si z9RkMIO0y@!K~f@^7-n%8Y|o0rpeTdhs#YkzQlJHxD5_ovWst-urH2BR0>8#mzPxL8IyQ5sb4V$J2JB~62^CcrhqLNq+%b5!T`->KwMEzxM3YZs zBIv;MAgg3l3J2n4kg3H$kHFj;1X7F#btJ8+V%x@r<6YLARtO`v$q9;-wPkDp)17!= zelJ2IDMs>yNOV|J1*02eWMHdv8w{DCw3w)cmuM&<@kY_sYYvkq>$}P;xWp{{ z5%#%OAi-aRi~*ZvJULtmaZ(W#G#}X7VX>`vJ7x`~Nkwr+L5JrXZ;u-3BrL&L4IK{2 zVY1@*XN02I!mCj-#Nzh^uG(M$%TX{;s)5<0H71!9S{Z8WO|}9>9*HnaWujRc;>c`> z;r3{wD;7Hi%E`4u^^pee$}FN{O~?VBYRBu52Ar}Hsyl_vfa7wmWa?+Aje3TUvBv6d zBVP9k=gkf~DKyh=)aQ8@IPU{5?1&j-Hm#4>Q+jh3-`0ggy7?V>?#4>RdWui6M#&4q zBYS8*PJSEZZIr;`k$Tb^N!1eM`Gqa9$4Y5ztjedQqOkj6lD)!av05Fkg3v1!zG4}I z;g>BPF05p?&@b7is3NuT1>VwJFz#F~_yxxAAOxy#UaZI_7~~b!TdBvCR__%?#GxxV z@x9t4eAKV+mNhi_ZC&)H8vIwIcSiTsm5=*ZYR!TMp!r1Wdo~6%xFDm%2txdY5s6ie z!3)xh@Z^wn&>K~9v{)b|Y$^RRdWsVKfDU!IX^54FCyDzmN0u_!aLjxametJ?qf1Fl zOZtn#P@LtoS>)0bl+B11R5P~Zo^Y0AJj%!p$gx?L$q2(BiI}e7YnTz;gOIZ3S%@!mZ3!bVEEz58i#bTu$$bq1lB7>4?FR(NjC&eDgd8AU8ooTEyxLDG# zJ?v%)YRg+H^Iu{qLG1{ZIh!-1&cZmu^rG&~;)GijtK>1~m~+Bgij(Tnr^bOfvbnE5 zoaLPp$F4eh6?Rb%dPOi9%IK)}_m}u;dr(ykCpA?v>3qpQ5n4)9D63if`o~+&F&wv< zXGpSj_LrAZ%ve-(NYuE(TqpUXbdHW9m|(GLE)}qQV(z1Gaw)dlTUury8e)uouzvC< zs;g|cS>!jw!s=dAnO=@^?c23zorMTNr(q`IX+1TY5W67C{AK3Ubyjp(DjD@;@{;3I z3tJ&2x*QikZ06{KA##rzN0}_$s-@U6SYJj+HW##Aa_KNaD&Sg{#}ui1CypOK!7k8< zW$zti#TlrXi1$w{Y4>>0ge{0@LNHQQE9%R}teP6Oo_TC-T}Op>IaAshV$uc58iWsXvv{9rbkY`77wtBS11 zGP^ZGjYPdau`J@UUIm&CH?noiKNHLG<>6+(-tZfRy6_|^q2*i?Jd9NiV9KsbHF@9i zFdyo!r{TolWPD!ZbQ^8zqYGJZCcVK7$)Wx@c*Cv7FJa=sPN^_bfeizRlVk`IpDUCK z`1Ryb4pT|EAxtzKC;O2O!;H@5{x)rV^XukJw*#H3L)$psaz( zrofc0c7wtzGoS)6QD6^Y?}F##9NAagMHN^SL_G*11ThQf#h4sq#_g;mm>qGhHq`?Y zgl3Gd-Ucop7Pm6{t5lb|F2}WC3A*n}iQk0gyM_|kIYdE^pi9sb$ZggXQnQtG@|26M zR2G6zV15PUeX0;2vFs0VTLMtx|9likQhHfvurH zF=6&FRs`K?)P@r;C4^}qO$!Cg6IogwQA;ul<>=dA-CtW*D8$~{I=_mY2us^$46^V9 zsi3WOG}ngEl>!u`?7D=Y_Se?K>k*Q*>>+gNf|8u|q?IJHW>9}<)vKo(LTxfF?5?d_ zKxlH+Zzw%XMeG-AU6L6>WHrW@Gt&)X1lFRfJqkM~dp0zO!tjZ7!&fY7hykc6+Ny`@ z;|+TD*CWJiChH~I<(r@DCoL9K){5c!Fbt{RIO!`o)LlbWuc7Vc08*r^)$<%wzn%fj z^-lup$PCrPu!K~jipuSQlOpv5g&mj;sEhk3&@geuz26X+%aSJLI$HM{Y3@sd>l93? zM4NH&qDy*&dzFun24@r)^DZWaNzB06!d56mhhZ9IRJu@NhVi--h|+?`Z-l>;m<@SR zt_{Yi3ohc8nyn`_CMCpZg0?bn!UXl5daPCkHwM>Hu2UK%=@G7FM1V=rc9rWyozHXW zBPU4;qyV951{5JPL!~5B^{JHRI>oO`!w1(QnQRnE(nX#mjpX}F-4oc@ki1`2Tc>DDJ&YnHDnD7T1{feM5*O3YRa#)Tsl+y znWFP#cavu2!q=JAAV(0@g0*1WWE+pZtcVms<;Y5?1{fq$;t~@lvvvqPv*0zS!( z7$oor2jif9CT(T{Mr!gz;rtj%+FPwA3N8dxpp~ZL49e z1p0=FYbgd~XKIS^ay2EUfrXg@E)p%uO5{nGnk~bwiIYXFA~H=VlRZm@i%5tps(nd= zFa_0^yP8~N7jX~$XaMUG*Zq}-*GMi(a;uOOa`y3xyXcBnI%M$>jqDGr-F1m>wgp0F zF?3nRW{}ZYX*3q&i?A`O45ID!fdYJJS3Nk5IKTUg7KMl8qfNKrFGd=4lwh|ZT6M|DqIq*&2RAY{-MbWq zfi^t4h{Bp-cXsbChAEfT?1BUhFI_KNrbA=7dYrX{%*gAZ<9DoaS=spiyk5G-Cy%J90Xd=`I~sTT-(swC~eTCeSIG%V`p%%j}wx zy#$mexZ;G1ZfiAA$W1v%X_odSRU35)ZGB9d#%0<$Dv+sy(&Wp_{T2;LPjr`dqv^)n9ihGI|KFI!S?9~$~k&C#E&XohMJ9!TO#uPY|q}OOGVO9s3NoDp>z>3m|&ZT^bYhpn#amJU&QPO0w zR)11GqlzIREJzauJHx4!YH_`kL!+iVDz=2L2_6T-9pxG-A0h}yBQuF?!jG#+o1;h9 zGJ05@7(EBJI&dMid@@Xm<(dY2K!#|b$XnD~2`o5%bASvp?Xxtm zIoZI|*OEC$EV}J2PBkR#5&TUK|Kcd8n4!YJWd?y?_^>y3fCVwr;z?{ZavVYfg2)+) zz*mwmCc}aq?nAH>kd7Jp&@@q610Xoeb&k_1cr-LP!D0)+^#K?RQ^upd2m1&IJO$Ke z{6uIhWq1m{sqYPHtN_r}p3q@(fE2$M9SZM?1OkJXfMJrf z|8KxhU@-Mh14EOLxGV63D5PFqToe9gkBG?$ixkC40YETGDvJh!Q8}{pXH5{xcD;vA zCm%(W9KnUGiEQQg(o(e%<UMjXF+Tg0+|#R6wT-krCseLlukz=KvZVGrF!*P~>44J<||=FHDD{gj@EJn63Y*HFngHD06FF$JDB^)#Rq zG*btAC)Y8f6dSNx10s4d(ZbckEBmW_1jR72p|yLTEP$~YWzgf!rd_v%?wVQ<*IY;4Ml!*mi{2WuX;sf4&!nyi5|E>%^gLO~_dkz+Pa zC1}hUdJGt%dT|+vSYB$7mZZfnttah13e_}z;%-Blx?*$ic(<{8k?Nt$m;#^cn7#%=qAg>F z@MmexP=WzkN(8+M9YU6i#T)YfU}aNP>O_DJs3PXSG|!! zlas?zdY+UeOG4MADXN9*G1B%$FlW)2y11g4leg#|aT$oaD3+KM59Z9kl#Y0UR4}<1 z%uVd$AXOwu1h@p&Y}GR6SI~Q@Mtj}tYk3s5W|VlxHw-FW*3!Fm>&NMJg!uj*hK! zKK&sVLkKe?hBeJwDx8>@-xy`GY#v=own37{7}>#uy~a5A>R%e;IO&qzxJVlH3H|fw z_k2OLTBG7sy3p*d;wG+}BMftun;+5*kw&=9SUst@~8&wLKRr8XG~mMs$XA5yKa#SODBW^K9$C$CP>AQG&)>d z7`1#XU)r&l2hh;_%c$dGSmL!L=pP`AT#;(9o zVR#tU7xA#mfs}wwkfPJb2_Aqp0VzAbuo)Tb;c?9I5|WYw!3Qx@)`JmsY}>N4u)WUQJcj9b`m(%ti;7-jTd1}l@u})Th{km1;z{m3cg8$70ObN z;zj~e-*5Pd@yQ>!2iDyU=&rvCA@;XInmam<|bZcgXMdgaDh0(0yMo=kpG&QuI zv9&;dl&6%JlDroU%U#C-&FnP`Qhi=};=EVN5uPV%p(^6dF| z&0UK?c*wGlgtiGSm;5*ioFRHBNU&5uE-60Lqez|`RuoUK5*z^T5Z4~kEGTqwDLcxA#2fuOReufuDg54CO z@ASfSEzWOhp-Mr2a9yD_T?4YobC{#wiqnqR5{1){WthUlw5h}bzt%2doK9SQTRpQd ztD+I=%}`XoM+Sc!qJ{a|$ikRLfPTbH8PYl=j6iO8VRZ0YPzyeE2k5kJM}SHA5~D)fSOgGs6#$i?6wj5x^YivSyPc5MfP9x}32RbZjuD zrXHkfv$Mp7I`TbuZ2l_ckYkk1f!~7b3>$KoYeZpIn}KXD)}h65`!#1QL@!8W zYRmF@P8O{IzgMtY!8GjD;5V#jivnuz}4%h_b%D{xBs0Qic-k3s|P8PyRtm%Hje#O<37q8`Wo}?`yO4o@@dZ-T2Ox(>5X5L_); zMy?QCG9Te9yCk?IrczMb_}wrM4O}j>6w!Jhvm_RDeNkp9pwvS=35&+akd9_Yi!W3X z6E%$7QX;$iKyD3Df)gm=#ls1Q%bZVLUn#)KmKMmZ=~|3FlLPq`Tvu%SL|I{LIl+Jr zgxD2{;` zu26wKx$D-aRR&CUkm8UcdFTn$8-Hu}^3y#4wIa#4wXP-_%o=q3=7x(-2O3CaYm zMEUa<^6DoLmI(x(&S90wB^NZT5KsW2?3)lAh{+5)A$_Hobdj5viOCG&Q3(!b)*8?1 z84=YRNKzO8LSd+}^YJscKm2n~-@M^&>^%SGYv26qZ=XOC$nKD6>^$-8J@^0cJvVJQ z8{4P<%Qye(Prv*t1>CGspQ7kFZ(R4><5#t=KDDv&;P3wRmtXqrfA<@ouQ%#%oOte; z)uU@SZruHaFaP#${M%pqpMK>RLHJ&6uKvd2v(Mbx=v;sEnNL6W{HK57r~dn&{BaW| zW#$;Fzxni;`)kYB+;rPb>nqLczVG2j?`3(UTLh5VscqNq{orGbV<&H9sJo}G`>`93 zTvZeNgNhud?W@i_bnqFU zd+_|H&e$muZ;rBI-P(5R(bIP{n%8O#_HO(9&NphKmKUjS-~HG_^(P5aI+P|9 zoH$8kCU@xzg{$s+=z(L$)*pZI|M_}NaA2l(p?=E;9=h?ypZbHp{P({Mckt`8 zwaw#qKlt!RKl`)K+bKng;Hf%Wuhy(>pSbIR`i(*ly#7yY9QQR%8OkdWLIz z$8Np%zFLW<*~*;#z53O6-edO)-nBwJ)V6r@U8Jc}g!9~M-9EUB2^GKhVixmVv>UYr zJCpMBj$g)9hxn%W=-D`_N(D+DT$}emTQdj!P?ZBlsDy(=EuyfJmOINn5FnF&CVf}? zLM_I*7gmvd0?a@eu&&+v;3_tN$tlIe1*t+~+7WaoeyzYc{Yq_ChPu?YQc*N% zQdlx^j=wl9>crYCBpHH%DZw#Gp#oX1H5qv?lppX30WdjRG$c@^dBKJjcmCN&?|kUz zp1kptdur>s0e3X4Zx(ILz}Uifp8wc`_x-cGZaC$f+J59O23!(76|0c`B8@k0|HQLb zEw5jH>eT(ebHFEYfGJ$3*mz^*`=4K5T)FPloiAQwmvO9KG8eh^H;#V%`R}VWuetG= zODt2ST8+?zd!+v6^DjJl_{7N@Hf~sL2YeG2Ez^{+*UpnKe6W6W^*YACd&4z9cH`nv zg3D8wo3>joeB}DZ%C$G1@=oo2_Di>)s-ewdFiY0A7oY#ggLnSSbC&baPizD^5o}-E zjYppU@LivIsk{<-HmSE)tkRPVu;`PYHDh<&3o4A-}tXFhye zt$DSwcW(W?pFVX8d$8GPC+gcrpZ@S83&)_4d#d~2?a*a?nwoI3#=ReUcD>QDM!WZ) z|Ku}4PPD##^_geytu4J*RNve9)tztDM}&2T>syPb&pf$sbnSX|w13CxU#ZLcm#=TX z?}N{tdi?W`tHS*+I(-}8gFsq5Z9AGDIEz?ZWBB@S|#KsfPJaH_ba{pdSJW}7j{mG|qsyDAzfBl)Ht#8(j zKlb#ajjL9#(+FjHD6wZV^>elQy-z-UBP6=v)W(lk1+4hBx&mG~F(R{DJJ){fsnf@f zt~~ZX|IybiI#o)Mwyw_Gg~q*4Jax+z=^y?*uN4W}$NSmCQ$w$1tt4?l7G*b!)74~+eCSURLH-hKMXTNl`I zJfa|@nw*p#n`isvLyw_yOEu}BM|B=VD+(%v1?xV zjM@K!;$iUm?)N?X_#@3DOh7?qQvV_#?cHPdK6?7L1yZGtDOK`OJ8Y+M;{%U9c2Yji zAVYDyyT@*S@Ui-?GG5sSyx2eIBN;-0DS_4xyJV5KmXLd1D>~Y!1Lr|vWP!du<+BLdi;AB zo<@SVzwvtg!5{wUv3GDgP~ml-`Q+8_U~`%`sPOm?fAXGpusE%~P@!Lcqw&vv=;Y=m&1Pg3Voq3XlHK4?KPaqYLr^(`^{Z z|Ir`(#NC&(y8$XRI}5vVtA6JXeE;edEN`$!2L5pn(8*7H;?4or>jqp;Mo!s$$vpmv zPdqhXdwa(AF2{y0?LYJJk6k_BetX9Kq+&@5%4o2C>&HI!(B&-9prK3#TSuP%=!a{U z@xaTm;UgdY*e#dw!5}LHwYF;O&wupUdoS|BivV%6w)or&A6>u14LMd}hQM)9{QOq! z(dS>d?;=wiWCkD+1ljoT^B+DQtWWP=ok-i>I$%=LbY!<5dG7h!2CTAoQ{C{Lq_{AN zSKDfT==okmKg54?g#ij~gqz0wx|m{h^OMX`Ikt;yk?WuBShI=7e~laN^O^&pvmD7@u(B ztxtaFOp6U&t1!}$+V+u0p83#yFu7Wp;Q$kFcMGuHwXLzrl~tp}bw^VlVzI8^J_Pd)O?8AEp<9wEh}4?OOfXQ7yEzQlYFN zh%Hu^~{|^RM7k1N|~gW-1+o}?%;!=Pw;kABE^oM zyq!0(?xxOs{+HiZrrO!%%6lF6M}G9ynOmNDcwRm2g~^6H_l7g-dY|>{`^zdfBd<-X4ap1qBB(B?Phz)Yld!BwPXLo@BE+TWb!mG zsJrd+-+$Y)$*^9n8cn|0B=u9zKXZF)@zCNkPv5ezL}&Xq%&#$#x4!Tb@2@74^`psT z=K0EdU$`-uN%odY4EgL0Cl2XF;qxDO`u@fD9aTrOx7_z$bu>PI=aV$~C>_1`C+!QIlrb4xXFQpFgwgDe@p^o!EEi~uSJrKu zJ6h1!fo5)g>Vd=8+^bsk_un<7TK9kOXFi@xjfjRO=Pp>L_8UPJ^5#!dvN2HjSjC;QJW7vdUJtK`DPQ_w?6mTO#Jyra`8<3 z^}l=J-@fvpjg1)w$Sbo>J^DZ+MWG};^=D~y@0o0NA)byqZ}otq~M6-~Q)>X8RmGx6d0*6^=(;^WU( z-v24a*S+hLzxJDVs?BRlwpHr)JaX?er8bunhg0#-tj7L>&1e)a2r^?%)m z(d7I*Z8CtR2Ol{#6wk%CZmq`S@4GerY$qOxZ{G1QZXb=u|MVB0`93UK=dLcNeR2#4{#sx68 zamNLlCJ+b-38CJ5zbb$bqW9iSclQ)K(@QcXnM{(+>}Gc-lYH6iPO_Q(XQz9L8>Xo6 z``#pTkAqg{0gHEPUf^m#A zunk5g#4~7&2lVaX)0LXRm6pebUs)I2$iPn5MoMsJNfKsB-Bkib`p<-ag;4u(k)$XN z4j|OvCdMvGG$pvV5OWnNf%5i1+hK_8J}Z&tZNku-7%7xE%JRW88z~feF%Hrkz-+J_D zZV|YC?{rLDB6j{x2qaYpi}rxcQe=ft+1`>yAtU5KIPgVf+$%W{6CSl`=Y7&ENTpl|+>lDQQ!1&0z@xFYXP*t*n3dVkF z-p_vV_FJU47SfNEax0k!51oc?iDaxCT5Aeim(FwevdXL|Fb>YXJk%G__YlNk%*smo z0sf2_v;E$Q-6yzJQfcm1@G_Y4`cx0O2T5NzaDl_EJg*owLhHdc8{Q&--70n;EC(l~ z31kvESoqpdFS!?P_6LhAxSZVcCoX_3nej+z6*CUPn+n3`ap@G7Tct7{-%Q4n12H4l z`v8JZUpNMkiX+e+03k8HX#LCYKQ@%+z(f1VuykQY1&7NO896&6Vf+LO-W>0x^b*n+ zPBJPuW!YIL&I5+P_zU~bz2?`xZ7DmS1k0A}+;yDEDra-5G|JQ4s1d4H`g&TeJxGt= z+TCNdrmv%!Sy^Ex35<{b^y+l?#D_cvV;4O6pCa_Nn#)-gm12$bWbDM%o*qXE22Sbh zNl8g3rZ1c>V^=UC2*BrHvGb4BzyD|S`Cl*@4ElkXB>By^U%pbyWmi=26ngnM=D%d!7Xke-X=?K|UAfo6` zY3)d9Oo#9t|TX&X=*+j6-W(hGTrgz5UVKmQrws!Kh>lICO!5i(%b%1)>O5q`=mnB2%P@ z(kbZ=599*2^kCNU+(Ins{q55qy=`W&*lbqW$?U@N{PRXR8_y0o%wj|wDo=r}KSd;l zzNV&slXTuOI`}(}~fbF^Qud_a1e-8#7dH!c_4b>CtgB_!-Ub6Sgz9#SbEIAjo zGE^v5Wxsdai+GXxrQSDx{i`Og_X>RTPrUi;#C0#l8&UT~Z-dA4c#@2wLTSAXY8z!PEwyEcDdpxyZwDjCR zy?)J8+tOW&)cT*h-rrbTL#e@4hq}Dg_-cgyRs7n7S#1?cyRCNA(R_2dxwZz3m-^?r zCmU;OW@?a{)dtv5s`2hnm&c8BBQAvg<$<-kCeyCw`1&wp%h-5bO*I%UP0qh?y}H`h zU5%@zxCyRMN39Fz!Z`tyyEb*sGMPBaHVbr%_tuMp)$VGfda3i}=O=63?g=;Irnm^s zKwFK|=^!}3#iI53Ak!+XK&!E;`g;fJz>fu2PrKXga(TO5E+@%JaQL0A)eZ+rL~-;l zkFDJpk6839@2nY6p1IqDE~g6*g@?Kt9V7=44Yk#yWb`w737x)eZ5k~$i)0;57MmUI z8SZj9oQN~R5gMvSsc5LxYbV-qwojU0zf6YmwqiS-5q0v)T|F(Yj!%p0!@PRc*G}P!q{SFd~M}jK3Wh(u?WG*CyYYTBC@o4Z|#9|8eG} z&WY<5)A)eJNHmfRIQ{2;MQ?p+qSJSUr*>(jMs0;uXMl>#7R0iOZSZEiY1M5+jDcZ` zx!OQ55cPOn;NIPT7eP$??#Z=@`2n>-3K4C+!GxF)Gxk3o99pv4FVz|9t`F&P`Uo9P z8&F}+A#{JyjHyK%mj9Mgz`3&@XuOPQ7;0t99tK8iFQdb*T~ciV9}%KdFKgz_)2@ zGx%d#gIJ=`LY){MYs+GbRjX}n)(+Ha@ESz@P^E5~ZZxV?A5Lh?A?0!x*cQg(cIO+k zRZ_J^tE1`=ZLr0x)gYRc#-Z*Sty)D;Eo%FF^e$8>X3$CWZ!_1Y^^mOQDb)bdLTiZH zfTr23QRCGsX1hw$pi&~rMTHX1Xp>W^rjzOZ{DifEwRAwE7YmdsHB^B>AB38X&=|Z5 zuMDahbPAkeSzYI87_gh^6uSRx*gquo;R&@?C{?OdP@hJPQwOz;78MRKL`A5^Cd0{A z6l!m~$wjBq?`5pd`B_>OPpnXa*@{{PE?Jd$C0>D-<77ciol%OD24re=EgrDVaW6p4vp2k-)fe^01(cQvb&3LY;Li%mk=eyo*Y`cR_OszgE& z5uC*d2z-3ieNA_@$kyOCmZw984Rif&!8(W7TddTmB?5sEFC+-?U`yaVkf`M~O*)n0 z^bv!t5K8_ociTFXU?{bE317e$-~>2+sEQBH;&}K<9QPs5R->>f1O@$l7cj`(rbiXw@Mjk_8mYl;9NyK^Qj-3N@GX0UvB%~kso`IZ|NaQBBvZ5SU?q_mu z+!_Z^IE=cG%N9w5$Dn%vMxuYw{Fe_u))t>wXCVhfVu?iUu<}_j{R>*&og1T!;jr{% z9!DguJenDfA*U*#i8ahOFMr&KHBFRMMnLukx`cm zLbu>;RvuR*<{f-oz{elGGTAxyA%{-iiBS=0QwPcuh@=`js;+$Y+0ju?D&Ut>heqN0 zfaO0Q9xC7oMZ6=KCwMF@IsLKXckkPN^d5swFUW{VRz3ap%UA1RI*TvpZClE`gJ9ISUkoK^N~?2Tr(EM^3j*aMn-B=OOTS4)WMO| zUMy+x5IBQCSeb9H%!NJ!aB(SvUJkc_g;LELAwl71hZBazuM8rCq3Tq4tjwRr!|E+U3&7t~r`3-{8HFcr4`RJ}1(1=t4}C+U>}A@^YB(KC5i z8v5ItAH8iTt`Z6b+*24CxnR@7FF)jQ!VMwBONH%ns!9{??TGZRGfx)r1Om>9^z57q zg%#KS_^yS)gP;DQsN!7i>3pSABESnmZYx|KS0yq;=9kE15(%VABhtUkJW*81=kv~_ zA39a`+(+-(OSo_aSQJR*N{!hp6Tp{{!yupuuw3)qjH3k{KEEn2Bd7n}mrM*UpU7W< zVIY?Z;Zq3JaA+Jn#PP8NdNBKZMHN!D%v5#v35z&YTdP8LSvjqIE%pzD{Lnczud0eK zEhywxMOTH4{9;=1+CfMFABHGE)wZgTo|{k0Uwa;e0DDg|xRnW&Aw@B~9qchnany2~ zyLtyl$0w&}=H@S5x_tSk&tAEF`PR+Lm#_Wu{U6=DdKtNlzqInq8!!L#*RNedE|KOx zerBDf$mxDVeod5M-{^Erza}jf2 zJbihcq;TtO?6#hP!O@Fzvo~jF=a9Lj8?XQSOLKEi-+<5l=id6&FP@zv%mrqzK6hmn zKTDYT{O0`3I#J21tLE1A_70AWU7xx&Gc$|K-o5#Y-~98X+1Zz8XJ>A|_r~p4XDBlf z(_h?}o0?kZDOq(Mm1U%7U}*IE+>L46G&1wuFW&yqrJ0#)*QcjvUY&d9)n})t$Wz40 z(Dj)~Wb)2qs$%q5m184)1H;odZ{3(erjY5SOP6oI2nD|Y-~2aTdGDt$Oj0HZ7eiO4 zCvX#Y9y68P8mG8-q_=-)$C8eHW9jfaU4I6 z(7#@1DduXGb*j5>U}*ZKTXPrj7ng24f92Nf#Ki3hWFjy8_!LQjXg7pAEk}>hi6BJhldD52>rhw^OK5dovM4F2i&`I`Rc^z z=-BA!<@u4(k&%m+MvxKGFkvV-JUucPF^HqzS!X9l-KeDZdRI^Xz}W3quZ`eGf?z(3 z8xGA+4v~iNgUCQ=dVGL5fb@Sh@HdvSSLISUCq}z_`v&H(&5sNdhKWOgt0RMh1LT3w z)L1{#kMG0vesb{%qH@A%75881@9ym%92y*gf4CvsAb!AqrN4i0pdZ(d>kCbe^b&h< zJ%8G(Omk>n3y|ou78i&i{a}m|QA*3x)v@v5(k$zh`Q?Z=&yJ zPgmF2Kv!2MzLU`L|Jpl;e!y7hF00Igp}MjLrarap6lwkJlolh2LQ44vz8x{7M8;%t8Q*>>*(z4 zB6i_B@g1vu?MS0EQSonXWgV4U%*4cSu zpmpHs*%n+2u9?_`H2x!LVWT#cyQ#UQ6~IUbsU6pbv@W(iJJ`}W*FJWs3ExC$#5a6T zTfSSTEty)>q^XB0TiYT4Kxlc?-_qUObg93ov#AjQM5wJ3f*dRLf6rJ>SW&H`p%E%< zX+^?~SsZC^Y8n}8oa}ADHy}Qw{?XuEKg2rzp0O06HnrQ=(9}$6#x*@0X>Dw5Xc(Lt z>u&JXBlS4%qHlbxp}n;(Oj*8uOj-D-Ra@tSXirmfa}xpUfT5O#1|QD1+}u|0>#z4h zq-43Jxuw6o&if>1d6Z>Ab(XbA5wQ_z2n;p*uzCpIK%KX@-h=Zj*L8LEjx{&_fV7-6 z+jK50zywhusKnne&{ALT#d&dc1W%}=86qevwRPPC4Q<$L_%Us%v{|%HkJk&uulOKJ z)ZYqG9(*0*!PVkxf_0q@ZoE6_sci?$caMonrqXUyReL;jPGj>4k^};s~NeVV3cjz2sT# zMzk8k^fcDi*5DzcgNLvT(TO;gP;Uc7AHoFY&i4dHV6$tj?rKk$ucoG&0Nx-jyc6e$ zKv%qV_B9Ig^ov$hp>Pj^{i2tM~^AYX(P6~ z#p`mpA<}~fb0Uh^?>D!$4-UAkR*Pkw#eDZYi=mq!A_EZ}-20x&l$oqHsDX&$!59H! zg86~ni8i*m9LC&#;4&?-zD{ZGJ*G5!*?_T_%y{qv3%snDQLA33)8e#If2ThPIQ*5)Rp3D@|jM5NIxj;)iL`;T)k`%3jDCu$%XR`oi9F3|X||MpM6BK>M1 zizCtMBnSV2)hrdOji}RR(ChFJItl*xr&s19<{zdXuvK^Xd1r=8#lxcGu}4w4jE6s`huU%#r6XVpGCbYt=>nH?dhf zuhkkHK2)QI5JN!w{LAwI0)7BGZnaj0vA+L{)?{G;6LVdy5sQ!nYkqZOjxqnt^OsOF^?XJ=b7Fm%S$EHDxR%B&4%T#L7v412q$15kW1k0EMA~uT}!}O2mW@ef*fE)WWCTB9nfX_V0C@7aJ zRg%JgBs3iT8liETvHlIsJOk6eP$TwOy+31oGGjQLVS#0(Gm6+UrAl=Chopuf<;&Jc zjl!h?Jko{pg!CC$7(1iJli>oH<%5h8HiVRf*?-4sBr0j;8mp1iV9-!&6I=;Hstnlr zGf+nc#)uwd7P9~>KKuh#QzBETl%g{jtI2cPRd`jX$!kTdAz21&{TXH}^fx8_>nu7; zrc{b@{>EuaB}$xfQN=%h{!D?UP79H$P<=K0NLRI3N=U2MYqikTkYmB8f16cQ4lyd( z`R{3sNP$-@Dj^JKL>)RMdwlQHNa`;LitvC$gSto_)##PbBhF6d`nft5X+oFQF)`_+V;pByAflw0A!(3BLSj z6Ky*!v~NExkrvGQNi6&c?K=zth}A^U)C7xPkHP*VF}K35P|8s%ks5RsZKrL5L$5_c z{Sj1ue6gq{7i1Nolp|CE)z3UE+Z6>z?r*KP$x9=PU)g$sB{hqw6zbBZL}A?#QB6E% zoO*-`!VYO^+%8={)A8m#|4>x98Pi{JtZfmYk?1zd%yAM+l>Y~OaOq69L^DPqvdkSL*&X-YgLkXD&SgZ)81w++rh z6eU&COu)yo&v4LQdC+sXQ$M)gF>N%j%|YNLVWI_lr2;W zO*yj-LU^uF<+lcQ%>%o zST%gc*+Za^SV)nSMepBz!67_>30gwi3MmB2N;5mz#M(fKqy%Wni8PRbJle!+4bU=P1T zM#hnYwB+rWee8ujWRPo6K0l;%w0C;+y!YZ0Yp!(%^7#%jtB$gf?ve zQAGqLg8X1p%8@9VqJIbZ+`*lj$Wi2A)QK#x2t?)!(!#=veH+OeL0NK|A5Gpw_S1Hq z$)T?vjAVEX>B@$q@`KTsY-X98OeP;W9ZjZ@{T18EIosevXyb0I zpC~jaWR(JLhG$O0blP^e`1(+Pbp;Ql>x$evSHvtkd8Tbxck%+SxG?u* z^vUId1Hy9$iZ@5#BaXb~|M5t9-u4J$#D>0LPm8BEsdm}h-UERGendn>WKXcAbWhrj zwB;;eTThRc8bOMP>q2%;d`>9$9K85wiE*W` zr^lDIH3Apm-;|ZI{~SnIRu85iDgL~kuDon`)#06za#mhW&J)`_df6FxKjNJ*wu?z3 zMeIB%>FaT%HFsoXU=o<~;W~&pUtK86Ia`tQgDs=%G+=`m7U{WX-IAEDY8Y{McV~)S zDK*{r?qDalN6fiHFUZMZoqckfa~69~WU%B)Z#UBYrT0`-YhSgzvZEtI=t$}Cq@?Wc zXw5wg7T=cS=j4>1dvXhFbq7o4yC695rLVNX%IC1zdi}m)VG37Wd~&Z|2Tuh7t~gxf zlUoc|*lxn6Gm0bh;!-xkz9(buQYa3jNM(h46tV+Z0Q@e$H0KOE=gBQ4Cs@#=#?&ps zOwh#vE(m=KiMZ86Sl^x#3p2vV(@ZAoLe7(04C$3&;uc=|>4IWFhPaiOaHW!qa1max za^C^$onNr3-P-@OoM3*9028&a_5n3zZD0k<_a1;T5X^IOSP09{NIQAHpd2ZWED2>~ zV*3lcObE~W3wE7Y+g}(uiH)V8cC@4rDfFLDIdLu@vKNuLfxHU>nIcKyS608)dLb9d z^`A~Yel8C?mJ>L`te(4`bUkqMN4*SKM$~^iaqZBCBf+C*3hBx8U_s8&Be)~}gYn1C zTqs3KSDPT35NsIfg_sJd{?XGv`BAO%`ddF9@z&w%@Ser4YlEP{sBP}7Apo6U8oqs_ zf3~gK6^@Gp`d*o9_L96vo!?unXz+T75LZ}f>bW)bQWwM{Le1?Uo*=lFsym;4b_|m^ z;Ju6Ww=VTxz0^`y2gV_{yp{lgh{cwtpKHH8{miWf&_e{8+CUCLa;1v+~D0|T1YjWTnWE5YsP}^8v_uTEy=i9115G)9x z5*HC70LzopUT1xS6Xxm!G~{alnFVlsh&%juwc9gydFp1p>*bfG20I(7?P6!OudR3b z#U6*Fx@Wur(@v1lkk<#Y1%i$2y3;y2RPA(j&R)O$+S4{s%UiGBzA@Dbp@5*XsUE}- zR6F7&fK-79frM2T2r!^Nix4Hj0TP4>LY_L1Nf0e~$0jsr=B$Y!s2FFjUA34=W*SPi z2My&G2w+gHBn#Obs_~jgrqvod-cGgQtwANz1O?zNG;`3|X)_UkxrdxyBf%Ij%yd=T zZ~((uFe@|J9AWa?+j{4kfPNDUA%_P<1MoZR_6=3rK&640@7rg`2Rh91GNZ3^V6@Lj zF)o_Xp2@nN2_V!YeE{|7^^nA09_&QjBdr!Q0jU3dtEoRjUK1fXdoFDjE#M0 z<9xSw%A?ms=t5`>!~_i}XRLM(Pqy_qv}A2i zgSsKLvp6(e-#6c0dl5BYYKx$_L<>dXw2zEU(@i5|K5u`uhOEJ>AJ|-KwYkncG*Q>t zZ`R}WBwbKcqR|qy1kEFD^;loqM2ktQQIpgp)m^i;8WazWLk$y62A#Lv4psq;pjZu3 z2}B)&l0YnB=^ARU)2Jd;ROM=m4yXI8$b7{Oz zg{T5*XRSs_QqmMbL#sj)0bYG=aC%#MhKE&EMasU5Lp?3^ZnaVotsuz*-gbx{5WpLv zGQ=xX&|qJLY*is6$pTidtVM+#ASptXg>r&?t1Mvj8D&zEG}ur-0%VT_)`%>~DGE-rAQlVK@2tyw@6EcaV2eGai0bO1zQKv0~^g>)N^za%iUq4GwX5K?eK zg+sw7@fVvM-Y&IBWRgNvBtd{rKgZ>hAz#0WCHVb(i4~Pq;j4mDR9O{Kb)PSiT2Zl3 zU~TKKQD7OmKvmIM4jc)nYkKS88Xx4#r93<@D6*<}6y9o;08+5K&u?u*G zXDfJcw(DEEd)wX0N@`_LU{Y7&DiJ=R62~Kg3W3ObAdu_%l?7+mm1d2U59$3#Zjh%} zL)JdPv$_>rJQr8#M>WE#Djo@B1$b_dQCPtxaA}+XS8C9JZeWoMp|B2fC5HpX%RGVB zt`%ZB0Sf2@Rx3DB9DkL)ZxaMMTA_42niL%MycLEfZCNmUV@#^eU@4kkVhSM3SvbNgwbH?SE(&^LJ)Tbggj0Ki^5vwC=6(moXsKw zGT33Lgp!GD63dSYSY|=_=JFM`!YSjj%c*(xn23?P;JtyN4lk4a;O*g__r zxmwPoFhk{-6cnkzvHU`7wXq7s03;@^lw5|C`YX*I9lMlJN+}D9HEayQ0s-ikm0GLI zTL;j*&S}T#UhiaE%sUm zYO_RJmhDojN~~wWJrgNA@~;1#OL{e@lvui9JUH6Z+?3SxsC8g;d}6{t2Wc>Y5jh&{ zVeQ+yWACFw^8V3LG@o8vT!JfEWsK3rf`)y^PwqUqkn0;8Yb%A!y?_O`e%L=!dQj;|(lutE|H2L8Z@(kB+t%6kI4MEGko`X5@hgVKp0j@}p>UxCoopeRcZwe|+T0 zd2(BG`IjZwY%&ZU7N5?|V@aCkM(g%=4;;?IR1gJ^vFOipn4h0{a%+F-y?ksoiD8k^ zd(JaOmGxsYzLAkEWqoP`mLVJhcVRYpr8_6*FYG6`IjjOW0LU>&H-6b#Y#W>K>7|2% zS#nS6U^6_~GT4`oLBD;WAt&c|q9?c5tdMbI7_3*X=8v}mV^kz=U$2m`K zVNO`sVKIU}L3Jpf$pKt2H8US>Oshw*&MnZW4u+BE-~Y{@?Kw|wF=UG#EdA1~yfQW* z5eZ(lDuqieT)L&1S#T~xg}E?+``Z>?2V2mf#AFHljPoVsf(?QoA7-mCL(H!e3lM>y zv;SOi8K|=&IiW-0nPyRQ6$jz?nS0LB!~4raVHOh9O;*6f(_fqh>zsi0AhI~XD3QpO zNlL$}=8bL!3^{-PuCs;VWBGwXUj3D4lAa0NdU2SWkIVPx?p!;x;dJn9epz{Pd9XAO zd-s_CL?TR#;d-=sc^*F>xOH=Wehxo}n_YP0=Wq69y!zhHpPQM1q&$8qaP8%rQ&<3Y z?(#+4MPvd$zI5ZYm#^NQ8yf{#0B$yL^PLwj&5&l0Y5z=5`t0-+VG2KafA;Ddx8A&R z@#4h9-2C|X7;$WAeE#KEo(5UV3}I&J$1mM{<)us0(^JH$P(gVnvCzyMq`V0uE93K%BSS+|xT(dt=UmAQ@P=I5Ro<+Uu9!m>a(c=AoAT@Y5xYtUUAV_%K-F zh6sb9iHneyCPEUMH1^kt+s{Au(&Xq*-gx%f{N!lk{^8M!vzMQJ{nF6T$o!3qFv3X# zxcJ! zoZg6@)ow_&6NXlYhY+YWIN;qkfFB^iVSF#K2N_xI=_X*w>_vi zdnda(I@$^Cq23|b2HKvU8S2G>O++`+<>x=u1j%s{B*$^>{;u(<>m%(r$X|!L2U>Bh zNQ-}FY<{q(8`q786!-n^8&_s8c2+&rG%`7JX&SQE5p9d@U6WS^CNFoiwvbu^UHvUB z%}Dd|+*IGdrHQUiLMN`{UMC1iI=D|Y3=a?Vbhfp%l3Evsr#eS&TpYOE-%M@}b@n#l znij{dkB>Zad1j&;>L;}YS}TwSNF-BQ7W!uTTY9@^E{#rfHIX0-6>9H>O!T9Zt! zUTG@Fd7GLVDUFNWvloZwhMF52d?cV?!RChU7Nq6j(DdN^a7%OlSO-`U8iP!H9Xv>Y z_(HAW^mohHg%@D1sexFYk7325a;`*sk3)z95gf~c+dFkmrTXlJ!M!X4^#d+;7&EeVpp!Mvwfz`i!Rmg|N(Jl%sH zC&d|T_0)!$=R#d;lefn0a%MdxhC5!s?Wu2c;(+fxay5EtdIr6X{dK^bLe6I3bStBS zZ9ZUpI5*DqwcFPOozUVq@RZom*VED3R1X?=61q^+(c<#dHuiPYJAi?O+|4KfT^jGI z8|VP43RIHl2%s5HiP4SdV#`2lYhOc6y%WWwp;|9wWS55T@5Z9$+ph(FSK+#a2 z%SyIBK%Kru$b8rL4z;-Kps4p-Eqk95LWGED3Amd2TP%1Bf)dO@Tb^Iol4g*A9mJRNj z+O8U-0Wsi>%NDEK>$YJzVT`ziv?_g+-fyzIQ6tc!MOfOPtr~5pHR?frZh+LW$&A*z zZAJqg^ymS!THg#=TcXx)cDO7$EkV0vX{k3i*1J$0QHSVPQSc0BShl%c4!hL|Ia|NI z$?nrZK6Y7eG+Ujh5eU_ivAMa?=yK|S9|l_MOa|b2I9*V0Gy<_)(V%E`g9&u&0VAZp z)D-oi*5<5jwqi+I5=h5`oo)koO4Q@jP#sKWp^ zZ6YYl{cgR=u7k{2NNoVpwW?B*l_XVAt;N*tep9vAX#lZ1Ug=i|#Udr7$q>0;>+qr~ zploDCKxwk8AxjrhVJde-^}jmQ?eY0)At$X-NVaV}B3Eb(7Ss)6*lm={B4s$a-(WFS z>mYQ6DDmNI%DslBmgag-?lFFS11MH}-pyWI{j$&OvKs74NWUS9Bfs*$_q5%r24VQB zd_HnMI6K_eRw9neQvH7WYR*d0;VXmx!_FM(cF~W1@^?;+@z{Psz#*{8iW1Q^b@fEF8lWU z+-xmJDFyMWQ0!};#m%nv!k(>L(Hgm_;oLoZg9rlZWomQ8zE2XBs zYqPBfM=qW^j%B8qVJI>8tE}kUQ{>zqY!jl-05*u#i_G5hmT*<=bC+9ZW=@#eGdgGR zGr>vlmY91dc~5RG?c|f&+>>YE03hdPkeM%gS?-ycHoI`~%K=`OSEo^_Jf0(bQ-<1IRhaFmIdv4nB|(*ur=HwmxU#W& zEbWY*fydw=tZ>gRIpA=d%COrj4?ED~M*#TU{@C0cYVMO;N^Y=pz=dU;O-C6#5#WLu zN6X-v0`E?RzGYg?N5jaoTQ)~#)>jBf(%?hg0W>E0bQTIzlp zt?}i{Cuy)k0pwt5cc@!8QV%quCnB~cr=}J%On-gW^XqvAkr9wL7{y?4H)-d2UVbEv z#@PgkR+cvbTeM)yzHL~V7DxS-#_Ka}r^N0^-CN9HD2Ly>DF;UAFEx1#*n$qYf6|r4Nn5DlN8Bz^9d+ zHf^h3e27Nd*gvK?egbOe(`fNW;}51n?Vld4q9*|SWM9lCVXGmH9J4buy_oUW5C83F zW(J<|sp;R|a5;3`eKgwU!`c-4RvPUPba~f+qZI4v0D8%aEs*f_sWa4s&e|$G*6_>{ z-gm|_5gUA8=BisP+TtW|^j=i#Zs?*)8ZBmU?gpTt&yy9^hauzpHFG~Td(3`>xG51< z+h7P@`mcAUwa{%V@=m=vCjl0kSUed+qwVZ5mu>`eKkewjU0AJm&NghP`nuFxDKT)e z&cQR}4D_{T04~`Ybn>iN=oSJsw4oRXoXU0S$ z(f)0_vtg|}JY$*Hrd1bg-wLVTP~urYg*MW#8c*#nNr4*g3KFPWyX*3Z8~*FdPo8$< z9goIG-;doxXRyRfbCX7PFn%lMY*Yp0ru|zEz$>MpzHhRNqA9|0-S&uo`s~{~f4u#U zo4Y3(7yV#=3FFEK^WAQB<&KyztO84Q!*Uwi;-IQO=jTwi4>#r!BH#Y+Pe0gn{{C10 zVTq59jyug@s3&_zw935X=xEHr&0DBZ)K#n}zeqSAOD!5TL`Q6SZa5>jOUbFaO5S^AXxtFP{TxG(w`W+>>@C@XeH z$HZ_&)OhNb6zaJiLwv-Rj+v`9IO;z8U;g~b*Ds~yFEBunGzzId+dmABsc^#_0cxTOrN@3A`|)|Va!)&-k~PpToQj;H*QdSMVv zC2dJf$u37*$7ilQ`|?lT`|tyMX(dC^r<50^#)3I_jCQO7GRu*$BE)}g@HDe2w78wA zdv@>1lY3jcyW3jo$1c^s+3IyEL?;qrV`5?{QE?thEal^}3BzvE=EPm8hZEqTr|g^) z2Qzjb$tg4acy?H?sMsGD6N|(K8)J`x?LyMCb>(DQ?9SA*{V*OrjfsnglJ=D_7-bw! zr(AL&F*XMN^Bjr97H#-$lXXa%5H9*;!k+8Dg5_0_=urH5=)Psqpi*9$84pE=z!QWL z+JBU?h4L-!+^8j!5E&1@%dF_(SB}5fk3nDvz(O$Pz9zY>Fa^qoe^@R){Rm|<<*U7I z&3R->bW&<+Zn5O9%6{>g*y!zfP{)#NTq_eDPTm%akA+1t(hpNMQof2-_EnK1Hg8W! zJyyb)`vX_IB8W{t4AzUR1`j+cl$yAG-6srk2(tHI&~gT>J4jLRV^1q$Fr4?_``!E5 zd*6P?13oRPN0bu&;T_3|>mVW}lyM4l0SnuvnzHb;nB-k)SaZLsnj03z1D46)UH|=`e>W?EwJmle??~Pr8ygo3 z8ii2ianK|@+`yjVlS!LkeVcvQS{RQ?#nYcONJR8qiOEQ^AIgoxlHkyQ%wrTHF@G3SJy;b*#=3rg0eF4K^qYS3m{cUl+mQhFP(HX43t9Mk2ab~?1vAE2 zVpIYQ-~w0);-28exk-~y$lkjxK4DuTR(Npxwm8rjJUDPleZ_Ks6bZMm)U%8z#(i#E zn@Cu7GBFM;!)^o<*DPa=SIpUX7%96_PhxGmQ)U?z2>8V*aj|jnV49e`BXN5iIPf4= zdJ)Ycz{yBSJyeW!SgB~rD&Vs-w#9(yda`j;x2oA`Y0 z=_Kf@g>_>ncpC^09&FN2poei}u-&yEJ8@qzn~Y4yl$c*dPm6AT|r0av%! zaC0%2ND=p=^1FHjaYPC@l$t>Y>maA27c$2y%*^dEV2_J_6oc7AwId+vh`7PEY_c406yaWLD#4|KY|n$1CIrVn|!xa zC@8aBl2uk#oJqzmHh@~*8Xb$BFsz?;fIQ(IId`U8T?DW=Y}{gJ?7sXrKhjO>Dl0h! zDG6}BKw=2dE8(^z??83{Bwl~1UdTN}+8DoMSK9FsIB|Y%|Fvlc>)AW zV9Xi{tLwXsnZsk|DlYeYB!E)SwG6-&ASB>1D2zarA=h#WZ#vN9% zh{I--ySm!Vm1Sp`7??TJ^75-9V<}vd9%%XCwU1L#QGRac_IO zne%o-;o&@1ZdFAI>-K+4^V!hcg;Mdw#tK-@qhL=`0xkg;Pe?!>SNb_NAh0@_wu^$? zTq)-`Bx#CSFZ{6$>nEmqvJom=Dlf`N#Lh_qIUxjt3G?=|wVytlT`sJ17@1`!3bjzh z1<^Zy>Vj4V$}O`V49P0o4_6du8E)I^_HD>ET*8BRaC)t);pzxNiAAp1FJ?C{|(J9BZpS;}efM^+F|I%tPSqvKIsONN;Ddo`( z|L^JQU(M2qbibs@p~jvR`OZ=2?HcI;Eys`xb#)J1sey3YC(in6yVYVg8no*6F-H={ zmG%_U>9T>JUzgAc@GPp{hl(MfcemaP;yQ?kd0J7lccgt31KZo?`|MV;$*9-p2l`B# zFv@VGi1WgfS67BrT~=RjF9$>aP|cO+Iw7&MG=kclSDw4s4}yqKMxUPqw~dgcw~sX| zX&6~LN0)zk?SoI=EW@hibUMrz0EBek>+7F$*zF+Wu+{d@&N)FS@xN$WSBnLz9<*y} zM{5c(vXqubpZ_ha#;?ZKZ1}XI-J)tk)hFzB^yagp&CPb3ZO~?OHahETAkOz`Lth69 zaPOQ!+un=r!^qP9BKluH{MVlv>3I65hJStC;jxRdVXcaWvFb_GYW2axCs(gec3C0x z_vyu3696{U)v5GTP0}z|$|&M|rz_zz!S!Xfve{{6r2%2T3k#Ffz~d&p@WjcD=brDh zm~rM$oP$$dK zO#f@HuX7p!=$$YrCkM?jVYVdZG3j*MD~*6$wlv%I$K%WvQ&l<;i z>>%OLwY4ZMR~vG}Wa-p9zrN~`(Ie=~44>OB$%+QCN2u8hd9 zqTQ&}%(u|jsM0V0@cR$&AKd?!t4ummz%aC0^~Vyo>IwRgu|rSQe`>DQd$DIyT=iOc z=d3+xohg0(r~mly1KbA>rWo|gAIx>uStPq-wnCh8wOtpf`-9$M)s>n#2o zPx|7c-+u7H`(`>_aj|>YW-8tn9Sw0x#IOk-c==py^yn16IW+bOj&$b_AAIl}G-!cQ zU2oAIjgN`eSTr%3&tRDerCc}K!TteH`sQ~Z)PwN~ug7WRvn)Ug+;c76VvbCzVs1W7n3b{--($D!jy7a}*N&s+=*iKQ87-I7+;?rvKxij34jR>t5F$MhLf+#AUcGTJ&;PYFSqb0VItM@0rJ7O zzq&Pf`=5R}4Uf~8uxfe?+Tt{r3as?oW!S>J}2QY~-RgajmNNes|~I|NI`1 zp?^|hV@xn$GDxzM0ECl-Om5q;*5_O}Cn{^0i`09Y)mZ_w#@nJ}$~X^jvs3K`5Ing|ho zA#%;RQ`Q(&KArBk|K9)i+v~so_Wc@gYf&*`(khPcO-cmNssOY%A%hLF&Z{EWz@j3s zUdMv+na=DrZgmc-`HDL;$Y)xf{_syf@s>6>>9njwU@Bo27sm%RPDpPNPy`S8qLGOT zYM5YU!$XAMaIgLT&mYcewX$P-l9Dmz5f{gg;D>Z(0SQ+5cqnYTBBQKPENuCZZ;ORf zpFqr`JOd^fNf^V5t0Gk)m_45WdYy-Y>RUC5VT!f;9DM`*yAsnCy+(XucVbc!=1g21 zkIV~JX$@6`ss}vVr4~3V7|A+Rgc|9mBu$ z8OOA0Wy!wycz}f48wWZa3iqB`&*imVcEqo7tqZX1#aFx+W+zaUN^l?oh%zeuv%CrB=z$?SZ+?xaiT z@06IvU}+ilUYL-_VWyZL@$3jTt^#2{5O!RtJ+j8RvI@cat785|mr@}(oD$|mFg*%8 z0#mD1HcY1o><9eTE7ix=nO7lr@>O|bn?fPEkcR!Z!%QmN_b?A4vL0}Iuhbl0qh9;4 z6Z%(1gN}htX%uo+dcrz2T6c*FtFx68%O7xhZ#c7wVfF=(NcvxS@BRxqYmmzY$9HTA zL!c7Ot>nZqW?31`ogPRoUPG})00GO$hemu>VrrXo%jMz=`?qd>%)r*FDI=BLXDMc< z^as}2S3Z3s{ZnpVhg>dWr6+FLyai);;bve}l$Mqupc=Z*a?TCOx2;jI^a6l<#%dps z$)r`;snJ`vY}pExe2;;-_I*y%vOTb{i~$1-4N@LLi|8DDe;qDCd9zC=+FpjcGhM{o(2wPgPIN)Kpi^l&fc| z+f!qgJ>4c5@$!2&op5i>=ezdr+$CJC-jP{lU}U z`tqIlZMObk&@fbp;qWKHEHDWdUiF=?-FoE}S6pBU*gGD08iBEM@gH*gc>LbWUwlB} ze;2>4BcqaUy4(M=#|Dr5>64%Q=w+8)ddZ;P=)CK9ulf()egEhGQLy!@gM{N5$M|Dm-v{Eh_Ywg1C||M%_R{P!1wCdTi( z;>CyL5xDH%v`d+EWKaLHH7J#@x%{#ZUv%de9=rLni{9~m(Z2sH5B}v}UwXZ8!I^6= zdhcaWUw-+e?`c;uUM8wur+<`jTa=$KeB`fCywGFb^}Y)}a@9Y5@{#{=A;4?+vH$#o zt6qHQa_{o-W$$g(GIN=!-er{K%4L^bbp2nN-u1heUG(lN{+Dlk|3CiS#|0PP_v9Zx z{}5tyeChl9bs+R?#^LFoK*&~s@ZviIwd-S-fAGQ|{QZ|Nx{yJxzxN|AJ$yNdOMb84 z%to`3%tX-KOaBb+XHlTK^~Tbq}D@QtmU0Dm@; z^@9d~nh7W`z3Oh$xh}Yw`hVvmfBTP*F~IQ$KK-@(Al>@Ng@;=?DP0kCJujdgn&>DK zMznd^b=O_^ws*e!#_P$9GWs_k|63a7J(3GQ_uU)x^^y;WTI61CD6IlT!_Sz$1zY4< zSzI=o#5!Ji>Bn!n@uQdem#$y@?rZnDLbQF^mDk^J!?hpf7}&bxJ)imC{{FV-UeM1Mzi+JxJF%`(YrK7GFJ+20hJi~W zm+XAxQo=X4FTVWi|K%U>B|J~pG^()UQ{^v_S{M*0z`j@`wlPcq9&piEwCm(z4 zq5B^H#)H50%R1G=ci*Vg8l#t9e)T(lL;)gMFr z=o1g!`{=7re(G1~R8QP}>w6*czH#c+Kl;;WpMLtq7oUFWxmUmUr(b-^f9gk1f90#M zJn{Hrk9_sf`=0vR10VR+I@RN!zv;K0e)^do{`t3GdFAP+p8BJwo_hABXJ1hEj-R~v zjW0h1`Lo}C;NBNrxNGn_o$9C3sqVk?6Tkh`Q%}G2?Js?on>8d{&VkdJ>fkOd3^JQFFgMEGvEK_D^HNmf9CCt_(S1`b{=`@q4|e? z^2k#UJu8|gp1$|aSH69FCD5k+-Hq=_oadi+rue(2O+9$qHG@=~XsO*79$b3x?;quQ z|NZwp{lw?*|G_gK+*hXl(^Zl4&I|vVDO1nie(Q(cnn;i}#CvF&7_6V(ckcsVxcAOy zzk4VCp*@e&e|?L0UV>xb?E7zj=(bzlR!Ao9fB63UmhSV(8}ie8@45S~JMVe**-Ot+ zss1i~-T;dAi=Vpv)~nvanfl!G_a?~|@-qtG@zggzUphynI{Jf^cOnnB-+R+jpF8sY zH=u!yzk1KZU%DrL&rj~Y3xa!Ieetr_=~VxGcc4?zhh)!&&?_3W)jKKu@uu%CYQu1B9HP->A>9RC@T+rRb2D;G?osy2W7 zT#f4f&))buV6{~G&d=ZT5?5iCK2NlkcgH{9_PH;8_wxhOa}GuQrQ93e{?@f#`LI)| z?l|%Za^j&pH;rsn;3#yIZyXWE0 zeCA_sE9O$n3t3k0y63YCpY@OY{INg2r+Glh`k(%f|FxO=o4<8R){CFL<Xa!~uikRY^>05c6C=e#H+CI$|HXZkeckHx`)>I5k(;l1=bG6tMd9BVy=iju?RR3e zI(^fP4}9-Q7UrOKb>!w7KKM4AQfh%S`G(L9(HnO@cRRU0&ffLimoEGz?dsW^Zo2v% zy(|XNq6VDC?Bm^V^wT%o@VPr~z#RALH?EDnPP=;fmYZ(){a?>bu-t6u0MU< z%`bfKzF$9}U;P~Y3KQE^zrJP~!?Y{cTpPJIeBGHFpZnguzcJ&yTGFjfe(?S$h)=uV zjqtRY!3$nt!a%QyT;pBqUvuV@FMsd;w;xcieroE~*KYdsr!IL@Q98+fhpwKx`posO z{M){q4+J$3DifBxhR*S-Dqs?~i&Lmj>B4d-V> zMjr!h(Wp*bdE^J*y8BbtUH8FXrCh!AD5Rs0z3bPq8Tk;B{{S)isaw@z@!9|W+0R^i zHR(3a|0VTm9rfz*>#n`_%6Gq|lnSSIlLfA5^kl#*T9JCoX!!8*y|* zGh->u36DPij7BjtTz&P&?{s?BZ`^p@)gL~fXFXvpUi`K97N#cz3&^d#vUQnOB{#T!~(vkDLgw|Vsq*I)P>?|jdZ zTL=Ul{qDY^^~ay(>(-SYe#@J)+Tl_lj+&k&&)BpMCX5ie%};#t=4&qd#F5WlbCrM9 z`o}K_6s>RHq;FUL{^2)e0RpNboZHT39KDy=4i+1l?W;d|%V&?=c+FMetG2GZ!1Sz_ z`FZs5KX}s{&|Mk7a`M@)-GIq<^zn~=XzhIXAZW$MeW*6@@+O9^kt?%TjxK-Cp}uj8 z)IQDUL_We$YSYaHRemh}vC$P5zv~Ugk?3SW>lxz`FEPgClg*u3)7DbQ@rze$UM*Z5 zk*>O4Yxym&9qEMHJR9FTQ#X5xQ)Mf)P|dII*0{~HTc_A=yE84fTM{><$5zlQg=<^Y zik^pRHm2pg_D-kW=LN4GPm1=&IphL|>bB{~g(@|VD%DD@(e#>rYpdPqboF=JZ-;oj z%qY^1;<%Z^3gvpOUaM6hp%Jg?(Pyvgb#|cf+Pj@TPgXiI*{f)118V@ZCu?a z+q9;jYeN(@qGK_Lqzc<+s?rc-UVSnp^4nY1Jx7!1oruLbP^RV8v3h8~^me<`rj2gL z>+GtHM9+)=JeE)cHu<$WwKMaLx(&r|`5nI->UjNR?`Jv`U@#YnuwRh0;=!0ZUN>w- zPs?5gGfs>8^=)RKS`QZWIwPjG-{&oPmDeFI=`kirmT6kB7#o0s>ZYY#kp=s$z6PEEho84ZQ z`F5qp!HIN+p5*goDz6d))tq%j$5xby>-UnqT^aaZ(=ZWpIjll3K%>=aHe3AV1wG;6 zBh}vN&FW3{`JN7vV^f*}_1CKPRvQY~yg8xsUBBz~yzXwN#{=vzK)AnyaPpGJIeiQh zl`B;iwApSqTV88hjfsj8_u#f(h_~ML-up<>NHXy>yDFD2IU-u}r!;M7LVBY;)Z^hg zNdDO*5ZhM!&?sO4DsM9;{nZYdfyC#b=zzqvBRQs}fOBX=e?!>}NFqEduhPz(^<#o& zkXyOE(v&(_T2Br7410GVI}$npgFmT}7p(ebi}1d7E7aO;vb91CVXt^7^9#vwgetZ@ zmW|%4FB-EI-qkdPdU}O#zJGkcC?#|qLB2?M3xY(GI$?*?rU+=3(M z(6(e2yB?BLYDE;TF)g6adoX&ha1ZHoht$fHgx3RmlTNFS zgc#8js+5;HjfgK0mDOZFFcug#;z;!B3{Rx?dy$^sowVv@s3xM4g_AeMSdgl1x1n{g z(+*GRJf0KW?)SPK$8W<(%T#*2^Q~hqUR;|F!+5)BIvbQ{jP^aiAQHmV!S*oekRvnrdfR~aHR%9$9%yDN5V8LhgE(NukcRx-zgv7~>OQ2Z19ZmU+z!-h~- zi|P1^=o8Qrg+WLLk#CrM3xx_&0Q!l+MAy{%djD4y~W3xu6^>?Aa63?@uCf^^to z%F@%0>s8KiVV`{6k<<5%=xx>=`3~fMYuKn3GqzNdWTgw=?iSz`-=j8)KtUU{UWhDXi=g3QPUm)x31@qYIBI1C!G5o&ZG58 zCbqJ&9LrQ%dPaKOZ9%M+a>P3Sb-uJjsK1Q(#M&W<8}&*qDdJ>FoVVUzztERYs{7x;lrt0rjq%^-%Y$&M9lX zl8di;tD{&dU+XYo>&@J1f-q6JCHCpJXdQkD7A@3WpOQC<=~aJqoGLWc_0!#EF}0E` ztM@vHh$1VTl?z2%*yw|K*Ri*$4)j{pe2N-&vOLK?IMJ<(X_E>km0*EUeY9}f#hYSF zdSF;41pO(|ck9JWVs$m1EH$CuZWhF}Y36GiLx`rJ5Gst-fvQ&>>WF~cN47ZfwRR;B zc_Lk?cj*3Bzmi^FUXABOPo%6#mwo!NjytHC``-Uf<7@3&DVJPL73%FC(gp@tT8XEp zA;(M~;sp$1qem3%(f(AlNT)(7maVW6I`v|5b!l;x7lV*i+j!GWHihyV!OS@k#mS+5 zpY3)It@YaVQjX^(k+$oNB5#B)uck}QPQ|aBan!Udv}Dq+#>BNivs4i7{)B_z5M0+l ztRf|vbv7H+$wFgoP2{D5L{uS181f#u`flViUGLBi9P2ehtuwV^I<~yHlE~J&hX#-i z;W|iJbYL>j3k(i)p$+j(7t-^02Ax*8b*fn+2jt>%B3Etq4-LwYo`m1D(eUr&S!@Ws z+76TsSzEuyhtGG^jeKm8dCpZkgF}vb2)juzdHHRPS&+$*`>k;sHfPjOv&a3`@n)@* zT3K9)XDZABf|@bO$V@=M2*wRugU2M|%Ub|f^sRlP~ z=hQH%bDjb8Iuqe_f3J$890@D1S-RBduCbDh1}6avbxONd6Da9iGPOu^z)Xv2IhA^c z4zqAf%F${Lo{y!}g+qf@rC3%Ceq~eBNCjvPUU5_7;M@dlX&QH>0(iY2TOG}MC7+71 zYjX7-v(T<&Q#y{QLUZXB(JO2*G*^Y-QK<7@T@Tuv4apeI=PIo}Gf>N|u4L6?$VVE2 zW??-T10AqQumkpIHiC97pTIOTwcwdc`L|FN(>sI&HoUrO!t9L!#Y3+ z7IHveVjDo=^=E)~XV#=4f?EG)c0!#Hk3vAT*#D=p2n0(Z0B%Ujs@A}e3{EYnxWFUFScvxlgD0Rz zgPha_FLgrtUm46PZKMWWowmHz@Ek%9G`Q41HAspkjgny@roRCD;UzH6 zAkjZ=s-mG~*q))I#)az=a}snw$DrJ4R78vCa4KcZtA!eVeTQ+GZX+}a7njPjJ&Fl3IX?E;MaYuAgElFvE zsA>Yqlt(SV4#HR46QxZW=L*9Q_b2E?XpmddX0<11h@IR*+w@vn&6dQ$FPHZzpQc}0 z1v-Wf8ES@GV=D~EXZ!XwxgqzQ;#BS2GLt4t2hFyWN&StkBVGzi!84-y{!uen8D9W7 zof_%Zj?yNgq}S0(pZ|yf=lef1k^@?#^kDI-^dkW$#7S8CpbQ)yIw4Q!q-E?mW{M{o zVO9KefJCr*)ax^LXna;Aie536N`<}iv{b^J#D&nGK)ghTNKhYoGpK~&!AKg8Q&RUe zLRUC~lniwzeah;&cz^ISm6d_b8A6y<>UHX!$B0{CIPC&NdbZ*qgfmYFfR)Ind^r{Kw?CBzwsYN|a-7yMHwb;s2u>*gxyi+z*V`Sed27c8y$+h3S$-NEJwoV?-V{KAL|$YL z=w%ApBM+^e8gv?!lATQ~Zy_NS?tlt-P<>SECOI_Mes`<4wl)AIl{w2$8#rAmf;$0y zBzxBBo<*#O2987=Q3Y$SfhwA1%*8@7l@jMHhdqG9%K(cwTKR`DBi*Y`eUs+7gP`E> zfcn%xYNxG5tzPA5l{;NI+XF18W)UPgk?m)|41n;joF+POVmmV}Q=D{Rm7_ zuOcWL^-?A-{2fb!Ol_D@`1wHNG&<=YQ^K2UIm_YetQBoG^Y&Gh>`*wL&6UF2a*u z7VR7bIZ!zy_?b6}n=@w96m`AC=JQrYs|g;LWXxNY^h$yV*L~_8M(tHbG;ZX6_Y9{6 zjYHk47g8(!%85j_qLZ#s$t9K(1eQADJuMGgjcDyW#t^MpTN`y7FeJn~sS?eui_KP+ z61q<57EM|rY9@_itTFN#I)1X>?XC^lwF0)Al~@9}>9_v5l3iI^T2AY#r{>JCHmqW# zFrp++)M$I1wLz<#gEp?GS(&Wk%|dbs=FVzc7j436_vE?626RvlF_%HlEun;LAP7b{ zE`_2MOBNt6>+Yr+FF5^BXDw}qI=ekP)_#h#rR$*dB)kojs+V&Nd2uzFGmOr_A@}m9 z1A3ji8n@7{11G(oSQQc`ymeK@wSu0%h~kvYSDMsuh7nN3IclP*sIt@a~|?zO!daJe`=6Ui@=G0?*6ja&_0-EW+(Qvq5o8gi-8 z=~hCOUzDWoF#=&4{4dZuMRV8@$O!1yx~)bS>SAgcoiQ%X3#g&988nsAsIjg4?bD80 ze0RtZuVal`Tv|qD!~6m^G?kC;v)K!5_aB>i0L#3#3}QqKYkwbN^laASES-jq39ruJ zS}mA`@x%9wpYG>P=d7p#s9gox@MEL*8pl{XM!uxQYa+Vp4Of9pAg4>=m@u&Mt}37g zwJ*3bt>Gx!bXgVTxtZ10SqcFgO>4k4JGh4iUM<1KP$OnLG+#(1(1S{4A9^vtl-?-| zU}Q}~r^OJaHDD^hD7RvAg9_09S2C(0R6d5nsAUW~;2@_jcO3)RRQnyBWQd(JT6_9d zFK6RRE7>#ek!L|@MO;U+tZFBR(5b_cX7RQ{8(G1Fs#X9H3Ks?YL)8hMBv#1$L3UQPr=Gywv@4AwMmMD11`g1mYy=z! z)^s(;D7)dbHkP(po2?B&kHSS>J396K1&W|lJ9E7HwNQPkM+x-mklk|=q6IpwZm;N2 z8YWN;7Ne*j%cO1oyaOsAh2>9`L(vV(Y&ZgT&Q*wePRi0$^RuEzCuV?SndL$N@0Sd@ zs1K=o(t_EH{7WUB<8QB0FA-9mg3JJUjYv$t39O{MI>co=aP4~uKaSpv!;eXo6A!P0 z<|%LwIxI$U9H2*~2}}mE1${93H2lQH@=GZ)Z2zxu9p>bY80^cpPf_B(jvH%*5b~LbQN@TK~e@z{O z(@2ivGBRipaJw=d2?D9j06ymw4EKLJ2=qE8)f{)`LZ@=Xn%5kG3*Z1DVt>!kXX;51 z@NpD3ttyv}X|?konYCX>!M&=KLIRSfWM9}XFWq+xo%q4JA3=qkM;|0eaK{F&aEu%j zaF00$rN>Sw)Tuq^prl9|b~wi%IziO6RI2Zlrh9C2OSQ;G$xNq?qAl#eI*8d>-6QjXCb>e0VARb-&!C<-C4 z)rSo;>$QPIshAh@6Mk}nj|4gk}vnwHB6Qh**LbR_QTd z3bo8GFPwx{V6p*SDeUo>T-DXFTnzi9US`8!oV5kjD+u7`Np zlkzT@7Rk|RZ92Mt?Z5^#(kx)#z=;sIA<|qDZQIYDl!4w*D@1H=nLXsFJ>{r4#z8T8 zZ0p|QmQXShRyG2kD;dFce74m-*$^?`td$kaSHi&;*Vs0fM3zYBGx%5c$)v1y7@HL2 zP0k%hS@KFlc85^0w>SZpvK4pId4jxl=qYzav>wE8ZWDGRG-7rMue-HZfnPprI^ZJu zz$)!}iAfsUw{k9=)N+^syVij5jQ7-fs57=+`{hYKp&p-gq(Tcu8qMu6r(SWy2~4Yj zzfF3S-&r>+2sZu{D0r{S+wmB_7gTFM8_7)|W?W;WZnGV=0sG=w5MMEiMh+S4Z++c{ z1>-Wd`*=6;%etFfph%e`BJk{KP6Am4G|Ty*vu?0)S6^jh>>E6$n;TC~& z+kw()=*g3hFsJ~;MFl6-c3el|%JNczNNF1Pa(h0;VL**+but{Cx3k^F0)wMVZ-y;f z&#}iszL?W6nh58XS<85A(dE_&Vf`T_>4(gMCm`8qBU~nIBF^o7M0>UCI5#hc`?gs#WG?v z7K)aoJVIQ;MMu-&{6^5Qrrn~Ghqx_yDG;j;bT#lZaBY3E8S1Dk?zlE6&E|Ob(=KYKD}>}@!?FeB_K4XNYO$kBZV51s z)Pr&{Ts)TNA1;uBi49aE|h?HEHNUxj)(*5kyCj?`E_&k z2$l7J_I;Ejy#x-$RvV_F$E>S@jeK%xZeHV7JoP9Rhai|cwT?AQ z%8DAdNC%iz1|Gu3v}~&2Xl8X`ZedaMbO0}#!Bl3S*|P`=861MqTmP*B{CZYFA;+}y zDA*DkUHf!(WfcapAxupM$Fw{Swmt*We_ zo$F0F9C9;^X0Jwy%*1zN{L9MOfaoLTG#U+EQOBxt2k0;p_hS)CddUem$*K%2e=^Tn zr3xFgc6~;#(qjcH0|PBD%v{ebl{(z^>$bo-Dy8^>RZcnzo36PYv1M9wtk~N5SiL|2 zF3K>JSf*?!35Ws{Fj-bqM-b5u)1nrX7fyy*vKb(g8T~>23hgfS1go^k|znQW^tsInHE%DFx5vX9vdC7S{DALa-0Hi zwcCH``MB^s3njQ*Ku=e=wOwi(I1MuJnzOib{v_ zxHXQ%(IF8jD9|mOm2WhaTu74skr~{mxM2^>*zR#xnZmNUPfA#UwU`=~pIRitoHj#M z#i`gw%vrTQYsuLhNJ!-q3#I0hTdZNB;bvf>?Ggo&c}x^e1Xx5<>SY#S%?)#0)>^Kp z?FLuWE9`2=?-r3KPWpP8S#nUFMbD9$21Ac^WYo9q2+Qfxwut}&{7k$wrL0}#OM2902E}=73t#so)G!(3 zOdgt}2xkPUw>pdr#fzJn;kE?#8PJv#J8Ro%swyJKXmW=W+$*nF0HVP_Gsdh)7`sJZ zZSGS>q)OR>X@Hf9+CnV~L@PN9W;5eL!^+R-NTu)u3l69yU<&0mo6pV!rToDh>FlI2 z2v+!|P;nwfVon8$s>UC9`PrO!%hZ{0DN@`)eN};tBK<;oij!t2LMzjXRFd6FsoN-(j$xv@W|XR9PbV%SA7wMB zq*tKRz_`5ymw=jR^23=)iq^xuNFLF?U+q|cm*UvFwP#5(z)~W-C{EqsUNj#*w{B?@ z%(OPPph7r9cq-*)_R7&)#?5++Ddje`Dn{T0MI$g`M7uZWuvdzdceQdeRt(8&HAX4M zVKtqnu+7sjUkP}mEcmm+n=T;Fk(;UZ=7j3!oq2*^Zbyj1jw%dUZl zBZW!?%wiz#oFZca7_*3hX^DBN_XFhUDlzmp6BL-G3et?qW1xe~00AfCG>M5%CuS4# zv|u<@MdmiJ#+my)aG~TbnOU)%?%mVl>t;-}+ye2u~<%g~zFbgV*fOOhSss!^5 z_GXKM)F?ave3;=>71*T15|xxw-jb1HM(T7(mh;2PNk!lY@aft_T?4GZ?=)*OVCRfA zyjO0>y%iNas3HhgfMP?zFm}^}Fky=32m?+srKso7;#hp%<81YK(7sK>+R*| z_RC60jIbYo;82cJqik7N0>}*$%Lc56?Y8|h40khVV<&`IGi+jC*0 z;trSoXDB-7iV4qhm=7|uNColGNb4gMIhG)zXeb3lPpvyBOGyscsDPaVO#ylw6K6(MKvtlJIoY!C6KwoTF`|>%?4Qa;p-u(yrdw^lWO~ zaBQk+NS!GF67H1^m;B-g(=GMRP}ED}MNFm)@^V{LnV_cKohf0!q65HuvtgiY3bu}t zDRr2@&H<{tYSv17#hDUW%2hs0`7o;?S-(SXbsH;0clRnbuxdpS1Qea+x|yOg`wD(D zk&T3u2H~oPiAra|aLhD2M;-T>kf_8HQJuZPnlB<}aA1$vX*|VGXWhXV$c_-XxcG-z z*CjZkl)c`hwUDu9bBep1@gSIgv!bL%b%9KplP;ry8!{DvU*6hlh>vN>foN(}7CLm@ z(*%&<)|%k#cbLs5gKjo6PnNJ@$^a>41>k&1M`y(n00jLq02Ld#Qr_Au7}h#mEQLw{ z5vp0pME1W&9lCQP+alo5$&wimkyRB*Z-Gpi@U;PWSf`tx+1e9Qi&o)06^_{&VmDKq z7_)o~1!1UC*i{wgEaSL~rpHysnDdkhrjnkQ1iqP5kP<6oE2^^fu89i6dT_l&H$7B& z(@2~+)wvriEFEbE(nS!}NCe0o&2AZOPS6O5is~p?GY$lp^QyQOtmB|ymEJM2YUtC( zP7Y8L0SMr16bz-sTGvpiRagxY33&ljNv9CzilDrdbm2%*?B;Z06vIJTY!D8_pmt4* zgIyg^*NkIAfyy~h3?92}4-OS63b;fw{(0N+;9dZsmkI0Yq^8T4s05$_$JDcc1m2MX zYm0U+g>>F|1hQ$uLSLb*Q@B{(X)0%U*J_ult9{2{3L7X+h(y!YsGW!+E-`Q$f!gVx z^gHdyi6T5aKxeTOfoIX(4Q?8$RzZSPSQ7$r)qYra?d9Z^wACU4vr!Fb(qt(UuMwfO zR&^4g8F7*@Sf*M#AtX>HOykhG)9`E-fJrcDG!Grir-V#jGa)f6I8yY0RO@mJ>$wL=~!6GWfDZ>`1q0`Vhw6@M;)? zua_{q>x{iLBkAZo?-A^`;ni8nOk}ADW95}Rb;1_wZ#2HdH$OJEs~h?(I}TzoVikme zp$7}-XzvkgAtVGdIab6Ub$;Lr?F1)swPXw(ONO~yvlPy0S!y^OOkn|)1R=VH67 zv8cL{*i8mSWXGWm8TV942+SSBYKsX{23u8P`n!{>f${(`aMnIoJvdbEVW%HxrGeJO3L_BuMNK6`m@-N6D z8>D%d=AytRKg$e;V~eUNm8Qf*SEkuwxlOBw=8}mSVR8)2u8gp|Sr@F&glI&mV$qqa z!NEk7WF*tzHe(KpEdhE_B;>j)R1epOvuD^+Q~Xa?!mRcp)2uKd;pss?+{f@MiR@=l z7=sFf>*81e;|omrkQq=}EYr!rR4#5Dxrzfu(oD#wpn0cxjI~xRdpcyh$s~#koS9=f zqADn(s#$fX^DjfXorSkrY?DX5cY*K5fuWd>^w06n4v4LvW(k4OT4cYp=#frMgfGEjZVV>F1JF zCQ`-7h)*|c%{Sg21~McBF)+jiGo`UajinuoX56kg{WA4)lnKCVSnasU!Xhezh2$m) zp|Qw965BDSmCW=gTD+Sjz>BpO4wElNN*&5R)6344iYeEMS~{ajx$;Z5V4w7?5{bYM zGDC!1d13E~f_H3596_2+Y4`({H?&9M6}W?^vq8;7-5k&2chspn282=1$TBb^AejEuyt6e}?`ib7GLQZQPC@WDnr2ATGK_xqK z)srwbdWx2S*DC5|=M0xn43kk|B(5_>Ah`sj$9A|suvh**~B!ZRnf|ub#K3Lz{pGFoGAr%eN7d<3uiEu z*0OGAuZh28V#!7Yvec+tM2*!Ql*eIE+*C(c4%QFn5b7D~cd_2?qE|=czX(oV69KTu zUj1grj-oNT@-oFn!5fY{fH{Roaf_<8((($}e&Uo!j?rPJh0WK1xQ6#+@-j6WeM_3r zI3E~YsdKLwxF-r)z}l_V2%+&g+pJa$t8g%BAngbpod6?WS4zlBt|-u}8J>cIs%}=? z7)fpw0vjxc)(mBbsE?Z4h-rjY<*X^E_)L;TXNnbEpAJ0CwultR)EF$HIngFk8nLmS zQ&5Yw$6NT(oCg+fmQ=@3FU;|-5t*qU>lmd^+I)&X41F`P(lvte95q7A*4r?>4J^-+ zW^TAz2veY|X7G%1vcIl=nX>WmI_s1JT}Y^!73T~GxQayV%#5f@q2k!OgiD$;7XgJ0 zASe&^r8EhVjgK`g#QnIfZ)Rq?g%{7&9i^;ncOjkzf&Zx-iC4f$VXUk}a@}||ldchQ zqf^{LWuXf6%s_=;jm#VX1XFYr7qF_5K`I?2(KQ#$rWRD9zQCC#(vZtHBh0VNIn8Sc|(LTq^BUDUrY}72UImfh@5oXNblw`)W zD@T=|l4a4nT@hykQTOGN)i|aE+EUmhuzA}-U?h@{rc&DG8L`(`8lj{q5hh`0(8G}^ z=OKV_D(nHtrg|_GVbhsCnxTnD=kHPnBAIO`U7WsqIq#& zH;8M|MI4p)-TbLMR?yz4RpT#gy zu=~t)>7P@WvE zy1l*KZxp#aE@sfuO2VM98U+oBAsmISq8Y)k-z;&+F=^(EmP1?w%Jrd{wirBX!?PRA z)~#lV{S3v(b|Nwok;h`ngu}frqtkr@Zt4;Ihx5MIV3sq=ZyxMRO*0wwE2Q&KbS|yX ze}%3&g6&?Th$PZVnkmKhx9pVWghEHH5~L?Ku>Gcq);(#uw$*Evh%94C&4X;mimZ|W zrC0HlVosD(?wL|<_S;n=_O*>LUr3spAlkvfDTk>~jGU&!@-V5Ju07=!;^Kz3D)I;_ zASr$aHn{Z^|4-Gcac3S%yMQ~_4G%Vm&*oBqoz3)8??FKo()!AmKzs#KL~r6}CB`QUG7b zvTP`9ovZ2u(M4$QG--IakfF$LC{5jzuwaLrRwosEM(mgdrrCQ&*=-# z&`l|Srl4V3)Zg^fLf-=7P>a-bYE(Cs!hz&^AB1`Lh^7hN+Dzy9BR#St3Yw+ zcB8`G$0XDeF6+Z(<~q_j=K5SPwOqT-m+t`gJ~j9@-Z0}01g|ccg$5^jHCj%rf;)_y zCFCqu2WO>Cx3QApfB8pcgX*E3TRs@*xwQiehyEp+ttedFj^j%AF=1*o2^&(!}*aCy}^JtnPp7%nB=X*zW2uz(!G9 ziGv_wj$c}`?c!9XU1eR7C}4ka&kNCR5{_FwtVNUjN!7Y_aa)WB=dl)YLiTytCGF=2t&n^A|hwE4#s@u0vvSfacGmDhCVjk1anGLK;961}h#tm>x} zM=5!PSe8FtfdtY(OPjiCr28IPP9Y-*yR`y`O+wiM^b((rYC#AM*ssiBj~y~!np(TA z7|>LB8#%tZN(_yT>7bbzpdf{rP8Ej7f)>b?rCqyXr4<@t^3<=;DS#@+Es0^Qen^Po zXQOX*s+kzMcjC6>vXXL6Xdnb!$zqT1!`(LmMTC|2L`M@D?^4M)7eM692=5KyHKYQ6 zNjAZub{^VtD-8n5=0>MxPY320I!Z93abxG+rwJHVi!4YbpT$m(WASssA^)lKJ zx{l(FgxTanH5sfuNPZw%H3`wsg?Irg?rCe*8}x>GCG1IupM9EBeKtQSR2*WIqhgB6_mBBk#V!pwhB1`Xs%NQ zgW>Z^L2616X?)LWn;mS^cAKLf8#PG}I&C8_r<8Cg5i@MRn}HgQ`at7RqHWIT_;Y6o zcl97!ZzIsKjq8%QCewW-7ov z4eM-A*G2QYD@<{UDp=BBi?o_7%cMopw9xAA64d5EvDWFfh)wRYjjNUD6llUdV!39K zt7;^^N=QDau}DUSSB?uNG*HTBP_gWCFOXIEZd(>Bq$Ls(h}%H0I^}Ja!`M6-Qjhl3 zHeO9t*&>-Cb)AG8#hiu8x5L2}+!o+Ia-S11l0CsuPvz>grM=oK5B3vC=U|8R^WLCbY$k^hT2| zvnv7>k2oa+HVoheikhZIG&+aqloAAodq0QAt3u5-H!2QffzBZ|@{{NwkRl~2Vt%<{ zz)=+LorJDZ7Ln#jnp!A-d|zSHh>R>^*E%$CO+vUgQesOb(Uc^V#Y1keb-2Q^Hs~S+ z*Gz-bDByl?1PtJUq6n}_GR00K@^GKKrBUb9C-SK(M9!t?FkO#>$DLPT7J|1qj&&GF zvfG%rGooBbLPWMq_|}HK8UQe^GY-**?L!ERjn3r}*O;3y)ws`dga;elpu5Rz-YjI&VU2WW57>wtC60~C z{%|+CsDOnsW)~NpsUs*-Al4Y!!O?^|W)tOiNW8|%bxEbm-s+zP`hgeC)+2;rp=*XR zfdeK0?BcFxc@IAuatu@B8hI3pwbhimD2MKDSQU&+6JDW*FFpPj|mqR zi@KV^lu=vx$cq{E4rTj!TEu;d+v3cht8B!}EGIq!1n)Oe5v~0+)1_uPDXhoJu?L}1a@ko<@NIE+BEI5?>9)aU zhgO_zMnHlJq`kA?x-yPDl9n3OaH3nutO6QQINiXt)k8|dp}rfOGk!U1{9;p%bP}V6 z`jbvMO(Gk`XyW+hZWmz%^!&JnTr@=mQq%TKUC{1eyzO#oWp#ChF!l-e`e^N7cbzSExl_uLf>$0HJQ4J1Xg|E;s=7ob?sezyi>;{ro(i4HK zoq7R^lEu4D!ysfKMi+9iyF^Oc{*m=BI7ThA^d@)}ZmH6)Gxi7V62_Iu!i0!3I5+q!e-yC6^zoyxFl4G|F1oNF&nv0y(iaPLwy@&jjt1_kA z=vMQ@8IXWLZaJJk=3YUID-sbCE=F{AON-l+2d=eFITPn@?~39R!E|HF+wBBvEmB%% zQ%Urj4B@sX2Zz(k%E^^gvaKL}swK;pU{v(bg~^?D8iF$-NWft8 z*x_vS8<<&Kkffj9G`VCW<1z$8dHwaG|WzjS$DS%1x z!WorfP~EoEHgcmy_%a+*G!m}&N1uONH&TF z1mYDuM$RifWCvp(rQ2lub}fhkbA6-65~hQDc2rJyA?k>4DgDXO!J2g1Q986&yj(0< z@i6{UrgOir@`qSq=~38jC5zO67@sjqnGWZM(u+xDZ7Dn$G6XZM0SY1AH-ZtV>3Ho< z%n~7c238Xw;92$s)pt7D6CBz~{>VSA5lPQ73c|4o0kDWuy>n9 z=6pOy*9;8eGIJiJ%g3QpL?X>O+XmN8aX+a=4p=;Y1_T5moW;{o!#p7AdOo(WFpu2= zvx0Qis026SO!8r(dlk0}Ub7FUXLBlRn?(rGiEL%C5e z#1~if#E6S!53Um_GR7uHm#lEhLFl~VO3^6?qRr_>qnwTR0aGt8e2e#%0!-2 zheIS^MZLv#6uOc+U~V6=Gl>Yf!T`2+4b!N#3#k-Ek;;!KQlo`50NSC>FUZ$K1eIcA z)n`YlPQ!eH2d^h(hMX}X)Hzixfav6FVz{DIj7KC7!q9qHqh9T-kg{uaYQ^ZF_GE!g z%L-Fegp_-_Gv{tKl zjV%42M6>dXJ9FH2qoAF(oQx*9F{S1t8I-F--WjcrQkw11QAsPF*6D2XYy??GVuXa5 zdMLd`YNb4usG?|V&;$`K_9Tx|=rYV7u*xlDxY6Bg!zzNZAawE{u$pG%^QH z&tiCQ^K5{{(=a+NFlaf0Ng0Vw5d`wjLnn7R4GEs^>dl62vcEE2#T97^_ zw=m2(Le|i0lOal+z|0safQSiaTJ#E=+GIlD!NB|IeEhrBy}7|ECD#=uRN8g9a0*=6 z^U`?FHJK%7ovv=mlU^2L6`9muL6|qf0DhG#Qf0Ylfl|!vn2J2;8mdGI922xyBjFq3 zfJ%lSHLC8tL?uuEM&6pLyN)Y6g*21WlT9TxCSX-3uM zy{1K6<|sw;vSccXpmhVDC0>g>L)a$JyL1?Zm76o@F=P#$j=Wt%mvvQCu7Ayw$U?d0!~^oC1!~G>LP(g`nvulhu}~LER+f{&>?0Vv4s_MX>nn0-X_*w zG=fa`gP~B0ZbM(fTO!e$aJ9@b2j0%?TtI<=TP-cCe(8}&SaB!@9y3mF)iO)7vvV{M zRThRo(iMt}X8xT>m*GhRYRCL0VNp#l&XVtDcY*Q>-ID#B>gS5`>~SEw9)XoX338xA zGpeQ+X6F$t+-T69t8ZjWzxBYJ5(^{6jd6mR>3NQ|KgF%h5LQYG&I>zmJMI~^RhfYM>^@2ox zDxv6MFD*xwW>De*yTeq2!Lq4CV@k9MQy{&v=oE@imMhBUU6UeH5*im~YtsVuXf}AR zik*t`ubT*7Qq~yP7P7v=_(Ev$CS0`2Vhn{}ggR%*cEzUR31dZ?lP@Lt+QH^3I%D*= zlqD1`hvy+hQk>)=v?`8LQsg119rc}9~tFZ(4ubN%qP=nv)o^-ce6z=>_!P#nD!Kne)o4G*8hxWciIwP1=GAr}p zdBx0HD7{kdoUwD+I7*G@^4*Ap%M939m8J50xqPf+Uo4Y|IwVv4^ z2Lu&!Lw>N-2liC3G-JN35{};MtI0+mWSHX!#{j@P4vN)2+&@8Na{{L&FtDbpQ26d(iLk#skf1istlLS%><`KFV>8sq2#I0*CRi$0L}O z3H4gMwOFoq)}UKcik#jM`>3Wxi{bH%&4laMhrPq6&*yO?b$}Nu8uocn)23M=?-KVz z4xjIxf94P+^juAqM3Jh3=QN?>BGIyXG1EWV>JAPc8qh@&vMcFBNm+DM&Knf@+V1i0 zLI>@bG=F63EL6F;5a~7hM`8R9IyMJuhUATj4C%l1g$d~O<9)AstVV)BPJ3+od&30wg=53ynB5_lDsO+Tk|3Sbb4%nF z%~x8Q7>bIgUCGEG(m$3WZ{@O*h5Q*eS9+*s% zJGRlWd;r=y$}r5-Fo&|9lAHT1Ww_0vXEm9uDA@(bi9)fJ{?S1!ret&yZ?L&Sy_okI zy5wtzSP8q)$8#B+S)G2H$R0K7rn7L9v-yM{it(@jKSTt!-ozXCR@8G zqYTsUB^X7dza_Io_x!ar)_MEz`8-0vwT~I{X|Mvb8p29{)ab1Z28aE_8;4l*Zi5u< zs)M!f^%MPL?ZM&0=O12!&j@Bl`>MC~)fic`n(QB?@wG#T``E*3n6`Nkgq#1&)FNL+ zzjl5PTZ96r%-_xHfVfz~?0)s}IMc;RqMWN_!zD{IETB}rAxQ^~p?p$CM0P*cIX0%g zhkD&UDGqT^>ql6JWz_GH9z4Z-V!D*R#aX|y#2X&N)r21EB3yixCKohlTs#9pq?G8; zTk=-7$!wodx93F7+d+E7YIl`yr{N}Y?qkJIBa7O-1>WYd{X-?Vyh+lieE#GKOp!2F zxnw)NCEl>2$a4QUuN835ja?2?$mR?0uh70n9mnF!aa={9V7NgxWioyBR^dRsfOP`w zpeMkzpRuEA!To*=uCtHAZ3sC86Hn;1bpu^&F1fC!VYjE>LTlt*cIlJ!l{>Ra0k6TG zK!o%Ut*sqeSB~p3nTE9ff_c}9bw@ykA|r6nP&!M{_2wzkNE-Bt!A}J%PFHMb=r-IO5DJ(7 z_IRH}P^7^Ut1Ka$iZxZu8%%bHb(biFlbVzl6o8MmmKNizi*=Y(Z{~fT?atF~q_@o( z#PgNP5xc#_gD9kAqpG2*vbc(Q?jSG)J#XcN5}6`;mdT2WNY*4145@-7$fr{g9??oPg#-e0~ijoUUk4fqM+!e$@b81sA!9ORL z;=EQ{#M{~F5sFC}NxFG)1bei5q8C$=%o_5&r^j9RuIQhbXiXl5I4$Pj5iXeV6qI(D zcBm3L%<`hroc%*Qla37isDkqpoP!9Az@J%oeb8-8!~!3Zs;M^=1?jMssnPvri$lUN z&J?{>H|Pr}%vy1!vu|*k=pf^?RuevgEJ01gW+8c4c6J(s8veYU3kjO^3cv{}wTayRcwzg317W=*?unI})MQGckfR)0W_yT|S6Yf@`E2uy4hF zp<)IzI8_QfRfETmjhdv)L{p}@4Ac9gir!41DR8T%S~JW-btyNl{?RzVKEr!yObc>E zm2f^V;=W28O>td7EF)irAOfT*;YsnHX9w#r9tB`Rpa3BfWiIJz$|Ypx zZQ#rc{7;9(KW2g|)W9KXE^O6!?9$_;OH(8e7NjilFvIJr%$(aNbVwW8g9(naIb}qa zc208T6z>(YVf4nGrsz1jG@lf$46q=9e7QA9^HrOTuP}~Y2jD4}6>@w3U~qSN$zO7?qfH-umX(b!`Mo?C>X~EX9B*ZtWcuI^m64RuPT19RUWPiBB#}TJ z#vM^(-X$W@2M)So#n@z>!4_2xq!~C%@>%VygGdO^PGZb2pv;aDR@!Rww$&C?V3kDp z5{9xcS&Wa(SfA>Pz@b7vs>DP=Y5dTaXo7jG)X3c`(d~%hGV5?*mIys)Qo6 zDzdl9>VUnC*DcuMbjCd$LqI3zzV^Ok-U-YL($i%q!td;=gWIH-D&{G`FM6=zgjq=` z2XG<;vkKzYER!$8&Ya2-27 z;0--p1W;mXwxV9}75L$Fgw+iv`2YoTZR-wGZ6uxXqLx4DKy^F?&5;Cu)U~5is{gnhy@5uL21X)o)#7s zv80or9_3R|Ud)}KjLh`H7ALUMFJMPmAwDwYKumDBQ^7I?1q(g$?+daZB^Or7L7v5c z&w~~My4#Y~y#w=WQ(9)6Y6A!856|}K$<^ZWn zGPXuIiJ1n3nwH5~JoMrw-|E|(LM7lX8nr%5Z64TPNLnx1j<5rX958u|Wo_dC874CJ zRr)|f8B4HlgjR>~wEcRx@5L}jEGtrORYl?PeokW5xCOHZyL^SG5&e}d4uhQG8o@5x zdiJlt^0A1;G_-sQfd!giwKx&Py4L+cieWGj3%iR{6;{Gcq4Dv;rjIX@HpwALAaH8xyF!Au{w2dEo|?6~yW+A3ND3>Fq*17K0@d>B$ES zPKXDV&mqP!YojELzH*l-Re>xSI|EIMpzTb5T*$KXy!ebV<*=)*fJ`0Rd|>Yi3Wiyj z35nhK*6fc!BKGU<3W@?M4I*BLI9_S>}fZYLy?prt}D&#MQ z=RZSH4@6!R8VeH^u{f_v|~2n#}RUWt$SDi42Sz z;{gRUDJ%XeteVOLOf+dKQRpL%WIgdn@v;@yjsOV+9}^C7jF>f!GcUF-o7=RAHrv$1 zu^W%MeDXtpnCNHu$YKZPjUATKrEJ+wup`Arvxo!=B>F?_1jr`6$HhYf067pR_tuqF z*#M6-aO|+?Ui=KQm?#;xQIc2S=;Sh!ndndWNc+318piSnyjN=QQ6{WJe=9A+qt@M9 z-e&)-CW`uq^x)%|S1q)KLrX)x@ccYqVtk4BcX-ofW@%g7BxwXOYSW{@Lt#?Hb9iyc z^7Hz6VARkS(>c1cEaAR8&%ZViyerICsfkqs+Q6!Dd~so(zxbQQ2L@m!!>A!!j9!64 zz72z~dW?oQdO!gH`X!U8Xle5!&IVi0t(6$a7VK&^4Ou3<1vagim))_A920WIq&&+s zE%lG%DRD7gOesOUC3E&u!4k6yz;>6BOFz321|uZ z3#N%mBS&&1;gDVJ`Yn^AAjaOJ*&i&@hr;g0-nPW1fFm-{2?B=3i=B23gEQ>TEuJ|X z(0Ws}->0a_1k48h(j-w-Nm)z$HdjV4Y3RHi_oXnf#TJ=hIk*cgvj7M$$OE)&=leuD zg|`@{2$7jIX?B|4Yovev{cICKBx<81zv^)dbzvA zX4%q|!wJn^oV5YfP*JSA!!hG6uj^VBk}E5tTta3FPI$hrbWOF8B@D>OPcs9v=LrFj zzP2}uER`}I>SgRtGoS#S%4oB82YOV=eYH_ zyN3N;phC_IjGsNALWmz`d#Xpagz{zv}?w+@1HsAqX3R%#(B*hO>-~bZ6=-MoH z4`k@t%;1nZz<;%UGb$_*5T!7}kq7QUNo$e88nw#Gwl+i8IgZuvng^}=G{gTjsb#6Z zgOxVSpKL3eh{L=gIXnnMCrgS@PXJ`JFvQk_nItIJLTj>6sD$b?6H>5cRDd*0YhXnk zq%vioEJJCRSM+r*&>%Hgq`qUB4JgXoH^WCYsyPyp#*eFAXoW;5EGX4m_DB7$S~2|S zG!{}+$AxD8qF~m|torv&P0(h7X())JGW^e5QHK$2j>U5PPn79uXL(DF>3NIeUUA|0rMGS3{aa4*23WI zFUO#i7p9(NO10PqH#x3#OfqrwEkWD1N&+?o2+IEDd3u=s?_Nz*o z^0I?S#m`NQ(`4+&UxNy0#KBjL=mQRp-{%Fc;V#cfXiUg|F(b@(Z)fBE=d!uWs| z)?_sk-0zB!Cl3*eoO1 z5m}VL=DjriRrEF`GPf=At32*Zzs>?#mS*UxHdFAUL{OBqQO)LQaUUWKLK1PFe%Yz$ z($pej8HjA!bBF?}z!XYJ30*;c&K8V`GJ+iZQ?wBnl0l7qtw}^ZK#eo%d2O<6PGL8 zB^QKjcJficX_`{w2{RSY)i7IRQ6;PzNi9_^3w@00BuqgbY+U!7j(iE6Nbnm{o3hFn zME6KlWd-#k13-A}{oo=k7LY_b#qz9$wS;sMj&;8o5m6KNqbXe~xW@6wxEJhFHUFcv zEg(DBBt5;}5*(wS)M07(@&rlZNFut0*#U-dbAXM(@r544S|NFv8K~I~C@A_#`wrkW z(ll$H6AV81RVRmzu_!-iadkW(^J2jd;`-o^CXbELy1ixEQgyLD9;=|;Q;2%F@qR?*m7$y$p0tIlc?K+c>;I(!$Fv*-^$ctT(oGYPimjd zqV?BdJ)yzZAw5ndNfwy_v3xN717G^I^k)Bj4YH&CB#lY-h zfdp+JA-b@8kXFPhC2kbt6Z<*Hr?zDfrGTr&p~5NDa)3oPTWiIxrU4rz6}6H=fA)Gg z6}w8z4S`_MP9#+|tm+^fAcJjUjHl))A&K%jC}?6LY$&v;wc`KBUbtd7yZL( zl6@iUN3Lr6GR1|ikS?04O6O#d2%2I;EGg__WHbi|gK+pzfm>YNv!DI-rPAL(eKXgfyBUbi*kfC`fmn_QZWNe=s+S;Yx)C~ zNX}wbu+={Z5|O1q!r&K^@;PQT#!UVaNDMZlbPTFPiUiQn!A0R1I9nN^6ku>JWR!>A z?=BkhJBSz!5_-XhUq+11u`dxkYhpM-XGK1%D>O8rKMOQUA`4N+?a#u9LUjRf6mVk~ z@B`8%s6hB#BX>ON@VsnT3zU;SD^zN{YjAuH?LogTNsQ*~5Bg|X2E=a;I4)>2VrrUW z=48`y|F4L=6-bu(GakL*{}Xg|9&VGSumHG@vH0_R|9{&%8{j;v?7qJr`j#vkVT>)? zva!LIUP-nrTf!FDFP4n~Id~VBp&dH)bZJATCLviu7>C`36sNRdGQctuCd0HWOAKUP z!q=v3Y&Y!2o6<%bySp@jiFbzGx*KvyF~!K|nEEo38dOF^s=rtlTJ5hBs~i{*m_8d4jmY3D7Yj_u3_wJhij)$l)LI zi(ydD`3e#4o>C_|U=cS9`Bgo3klPhedEM?)Xt ztZ5E=*A^*R1kREXIJQZ|Up=B<@e5WdMjHA~Z$(@;l}A6b9VLU~NXw|vff2ta1L0qi zS414%dLWD=+8*~9?!eAP)^~KNTppcO>f{+xPcs%VM(pirrR2-Vz~vmey42@rv=**S z7D8(iE@Kc?xlO2k;@A9!4z4RLrWY>4>(z_Ax+qq+Li?~d8e(B&uBVhvN>uJTD1AN; zjaY}PqQ#%fn{qu%sLK)%e~LHaGM6_(%mj2;3aiyl&9nK*xRYL2x`^s8mARBYJ8Hsc zQg|zh(-6k&=sB>$1dZG*ngnOV(zb;2rO9%OO?~p9k@=97B3b}tYkZjexILum?X{Zf zW+`V}GB>``SXv0H>|_hqopH@j(LB5jSDhA+B=XZ#xz*A8SZk7D2CnA!$hP_f(L><$ zt7Hdu5v(*95HgouP}*_;dkdw+Y=sXebu&-#f#Nv-| zqH>Q!gzMT0R~#Ovm(HnM780;%laow*y%qgH9fY>t$xyM<3TBgx ztD4Wke)+&#=5|8B79d# zRn?hR-`5uRMn$m&3?L4kHpFlT@KIUj!tU48Rj?aVh_JSaYQcKC8^E#zEYgoDl1p^Q zByA&`D%?mhL5&po6%fwC3_2GWy}odiJE%_C$r7}rECh#eIjG9FR@J>13LHG*ecQq? zqhPXa8<7eQMF*&Y8W2D*TOZR~Et`^=^T-}y7Ly%FJT7wk2B9ESLInr3P+J8DG@yf~ z4M55iasscB|5C?>A!Rd7MGlY)X{>Qw-O z_SD)MkoZuKhOt{|pY77CNW1nFCiH5SRsju_G#BpO57WW)ijax@i?oCv1bV68+F)&Q zfDDIQxDys#^CC`&CswU#gP;6XK!sCKU>Rx|+=$T8E+%0@7FtgAQhW%jgG+%0XGO_0 z2c4o23MV}L(iZo{?so1&zANy8zrw(#{eJc4`Vat7_g^Se;V(a^mjWo_tQCGnj4hYU zf00RZfwKlY2`sxC-G#xl>eUm?(bXsZ%k^?H&gI#qzGdliQOh0iW*xt+^xfEkyl8`5 zjH+V-wDQb!9d*UFE%LaEjT4EK@FjB&FmTgG%@@bDVL`*0oHD_oo5ghmiCjl^p=NGm zGEuTr#L$vrX)+a;rRbq%k9?Pj7Q~_{?=&)uhAC`Gc#4$Uz%>g_+~Yv=aszo&S|t+Et~{prrJ z_`IGEzIAtpy}L5$8C>Ar(t56!Gfywgeq$ZZV>6)Q%byBlglQyI-t z0}HjWE)06?lddDQ5GV6Y2#u~DNPDZ=QEFlmRR}Ut7l1!a8d5oBr#Uv&6=I7M{5J*_v zIguhOBPPn^b)CO}Y1Fo8LByi2$|sAW6Q@~pdu5<}?w?uIXAz!Dbd|Vstlw<@ril7khGS# zHxx)|og}~<{!*VW7SOf?$mwLUdvRpN5CnSVwulaiTf>IlT2RVqn1NDO@gP`?DdQrK zO^hLIr=cl`-cIr1ZWB#4GMtuHE@I@!=upYp2~-KL7Nd1BAU^^2`12N8diZ9_T$moC z?g&>b_MGr;(z;fx^tT~sYLm1bE1NHkkqd#sKr2!j#76&O1mRm@n{pWKp?}>j$2;(b z7m8v3WvNY1_rhBxQp==J(2e<&sc0sZUnJ`2|{3ZV&_&N5D7cafMP<6M#K*`go40pwmRQp6h#%$T&|1V z%ea;uu!2r$#o*=~E&xZgL-0UCU<Q%ArF6Y7BsEkFp_ zS{HC4L5n&d2E#xAes)yjssk<7l)8Ifm7Q5o5 z$u=y{pHj&f;u}h0wwB5>#w&Z)#IMW*XNXAfI?c@HHo<|L=3;`OCDgP5Yy7xLf;W7W zr?65VHWruEPVPE#bojJ>Q8%%zD5NJ zE$l^2?gAWl@_O9=4FIo(YRayXfJ=6N$W;{E2p#$bkQy`dd`#2j>)ksfNv zy60j3*hbpz-cO8d6AH$gD6FY8o0|n;Wu2vsT(dT+G$^{>0MEM(t19%)AmR3<@!P;` zZixGNytt5bv??>FfouIv#kwIxn|GL1Vs3>d&vVn$y%N^R`+$RZmhK(fgcr3Wmy*|e z-!+&_G@9QwCS+a6ejPHX4q6c9x5sr%94Cb!)hRBNM$^O5_D~>;vY}ChEOPR8qvM0? z^=U?{@`&X-)XpS}j~n58fj(GN1K0LPE#n+5cK6CWZyfHvbQ9mxMG@2owzu3RT#M%^ zyATg(1v*ujoJVQZ(^3tI_CsN*OR6=^NMQudG!OLpbcfg(P)St!!|z3%reFZe6{P9F z>RF2wRD<4YGF-8esj;L|z$ctlT1i4HmT5Un2!JL^NH-2|GyZJCOwJ(@#{x=Diqy3U z`;qKN00nxf0qI@}J3L427|JvCI3gXKP=C!!tZLw*4!tNt8~K&NbkI)l7i@XM-xeM; zBEvcj4UADUnf&#cBJ7AXb+7Y9T@?YK$Tb7lP7Sbrdd7t1)~#R@#={VMf-}6K+~`hg zg^A55el)#>e!AH^958;9n?EOPs6L5nJV3ozYoM<})v0>exd-%@>j?=e6iX}%l`dPH z>r3DrN}stygHi$pg=;(E&em2M&|EqV=11Mw&RLlHl&JdlUQn6@M6Dn=<@`H^cwN`C zg4%UR9CKxWZL+dS7-ojq`Y(}@&~M!1j%4>vo`4?d3lo86DP8OoVH1Aca20(dT^TXP z5|&T16=I-z5O3i!Ced~Jp^@dNk`wGQ0>Z*1h9MV|Nqi9QEaU0cb>C}*Nj^#5st?j@tu)^mWx4{8>gQx3>551)(%IiYvH)-? zS|5!{WgKngmDmGf^_6#KlgKV}{e1Yz&>G3X{5jq+Pc(&&J;QA=KG4NU;WcF-Jxl_u zJSjj)Hf*KtssUYP!~wACBp7py{ZDeche%~JZp!S`{)>>Q*_eonX?5&W z<<+@d8}7|wtv;wnI?ZT^H;QPYh&tUzB-17DJR548kRLbMHicl#rxcdGT*7VXSw|vE zUNDmcT{Vw!=uTb|*J*h_T`QVyI8{iif^y{$ zIy)`GqG*YFML~1xg_<_Dby&X<;JOmQiIB1?(;ibH{?WuEGVYM(zA4!x8={4rjqX!% zd#|Ba6{n+vbrnnyQ3-LVb!bDU%s-F=k)MJ98cA`HM>^)yYb~yG-+3Vd@ZMOL^TB%! zsn_RFK_>V@0RDn_0?gR>K>M^^bzC1eHpB&LC#5jS`xqEZay@K8$jl{d7VG zOEjr!BkirZjK}#~nGfMFCS9WXNSQT0Sg5$yE}O0f7f|a^M9G@o$_r*PCa2ADb4*Mi z*KA^TYo5|}lOk5qNM(qc+3b(JEo2W=U#Si5ygrvMdrh|!qRbTL6sM~(6KW+0=Y!;@ zP=gJkr50no&VAhnk#QQ%>^1!hva1QyJKD$?0i$c3lpcV?;kUWMB6;R@bWUy5%c}

  • 8is;1r7zCwNf1 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�dH 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%0D9>uHw9?==@y+ENzKSNsw6}G&j~Xwdi&m_B6=+ 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 literal 0 HcmV?d00001 diff --git a/doc/source/_images/general/telnet.xcf b/doc/source/_images/general/telnet.xcf new file mode 100644 index 0000000000000000000000000000000000000000..4ed47ffc609c716a3dfc58fadf79b1e00bd46b93 GIT binary patch literal 1672106 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

    /// string to write @@ -433,7 +433,7 @@ public void AllowTerminalTypeInfo(bool modeOn) /// of network sockets, and hid the abilty to change that setting. It's stuck at its default value of 2 hours. /// To change it from 2 hours would requre dropping into the Windows OS-specific libraries and we're trying to /// avoid that so KOS can run on Mac and Linux. (Rant: The ability to choose the TCP/IP keepalive interval - /// is old bog-standard internet stuff and in no way is it Windows-specific so there's no reason to restrict + /// is old bog-standard Internet stuff and in no way is it Windows-specific so there's no reason to restrict /// it to the windows-specific part of the API, dammit! It should be part of .NET because every OS can do it!!) /// private bool IsHung() From f4fa41b2c7b5ccf329bb36e51e682e875f6abd6b Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Sun, 15 Feb 2015 02:20:40 -0600 Subject: [PATCH 158/446] Did the rest of Unity's darn work. fixes #565 It's ridiculous that there isn't already a field widget that behaves in this sensible way. But this should fix 565. --- src/kOS/Screen/KOSToolBarWindow.cs | 75 ++++++++++++++++++++++--- src/kOS/UserIO/TelnetSingletonServer.cs | 3 +- 2 files changed, 70 insertions(+), 8 deletions(-) diff --git a/src/kOS/Screen/KOSToolBarWindow.cs b/src/kOS/Screen/KOSToolBarWindow.cs index 66bc1732f..2d1b44ee8 100644 --- a/src/kOS/Screen/KOSToolBarWindow.cs +++ b/src/kOS/Screen/KOSToolBarWindow.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Linq; using UnityEngine; using kOS.Utilities; @@ -93,6 +94,8 @@ public class KOSToolBarWindow : MonoBehaviour private bool onGUICalledThisInstance = false; private bool onGUIWasOpenThisInstance = false; // ReSharper enable RedundantDefaultFieldInitializer + + private List backingConfigInts; public KOSToolBarWindow() { @@ -178,7 +181,26 @@ public void RunWhenReady() launcher.AddOnShowCallback(CallbackOnShow); launcher.AddOnHideCallback(CallbackOnHide); - launcher.EnableMutuallyExclusive(launcherButton); + launcher.EnableMutuallyExclusive(launcherButton); + SetupBackingConfigInts(); + } + + /// + /// In order to support the changes to solve issue #565 (see github for kOS) + /// we have to store a temp value per integer field, that is NOT the actual + /// official integer value of the field, but just stores the value the user + /// is temporarily typing: + /// + public void SetupBackingConfigInts() + { + List keys = Config.Instance.GetConfigKeys(); + backingConfigInts = new List(); + // Fills exactly the expected number of needed ints, in the same + // order they will be encountered in when iterating over GetConfigKeys later + // in the gui drawing method: + foreach (ConfigKey key in keys) + if (key.Value is int) + backingConfigInts.Add((int)(key.Value)); } public void GoAway() @@ -345,6 +367,8 @@ public void DrawWindow(int windowID) GUILayout.Label("CONFIG VALUES", headingLabelStyle); GUILayout.Label("Changes to these settings are saved and globally affect all saved games.", tooltipLabelStyle); + int whichInt = 0; // increments only when an integer field is encountered in the config keys, else stays put. + foreach (ConfigKey key in Config.Instance.GetConfigKeys()) { CountBeginHorizontal(); @@ -358,12 +382,7 @@ public void DrawWindow(int windowID) } else if (key.Value is int) { - string fieldValue = key.Value.ToString(); - fieldValue = GUILayout.TextField(fieldValue, 6, panelSkin.textField, GUILayout.MinWidth(60)); - int newInt; - if (int.TryParse(fieldValue, out newInt)) - key.Value = newInt; - // else it reverts to what it was and wipes the typing if you don't assign it to anything. + key.Value = DrawConfigIntField((int)(key.Value), whichInt++); } else { @@ -387,8 +406,50 @@ public void DrawWindow(int windowID) CountEndVertical(); EndHoverHousekeeping(); + GUI.SetNextControlName(""); // because if you don't then there is no such thing as the "non" control to move the focus to. + // This is an invisible dummy control to "focus on" to, basically, unfocus, because Unity didn't + // provide an unfocus method. } + private int DrawConfigIntField(int keyVal, int whichInt) + { + int returnValue = keyVal; // no change, by default - return what was passed. + string fieldName = String.Format("CONFIG_intfield_{0}",whichInt); + + bool hasFocus = GUI.GetNameOfFocusedControl().Equals(fieldName); + bool userHitReturnThisPass = hasFocus && (Event.current.keyCode == KeyCode.Return || Event.current.keyCode == KeyCode.KeypadEnter); + int backInt = backingConfigInts[whichInt]; + string fieldValue = (backInt == 0) ? "" : backInt.ToString(); // this lets the user temporarily delete the whole value instead of having it become a zero. + + GUI.SetNextControlName(fieldName); + fieldValue = GUILayout.TextField(fieldValue, 6, panelSkin.textField, GUILayout.MinWidth(60)); + + fieldValue = fieldValue.Trim(' '); + int newInt = -99; // Nonzero value to act as a flag to detect if the following line got triggered: + if (fieldValue.Length == 0 ) + newInt = 0;// Empty or whitespace input should be a zero, instead of letting int.TryParse() call it an error. + if ( newInt == 0 || int.TryParse(fieldValue, out newInt)) + { + backingConfigInts[whichInt] = newInt; + // Don't commit the temp value back to the CONFIGs unless RETURN is being pressed right now: + if (userHitReturnThisPass) + { + returnValue = backingConfigInts[whichInt]; + GUI.FocusControl(""); // unfocus this textfield - it should give the user a visual clue that the edit has been committed. + } + // (Upon committing the value back to config, config will range-check it and clamp it if its out of range). + } + // else it reverts to what it was and wipes the typing if you don't assign it to anything. + + // Lastly, check for losing the focus - when focus is lost (i.e. user clicks outside the textfield), then + // revert the backing value to the config value, throwing away edits. + if (!hasFocus) + backingConfigInts[whichInt] = keyVal; + + + return returnValue; + } + private string TelnetStatusMessage() { if (TelnetMainServer.Instance == null) // We can't control the order in which monobeavhiors are loaded, so TelnetMainServer might not be there yet. diff --git a/src/kOS/UserIO/TelnetSingletonServer.cs b/src/kOS/UserIO/TelnetSingletonServer.cs index 91f4b5af2..08e506012 100644 --- a/src/kOS/UserIO/TelnetSingletonServer.cs +++ b/src/kOS/UserIO/TelnetSingletonServer.cs @@ -328,7 +328,8 @@ private void SendTextRaw(byte[] buff) else throw; // Not one of the expected thread-closed IO exceptions, so don't hide it - let it get reported. } - if (VERBOSE_DEBUG_SEND) + + if (VERBOSE_DEBUG_SEND) // compiler warning - this code block is hardcoded to be unreachable. But that's deliberate. { StringBuilder logMessage = new StringBuilder(); logMessage.Append("kOS Telnet server: Just wrote the following buffer chunk out to the client:"); From a2e7547b512bcb953dfcc349e9ce0a446d6f0b46 Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Sun, 15 Feb 2015 02:42:20 -0600 Subject: [PATCH 159/446] for #565, had to also make it detect config change Before fixing #565, it just stuffed the config values directly into the text fields, live. Thus is got whatever the values happened to be at the time, and they got auto-updated. Now that there's the backing ints, the widgets were showing stale numbers if the config was changed from outside the window. (i.e. use the window to click the field and set it to 500. then type SET CONFIG:IPU TO 200 in the terminal, and the config window still showed a value of 500 in the display because it was showing the old backing copy, and didn't notice there was a change.) This update fixes that secondary problem, by keeping track of a timestamp of the most recent CONFIG change. If the control panel notices its last fetch is stale, it gets a new one. --- src/kOS/Screen/KOSToolBarWindow.cs | 8 ++++++++ src/kOS/Suffixed/Config.cs | 14 ++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/src/kOS/Screen/KOSToolBarWindow.cs b/src/kOS/Screen/KOSToolBarWindow.cs index 2d1b44ee8..0b269a3b3 100644 --- a/src/kOS/Screen/KOSToolBarWindow.cs +++ b/src/kOS/Screen/KOSToolBarWindow.cs @@ -95,6 +95,8 @@ public class KOSToolBarWindow : MonoBehaviour private bool onGUIWasOpenThisInstance = false; // ReSharper enable RedundantDefaultFieldInitializer + private DateTime prevConfigTimeStamp = DateTime.MinValue; + private List backingConfigInts; public KOSToolBarWindow() @@ -193,6 +195,10 @@ public void RunWhenReady() /// public void SetupBackingConfigInts() { + if (Config.Instance.TimeStamp() <= prevConfigTimeStamp) + return; + prevConfigTimeStamp = DateTime.Now; + List keys = Config.Instance.GetConfigKeys(); backingConfigInts = new List(); // Fills exactly the expected number of needed ints, in the same @@ -369,6 +375,8 @@ public void DrawWindow(int windowID) int whichInt = 0; // increments only when an integer field is encountered in the config keys, else stays put. + SetupBackingConfigInts(); + foreach (ConfigKey key in Config.Instance.GetConfigKeys()) { CountBeginHorizontal(); diff --git a/src/kOS/Suffixed/Config.cs b/src/kOS/Suffixed/Config.cs index 4f21ba58f..28f66ad07 100644 --- a/src/kOS/Suffixed/Config.cs +++ b/src/kOS/Suffixed/Config.cs @@ -12,6 +12,7 @@ public class Config : Structure, IConfig private readonly Dictionary keys; private readonly Dictionary alias; private readonly Dictionary properties; + private DateTime lastChangeTime; public int InstructionsPerUpdate { get { return GetPropValue(PropId.InstructionsPerUpdate); } set { SetPropValue(PropId.InstructionsPerUpdate, value); } } public bool UseCompressedPersistence { get { return GetPropValue(PropId.UseCompressedPersistence); } set { SetPropValue(PropId.UseCompressedPersistence, value); } } @@ -31,6 +32,7 @@ private Config() properties = new Dictionary(); BuildValuesDictionary(); LoadConfig(); + lastChangeTime = DateTime.Now; } private void BuildValuesDictionary() @@ -92,6 +94,8 @@ private T GetPropValue(PropId id) private void SetPropValue(PropId id, object value) { + if (! value.Equals(properties[id].Value)) + lastChangeTime = DateTime.Now; properties[id].Value = value; } @@ -160,6 +164,16 @@ public override bool SetSuffix(String suffixName, object value) } throw new Exception(string.Format("The value of the configuration key '{0}' has to be of type '{1}'", key.Name, key.ValType)); } + + /// + /// Return the moment in time when the most recent change to any of the + /// config values happened. Used by KOSTollBarWindow to decide whether or not + /// it needs to assume its cached values are stale and need re-loading. + /// + public DateTime TimeStamp() + { + return lastChangeTime; + } public List GetConfigKeys() { From 454272e1e35260a86701cacc5909cfb511baf14a Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Sun, 15 Feb 2015 19:35:44 -0600 Subject: [PATCH 160/446] Fixes 564 - and several other doc missing stuff Also fixed a few missing image links that never got copied into the newer doc system, and fixed that I forgot to document CONFIG:TELNET. --- doc/source/bindings.rst | 225 ++++++++++--------- doc/source/commands/parts.rst | 2 +- doc/source/general/nametag.rst | 4 +- doc/source/general/parts_and_partmodules.rst | 9 +- doc/source/structures/misc/config.rst | 69 +++++- doc/source/structures/misc/time.rst | 5 +- doc/source/tutorials/designpatterns.rst | 2 +- doc/source/tutorials/quickstart.rst | 6 +- 8 files changed, 201 insertions(+), 121 deletions(-) diff --git a/doc/source/bindings.rst b/doc/source/bindings.rst index 30c68c27b..189fc279f 100644 --- a/doc/source/bindings.rst +++ b/doc/source/bindings.rst @@ -14,19 +14,21 @@ effective kOS scripts. NAMED VESSELS AND BODIES ------------------------ -Variable Name \| Can Read \| Can Set \| Type \| Description -==============\|==========\|=========\|======\|============ -SHIP \| yes \| no \| `Vessel <../structure/vessel/index.html>`__ \| -Whichever vessel happens to be the one containing the CPU part that is -running this Kerboscript code at the moment. This is the `CPU -Vessel <../summary_topics/CPU_vessel/index.html>`__. -TARGET \| yes \| yes \| `Vessel <../structure/vessel/index.html>`__ or -`Body <../structure/body/index.html>`__ \| Whichever -`Orbitable <../structure/orbitable/index.html>`__ object happens to be -the one selected as the current KSP target. If set to a string, it will -assume the string is the name of a vessel being targetted and set it to -a vessel by that name. For best results set it to Body("some name") or -Vessel("some name") explicitly. +SHIP: + +| **Variable name**: SHIP +| **Gettable**: yes +| **Settable**: no +| **Type**: `Vessel `__ +| **Description**: Whichever vessel happens to be the one containing the CPU part that is running this Kerboscript code at the moment. This is the `CPU Vessel `__. + +TARGET: + +| **Variable Name**: TARGET +| **Gettable**: yes +| **Settable**: yes +| **Type**: `Vessel `__ or `Body `__ +| **Description**: Whichever `Orbitable `__ object happens to be the one selected as the current KSP target. If set to a string, it will assume the string is the name of a vessel being targetted and set it to a vessel by that name. For best results set it to Body("some name") or Vessel("some name") explicitly. Alias shortcuts for SHIP fields ------------------------------- @@ -34,43 +36,44 @@ Alias shortcuts for SHIP fields The following are all alias shortcuts for accessing the fields of the SHIP vessel. To see their definition, please consult the -`Vessel <../structure/vessel/index.html>`__ +`Vessel `__ page, as they are all just instances of the standard vessel suffixes. -Variable \| Same as -=========\|=========== -HEADING \| Same as SHIP:HEADING -PROGRADE \| Same as SHIP:PROGRADE -RETROGRADE \| Same as SHIP:RETROGRADE -FACING \| Same as SHIP:FACING -MAXTHRUST \| Same as SHIP:MAXTHRUST -VELOCITY \| Same as SHIP:VELOCITY -GEOPOSITION \| Same as SHIP:GEOPOSITION -LATITUDE \| Same as SHIP:LATITUDE -LONGITUDE \| Same as SHIP:LONGITUDE -UP \| Same as SHIP:UP -NORTH \| Same as SHIP:NORTH -BODY \| Same as SHIP:BODY -ANGULARMOMENTUM \| Same as SHIP:ANGULARMOMENTUM -ANGULARVEL \| Same as SHIP:ANGULARVEL -ANGULARVELOCITY \| Same as SHIP:ANGULARVEL -COMMRANGE \| Same as SHIP:COMMRANGE -MASS \| Same as SHIP:MASS -VERTICALSPEED \| Same as SHIP:VERTICALSPEED -SURFACESPEED \| Same as SHIP:SURFACESPEED -AIRSPEED \| Same as SHIP:AIRSPEED -VESSELNAME \| Same as SHIP:VESSELNAME -ALTITUDE \| Same as SHIP:ALTITUDE -APOAPSIS \| Same as SHIP:APOAPSIS -PERIAPSIS \| Same as SHIP:PERIAPSIS -SENSOR \| Same as SHIP:SENSOR -SRFPROGRADE \| Same as SHIP:SRFPROGRADE -SRFREROGRADE \| Same as SHIP:SRFREROGRADE -OBT \| Same as SHIP:OBT -STATUS \| Same as SHIP:STATUS -VESSELNAME \| Same as SHIP:NAME -*Any resource* \| Same as SHIP:\ *resource name*, eg. LIQUIDFUEL is the -same as SHIP:LIQUIDFUEL +================ ============================================================================== +Variable Same as +================ ============================================================================== +HEADING Same as SHIP:HEADING +PROGRADE Same as SHIP:PROGRADE +RETROGRADE Same as SHIP:RETROGRADE +FACING Same as SHIP:FACING +MAXTHRUST Same as SHIP:MAXTHRUST +VELOCITY Same as SHIP:VELOCITY +GEOPOSITION Same as SHIP:GEOPOSITION +LATITUDE Same as SHIP:LATITUDE +LONGITUDE Same as SHIP:LONGITUDE +UP Same as SHIP:UP +NORTH Same as SHIP:NORTH +BODY Same as SHIP:BODY +ANGULARMOMENTUM Same as SHIP:ANGULARMOMENTUM +ANGULARVEL Same as SHIP:ANGULARVEL +ANGULARVELOCITY Same as SHIP:ANGULARVEL +COMMRANGE Same as SHIP:COMMRANGE +MASS Same as SHIP:MASS +VERTICALSPEED Same as SHIP:VERTICALSPEED +SURFACESPEED Same as SHIP:SURFACESPEED +AIRSPEED Same as SHIP:AIRSPEED +VESSELNAME Same as SHIP:VESSELNAME +ALTITUDE Same as SHIP:ALTITUDE +APOAPSIS Same as SHIP:APOAPSIS +PERIAPSIS Same as SHIP:PERIAPSIS +SENSOR Same as SHIP:SENSOR +SRFPROGRADE Same as SHIP:SRFPROGRADE +SRFREROGRADE Same as SHIP:SRFREROGRADE +OBT Same as SHIP:OBT +STATUS Same as SHIP:STATUS +VESSELNAME Same as SHIP:NAME +*Any resource* Same as SHIP:*resourcename*, eg. LIQUIDFUEL is the same as SHIP:LIQUIDFUEL +================ ============================================================================== Resource Types -------------- @@ -124,15 +127,13 @@ structure with suffixes but it's acually a bit "fake" in that it's not really a structure. The following terms are just exceptions that don't fit anywhere else: -Variable \| Type \| Meaning -==============\|========\|========== -ALT:APOAPSIS \| number \| The altitude of the apoapsis of the current -ship. Identical to SHIP:APOAPSIS. -ALT:PERIAPSIS \| number \| The altitude of the periapsis of the current -ship. Identical to SHIP:PERIAPSIS. -ALT:RADAR \| number \| The altitude of the current ship above the -terrain, rather than above the sea level. Does not have an alias -anywhere. +============== ======== ========== +Variable Type Meaning +============== ======== ========== +ALT:APOAPSIS number The altitude of the apoapsis of the current ship. Identical to SHIP:APOAPSIS. +ALT:PERIAPSIS number The altitude of the periapsis of the current ship. Identical to SHIP:PERIAPSIS. +ALT:RADAR number The altitude of the current ship above the terrain. Does not have an alias anywhere. +============== ======== ========== ETA ALIAS --------- @@ -142,22 +143,20 @@ structure with suffixes but it's acually a bit "fake" in that it's not really a structure. The following terms are just exceptions that don't fit anywhere else: -Variable \| Type \| Meaning -===============\|========\|========== -ETA:APOAPSIS \| number \| The number of seconds until the current ship -will reach its apoapsis. -ETA:PERIAPSIS \| number \| The number of seconds until the current ship -will reach its periapsis. -ETA:TRANSITION \| number \| The number of seconds until the current ship -will leave the current sphere of influence and enter the sphere of -influence of another celestial body. +============== ======== ========== +Variable Type Meaning +============== ======== ========== +ETA:APOAPSIS number seconds until SHIP will reach its apoapsis. +ETA:PERIAPSIS number seconds until SHIP will reach its periapsis. +ETA:TRANSITION number seconds until SHIP will leave its SOI to enter the SOI of another body. +============== ======== ========== ENCOUNTER --------- The body being encountered next by the current vessel. Returns the special string "None" if there is no expected encounter, or an object of -type `Body <../structures/body/index.html>`__ if an encounter is +type `Body `__ if an encounter is expected. BOOLEAN TOGGLE FIELDS: @@ -174,41 +173,52 @@ so you might need to check for both the change in state from false to true AND the change in state from true to false to see if the key was hit. -Variable Name \| Can Read \| Can Set \| Description -==============\|==========\|=========\|=============== -SAS \| yes \| yes \| Is the SAS stabalizer control enabled right now? -(Same as "SAS" indicator on the navball.) -RCS \| yes \| yes \| Is the RCS thrust flag enbabled right now? (Same as -"RCS" indicator on the navball.) -GEAR \| yes \| yes \| Is the GEAR enabled right now? (Note, KSP does -some strange things with this flag, like needing to hit it twice the -first time). -LEGS \| yes \| yes \| Are the landing LEGS extended? (as opposed to GEAR -which is for the wheels of a plane.) -CHUTES \| yes \| yes \| Are the parachutes extended? (Treats all -parachutes as one single unit. Does not activate them individually.) -LIGHTS \| yes \| yes \| Are the lights on? (like the "U" key in manual -flight.) -PANELS \| yes \| yes \| Are the solar panels extended? (Treats all solar -panels as one single unit. Does not activate them individually.) -BRAKES \| yes \| yes \| Are the brakes on? -ABORT \| yes \| yes \| Abort Action Group. -AG1 \| yes \| yes \| Action Group 1. -AG2 \| yes \| yes \| Action Group 2. -AG3 \| yes \| yes \| Action Group 3. -AG4 \| yes \| yes \| Action Group 4. -AG5 \| yes \| yes \| Action Group 5. -AG6 \| yes \| yes \| Action Group 6. -AG7 \| yes \| yes \| Action Group 7. -AG8 \| yes \| yes \| Action Group 8. -AG9 \| yes \| yes \| Action Group 9. -AG10 \| yes \| yes \| Action Group 10. +============== ========== ========= =============== +Variable Name Can Read Can Set Description +============== ========== ========= =============== +SAS yes yes (Same as "SAS" indicator on the navball.) +RCS yes yes (Same as "RCS" indicator on the navball.) +GEAR yes yes Is the GEAR enabled right now? (Note, KSP does some strange things with this flag, like needing to hit it twice the first time). +LEGS yes yes Are the landing LEGS extended? (as opposed to GEAR which is for the wheels of a plane.) +CHUTES yes yes Are the parachutes extended? (Treats all parachutes as one single unit. Does not activate them individually.) +LIGHTS yes yes Are the lights on? (like the "U" key in manual flight.) +PANELS yes yes Are the solar panels extended? (Treats all solar panels as one single unit. Does not activate them individually.) +BRAKES yes yes Are the brakes on? +ABORT yes yes Abort Action Group. +AG1 yes yes Action Group 1. +AG2 yes yes Action Group 2. +AG3 yes yes Action Group 3. +AG4 yes yes Action Group 4. +AG5 yes yes Action Group 5. +AG6 yes yes Action Group 6. +AG7 yes yes Action Group 7. +AG8 yes yes Action Group 8. +AG9 yes yes Action Group 9. +AG10 yes yes Action Group 10. +AGn yes yes If you have the Action Groups Extended mod installed, you can access its groups the same way, i.e. AG11, AG12, AG13, etc. +============== ========== ========= =============== Flight Control -------------- -A summary page describing the basics of controlling the flight of a ship -`can be found here <../summary_topics/ship_control/index.html>`__ +There are bound variables used in controlling the flight of a ship, which +can be found at the following links: + +If you want to let kOS do a lot of the work of alignging to a desired +heading for you, use `Cooked Control `__. + +If you want your script to manipulate the controls directly (as in "set +yaw axis halfway left for a few seconds (using the 'A' key)", then +use `Raw Control `__. + +If you want to be able to READ what the player is attempting to do +while your script is running, and perhaps respond to it, then use +`Reading the Pilot's Control settings (i.e reading what the manual input is attempting) `__ +(By default your script will override manual piloting attempts, but +you can read what the pilot's controls are set at and make your +autopilot take them under advisement - sort of like how a +fly-by-wire plane works.) + Controls that must be used with LOCK ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -248,7 +258,7 @@ CONFIG is a special variable name that refers to the configuration settings for the kOS mod, and can be used to set or get various options. -`CONFIG has its own page <../structure/config/index.html>`__ for further +`CONFIG has its own page `__ for further details. Game State @@ -256,15 +266,12 @@ Game State Variables that have something to do with the state of the universe. -Variable \| Type \| Meaning -=========\|======\|========= -TIME \| `Time <../structure/time/index.html>`__ \| Simulated amount of -time that passed since the beginning of the game's universe epoch. (A -brand new campaign that just started begins at TIME zero.) -MAPVIEW \| boolean \| Both settable and gettable. If you query MAPVIEW, -it's true if on the map screen, and false if on the flight view screen. -If you SET MAPVIEW, you can cause the game to switch between mapview and -flight view or visa versa. +========= ====================================== ============== +Variable Type Meaning +========= ====================================== ============== +TIME `Time `__ Simulated amount of time that passed since the beginning of the game's universe epoch. (A brand new campaign that just started begins at TIME zero.) +MAPVIEW boolean Both settable and gettable. If you query MAPVIEW, it's true if on the map screen, and false if on the flight view screen. If you SET MAPVIEW, you can cause the game to switch between mapview and flight view or visa versa. +========= ====================================== ============== TIME is a useful system variable for calculating the passage of time between taking @@ -285,7 +292,7 @@ time, which is what TIME returns. It's important to be aware of the `frozen update -nature <../summary_topics/CPU_hardware/index.html#FROZEN>`__ of the kOS +nature `__ of the kOS computer when reading TIME. .. |Resources| image:: /_images/reference/bindings/resources.png diff --git a/doc/source/commands/parts.rst b/doc/source/commands/parts.rst index 83414d561..778f366a9 100644 --- a/doc/source/commands/parts.rst +++ b/doc/source/commands/parts.rst @@ -4,7 +4,7 @@ Querying a vessel's parts This is a quick list to get the idea across fast. The actual details of the meaning of these things is complex enough to warrant `its own -topic <../../summary_topics/ship_parts_and_modules/index.html>`__. +topic <../general/parts_and_partmodules.html>`__. To get the parts of a vessel (such as your current vessel, called SHIP), you can do the following things: diff --git a/doc/source/general/nametag.rst b/doc/source/general/nametag.rst index 643abb6a6..90cf88cf7 100644 --- a/doc/source/general/nametag.rst +++ b/doc/source/general/nametag.rst @@ -3,6 +3,8 @@ The Name Tag System =================== +.. figure:: /_images/nametag.png + One useful thing to do is to be able to give parts on a craft your own chosen names that you can use to get a reference to the parts, utterly bypassing the naming schemes used by KSP, and ignoring the complex part tree system. The Name Tag system was designed to make it possible for you to just give any part on a craft whatever arbitrary name you feel like. .. contents:: @@ -28,7 +30,7 @@ Giving a Part a Name 3. From now on this part can be retrieved using either the :PARTSDUBBED or the :PARTSTAGGED methods of the vessel, as described - `on the Vessel Page <../../structure/vessel/index.html>`__ + `on the Vessel Page <../structures/vessels/vessel.html>`__ Cloning with Symmetry --------------------- diff --git a/doc/source/general/parts_and_partmodules.rst b/doc/source/general/parts_and_partmodules.rst index a33e37050..a16484814 100644 --- a/doc/source/general/parts_and_partmodules.rst +++ b/doc/source/general/parts_and_partmodules.rst @@ -34,7 +34,7 @@ Accessing the parts by various naming systems Any time you have a vessel variable, you can use these suffixes to get lists of parts on it by their names using several different naming schemes: -**Part Tag**: A part's *tag* is whatever custom name you have given it using the `nametag system described here <../nametag/index.html>`__. This is probably the best naming convention to use because it lets you make up whatever name you like for the part and use it to pick the parts you want to deal with in your script. +**Part Tag**: A part's *tag* is whatever custom name you have given it using the `nametag system described here `__. This is probably the best naming convention to use because it lets you make up whatever name you like for the part and use it to pick the parts you want to deal with in your script. **Part Title**: A part's *title* is the name it has inside the GUI interface on the screen that you see as the user. @@ -71,7 +71,7 @@ In all cases the checks are performed case-insensitively. These are different styles of naming parts, all slightly different, and you can use any of them you like to get access to the part or parts you're interested in. -They all return a `List <../../structure/list/index.html>`__ of `Parts <../../structure/index.html>`__ rather than just one single part. This is because any name could have more than one hit. If you expect to get just one single hit, you can just look at the zero-th value of the list, like so:: +They all return a `List <../structures/misc/list.html>`__ of `Parts <../structures/vessels/part.html>`__ rather than just one single part. This is because any name could have more than one hit. If you expect to get just one single hit, you can just look at the zero-th value of the list, like so:: SET onePart TO somevessel:PARTSDUBBED("my favorite engine")[0]. @@ -89,6 +89,9 @@ Examples:: somechute:GETMODULE("ModuleParachute"):SETFIELD("DEPLOYALTITUDE", 1500). }. +.. figure:: /_images/ship_parts_tree.png + :align: right + Accessing the parts list as a tree ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -119,7 +122,7 @@ Return a List of just the parts that have had some sort of activity attached to PartModules and the right-click menu: ------------------------------------- -Each Part, in turn has a list of what are called `PartModules <../../structure/partmodule/index.html>`__ on it. A PartModule is a collection of variables and executable program hooks that gives the part some of its behaviors and properties. Without a PartModule, a part is really nothing more than a passive bit of structure that has nothing more than a shape, a look, and a strength to it. Some of the parts in the "structure" tab of the parts bin, like pure I-beams and girders, are like this - they have no PartModules on them. But all of the *interesting* parts you might want to do something with will have a PartModule on them. Through PartModules, \*\*kOS will now allow you to manipulate or query anything that any KSP programmer, stock or mod, has added to the rightclick menu\*\*, or action group actions, for a part. +Each Part, in turn has a list of what are called `PartModules <../structures/vessels/partmodule.html>`__ on it. A PartModule is a collection of variables and executable program hooks that gives the part some of its behaviors and properties. Without a PartModule, a part is really nothing more than a passive bit of structure that has nothing more than a shape, a look, and a strength to it. Some of the parts in the "structure" tab of the parts bin, like pure I-beams and girders, are like this - they have no PartModules on them. But all of the *interesting* parts you might want to do something with will have a PartModule on them. Through PartModules, \*\*kOS will now allow you to manipulate or query anything that any KSP programmer, stock or mod, has added to the rightclick menu\*\*, or action group actions, for a part. PartModules, Stock vs Mods: ~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/doc/source/structures/misc/config.rst b/doc/source/structures/misc/config.rst index 0473c9bc9..6027bdf03 100644 --- a/doc/source/structures/misc/config.rst +++ b/doc/source/structures/misc/config.rst @@ -23,7 +23,7 @@ Configuration of kOS * - :attr:`IPU` - integer - - + - 150 - Instructions per update * - :attr:`UCP` - boolean @@ -49,6 +49,18 @@ Configuration of kOS - boolean - False - Enable verbose exceptions + * - :attr:`TELNET` + - boolean + - False + - activate the telnet server + * - :attr:`TPORT` + - integer + - 5410 + - set the port the telnet server will run on + * - :attr:`LOOPBACK` + - boolean + - True + - Force the telnet server to use loopback (127.0.0.1) address .. attribute:: Config:IPU @@ -116,7 +128,6 @@ Configuration of kOS If false, then these operations are permitted, but the result may lead to code that does not function correctly if you are not careful about how you use it. Using a value that is not a real number may result in freezing Kerbal Space Program itself if that value is used in a variable that is passed into Kerbal Space Program's API routines. KSP's own API interface does not seem to have any protective checks in place and will faithfully try to use whatever values its given. - .. attribute:: Config:VERBOSE :access: Get/Set @@ -126,4 +137,58 @@ Configuration of kOS If true, then it enables a mode in which errors coming from kOS are very long and verbose, trying to explain every detail of the problem. +.. attribute:: Config:TELNET + + :access: Get/Set + :type: boolean + + Configures the ``EnableTelnet`` setting. + + When set to true, it activates a + `kOS telnet server in game <../../general/telnet.html>`__ that allows you to + connect external terminal programs like Putty and Xterm to it. + Turning the option off or on immediately toggles the server. (When + you change it from false to true, it will start the server right then. + When you change it from true to false, it will stop the server right + then.) Therefore **to restart the server** after changing a setting like + :attr:`TPORT`, DO this:: + + // Restart telnet server: + SET CONFIG:TELNET TO FALSE. + WAIT 0.5. // important to give kOS a moment to notice and kill the old server. + SET CONFIG:TELNET TO TRUE. + + Of course, you can do the equivalent of that by using the GUI config panel and just + clicking the button off then clicking it on. + +.. attribute:: Config:TPORT + + :access: Get/Set + :type: boolean + + Configures the ``TelnetPort`` setting. + + Changes the TCP/IP port number that the + `kOS telnet server in game <../../general/telnet.html>`__ + will listen to. + + To make the change take effect you may have to + stop, then restart the telnet server, as described above. + +.. attribute:: Config:LOOPBACK + + :access: Get/Set + :type: boolean + + Configures the ``TelnetLoopback`` setting. + + If true, then it tells the + `kOS telnet server in game <../../general/telnet.html>`__ + to refuse to use the computer's actual IP address, and + instead use the loopback address (127.0.0.1). This is + the default mode the kOS mod ships in, in order to + make it impossible get external access to your computer. + + To make the change take effect you may have to + stop, then restart the telnet server, as described above. diff --git a/doc/source/structures/misc/time.rst b/doc/source/structures/misc/time.rst index 7f1b602a8..8fe22e6ca 100644 --- a/doc/source/structures/misc/time.rst +++ b/doc/source/structures/misc/time.rst @@ -9,7 +9,10 @@ In several places the game uses a :struct:`TimeSpan` format. This is a strucure TimeSpan represents *SIMULATED* time ------------------------------------ -When you are examining a :struct:`TimeSpan` you are looking the "in character" **simulated** time, not the "out of character" real world time. This is very important distinction to remember, as the following points illustrate: +When you are examining a :struct:`TimeSpan` you are looking at the +"in character" **simulated** time, not the "out of character" real +world time. This is a very important distinction to remember, as +the following points illustrate: - A :struct:`TimeSpan` does not count the time that was passing while the game was paused. - If you turn off your computer and don't play the game for several days, the :struct:`TimeSpan` does not count this time. diff --git a/doc/source/tutorials/designpatterns.rst b/doc/source/tutorials/designpatterns.rst index c4da06dca..a9a4a5de6 100644 --- a/doc/source/tutorials/designpatterns.rst +++ b/doc/source/tutorials/designpatterns.rst @@ -176,7 +176,7 @@ Understanding why this does not work is important. Everything in a WHEN/THEN blo Now this program should work. The variable dthrott had to be set to 0 in the beginning so that the throttle is kept at maximum until 1km, the UNTIL loop operates every 0.1 seconds, and the WHEN/THEN triggers are run only once when the condition is met. The take-away from this example is to keep WHEN/THEN blocks separate from UNTIL loops. Specifically, never put an UNTIL loop inside a WHEN/THEN block and it should be extremely rare to put a WHEN/THEN statement inside an UNTIL loop. -Finally, as a bit of foreshadowing, this bit of code is actually a "`proportional feedback loop `__." From an altitude of 1km up to 40km, the total g-force exerted on the ship is kept near 1.2 by constantly adjusting the throttle. The value of 1.2 is called the "setpoint," the measured g-force is called the "process variable," and the mystical 0.05 is called the "proportional gain." Please take a look at the `PID Loop Tutorial <../pidloop_tutorial/index.html>`__ which takes this script as a starting point and develops a full PID-loop in kOS. +Finally, as a bit of foreshadowing, this bit of code is actually a "`proportional feedback loop `__." From an altitude of 1km up to 40km, the total g-force exerted on the ship is kept near 1.2 by constantly adjusting the throttle. The value of 1.2 is called the "setpoint," the measured g-force is called the "process variable," and the mystical 0.05 is called the "proportional gain." Please take a look at the `PID Loop Tutorial `__ which takes this script as a starting point and develops a full PID-loop in kOS. 2. Minimize Trigger Conditions ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/doc/source/tutorials/quickstart.rst b/doc/source/tutorials/quickstart.rst index bf456de20..e5c549c41 100644 --- a/doc/source/tutorials/quickstart.rst +++ b/doc/source/tutorials/quickstart.rst @@ -245,7 +245,7 @@ So to fix that problem, let's add steering control to the script. The easy way to control steering is to use the ``LOCK STEERING`` command. -Once you have mastered the basics of **kOS**, you should go and read `the documentation on ship steering techniques <../ship_control/index.html>`__, but that's a more advanced topic for later. +Once you have mastered the basics of **kOS**, you should go and read `the documentation on ship steering techniques <../commands/flight.html>`__, but that's a more advanced topic for later. The way to use the ``LOCK STEERING`` command is to set it to a thing called a :struct:`Vector` or a :struct:`Direction`. There are several Directions built-in to **kOS**, one of which is called "UP". "UP" is a Direction that always aims directly toward the sky (the center of the blue part of the navball). @@ -304,11 +304,11 @@ Step 5: Add staging logic The logic for how and when to stage can be an interesting and fun thing to write yourself. This example will keep it very simple, and this is the part where it's important that you are using a vessel that only contains liquidfuel engines. If your vessel has some booster engines, then it would require a more sophisticated script to launch it correctly than this tutorial gives you. -To add the logic to check when to stage, we introduce a new concept called the WHEN trigger. To see full documentation on it when you finish the tutorial, look for it on the `Flow Control page <../../command/flowControl/index.html>`__ +To add the logic to check when to stage, we introduce a new concept called the WHEN trigger. To see full documentation on it when you finish the tutorial, look for it on the `Flow Control page <../language/flow.html>`__ The quick and dirty explanation is that a WHEN section is a short section of code that you set up to run LATER rather than right now. It creates a check in the background that will constantly look for some condition to occur, and when it happens, it interrupts whatever else the code is doing, and it will run the body of the WHEN code before continuing from where it left off in the main script. -There are some complex dangers with writing WHEN triggers that can cause **KSP** itself to hang or stutter if you are not careful, but explaining them is beyond the scope of this tutorial. But when you want to start using WHEN triggers yourself, you really should read the section on WHEN in the `Flow Control page <../../command/flowControl/index.html>`__ before you do so. +There are some complex dangers with writing WHEN triggers that can cause **KSP** itself to hang or stutter if you are not careful, but explaining them is beyond the scope of this tutorial. But when you want to start using WHEN triggers yourself, you really should read the section on WHEN in the `Flow Control page <../language/flow.html>`__ before you do so. The WHEN trigger we are going to add to the launch script looks like this:: From c054e661a529220f5774f67e9c10b9bded2a65b9 Mon Sep 17 00:00:00 2001 From: Chris Woerz Date: Mon, 16 Feb 2015 15:14:32 -0700 Subject: [PATCH 161/446] fixes #72 and fixes #548 --- doc/source/structures.rst | 1 + doc/source/structures/vessels/stage.rst | 98 +++++++++++++++++++++++++ src/kOS/Function/Misc.cs | 16 +++- src/kOS/Suffixed/StageValues.cs | 3 + 4 files changed, 117 insertions(+), 1 deletion(-) create mode 100644 doc/source/structures/vessels/stage.rst diff --git a/doc/source/structures.rst b/doc/source/structures.rst index b0ffa4be9..e74df9078 100644 --- a/doc/source/structures.rst +++ b/doc/source/structures.rst @@ -28,6 +28,7 @@ A general discussion of structures :ref:`can be found here * :struct:`AggregateResource` * :struct:`DockingPort` * :struct:`Gimbal` + * :struct:`Stage` * :struct:`Part` * :struct:`PartModule` * :struct:`Sensor` diff --git a/doc/source/structures/vessels/stage.rst b/doc/source/structures/vessels/stage.rst new file mode 100644 index 000000000..c99578d6b --- /dev/null +++ b/doc/source/structures/vessels/stage.rst @@ -0,0 +1,98 @@ +.. _stage: + +Stage +============= + +*Contents* + + - :global:`EXAMPLE` + - :global:`READY` + - :global:`RESOURCES` + - :struct:`Stage` + +A planned velocity change along an orbit. These are the nodes that you can set in the KSP user interface. Setting one through kOS will make it appear on the in-game map view, and creating one manually on the in-game map view will cause it to be visible to kOS. + +Access +-------- + +You access the current stage for the vessel the kOS core is attached to with the STAGE: command. + +.. global::EXAMPLE + + + A very simple auto-stager using :READY + + LIST ENGINES IN elist. + + UNTIL false { + PRINT "Stage: " + STAGE:NUMBER AT (0,0). + FOR e IN elist { + IF e:FLAMEOUT { + STAGE. + PRINT "STAGING!" AT (0,0). + + UNTIL STAGE:READY { } + + LIST ENGINES IN elist. + CLEARSCREEN. + BREAK. + } + } + } + +.. global::NUMBER + + Every craft has a current stage, and that stage is represented by a number, this is it! + +.. global::RESOURCES + + + +Structure +--------- + +.. structure:: Stage + + .. list-table:: Members + :header-rows: 1 + :widths: 1 1 1 2 + + * - Suffix + - Type (units) + - Access + - Description + + * - :attr:`READY` + - bool + - Get only + - Is the craft ready to activate the next stage. + * - :attr:`NUMBER` + - scalar + - Get only + - The current stage number for the craft + * - :attr:`RESOURCES` + - :struct:`List` + - Get only + - the :struct:`List` of :struct:`Resource` in the current stage + +.. attribute:: Stage:READY + + :access: Get only + :type: bool + + Kerbal Space Program enforces a small delay between staging commands, this is to allow the last staging command to complete. This bool value will let you know if kOS can activate the next stage. + +.. attribute:: Stage:NUMBER + + :access: Get only + :type: scalar + + Every craft has a current stage, and that stage is represented by a number, this is it! + +.. attribute:: Stage:Resources + + :access: Get + :type: :struct:`List` + + This is a collection of the available :struct:`Resource` for the current stage. + \ No newline at end of file diff --git a/src/kOS/Function/Misc.cs b/src/kOS/Function/Misc.cs index fe813299c..9a3dcb6ea 100644 --- a/src/kOS/Function/Misc.cs +++ b/src/kOS/Function/Misc.cs @@ -1,11 +1,14 @@ using System; using System.Collections.Generic; +using FinePrint.Utilities; using kOS.Execution; using kOS.Safe.Compilation; +using kOS.Safe.Exceptions; using kOS.Safe.Function; using kOS.Safe.Module; using kOS.Safe.Persistence; using kOS.Suffixed; +using kOS.Utilities; namespace kOS.Function { @@ -57,7 +60,18 @@ public class FunctionStage : FunctionBase { public override void Execute(SharedObjects shared) { - Staging.ActivateNextStage(); + if (Staging.separate_ready && shared.Vessel.isActiveVessel) + { + Staging.ActivateNextStage(); + } + else if (!Staging.separate_ready) + { + Safe.Utilities.Debug.Logger.Log("FAIL SILENT: Stage is called before it is ready, Use STAGE:READY to check first if staging rapidly"); + } + else if (!shared.Vessel.isActiveVessel) + { + throw new KOSCommandInvalidHere("STAGE", "a non-active SHIP, KSP does not support this", "Core is on the active vessel"); + } } } diff --git a/src/kOS/Suffixed/StageValues.cs b/src/kOS/Suffixed/StageValues.cs index 4e04af4af..48f817833 100644 --- a/src/kOS/Suffixed/StageValues.cs +++ b/src/kOS/Suffixed/StageValues.cs @@ -18,7 +18,10 @@ public StageValues(SharedObjects shared) private void InitializeSuffixes() { + AddSuffix("NUMBER", new Suffix(() => Staging.CurrentStage)); + AddSuffix("READY", new Suffix(() => shared.Vessel.isActiveVessel && Staging.separate_ready)); AddSuffix("RESOURCES", new Suffix>(GetResourceManifest)); + } private ListValue GetResourceManifest() From 4687fdc6425e57cfd844f9c1bc0bd970bd9d3fb5 Mon Sep 17 00:00:00 2001 From: Chris Woerz Date: Mon, 16 Feb 2015 15:22:20 -0700 Subject: [PATCH 162/446] doc work --- doc/source/structures/vessels/stage.rst | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/doc/source/structures/vessels/stage.rst b/doc/source/structures/vessels/stage.rst index c99578d6b..6e080b31c 100644 --- a/doc/source/structures/vessels/stage.rst +++ b/doc/source/structures/vessels/stage.rst @@ -6,18 +6,11 @@ Stage *Contents* - :global:`EXAMPLE` - - :global:`READY` - - :global:`RESOURCES` - :struct:`Stage` -A planned velocity change along an orbit. These are the nodes that you can set in the KSP user interface. Setting one through kOS will make it appear on the in-game map view, and creating one manually on the in-game map view will cause it to be visible to kOS. - -Access --------- - You access the current stage for the vessel the kOS core is attached to with the STAGE: command. -.. global::EXAMPLE +.. global::EXAMPLE A very simple auto-stager using :READY From 3d37fbb9b00cd653d9ab2f03d9ba9db4f33d6c24 Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Mon, 16 Feb 2015 23:21:35 -0600 Subject: [PATCH 163/446] fixes #571 - telnet clearsceen bug. Needed to explixitly set the prev screen buffer snapshot to a blank buffer when the telnet client is given a CLEARSCREEN directive, else the prev buffer stays at whatever the previous snapshot looked like prior to the clearscreen. So it does not represent what the terminal really looks like. --- src/kOS.Safe/Screen/ScreenSnapshot.cs | 18 ++++++++++++++++++ src/kOS/Screen/TermWindow.cs | 11 +++++++++++ 2 files changed, 29 insertions(+) diff --git a/src/kOS.Safe/Screen/ScreenSnapshot.cs b/src/kOS.Safe/Screen/ScreenSnapshot.cs index fd4a61dcf..232bc0975 100644 --- a/src/kOS.Safe/Screen/ScreenSnapshot.cs +++ b/src/kOS.Safe/Screen/ScreenSnapshot.cs @@ -47,6 +47,24 @@ public ScreenSnapShot(IScreenBuffer fromScreen) private ScreenSnapShot() { } + + /// + /// A factory that constructs an empty screen buffer of a correct size for the fromScreen + /// + /// The screen - only used to determine the needed width/height + /// An empty snapshot buffer + public static ScreenSnapShot EmptyScreen(IScreenBuffer fromScreen) + { + ScreenSnapShot newThing = new ScreenSnapShot(); + newThing.TopRow = fromScreen.TopRow; + newThing.CursorColumn = fromScreen.CursorColumnShow; + newThing.CursorRow = fromScreen.CursorRowShow; + newThing.RowCount = fromScreen.RowCount; + newThing.Buffer = new List(); + for (int i = 0; i < newThing.RowCount ; ++i) + newThing.Buffer.Add(new ScreenBufferLine(fromScreen.ColumnCount)); + return newThing; + } /// /// Make a copy of me for later diffing against. diff --git a/src/kOS/Screen/TermWindow.cs b/src/kOS/Screen/TermWindow.cs index b344ad4e5..0a7698b15 100644 --- a/src/kOS/Screen/TermWindow.cs +++ b/src/kOS/Screen/TermWindow.cs @@ -459,6 +459,14 @@ void SpecialKey(char key) } } + /// + /// Get the newest copy of the screen buffer once, for use in all calculations for a while. + /// This was added when telnet clients were added. The execution cost of obtaining a buffer snapshot + /// from the ScreenBuffer class is non-trivial, and therefore shouldn't be done over and over + /// for each telnet client that needs it within the span of a short time. This gets it + /// once for all of them to borrow. All calls will re-use this copy for a while, + /// until the next terminal refresh (1/20th of a second, at the moment). + /// void GetNewestBuffer() { DateTime newTime = DateTime.Now; @@ -796,7 +804,10 @@ public void ClearScreen() { shared.Screen.ClearScreen(); foreach (TelnetSingletonServer telnet in telnets) + { telnet.Write((char)UnicodeCommand.CLEARSCREEN); + prevTelnetScreens[telnet] = ScreenSnapShot.EmptyScreen(shared.Screen); + } } public int NumTelnets() From cb8ff6fe57c725fc17fb3e5317e82f0ea1623c75 Mon Sep 17 00:00:00 2001 From: Peter Goddard Date: Tue, 17 Feb 2015 13:09:46 -0500 Subject: [PATCH 164/446] Update Misc.cs --- src/kOS/Function/Misc.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kOS/Function/Misc.cs b/src/kOS/Function/Misc.cs index fd4336c4f..da4bbc5e6 100644 --- a/src/kOS/Function/Misc.cs +++ b/src/kOS/Function/Misc.cs @@ -29,7 +29,7 @@ public override void Execute(SharedObjects shared) } [Function("hudtext")] - public class FunctionHudTxt : FunctionBase + public class FunctionHudText : FunctionBase { public override void Execute(SharedObjects shared) From 6dd9a2517d2e435657361d4d25f97f76c046268a Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Tue, 17 Feb 2015 18:05:58 -0600 Subject: [PATCH 165/446] changed '==' to '=' --- doc/source/general/parts_and_partmodules.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/general/parts_and_partmodules.rst b/doc/source/general/parts_and_partmodules.rst index a16484814..74f9ad130 100644 --- a/doc/source/general/parts_and_partmodules.rst +++ b/doc/source/general/parts_and_partmodules.rst @@ -78,7 +78,7 @@ They all return a `List <../structures/misc/list.html>`__ of `Parts <../structur If the name does not exist, you can tell by seeing if the list returned has a length of zero:: - IF somevessel:PARTSDUBBED("my favorite engine"):LENGTH == 0 { + IF somevessel:PARTSDUBBED("my favorite engine"):LENGTH = 0 { PRINT "There is no part named 'my favorite engine'.". }. From d49fc3b0d71b81a5bbc69d4c810304ae1539b66d Mon Sep 17 00:00:00 2001 From: Peter Goddard Date: Wed, 18 Feb 2015 12:29:56 -0500 Subject: [PATCH 166/446] Update Misc.cs --- src/kOS/Function/Misc.cs | 66 ++++++++++++++++------------------------ 1 file changed, 27 insertions(+), 39 deletions(-) diff --git a/src/kOS/Function/Misc.cs b/src/kOS/Function/Misc.cs index da4bbc5e6..93a0f0825 100644 --- a/src/kOS/Function/Misc.cs +++ b/src/kOS/Function/Misc.cs @@ -27,52 +27,40 @@ public override void Execute(SharedObjects shared) shared.Screen.Print(textToPrint); } } - -[Function("hudtext")] + + [Function("hudtext")] public class FunctionHudText : FunctionBase { - - public override void Execute(SharedObjects shared) + public override void Execute (SharedObjects shared) { - int mirror = Convert.ToInt32(shared.Cpu.PopValue()); - string color = shared.Cpu.PopValue().ToString(); - int size = Convert.ToInt32(shared.Cpu.PopValue()); - int style = Convert.ToInt32(shared.Cpu.PopValue()); - int delay = Convert.ToInt32(shared.Cpu.PopValue()); - string textToHud = shared.Cpu.PopValue().ToString(); - - if (style == 1) - { - ScreenMessages.PostScreenMessage(""+textToHud+"", delay, ScreenMessageStyle.UPPER_LEFT); - } - else if (style == 2) - { - ScreenMessages.PostScreenMessage(""+textToHud+"", delay, ScreenMessageStyle.UPPER_CENTER); - } - else if (style == 3) - { - ScreenMessages.PostScreenMessage(""+textToHud+"", delay, ScreenMessageStyle.UPPER_RIGHT); - } - else if (style == 4) - { - ScreenMessages.PostScreenMessage(""+textToHud+"", delay, ScreenMessageStyle.LOWER_CENTER); - } - else - { - ScreenMessages.PostScreenMessage("*"+textToHud, 3f, ScreenMessageStyle.UPPER_CENTER); - } - if (mirror == 1) - { + bool echo = Convert.ToBoolean(shared.Cpu.PopValue()); + RgbaColor rgba = GetRgba(shared.Cpu.PopValue()); + int size = Convert.ToInt32 (shared.Cpu.PopValue ()); + int style = Convert.ToInt32 (shared.Cpu.PopValue ()); + int delay = Convert.ToInt32 (shared.Cpu.PopValue ()); + string textToHud = shared.Cpu.PopValue ().ToString (); + string htmlColour = rgba.ToHTMLString(); + { + if (style == 1) { + ScreenMessages.PostScreenMessage("" + textToHud + "",delay,ScreenMessageStyle.UPPER_LEFT); + } else if (style == 2) { + ScreenMessages.PostScreenMessage("" + textToHud + "",delay,ScreenMessageStyle.UPPER_CENTER); + } else if (style == 3) { + ScreenMessages.PostScreenMessage("" + textToHud + "",delay,ScreenMessageStyle.UPPER_RIGHT); + } else if (style == 4) { + ScreenMessages.PostScreenMessage("" + textToHud + "",delay,ScreenMessageStyle.LOWER_CENTER); + } else { + ScreenMessages.PostScreenMessage("*" + textToHud, 3f, ScreenMessageStyle.UPPER_CENTER); + } + if (echo) { shared.Screen.Print ("HUD: " + textToHud); - //shared.Screen.Print ("delay " + delay); - //shared.Screen.Print ("color " + color); - //shared.Screen.Print ("size " + size); - } - } - } + } + } + } + [Function("printat")] public class FunctionPrintAt : FunctionBase { From f26ef14500652ade1affabb3781455bde117109f Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Wed, 18 Feb 2015 23:38:40 -0600 Subject: [PATCH 167/446] Fixes #555 by altering the new vessel check logic. The old code had some wonky behavior where as long as the new vessel being switched to was valid... it refused to do the switch. --- src/kOS/Binding/FlightControlManager.cs | 29 +++++++++++++++++++------ src/kOS/Module/kOSProcessor.cs | 2 +- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/src/kOS/Binding/FlightControlManager.cs b/src/kOS/Binding/FlightControlManager.cs index 1542f4f84..364b347e1 100644 --- a/src/kOS/Binding/FlightControlManager.cs +++ b/src/kOS/Binding/FlightControlManager.cs @@ -71,18 +71,33 @@ public override void Update() { UnbindUnloaded(); - if (currentVessel.id == Shared.Vessel.id) return; - - // Try to re-establish connection to vessel - if (VesselIsValid(currentVessel)) + // Why the "currentVessel != null checks? + // Because of a timing issue where it can still be set to null during the span of one single + // update if the new vessel isn't valid and set up yet when the old vessel connection got + // broken off. + // + if (currentVessel != null && currentVessel.id == Shared.Vessel.id) return; + + // If it gets this far, that means the part the kOSProcessor module is inside of + // got disconnected from its original vessel and became a member + // of a new child vessel, either do to undocking, decoupling, or breakage. + + // currentVessel is now a stale reference to the vessel this manager used to be a member of, + // while Shared.Vessel is the new vessel it is now contained in. + + // Before updating currentVessel, use it to break connection from the old vessel, + // so this this stops trying to pilot the vessel it's not attached to anymore: + if (currentVessel != null && VesselIsValid(currentVessel)) { currentVessel.OnPreAutopilotUpdate -= OnFlyByWire; currentVessel = null; } - if (VesselIsValid(Shared.Vessel)) return; - - currentVessel = Shared.Vessel; + // If the new vessel isn't ready for it, then don't attach to it yet (wait for a future update): + if (! VesselIsValid(Shared.Vessel)) return; + + // Now attach to the new vessel: + currentVessel = Shared.Vessel; currentVessel.OnPreAutopilotUpdate += OnFlyByWire; foreach (var param in flightParameters.Values) diff --git a/src/kOS/Module/kOSProcessor.cs b/src/kOS/Module/kOSProcessor.cs index 5ce2fb32f..980a61cad 100644 --- a/src/kOS/Module/kOSProcessor.cs +++ b/src/kOS/Module/kOSProcessor.cs @@ -381,7 +381,7 @@ private void ProcessBoot() public void UpdateParts() { - // Trigger whenever the number of parts in the vessel changes (like when staging, docking or undocking) + // Trigger whenever the number of parts in the vessel changes (like when staging, docking or undocking). if (vessel.parts.Count == vesselPartCount) return; var missingHardDisks = false; From 0a02ffc04b3e530c79c71715a135b38f0bd16fa9 Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Thu, 19 Feb 2015 01:40:42 -0600 Subject: [PATCH 168/446] Merged pgodd's hudtext, with user docs added. --- doc/source/commands.rst | 2 +- doc/source/commands/terminal.rst | 64 ---------------- doc/source/commands/terminalgui.rst | 115 ++++++++++++++++++++++++++++ src/kOS/Function/Misc.cs | 34 ++++---- 4 files changed, 135 insertions(+), 80 deletions(-) delete mode 100644 doc/source/commands/terminal.rst create mode 100644 doc/source/commands/terminalgui.rst diff --git a/doc/source/commands.rst b/doc/source/commands.rst index fc9b92606..394b750c8 100644 --- a/doc/source/commands.rst +++ b/doc/source/commands.rst @@ -11,4 +11,4 @@ Command Reference Listing Data Parts Information File I/O - Terminal + Terminal and GUI diff --git a/doc/source/commands/terminal.rst b/doc/source/commands/terminal.rst deleted file mode 100644 index 0d0ceef19..000000000 --- a/doc/source/commands/terminal.rst +++ /dev/null @@ -1,64 +0,0 @@ -.. _terminal: - -Terminal and game environment -============================= - -.. global:: CLEARSCREEN - - - Clears the screen and places the cursor at the top left:: - - CLEARSCREEN. - -.. global:: PRINT - - Prints the selected text to the screen. Can print strings, or the result of an expression:: - - PRINT “Hello”. - PRINT 4+1. - PRINT “4 times 8 is: “ + (4*8). - -.. global:: SET TERMINAL:WIDTH. GET TERMINAL:WIDTH - - Gets or sets the terminal's width in characters. - -.. global:: SET TERMINAL:HEIGHT. GET TERMINAL:HEIGHT - - Gets or sets the terminal's height in characters. - -.. function:: AT(col,line) - - :parameter col: (integer) column starting with zero (left) - :parameter line: (integer) line starting with zero (top) - - Used in combination with :global:`PRINT`. Prints the selected text to the screen at specified location. Can print strings, or the result of an expression:: - - PRINT “Hello” AT(0,10). - PRINT 4+1 AT(0,10). - PRINT “4 times 8 is: “ + (4*8) AT(0,10). - -.. global:: MAPVIEW - - :access: Get/Set - :type: boolean - - A variable that controls or queries whether or not the game is in map view:: - - IF MAPVIEW { - PRINT "You are looking at the map.". - } ELSE { - PRINT "You are looking at the flight view.". - }. - - You can switch between map and flight views by setting this variable:: - - SET MAPVIEW TO TRUE. // to map view - SET MAPVIEW TO FALSE. // to flight view - -.. global:: REBOOT - - Reboots the kOS module. - -.. global:: SHUTDOWN - - Causes kOS module to shutdown. diff --git a/doc/source/commands/terminalgui.rst b/doc/source/commands/terminalgui.rst new file mode 100644 index 000000000..7f1dc77b8 --- /dev/null +++ b/doc/source/commands/terminalgui.rst @@ -0,0 +1,115 @@ +.. _terminal: + +Terminal and game environment +============================= + +.. global:: CLEARSCREEN + + + Clears the screen and places the cursor at the top left:: + + CLEARSCREEN. + +.. global:: PRINT + + Prints the selected text to the screen. Can print strings, or the result of an expression:: + + PRINT “Hello”. + PRINT 4+1. + PRINT “4 times 8 is: “ + (4*8). + +.. global:: SET TERMINAL:WIDTH. GET TERMINAL:WIDTH + + Gets or sets the terminal's width in characters. + +.. global:: SET TERMINAL:HEIGHT. GET TERMINAL:HEIGHT + + Gets or sets the terminal's height in characters. + +.. function:: AT(col,line) + + :parameter col: (integer) column starting with zero (left) + :parameter line: (integer) line starting with zero (top) + + Used in combination with :global:`PRINT`. Prints the selected text to the screen at specified location. Can print strings, or the result of an expression:: + + PRINT “Hello” AT(0,10). + PRINT 4+1 AT(0,10). + PRINT “4 times 8 is: “ + (4*8) AT(0,10). + +.. global:: MAPVIEW + + :access: Get/Set + :type: boolean + + A variable that controls or queries whether or not the game is in map view:: + + IF MAPVIEW { + PRINT "You are looking at the map.". + } ELSE { + PRINT "You are looking at the flight view.". + }. + + You can switch between map and flight views by setting this variable:: + + SET MAPVIEW TO TRUE. // to map view + SET MAPVIEW TO FALSE. // to flight view + +.. global:: REBOOT + + Reboots the kOS module. + +.. global:: SHUTDOWN + + Causes kOS module to shutdown. + +GUI display tools +------------------ + +.. global:: VECDRAW + + See VECDRAWARGS, below + +.. global:: VECDRAWARGS + + You can **draw visual vectors on the screen** in kOS to help debugging + or to help show the player information. The full description can be + found on the `Vecdraw Page <../structures/misc/vecdraw.html>`__. + +.. global:: HUDTEXT + + You can make text messages appear on the heads-up display, in the + same way that the in-game stock messages appear, by calling the + HUDTEXT function, as follows: + + HUDTEXT( string Message, integer delaySeconds, integer style, integer size, RGBA colour, boolean doEcho). + + Message + The message to show to the user on screen + delaySeconds + How long to make the message remain onscreen before it goes away. + If another message is drawn while an old message is still displaying, + both messages remain, the new message scrolls up the old message. + style + Where to show the message on the screen: + - 1 = upper left + - 2 = upper center + - 3 = lower right + - 4 = lower center + Note that all these locations have their own defined slightly + different fonts and default sizes, enforced by the stock KSP game. + size + A number describing the font point size: NOTE that the actual size + varies depending on which of the above styles you're using. Some + of the locations have a magnifying factor attached to their fonts. + colour + The colour to show the text in, using `one of the built-in colour names + or the RGB constructor to make one up <../structures/misc/rgba.html>`__ + doEcho + If true, then the message is also echoed to the terminal as "HUD: message". + + Examples:: + + HUDTEXT("Warning: Vertical Speed too High", 5, 2, 15, red, false). + HUDTEXT("docking mode begun", 8, 1, 12, rgb(1,1,0.5), false). + diff --git a/src/kOS/Function/Misc.cs b/src/kOS/Function/Misc.cs index d0aefcf23..f472da526 100644 --- a/src/kOS/Function/Misc.cs +++ b/src/kOS/Function/Misc.cs @@ -41,25 +41,29 @@ public override void Execute (SharedObjects shared) int delay = Convert.ToInt32 (shared.Cpu.PopValue ()); string textToHud = shared.Cpu.PopValue ().ToString (); string htmlColour = rgba.ToHTMLString(); - { - if (style == 1) { - ScreenMessages.PostScreenMessage("" + textToHud + "",delay,ScreenMessageStyle.UPPER_LEFT); - } else if (style == 2) { - ScreenMessages.PostScreenMessage("" + textToHud + "",delay,ScreenMessageStyle.UPPER_CENTER); - } else if (style == 3) { - ScreenMessages.PostScreenMessage("" + textToHud + "",delay,ScreenMessageStyle.UPPER_RIGHT); - } else if (style == 4) { - ScreenMessages.PostScreenMessage("" + textToHud + "",delay,ScreenMessageStyle.LOWER_CENTER); - } else { - ScreenMessages.PostScreenMessage("*" + textToHud, 3f, ScreenMessageStyle.UPPER_CENTER); + switch (style) + { + case 1: + ScreenMessages.PostScreenMessage("" + textToHud + "",delay,ScreenMessageStyle.UPPER_LEFT); + break; + case 2: + ScreenMessages.PostScreenMessage("" + textToHud + "",delay,ScreenMessageStyle.UPPER_CENTER); + break; + case 3: + ScreenMessages.PostScreenMessage("" + textToHud + "",delay,ScreenMessageStyle.UPPER_RIGHT); + break; + case 4: + ScreenMessages.PostScreenMessage("" + textToHud + "",delay,ScreenMessageStyle.LOWER_CENTER); + break; + default: + ScreenMessages.PostScreenMessage("*" + textToHud, 3f, ScreenMessageStyle.UPPER_CENTER); + break; } if (echo) { shared.Screen.Print ("HUD: " + textToHud); } - } - - } - + } + } [Function("printat")] public class FunctionPrintAt : FunctionBase From 7402da58779108cecb30899b6af1cc7a83efb140 Mon Sep 17 00:00:00 2001 From: Chris Woerz Date: Thu, 19 Feb 2015 11:53:41 -0700 Subject: [PATCH 169/446] fixes #563 --- src/kOS/Suffixed/FlightControl.cs | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/src/kOS/Suffixed/FlightControl.cs b/src/kOS/Suffixed/FlightControl.cs index 8ae4d7963..6ba6169e6 100644 --- a/src/kOS/Suffixed/FlightControl.cs +++ b/src/kOS/Suffixed/FlightControl.cs @@ -125,8 +125,10 @@ private void InitializePilotSuffixes() AddSuffix(new[] { "PILOTROLLTRIM" }, new Suffix(() => ReadPilot(ref FlightInputHandler.state.rollTrim))); AddSuffix(new[] { "PILOTPITCH" }, new Suffix(() => ReadPilot(ref FlightInputHandler.state.pitch))); AddSuffix(new[] { "PILOTPITCHTRIM" }, new Suffix(() => ReadPilot(ref FlightInputHandler.state.pitchTrim))); - AddSuffix(new[] { "PILOTFORE" }, new Suffix(() => ReadPilot(ref FlightInputHandler.state.Z))); - AddSuffix(new[] { "PILOTSTARBOARD" }, new Suffix(() => ReadPilot(ref FlightInputHandler.state.X))); + + AddSuffix(new[] { "PILOTFORE" }, new Suffix(() => Invert(ReadPilot(ref FlightInputHandler.state.Z)))); + AddSuffix(new[] { "PILOTSTARBOARD" }, new Suffix(() => Invert(ReadPilot(ref FlightInputHandler.state.X)))); + AddSuffix(new[] { "PILOTTOP" }, new Suffix(() => ReadPilot(ref FlightInputHandler.state.Y))); AddSuffix(new[] { "PILOTWHEELTHROTTLE" }, new Suffix(() => ReadPilot(ref FlightInputHandler.state.wheelThrottle))); AddSuffix(new[] { "PILOTWHEELTHROTTLETRIM" }, new Suffix(() => ReadPilot(ref FlightInputHandler.state.wheelThrottleTrim))); @@ -189,11 +191,21 @@ private Vector GetPilotTranslation() { if (Vessel == FlightGlobals.ActiveVessel) { - return new Vector(FlightInputHandler.state.X, FlightInputHandler.state.Y, FlightInputHandler.state.Z); + return new Vector( + Invert(FlightInputHandler.state.X), + FlightInputHandler.state.Y, + Invert(FlightInputHandler.state.Z) + ); } return Vector.Zero; } + private float Invert(float f) + { + // starboard and fore are reversed in KSP so we invert them here + return f * -1; + } + private Vector GetPilotRotation() { if (Vessel == FlightGlobals.ActiveVessel) @@ -362,10 +374,9 @@ private void PushNewSetting(ref FlightCtrlState st) if(Math.Abs(pitchTrim) > SETTING_EPILSON) st.pitchTrim = pitchTrim; if(Math.Abs(rollTrim) > SETTING_EPILSON) st.rollTrim = rollTrim; - // starboard and fore are reversed in KSP so we invert them here - if(Math.Abs(starboard) > SETTING_EPILSON) st.X = starboard * -1; + if(Math.Abs(starboard) > SETTING_EPILSON) st.X = Invert(starboard); if(Math.Abs(top) > SETTING_EPILSON) st.Y = top; - if(Math.Abs(fore) > SETTING_EPILSON) st.Z = fore * -1; + if(Math.Abs(fore) > SETTING_EPILSON) st.Z = Invert(fore); if(Math.Abs(wheelSteer) > SETTING_EPILSON) st.wheelSteer = wheelSteer; if(Math.Abs(wheelThrottle) > SETTING_EPILSON) st.wheelThrottle = wheelThrottle; From 1eb07a6eb2c451cf5b1fc424d0615c49b9d26906 Mon Sep 17 00:00:00 2001 From: Chris Woerz Date: Thu, 19 Feb 2015 11:52:20 -0700 Subject: [PATCH 170/446] when we are changing power states, we should unbind from steering --- src/kOS/Module/kOSProcessor.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/kOS/Module/kOSProcessor.cs b/src/kOS/Module/kOSProcessor.cs index 980a61cad..c103085a5 100644 --- a/src/kOS/Module/kOSProcessor.cs +++ b/src/kOS/Module/kOSProcessor.cs @@ -535,6 +535,7 @@ public void SetMode(ProcessorModes newProcessorMode) case ProcessorModes.STARVED: if (shared.Interpreter != null) shared.Interpreter.SetInputLock(true); if (shared.Window != null) shared.Window.IsPowered = false; + if (shared.BindingMgr != null) shared.BindingMgr.UnBindAll(); break; } From c766c48e8deb61f547b13bfdffc1467a802bde12 Mon Sep 17 00:00:00 2001 From: Chris Woerz Date: Thu, 19 Feb 2015 18:26:43 -0700 Subject: [PATCH 171/446] reboot now turns the processor off, then back on again --- src/kOS/Function/Misc.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/kOS/Function/Misc.cs b/src/kOS/Function/Misc.cs index f472da526..9ffe01261 100644 --- a/src/kOS/Function/Misc.cs +++ b/src/kOS/Function/Misc.cs @@ -278,7 +278,11 @@ public class FunctionReboot : FunctionBase { public override void Execute(SharedObjects shared) { - if (shared.Cpu != null) shared.Cpu.Boot(); + if (shared.Processor != null) + { + shared.Processor.SetMode(ProcessorModes.OFF); + shared.Processor.SetMode(ProcessorModes.READY); + } } } From 0409e0684123b3cfb2977b49a224ae4fc9967d5c Mon Sep 17 00:00:00 2001 From: Chris Woerz Date: Thu, 19 Feb 2015 11:49:31 -0700 Subject: [PATCH 172/446] switching debug statements to the kosLogger --- src/kOS/Binding/BindingsUniverse.cs | 2 +- src/kOS/Binding/FlightControlManager.cs | 12 ++++++------ src/kOS/Suffixed/Config.cs | 4 ++-- src/kOS/Suffixed/FlightControl.cs | 8 ++++---- src/kOS/Utilities/Utils.cs | 4 ++-- 5 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/kOS/Binding/BindingsUniverse.cs b/src/kOS/Binding/BindingsUniverse.cs index 3ab56d231..7e05bf11a 100644 --- a/src/kOS/Binding/BindingsUniverse.cs +++ b/src/kOS/Binding/BindingsUniverse.cs @@ -28,7 +28,7 @@ public override void AddTo(SharedObjects shared) } catch (Exception ex) { - UnityEngine.Debug.Log(ex.Message); + Safe.Utilities.Debug.Logger.Log(ex.Message); return false; } return true; diff --git a/src/kOS/Binding/FlightControlManager.cs b/src/kOS/Binding/FlightControlManager.cs index 364b347e1..dd6571efb 100644 --- a/src/kOS/Binding/FlightControlManager.cs +++ b/src/kOS/Binding/FlightControlManager.cs @@ -32,7 +32,7 @@ public override void AddTo(SharedObjects shared) return; } - Debug.Log("kOS: FlightControlManager.AddTo " + Shared.Vessel.id); + Safe.Utilities.Debug.Logger.Log("FlightControlManager.AddTo " + Shared.Vessel.id); currentVessel = shared.Vessel; currentVessel.OnPreAutopilotUpdate += OnFlyByWire; @@ -57,7 +57,7 @@ private void OnFlyByWire(FlightCtrlState c) public void ToggleFlyByWire(string paramName, bool enabled) { - Debug.Log(string.Format("kOS: FlightControlManager: ToggleFlyByWire: {0} {1}", paramName, enabled)); + Safe.Utilities.Debug.Logger.Log(string.Format("FlightControlManager: ToggleFlyByWire: {0} {1}", paramName, enabled)); if (!flightParameters.ContainsKey(paramName)) return; flightParameters[paramName].Enabled = enabled; @@ -126,7 +126,7 @@ private static void UnbindUnloaded() { var value = flightControls[key]; if (value.Vessel.loaded) continue; - Debug.Log("kOS: Unloading " + value.Vessel.vesselName); + Safe.Utilities.Debug.Logger.Log("Unloading " + value.Vessel.vesselName); toRemove.Add(key); value.Dispose(); } @@ -203,7 +203,7 @@ public bool Enabled get { return enabled; } set { - Debug.Log(string.Format("kOS: FlightCtrlParam: Enabled: {0} {1}", name, enabled)); + Safe.Utilities.Debug.Logger.Log(string.Format("FlightCtrlParam: Enabled: {0} {1}", name, enabled)); enabled = value; if (RemoteTechHook.IsAvailable(control.Vessel.id)) @@ -222,12 +222,12 @@ private void HandleRemoteTechPilot() } if (Enabled) { - Debug.Log(string.Format("kOS: Adding RemoteTechPilot: " + name + " For : " + control.Vessel.id)); + Safe.Utilities.Debug.Logger.Log(string.Format("Adding RemoteTechPilot: " + name + " For : " + control.Vessel.id)); RemoteTechHook.Instance.AddSanctionedPilot(control.Vessel.id, action); } else { - Debug.Log(string.Format("kOS: Removing RemoteTechPilot: " + name + " For : " + control.Vessel.id)); + Safe.Utilities.Debug.Logger.Log(string.Format("Removing RemoteTechPilot: " + name + " For : " + control.Vessel.id)); RemoteTechHook.Instance.RemoveSanctionedPilot(control.Vessel.id, action); } } diff --git a/src/kOS/Suffixed/Config.cs b/src/kOS/Suffixed/Config.cs index 28f66ad07..f4e242793 100644 --- a/src/kOS/Suffixed/Config.cs +++ b/src/kOS/Suffixed/Config.cs @@ -69,13 +69,13 @@ private void LoadConfig() if (value != null) { key.Value = value; - UnityEngine.Debug.LogError(string.Format("kOS: Loading Config: {0} Value: {1}", key.StringKey, value)); + Safe.Utilities.Debug.Logger.Log(string.Format("kOS: Loading Config: {0} Value: {1}", key.StringKey, value)); } } } catch (Exception ex) { - UnityEngine.Debug.LogError("kOS: Exception Loading Config: " + ex.Message); + Safe.Utilities.Debug.Logger.Log("kOS: Exception Loading Config: " + ex.Message); } } diff --git a/src/kOS/Suffixed/FlightControl.cs b/src/kOS/Suffixed/FlightControl.cs index 6ba6169e6..bd81ed2db 100644 --- a/src/kOS/Suffixed/FlightControl.cs +++ b/src/kOS/Suffixed/FlightControl.cs @@ -87,7 +87,7 @@ public override bool SetSuffix(string suffixName, object value) public void Unbind() { - UnityEngine.Debug.Log("kOS: FlightControl Unbinding"); + Debug.Logger.Log("kOS: FlightControl Unbinding"); if (!bound) return; if (RemoteTechHook.IsAvailable()) @@ -99,7 +99,7 @@ public void Unbind() Vessel.OnPreAutopilotUpdate -= OnFlyByWire; } bound = false; - UnityEngine.Debug.Log("kOS: FlightControl Unbound"); + Debug.Logger.Log("kOS: FlightControl Unbound"); } public void UpdateVessel(Vessel toUpdate) @@ -281,7 +281,7 @@ private static bool ValueToFloat(object value, ref float doubleValue) private void Bind() { - UnityEngine.Debug.Log("kOS: FlightControl Binding"); + Debug.Logger.Log("kOS: FlightControl Binding"); if (bound) return; if (RemoteTechHook.IsAvailable(Vessel.id)) @@ -293,7 +293,7 @@ private void Bind() Vessel.OnPreAutopilotUpdate += OnFlyByWire; } bound = true; - UnityEngine.Debug.Log("kOS: FlightControl Bound"); + Debug.Logger.Log("kOS: FlightControl Bound"); } private bool CheckKillRotation(string suffixName, object value) diff --git a/src/kOS/Utilities/Utils.cs b/src/kOS/Utilities/Utils.cs index 400a31b4a..870c0b4dc 100644 --- a/src/kOS/Utilities/Utils.cs +++ b/src/kOS/Utilities/Utils.cs @@ -157,8 +157,8 @@ public static Boolean BodyOrbitsBody(CelestialBody a, CelestialBody b) { const bool DEBUG_WALK = false; - if (DEBUG_WALK) Debug.Log("BodyOrbitsBody(" + a.name + "," + b.name + ")"); - if (DEBUG_WALK) Debug.Log("a's ref body = " + (a.referenceBody == null ? "null" : a.referenceBody.name)); + if (DEBUG_WALK) Safe.Utilities.Debug.Logger.Log("BodyOrbitsBody(" + a.name + "," + b.name + ")"); + if (DEBUG_WALK) Safe.Utilities.Debug.Logger.Log("a's ref body = " + (a.referenceBody == null ? "null" : a.referenceBody.name)); Boolean found = false; for (var curBody = a.referenceBody; curBody != null && curBody != curBody.referenceBody; // reference body of Sun points to itself, weirdly. From 1b4bcc0fb8cfa59103c7be0cc3e9f327a4d9a212 Mon Sep 17 00:00:00 2001 From: Chris Woerz Date: Thu, 19 Feb 2015 12:27:26 -0700 Subject: [PATCH 173/446] moved logger to 'safehouse' --- src/kOS.Safe.Test/SetSuffixTest.cs | 2 +- .../StructureSuffixIntegrationTest.cs | 2 +- src/kOS.Safe.Test/StructureTest.cs | 2 +- src/kOS.Safe.Test/TestLogger.cs | 5 ++ src/kOS.Safe/Compilation/KS/Compiler.cs | 6 +-- src/kOS.Safe/Compilation/Opcode.cs | 3 +- src/kOS.Safe/Encapsulation/Structure.cs | 3 +- src/kOS.Safe/ILogger.cs | 1 + src/kOS.Safe/Persistence/Archive.cs | 22 ++++---- src/kOS.Safe/Persistence/Harddisk.cs | 5 +- src/kOS.Safe/Persistence/Volume.cs | 24 ++++----- src/kOS.Safe/Utilities/Debug.cs | 2 +- .../{Environment.cs => SafeHouse.cs} | 4 +- src/kOS.Safe/kOS.Safe.csproj | 6 +-- src/kOS/AddOns/RemoteTech2/RemoteTechHook.cs | 13 ++--- src/kOS/Binding/FlightControlManager.cs | 5 +- src/kOS/Binding/FlightStats.cs | 4 -- src/kOS/Execution/CPU.cs | 37 +++++++------- src/kOS/Function/Persistence.cs | 2 +- src/kOS/Logger.cs | 5 ++ src/kOS/Module/Bootstrapper.cs | 24 +++++---- src/kOS/Persistence/PersistenceExtensions.cs | 4 +- src/kOS/Screen/KOSToolBarWindow.cs | 50 ++++++++++--------- src/kOS/Suffixed/Orbitable.cs | 3 +- src/kOS/Suffixed/RgbaColor.cs | 3 +- src/kOS/UserIO/TelnetMainServer.cs | 8 +-- src/kOS/UserIO/TelnetSingletonServer.cs | 29 +++++------ src/kOS/UserIO/TelnetWelcomeMenu.cs | 4 +- 28 files changed, 151 insertions(+), 127 deletions(-) rename src/kOS.Safe/Utilities/{Environment.cs => SafeHouse.cs} (84%) diff --git a/src/kOS.Safe.Test/SetSuffixTest.cs b/src/kOS.Safe.Test/SetSuffixTest.cs index c157b8f69..443c98bd4 100644 --- a/src/kOS.Safe.Test/SetSuffixTest.cs +++ b/src/kOS.Safe.Test/SetSuffixTest.cs @@ -11,7 +11,7 @@ public class SetSuffixTest [TestFixtureSetUp] public void Setup() { - Debug.Logger = new TestLogger(); + SafeHouse.Logger = new TestLogger(); } [Test] diff --git a/src/kOS.Safe.Test/StructureSuffixIntegrationTest.cs b/src/kOS.Safe.Test/StructureSuffixIntegrationTest.cs index 96efe85d0..6b650a3b6 100644 --- a/src/kOS.Safe.Test/StructureSuffixIntegrationTest.cs +++ b/src/kOS.Safe.Test/StructureSuffixIntegrationTest.cs @@ -11,7 +11,7 @@ public class StructureSuffixIntegrationTest [TestFixtureSetUp] public void Setup() { - Debug.Logger = new TestLogger(); + SafeHouse.Logger = new TestLogger(); } [Test] diff --git a/src/kOS.Safe.Test/StructureTest.cs b/src/kOS.Safe.Test/StructureTest.cs index b530bdcd7..7869860bc 100644 --- a/src/kOS.Safe.Test/StructureTest.cs +++ b/src/kOS.Safe.Test/StructureTest.cs @@ -36,7 +36,7 @@ public void TestAddInstanceSuffix(string[] name, ISuffix suffix) [TestFixtureSetUp] public void Setup() { - Debug.Logger = new TestLogger(); + SafeHouse.Logger = new TestLogger(); } [Test] diff --git a/src/kOS.Safe.Test/TestLogger.cs b/src/kOS.Safe.Test/TestLogger.cs index d915a1e61..d66b25bce 100644 --- a/src/kOS.Safe.Test/TestLogger.cs +++ b/src/kOS.Safe.Test/TestLogger.cs @@ -21,5 +21,10 @@ public void SuperVerbose(string s) { throw new NotImplementedException(); } + + public void LogWarning(string s) + { + throw new NotImplementedException(); + } } } diff --git a/src/kOS.Safe/Compilation/KS/Compiler.cs b/src/kOS.Safe/Compilation/KS/Compiler.cs index b6e8d580e..e37b9543b 100644 --- a/src/kOS.Safe/Compilation/KS/Compiler.cs +++ b/src/kOS.Safe/Compilation/KS/Compiler.cs @@ -56,8 +56,8 @@ public CodePart Compile(int startLineNum, ParseTree tree, Context context, Compi // attach source/line information to the exception before throwing it upward. // that's why this seemingly pointless "catch and then throw again" is here. } - Debug.Logger.Log("Exception in Compiler: " + kosException.Message); - Debug.Logger.Log(kosException.StackTrace); + SafeHouse.Logger.Log("Exception in Compiler: " + kosException.Message); + SafeHouse.Logger.Log(kosException.StackTrace); throw; // throw it up in addition to logging the stack trace, so the kOS terminal will also give the user some message. } @@ -88,7 +88,7 @@ private bool NodeStartHousekeeping(ParseNode node) if (node == null) { throw new ArgumentNullException("node"); } if (TRACE_PARSE) - Debug.Logger.Log("traceParse: visiting node: " + node.Token.Type.ToString() + ", " + node.Token.Text); + SafeHouse.Logger.Log("traceParse: visiting node: " + node.Token.Type.ToString() + ", " + node.Token.Text); if (node.Token == null || node.Token.Line <= 0) { diff --git a/src/kOS.Safe/Compilation/Opcode.cs b/src/kOS.Safe/Compilation/Opcode.cs index 5047043f0..ed4ab6dff 100644 --- a/src/kOS.Safe/Compilation/Opcode.cs +++ b/src/kOS.Safe/Compilation/Opcode.cs @@ -5,6 +5,7 @@ using kOS.Safe.Encapsulation; using kOS.Safe.Execution; using kOS.Safe.Exceptions; +using kOS.Safe.Utilities; namespace kOS.Safe.Compilation { @@ -286,7 +287,7 @@ public static void InitMachineCodeData() } catch (MissingMethodException) { - Utilities.Debug.Logger.Log( String.Format(forceDefaultConstructorMsg, opType.Name) ); + SafeHouse.Logger.Log( String.Format(forceDefaultConstructorMsg, opType.Name) ); Utilities.Debug.AddNagMessage( Utilities.Debug.NagType.NAGFOREVER, "ERROR IN OPCODE DEFINITION " + opType.Name ); return; } diff --git a/src/kOS.Safe/Encapsulation/Structure.cs b/src/kOS.Safe/Encapsulation/Structure.cs index 014fcc3ee..77b740f6d 100644 --- a/src/kOS.Safe/Encapsulation/Structure.cs +++ b/src/kOS.Safe/Encapsulation/Structure.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using kOS.Safe.Exceptions; +using kOS.Safe.Utilities; namespace kOS.Safe.Encapsulation { @@ -138,7 +139,7 @@ public virtual object TryOperation(string op, object other, bool reverseOrder) var message = string.Format("Cannot perform the operation: {0} On Structures {1} and {2}", op, GetType(), other.GetType()); - Utilities.Debug.Logger.Log(message); + SafeHouse.Logger.Log(message); throw new InvalidOperationException(message); } diff --git a/src/kOS.Safe/ILogger.cs b/src/kOS.Safe/ILogger.cs index 76aaa1e88..18b99c1bb 100644 --- a/src/kOS.Safe/ILogger.cs +++ b/src/kOS.Safe/ILogger.cs @@ -7,5 +7,6 @@ public interface ILogger void Log(string text); void Log(Exception e); void SuperVerbose(string s); + void LogWarning(string s); } } \ No newline at end of file diff --git a/src/kOS.Safe/Persistence/Archive.cs b/src/kOS.Safe/Persistence/Archive.cs index 018807edd..bd9e595fb 100644 --- a/src/kOS.Safe/Persistence/Archive.cs +++ b/src/kOS.Safe/Persistence/Archive.cs @@ -11,7 +11,7 @@ public class Archive : Volume { private static string ArchiveFolder { - get { return Utilities.Environment.ArchiveFolder; } + get { return SafeHouse.ArchiveFolder; } } public Archive() @@ -36,7 +36,7 @@ public override ProgramFile GetByName(string name, bool ksmDefault = false) { try { - Debug.Logger.Log("Archive: Getting File By Name: " + name); + SafeHouse.Logger.Log("Archive: Getting File By Name: " + name); var fileInfo = FileSearch(name, ksmDefault); if (fileInfo == null) { @@ -64,7 +64,7 @@ public override ProgramFile GetByName(string name, bool ksmDefault = false) } catch (Exception e) { - Debug.Logger.Log(e); + SafeHouse.Logger.Log(e); return null; } } @@ -77,7 +77,7 @@ public override bool SaveFile(ProgramFile file) try { - Debug.Logger.Log("Archive: Saving File Name: " + file.Filename); + SafeHouse.Logger.Log("Archive: Saving File Name: " + file.Filename); byte[] fileBody; string fileExtension; switch (file.Category) @@ -87,7 +87,7 @@ public override bool SaveFile(ProgramFile file) case FileCategory.ASCII: case FileCategory.KERBOSCRIPT: string tempString = file.StringContent; - if (Utilities.Environment.IsWindows) + if (SafeHouse.IsWindows) { // Only evil windows gets evil windows line breaks, and only if this is some sort of ASCII: tempString = tempString.Replace("\n", "\r\n"); @@ -110,7 +110,7 @@ public override bool SaveFile(ProgramFile file) } catch (Exception e) { - Debug.Logger.Log(e); + SafeHouse.Logger.Log(e); return false; } @@ -121,7 +121,7 @@ public override bool DeleteByName(string name) { try { - Debug.Logger.Log("Archive: Deleting File Name: " + name); + SafeHouse.Logger.Log("Archive: Deleting File Name: " + name); var fullPath = FileSearch(name); if (fullPath == null) { @@ -142,7 +142,7 @@ public override bool RenameFile(string name, string newName) { try { - Debug.Logger.Log(string.Format("Archive: Renaming: {0} To: {1}", name, newName)); + SafeHouse.Logger.Log(string.Format("Archive: Renaming: {0} To: {1}", name, newName)); var fullSourcePath = FileSearch(name); if (fullSourcePath == null) { @@ -170,7 +170,7 @@ public override List GetFileList() try { - Debug.Logger.Log(string.Format("Archive: Listing Files")); + SafeHouse.Logger.Log(string.Format("Archive: Listing Files")); var kosFiles = Directory.GetFiles(ArchiveFolder); retList.AddRange(kosFiles.Select(file => new System.IO.FileInfo(file)).Select(sysFileInfo => new FileInfo(sysFileInfo))); } @@ -235,7 +235,7 @@ private byte[] ProcessBinaryReader(BinaryReader infile) public override void AppendToFile(string name, string textToAppend) { - Debug.Logger.SuperVerbose("Archive: AppendToFile: " + name); + SafeHouse.Logger.SuperVerbose("Archive: AppendToFile: " + name); System.IO.FileInfo info = FileSearch(name); string fullPath = info == null ? string.Format("{0}{1}", ArchiveFolder, PersistenceUtilities.CookedFilename(name, KERBOSCRIPT_EXTENSION, true)) : info.FullName; @@ -251,7 +251,7 @@ public override void AppendToFile(string name, string textToAppend) public override void AppendToFile(string name, byte[] bytesToAppend) { - Debug.Logger.SuperVerbose("Archive: AppendToFile: " + name); + SafeHouse.Logger.SuperVerbose("Archive: AppendToFile: " + name); System.IO.FileInfo info = FileSearch(name); string fullPath = info == null ? string.Format("{0}{1}", ArchiveFolder, PersistenceUtilities.CookedFilename(name, KERBOSCRIPT_EXTENSION, true)) : info.FullName; diff --git a/src/kOS.Safe/Persistence/Harddisk.cs b/src/kOS.Safe/Persistence/Harddisk.cs index c4451248f..9fdb041e7 100644 --- a/src/kOS.Safe/Persistence/Harddisk.cs +++ b/src/kOS.Safe/Persistence/Harddisk.cs @@ -1,5 +1,4 @@ -using System; -using kOS.Safe.Utilities; +using kOS.Safe.Utilities; namespace kOS.Safe.Persistence { @@ -12,7 +11,7 @@ public Harddisk(int size) public override bool SaveFile(ProgramFile file) { - Debug.Logger.Log("HardDisk: SaveFile: " + file.Filename); + SafeHouse.Logger.Log("HardDisk: SaveFile: " + file.Filename); return IsRoomFor(file) && base.SaveFile(file); } diff --git a/src/kOS.Safe/Persistence/Volume.cs b/src/kOS.Safe/Persistence/Volume.cs index 506c41db7..47eebeff5 100644 --- a/src/kOS.Safe/Persistence/Volume.cs +++ b/src/kOS.Safe/Persistence/Volume.cs @@ -22,7 +22,7 @@ public Dictionary FileList { get { - Debug.Logger.SuperVerbose("Volume: Get-FileList: " + files.Count); + SafeHouse.Logger.SuperVerbose("Volume: Get-FileList: " + files.Count); return files.ToDictionary(pair => pair.Key, pair => pair.Value, StringComparer.OrdinalIgnoreCase); } } @@ -32,7 +32,7 @@ public Dictionary FileList protected Volume() { - Debug.Logger.SuperVerbose("Volume: CONSTRUCT"); + SafeHouse.Logger.SuperVerbose("Volume: CONSTRUCT"); Renameable = true; Capacity = -1; Name = ""; @@ -58,7 +58,7 @@ private void InitializeVolumeSuffixes() /// the file public virtual ProgramFile GetByName(string name, bool ksmDefault = false ) { - Debug.Logger.SuperVerbose("Volume: GetByName: " + name); + SafeHouse.Logger.SuperVerbose("Volume: GetByName: " + name); var fullPath = FileSearch(name, ksmDefault); if (fullPath == null) { @@ -70,7 +70,7 @@ public virtual ProgramFile GetByName(string name, bool ksmDefault = false ) public virtual bool DeleteByName(string name) { - Debug.Logger.SuperVerbose("Volume: DeleteByName: " + name); + SafeHouse.Logger.SuperVerbose("Volume: DeleteByName: " + name); var fullPath = FileSearch(name); if (fullPath == null) @@ -87,7 +87,7 @@ public virtual bool DeleteByName(string name) public virtual bool RenameFile(string name, string newName) { - Debug.Logger.SuperVerbose("Volume: RenameFile: From: " + name + " To: " + newName); + SafeHouse.Logger.SuperVerbose("Volume: RenameFile: From: " + name + " To: " + newName); ProgramFile file = GetByName(name); if (file != null) { @@ -101,7 +101,7 @@ public virtual bool RenameFile(string name, string newName) public virtual void AppendToFile(string name, string textToAppend) { - Debug.Logger.SuperVerbose("Volume: AppendToFile: " + name); + SafeHouse.Logger.SuperVerbose("Volume: AppendToFile: " + name); ProgramFile file = GetByName(name) ?? new ProgramFile(name); if (file.StringContent.Length > 0 && !file.StringContent.EndsWith("\n")) @@ -115,7 +115,7 @@ public virtual void AppendToFile(string name, string textToAppend) public virtual void AppendToFile(string name, byte[] bytesToAppend) { - Debug.Logger.SuperVerbose("Volume: AppendToFile: " + name); + SafeHouse.Logger.SuperVerbose("Volume: AppendToFile: " + name); ProgramFile file = GetByName(name) ?? new ProgramFile(name); file.BinaryContent = new byte[file.BinaryContent.Length + bytesToAppend.Length]; @@ -125,7 +125,7 @@ public virtual void AppendToFile(string name, byte[] bytesToAppend) public virtual void Add(ProgramFile file, bool withReplacement = false) { - Debug.Logger.SuperVerbose("Volume: Add: " + file.Filename); + SafeHouse.Logger.SuperVerbose("Volume: Add: " + file.Filename); if (withReplacement) { files[file.Filename] = file; @@ -138,7 +138,7 @@ public virtual void Add(ProgramFile file, bool withReplacement = false) public virtual bool SaveFile(ProgramFile file) { - Debug.Logger.SuperVerbose("Volume: SaveFile: " + file.Filename); + SafeHouse.Logger.SuperVerbose("Volume: SaveFile: " + file.Filename); Add(file, true); return true; @@ -153,7 +153,7 @@ public virtual bool SaveObjectFile(string fileNameOut, List parts) public List LoadObjectFile(string filePath, string prefix, byte[] content) { - Debug.Logger.SuperVerbose("Volume: LoadObjectFile: " + filePath); + SafeHouse.Logger.SuperVerbose("Volume: LoadObjectFile: " + filePath); List parts = CompiledObject.UnPack(filePath, prefix, content); return parts; } @@ -168,7 +168,7 @@ protected int GetUsedSpace() public virtual List GetFileList() { - Debug.Logger.SuperVerbose("Volume: GetFileList: " + files.Count); + SafeHouse.Logger.SuperVerbose("Volume: GetFileList: " + files.Count); List returnList = files.Values.Select(file => new FileInfo(file.Filename, file.GetSize())).ToList(); returnList.Sort(FileInfoComparer); // make sure files will print in sorted form. return returnList; @@ -189,7 +189,7 @@ public virtual float RequiredPower() private ProgramFile FileSearch(string name, bool ksmDefault = false) { - Debug.Logger.SuperVerbose("Volume: FileSearch: " + files.Count); + SafeHouse.Logger.SuperVerbose("Volume: FileSearch: " + files.Count); var kerboscriptFilename = PersistenceUtilities.CookedFilename(name, KERBOSCRIPT_EXTENSION, true); var kosMlFilename = PersistenceUtilities.CookedFilename(name, KOS_MACHINELANGUAGE_EXTENSION, true); diff --git a/src/kOS.Safe/Utilities/Debug.cs b/src/kOS.Safe/Utilities/Debug.cs index 431bc4f5a..19f5b4585 100644 --- a/src/kOS.Safe/Utilities/Debug.cs +++ b/src/kOS.Safe/Utilities/Debug.cs @@ -61,7 +61,7 @@ public static List GetPendingNags() return returnVal; } - public static ILogger Logger { get; set; } + public static ObjectIDGenerator IDGenerator { get; set; } } } diff --git a/src/kOS.Safe/Utilities/Environment.cs b/src/kOS.Safe/Utilities/SafeHouse.cs similarity index 84% rename from src/kOS.Safe/Utilities/Environment.cs rename to src/kOS.Safe/Utilities/SafeHouse.cs index d2670450f..697de2502 100644 --- a/src/kOS.Safe/Utilities/Environment.cs +++ b/src/kOS.Safe/Utilities/SafeHouse.cs @@ -2,7 +2,7 @@ namespace kOS.Safe.Utilities { - public static class Environment + public static class SafeHouse { public static IConfig Config { get; private set; } public static bool IsWindows { get; private set; } @@ -14,5 +14,7 @@ public static void Init(IConfig config, bool isWindows, string archiveFolder) IsWindows = isWindows; ArchiveFolder = archiveFolder; } + + public static ILogger Logger { get; set; } } } diff --git a/src/kOS.Safe/kOS.Safe.csproj b/src/kOS.Safe/kOS.Safe.csproj index 0622a04ef..50c8f54ab 100644 --- a/src/kOS.Safe/kOS.Safe.csproj +++ b/src/kOS.Safe/kOS.Safe.csproj @@ -147,7 +147,7 @@ - + @@ -163,9 +163,7 @@ Resources.Designer.cs - - - + + + + \ No newline at end of file diff --git a/src/packages/repositories.config b/src/packages/repositories.config index 94596777a..4644e02bc 100644 --- a/src/packages/repositories.config +++ b/src/packages/repositories.config @@ -1,4 +1,5 @@ - - - + + + + \ No newline at end of file From 8b7c8bc836c8e0cfaa5b9aa585986891a26dfd84 Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Tue, 10 Mar 2015 16:12:17 -0500 Subject: [PATCH 285/446] Changed file scope to global scope. Removed the outermost file scope's implicit scope wrappers. (file scope IS global scope now) Changed the conditions of KOSIdentifierClashException so that it only complains when the overridden variable is a bound variable - overriding user vars should be allowed. Changed TinyPG grammar to allow block scope braces whereever you feel like. (Therefore if somebody wants to create a varible that's local to the file, they can do so by just wrapping their whole file inside an explicit set of braces). --- src/kOS.Safe/Compilation/CompilerOptions.cs | 13 - src/kOS.Safe/Compilation/KS/Compiler.cs | 16 +- src/kOS.Safe/Compilation/KS/Parser.cs | 229 +++++++----------- src/kOS.Safe/Compilation/KS/kRISC.tpg | 13 +- .../Exceptions/KOSIdentifierClashException.cs | 16 +- src/kOS/Execution/CPU.cs | 8 +- src/kOS/Function/Misc.cs | 6 +- 7 files changed, 113 insertions(+), 188 deletions(-) diff --git a/src/kOS.Safe/Compilation/CompilerOptions.cs b/src/kOS.Safe/Compilation/CompilerOptions.cs index 6f7517f59..01ef1cdba 100644 --- a/src/kOS.Safe/Compilation/CompilerOptions.cs +++ b/src/kOS.Safe/Compilation/CompilerOptions.cs @@ -4,17 +4,6 @@ public class CompilerOptions { public bool LoadProgramsInSameAddressSpace { get; set; } - /// - /// True if the compile should act as if there was an outer wrapping local - /// block scope around the whole thing being compiled. In other words - /// DECLARE statements inside the thing being compiled are local to just - /// the thing being compiled and cannot be seen outside the thing being - /// compiled. If false, then it assumes the outermost scope of the - /// compilation unit is identical to the entire computer's global scope. - /// (such that variables declared there are available everywhere). - /// - public bool WrapImplicitBlockScope {get; set;} - public CompilerOptions() { LoadDefaults(); @@ -23,8 +12,6 @@ public CompilerOptions() private void LoadDefaults() { LoadProgramsInSameAddressSpace = false; - WrapImplicitBlockScope = false; - } } } diff --git a/src/kOS.Safe/Compilation/KS/Compiler.cs b/src/kOS.Safe/Compilation/KS/Compiler.cs index d89469f05..d45bcd6de 100644 --- a/src/kOS.Safe/Compilation/KS/Compiler.cs +++ b/src/kOS.Safe/Compilation/KS/Compiler.cs @@ -72,7 +72,7 @@ public CodePart Compile(int startLineNum, ParseTree tree, Context context, Compi if (tree.Nodes.Count > 0) { PreProcess(tree); - CompileProgram(tree, options.WrapImplicitBlockScope); + CompileProgram(tree); } } catch (KOSException kosException) @@ -91,24 +91,12 @@ public CodePart Compile(int startLineNum, ParseTree tree, Context context, Compi return part; } - private void CompileProgram(ParseTree tree, bool wrapInAScope) + private void CompileProgram(ParseTree tree) { currentCodeSection = part.MainCode; - - if (wrapInAScope) - { - ++braceNestLevel; - AddOpcode(new OpcodePushScope()); - } PushProgramParameters(); VisitNode(tree.Nodes[0]); - - if (wrapInAScope) - { - --braceNestLevel; - AddOpcode(new OpcodePopScope()); - } if (addBranchDestination) { diff --git a/src/kOS.Safe/Compilation/KS/Parser.cs b/src/kOS.Safe/Compilation/KS/Parser.cs index 6029d8562..5b5a9df63 100644 --- a/src/kOS.Safe/Compilation/KS/Parser.cs +++ b/src/kOS.Safe/Compilation/KS/Parser.cs @@ -47,7 +47,7 @@ private void ParseStart(ParseNode parent) - tok = scanner.LookAhead(TokenType.SET, TokenType.IF, TokenType.UNTIL, TokenType.LOCK, TokenType.UNLOCK, TokenType.PRINT, TokenType.ON, TokenType.TOGGLE, TokenType.WAIT, TokenType.WHEN, TokenType.STAGE, TokenType.CLEARSCREEN, TokenType.ADD, TokenType.REMOVE, TokenType.LOG, TokenType.BREAK, TokenType.PRESERVE, TokenType.DECLARE, TokenType.SWITCH, TokenType.COPY, TokenType.RENAME, TokenType.DELETE, TokenType.EDIT, TokenType.RUN, TokenType.COMPILE, TokenType.LIST, TokenType.REBOOT, TokenType.SHUTDOWN, TokenType.FOR, TokenType.UNSET, TokenType.BATCH, TokenType.DEPLOY, TokenType.PLUSMINUS, TokenType.NOT, TokenType.INTEGER, TokenType.DOUBLE, TokenType.TRUEFALSE, TokenType.IDENTIFIER, TokenType.FILEIDENT, TokenType.BRACKETOPEN, TokenType.STRING); + tok = scanner.LookAhead(TokenType.SET, TokenType.IF, TokenType.UNTIL, TokenType.LOCK, TokenType.UNLOCK, TokenType.PRINT, TokenType.ON, TokenType.TOGGLE, TokenType.WAIT, TokenType.WHEN, TokenType.STAGE, TokenType.CLEARSCREEN, TokenType.ADD, TokenType.REMOVE, TokenType.LOG, TokenType.BREAK, TokenType.PRESERVE, TokenType.DECLARE, TokenType.SWITCH, TokenType.COPY, TokenType.RENAME, TokenType.DELETE, TokenType.EDIT, TokenType.RUN, TokenType.COMPILE, TokenType.LIST, TokenType.REBOOT, TokenType.SHUTDOWN, TokenType.FOR, TokenType.UNSET, TokenType.BATCH, TokenType.DEPLOY, TokenType.CURLYOPEN, TokenType.PLUSMINUS, TokenType.NOT, TokenType.INTEGER, TokenType.DOUBLE, TokenType.TRUEFALSE, TokenType.IDENTIFIER, TokenType.FILEIDENT, TokenType.BRACKETOPEN, TokenType.STRING); while (tok.Type == TokenType.SET || tok.Type == TokenType.IF || tok.Type == TokenType.UNTIL @@ -80,6 +80,7 @@ private void ParseStart(ParseNode parent) || tok.Type == TokenType.UNSET || tok.Type == TokenType.BATCH || tok.Type == TokenType.DEPLOY + || tok.Type == TokenType.CURLYOPEN || tok.Type == TokenType.PLUSMINUS || tok.Type == TokenType.NOT || tok.Type == TokenType.INTEGER @@ -91,7 +92,7 @@ private void ParseStart(ParseNode parent) || tok.Type == TokenType.STRING) { Parseinstruction(node); - tok = scanner.LookAhead(TokenType.SET, TokenType.IF, TokenType.UNTIL, TokenType.LOCK, TokenType.UNLOCK, TokenType.PRINT, TokenType.ON, TokenType.TOGGLE, TokenType.WAIT, TokenType.WHEN, TokenType.STAGE, TokenType.CLEARSCREEN, TokenType.ADD, TokenType.REMOVE, TokenType.LOG, TokenType.BREAK, TokenType.PRESERVE, TokenType.DECLARE, TokenType.SWITCH, TokenType.COPY, TokenType.RENAME, TokenType.DELETE, TokenType.EDIT, TokenType.RUN, TokenType.COMPILE, TokenType.LIST, TokenType.REBOOT, TokenType.SHUTDOWN, TokenType.FOR, TokenType.UNSET, TokenType.BATCH, TokenType.DEPLOY, TokenType.PLUSMINUS, TokenType.NOT, TokenType.INTEGER, TokenType.DOUBLE, TokenType.TRUEFALSE, TokenType.IDENTIFIER, TokenType.FILEIDENT, TokenType.BRACKETOPEN, TokenType.STRING); + tok = scanner.LookAhead(TokenType.SET, TokenType.IF, TokenType.UNTIL, TokenType.LOCK, TokenType.UNLOCK, TokenType.PRINT, TokenType.ON, TokenType.TOGGLE, TokenType.WAIT, TokenType.WHEN, TokenType.STAGE, TokenType.CLEARSCREEN, TokenType.ADD, TokenType.REMOVE, TokenType.LOG, TokenType.BREAK, TokenType.PRESERVE, TokenType.DECLARE, TokenType.SWITCH, TokenType.COPY, TokenType.RENAME, TokenType.DELETE, TokenType.EDIT, TokenType.RUN, TokenType.COMPILE, TokenType.LIST, TokenType.REBOOT, TokenType.SHUTDOWN, TokenType.FOR, TokenType.UNSET, TokenType.BATCH, TokenType.DEPLOY, TokenType.CURLYOPEN, TokenType.PLUSMINUS, TokenType.NOT, TokenType.INTEGER, TokenType.DOUBLE, TokenType.TRUEFALSE, TokenType.IDENTIFIER, TokenType.FILEIDENT, TokenType.BRACKETOPEN, TokenType.STRING); } @@ -114,139 +115,88 @@ private void Parseinstruction_block(ParseNode parent) ParseNode node = parent.CreateNode(scanner.GetToken(TokenType.instruction_block), "instruction_block"); parent.Nodes.Add(node); - tok = scanner.LookAhead(TokenType.SET, TokenType.IF, TokenType.UNTIL, TokenType.LOCK, TokenType.UNLOCK, TokenType.PRINT, TokenType.ON, TokenType.TOGGLE, TokenType.WAIT, TokenType.WHEN, TokenType.STAGE, TokenType.CLEARSCREEN, TokenType.ADD, TokenType.REMOVE, TokenType.LOG, TokenType.BREAK, TokenType.PRESERVE, TokenType.DECLARE, TokenType.SWITCH, TokenType.COPY, TokenType.RENAME, TokenType.DELETE, TokenType.EDIT, TokenType.RUN, TokenType.COMPILE, TokenType.LIST, TokenType.REBOOT, TokenType.SHUTDOWN, TokenType.FOR, TokenType.UNSET, TokenType.BATCH, TokenType.DEPLOY, TokenType.PLUSMINUS, TokenType.NOT, TokenType.INTEGER, TokenType.DOUBLE, TokenType.TRUEFALSE, TokenType.IDENTIFIER, TokenType.FILEIDENT, TokenType.BRACKETOPEN, TokenType.STRING, TokenType.CURLYOPEN); - switch (tok.Type) - { - case TokenType.SET: - case TokenType.IF: - case TokenType.UNTIL: - case TokenType.LOCK: - case TokenType.UNLOCK: - case TokenType.PRINT: - case TokenType.ON: - case TokenType.TOGGLE: - case TokenType.WAIT: - case TokenType.WHEN: - case TokenType.STAGE: - case TokenType.CLEARSCREEN: - case TokenType.ADD: - case TokenType.REMOVE: - case TokenType.LOG: - case TokenType.BREAK: - case TokenType.PRESERVE: - case TokenType.DECLARE: - case TokenType.SWITCH: - case TokenType.COPY: - case TokenType.RENAME: - case TokenType.DELETE: - case TokenType.EDIT: - case TokenType.RUN: - case TokenType.COMPILE: - case TokenType.LIST: - case TokenType.REBOOT: - case TokenType.SHUTDOWN: - case TokenType.FOR: - case TokenType.UNSET: - case TokenType.BATCH: - case TokenType.DEPLOY: - case TokenType.PLUSMINUS: - case TokenType.NOT: - case TokenType.INTEGER: - case TokenType.DOUBLE: - case TokenType.TRUEFALSE: - case TokenType.IDENTIFIER: - case TokenType.FILEIDENT: - case TokenType.BRACKETOPEN: - case TokenType.STRING: - Parseinstruction(node); - break; - case TokenType.CURLYOPEN: - - tok = scanner.Scan(TokenType.CURLYOPEN); - n = node.CreateNode(tok, tok.ToString() ); - node.Token.UpdateRange(tok); - node.Nodes.Add(n); - if (tok.Type != TokenType.CURLYOPEN) { - tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.CURLYOPEN.ToString(), 0x1001, tok)); - return; - } + + tok = scanner.Scan(TokenType.CURLYOPEN); + n = node.CreateNode(tok, tok.ToString() ); + node.Token.UpdateRange(tok); + node.Nodes.Add(n); + if (tok.Type != TokenType.CURLYOPEN) { + tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.CURLYOPEN.ToString(), 0x1001, tok)); + return; + } - - tok = scanner.LookAhead(TokenType.SET, TokenType.IF, TokenType.UNTIL, TokenType.LOCK, TokenType.UNLOCK, TokenType.PRINT, TokenType.ON, TokenType.TOGGLE, TokenType.WAIT, TokenType.WHEN, TokenType.STAGE, TokenType.CLEARSCREEN, TokenType.ADD, TokenType.REMOVE, TokenType.LOG, TokenType.BREAK, TokenType.PRESERVE, TokenType.DECLARE, TokenType.SWITCH, TokenType.COPY, TokenType.RENAME, TokenType.DELETE, TokenType.EDIT, TokenType.RUN, TokenType.COMPILE, TokenType.LIST, TokenType.REBOOT, TokenType.SHUTDOWN, TokenType.FOR, TokenType.UNSET, TokenType.BATCH, TokenType.DEPLOY, TokenType.PLUSMINUS, TokenType.NOT, TokenType.INTEGER, TokenType.DOUBLE, TokenType.TRUEFALSE, TokenType.IDENTIFIER, TokenType.FILEIDENT, TokenType.BRACKETOPEN, TokenType.STRING); - while (tok.Type == TokenType.SET - || tok.Type == TokenType.IF - || tok.Type == TokenType.UNTIL - || tok.Type == TokenType.LOCK - || tok.Type == TokenType.UNLOCK - || tok.Type == TokenType.PRINT - || tok.Type == TokenType.ON - || tok.Type == TokenType.TOGGLE - || tok.Type == TokenType.WAIT - || tok.Type == TokenType.WHEN - || tok.Type == TokenType.STAGE - || tok.Type == TokenType.CLEARSCREEN - || tok.Type == TokenType.ADD - || tok.Type == TokenType.REMOVE - || tok.Type == TokenType.LOG - || tok.Type == TokenType.BREAK - || tok.Type == TokenType.PRESERVE - || tok.Type == TokenType.DECLARE - || tok.Type == TokenType.SWITCH - || tok.Type == TokenType.COPY - || tok.Type == TokenType.RENAME - || tok.Type == TokenType.DELETE - || tok.Type == TokenType.EDIT - || tok.Type == TokenType.RUN - || tok.Type == TokenType.COMPILE - || tok.Type == TokenType.LIST - || tok.Type == TokenType.REBOOT - || tok.Type == TokenType.SHUTDOWN - || tok.Type == TokenType.FOR - || tok.Type == TokenType.UNSET - || tok.Type == TokenType.BATCH - || tok.Type == TokenType.DEPLOY - || tok.Type == TokenType.PLUSMINUS - || tok.Type == TokenType.NOT - || tok.Type == TokenType.INTEGER - || tok.Type == TokenType.DOUBLE - || tok.Type == TokenType.TRUEFALSE - || tok.Type == TokenType.IDENTIFIER - || tok.Type == TokenType.FILEIDENT - || tok.Type == TokenType.BRACKETOPEN - || tok.Type == TokenType.STRING) - { - Parseinstruction(node); - tok = scanner.LookAhead(TokenType.SET, TokenType.IF, TokenType.UNTIL, TokenType.LOCK, TokenType.UNLOCK, TokenType.PRINT, TokenType.ON, TokenType.TOGGLE, TokenType.WAIT, TokenType.WHEN, TokenType.STAGE, TokenType.CLEARSCREEN, TokenType.ADD, TokenType.REMOVE, TokenType.LOG, TokenType.BREAK, TokenType.PRESERVE, TokenType.DECLARE, TokenType.SWITCH, TokenType.COPY, TokenType.RENAME, TokenType.DELETE, TokenType.EDIT, TokenType.RUN, TokenType.COMPILE, TokenType.LIST, TokenType.REBOOT, TokenType.SHUTDOWN, TokenType.FOR, TokenType.UNSET, TokenType.BATCH, TokenType.DEPLOY, TokenType.PLUSMINUS, TokenType.NOT, TokenType.INTEGER, TokenType.DOUBLE, TokenType.TRUEFALSE, TokenType.IDENTIFIER, TokenType.FILEIDENT, TokenType.BRACKETOPEN, TokenType.STRING); - } + + tok = scanner.LookAhead(TokenType.SET, TokenType.IF, TokenType.UNTIL, TokenType.LOCK, TokenType.UNLOCK, TokenType.PRINT, TokenType.ON, TokenType.TOGGLE, TokenType.WAIT, TokenType.WHEN, TokenType.STAGE, TokenType.CLEARSCREEN, TokenType.ADD, TokenType.REMOVE, TokenType.LOG, TokenType.BREAK, TokenType.PRESERVE, TokenType.DECLARE, TokenType.SWITCH, TokenType.COPY, TokenType.RENAME, TokenType.DELETE, TokenType.EDIT, TokenType.RUN, TokenType.COMPILE, TokenType.LIST, TokenType.REBOOT, TokenType.SHUTDOWN, TokenType.FOR, TokenType.UNSET, TokenType.BATCH, TokenType.DEPLOY, TokenType.CURLYOPEN, TokenType.PLUSMINUS, TokenType.NOT, TokenType.INTEGER, TokenType.DOUBLE, TokenType.TRUEFALSE, TokenType.IDENTIFIER, TokenType.FILEIDENT, TokenType.BRACKETOPEN, TokenType.STRING); + while (tok.Type == TokenType.SET + || tok.Type == TokenType.IF + || tok.Type == TokenType.UNTIL + || tok.Type == TokenType.LOCK + || tok.Type == TokenType.UNLOCK + || tok.Type == TokenType.PRINT + || tok.Type == TokenType.ON + || tok.Type == TokenType.TOGGLE + || tok.Type == TokenType.WAIT + || tok.Type == TokenType.WHEN + || tok.Type == TokenType.STAGE + || tok.Type == TokenType.CLEARSCREEN + || tok.Type == TokenType.ADD + || tok.Type == TokenType.REMOVE + || tok.Type == TokenType.LOG + || tok.Type == TokenType.BREAK + || tok.Type == TokenType.PRESERVE + || tok.Type == TokenType.DECLARE + || tok.Type == TokenType.SWITCH + || tok.Type == TokenType.COPY + || tok.Type == TokenType.RENAME + || tok.Type == TokenType.DELETE + || tok.Type == TokenType.EDIT + || tok.Type == TokenType.RUN + || tok.Type == TokenType.COMPILE + || tok.Type == TokenType.LIST + || tok.Type == TokenType.REBOOT + || tok.Type == TokenType.SHUTDOWN + || tok.Type == TokenType.FOR + || tok.Type == TokenType.UNSET + || tok.Type == TokenType.BATCH + || tok.Type == TokenType.DEPLOY + || tok.Type == TokenType.CURLYOPEN + || tok.Type == TokenType.PLUSMINUS + || tok.Type == TokenType.NOT + || tok.Type == TokenType.INTEGER + || tok.Type == TokenType.DOUBLE + || tok.Type == TokenType.TRUEFALSE + || tok.Type == TokenType.IDENTIFIER + || tok.Type == TokenType.FILEIDENT + || tok.Type == TokenType.BRACKETOPEN + || tok.Type == TokenType.STRING) + { + Parseinstruction(node); + tok = scanner.LookAhead(TokenType.SET, TokenType.IF, TokenType.UNTIL, TokenType.LOCK, TokenType.UNLOCK, TokenType.PRINT, TokenType.ON, TokenType.TOGGLE, TokenType.WAIT, TokenType.WHEN, TokenType.STAGE, TokenType.CLEARSCREEN, TokenType.ADD, TokenType.REMOVE, TokenType.LOG, TokenType.BREAK, TokenType.PRESERVE, TokenType.DECLARE, TokenType.SWITCH, TokenType.COPY, TokenType.RENAME, TokenType.DELETE, TokenType.EDIT, TokenType.RUN, TokenType.COMPILE, TokenType.LIST, TokenType.REBOOT, TokenType.SHUTDOWN, TokenType.FOR, TokenType.UNSET, TokenType.BATCH, TokenType.DEPLOY, TokenType.CURLYOPEN, TokenType.PLUSMINUS, TokenType.NOT, TokenType.INTEGER, TokenType.DOUBLE, TokenType.TRUEFALSE, TokenType.IDENTIFIER, TokenType.FILEIDENT, TokenType.BRACKETOPEN, TokenType.STRING); + } - - tok = scanner.Scan(TokenType.CURLYCLOSE); - n = node.CreateNode(tok, tok.ToString() ); - node.Token.UpdateRange(tok); - node.Nodes.Add(n); - if (tok.Type != TokenType.CURLYCLOSE) { - tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.CURLYCLOSE.ToString(), 0x1001, tok)); - return; - } + + tok = scanner.Scan(TokenType.CURLYCLOSE); + n = node.CreateNode(tok, tok.ToString() ); + node.Token.UpdateRange(tok); + node.Nodes.Add(n); + if (tok.Type != TokenType.CURLYCLOSE) { + tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.CURLYCLOSE.ToString(), 0x1001, tok)); + return; + } - - tok = scanner.LookAhead(TokenType.EOI); - if (tok.Type == TokenType.EOI) - { - tok = scanner.Scan(TokenType.EOI); - n = node.CreateNode(tok, tok.ToString() ); - node.Token.UpdateRange(tok); - node.Nodes.Add(n); - if (tok.Type != TokenType.EOI) { - tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.EOI.ToString(), 0x1001, tok)); - return; - } - } - break; - default: - tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found.", 0x0002, tok)); - break; + + tok = scanner.LookAhead(TokenType.EOI); + if (tok.Type == TokenType.EOI) + { + tok = scanner.Scan(TokenType.EOI); + n = node.CreateNode(tok, tok.ToString() ); + node.Token.UpdateRange(tok); + node.Nodes.Add(n); + if (tok.Type != TokenType.EOI) { + tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.EOI.ToString(), 0x1001, tok)); + return; + } } parent.Token.UpdateRange(node.Token); @@ -259,7 +209,7 @@ private void Parseinstruction(ParseNode parent) ParseNode node = parent.CreateNode(scanner.GetToken(TokenType.instruction), "instruction"); parent.Nodes.Add(node); - tok = scanner.LookAhead(TokenType.SET, TokenType.IF, TokenType.UNTIL, TokenType.LOCK, TokenType.UNLOCK, TokenType.PRINT, TokenType.ON, TokenType.TOGGLE, TokenType.WAIT, TokenType.WHEN, TokenType.STAGE, TokenType.CLEARSCREEN, TokenType.ADD, TokenType.REMOVE, TokenType.LOG, TokenType.BREAK, TokenType.PRESERVE, TokenType.DECLARE, TokenType.SWITCH, TokenType.COPY, TokenType.RENAME, TokenType.DELETE, TokenType.EDIT, TokenType.RUN, TokenType.COMPILE, TokenType.LIST, TokenType.REBOOT, TokenType.SHUTDOWN, TokenType.FOR, TokenType.UNSET, TokenType.BATCH, TokenType.DEPLOY, TokenType.PLUSMINUS, TokenType.NOT, TokenType.INTEGER, TokenType.DOUBLE, TokenType.TRUEFALSE, TokenType.IDENTIFIER, TokenType.FILEIDENT, TokenType.BRACKETOPEN, TokenType.STRING); + tok = scanner.LookAhead(TokenType.SET, TokenType.IF, TokenType.UNTIL, TokenType.LOCK, TokenType.UNLOCK, TokenType.PRINT, TokenType.ON, TokenType.TOGGLE, TokenType.WAIT, TokenType.WHEN, TokenType.STAGE, TokenType.CLEARSCREEN, TokenType.ADD, TokenType.REMOVE, TokenType.LOG, TokenType.BREAK, TokenType.PRESERVE, TokenType.DECLARE, TokenType.SWITCH, TokenType.COPY, TokenType.RENAME, TokenType.DELETE, TokenType.EDIT, TokenType.RUN, TokenType.COMPILE, TokenType.LIST, TokenType.REBOOT, TokenType.SHUTDOWN, TokenType.FOR, TokenType.UNSET, TokenType.BATCH, TokenType.DEPLOY, TokenType.CURLYOPEN, TokenType.PLUSMINUS, TokenType.NOT, TokenType.INTEGER, TokenType.DOUBLE, TokenType.TRUEFALSE, TokenType.IDENTIFIER, TokenType.FILEIDENT, TokenType.BRACKETOPEN, TokenType.STRING); switch (tok.Type) { case TokenType.SET: @@ -358,6 +308,9 @@ private void Parseinstruction(ParseNode parent) case TokenType.DEPLOY: Parsedeploy_stmt(node); break; + case TokenType.CURLYOPEN: + Parseinstruction_block(node); + break; case TokenType.PLUSMINUS: case TokenType.NOT: case TokenType.INTEGER: @@ -446,7 +399,7 @@ private void Parseif_stmt(ParseNode parent) Parseexpr(node); - Parseinstruction_block(node); + Parseinstruction(node); tok = scanner.LookAhead(TokenType.ELSE); @@ -464,7 +417,7 @@ private void Parseif_stmt(ParseNode parent) } - Parseinstruction_block(node); + Parseinstruction(node); } @@ -506,7 +459,7 @@ private void Parseuntil_stmt(ParseNode parent) Parseexpr(node); - Parseinstruction_block(node); + Parseinstruction(node); tok = scanner.LookAhead(TokenType.EOI); @@ -747,7 +700,7 @@ private void Parseon_stmt(ParseNode parent) Parsevaridentifier(node); - Parseinstruction_block(node); + Parseinstruction(node); tok = scanner.LookAhead(TokenType.EOI); @@ -880,7 +833,7 @@ private void Parsewhen_stmt(ParseNode parent) } - Parseinstruction_block(node); + Parseinstruction(node); tok = scanner.LookAhead(TokenType.EOI); @@ -1914,7 +1867,7 @@ private void Parsefor_stmt(ParseNode parent) Parsevaridentifier(node); - Parseinstruction_block(node); + Parseinstruction(node); tok = scanner.LookAhead(TokenType.EOI); diff --git a/src/kOS.Safe/Compilation/KS/kRISC.tpg b/src/kOS.Safe/Compilation/KS/kRISC.tpg index 8adc11713..b7519c902 100644 --- a/src/kOS.Safe/Compilation/KS/kRISC.tpg +++ b/src/kOS.Safe/Compilation/KS/kRISC.tpg @@ -84,7 +84,7 @@ COMMENTLINE -> @"//[^\n]*\n?"; // Rules // =================================================== Start -> (instruction)* EOF; -instruction_block -> instruction | CURLYOPEN instruction* CURLYCLOSE EOI?; +instruction_block -> CURLYOPEN instruction* CURLYCLOSE EOI?; instruction -> set_stmt | if_stmt | until_stmt | @@ -117,21 +117,22 @@ instruction -> set_stmt | unset_stmt | batch_stmt | deploy_stmt | + instruction_block | identifier_led_stmt; // any statement that starts with an identifier. // ------------ statements -------------------- set_stmt -> SET varidentifier TO expr EOI; -if_stmt -> IF expr instruction_block (ELSE instruction_block)? EOI?; -until_stmt -> UNTIL expr instruction_block EOI?; +if_stmt -> IF expr instruction (ELSE instruction)? EOI?; +until_stmt -> UNTIL expr instruction EOI?; lock_stmt -> LOCK IDENTIFIER TO expr EOI; unlock_stmt -> UNLOCK (IDENTIFIER | ALL) EOI; print_stmt -> PRINT expr (AT BRACKETOPEN expr COMMA expr BRACKETCLOSE)? EOI; -on_stmt -> ON varidentifier instruction_block EOI?; +on_stmt -> ON varidentifier instruction EOI?; toggle_stmt -> TOGGLE varidentifier EOI; wait_stmt -> WAIT UNTIL? expr EOI; -when_stmt -> WHEN expr THEN instruction_block EOI?; +when_stmt -> WHEN expr THEN instruction EOI?; onoff_stmt -> varidentifier onoff_trailer EOI; onoff_trailer -> (ON | OFF); stage_stmt -> STAGE EOI; @@ -152,7 +153,7 @@ compile_stmt -> COMPILE expr (TO expr)? EOI; list_stmt -> LIST (IDENTIFIER (IN IDENTIFIER)?)? EOI; reboot_stmt -> REBOOT EOI; shutdown_stmt -> SHUTDOWN EOI; -for_stmt -> FOR IDENTIFIER IN varidentifier instruction_block EOI?; +for_stmt -> FOR IDENTIFIER IN varidentifier instruction EOI?; unset_stmt -> UNSET (IDENTIFIER | ALL) EOI; batch_stmt -> BATCH EOI; deploy_stmt -> DEPLOY EOI; diff --git a/src/kOS.Safe/Exceptions/KOSIdentifierClashException.cs b/src/kOS.Safe/Exceptions/KOSIdentifierClashException.cs index 62a590f8f..5bea2b834 100644 --- a/src/kOS.Safe/Exceptions/KOSIdentifierClashException.cs +++ b/src/kOS.Safe/Exceptions/KOSIdentifierClashException.cs @@ -8,7 +8,7 @@ namespace kOS.Safe.Exceptions /// public class KOSIdentiferClashException: KOSException { - private const string TERSE_MSG_FMT = "An identifier called '{0}' is already present at this scope"; + private const string TERSE_MSG_FMT = "A built-in language identifier called '{0}' is already present at this scope"; public override string VerboseMessage { get{ return BuildVerboseMessage(); } } @@ -27,16 +27,12 @@ private string BuildVerboseMessage() const string VERBOSE_TEXT = "As of version 0.17, kOS no longer allows you to declare\n" + "an identifier that clashes with the name of an existing\n" + - "identifier at the same scope level. You are allowed to make\n" + - "a more local identifier that masks a more global one, but\n" + - "it is now an error to make an identifier that has the same\n" + - "name as one already at the *same* nesting scope level.\n" + + "built-in bound identifier at the same scope level. You\n" + + "are, however, allowed to replace your own homemade variables\n" + + "(i.e. declare the same variable twice, so the second one\n" + + "replaces the first).\n" + "\n" + - " Your variable '{0}' is already the name of a variable here.\n"+ - "\n" + - "Note that all identifiers you make explicitlty with SET\n" + - "end up at the same global scope, and all built-in bound\n" + - "variables (for example SHIP, or MUN) are also at global scope.\n" + + " Your variable '{0}' is already the name of a built-in variable.\n"+ "\n" + "If you wish to mask the name of a built-in identifier with your\n" + "own variable, you must be in a local scope (inside braces) and\n" + diff --git a/src/kOS/Execution/CPU.cs b/src/kOS/Execution/CPU.cs index 0f96a33b9..d1295bbe0 100644 --- a/src/kOS/Execution/CPU.cs +++ b/src/kOS/Execution/CPU.cs @@ -494,10 +494,10 @@ public void AddVariable(Variable variable, string identifier, bool local) whichDict = globalVariables; if (whichDict.ContainsKey(identifier)) { - // was this: TODO - delete it after testing: - // whichDict.Remove(identifier); - - throw new KOSIdentiferClashException(identifier); + if (whichDict[identifier].Value is BoundVariable) + throw new KOSIdentiferClashException(identifier); + else + whichDict.Remove(identifier); } whichDict.Add(identifier, variable); } diff --git a/src/kOS/Function/Misc.cs b/src/kOS/Function/Misc.cs index 42fa30a03..53c9e661a 100644 --- a/src/kOS/Function/Misc.cs +++ b/src/kOS/Function/Misc.cs @@ -150,7 +150,7 @@ public override void Execute(SharedObjects shared) if (shared.ProcessorMgr != null) { string filePath = string.Format("{0}/{1}", shared.VolumeMgr.GetVolumeRawIdentifier(targetVolume), fileName) ; - var options = new CompilerOptions {LoadProgramsInSameAddressSpace = true, WrapImplicitBlockScope = true}; + var options = new CompilerOptions {LoadProgramsInSameAddressSpace = true}; List parts = shared.ScriptHandler.Compile(filePath, 1, file.StringContent, "program", options); var builder = new ProgramBuilder(); builder.AddRange(parts); @@ -168,7 +168,7 @@ public override void Execute(SharedObjects shared) // clear the "program" compilation context shared.ScriptHandler.ClearContext("program"); string filePath = shared.VolumeMgr.GetVolumeRawIdentifier(shared.VolumeMgr.CurrentVolume) + "/" + fileName ; - var options = new CompilerOptions {LoadProgramsInSameAddressSpace = true, WrapImplicitBlockScope = true}; + var options = new CompilerOptions {LoadProgramsInSameAddressSpace = true}; var programContext = ((CPU)shared.Cpu).GetProgramContext(); List codeParts; @@ -230,7 +230,7 @@ public override void Execute(SharedObjects shared) if (shared.ScriptHandler != null) { - var options = new CompilerOptions { LoadProgramsInSameAddressSpace = true, WrapImplicitBlockScope = true }; + var options = new CompilerOptions { LoadProgramsInSameAddressSpace = true }; string filePath = shared.VolumeMgr.GetVolumeRawIdentifier(shared.VolumeMgr.CurrentVolume) + "/" + fileName; // add this program to the address space of the parent program, // or to a file to save: From 5789d75ff6ee4829802fbc6fea846e19004e3ec5 Mon Sep 17 00:00:00 2001 From: ZiwKerman Date: Wed, 11 Mar 2015 12:16:49 +0000 Subject: [PATCH 286/446] Moved all KAC related files to Addons/KAC Created Monobehaviour for Handling KAC events. For now it just writes to log on each KAC state change. --- .../KAC}/KACAlarmWrapper.cs | 32 +++++++++++++- src/kOS/AddOns/KAC/KACEventHandler.cs | 43 +++++++++++++++++++ .../KAC.cs => AddOns/KAC/KACFunctions.cs} | 26 ++++++++--- src/kOS/AddOns/KAC/KACWrapper.cs | 2 +- src/kOS/Module/Bootstrapper.cs | 14 +----- src/kOS/Module/kOSProcessor.cs | 33 -------------- src/kOS/kOS.csproj | 5 ++- 7 files changed, 98 insertions(+), 57 deletions(-) rename src/kOS/{Suffixed => AddOns/KAC}/KACAlarmWrapper.cs (59%) create mode 100644 src/kOS/AddOns/KAC/KACEventHandler.cs rename src/kOS/{Function/KAC.cs => AddOns/KAC/KACFunctions.cs} (69%) diff --git a/src/kOS/Suffixed/KACAlarmWrapper.cs b/src/kOS/AddOns/KAC/KACAlarmWrapper.cs similarity index 59% rename from src/kOS/Suffixed/KACAlarmWrapper.cs rename to src/kOS/AddOns/KAC/KACAlarmWrapper.cs index ce36d1fb7..fe4064bf9 100644 --- a/src/kOS/Suffixed/KACAlarmWrapper.cs +++ b/src/kOS/AddOns/KAC/KACAlarmWrapper.cs @@ -2,7 +2,8 @@ using System.Linq; using kOS.Safe.Encapsulation; using kOS.Safe.Encapsulation.Suffixes; -using kOS_KACWrapper; +using kOS.Safe.Utilities; +using kOS.KAC; namespace kOS.Suffixed { @@ -27,7 +28,11 @@ private void InitializeSuffixes() AddSuffix("VESSELID", new SetSuffix(() => alarm.VesselID, value => alarm.VesselID = value)); AddSuffix("NOTES", new SetSuffix(() => alarm.Name, value => alarm.Name = value)); - AddSuffix("REMAINING", new Suffix(() => (double)alarm.Remaining)); + AddSuffix("ALARMACTION", new SetSuffix (alarm.AlarmAction.ToString, SetAlarmAction)); + + AddSuffix("ALARMTYPE", new Suffix (alarm.AlarmType.ToString)); + + AddSuffix("REMAINING", new Suffix(GetRemaining)); AddSuffix("ALARMTIME", new SetSuffix(() => alarm.AlarmTime, value => alarm.AlarmTime = value)); AddSuffix("ALARMMARGIN", new SetSuffix(() => alarm.AlarmMargin, value => alarm.AlarmMargin = value)); @@ -39,6 +44,29 @@ private void InitializeSuffixes() AddSuffix("XferOriginBodyName", new SetSuffix(() => alarm.XferOriginBodyName, value => alarm.XferOriginBodyName = value)); AddSuffix("XferTargetBodyName", new SetSuffix(() => alarm.XferTargetBodyName, value => alarm.XferTargetBodyName = value)); + + } + + private double GetRemaining() + { + /*SafeHouse.Logger.LogWarning (string.Format ("Trying to get remaining time, {0}", alarm.Remaining));*/ + //workaround for alarm.Remaining type mismatch + return alarm.AlarmTime - Planetarium.GetUniversalTime(); + } + + private void SetAlarmAction(string newAlarmAction) + { + KACWrapper.KACAPI.AlarmActionEnum result; + try + { + result = (KACWrapper.KACAPI.AlarmActionEnum) Enum.Parse(typeof(KACWrapper.KACAPI.AlarmActionEnum), newAlarmAction); + alarm.AlarmAction = result; + } + catch (ArgumentException) + { + SafeHouse.Logger.LogWarning (string.Format ("Failed parsing {0} into KACAPI.AlarmActionEnum", newAlarmAction)); + } + } } } diff --git a/src/kOS/AddOns/KAC/KACEventHandler.cs b/src/kOS/AddOns/KAC/KACEventHandler.cs new file mode 100644 index 000000000..ba3092b53 --- /dev/null +++ b/src/kOS/AddOns/KAC/KACEventHandler.cs @@ -0,0 +1,43 @@ +using System; +using System.IO; +using kOS.Safe.Persistence; +using kOS.Safe.Utilities; +using kOS.Suffixed; +using UnityEngine; +using Debug = UnityEngine.Debug; + +using kOS.KAC; + +namespace kOS +{ + [KSPAddon(KSPAddon.Startup.EveryScene, false)] + public class KACEventHandler : MonoBehaviour + { + public void Start() + { + KACWrapper.InitKACWrapper(); + if (KACWrapper.APIReady) + { + //All good to go + //register Event Handler + KACWrapper.KAC.onAlarmStateChanged += KAC_onAlarmStateChanged; + + Debug.Log (string.Format ("{0} Kerbal Alarm Clock found, Alarms Count {1}", KSPLogger.LOGGER_PREFIX, KACWrapper.KAC.Alarms.Count)); + } + + } + + public void OnDestroy() + { + //destroy the event hook + KACWrapper.KAC.onAlarmStateChanged -= KAC_onAlarmStateChanged; + } + + void KAC_onAlarmStateChanged(KACWrapper.KACAPI.AlarmStateChangedEventArgs e) + { + //output whats happened + Debug.Log (string.Format("{0}, caugth Event from alarm {1}, event type {2}", KSPLogger.LOGGER_PREFIX, e.alarm.Name, e.eventType)); + } + + } +} \ No newline at end of file diff --git a/src/kOS/Function/KAC.cs b/src/kOS/AddOns/KAC/KACFunctions.cs similarity index 69% rename from src/kOS/Function/KAC.cs rename to src/kOS/AddOns/KAC/KACFunctions.cs index b6113bd99..2805b73b0 100644 --- a/src/kOS/Function/KAC.cs +++ b/src/kOS/AddOns/KAC/KACFunctions.cs @@ -6,7 +6,7 @@ using kOS.Safe.Persistence; using kOS.Suffixed; using kOS.Utilities; -using kOS_KACWrapper; +using kOS.KAC; namespace kOS.Function { @@ -18,12 +18,25 @@ public override void Execute(SharedObjects shared) string alarmNotes = shared.Cpu.PopValue().ToString(); string alarmName = shared.Cpu.PopValue().ToString(); double alarmUT = GetDouble(shared.Cpu.PopValue()); + string alarmType = shared.Cpu.PopValue().ToString(); //alarm type is read-only, you cannot change it afterwards if (KACWrapper.APIReady) { - String aID = KACWrapper.KAC.CreateAlarm(KACWrapper.KACAPI.AlarmTypeEnum.Raw, alarmName, alarmUT); + KACWrapper.KACAPI.AlarmTypeEnum newAlarmType; + try + { + newAlarmType = (KACWrapper.KACAPI.AlarmTypeEnum) Enum.Parse(typeof(KACWrapper.KACAPI.AlarmTypeEnum), alarmType); + } + catch (ArgumentException) + { + SafeHouse.Logger.LogWarning (string.Format ("Failed parsing {0} into KACAPI.AlarmTypeEnum", alarmType)); + //failed parsing alarmType, defaulting to Raw + newAlarmType = KACWrapper.KACAPI.AlarmTypeEnum.Raw; + } + + String aID = KACWrapper.KAC.CreateAlarm(newAlarmType, alarmName, alarmUT); - SafeHouse.Logger.Log (string.Format ("Trying to create KAC Alarm, UT={0}, Name={1}", alarmUT.ToString (), alarmName)); + SafeHouse.Logger.Log (string.Format ("Trying to create KAC Alarm, UT={0}, Name={1}, type = {2}", alarmUT.ToString (), alarmName, alarmType)); if (aID !="") { @@ -35,13 +48,13 @@ public override void Execute(SharedObjects shared) a.AlarmAction = KACWrapper.KACAPI.AlarmActionEnum.PauseGame; a.VesselID = shared.Vessel.id.ToString(); - KACAlarmWrapper result = new KACAlarmWrapper (a); + var result = new KACAlarmWrapper (a); shared.Cpu.PushStack(result); } else { - //failed creating node + //failed creating alarm shared.Cpu.PushStack(""); } @@ -70,7 +83,8 @@ public override void Execute(SharedObjects shared) foreach (KACWrapper.KACAPI.KACAlarm a in alarms) { - list.Add (new KACAlarmWrapper(a)); + if (alarmTypes == "All" || a.AlarmTime.ToString() == alarmTypes) + list.Add (new KACAlarmWrapper(a)); } } shared.Cpu.PushStack(list); diff --git a/src/kOS/AddOns/KAC/KACWrapper.cs b/src/kOS/AddOns/KAC/KACWrapper.cs index 4219bf467..6e64b4c13 100644 --- a/src/kOS/AddOns/KAC/KACWrapper.cs +++ b/src/kOS/AddOns/KAC/KACWrapper.cs @@ -6,7 +6,7 @@ using System.Reflection; using System.Text; -namespace kOS_KACWrapper +namespace kOS.KAC { /////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/kOS/Module/Bootstrapper.cs b/src/kOS/Module/Bootstrapper.cs index bca86b6a7..730bcc08e 100644 --- a/src/kOS/Module/Bootstrapper.cs +++ b/src/kOS/Module/Bootstrapper.cs @@ -6,7 +6,7 @@ using UnityEngine; using Debug = UnityEngine.Debug; -using kOS_KACWrapper; +using kOS.KAC; namespace kOS.Module { @@ -26,8 +26,6 @@ public void Start() CheckForLegacyArchive(); - //try to init here, but most likely will fail due to load order - InitKAC(); } private void BuildEnvironment() @@ -72,16 +70,6 @@ private void CheckForLegacyArchive() ); } - private void InitKAC() - { - KACWrapper.InitKACWrapper(); - if (KACWrapper.APIReady) - { - //All good to go - Debug.Log (string.Format ("{0} Kerbal Alarm CLock found, Alarms Count {1}", KSPLogger.LOGGER_PREFIX, KACWrapper.KAC.Alarms.Count)); - } - } - private void MigrateScripts() { if (backup) diff --git a/src/kOS/Module/kOSProcessor.cs b/src/kOS/Module/kOSProcessor.cs index 472cb3e46..aae636800 100644 --- a/src/kOS/Module/kOSProcessor.cs +++ b/src/kOS/Module/kOSProcessor.cs @@ -21,7 +21,6 @@ using kOS.Suffixed; using KSPAPIExtensions; -using kOS_KACWrapper; using FileInfo = kOS.Safe.Encapsulation.FileInfo; namespace kOS.Module @@ -312,39 +311,10 @@ public void InitObjects() InitProcessorTracking(); - if (!KACWrapper.APIReady) - { - InitKAC (); - } - // move Cpu.Boot() to within the first Update() to prevent boot script errors from killing OnStart // shared.Cpu.Boot(); } - private void InitKAC() - { - KACWrapper.InitKACWrapper(); - if (KACWrapper.APIReady) - { - //register event handler - - KACWrapper.KAC.onAlarmStateChanged += KAC_onAlarmStateChanged; - - SafeHouse.Logger.Log(string.Format ("Kerbal Alarm Clock found, Alarms Count {0}", KACWrapper.KAC.Alarms.Count)); - } - } - - void KAC_onAlarmStateChanged(KACWrapper.KACAPI.AlarmStateChangedEventArgs e) - { - //output whats happened - if (IsAlive()) - { - //when you have multiple instances of kOSProcessor only first instance has this handler - shared.Screen.Print(string.Format("Caught event{0}->{1}", e.alarm.Name, e.eventType)); - } - SafeHouse.Logger.Log(string.Format("{0}->{1}", e.alarm.Name, e.eventType)); - } - private void InitProcessorTracking() { // Track a list of all instances of me that exist: @@ -376,9 +346,6 @@ private void OnDestroyingMyHardware(Part p) if (p != part) return; - //destroy the event hook - KACWrapper.KAC.onAlarmStateChanged -= KAC_onAlarmStateChanged; - GetWindow().DetachAllTelnets(); allMyInstances.RemoveAll(m => m==this); diff --git a/src/kOS/kOS.csproj b/src/kOS/kOS.csproj index 0c0a29c74..53a236338 100644 --- a/src/kOS/kOS.csproj +++ b/src/kOS/kOS.csproj @@ -157,8 +157,9 @@ - - + + +
    From 657b6826ca635ce4c76cecb1d0bfc5bbd382c26a Mon Sep 17 00:00:00 2001 From: ZiwKerman Date: Wed, 11 Mar 2015 17:13:08 +0000 Subject: [PATCH 287/446] Code cleanup, addons capabilities checking --- src/kOS/AddOns/KAC/KACAlarmWrapper.cs | 2 +- src/kOS/AddOns/KAC/KACEventHandler.cs | 2 +- src/kOS/AddOns/KAC/KACFunctions.cs | 2 +- src/kOS/AddOns/KAC/KACWrapper.cs | 2 +- src/kOS/Function/Suffixed.cs | 11 +++ src/kOS/Module/Bootstrapper.cs | 2 - src/kOS/Suffixed/Addons.cs | 129 ++++++++++++++++++++++++++ src/kOS/kOS.csproj | 1 + 8 files changed, 145 insertions(+), 6 deletions(-) create mode 100644 src/kOS/Suffixed/Addons.cs diff --git a/src/kOS/AddOns/KAC/KACAlarmWrapper.cs b/src/kOS/AddOns/KAC/KACAlarmWrapper.cs index fe4064bf9..a5a006b19 100644 --- a/src/kOS/AddOns/KAC/KACAlarmWrapper.cs +++ b/src/kOS/AddOns/KAC/KACAlarmWrapper.cs @@ -3,7 +3,7 @@ using kOS.Safe.Encapsulation; using kOS.Safe.Encapsulation.Suffixes; using kOS.Safe.Utilities; -using kOS.KAC; +using kOS.AddOns.KAC; namespace kOS.Suffixed { diff --git a/src/kOS/AddOns/KAC/KACEventHandler.cs b/src/kOS/AddOns/KAC/KACEventHandler.cs index ba3092b53..0a022f39e 100644 --- a/src/kOS/AddOns/KAC/KACEventHandler.cs +++ b/src/kOS/AddOns/KAC/KACEventHandler.cs @@ -6,7 +6,7 @@ using UnityEngine; using Debug = UnityEngine.Debug; -using kOS.KAC; +using kOS.AddOns.KAC; namespace kOS { diff --git a/src/kOS/AddOns/KAC/KACFunctions.cs b/src/kOS/AddOns/KAC/KACFunctions.cs index 2805b73b0..2e8a22af9 100644 --- a/src/kOS/AddOns/KAC/KACFunctions.cs +++ b/src/kOS/AddOns/KAC/KACFunctions.cs @@ -6,7 +6,7 @@ using kOS.Safe.Persistence; using kOS.Suffixed; using kOS.Utilities; -using kOS.KAC; +using kOS.AddOns.KAC; namespace kOS.Function { diff --git a/src/kOS/AddOns/KAC/KACWrapper.cs b/src/kOS/AddOns/KAC/KACWrapper.cs index 6e64b4c13..cdde14ed8 100644 --- a/src/kOS/AddOns/KAC/KACWrapper.cs +++ b/src/kOS/AddOns/KAC/KACWrapper.cs @@ -6,7 +6,7 @@ using System.Reflection; using System.Text; -namespace kOS.KAC +namespace kOS.AddOns.KAC { /////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/kOS/Function/Suffixed.cs b/src/kOS/Function/Suffixed.cs index a9f631181..3ff4f2592 100644 --- a/src/kOS/Function/Suffixed.cs +++ b/src/kOS/Function/Suffixed.cs @@ -9,6 +9,17 @@ namespace kOS.Function { + + [Function("addons")] + public class FunctionAddons : FunctionBase + { + public override void Execute(SharedObjects shared) + { + var addons = new AddonList(); + shared.Cpu.PushStack(addons); + } + } + [Function("node")] public class FunctionNode : FunctionBase { diff --git a/src/kOS/Module/Bootstrapper.cs b/src/kOS/Module/Bootstrapper.cs index 730bcc08e..bf6df2c12 100644 --- a/src/kOS/Module/Bootstrapper.cs +++ b/src/kOS/Module/Bootstrapper.cs @@ -6,8 +6,6 @@ using UnityEngine; using Debug = UnityEngine.Debug; -using kOS.KAC; - namespace kOS.Module { [KSPAddon(KSPAddon.Startup.Instantly, true)] diff --git a/src/kOS/Suffixed/Addons.cs b/src/kOS/Suffixed/Addons.cs new file mode 100644 index 000000000..dfbd24d85 --- /dev/null +++ b/src/kOS/Suffixed/Addons.cs @@ -0,0 +1,129 @@ +using System; +using kOS.Safe.Encapsulation.Suffixes; +using kOS.Safe.Encapsulation; + +namespace kOS.Suffixed +{ + public class AddonList : Structure + { + private Addon KACAddon; + private Addon RTAddon; + private Addon AGXAddon; + + public AddonList() + { + KACAddon = new Addon ("KAC"); + RTAddon = new Addon ("RT"); + AGXAddon = new Addon ("AGX"); + } + + private void InitializeSuffixes() + { + AddSuffix("KAC", new Suffix(() => KACAddon)); + AddSuffix("RT", new Suffix(() => RTAddon)); + AddSuffix("AGX", new Suffix(() => AGXAddon)); + } + + public override string ToString() + { + return string.Format("{0} AddonList", base.ToString()); + } + } + + public class Addon : Structure + { + public string addonName = ""; + + public Addon(string name) + { + addonName = name; + } + private void InitializeSuffixes() + { + AddSuffix("AVAILABLE", new Suffix(Available)); + + if (addonName == "RT") + { + AddSuffix("GETDELAY", new OneArgsSuffix(RTGetDelay, "Get current Shortest Signal Delay for Vessel")); + + AddSuffix("GETKSCDELAY", new OneArgsSuffix(RTGetKSCDelay, "Get current KSC Signal Delay")); + + AddSuffix("HASCONNECTION", new OneArgsSuffix(RTHasConnection, "True if ship has any connection")); + + AddSuffix("HASCONNECTION", new OneArgsSuffix(RTHasConnection, "True if ship has connection to KSC")); + } + } + + private static double RTGetDelay(Vessel tgtVessel) + { + double waitTotal = 0; + + if (kOS.AddOns.RemoteTech.RemoteTechHook.IsAvailable(tgtVessel.id) && tgtVessel.GetVesselCrew().Count == 0) + { + waitTotal = kOS.AddOns.RemoteTech.RemoteTechHook.Instance.GetShortestSignalDelay(tgtVessel.id); + } + + return waitTotal; + } + + private static double RTGetKSCDelay(Vessel tgtVessel) + { + double waitTotal = 0; + + if (kOS.AddOns.RemoteTech.RemoteTechHook.IsAvailable(tgtVessel.id) && tgtVessel.GetVesselCrew().Count == 0) + { + waitTotal = kOS.AddOns.RemoteTech.RemoteTechHook.Instance.GetSignalDelayToKSC(tgtVessel.id); + } + + return waitTotal; + } + + private static bool RTHasConnection(Vessel tgtVessel) + { + bool result = false; + + if (kOS.AddOns.RemoteTech.RemoteTechHook.IsAvailable(tgtVessel.id) && tgtVessel.GetVesselCrew().Count == 0) + { + result = kOS.AddOns.RemoteTech.RemoteTechHook.Instance.HasAnyConnection(tgtVessel.id); + } + + return result; + } + + private static bool RTHasKSCConnection(Vessel tgtVessel) + { + bool result = false; + + if (kOS.AddOns.RemoteTech.RemoteTechHook.IsAvailable(tgtVessel.id) && tgtVessel.GetVesselCrew().Count == 0) + { + result = kOS.AddOns.RemoteTech.RemoteTechHook.Instance.HasConnectionToKSC(tgtVessel.id); + } + + return result; + } + + public Boolean Available() + { + if (addonName == "AGX") + { + return kOS.AddOns.ActionGroupsExtended.ActionGroupsExtendedAPI.Instance.Installed (); + } + + if (addonName == "KAC") + { + return kOS.AddOns.KAC.KACWrapper.APIReady; + } + + if (addonName == "RT") + { + return kOS.AddOns.RemoteTech.RemoteTechHook.IsAvailable (); + } + return false; + } + + public override string ToString() + { + return string.Format("{0} Addon", base.ToString()); + } + } +} diff --git a/src/kOS/kOS.csproj b/src/kOS/kOS.csproj index 53a236338..b056c3178 100644 --- a/src/kOS/kOS.csproj +++ b/src/kOS/kOS.csproj @@ -160,6 +160,7 @@ + From d7f5edb931f9e36ca0c9d385a41c438a9f96bf94 Mon Sep 17 00:00:00 2001 From: ZiwKerman Date: Wed, 11 Mar 2015 18:30:31 +0000 Subject: [PATCH 288/446] bugfixes Usage for AddonList `print addons():kac:available` or `print addons():rt:getdelay(ship)` --- src/kOS/Suffixed/Addons.cs | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/src/kOS/Suffixed/Addons.cs b/src/kOS/Suffixed/Addons.cs index dfbd24d85..02d2f5417 100644 --- a/src/kOS/Suffixed/Addons.cs +++ b/src/kOS/Suffixed/Addons.cs @@ -15,6 +15,8 @@ public AddonList() KACAddon = new Addon ("KAC"); RTAddon = new Addon ("RT"); AGXAddon = new Addon ("AGX"); + + InitializeSuffixes(); } private void InitializeSuffixes() @@ -37,6 +39,8 @@ public class Addon : Structure public Addon(string name) { addonName = name; + + InitializeSuffixes(); } private void InitializeSuffixes() { @@ -44,59 +48,59 @@ private void InitializeSuffixes() if (addonName == "RT") { - AddSuffix("GETDELAY", new OneArgsSuffix(RTGetDelay, "Get current Shortest Signal Delay for Vessel")); + AddSuffix("GETDELAY", new OneArgsSuffix(RTGetDelay, "Get current Shortest Signal Delay for Vessel")); - AddSuffix("GETKSCDELAY", new OneArgsSuffix(RTGetKSCDelay, "Get current KSC Signal Delay")); + AddSuffix("GETKSCDELAY", new OneArgsSuffix(RTGetKSCDelay, "Get current KSC Signal Delay")); - AddSuffix("HASCONNECTION", new OneArgsSuffix(RTHasConnection, "True if ship has any connection")); + AddSuffix("HASCONNECTION", new OneArgsSuffix(RTHasConnection, "True if ship has any connection")); - AddSuffix("HASCONNECTION", new OneArgsSuffix(RTHasConnection, "True if ship has connection to KSC")); + AddSuffix("HASCONNECTION", new OneArgsSuffix(RTHasConnection, "True if ship has connection to KSC")); } } - private static double RTGetDelay(Vessel tgtVessel) + private static double RTGetDelay(VesselTarget tgtVessel) { double waitTotal = 0; - if (kOS.AddOns.RemoteTech.RemoteTechHook.IsAvailable(tgtVessel.id) && tgtVessel.GetVesselCrew().Count == 0) + if (kOS.AddOns.RemoteTech.RemoteTechHook.IsAvailable(tgtVessel.Vessel.id) && tgtVessel.Vessel.GetVesselCrew().Count == 0) { - waitTotal = kOS.AddOns.RemoteTech.RemoteTechHook.Instance.GetShortestSignalDelay(tgtVessel.id); + waitTotal = kOS.AddOns.RemoteTech.RemoteTechHook.Instance.GetShortestSignalDelay(tgtVessel.Vessel.id); } return waitTotal; } - private static double RTGetKSCDelay(Vessel tgtVessel) + private static double RTGetKSCDelay(VesselTarget tgtVessel) { double waitTotal = 0; - if (kOS.AddOns.RemoteTech.RemoteTechHook.IsAvailable(tgtVessel.id) && tgtVessel.GetVesselCrew().Count == 0) + if (kOS.AddOns.RemoteTech.RemoteTechHook.IsAvailable(tgtVessel.Vessel.id) && tgtVessel.Vessel.GetVesselCrew().Count == 0) { - waitTotal = kOS.AddOns.RemoteTech.RemoteTechHook.Instance.GetSignalDelayToKSC(tgtVessel.id); + waitTotal = kOS.AddOns.RemoteTech.RemoteTechHook.Instance.GetSignalDelayToKSC(tgtVessel.Vessel.id); } return waitTotal; } - private static bool RTHasConnection(Vessel tgtVessel) + private static bool RTHasConnection(VesselTarget tgtVessel) { bool result = false; - if (kOS.AddOns.RemoteTech.RemoteTechHook.IsAvailable(tgtVessel.id) && tgtVessel.GetVesselCrew().Count == 0) + if (kOS.AddOns.RemoteTech.RemoteTechHook.IsAvailable(tgtVessel.Vessel.id)) { - result = kOS.AddOns.RemoteTech.RemoteTechHook.Instance.HasAnyConnection(tgtVessel.id); + result = kOS.AddOns.RemoteTech.RemoteTechHook.Instance.HasAnyConnection(tgtVessel.Vessel.id); } return result; } - private static bool RTHasKSCConnection(Vessel tgtVessel) + private static bool RTHasKSCConnection(VesselTarget tgtVessel) { bool result = false; - if (kOS.AddOns.RemoteTech.RemoteTechHook.IsAvailable(tgtVessel.id) && tgtVessel.GetVesselCrew().Count == 0) + if (kOS.AddOns.RemoteTech.RemoteTechHook.IsAvailable(tgtVessel.Vessel.id)) { - result = kOS.AddOns.RemoteTech.RemoteTechHook.Instance.HasConnectionToKSC(tgtVessel.id); + result = kOS.AddOns.RemoteTech.RemoteTechHook.Instance.HasConnectionToKSC(tgtVessel.Vessel.id); } return result; From be66b6eaf95da2372671ed1339f7967c3c8b71bc Mon Sep 17 00:00:00 2001 From: ZiwKerman Date: Wed, 11 Mar 2015 21:03:51 +0000 Subject: [PATCH 289/446] final touches added KOSUnavailableAddonException --- .../KOSUnavailableAddonException.cs | 33 +++++++++++++++++++ src/kOS.Safe/kOS.Safe.csproj | 1 + src/kOS/AddOns/KAC/KACFunctions.cs | 21 +++++++++--- src/kOS/Binding/BindingConfig.cs | 1 + src/kOS/Function/Suffixed.cs | 11 ------- 5 files changed, 51 insertions(+), 16 deletions(-) create mode 100644 src/kOS.Safe/Exceptions/KOSUnavailableAddonException.cs diff --git a/src/kOS.Safe/Exceptions/KOSUnavailableAddonException.cs b/src/kOS.Safe/Exceptions/KOSUnavailableAddonException.cs new file mode 100644 index 000000000..e65955728 --- /dev/null +++ b/src/kOS.Safe/Exceptions/KOSUnavailableAddonException.cs @@ -0,0 +1,33 @@ +using System; + +namespace kOS.Safe.Exceptions +{ + /// + /// Thrown when user tries to call a function/suffix that is reliant on the availability of a certain addon, + /// like RemoteTech, Kerbal Alarm Clock or AGX. + /// + public class KOSUnavailableAddonException : KOSException + { + private const string TERSE_MSG_FMT = "'{0}' command requires {1} addon to be available."; + + protected string VerbosePrefix = + "It seems you tried calling a function or suffix \n" + + "that relies on the availability of a certain mod installed.\n" + + "You can check the availability of addons via 'addons' global, \n" + + "for example 'addons:rt:available' returns true if RemoteTech is present.\n"; + + // Just nothing by default: + public override string HelpURL { get { return ""; } } + public override string VerboseMessage { get { return VerbosePrefix; } } + + /// + /// Describe the condition under which the invalidity is happening. + /// + /// string name of the invalid command + /// describing which addon/mod is required + public KOSUnavailableAddonException(string command, string addonRequired) : + base(String.Format(TERSE_MSG_FMT, command, addonRequired)) + { + } + } +} diff --git a/src/kOS.Safe/kOS.Safe.csproj b/src/kOS.Safe/kOS.Safe.csproj index 50c8f54ab..f1e906887 100644 --- a/src/kOS.Safe/kOS.Safe.csproj +++ b/src/kOS.Safe/kOS.Safe.csproj @@ -106,6 +106,7 @@ + diff --git a/src/kOS/AddOns/KAC/KACFunctions.cs b/src/kOS/AddOns/KAC/KACFunctions.cs index 2e8a22af9..8b27ede80 100644 --- a/src/kOS/AddOns/KAC/KACFunctions.cs +++ b/src/kOS/AddOns/KAC/KACFunctions.cs @@ -4,6 +4,7 @@ using kOS.Safe.Function; using kOS.Safe.Utilities; using kOS.Safe.Persistence; +using kOS.Safe.Exceptions; using kOS.Suffixed; using kOS.Utilities; using kOS.AddOns.KAC; @@ -54,8 +55,8 @@ public override void Execute(SharedObjects shared) } else { - //failed creating alarm shared.Cpu.PushStack(""); + SafeHouse.Logger.Log(string.Format("Failed creating KAC Alarm, UT={0}, Name={1}, type = {2}", alarmUT.ToString(), alarmName, alarmType)); } } @@ -63,6 +64,7 @@ public override void Execute(SharedObjects shared) { //KAC integration not present. shared.Cpu.PushStack(""); + throw new KOSUnavailableAddonException("addAlarm()", "Kerbal Alarm Clock"); } } } @@ -86,8 +88,14 @@ public override void Execute(SharedObjects shared) if (alarmTypes == "All" || a.AlarmTime.ToString() == alarmTypes) list.Add (new KACAlarmWrapper(a)); } + shared.Cpu.PushStack(list); } - shared.Cpu.PushStack(list); + else + { + shared.Cpu.PushStack(list); + throw new KOSUnavailableAddonException("listAlarms()", "Kerbal Alarm Clock"); + } + } } @@ -103,10 +111,13 @@ public override void Execute(SharedObjects shared) { //Delete the Alarm using its ID and get the result result = KACWrapper.KAC.DeleteAlarm(alarmID); - + shared.Cpu.PushStack(result); + } + else + { + shared.Cpu.PushStack(result); + throw new KOSUnavailableAddonException("deleteAlarm()", "Kerbal Alarm Clock"); } - - shared.Cpu.PushStack(result); } } } diff --git a/src/kOS/Binding/BindingConfig.cs b/src/kOS/Binding/BindingConfig.cs index 1f6967a09..51ca102ce 100644 --- a/src/kOS/Binding/BindingConfig.cs +++ b/src/kOS/Binding/BindingConfig.cs @@ -9,6 +9,7 @@ public class BindingConfig : Binding public override void AddTo(SharedObjects shared) { shared.BindingMgr.AddGetter("CONFIG", () => Config.Instance); + shared.BindingMgr.AddGetter("ADDONS", () => new AddonList()); } } } diff --git a/src/kOS/Function/Suffixed.cs b/src/kOS/Function/Suffixed.cs index 3ff4f2592..a9f631181 100644 --- a/src/kOS/Function/Suffixed.cs +++ b/src/kOS/Function/Suffixed.cs @@ -9,17 +9,6 @@ namespace kOS.Function { - - [Function("addons")] - public class FunctionAddons : FunctionBase - { - public override void Execute(SharedObjects shared) - { - var addons = new AddonList(); - shared.Cpu.PushStack(addons); - } - } - [Function("node")] public class FunctionNode : FunctionBase { From 3309db6b0fdae72ceb6c84758a47b7dc9b3a32c4 Mon Sep 17 00:00:00 2001 From: ZiwKerman Date: Wed, 11 Mar 2015 22:02:25 +0000 Subject: [PATCH 290/446] bugfix in KACEventHandler --- src/kOS/AddOns/KAC/KACEventHandler.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/kOS/AddOns/KAC/KACEventHandler.cs b/src/kOS/AddOns/KAC/KACEventHandler.cs index 0a022f39e..a539cc25e 100644 --- a/src/kOS/AddOns/KAC/KACEventHandler.cs +++ b/src/kOS/AddOns/KAC/KACEventHandler.cs @@ -29,8 +29,11 @@ public void Start() public void OnDestroy() { - //destroy the event hook - KACWrapper.KAC.onAlarmStateChanged -= KAC_onAlarmStateChanged; + if (KACWrapper.APIReady) + { + //destroy the event hook + KACWrapper.KAC.onAlarmStateChanged -= KAC_onAlarmStateChanged; + } } void KAC_onAlarmStateChanged(KACWrapper.KACAPI.AlarmStateChangedEventArgs e) From f19044f50ce4f7234dfb4f38c4bb5a497b94b700 Mon Sep 17 00:00:00 2001 From: ZiwKerman Date: Thu, 12 Mar 2015 12:18:33 +0000 Subject: [PATCH 291/446] Documentation + minor fix --- doc/source/addons.rst | 23 +++- doc/source/addons/KAC.rst | 190 ++++++++++++++++++++++++++ doc/source/addons/RemoteTech.rst | 53 ++++++- src/kOS/AddOns/KAC/KACAlarmWrapper.cs | 19 ++- src/kOS/AddOns/KAC/KACFunctions.cs | 6 +- src/kOS/Suffixed/Addons.cs | 2 +- 6 files changed, 285 insertions(+), 8 deletions(-) create mode 100644 doc/source/addons/KAC.rst diff --git a/doc/source/addons.rst b/doc/source/addons.rst index 3563c0f6c..0294c011a 100644 --- a/doc/source/addons.rst +++ b/doc/source/addons.rst @@ -5,10 +5,31 @@ Addon Reference This section is for ways in which kOS has special case exceptions to its normal generic behaviors, in order to - accomdate other KSP mods. If you don't use the KSP mod mentioned, + accomdate other KSP mods. If you don't use any of KSP mods mentioned, you don't need to read this section. + .. toctree:: Action Groups Extended RemoteTech + Kerbal Alarm Clock + +To help KOS scripts identify whether or not certain mod is installed and available following suffixed functions were introduced in version 0.17 + +``ADDONS:AGX:AVAILABLE`` +------------------------ + +Returns True if mod Action Groupd Extended is istalled and available to KOS. + + +``ADDONS:RT:AVAILABLE`` +------------------------ + +Returns True if mod Remote Tech is istalled and available to KOS. See more Remote Tech functions here . + + +``ADDONS:KAC:AVAILABLE`` +------------------------ + +Returns True if mod Kerbal Alarm Clock is istalled and available to KOS. \ No newline at end of file diff --git a/doc/source/addons/KAC.rst b/doc/source/addons/KAC.rst new file mode 100644 index 000000000..effd80f3f --- /dev/null +++ b/doc/source/addons/KAC.rst @@ -0,0 +1,190 @@ +.. _KAC: + +Kerbal Alarm Clock +================== + +- Download: https://github.com/TriggerAu/KerbalAlarmClock/releases +- Alternative download https://kerbalstuff.com/mod/231/Kerbal%20Alarm%20Clock +- Forum thread, including full instructions: http://forum.kerbalspaceprogram.com/threads/24786 + +The Kerbal Alarm Clock is a plugin that allows you to create reminder alarms at future periods to help you manage your flights and not warp past important times. + +.. figure:: http://triggerau.github.io/KerbalAlarmClock/images/KACForumPic.png + +Creator of the KAC provides API for integration with other mods. In KOS we provide limited access to KAC alarms via following structure and functions. + +.. structure:: KACAlarm + + ===================================== ========================= ============= + Suffix Type Description + ===================================== ========================= ============= + :attr:`ID` string (readonly) Unique identifier + :attr:`NAME` string Name of the alarm + :attr:`ALARMACTION` string What should the Alarm Clock do when the alarm fires + :attr:`ALARMTYPE` string (readonly) What type of Alarm is this - affects icon displayed and some calc options + :attr:`NOTES` string Long description of the alarm (optional) + :attr:`REMAINING` scalar (s) Time remaining until alarm is triggered + :attr:`REPEATALARM` bool Should the alarm be repeated once it fires + :attr:`REPEATALARMPERIOD` scalar (s) How long after the alarm fires should the next alarm be set up + :attr:`VESSELID` string Unique Identifier of the Vessel that the alarm is attached to + :attr:`VESSEL` :struct: `Vessel` Vessel structure of that the alarm is attached to, use this to set VESSELID + :attr:`XferOriginBodyname` string Name of the body the vessel is departing from + :attr:`XferTargetBodyname` string Name of the body the vessel is arriving at + ===================================== ========================= ============= + +.. attribute:: KACAlarm:ID + + :type: string + :access: Get only + + Unique identifier of the alarm. + +.. attribute:: KACAlarm:NAME + + :type: string + :access: Get/Set + + Name of the alarm. Displayed in main KAC window. + +.. attribute:: KACAlarm:ALARMACTION + + :type: string + :access: Get/Set + + Should be one of the following + + * `MessageOnly` - Message Only-No Affect on warp + * `KillWarpOnly` - Kill Warp Only-No Message + * `KillWarp` - Kill Warp and Message + * `PauseGame` - Pause Game and Message + + If set incorrectly will log a warning in Debug log and revert to previous or default value. + +.. attribute:: KACAlarm:ALARMTYPE + + :type: string + :access: Get only + + Can only be set at Alarm creation. + Could be one of the following as per API + + * Raw (default) + * Maneuver + * ManeuverAuto + * Apoapsis + * Periapsis + * AscendingNode + * DescendingNode + * LaunchRendevous + * Closest + * SOIChange + * SOIChangeAuto + * Transfer + * TransferModelled + * Distance + * Crew + * EarthTime + + **Warning** Unless you are 100% certain you know what you're doing, create only "Raw" AlarmTypes to avoid unnecessary complications. + +.. attribute:: KACAlarm:NOTES + + :type: string + :access: Get/Set + + Long description of the alarm. Can be seen when alarm pops or by doubleclicking alarm in UI. + + **Warning** This field may be reserved in the fututre version of KAC-KOS integration for automated script execution upon triggering of the alarm. + +.. attribute:: KACAlarm:REMAINING + + :type: double + :access: Get only + + Time remaining until alarm is triggered. + +.. attribute:: KACAlarm:REPEATALARM + + :type: bool + :access: Get/Set + + Should the alarm be repeated once it fires. + +.. attribute:: KACAlarm:REPEATALARMPERIOD + + :type: double + :access: Get/Set + + How long after the alarm fires should the next alarm be set up. + +.. attribute:: KACAlarm:VESSELID + + :type: string + :access: Get/Set + + Unique Identifier of the Vessel that the alarm is attached to. Should only be used to unattach Alarm from any Vessel by setting to ampty string. + +.. attribute:: KACAlarm:VESSEL + + :type: :struct: `Vessel` + :access: Get/Set + + :ref:`Vessel ` structure of that the alarm is attached to, use this to set VESSELID, instead of setting it directly, unless you want to unattach the Alarm from any Vessel. + + +.. attribute:: KACAlarm:XferOriginBodyname + + :type: string + :access: Get/Set + + Name of the body the vessel is departing from. + +.. attribute:: KACAlarm:XferTargetBodyname + + :type: string + :access: Get/Set + + Name of the body the vessel is arriving to. + + + +Available Functions +=================== + +============================================= =================================================== + Function Description +============================================= =================================================== + :func:`ADDALARM(AlarmType, UT, Name, Notes)` Create new alarm of AlarmType at UT + :func:`LISTALARMS(alarmType)` List alarms with type `alarmType`. + :func:`DELETEALARM(alarmID)` Delete alarm with ID = alarmID +============================================= =================================================== + +.. function:: ADDALARM(AlarmType, UT, Name, Notes) + + Creates alarm of type `KACAlarm:ALARMTYPE` at `UT` with `Name` and `Notes` attributes set. Attaches alarm to current :ref:`CPU Vessel `. Returns :struct:`KACAlarm` object if creation was successful and empty string otherwise:: + + set na to addAlarm("Raw",time:seconds+300, "Test", "Notes"). + print na:NAME. //prints 'Test' + set na:NOTES to "New Description". + print na:NOTES. //prints 'New Description' + +.. function:: LISTALARMS(alarmType) + + If `alarmType` equals "All", returns :struct:`List` of *all* :struct:`KACAlarm` objects, otherwise returns :struct:`List` of all :struct:`KACAlarm` objects with `KACAlarm:ALARMTYPE` equeal to `alarmType':: + + set al to listAlarms("All"). + + for i in al + { + print i:ID + " - " + i:name. + } + +.. function:: DELETEALARM(alarmID) + + Deletes alarm with ID equal to alarmID. Returns True if successful, false otherwise:: + + set na to addAlarm("Raw",time:seconds+300, "Test", "Notes"). + if (DELETEALARM(na:ID)) + { + print "Alarm Deleted". + } diff --git a/doc/source/addons/RemoteTech.rst b/doc/source/addons/RemoteTech.rst index 4b29d4e9f..0eee2f3fc 100644 --- a/doc/source/addons/RemoteTech.rst +++ b/doc/source/addons/RemoteTech.rst @@ -3,4 +3,55 @@ RemoteTech ========== -Stub for RemoteTech documentation. +**Warning! This documentation is incomplete!** + +Access structure RTAddon via `ADDONS:RT`. + +.. structure:: RTAddon + + ===================================== ========================= ============= + Suffix Type Description + ===================================== ========================= ============= + :attr:`AVAILABLE` bool(readonly) True if RT is installed and RT integration enabled. + :meth:`GETDELAY(vessel)` double Get shortest possible delay to given :struct:`Vessel` + :meth:`GETKSCDELAY(vessel)` double Get delay from KSC to given :struct:`Vessel` + :meth:`HASCONNECTION(vessel)` bool True if given :struct:`Vessel` has any connection + :meth:`HASKSCCONNECTION(vessel)` bool True if given :struct:`Vessel` has connection to KSC + ===================================== ========================= ============= + + + +.. attribute:: RTADDON:AVAILABLE + + :type: bool + :access: Get only + + True if RT is installed and RT integration enabled. + +.. method:: RTAddon:GETDELAY(vessel) + + :parameter vessel: :struct:`Vessel` + :return: (double) seconds + + Returns shortest possible delay for `vessel` (Will be less than KSC delay if you have a local command post). + +.. method:: RTAddon:GETKSCDELAY(vessel) + + :parameter vessel: :struct:`Vessel` + :return: (double) seconds + + Returns delay in seconds from KSC to `vessel`. + +.. method:: RTAddon:HASCONNECTION(vessel) + + :parameter vessel: :struct:`Vessel` + :return: bool + + Returns True if `vessel` has any connection (including to local command posts). + +.. method:: RTAddon:HASKSCCONNECTION(vessel) + + :parameter vessel: :struct:`Vessel` + :return: bool + + Returns True if `vessel` has connection to KSC. \ No newline at end of file diff --git a/src/kOS/AddOns/KAC/KACAlarmWrapper.cs b/src/kOS/AddOns/KAC/KACAlarmWrapper.cs index a5a006b19..e782ac8dd 100644 --- a/src/kOS/AddOns/KAC/KACAlarmWrapper.cs +++ b/src/kOS/AddOns/KAC/KACAlarmWrapper.cs @@ -10,22 +10,28 @@ namespace kOS.Suffixed public class KACAlarmWrapper : Structure { private KACWrapper.KACAPI.KACAlarm alarm; + private SharedObjects shared; - public KACAlarmWrapper(KACWrapper.KACAPI.KACAlarm init) + public KACAlarmWrapper(KACWrapper.KACAPI.KACAlarm init, SharedObjects shared) { alarm = init; + this.shared = shared; InitializeSuffixes(); } - public KACAlarmWrapper(String alarmID) + public KACAlarmWrapper(String alarmID, SharedObjects shared) { alarm = KACWrapper.KAC.Alarms.First(z=>z.ID==alarmID); + this.shared = shared; InitializeSuffixes(); } private void InitializeSuffixes() { AddSuffix("ID", new Suffix(() => alarm.ID)); AddSuffix("NAME", new SetSuffix(() => alarm.Name, value => alarm.Name = value)); + AddSuffix("VESSELID", new SetSuffix(() => alarm.VesselID, value => alarm.VesselID = value)); + AddSuffix("VESSEL", new SetSuffix(() => getVesselByID(alarm.VesselID), value => alarm.VesselID = value.Vessel.id.ToString())); + AddSuffix("NOTES", new SetSuffix(() => alarm.Name, value => alarm.Name = value)); AddSuffix("ALARMACTION", new SetSuffix (alarm.AlarmAction.ToString, SetAlarmAction)); @@ -46,6 +52,15 @@ private void InitializeSuffixes() } + private VesselTarget getVesselByID (string vesselID) + { + if (string.IsNullOrEmpty (vesselID)) + return null; + + var g = new Guid(vesselID); + Vessel v = FlightGlobals.Vessels.First (z => z.id == g); + return v != null ? new VesselTarget (v, shared) : null; + } private double GetRemaining() { diff --git a/src/kOS/AddOns/KAC/KACFunctions.cs b/src/kOS/AddOns/KAC/KACFunctions.cs index 8b27ede80..ac1617ede 100644 --- a/src/kOS/AddOns/KAC/KACFunctions.cs +++ b/src/kOS/AddOns/KAC/KACFunctions.cs @@ -49,7 +49,7 @@ public override void Execute(SharedObjects shared) a.AlarmAction = KACWrapper.KACAPI.AlarmActionEnum.PauseGame; a.VesselID = shared.Vessel.id.ToString(); - var result = new KACAlarmWrapper (a); + var result = new KACAlarmWrapper (a, shared); shared.Cpu.PushStack(result); } @@ -85,8 +85,8 @@ public override void Execute(SharedObjects shared) foreach (KACWrapper.KACAPI.KACAlarm a in alarms) { - if (alarmTypes == "All" || a.AlarmTime.ToString() == alarmTypes) - list.Add (new KACAlarmWrapper(a)); + if (alarmTypes.ToUpperInvariant() == "ALL" || a.AlarmTime.ToString() == alarmTypes) + list.Add (new KACAlarmWrapper(a, shared)); } shared.Cpu.PushStack(list); } diff --git a/src/kOS/Suffixed/Addons.cs b/src/kOS/Suffixed/Addons.cs index 02d2f5417..98a5e2bae 100644 --- a/src/kOS/Suffixed/Addons.cs +++ b/src/kOS/Suffixed/Addons.cs @@ -54,7 +54,7 @@ private void InitializeSuffixes() AddSuffix("HASCONNECTION", new OneArgsSuffix(RTHasConnection, "True if ship has any connection")); - AddSuffix("HASCONNECTION", new OneArgsSuffix(RTHasConnection, "True if ship has connection to KSC")); + AddSuffix("HASKSCCONNECTION", new OneArgsSuffix(RTHasKSCConnection, "True if ship has connection to KSC")); } } From c7b0bf57799af67b5c38c4322866df52545c7b3c Mon Sep 17 00:00:00 2001 From: ZiwKerman Date: Thu, 12 Mar 2015 15:32:37 +0000 Subject: [PATCH 292/446] rename AddOns/KAC to AddOns/KerbalAlarmClock --- .../{KAC => KerbalAlarmClock}/KACAlarmWrapper.cs | 0 .../{KAC => KerbalAlarmClock}/KACEventHandler.cs | 0 .../AddOns/{KAC => KerbalAlarmClock}/KACFunctions.cs | 0 src/kOS/AddOns/{KAC => KerbalAlarmClock}/KACWrapper.cs | 0 src/kOS/kOS.csproj | 10 +++++----- 5 files changed, 5 insertions(+), 5 deletions(-) rename src/kOS/AddOns/{KAC => KerbalAlarmClock}/KACAlarmWrapper.cs (100%) rename src/kOS/AddOns/{KAC => KerbalAlarmClock}/KACEventHandler.cs (100%) rename src/kOS/AddOns/{KAC => KerbalAlarmClock}/KACFunctions.cs (100%) rename src/kOS/AddOns/{KAC => KerbalAlarmClock}/KACWrapper.cs (100%) diff --git a/src/kOS/AddOns/KAC/KACAlarmWrapper.cs b/src/kOS/AddOns/KerbalAlarmClock/KACAlarmWrapper.cs similarity index 100% rename from src/kOS/AddOns/KAC/KACAlarmWrapper.cs rename to src/kOS/AddOns/KerbalAlarmClock/KACAlarmWrapper.cs diff --git a/src/kOS/AddOns/KAC/KACEventHandler.cs b/src/kOS/AddOns/KerbalAlarmClock/KACEventHandler.cs similarity index 100% rename from src/kOS/AddOns/KAC/KACEventHandler.cs rename to src/kOS/AddOns/KerbalAlarmClock/KACEventHandler.cs diff --git a/src/kOS/AddOns/KAC/KACFunctions.cs b/src/kOS/AddOns/KerbalAlarmClock/KACFunctions.cs similarity index 100% rename from src/kOS/AddOns/KAC/KACFunctions.cs rename to src/kOS/AddOns/KerbalAlarmClock/KACFunctions.cs diff --git a/src/kOS/AddOns/KAC/KACWrapper.cs b/src/kOS/AddOns/KerbalAlarmClock/KACWrapper.cs similarity index 100% rename from src/kOS/AddOns/KAC/KACWrapper.cs rename to src/kOS/AddOns/KerbalAlarmClock/KACWrapper.cs diff --git a/src/kOS/kOS.csproj b/src/kOS/kOS.csproj index b056c3178..2352afd91 100644 --- a/src/kOS/kOS.csproj +++ b/src/kOS/kOS.csproj @@ -156,11 +156,11 @@ - - - - + + + + @@ -188,6 +188,6 @@ --> - + \ No newline at end of file From c256399cf89f1e4654d2f2676e1a05eb74095887 Mon Sep 17 00:00:00 2001 From: ZiwKerman Date: Thu, 12 Mar 2015 15:48:14 +0000 Subject: [PATCH 293/446] Code cleanup, minor fixes --- doc/source/addons/KAC.rst | 8 ++++---- src/kOS/AddOns/KerbalAlarmClock/KACAlarmWrapper.cs | 2 +- src/kOS/AddOns/KerbalAlarmClock/KACEventHandler.cs | 2 +- src/kOS/AddOns/KerbalAlarmClock/KACFunctions.cs | 6 +++--- src/kOS/AddOns/KerbalAlarmClock/KACWrapper.cs | 2 +- src/kOS/Suffixed/Addons.cs | 2 +- 6 files changed, 11 insertions(+), 11 deletions(-) diff --git a/doc/source/addons/KAC.rst b/doc/source/addons/KAC.rst index effd80f3f..e74277bf6 100644 --- a/doc/source/addons/KAC.rst +++ b/doc/source/addons/KAC.rst @@ -28,8 +28,8 @@ Creator of the KAC provides API for integration with other mods. In KOS we provi :attr:`REPEATALARMPERIOD` scalar (s) How long after the alarm fires should the next alarm be set up :attr:`VESSELID` string Unique Identifier of the Vessel that the alarm is attached to :attr:`VESSEL` :struct: `Vessel` Vessel structure of that the alarm is attached to, use this to set VESSELID - :attr:`XferOriginBodyname` string Name of the body the vessel is departing from - :attr:`XferTargetBodyname` string Name of the body the vessel is arriving at + :attr:`XFERORIGINBODYNAME` string Name of the body the vessel is departing from + :attr:`XFERTARGETBODYNAME` string Name of the body the vessel is arriving at ===================================== ========================= ============= .. attribute:: KACAlarm:ID @@ -132,14 +132,14 @@ Creator of the KAC provides API for integration with other mods. In KOS we provi :ref:`Vessel ` structure of that the alarm is attached to, use this to set VESSELID, instead of setting it directly, unless you want to unattach the Alarm from any Vessel. -.. attribute:: KACAlarm:XferOriginBodyname +.. attribute:: KACAlarm:XFERORIGINBODYNAME :type: string :access: Get/Set Name of the body the vessel is departing from. -.. attribute:: KACAlarm:XferTargetBodyname +.. attribute:: KACAlarm:XFERTARGETBODYNAME :type: string :access: Get/Set diff --git a/src/kOS/AddOns/KerbalAlarmClock/KACAlarmWrapper.cs b/src/kOS/AddOns/KerbalAlarmClock/KACAlarmWrapper.cs index e782ac8dd..2749a3822 100644 --- a/src/kOS/AddOns/KerbalAlarmClock/KACAlarmWrapper.cs +++ b/src/kOS/AddOns/KerbalAlarmClock/KACAlarmWrapper.cs @@ -3,7 +3,7 @@ using kOS.Safe.Encapsulation; using kOS.Safe.Encapsulation.Suffixes; using kOS.Safe.Utilities; -using kOS.AddOns.KAC; +using kOS.AddOns.KerbalAlarmClock; namespace kOS.Suffixed { diff --git a/src/kOS/AddOns/KerbalAlarmClock/KACEventHandler.cs b/src/kOS/AddOns/KerbalAlarmClock/KACEventHandler.cs index a539cc25e..800105fce 100644 --- a/src/kOS/AddOns/KerbalAlarmClock/KACEventHandler.cs +++ b/src/kOS/AddOns/KerbalAlarmClock/KACEventHandler.cs @@ -6,7 +6,7 @@ using UnityEngine; using Debug = UnityEngine.Debug; -using kOS.AddOns.KAC; +using kOS.AddOns.KerbalAlarmClock; namespace kOS { diff --git a/src/kOS/AddOns/KerbalAlarmClock/KACFunctions.cs b/src/kOS/AddOns/KerbalAlarmClock/KACFunctions.cs index ac1617ede..4de105a81 100644 --- a/src/kOS/AddOns/KerbalAlarmClock/KACFunctions.cs +++ b/src/kOS/AddOns/KerbalAlarmClock/KACFunctions.cs @@ -7,7 +7,7 @@ using kOS.Safe.Exceptions; using kOS.Suffixed; using kOS.Utilities; -using kOS.AddOns.KAC; +using kOS.AddOns.KerbalAlarmClock; namespace kOS.Function { @@ -105,17 +105,17 @@ public class FunctionDeleteAlarm : FunctionBase public override void Execute(SharedObjects shared) { string alarmID = shared.Cpu.PopValue().ToString(); - Boolean result = false; if (KACWrapper.APIReady) { + Boolean result = false; //Delete the Alarm using its ID and get the result result = KACWrapper.KAC.DeleteAlarm(alarmID); shared.Cpu.PushStack(result); } else { - shared.Cpu.PushStack(result); + shared.Cpu.PushStack(false); throw new KOSUnavailableAddonException("deleteAlarm()", "Kerbal Alarm Clock"); } } diff --git a/src/kOS/AddOns/KerbalAlarmClock/KACWrapper.cs b/src/kOS/AddOns/KerbalAlarmClock/KACWrapper.cs index cdde14ed8..e3600e940 100644 --- a/src/kOS/AddOns/KerbalAlarmClock/KACWrapper.cs +++ b/src/kOS/AddOns/KerbalAlarmClock/KACWrapper.cs @@ -6,7 +6,7 @@ using System.Reflection; using System.Text; -namespace kOS.AddOns.KAC +namespace kOS.AddOns.KerbalAlarmClock { /////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/kOS/Suffixed/Addons.cs b/src/kOS/Suffixed/Addons.cs index 98a5e2bae..8a620509d 100644 --- a/src/kOS/Suffixed/Addons.cs +++ b/src/kOS/Suffixed/Addons.cs @@ -115,7 +115,7 @@ public Boolean Available() if (addonName == "KAC") { - return kOS.AddOns.KAC.KACWrapper.APIReady; + return kOS.AddOns.KerbalAlarmClock.KACWrapper.APIReady; } if (addonName == "RT") From 63004b23264128dc74d37ef636286392377a3a57 Mon Sep 17 00:00:00 2001 From: ZiwKerman Date: Thu, 12 Mar 2015 16:34:50 +0000 Subject: [PATCH 294/446] code cleanup, suffix readability --- doc/source/addons/KAC.rst | 42 ++++++++----------- .../KerbalAlarmClock/KACAlarmWrapper.cs | 27 +++++++----- src/kOS/Suffixed/{Addons.cs => Addon.cs} | 30 +------------ src/kOS/Suffixed/AddonList.cs | 34 +++++++++++++++ src/kOS/kOS.csproj | 3 +- 5 files changed, 71 insertions(+), 65 deletions(-) rename src/kOS/Suffixed/{Addons.cs => Addon.cs} (78%) create mode 100644 src/kOS/Suffixed/AddonList.cs diff --git a/doc/source/addons/KAC.rst b/doc/source/addons/KAC.rst index e74277bf6..8ea618ff4 100644 --- a/doc/source/addons/KAC.rst +++ b/doc/source/addons/KAC.rst @@ -20,16 +20,15 @@ Creator of the KAC provides API for integration with other mods. In KOS we provi ===================================== ========================= ============= :attr:`ID` string (readonly) Unique identifier :attr:`NAME` string Name of the alarm - :attr:`ALARMACTION` string What should the Alarm Clock do when the alarm fires - :attr:`ALARMTYPE` string (readonly) What type of Alarm is this - affects icon displayed and some calc options + :attr:`ACTION` string What should the Alarm Clock do when the alarm fires + :attr:`TYPE` string (readonly) What type of Alarm is this - affects icon displayed and some calc options :attr:`NOTES` string Long description of the alarm (optional) :attr:`REMAINING` scalar (s) Time remaining until alarm is triggered - :attr:`REPEATALARM` bool Should the alarm be repeated once it fires - :attr:`REPEATALARMPERIOD` scalar (s) How long after the alarm fires should the next alarm be set up - :attr:`VESSELID` string Unique Identifier of the Vessel that the alarm is attached to + :attr:`REPEAT` bool Should the alarm be repeated once it fires + :attr:`REPEATPERIOD` scalar (s) How long after the alarm fires should the next alarm be set up :attr:`VESSEL` :struct: `Vessel` Vessel structure of that the alarm is attached to, use this to set VESSELID - :attr:`XFERORIGINBODYNAME` string Name of the body the vessel is departing from - :attr:`XFERTARGETBODYNAME` string Name of the body the vessel is arriving at + :attr:`ORIGINBODY` string Name of the body the vessel is departing from + :attr:`TARGETBODY` string Name of the body the vessel is arriving at ===================================== ========================= ============= .. attribute:: KACAlarm:ID @@ -46,7 +45,7 @@ Creator of the KAC provides API for integration with other mods. In KOS we provi Name of the alarm. Displayed in main KAC window. -.. attribute:: KACAlarm:ALARMACTION +.. attribute:: KACAlarm:ACTION :type: string :access: Get/Set @@ -60,7 +59,7 @@ Creator of the KAC provides API for integration with other mods. In KOS we provi If set incorrectly will log a warning in Debug log and revert to previous or default value. -.. attribute:: KACAlarm:ALARMTYPE +.. attribute:: KACAlarm:TYPE :type: string :access: Get only @@ -103,27 +102,20 @@ Creator of the KAC provides API for integration with other mods. In KOS we provi Time remaining until alarm is triggered. -.. attribute:: KACAlarm:REPEATALARM +.. attribute:: KACAlarm:REPEAT :type: bool :access: Get/Set Should the alarm be repeated once it fires. -.. attribute:: KACAlarm:REPEATALARMPERIOD +.. attribute:: KACAlarm:REPEATPERIOD :type: double :access: Get/Set How long after the alarm fires should the next alarm be set up. -.. attribute:: KACAlarm:VESSELID - - :type: string - :access: Get/Set - - Unique Identifier of the Vessel that the alarm is attached to. Should only be used to unattach Alarm from any Vessel by setting to ampty string. - .. attribute:: KACAlarm:VESSEL :type: :struct: `Vessel` @@ -132,14 +124,14 @@ Creator of the KAC provides API for integration with other mods. In KOS we provi :ref:`Vessel ` structure of that the alarm is attached to, use this to set VESSELID, instead of setting it directly, unless you want to unattach the Alarm from any Vessel. -.. attribute:: KACAlarm:XFERORIGINBODYNAME +.. attribute:: KACAlarm:ORIGINBODY :type: string :access: Get/Set Name of the body the vessel is departing from. -.. attribute:: KACAlarm:XFERTARGETBODYNAME +.. attribute:: KACAlarm:TARGETBODY :type: string :access: Get/Set @@ -149,7 +141,7 @@ Creator of the KAC provides API for integration with other mods. In KOS we provi Available Functions -=================== +------------------- ============================================= =================================================== Function Description @@ -184,7 +176,7 @@ Available Functions Deletes alarm with ID equal to alarmID. Returns True if successful, false otherwise:: set na to addAlarm("Raw",time:seconds+300, "Test", "Notes"). - if (DELETEALARM(na:ID)) - { - print "Alarm Deleted". - } + if (DELETEALARM(na:ID)) + { + print "Alarm Deleted". + } diff --git a/src/kOS/AddOns/KerbalAlarmClock/KACAlarmWrapper.cs b/src/kOS/AddOns/KerbalAlarmClock/KACAlarmWrapper.cs index 2749a3822..85c637008 100644 --- a/src/kOS/AddOns/KerbalAlarmClock/KACAlarmWrapper.cs +++ b/src/kOS/AddOns/KerbalAlarmClock/KACAlarmWrapper.cs @@ -24,34 +24,36 @@ public KACAlarmWrapper(String alarmID, SharedObjects shared) this.shared = shared; InitializeSuffixes(); } + private void InitializeSuffixes() { AddSuffix("ID", new Suffix(() => alarm.ID)); AddSuffix("NAME", new SetSuffix(() => alarm.Name, value => alarm.Name = value)); - AddSuffix("VESSELID", new SetSuffix(() => alarm.VesselID, value => alarm.VesselID = value)); - AddSuffix("VESSEL", new SetSuffix(() => getVesselByID(alarm.VesselID), value => alarm.VesselID = value.Vessel.id.ToString())); + //AddSuffix("VESSELID", new SetSuffix(() => alarm.VesselID, value => alarm.VesselID = value)); + AddSuffix("VESSEL", new SetSuffix (() => getVesselByID (alarm.VesselID), setVesselID)); AddSuffix("NOTES", new SetSuffix(() => alarm.Name, value => alarm.Name = value)); - AddSuffix("ALARMACTION", new SetSuffix (alarm.AlarmAction.ToString, SetAlarmAction)); + AddSuffix("ACTION", new SetSuffix (alarm.AlarmAction.ToString, SetAlarmAction)); - AddSuffix("ALARMTYPE", new Suffix (alarm.AlarmType.ToString)); + AddSuffix("TYPE", new Suffix (alarm.AlarmType.ToString)); AddSuffix("REMAINING", new Suffix(GetRemaining)); - AddSuffix("ALARMTIME", new SetSuffix(() => alarm.AlarmTime, value => alarm.AlarmTime = value)); - AddSuffix("ALARMMARGIN", new SetSuffix(() => alarm.AlarmMargin, value => alarm.AlarmMargin = value)); + AddSuffix("TIME", new SetSuffix(() => alarm.AlarmTime, value => alarm.AlarmTime = value)); + AddSuffix("MARGIN", new SetSuffix(() => alarm.AlarmMargin, value => alarm.AlarmMargin = value)); - AddSuffix("REPEATALARM", new SetSuffix(() => alarm.RepeatAlarm, value => alarm.RepeatAlarm = value)); + AddSuffix("REPEAT", new SetSuffix(() => alarm.RepeatAlarm, value => alarm.RepeatAlarm = value)); - AddSuffix("REPEATALARMPERIOD", new SetSuffix(() => alarm.RepeatAlarmPeriod, value => alarm.RepeatAlarmPeriod = value)); + AddSuffix("REPEATPERIOD", new SetSuffix(() => alarm.RepeatAlarmPeriod, value => alarm.RepeatAlarmPeriod = value)); - AddSuffix("XferOriginBodyName", new SetSuffix(() => alarm.XferOriginBodyName, value => alarm.XferOriginBodyName = value)); - AddSuffix("XferTargetBodyName", new SetSuffix(() => alarm.XferTargetBodyName, value => alarm.XferTargetBodyName = value)); + AddSuffix("ORIGINBODY", new SetSuffix(() => alarm.XferOriginBodyName, value => alarm.XferOriginBodyName = value)); + AddSuffix("TARGETBODY", new SetSuffix(() => alarm.XferTargetBodyName, value => alarm.XferTargetBodyName = value)); } + private VesselTarget getVesselByID (string vesselID) { if (string.IsNullOrEmpty (vesselID)) @@ -62,6 +64,11 @@ private VesselTarget getVesselByID (string vesselID) return v != null ? new VesselTarget (v, shared) : null; } + private void setVesselID (VesselTarget v) + { + alarm.VesselID = v.Vessel == null ? "" : v.Vessel.id.ToString (); + } + private double GetRemaining() { /*SafeHouse.Logger.LogWarning (string.Format ("Trying to get remaining time, {0}", alarm.Remaining));*/ diff --git a/src/kOS/Suffixed/Addons.cs b/src/kOS/Suffixed/Addon.cs similarity index 78% rename from src/kOS/Suffixed/Addons.cs rename to src/kOS/Suffixed/Addon.cs index 8a620509d..75482eee5 100644 --- a/src/kOS/Suffixed/Addons.cs +++ b/src/kOS/Suffixed/Addon.cs @@ -4,37 +4,9 @@ namespace kOS.Suffixed { - public class AddonList : Structure - { - private Addon KACAddon; - private Addon RTAddon; - private Addon AGXAddon; - - public AddonList() - { - KACAddon = new Addon ("KAC"); - RTAddon = new Addon ("RT"); - AGXAddon = new Addon ("AGX"); - - InitializeSuffixes(); - } - - private void InitializeSuffixes() - { - AddSuffix("KAC", new Suffix(() => KACAddon)); - AddSuffix("RT", new Suffix(() => RTAddon)); - AddSuffix("AGX", new Suffix(() => AGXAddon)); - } - - public override string ToString() - { - return string.Format("{0} AddonList", base.ToString()); - } - } - public class Addon : Structure { - public string addonName = ""; + private string addonName = ""; public Addon(string name) { diff --git a/src/kOS/Suffixed/AddonList.cs b/src/kOS/Suffixed/AddonList.cs new file mode 100644 index 000000000..d74232b40 --- /dev/null +++ b/src/kOS/Suffixed/AddonList.cs @@ -0,0 +1,34 @@ +using System; +using kOS.Safe.Encapsulation.Suffixes; +using kOS.Safe.Encapsulation; + +namespace kOS.Suffixed +{ + public class AddonList : Structure + { + private Addon kacAddon; + private Addon rtAddon; + private Addon agxAddon; + + public AddonList() + { + kacAddon = new Addon ("KAC"); + rtAddon = new Addon ("RT"); + agxAddon = new Addon ("AGX"); + + InitializeSuffixes(); + } + + private void InitializeSuffixes() + { + AddSuffix("KAC", new Suffix(() => kacAddon)); + AddSuffix("RT", new Suffix(() => rtAddon)); + AddSuffix("AGX", new Suffix(() => agxAddon)); + } + + public override string ToString() + { + return string.Format("{0} AddonList", base.ToString()); + } + } +} diff --git a/src/kOS/kOS.csproj b/src/kOS/kOS.csproj index 2352afd91..fd4b7c25b 100644 --- a/src/kOS/kOS.csproj +++ b/src/kOS/kOS.csproj @@ -156,11 +156,12 @@ - + + From 25038dfd4e378c8b43573fa3baf65eeb1298ce7a Mon Sep 17 00:00:00 2001 From: ZiwKerman Date: Thu, 12 Mar 2015 16:40:36 +0000 Subject: [PATCH 295/446] RT suffix fix + docs --- doc/source/addons/RemoteTech.rst | 8 ++++---- src/kOS/Suffixed/Addon.cs | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/doc/source/addons/RemoteTech.rst b/doc/source/addons/RemoteTech.rst index 0eee2f3fc..5abe644ef 100644 --- a/doc/source/addons/RemoteTech.rst +++ b/doc/source/addons/RemoteTech.rst @@ -13,8 +13,8 @@ Access structure RTAddon via `ADDONS:RT`. Suffix Type Description ===================================== ========================= ============= :attr:`AVAILABLE` bool(readonly) True if RT is installed and RT integration enabled. - :meth:`GETDELAY(vessel)` double Get shortest possible delay to given :struct:`Vessel` - :meth:`GETKSCDELAY(vessel)` double Get delay from KSC to given :struct:`Vessel` + :meth:`DELAY(vessel)` double Get shortest possible delay to given :struct:`Vessel` + :meth:`KSCDELAY(vessel)` double Get delay from KSC to given :struct:`Vessel` :meth:`HASCONNECTION(vessel)` bool True if given :struct:`Vessel` has any connection :meth:`HASKSCCONNECTION(vessel)` bool True if given :struct:`Vessel` has connection to KSC ===================================== ========================= ============= @@ -28,14 +28,14 @@ Access structure RTAddon via `ADDONS:RT`. True if RT is installed and RT integration enabled. -.. method:: RTAddon:GETDELAY(vessel) +.. method:: RTAddon:DELAY(vessel) :parameter vessel: :struct:`Vessel` :return: (double) seconds Returns shortest possible delay for `vessel` (Will be less than KSC delay if you have a local command post). -.. method:: RTAddon:GETKSCDELAY(vessel) +.. method:: RTAddon:KSCDELAY(vessel) :parameter vessel: :struct:`Vessel` :return: (double) seconds diff --git a/src/kOS/Suffixed/Addon.cs b/src/kOS/Suffixed/Addon.cs index 75482eee5..0ea39ac33 100644 --- a/src/kOS/Suffixed/Addon.cs +++ b/src/kOS/Suffixed/Addon.cs @@ -20,9 +20,9 @@ private void InitializeSuffixes() if (addonName == "RT") { - AddSuffix("GETDELAY", new OneArgsSuffix(RTGetDelay, "Get current Shortest Signal Delay for Vessel")); + AddSuffix("DELAY", new OneArgsSuffix(RTGetDelay, "Get current Shortest Signal Delay for Vessel")); - AddSuffix("GETKSCDELAY", new OneArgsSuffix(RTGetKSCDelay, "Get current KSC Signal Delay")); + AddSuffix("KSCDELAY", new OneArgsSuffix(RTGetKSCDelay, "Get current KSC Signal Delay")); AddSuffix("HASCONNECTION", new OneArgsSuffix(RTHasConnection, "True if ship has any connection")); From 73c0d823a3815c0e9f5fa64f9343badef533f48f Mon Sep 17 00:00:00 2001 From: Chris Woerz Date: Thu, 12 Mar 2015 11:34:46 -0600 Subject: [PATCH 296/446] fiddly bits --- .../KerbalAlarmClock/KACAlarmWrapper.cs | 56 +++++++-------- .../KerbalAlarmClock/KACEventHandler.cs | 19 ++--- .../AddOns/KerbalAlarmClock/KACFunctions.cs | 71 +++++++++---------- src/kOS/AddOns/KerbalAlarmClock/KACWrapper.cs | 3 +- src/kOS/Suffixed/Addon.cs | 31 ++++---- src/kOS/Suffixed/AddonList.cs | 17 +++-- 6 files changed, 90 insertions(+), 107 deletions(-) diff --git a/src/kOS/AddOns/KerbalAlarmClock/KACAlarmWrapper.cs b/src/kOS/AddOns/KerbalAlarmClock/KACAlarmWrapper.cs index 85c637008..322180134 100644 --- a/src/kOS/AddOns/KerbalAlarmClock/KACAlarmWrapper.cs +++ b/src/kOS/AddOns/KerbalAlarmClock/KACAlarmWrapper.cs @@ -1,26 +1,27 @@ -using System; -using System.Linq; -using kOS.Safe.Encapsulation; +using kOS.Safe.Encapsulation; using kOS.Safe.Encapsulation.Suffixes; using kOS.Safe.Utilities; -using kOS.AddOns.KerbalAlarmClock; +using kOS.Suffixed; +using System; +using System.Linq; -namespace kOS.Suffixed +namespace kOS.AddOns.KerbalAlarmClock { public class KACAlarmWrapper : Structure { - private KACWrapper.KACAPI.KACAlarm alarm; - private SharedObjects shared; + private readonly KACWrapper.KACAPI.KACAlarm alarm; + private readonly SharedObjects shared; - public KACAlarmWrapper(KACWrapper.KACAPI.KACAlarm init, SharedObjects shared) - { + public KACAlarmWrapper(KACWrapper.KACAPI.KACAlarm init, SharedObjects shared) + { alarm = init; this.shared = shared; InitializeSuffixes(); } - public KACAlarmWrapper(String alarmID, SharedObjects shared) + + public KACAlarmWrapper(String alarmID, SharedObjects shared) { - alarm = KACWrapper.KAC.Alarms.First(z=>z.ID==alarmID); + alarm = KACWrapper.KAC.Alarms.First(z => z.ID == alarmID); this.shared = shared; InitializeSuffixes(); } @@ -31,13 +32,13 @@ private void InitializeSuffixes() AddSuffix("NAME", new SetSuffix(() => alarm.Name, value => alarm.Name = value)); //AddSuffix("VESSELID", new SetSuffix(() => alarm.VesselID, value => alarm.VesselID = value)); - AddSuffix("VESSEL", new SetSuffix (() => getVesselByID (alarm.VesselID), setVesselID)); + AddSuffix("VESSEL", new SetSuffix(() => GetVesselByID(alarm.VesselID), SetVesselID)); AddSuffix("NOTES", new SetSuffix(() => alarm.Name, value => alarm.Name = value)); - AddSuffix("ACTION", new SetSuffix (alarm.AlarmAction.ToString, SetAlarmAction)); + AddSuffix("ACTION", new SetSuffix(alarm.AlarmAction.ToString, SetAlarmAction)); - AddSuffix("TYPE", new Suffix (alarm.AlarmType.ToString)); + AddSuffix("TYPE", new Suffix(alarm.AlarmType.ToString)); AddSuffix("REMAINING", new Suffix(GetRemaining)); @@ -50,23 +51,21 @@ private void InitializeSuffixes() AddSuffix("ORIGINBODY", new SetSuffix(() => alarm.XferOriginBodyName, value => alarm.XferOriginBodyName = value)); AddSuffix("TARGETBODY", new SetSuffix(() => alarm.XferTargetBodyName, value => alarm.XferTargetBodyName = value)); - - } - private VesselTarget getVesselByID (string vesselID) + private VesselTarget GetVesselByID(string vesselID) { - if (string.IsNullOrEmpty (vesselID)) + if (string.IsNullOrEmpty(vesselID)) return null; - + var g = new Guid(vesselID); - Vessel v = FlightGlobals.Vessels.First (z => z.id == g); - return v != null ? new VesselTarget (v, shared) : null; + Vessel v = FlightGlobals.Vessels.First(z => z.id == g); + return v != null ? new VesselTarget(v, shared) : null; } - private void setVesselID (VesselTarget v) + private void SetVesselID(VesselTarget v) { - alarm.VesselID = v.Vessel == null ? "" : v.Vessel.id.ToString (); + alarm.VesselID = v.Vessel == null ? "" : v.Vessel.id.ToString(); } private double GetRemaining() @@ -75,21 +74,18 @@ private double GetRemaining() //workaround for alarm.Remaining type mismatch return alarm.AlarmTime - Planetarium.GetUniversalTime(); } - + private void SetAlarmAction(string newAlarmAction) { - KACWrapper.KACAPI.AlarmActionEnum result; try { - result = (KACWrapper.KACAPI.AlarmActionEnum) Enum.Parse(typeof(KACWrapper.KACAPI.AlarmActionEnum), newAlarmAction); + var result = (KACWrapper.KACAPI.AlarmActionEnum)Enum.Parse(typeof(KACWrapper.KACAPI.AlarmActionEnum), newAlarmAction); alarm.AlarmAction = result; } catch (ArgumentException) { - SafeHouse.Logger.LogWarning (string.Format ("Failed parsing {0} into KACAPI.AlarmActionEnum", newAlarmAction)); + SafeHouse.Logger.LogWarning(string.Format("Failed parsing {0} into KACAPI.AlarmActionEnum", newAlarmAction)); } - } } -} - +} \ No newline at end of file diff --git a/src/kOS/AddOns/KerbalAlarmClock/KACEventHandler.cs b/src/kOS/AddOns/KerbalAlarmClock/KACEventHandler.cs index 800105fce..6e5d43f61 100644 --- a/src/kOS/AddOns/KerbalAlarmClock/KACEventHandler.cs +++ b/src/kOS/AddOns/KerbalAlarmClock/KACEventHandler.cs @@ -1,14 +1,7 @@ -using System; -using System.IO; -using kOS.Safe.Persistence; -using kOS.Safe.Utilities; -using kOS.Suffixed; -using UnityEngine; +using UnityEngine; using Debug = UnityEngine.Debug; -using kOS.AddOns.KerbalAlarmClock; - -namespace kOS +namespace kOS.AddOns.KerbalAlarmClock { [KSPAddon(KSPAddon.Startup.EveryScene, false)] public class KACEventHandler : MonoBehaviour @@ -22,9 +15,8 @@ public void Start() //register Event Handler KACWrapper.KAC.onAlarmStateChanged += KAC_onAlarmStateChanged; - Debug.Log (string.Format ("{0} Kerbal Alarm Clock found, Alarms Count {1}", KSPLogger.LOGGER_PREFIX, KACWrapper.KAC.Alarms.Count)); + Debug.Log(string.Format("{0} Kerbal Alarm Clock found, Alarms Count {1}", KSPLogger.LOGGER_PREFIX, KACWrapper.KAC.Alarms.Count)); } - } public void OnDestroy() @@ -36,11 +28,10 @@ public void OnDestroy() } } - void KAC_onAlarmStateChanged(KACWrapper.KACAPI.AlarmStateChangedEventArgs e) + private void KAC_onAlarmStateChanged(KACWrapper.KACAPI.AlarmStateChangedEventArgs e) { //output whats happened - Debug.Log (string.Format("{0}, caugth Event from alarm {1}, event type {2}", KSPLogger.LOGGER_PREFIX, e.alarm.Name, e.eventType)); + Debug.Log(string.Format("{0}, caught Event from alarm {1}, event type {2}", KSPLogger.LOGGER_PREFIX, e.alarm.Name, e.eventType)); } - } } \ No newline at end of file diff --git a/src/kOS/AddOns/KerbalAlarmClock/KACFunctions.cs b/src/kOS/AddOns/KerbalAlarmClock/KACFunctions.cs index 4de105a81..d57850750 100644 --- a/src/kOS/AddOns/KerbalAlarmClock/KACFunctions.cs +++ b/src/kOS/AddOns/KerbalAlarmClock/KACFunctions.cs @@ -1,15 +1,12 @@ -using System; -using System.Linq; +using kOS.Function; using kOS.Safe.Encapsulation; +using kOS.Safe.Exceptions; using kOS.Safe.Function; using kOS.Safe.Utilities; -using kOS.Safe.Persistence; -using kOS.Safe.Exceptions; -using kOS.Suffixed; -using kOS.Utilities; -using kOS.AddOns.KerbalAlarmClock; +using System; +using System.Linq; -namespace kOS.Function +namespace kOS.AddOns.KerbalAlarmClock { [Function("addAlarm")] public class FunctionAddAlarm : FunctionBase @@ -26,45 +23,44 @@ public override void Execute(SharedObjects shared) KACWrapper.KACAPI.AlarmTypeEnum newAlarmType; try { - newAlarmType = (KACWrapper.KACAPI.AlarmTypeEnum) Enum.Parse(typeof(KACWrapper.KACAPI.AlarmTypeEnum), alarmType); + newAlarmType = (KACWrapper.KACAPI.AlarmTypeEnum)Enum.Parse(typeof(KACWrapper.KACAPI.AlarmTypeEnum), alarmType); } catch (ArgumentException) { - SafeHouse.Logger.LogWarning (string.Format ("Failed parsing {0} into KACAPI.AlarmTypeEnum", alarmType)); + SafeHouse.Logger.LogWarning(string.Format("Failed parsing {0} into KACAPI.AlarmTypeEnum", alarmType)); //failed parsing alarmType, defaulting to Raw newAlarmType = KACWrapper.KACAPI.AlarmTypeEnum.Raw; } String aID = KACWrapper.KAC.CreateAlarm(newAlarmType, alarmName, alarmUT); - SafeHouse.Logger.Log (string.Format ("Trying to create KAC Alarm, UT={0}, Name={1}, type = {2}", alarmUT.ToString (), alarmName, alarmType)); + SafeHouse.Logger.Log(string.Format("Trying to create KAC Alarm, UT={0}, Name={1}, Type= {2}", alarmUT, alarmName, alarmType)); - if (aID !="") + if (!string.IsNullOrEmpty(aID)) { //if the alarm was made get the object so we can update it - KACWrapper.KACAPI.KACAlarm a = KACWrapper.KAC.Alarms.First(z=>z.ID==aID); + KACWrapper.KACAPI.KACAlarm a = KACWrapper.KAC.Alarms.First(z => z.ID == aID); //Now update some of the other properties a.Notes = alarmNotes; a.AlarmAction = KACWrapper.KACAPI.AlarmActionEnum.PauseGame; a.VesselID = shared.Vessel.id.ToString(); - var result = new KACAlarmWrapper (a, shared); + var result = new KACAlarmWrapper(a, shared); shared.Cpu.PushStack(result); } else { - shared.Cpu.PushStack(""); - SafeHouse.Logger.Log(string.Format("Failed creating KAC Alarm, UT={0}, Name={1}, type = {2}", alarmUT.ToString(), alarmName, alarmType)); + shared.Cpu.PushStack(string.Empty); + SafeHouse.Logger.Log(string.Format("Failed creating KAC Alarm, UT={0}, Name={1}, Type= {2}", alarmUT, alarmName, alarmType)); } - } else { //KAC integration not present. - shared.Cpu.PushStack(""); - throw new KOSUnavailableAddonException("addAlarm()", "Kerbal Alarm Clock"); + shared.Cpu.PushStack(string.Empty); + throw new KOSUnavailableAddonException("addAlarm()", "Kerbal Alarm Clock"); } } } @@ -78,27 +74,30 @@ public override void Execute(SharedObjects shared) string alarmTypes = shared.Cpu.PopValue().ToString(); - if (KACWrapper.APIReady) + if (!KACWrapper.APIReady) { - //Get the list of alarms from the KAC Object - KACWrapper.KACAPI.KACAlarmList alarms = KACWrapper.KAC.Alarms; - - foreach (KACWrapper.KACAPI.KACAlarm a in alarms) - { - if (alarmTypes.ToUpperInvariant() == "ALL" || a.AlarmTime.ToString() == alarmTypes) - list.Add (new KACAlarmWrapper(a, shared)); - } shared.Cpu.PushStack(list); + throw new KOSUnavailableAddonException("listAlarms()", "Kerbal Alarm Clock"); } - else + + //Get the list of alarms from the KAC Object + KACWrapper.KACAPI.KACAlarmList alarms = KACWrapper.KAC.Alarms; + + foreach (KACWrapper.KACAPI.KACAlarm alarm in alarms) { - shared.Cpu.PushStack(list); - throw new KOSUnavailableAddonException("listAlarms()", "Kerbal Alarm Clock"); + // if its not my alarm or a general alarm, ignore it + if (!string.IsNullOrEmpty(alarm.VesselID) && alarm.VesselID != shared.Vessel.id.ToString()) + { + continue; + } + + if (alarmTypes.ToUpperInvariant() == "ALL" || alarm.AlarmTime.ToString() == alarmTypes) + list.Add(new KACAlarmWrapper(alarm, shared)); } - + shared.Cpu.PushStack(list); } } - + [Function("deleteAlarm")] public class FunctionDeleteAlarm : FunctionBase { @@ -108,9 +107,7 @@ public override void Execute(SharedObjects shared) if (KACWrapper.APIReady) { - Boolean result = false; - //Delete the Alarm using its ID and get the result - result = KACWrapper.KAC.DeleteAlarm(alarmID); + bool result = KACWrapper.KAC.DeleteAlarm(alarmID); shared.Cpu.PushStack(result); } else @@ -120,4 +117,4 @@ public override void Execute(SharedObjects shared) } } } -} +} \ No newline at end of file diff --git a/src/kOS/AddOns/KerbalAlarmClock/KACWrapper.cs b/src/kOS/AddOns/KerbalAlarmClock/KACWrapper.cs index e3600e940..84a9f81ce 100644 --- a/src/kOS/AddOns/KerbalAlarmClock/KACWrapper.cs +++ b/src/kOS/AddOns/KerbalAlarmClock/KACWrapper.cs @@ -4,13 +4,12 @@ using System.ComponentModel; using System.Linq; using System.Reflection; -using System.Text; namespace kOS.AddOns.KerbalAlarmClock { /////////////////////////////////////////////////////////////////////////////////////////// - // BELOW HERE SHOULD NOT BE EDITED - this links to the loaded KAC module without requiring a Hard Dependancy + // BELOW HERE SHOULD NOT BE EDITED - this links to the loaded KAC module without requiring a Hard Dependency /////////////////////////////////////////////////////////////////////////////////////////// /// diff --git a/src/kOS/Suffixed/Addon.cs b/src/kOS/Suffixed/Addon.cs index 0ea39ac33..8eb60d100 100644 --- a/src/kOS/Suffixed/Addon.cs +++ b/src/kOS/Suffixed/Addon.cs @@ -1,12 +1,12 @@ -using System; +using kOS.Safe.Encapsulation; using kOS.Safe.Encapsulation.Suffixes; -using kOS.Safe.Encapsulation; +using System; namespace kOS.Suffixed { public class Addon : Structure { - private string addonName = ""; + private readonly string addonName; public Addon(string name) { @@ -14,6 +14,7 @@ public Addon(string name) InitializeSuffixes(); } + private void InitializeSuffixes() { AddSuffix("AVAILABLE", new Suffix(Available)); @@ -34,9 +35,9 @@ private static double RTGetDelay(VesselTarget tgtVessel) { double waitTotal = 0; - if (kOS.AddOns.RemoteTech.RemoteTechHook.IsAvailable(tgtVessel.Vessel.id) && tgtVessel.Vessel.GetVesselCrew().Count == 0) + if (AddOns.RemoteTech.RemoteTechHook.IsAvailable(tgtVessel.Vessel.id) && tgtVessel.Vessel.GetVesselCrew().Count == 0) { - waitTotal = kOS.AddOns.RemoteTech.RemoteTechHook.Instance.GetShortestSignalDelay(tgtVessel.Vessel.id); + waitTotal = AddOns.RemoteTech.RemoteTechHook.Instance.GetShortestSignalDelay(tgtVessel.Vessel.id); } return waitTotal; @@ -46,9 +47,9 @@ private static double RTGetKSCDelay(VesselTarget tgtVessel) { double waitTotal = 0; - if (kOS.AddOns.RemoteTech.RemoteTechHook.IsAvailable(tgtVessel.Vessel.id) && tgtVessel.Vessel.GetVesselCrew().Count == 0) + if (AddOns.RemoteTech.RemoteTechHook.IsAvailable(tgtVessel.Vessel.id) && tgtVessel.Vessel.GetVesselCrew().Count == 0) { - waitTotal = kOS.AddOns.RemoteTech.RemoteTechHook.Instance.GetSignalDelayToKSC(tgtVessel.Vessel.id); + waitTotal = AddOns.RemoteTech.RemoteTechHook.Instance.GetSignalDelayToKSC(tgtVessel.Vessel.id); } return waitTotal; @@ -58,9 +59,9 @@ private static bool RTHasConnection(VesselTarget tgtVessel) { bool result = false; - if (kOS.AddOns.RemoteTech.RemoteTechHook.IsAvailable(tgtVessel.Vessel.id)) + if (AddOns.RemoteTech.RemoteTechHook.IsAvailable(tgtVessel.Vessel.id)) { - result = kOS.AddOns.RemoteTech.RemoteTechHook.Instance.HasAnyConnection(tgtVessel.Vessel.id); + result = AddOns.RemoteTech.RemoteTechHook.Instance.HasAnyConnection(tgtVessel.Vessel.id); } return result; @@ -70,9 +71,9 @@ private static bool RTHasKSCConnection(VesselTarget tgtVessel) { bool result = false; - if (kOS.AddOns.RemoteTech.RemoteTechHook.IsAvailable(tgtVessel.Vessel.id)) + if (AddOns.RemoteTech.RemoteTechHook.IsAvailable(tgtVessel.Vessel.id)) { - result = kOS.AddOns.RemoteTech.RemoteTechHook.Instance.HasConnectionToKSC(tgtVessel.Vessel.id); + result = AddOns.RemoteTech.RemoteTechHook.Instance.HasConnectionToKSC(tgtVessel.Vessel.id); } return result; @@ -82,17 +83,17 @@ public Boolean Available() { if (addonName == "AGX") { - return kOS.AddOns.ActionGroupsExtended.ActionGroupsExtendedAPI.Instance.Installed (); + return AddOns.ActionGroupsExtended.ActionGroupsExtendedAPI.Instance.Installed(); } if (addonName == "KAC") { - return kOS.AddOns.KerbalAlarmClock.KACWrapper.APIReady; + return AddOns.KerbalAlarmClock.KACWrapper.APIReady; } if (addonName == "RT") { - return kOS.AddOns.RemoteTech.RemoteTechHook.IsAvailable (); + return AddOns.RemoteTech.RemoteTechHook.IsAvailable(); } return false; } @@ -102,4 +103,4 @@ public override string ToString() return string.Format("{0} Addon", base.ToString()); } } -} +} \ No newline at end of file diff --git a/src/kOS/Suffixed/AddonList.cs b/src/kOS/Suffixed/AddonList.cs index d74232b40..630e3f5ca 100644 --- a/src/kOS/Suffixed/AddonList.cs +++ b/src/kOS/Suffixed/AddonList.cs @@ -1,20 +1,19 @@ -using System; +using kOS.Safe.Encapsulation; using kOS.Safe.Encapsulation.Suffixes; -using kOS.Safe.Encapsulation; namespace kOS.Suffixed { public class AddonList : Structure { - private Addon kacAddon; - private Addon rtAddon; - private Addon agxAddon; + private readonly Addon kacAddon; + private readonly Addon rtAddon; + private readonly Addon agxAddon; public AddonList() { - kacAddon = new Addon ("KAC"); - rtAddon = new Addon ("RT"); - agxAddon = new Addon ("AGX"); + kacAddon = new Addon("KAC"); + rtAddon = new Addon("RT"); + agxAddon = new Addon("AGX"); InitializeSuffixes(); } @@ -31,4 +30,4 @@ public override string ToString() return string.Format("{0} AddonList", base.ToString()); } } -} +} \ No newline at end of file From 6b6cac16da1668351f534315d242749a93d89555 Mon Sep 17 00:00:00 2001 From: Chris Woerz Date: Thu, 12 Mar 2015 11:38:51 -0600 Subject: [PATCH 297/446] removed vessel --- src/kOS/AddOns/KerbalAlarmClock/KACAlarmWrapper.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/kOS/AddOns/KerbalAlarmClock/KACAlarmWrapper.cs b/src/kOS/AddOns/KerbalAlarmClock/KACAlarmWrapper.cs index 322180134..5645a0da7 100644 --- a/src/kOS/AddOns/KerbalAlarmClock/KACAlarmWrapper.cs +++ b/src/kOS/AddOns/KerbalAlarmClock/KACAlarmWrapper.cs @@ -31,9 +31,6 @@ private void InitializeSuffixes() AddSuffix("ID", new Suffix(() => alarm.ID)); AddSuffix("NAME", new SetSuffix(() => alarm.Name, value => alarm.Name = value)); - //AddSuffix("VESSELID", new SetSuffix(() => alarm.VesselID, value => alarm.VesselID = value)); - AddSuffix("VESSEL", new SetSuffix(() => GetVesselByID(alarm.VesselID), SetVesselID)); - AddSuffix("NOTES", new SetSuffix(() => alarm.Name, value => alarm.Name = value)); AddSuffix("ACTION", new SetSuffix(alarm.AlarmAction.ToString, SetAlarmAction)); From 3b4a635188288f5ad8225dbedf6bfbeb4b28bbd5 Mon Sep 17 00:00:00 2001 From: Stepan Andreev Date: Thu, 12 Mar 2015 17:54:44 +0000 Subject: [PATCH 298/446] Update KAC.rst --- doc/source/addons/KAC.rst | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/doc/source/addons/KAC.rst b/doc/source/addons/KAC.rst index 8ea618ff4..ad718efb5 100644 --- a/doc/source/addons/KAC.rst +++ b/doc/source/addons/KAC.rst @@ -26,7 +26,6 @@ Creator of the KAC provides API for integration with other mods. In KOS we provi :attr:`REMAINING` scalar (s) Time remaining until alarm is triggered :attr:`REPEAT` bool Should the alarm be repeated once it fires :attr:`REPEATPERIOD` scalar (s) How long after the alarm fires should the next alarm be set up - :attr:`VESSEL` :struct: `Vessel` Vessel structure of that the alarm is attached to, use this to set VESSELID :attr:`ORIGINBODY` string Name of the body the vessel is departing from :attr:`TARGETBODY` string Name of the body the vessel is arriving at ===================================== ========================= ============= @@ -116,14 +115,6 @@ Creator of the KAC provides API for integration with other mods. In KOS we provi How long after the alarm fires should the next alarm be set up. -.. attribute:: KACAlarm:VESSEL - - :type: :struct: `Vessel` - :access: Get/Set - - :ref:`Vessel ` structure of that the alarm is attached to, use this to set VESSELID, instead of setting it directly, unless you want to unattach the Alarm from any Vessel. - - .. attribute:: KACAlarm:ORIGINBODY :type: string @@ -162,14 +153,14 @@ Available Functions .. function:: LISTALARMS(alarmType) - If `alarmType` equals "All", returns :struct:`List` of *all* :struct:`KACAlarm` objects, otherwise returns :struct:`List` of all :struct:`KACAlarm` objects with `KACAlarm:ALARMTYPE` equeal to `alarmType':: + If `alarmType` equals "All", returns :struct:`List` of *all* :struct:`KACAlarm` objects attached to current vessel or have no vessel attached. + Otherwise returns :struct:`List` of all :struct:`KACAlarm` objects with `KACAlarm:ALARMTYPE` equeal to `alarmType' and attached to current vessel or have no vessel attached.:: set al to listAlarms("All"). - - for i in al - { - print i:ID + " - " + i:name. - } + for i in al + { + print i:ID + " - " + i:name. + } .. function:: DELETEALARM(alarmID) From a7ea7e03db5d74dd6485bcce477f404723bb47aa Mon Sep 17 00:00:00 2001 From: Stepan Andreev Date: Thu, 12 Mar 2015 17:55:41 +0000 Subject: [PATCH 299/446] Update KAC.rst --- doc/source/addons/KAC.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/addons/KAC.rst b/doc/source/addons/KAC.rst index ad718efb5..fb44c3746 100644 --- a/doc/source/addons/KAC.rst +++ b/doc/source/addons/KAC.rst @@ -154,7 +154,7 @@ Available Functions .. function:: LISTALARMS(alarmType) If `alarmType` equals "All", returns :struct:`List` of *all* :struct:`KACAlarm` objects attached to current vessel or have no vessel attached. - Otherwise returns :struct:`List` of all :struct:`KACAlarm` objects with `KACAlarm:ALARMTYPE` equeal to `alarmType' and attached to current vessel or have no vessel attached.:: + Otherwise returns :struct:`List` of all :struct:`KACAlarm` objects with `KACAlarm:TYPE` equeal to `alarmType' and attached to current vessel or have no vessel attached.:: set al to listAlarms("All"). for i in al From f7dc3daaf9d9c29a768f46e29419148553e373c1 Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Fri, 13 Mar 2015 20:45:33 -0500 Subject: [PATCH 300/446] temp commit before switching to testing erendrakes' PR --- doc/source/language/syntax.rst | 53 +++++++++++++++++++++++++++++++ doc/source/language/variables.rst | 10 ------ 2 files changed, 53 insertions(+), 10 deletions(-) diff --git a/doc/source/language/syntax.rst b/doc/source/language/syntax.rst index 09cde4f56..8821d0f32 100644 --- a/doc/source/language/syntax.rst +++ b/doc/source/language/syntax.rst @@ -71,6 +71,59 @@ Suffixes can be chained together, as in this example:: In the above example you'd say "``velocity`` is a suffix of ``ship``", and "``orbit`` is a suffix of ``ship:velocity``", and "``x`` is a suffix of ``ship:velocity:orbit``". +Braces (statement blocks) +------------------------- + +Anywhere you feel like, you may insert braces around a list of statements +to get the language to treat them all as a single statement block. + +For example: the IF statement expects one statement as its body, like so:: + + if x = 1 + print "it's 1". + +But you can put multiple statements there as its body by surrounding them +with braces, like so:: + + if x = 1 { print "it's 1". print "yippieee.". } + +(Although this is usually preferred to be indented as follows):: + + if x = 1 { + print "it's 1". + print "yippieee.". + } + +or:: + + if x = 1 + { + print "it's 1". + print "yippieee.". + } + +Kerboscript does not require proper indentation of the brace sections, +but it is a good idea to make things clear. + +You are allowed to just insert braces anywhere you feel like even when the +language does not require it, as shown below:: + + declare x to 3. + print "x here is " + x. + { + declare x to 5. + print "x here is " + x. + { + declare x to 7. + print "x here is " + x. + } + } + +The usual reason for doing this is to create a +:ref:`local scope section ` for yourself. +In the above example, there are actually 3 *different* +variables called 'x' - each with a different scope. + Functions (built-in) -------------------- diff --git a/doc/source/language/variables.rst b/doc/source/language/variables.rst index 2e1275923..fd505bea6 100644 --- a/doc/source/language/variables.rst +++ b/doc/source/language/variables.rst @@ -60,16 +60,6 @@ Kerboscript now requires the use of the initializer clause (the "TO" keyword) after the identifer name so as to make it impossible for there to exist any uninitialized variables in a script. -.. _declare glboal: - -``DECLARE GLOBAL`` ------------------- - -TODO: need to document this after it's made - basiclly makes -globals just like SET implicitly does, but does so explicitly so -it can still be done when in NOLAZYGLOBAL section. - - .. _declare parameter: ``DECLARE PARAMETER`` From e452b1c8f6db91b9da22595679e375a9cd5890d5 Mon Sep 17 00:00:00 2001 From: Chris Woerz Date: Fri, 13 Mar 2015 22:06:18 -0600 Subject: [PATCH 301/446] renamed updates to make their usage clearer --- src/kOS.Safe/IUpdateObserver.cs | 7 ++++++- src/kOS.Safe/UpdateHandler.cs | 12 ++++++------ src/kOS/AddOns/RemoteTech/RemoteTechInterpreter.cs | 2 +- src/kOS/Execution/CPU.cs | 2 +- src/kOS/Execution/TransferManager.cs | 6 ++++-- src/kOS/Function/HighlightStructure.cs | 2 +- src/kOS/Suffixed/VectorRenderer.cs | 2 +- 7 files changed, 20 insertions(+), 13 deletions(-) diff --git a/src/kOS.Safe/IUpdateObserver.cs b/src/kOS.Safe/IUpdateObserver.cs index 62da4e32f..0fe2065a1 100644 --- a/src/kOS.Safe/IUpdateObserver.cs +++ b/src/kOS.Safe/IUpdateObserver.cs @@ -4,6 +4,11 @@ namespace kOS.Safe { public interface IUpdateObserver : IDisposable { - void Update(double deltaTime); + void KOSUpdate(double deltaTime); + } + + public interface IFixedUpdateObserver : IDisposable + { + void KOSFixedUpdate(double deltaTime); } } \ No newline at end of file diff --git a/src/kOS.Safe/UpdateHandler.cs b/src/kOS.Safe/UpdateHandler.cs index 60f925557..677fcaa2c 100644 --- a/src/kOS.Safe/UpdateHandler.cs +++ b/src/kOS.Safe/UpdateHandler.cs @@ -9,7 +9,7 @@ public class UpdateHandler // once and therefore only gets its Update() called once per update. // The value of the KeyValuePair, the int, is unused. private readonly HashSet observers = new HashSet(); - private readonly HashSet fixedObservers = new HashSet(); + private readonly HashSet fixedObservers = new HashSet(); public double CurrentFixedTime { get; private set; } public double LastDeltaFixedTime { get; private set; } @@ -21,7 +21,7 @@ public void AddObserver(IUpdateObserver observer) observers.Add(observer); } - public void AddFixedObserver(IUpdateObserver observer) + public void AddFixedObserver(IFixedUpdateObserver observer) { fixedObservers.Add(observer); } @@ -31,7 +31,7 @@ public void RemoveObserver(IUpdateObserver observer) observers.Remove(observer); } - public void RemoveFixedObserver(IUpdateObserver observer) + public void RemoveFixedObserver(IFixedUpdateObserver observer) { fixedObservers.Remove(observer); } @@ -44,7 +44,7 @@ public void UpdateObservers(double deltaTime) var snapshot = new HashSet(observers); foreach (var observer in snapshot) { - observer.Update(deltaTime); + observer.KOSUpdate(deltaTime); } } @@ -53,10 +53,10 @@ public void UpdateFixedObservers(double deltaTime) LastDeltaFixedTime = deltaTime; CurrentFixedTime += deltaTime; - var snapshot = new HashSet(fixedObservers); + var snapshot = new HashSet(fixedObservers); foreach (var observer in snapshot) { - observer.Update(deltaTime); + observer.KOSFixedUpdate(deltaTime); } } } diff --git a/src/kOS/AddOns/RemoteTech/RemoteTechInterpreter.cs b/src/kOS/AddOns/RemoteTech/RemoteTechInterpreter.cs index be38f1c65..b852527c2 100644 --- a/src/kOS/AddOns/RemoteTech/RemoteTechInterpreter.cs +++ b/src/kOS/AddOns/RemoteTech/RemoteTechInterpreter.cs @@ -93,7 +93,7 @@ private void StopDeployment() waitElapsed = 0; } - public void Update(double deltaTime) + public void KOSUpdate(double deltaTime) { if (!deploymentInProgress && commandQueue.Count > 0 && !BatchMode) { diff --git a/src/kOS/Execution/CPU.cs b/src/kOS/Execution/CPU.cs index d14490037..4bff2266b 100644 --- a/src/kOS/Execution/CPU.cs +++ b/src/kOS/Execution/CPU.cs @@ -539,7 +539,7 @@ public void EndWait() currentStatus = Status.Running; } - public void Update(double deltaTime) + public void KOSUpdate(double deltaTime) { bool showStatistics = Config.Instance.ShowStatistics; Stopwatch updateWatch = null; diff --git a/src/kOS/Execution/TransferManager.cs b/src/kOS/Execution/TransferManager.cs index 772715529..bec27dd6d 100644 --- a/src/kOS/Execution/TransferManager.cs +++ b/src/kOS/Execution/TransferManager.cs @@ -6,7 +6,7 @@ namespace kOS.Execution { - public class TransferManager : IUpdateObserver + public class TransferManager : IFixedUpdateObserver { public enum TransferStatus { @@ -52,8 +52,10 @@ public static PartResourceDefinition ParseResource(string resourceName) return resourceInfo; } - public void Update(double deltaTime) + public void KOSFixedUpdate(double deltaTime) { + if (!transfers.Any()) return; + foreach (var transfer in transfers) { transfer.Update(deltaTime); diff --git a/src/kOS/Function/HighlightStructure.cs b/src/kOS/Function/HighlightStructure.cs index bbe288f31..b731bbc94 100644 --- a/src/kOS/Function/HighlightStructure.cs +++ b/src/kOS/Function/HighlightStructure.cs @@ -66,7 +66,7 @@ private void DetermineType() } } - public void Update(double deltaTime) + public void KOSUpdate(double deltaTime) { if (!stale) return; diff --git a/src/kOS/Suffixed/VectorRenderer.cs b/src/kOS/Suffixed/VectorRenderer.cs index 52bcb79f5..6a955485b 100644 --- a/src/kOS/Suffixed/VectorRenderer.cs +++ b/src/kOS/Suffixed/VectorRenderer.cs @@ -80,7 +80,7 @@ public void ScopeLost() /// and move to wherever that ship is within its local XYZ world (which /// isn't always at (0,0,0), as it turns out.): /// - public void Update( double deltaTime ) + public void KOSUpdate( double deltaTime ) { if (line == null || hat == null) return; if (!enable) return; From 9f9ec9116a5bd635769551c7e1dcda82c984d58e Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Sat, 14 Mar 2015 00:36:47 -0500 Subject: [PATCH 302/446] Throwing back to @erendrake to fix parts list case not working. --- doc/source/commands/resource_transfer.rst | 50 +++++++--------- .../structures/misc/resource_transfer.rst | 58 +++++++++---------- .../Exceptions/KOSInvalidArgumentException.cs | 2 +- src/kOS/Suffixed/ResourceTransferValue.cs | 57 ++++++++---------- 4 files changed, 75 insertions(+), 92 deletions(-) diff --git a/doc/source/commands/resource_transfer.rst b/doc/source/commands/resource_transfer.rst index dfe897d6d..e846b0ef3 100644 --- a/doc/source/commands/resource_transfer.rst +++ b/doc/source/commands/resource_transfer.rst @@ -10,9 +10,9 @@ To accomplish all of this we have two new functions :: - SET transferFoo TO TRANSFER(resourceName, fromParts, toParts, amount). - SET transferBar TO TRANSFERALL(resourceName, fromParts, toParts). - + SET transferFoo TO TRANSFER(resourceName, fromParts, toParts, amount). + SET transferBar TO TRANSFERALL(resourceName, fromParts, toParts). + TRANSFER will move the specified amount of a resource, where TRANSFERALL will move the resource until the source is empty or the destination is full. Both functions return a new :struct:`ResourceTransfer`. @@ -21,13 +21,13 @@ Resource -------- in all transfers, you must specify a resource by name -(eg "oxidizer", "LIQUIDFUEL", ect). this term is not case sensitive. - +(eg "oxidizer", "LIQUIDFUEL", etc). this term is not case sensitive. + Source and Destination ---------------------- -in all transfers, you must specify a source and a destination, both of these need -to be one of three types. +In all transfers, you must specify a source and a destination, both of these need +to be one of these three types: * :struct:`Part` * :struct:`List` of :struct:`Part` @@ -37,28 +37,22 @@ Examples -------- Building a list of :struct:`Element`, then transferring all of the oxidizer from -one element to another. - -:: - - LIST ELEMENTS IN elist. - SET foo TO TRANSFERALL("OXIDIZER", elist[0], elist[1]). - SET foo:ACTIVE to TRUE. - +one element to another: :: + + LIST ELEMENTS IN elist. + SET foo TO TRANSFERALL("OXIDIZER", elist[0], elist[1]). + SET foo:ACTIVE to TRUE. + Finding two parts by index, then transferring all of the oxidizer from -part 1 to part 2. - -:: - - SET foo TO TRANSFERALL("OXIDIZER", SHIP:PARTS[0], SHIP:PARTS[1]). - SET foo:ACTIVE to TRUE. - -Finding two lists of parts by tag, then transferring 100 units of liquidfuel. +part 1 to part 2: :: -:: + SET foo TO TRANSFERALL("OXIDIZER", SHIP:PARTS[0], SHIP:PARTS[1]). + SET foo:ACTIVE to TRUE. + +Finding two lists of parts by tag, then transferring 100 units of liquidfuel: :: - SET sourceParts to SHIP:PARTSDUBBED("fooPart"). - SET destinationParts to SHIP:PARTSDUBBED("barPart"). - SET foo TO TRANSFER("liquidfuel", sourceParts, destinationParts, 100). - SET foo:ACTIVE to TRUE. \ No newline at end of file + SET sourceParts to SHIP:PARTSDUBBED("fooPart"). + SET destinationParts to SHIP:PARTSDUBBED("barPart"). + SET foo TO TRANSFER("liquidfuel", sourceParts, destinationParts, 100). + SET foo:ACTIVE to TRUE. diff --git a/doc/source/structures/misc/resource_transfer.rst b/doc/source/structures/misc/resource_transfer.rst index 67f2645e1..94de1f3b0 100644 --- a/doc/source/structures/misc/resource_transfer.rst +++ b/doc/source/structures/misc/resource_transfer.rst @@ -22,7 +22,7 @@ Structure * - :attr:`STATUS` - string - Get only - - The text status of the transfer (eg Inactive, Transferring, Failed) + - The string status of the transfer (eg "Inactive", "Transferring", "Failed") * - :attr:`MESSAGE` - string - Get only @@ -30,71 +30,71 @@ Structure * - :attr:`GOAL` - scalar - Get only - - this is how much of the resource will be transferred. - * - :attr:`TRANSFERED` + - This is how much of the resource will be transferred. + * - :attr:`TRANSFERRED` - scalar - Get only - - this is how much of the resource has been transferred. - * - :attr:`RESOURCE` + - This is how much of the resource has been transferred. + * - :attr:`RESOURCE` - string - Get only - The name of the resource (eg oxidizer, liquidfuel) - * - :attr:`ACTIVE` + * - :attr:`ACTIVE` - bool - - Get \ Set + - Get / Set - Setting this value will either start, pause or restart a transfer. Default is false. - - + + .. attribute:: RESOURCETRANSFER:STATUS :access: Get only :type: string - This enumerated type shows the status of the transfer. the possible values are: - - * Inactive (default) - - Transfer is stopped - * Finished - - Transfer has reached its goal - * Failed - - There was an error in the transfer, see :attr:`MESSAGE` for details - * Transferring - - The transfer is in progress. - + This enumerated type shows the status of the transfer. the possible values are: + + * Inactive (default) + - Transfer is stopped + * Finished + - Transfer has reached its goal + * Failed + - There was an error in the transfer, see :attr:`MESSAGE` for details + * Transferring + - The transfer is in progress. + .. attribute:: RESOURCETRANSFER:MESSAGE :access: Get only :type: string - This shows the detail related to :attr:`STATUS` - + This shows the detail related to :attr:`STATUS` + .. attribute:: RESOURCETRANSFER:GOAL :access: Get only :type: scalar - + If you specified an amount to transfer in your transfer request, it will be shown here. - If you did not, this will return the sentinel value -1. + If you did not, this will return the sentinel value -1. -.. attribute:: RESOURCETRANSFER:TRANSFERED +.. attribute:: RESOURCETRANSFER:TRANSFERRED :access: Get only :type: scalar Returns the amount of the specified resource that has been transferred by this resource transfer. - + .. attribute:: RESOURCETRANSFER:RESOURCE :access: Get only :type: string The name of the resource that will be transferred. (eg, oxidizer, liquidfuel) - + .. attribute:: RESOURCETRANSFER:ACTIVE :access: Get / Set :type: bool When getting, this suffix is simply a shortcut to tell you if :attr:`STATUS` is Transferring. - Setting true will change the status of the transfer to Transferring, setting false will change status to inactive. - \ No newline at end of file + Setting true will change the status of the transfer to Transferring, setting false will change status to inactive. + diff --git a/src/kOS.Safe/Exceptions/KOSInvalidArgumentException.cs b/src/kOS.Safe/Exceptions/KOSInvalidArgumentException.cs index f8d3e217d..d959fbc1c 100644 --- a/src/kOS.Safe/Exceptions/KOSInvalidArgumentException.cs +++ b/src/kOS.Safe/Exceptions/KOSInvalidArgumentException.cs @@ -8,4 +8,4 @@ public KOSInvalidArgumentException(string functionName, string argumentName, str { } } -} \ No newline at end of file +} diff --git a/src/kOS/Suffixed/ResourceTransferValue.cs b/src/kOS/Suffixed/ResourceTransferValue.cs index c33164733..82fa40094 100644 --- a/src/kOS/Suffixed/ResourceTransferValue.cs +++ b/src/kOS/Suffixed/ResourceTransferValue.cs @@ -21,7 +21,7 @@ private enum TransferPartType } private readonly double? amount; - private double transferedAmount; + private double transferredAmount; private readonly TransferManager transferManager; private readonly PartResourceDefinition resourceInfo; private readonly object transferTo; @@ -39,6 +39,7 @@ private set { status = value; transferManager.ReregisterTransfer(this); + SafeHouse.Logger.Log(StatusChangeMessage()); } } @@ -53,10 +54,11 @@ public ResourceTransferValue(TransferManager transferManager, PartResourceDefini this.resourceInfo = resourceInfo; this.transferTo = transferTo; this.transferFrom = transferFrom; - Status = TransferManager.TransferStatus.Inactive; DetermineTypes(); InitializeSuffixes(); + + Status = TransferManager.TransferStatus.Inactive; // Last because the setter for Status prints some of the values calculated above to the log } public void Update(double deltaTime) @@ -64,12 +66,9 @@ public void Update(double deltaTime) if (Status != TransferManager.TransferStatus.Transferring) { return; } IList fromParts = GetParts(transferFromType, transferFrom); - SafeHouse.Logger.Log("TRANSFER: FromParts Count: " + fromParts.Count); IList toParts = GetParts(transferFromType, transferTo); - SafeHouse.Logger.Log("TRANSFER: ToParts Count: " + toParts.Count); if (!AllPartsAreConnected(fromParts, toParts)) { return; } - SafeHouse.Logger.Log("TRANSFER: All Parts Connected"); if (!CanTransfer(fromParts, toParts)) { @@ -80,13 +79,16 @@ public void Update(double deltaTime) public override string ToString() { - return string.Format("Transfer( {0}, {1} )", Status, StatusMessage); + return string.Format("{0}(\"{1}\", {2}, {3}{4})", + amount.HasValue ? "TRANSFER" : "TRANSFERALL", + resourceInfo.name, transferFromType, transferToType, + amount.HasValue ? (", " + amount) : "" ); } private void InitializeSuffixes() { AddSuffix("GOAL", new Suffix(() => amount.HasValue ? amount.Value : -1)); - AddSuffix("TRANSFERED", new Suffix(() => transferedAmount)); + AddSuffix("TRANSFERRED", new Suffix(() => transferredAmount)); AddSuffix("STATUS", new Suffix(() => Status.ToString())); AddSuffix("MESSAGE", new Suffix(() => StatusMessage)); AddSuffix("RESOURCE", new Suffix(() => resourceInfo.name)); @@ -95,13 +97,16 @@ private void InitializeSuffixes() Status = value ? TransferManager.TransferStatus.Transferring : TransferManager.TransferStatus.Inactive; })); } + + private string StatusChangeMessage() + { + return string.Format("{0} is now {1}.", ToString(), Status); + } private void DetermineTypes() { transferToType = DetermineType(transferTo); - SafeHouse.Logger.Log("TRANSFER: To Type: " + transferToType); transferFromType = DetermineType(transferFrom); - SafeHouse.Logger.Log("TRANSFER: From Type: " + transferFromType); } private TransferPartType DetermineType(object toTest) @@ -123,21 +128,18 @@ private TransferPartType DetermineType(object toTest) private void WorkTransfer(IList fromParts, IList toParts) { - SafeHouse.Logger.Log("TRANSFER WORK: Have already transfered: " + transferedAmount); - var transferGoal = CalculateTransferGoal(toParts); double pulledAmount = PullResources(fromParts, transferGoal); PutResources(toParts, pulledAmount); - transferedAmount += pulledAmount; + transferredAmount += pulledAmount; if (Status == TransferManager.TransferStatus.Transferring) { - StatusMessage = string.Format("Transfered: {0}", transferedAmount); + StatusMessage = string.Format("Transferred: {0}", transferredAmount); } - SafeHouse.Logger.Log("TRANSFER WORK: Have now transfered: " + transferedAmount); } /// @@ -165,11 +167,7 @@ private void PutResources(IList parts, double pulledAmount) var transferAmount = Math.Min(remaining, evenShare); - SafeHouse.Logger.Log(string.Format("TRANSFER WORK: {0} PUT AMOUNT: {1}", part.flightID, transferAmount)); - remaining += part.TransferResource(resource.info.id, transferAmount); - - SafeHouse.Logger.Log(string.Format("TRANSFER WORK: {0} PUT REMAINING: {1}", part.flightID, remaining)); } retries++; } @@ -201,13 +199,8 @@ private double PullResources(IList parts, double transferGoal) // the amount is subject to floating point lameness, if we round it here it is not material to the request but should make the numbers work out nicer. thisPartsShare = Math.Round(thisPartsShare, 5); - SafeHouse.Logger.Log(string.Format("TRANSFER WORK: {0} PULL AMOUNT: {1}", part.flightID, thisPartsShare)); - toReturn += part.TransferResource(resourceInfo.id, thisPartsShare); - - SafeHouse.Logger.Log(string.Format("TRANSFER WORK: {0} PULLED RESOURCE: {1}", part.flightID, toReturn)); } - SafeHouse.Logger.Log("TRANSFER WORK: Pulled: " + toReturn); return toReturn; } @@ -217,14 +210,14 @@ private double CalculateTransferGoal(IEnumerable toParts) var destinationAvailableCapacity = CalculateAvailableSpace(toParts); - if (!amount.HasValue) + if (amount.HasValue) { - toReturn = destinationAvailableCapacity; + var rawGoal = amount.Value - transferredAmount; + toReturn = Math.Min(destinationAvailableCapacity, rawGoal); } else { - var rawGoal = amount.Value - transferedAmount; - toReturn = Math.Min(destinationAvailableCapacity, rawGoal); + toReturn = destinationAvailableCapacity; } return toReturn; @@ -242,7 +235,7 @@ private bool CanTransfer(IEnumerable fromParts, IEnumerable toParts) private void MarkFailed(string message) { - SafeHouse.Logger.Log("TRANSFER FAILED: " + message); StatusMessage = message; Status = TransferManager.TransferStatus.Failed; } private void MarkFinished() { - transferedAmount = Math.Round(transferedAmount, 5); - SafeHouse.Logger.Log(string.Format("TRANSFER FINISHED: Transfered {0} {1}", transferedAmount, resourceInfo.name)); - StatusMessage = string.Format("Transfered: {0}", transferedAmount); + transferredAmount = Math.Round(transferredAmount, 5); + StatusMessage = string.Format("Transferred: {0}", transferredAmount); Status = TransferManager.TransferStatus.Finished; } @@ -310,7 +301,6 @@ private double CalculateAvailableSpace(IEnumerable parts) { var resources = parts.SelectMany(p => p.Resources.GetAll(resourceInfo.id)); var toReturn = resources.Sum(r => r.maxAmount - r.amount); - SafeHouse.Logger.Log("TRANSFER: Available Space: " + toReturn); return toReturn; } @@ -318,7 +308,6 @@ private double CalculateAvailableResource(IEnumerable fromParts) { var resources = fromParts.SelectMany(p => p.Resources.GetAll(resourceInfo.id)); var toReturn = resources.Sum(r => r.amount); - SafeHouse.Logger.Log("TRANSFER: Available Resource: " + toReturn); return toReturn; } From 210d22bacc2f899b2947dc27e92c22a71d6e634a Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Wed, 18 Mar 2015 05:24:07 -0500 Subject: [PATCH 303/446] DECLARE PARAMETER working, with recursion. Still no lexical scope checking. That's next. --- src/kOS.Safe/Compilation/CompilerOptions.cs | 9 +- src/kOS.Safe/Compilation/KS/BreakInfo.cs | 4 +- src/kOS.Safe/Compilation/KS/Compiler.cs | 342 ++++++++++++++++-- src/kOS.Safe/Compilation/KS/Lock.cs | 31 +- src/kOS.Safe/Compilation/KS/ParseTree.cs | 10 + src/kOS.Safe/Compilation/KS/Parser.cs | 102 +++++- src/kOS.Safe/Compilation/KS/Scanner.cs | 219 +++++------ src/kOS.Safe/Compilation/KS/kRISC.tpg | 6 +- src/kOS.Safe/Compilation/Opcode.cs | 76 +++- .../KOSArgumentMismatchException.cs | 16 + .../KOSReturnInvalidHereException.cs | 26 ++ src/kOS.Safe/Function/IFunctionManager.cs | 1 + src/kOS.Safe/kOS.Safe.csproj | 1 + src/kOS/Execution/CPU.cs | 6 + src/kOS/Function/FunctionManager.cs | 11 + src/kOS/Function/Misc.cs | 6 +- src/kOS/Screen/Interpreter.cs | 3 +- 17 files changed, 701 insertions(+), 168 deletions(-) create mode 100644 src/kOS.Safe/Exceptions/KOSReturnInvalidHereException.cs diff --git a/src/kOS.Safe/Compilation/CompilerOptions.cs b/src/kOS.Safe/Compilation/CompilerOptions.cs index 01ef1cdba..cd7b59d94 100644 --- a/src/kOS.Safe/Compilation/CompilerOptions.cs +++ b/src/kOS.Safe/Compilation/CompilerOptions.cs @@ -1,9 +1,10 @@ +using kOS.Safe.Function; namespace kOS.Safe.Compilation { public class CompilerOptions { public bool LoadProgramsInSameAddressSpace { get; set; } - + public IFunctionManager FuncManager { get; set; } public CompilerOptions() { LoadDefaults(); @@ -12,6 +13,12 @@ public CompilerOptions() private void LoadDefaults() { LoadProgramsInSameAddressSpace = false; + FuncManager = null; + } + + public bool BuiltInExists(string identifier) + { + return (FuncManager == null ) ? false : FuncManager.Exists(identifier); } } } diff --git a/src/kOS.Safe/Compilation/KS/BreakInfo.cs b/src/kOS.Safe/Compilation/KS/BreakInfo.cs index ba3bd161e..8ff51bffb 100644 --- a/src/kOS.Safe/Compilation/KS/BreakInfo.cs +++ b/src/kOS.Safe/Compilation/KS/BreakInfo.cs @@ -19,7 +19,7 @@ public class BreakInfo /// What is the nesting level that should be broken back to. /// public Int16 NestLevel {get; private set;} // 32767 max recursion supported? Seems fine. - + /// /// Which opcodes are in need of adjusting. /// There are two kinds of adjustment: @@ -33,11 +33,13 @@ public class BreakInfo /// /// Make a new break info block, with empty opcode list, given the current brace nest level. /// + /// Whether this is in the context of being a loop or being a function body. /// current brace nest level when the break info was set up public BreakInfo(int nest) { NestLevel = (Int16)nest; Opcodes = new List(); } + } } diff --git a/src/kOS.Safe/Compilation/KS/Compiler.cs b/src/kOS.Safe/Compilation/KS/Compiler.cs index d45bcd6de..d10d91c52 100644 --- a/src/kOS.Safe/Compilation/KS/Compiler.cs +++ b/src/kOS.Safe/Compilation/KS/Compiler.cs @@ -3,6 +3,7 @@ using System.Linq; using kOS.Safe.Exceptions; using kOS.Safe.Utilities; +using kOS.Safe.Function; namespace kOS.Safe.Compilation.KS { @@ -17,12 +18,14 @@ class Compiler private short lastLine; private short lastColumn; private readonly List breakList = new List(); + private readonly List returnList = new List(); private readonly List triggerRemoveNames = new List(); private bool nowCompilingTrigger; private bool compilingSetDestination; private bool identifierIsVariable; private bool identifierIsSuffix; private bool nowInALoop; + private bool needImplicitReturn; private int braceNestLevel; private readonly List programParameters = new List(); private CompilerOptions options; @@ -49,11 +52,13 @@ private void InitCompileFlags() lastLine = 0; lastColumn = 0; breakList.Clear(); + returnList.Clear(); triggerRemoveNames.Clear(); nowCompilingTrigger = false; compilingSetDestination = false; identifierIsSuffix = false; nowInALoop = false; + needImplicitReturn = true; braceNestLevel = 0; programParameters.Clear(); } @@ -95,7 +100,7 @@ private void CompileProgram(ParseTree tree) { currentCodeSection = part.MainCode; - PushProgramParameters(); + PushReversedParameters(); VisitNode(tree.Nodes[0]); if (addBranchDestination) @@ -172,7 +177,10 @@ private void IterateLocks(ParseNode node, Action action) { switch (node.Token.Type) { - // statements that can have a lock inside + // Statements that can have other statements nested inside them need to be + // recursed through to search for instances of the special statements + // we are looking for here: + // case TokenType.Start: case TokenType.instruction_block: case TokenType.instruction: @@ -183,7 +191,11 @@ private void IterateLocks(ParseNode node, Action action) foreach (ParseNode childNode in node.Nodes) IterateLocks(childNode, action); break; + + // These are the statements we're searching for to work on here: + // case TokenType.lock_stmt: + case TokenType.declare_stmt: // for DECLARE FUNCTION's action.Invoke(node); break; } @@ -345,18 +357,86 @@ private string ConcatenateNodes(ParseNode node) private void IdentifyLocks(ParseNode node) { - string lockIdentifier = node.Nodes[1].Token.Text; + if (node.Nodes.Count <= 0 ) + return; + + string lockIdentifier; + if (IsLockStatement(node)) + lockIdentifier = node.Nodes[1].Token.Text; + else if (IsDefineFunctionStatement(node)) + lockIdentifier = node.Nodes[2].Token.Text; + else + return; // not one of the types of statement we're really meant to run IdentifyLocks on. + context.Locks.GetLock(lockIdentifier); } - + + private bool IsLockStatement(ParseNode node) + { + return node.Nodes[0].Token.Type == TokenType.LOCK; + } + + private bool IsDefineFunctionStatement(ParseNode node) + { + return + node.Nodes[0].Token.Type == TokenType.DECLARE && + ( (node.Nodes.Count > 1) && node.Nodes[1].Token.Type == TokenType.FUNCTION ) && + ( (node.Nodes.Count > 2) && node.Nodes[2].Token.Type == TokenType.IDENTIFIER ); + } + + private bool IsInsideDefineFunctionStatement(ParseNode node) + { + while (node != null) + { + if (IsDefineFunctionStatement(node)) + return true; + node = node.Parent; + } + return false; + } + private void PreProcessLockStatement(ParseNode node) { NodeStartHousekeeping(node); - string lockIdentifier = node.Nodes[1].Token.Text; + + // The name of the lock or function to be executed: + string lockIdentifier; + // The syntax node for the body of the lock or function: the stuff it actually executes. + ParseNode bodyNode; + + bool isLock = IsLockStatement(node); + bool isDefFunc = IsDefineFunctionStatement(node); + if (isLock) + { + lockIdentifier = node.Nodes[1].Token.Text; // The IDENT of: LOCK IDENT TO EXPR. + bodyNode = node.Nodes[3]; // The EXPR of: LOCK IDENT TO EXPR. + } + else if (isDefFunc) + { + lockIdentifier = node.Nodes[2].Token.Text; // The IDENT of: DEFINE FUNCTION IDENT INSTRUCTION_BLOCK. + bodyNode = node.Nodes[3]; // The INSTRUCTION_BLOCK of: DEFINE FUNCTION IDENT INSTRUCTION_BLOCK. + } + else + return; // In principle this shouldn't have ever been called in this case. + Lock lockObject = context.Locks.GetLock(lockIdentifier); int expressionHash = ConcatenateNodes(node.Nodes[3]).GetHashCode(); - if (!lockObject.IsInitialized()) + needImplicitReturn = true; // Locks always need an implicit return. Functions might not if all paths have an explicit one. + + // Both locks and functions also get an identifier storing their + // destination instruction pointer, but the means of doing so + // is slightly different. Locks always need a dummy do-nothing + // function to exist at first, which then can get replaced later + // when the statement containing the lock definition is encountered. + // Whereas, function bodies don't get overwritten like that. They + // exist exactly once, and can be "forward" called from higher up in + // the same scope so they get assigned when the scope is first opened. + // + // TODO ? ? : Do we want to have local locks? It could be done by having them + // define the lock... but.... could mess things up for system locks. For + // now, we're defining that all locks are global? + if (isLock && !lockObject.IsInitialized()) { // initialization code currentCodeSection = lockObject.InitializationCode; @@ -380,23 +460,51 @@ private void PreProcessLockStatement(ParseNode node) lastLine = rememberLastLine; } - // default function + // build default dummy function to be used when this is a LOCK: currentCodeSection = lockObject.GetLockFunction(0); AddOpcode(new OpcodePush("$" + lockObject.Identifier)).Label = lockObject.DefaultLabel; AddOpcode(new OpcodeReturn()); } - // function code + // lock expression's or function body's code currentCodeSection = lockObject.GetLockFunction(expressionHash); - VisitNode(node.Nodes[3]); - AddOpcode(new OpcodeReturn()); + if (isDefFunc) + PushReturnList(); + VisitNode(bodyNode); + if (isDefFunc) + PopReturnList(); + if (needImplicitReturn) + { + if (isDefFunc) + AddOpcode(new OpcodePush(0)); // Functions must push a dummy return val when making implicit returns. Locks already leave an expr atop the stack. + AddOpcode(new OpcodeReturn()); + } + if (isDefFunc) + { + lockObject.ScopeNode = GetContainingBlockNode(node); // This limits the scope of the function to the instruction_block the DEFINE was in. + lockObject.IsFunction = true; + } + } + + /// + /// Get the instruction_block this node is immediately inside of. + /// Gives a null if the node isn't in one (it's global). + /// + private ParseNode GetContainingBlockNode(ParseNode node) + { + while (node != null && node.Token.Type != TokenType.instruction_block) + node = node.Parent; + return node; } private void PreProcessProgramParameters(ParseNode node) { NodeStartHousekeeping(node); - // if the declaration is a parameter - if (node.Nodes[1].Token.Type == TokenType.PARAMETER) + // if the declaration is a parameter, + // and this is NOT contained inside a DEFINE FUNCTION block and + // is therefore a global program paramter (for the run statement): + if (node.Nodes[1].Token.Type == TokenType.PARAMETER && + (!(IsInsideDefineFunctionStatement(node)))) { for (int index = 2; index < node.Nodes.Count; index += 2) { @@ -453,7 +561,7 @@ private void PreProcessRunStatement(ParseNode node) } } - private void PushProgramParameters() + private void PushReversedParameters() { // reverse the order of parameters so the stack // is popped in the correct order @@ -502,7 +610,7 @@ private void AddToBreakList(Opcode opcode) list.Opcodes.Add(opcode); } } - + private void PopBreakList(string label) { if (breakList.Count > 0) @@ -526,6 +634,22 @@ private void PopBreakList(string label) } } } + + private void PushReturnList() + { + returnList.Add(braceNestLevel); + } + + private void PopReturnList() + { + if (returnList.Count > 0) + returnList.RemoveAt(returnList.Count-1); + } + + private int GetReturnNestLevel() + { + return (returnList.Count > 0) ? returnList.Last() : -1; + } private void VisitNode(ParseNode node) { @@ -536,15 +660,14 @@ private void VisitNode(ParseNode node) switch (node.Token.Type) { case TokenType.Start: + AddFunctionJumpVars(null); + VisitChildNodes(node); + break; case TokenType.instruction: VisitChildNodes(node); break; case TokenType.instruction_block: - ++braceNestLevel; - AddOpcode(new OpcodePushScope()); - VisitChildNodes(node); - AddOpcode(new OpcodePopScope()); - --braceNestLevel; + VisitInstructionBlock(node); break; case TokenType.set_stmt: VisitSetStatement(node); @@ -558,6 +681,9 @@ private void VisitNode(ParseNode node) case TokenType.lock_stmt: VisitLockStatement(node); break; + case TokenType.return_stmt: + VisitReturnStatement(node); + break; case TokenType.unlock_stmt: VisitUnlockStatement(node); break; @@ -893,16 +1019,19 @@ private void VisitOnOffTrailer(ParseNode node) /// the name to the left of the parentheses will be the name of the function call. If isDirect is false, then it will /// ignore the name to the left of the parentheses and presume the function name, delegate, or branch index was /// already placed atop the stack by other parts of this compiler. + /// true if this is a function call that will jump to user instructions in the code (LOCK and DECLARE FUNCTION), rather + /// than execute using C# code. /// In the case where it's a direct function, what's the name of it? In the case /// where it's not direct, this argument doesn't matter. - private void VisitActualFunction(ParseNode node, bool isDirect, string directName = "") + private void VisitActualFunction(ParseNode node, bool isDirect, bool isUserFunc, string directName = "") { NodeStartHousekeeping(node); + Console.WriteLine("eraseme: kOS: VisitActualFunction, isDirect="+isDirect+", directName="+directName); int parameterCount = 0; ParseNode trailerNode = node; // the function_trailer rule is here. - if (!isDirect) + if (isUserFunc || !isDirect) { // Need to tell OpcodeCall where in the stack the bottom of the arg list is. // Even if there are no arguments, it still has to be TOLD that by showing @@ -927,7 +1056,9 @@ private void VisitActualFunction(ParseNode node, bool isDirect, string directNam { string functionName = directName; - string overloadedFunctionName = GetFunctionOverload(functionName, parameterCount) + "()"; + string overloadedFunctionName = GetFunctionOverload(functionName, parameterCount); + if (options.FuncManager.Exists(overloadedFunctionName)) // if the name is a built-in, then add the "()" after it. + overloadedFunctionName += "()"; AddOpcode(new OpcodeCall(overloadedFunctionName)); } else @@ -996,53 +1127,84 @@ private void VisitSuffix(ParseNode node) suffixTerm.Nodes[1].Nodes[0].Token.Type == TokenType.function_trailer); string firstIdentifier = ""; + bool isUserFunc = false; + Console.WriteLine("eraseme: kOS: VisitSuffix, A"); + if (nodeIndex == 0) + { + Console.WriteLine("eraseme: kOS: VisitSuffix, B"); + firstIdentifier = GetIdentifierText(suffixTerm); + if (context.Locks.Contains(firstIdentifier)) + { + Console.WriteLine("eraseme: kOS: VisitSuffix, C"); + Lock lockObject = context.Locks.GetLock(firstIdentifier); + firstIdentifier = lockObject.PointerIdentifier; + isUserFunc = true; + } + } + Console.WriteLine("eraseme: kOS: VisitSuffix, D"); // The term starts with either an identifier or an expression. If it's the start, then parse // it as a variable, else parse it as a raw identifier: bool rememberIsV = identifierIsVariable; identifierIsVariable = (!startsWithFunc) && nodeIndex == 0; - - // Push this term on the stack unless it's the name of the built-in-function (built-in-functions - // being called without any preceding colon term, with methods on the other hand having suffixes): - if (nodeIndex > 0 || !startsWithFunc) - VisitNode(suffixTerm.Nodes[0]); - identifierIsVariable = rememberIsV; - if (nodeIndex == 0) + // Push this term on the stack unless it's the name of the user function or built-in function: + bool isDirect = true; + Console.WriteLine("eraseme: kOS: VisitSuffix, E"); + if ( (!isUserFunc) && (nodeIndex > 0 || !startsWithFunc) ) { - firstIdentifier = GetIdentifierText(suffixTerm); + Console.WriteLine("eraseme: kOS: VisitSuffix, F"); + VisitNode(suffixTerm.Nodes[0]); + isDirect = false; } - else + Console.WriteLine("eraseme: kOS: VisitSuffix, G"); + identifierIsVariable = rememberIsV; + if (nodeIndex != 0) { + Console.WriteLine("eraseme: kOS: VisitSuffix, H"); // when we are setting a member value we need to leave // the last object and the last suffix in the stack bool usingSetMember = (suffixTerm.Nodes.Count > 0) && (compilingSetDestination && nodeIndex == (node.Nodes.Count - 1)); if (!usingSetMember) { + Console.WriteLine("eraseme: kOS: VisitSuffix, I"); AddOpcode(startsWithFunc ? new OpcodeGetMethod() : new OpcodeGetMember()); } } - + Console.WriteLine("eraseme: kOS: VisitSuffix, isDirect="+isDirect+", firstIdentifier="+firstIdentifier); // The remaining terms are a chain of function_trailers "(...)" and array_trailers "[...]" or "#.." in any arbitrary order: for (int trailerIndex = 1; trailerIndex < suffixTerm.Nodes.Count; ++trailerIndex) { + Console.WriteLine("eraseme: kOS: VisitSuffix, J"); // suffixterm_trailer is always a wrapper around either function_trailer or array_trailer, // so delve down one level to get which of them it is: ParseNode trailerTerm = suffixTerm.Nodes[trailerIndex].Nodes[0]; bool isFunc = (trailerTerm.Token.Type == TokenType.function_trailer); bool isArray = (trailerTerm.Token.Type == TokenType.array_trailer); - if (isFunc) + if (isFunc || isUserFunc) { + Console.WriteLine("eraseme: kOS: VisitSuffix, K"); // direct if it's just one term like foo(aaa) but indirect // if it's a list of suffixes like foo:bar(aaa): - VisitActualFunction(trailerTerm, (nodeIndex == 0), firstIdentifier); + VisitActualFunction(trailerTerm, isDirect, isUserFunc, firstIdentifier); } if (isArray) { + Console.WriteLine("eraseme: kOS: VisitSuffix, L"); VisitActualArray(trailerTerm); } } + + // In the case of a lock function withiout parentheses, it needs this special case: + if (suffixTerm.Nodes.Count <= 1) + { + if (isDirect && isUserFunc) + { + AddOpcode(new OpcodePush(OpcodeCall.ARG_MARKER_STRING)); + AddOpcode(new OpcodeCall(firstIdentifier)); + } + } identifierIsSuffix = remember; @@ -1205,27 +1367,33 @@ private bool IsActualArrayIndexing(ParseNode node) private void VisitSuffixTerm(ParseNode node) { NodeStartHousekeeping(node); + + // I'm not entirely convinced this method is even being called by the parser anymore. + // I think it's arranged such that it's VisitSuffix that does all the work. + // If I can find a way to prove that I might want to see this method deleted. if (node.Nodes.Count > 1 && node.Nodes[1].Token.Type == TokenType.function_trailer) { // if a bracket follows an identifier then its a function call - VisitActualFunction(node.Nodes[1], true, GetIdentifierText(node)); + VisitActualFunction(node.Nodes[1], true, false, GetIdentifierText(node)); } else { VisitNode(node.Nodes[0]); // I'm not really a function call after all - just a wrapper around another node type. } } - + private void VisitIdentifier(ParseNode node) { NodeStartHousekeeping(node); bool isVariable = (identifierIsVariable && !identifierIsSuffix); string prefix = isVariable ? "$" : String.Empty; string identifier = GetIdentifierText(node); + Console.WriteLine("eraseme: kOS: VisitIdentifier called, on identifier " + identifier ); if (isVariable && context.Locks.Contains(identifier)) { + Console.WriteLine("eraseme: kOS: It thinks it is an identifier."); Lock lockObject = context.Locks.GetLock(identifier); if (compilingSetDestination) { @@ -1585,6 +1753,52 @@ private void VisitComparator(ParseNode node) } } + private void VisitInstructionBlock(ParseNode node) + { + ++braceNestLevel; + AddOpcode(new OpcodePushScope()); + AddFunctionJumpVars(node); + VisitChildNodes(node); + AddOpcode(new OpcodePopScope()); + --braceNestLevel; + } + + /// + /// Add all the variables at this local scope for holding the jump addresses to go to + /// for the given function names defined in this scope. Pass a NULL to mean global scope. + /// + /// + private void AddFunctionJumpVars(ParseNode node) + { + Console.WriteLine("eraseme: AddFunctionJumpVars("+((node==null)?"null":node.Token.Type.ToString())+"), when locks is size = " + (context.Locks == null ? -1 : context.Locks.GetLockList().Count())); + /*eraseme*/ foreach ( Lock l in context.Locks.GetLockList()) { + /*eraseme*/ Console.WriteLine(" " + (l.Identifier ?? "null") + ", IsFunction=" + l.IsFunction + ", ScopeNode=" + (l.ScopeNode == null ? "null" : l.ScopeNode.Token.Type.ToString())); + /*eraseme*/ } + // All the functions for which this scope is where they live: + IEnumerable theseFuncs = context.Locks.GetLockList().Where((item) => item.IsFunction && item.ScopeNode == node); + + foreach (Lock func in theseFuncs) + { + // Populate the LOCAL name with the function jump location. + // By storing the mapping from identifier name to instruction jump point in + // a local variable, we're masking the function from view when its variable + // identifier is out of scope. (For example if a function's body of Opcodes + // is stored at locations K100_021 trhough K100_141, then those 100 opcodes + // are compiled statically and are always present in memory in a way that ignores scope, + // but the variable "$MyFunc*" that contains the value K100_021 to tell you where + // to jump to to start the function will stop existing once MyFunc is out of scope). + // This is typical of an OOP langauge. The physical code is always static for all + // methods and functions, and always has exactly one copy in memory whether there are + // one, many, or zero "instances" of it present in scope at the moment. + AddOpcode(new OpcodePush(func.PointerIdentifier)); + AddOpcode(new OpcodePushRelocateLater(null), func.GetFuncLabel()); + if (node == null) // global scope, sO use a normal Store: + AddOpcode(new OpcodeStore()); // + else + AddOpcode(new OpcodeStoreLocal()); // OpcodeStoreLOCAL to force a local var. OpcodeStore would follow up the nest to more global scopes. + } + } + private void VisitLockStatement(ParseNode node) { NodeStartHousekeeping(node); @@ -1620,7 +1834,7 @@ private void VisitLockStatement(ParseNode node) } } } - + private void VisitUnlockStatement(ParseNode node) { NodeStartHousekeeping(node); @@ -1738,6 +1952,25 @@ private void VisitDeclareStatement(ParseNode node) VisitNode(node.Nodes[3]); AddOpcode(new OpcodeStoreLocal()); } + // If the declare statement is of the form: + // DECLARE PARAMETER ident. + // or + // DECLARE PARAMETER ident,ident,ident... + // AND this is inside a function definition rather than being at the global script level. + // (at the global script level a DEFINE PARAMETER statement is for RUN parameters, which + // get handled differently.) + else if (node.Nodes.Count > 1 && node.Nodes[1].Token.Type == TokenType.PARAMETER && + IsInsideDefineFunctionStatement(node)) + { + for (int i = 2 ; i < node.Nodes.Count ; i += 2) + { + VisitNode(node.Nodes[i]); + AddOpcode(new OpcodeSwap()); + AddOpcode(new OpcodeStoreLocal()); + } + } + // Note: DECLARE FUNCTION is dealt with entirely during + // PreprocessDeclareStatement, with nothing for VisitNode to do. } private void VisitToggleStatement(ParseNode node) @@ -1954,7 +2187,10 @@ private void VisitBreakStatement(ParseNode node) // number of braces we're skipping out of. For now just record the // current nest level in the opcode. Later, during PopBreakList(), // the nest argument gets replaced with the real value it will have - // in the final program: + // in the final program. The reason for not just doing it now is + // that we have to wait until the bottom of the nested braces to + // find out where to jump to anyway, so this opcode will have to be + // revisted then anyway: Opcode popScope = AddOpcode(new OpcodePopScope(braceNestLevel)); AddToBreakList(popScope); @@ -1965,6 +2201,36 @@ private void VisitBreakStatement(ParseNode node) AddToBreakList(jump); } + private void VisitReturnStatement(ParseNode node) + { + NodeStartHousekeeping(node); + + int nestLevelJustOutsideFuncBraces = GetReturnNestLevel(); + + if (nestLevelJustOutsideFuncBraces < 0) + throw new KOSReturnInvalidHereException(); + + // Push the return expression onto the stack, or if it was a naked RETURN + // keyword with no expression, then push a secret dummy return value of zero: + if (node.Nodes.Count > 1) + { + VisitNode(node.Nodes[1]); + AddOpcode(new OpcodeEval()); // vital because we can't return a local var to the caller, + // we must return the value it contained instead. + } + else + { + AddOpcode(new OpcodePush(0)); + } + + // Pop the correct number of scoping levels and return. This is much + // simpler than the BREAK case because RETURN already knows to use the function + // call stack to figure out where to return to, so we don't have to wait until + // later to decide where to jump to like we do in BREAK: + AddOpcode(new OpcodePopScope(braceNestLevel - nestLevelJustOutsideFuncBraces)); + AddOpcode(new OpcodeReturn()); + } + private void VisitPreserveStatement(ParseNode node) { NodeStartHousekeeping(node); diff --git a/src/kOS.Safe/Compilation/KS/Lock.cs b/src/kOS.Safe/Compilation/KS/Lock.cs index dff218865..24c7cb786 100644 --- a/src/kOS.Safe/Compilation/KS/Lock.cs +++ b/src/kOS.Safe/Compilation/KS/Lock.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Linq; namespace kOS.Safe.Compilation.KS { @@ -13,6 +14,14 @@ public class Lock public string Identifier { get; private set; } public string PointerIdentifier{ get; private set; } public string DefaultLabel{ get; private set; } + + /// + /// A the thing this was defined in. (it will be part of the parse tree of the compiler). + /// null = global + /// + public ParseNode ScopeNode {get; set;} + + public bool IsFunction {get; set; } public List InitializationCode { @@ -24,7 +33,6 @@ public List MainCode get { return codePart.MainCode; } } - public Lock() { codePart = new CodePart(); @@ -40,12 +48,27 @@ public Lock(string lockIdentifier) DefaultLabel = Identifier + "-default"; } - public bool IsInitialized() { - return (codePart.InitializationCode.Count > 0); + return (IsFunction || codePart.InitializationCode.Count > 0); } + /// + /// Get the label of the function body entry point, + /// in other words the label of the very first Opcode + /// instruction at the start of the function body. + /// + /// string label, i.e. K00001 + public string GetFuncLabel() + { + if (functions.Count <= 0) + return "undefined"; + else if (! IsFunction) + return "not-a-function"; + else + return functions.Values.FirstOrDefault().Code[0].Label; + } + public List GetLockFunction(int expressionHash) { if (functions.ContainsKey(expressionHash)) @@ -57,7 +80,7 @@ public List GetLockFunction(int expressionHash) newFunctions.Add(newLockFunction); return newLockFunction.Code; } - + public CodePart GetCodePart() { var mergedPart = new CodePart diff --git a/src/kOS.Safe/Compilation/KS/ParseTree.cs b/src/kOS.Safe/Compilation/KS/ParseTree.cs index 5a0edb514..d580da374 100644 --- a/src/kOS.Safe/Compilation/KS/ParseTree.cs +++ b/src/kOS.Safe/Compilation/KS/ParseTree.cs @@ -247,6 +247,9 @@ internal object Eval(ParseTree tree, params object[] paramlist) case TokenType.declare_stmt: Value = Evaldeclare_stmt(tree, paramlist); break; + case TokenType.return_stmt: + Value = Evalreturn_stmt(tree, paramlist); + break; case TokenType.switch_stmt: Value = Evalswitch_stmt(tree, paramlist); break; @@ -513,6 +516,13 @@ protected virtual object Evaldeclare_stmt(ParseTree tree, params object[] paraml return null; } + protected virtual object Evalreturn_stmt(ParseTree tree, params object[] paramlist) + { + foreach (var node in Nodes) + node.Eval(tree, paramlist); + return null; + } + protected virtual object Evalswitch_stmt(ParseTree tree, params object[] paramlist) { foreach (var node in Nodes) diff --git a/src/kOS.Safe/Compilation/KS/Parser.cs b/src/kOS.Safe/Compilation/KS/Parser.cs index 5b5a9df63..f80e7668e 100644 --- a/src/kOS.Safe/Compilation/KS/Parser.cs +++ b/src/kOS.Safe/Compilation/KS/Parser.cs @@ -47,7 +47,7 @@ private void ParseStart(ParseNode parent) - tok = scanner.LookAhead(TokenType.SET, TokenType.IF, TokenType.UNTIL, TokenType.LOCK, TokenType.UNLOCK, TokenType.PRINT, TokenType.ON, TokenType.TOGGLE, TokenType.WAIT, TokenType.WHEN, TokenType.STAGE, TokenType.CLEARSCREEN, TokenType.ADD, TokenType.REMOVE, TokenType.LOG, TokenType.BREAK, TokenType.PRESERVE, TokenType.DECLARE, TokenType.SWITCH, TokenType.COPY, TokenType.RENAME, TokenType.DELETE, TokenType.EDIT, TokenType.RUN, TokenType.COMPILE, TokenType.LIST, TokenType.REBOOT, TokenType.SHUTDOWN, TokenType.FOR, TokenType.UNSET, TokenType.BATCH, TokenType.DEPLOY, TokenType.CURLYOPEN, TokenType.PLUSMINUS, TokenType.NOT, TokenType.INTEGER, TokenType.DOUBLE, TokenType.TRUEFALSE, TokenType.IDENTIFIER, TokenType.FILEIDENT, TokenType.BRACKETOPEN, TokenType.STRING); + tok = scanner.LookAhead(TokenType.SET, TokenType.IF, TokenType.UNTIL, TokenType.LOCK, TokenType.UNLOCK, TokenType.PRINT, TokenType.ON, TokenType.TOGGLE, TokenType.WAIT, TokenType.WHEN, TokenType.STAGE, TokenType.CLEARSCREEN, TokenType.ADD, TokenType.REMOVE, TokenType.LOG, TokenType.BREAK, TokenType.PRESERVE, TokenType.DECLARE, TokenType.RETURN, TokenType.SWITCH, TokenType.COPY, TokenType.RENAME, TokenType.DELETE, TokenType.EDIT, TokenType.RUN, TokenType.COMPILE, TokenType.LIST, TokenType.REBOOT, TokenType.SHUTDOWN, TokenType.FOR, TokenType.UNSET, TokenType.BATCH, TokenType.DEPLOY, TokenType.CURLYOPEN, TokenType.PLUSMINUS, TokenType.NOT, TokenType.INTEGER, TokenType.DOUBLE, TokenType.TRUEFALSE, TokenType.IDENTIFIER, TokenType.FILEIDENT, TokenType.BRACKETOPEN, TokenType.STRING); while (tok.Type == TokenType.SET || tok.Type == TokenType.IF || tok.Type == TokenType.UNTIL @@ -66,6 +66,7 @@ private void ParseStart(ParseNode parent) || tok.Type == TokenType.BREAK || tok.Type == TokenType.PRESERVE || tok.Type == TokenType.DECLARE + || tok.Type == TokenType.RETURN || tok.Type == TokenType.SWITCH || tok.Type == TokenType.COPY || tok.Type == TokenType.RENAME @@ -92,7 +93,7 @@ private void ParseStart(ParseNode parent) || tok.Type == TokenType.STRING) { Parseinstruction(node); - tok = scanner.LookAhead(TokenType.SET, TokenType.IF, TokenType.UNTIL, TokenType.LOCK, TokenType.UNLOCK, TokenType.PRINT, TokenType.ON, TokenType.TOGGLE, TokenType.WAIT, TokenType.WHEN, TokenType.STAGE, TokenType.CLEARSCREEN, TokenType.ADD, TokenType.REMOVE, TokenType.LOG, TokenType.BREAK, TokenType.PRESERVE, TokenType.DECLARE, TokenType.SWITCH, TokenType.COPY, TokenType.RENAME, TokenType.DELETE, TokenType.EDIT, TokenType.RUN, TokenType.COMPILE, TokenType.LIST, TokenType.REBOOT, TokenType.SHUTDOWN, TokenType.FOR, TokenType.UNSET, TokenType.BATCH, TokenType.DEPLOY, TokenType.CURLYOPEN, TokenType.PLUSMINUS, TokenType.NOT, TokenType.INTEGER, TokenType.DOUBLE, TokenType.TRUEFALSE, TokenType.IDENTIFIER, TokenType.FILEIDENT, TokenType.BRACKETOPEN, TokenType.STRING); + tok = scanner.LookAhead(TokenType.SET, TokenType.IF, TokenType.UNTIL, TokenType.LOCK, TokenType.UNLOCK, TokenType.PRINT, TokenType.ON, TokenType.TOGGLE, TokenType.WAIT, TokenType.WHEN, TokenType.STAGE, TokenType.CLEARSCREEN, TokenType.ADD, TokenType.REMOVE, TokenType.LOG, TokenType.BREAK, TokenType.PRESERVE, TokenType.DECLARE, TokenType.RETURN, TokenType.SWITCH, TokenType.COPY, TokenType.RENAME, TokenType.DELETE, TokenType.EDIT, TokenType.RUN, TokenType.COMPILE, TokenType.LIST, TokenType.REBOOT, TokenType.SHUTDOWN, TokenType.FOR, TokenType.UNSET, TokenType.BATCH, TokenType.DEPLOY, TokenType.CURLYOPEN, TokenType.PLUSMINUS, TokenType.NOT, TokenType.INTEGER, TokenType.DOUBLE, TokenType.TRUEFALSE, TokenType.IDENTIFIER, TokenType.FILEIDENT, TokenType.BRACKETOPEN, TokenType.STRING); } @@ -127,7 +128,7 @@ private void Parseinstruction_block(ParseNode parent) } - tok = scanner.LookAhead(TokenType.SET, TokenType.IF, TokenType.UNTIL, TokenType.LOCK, TokenType.UNLOCK, TokenType.PRINT, TokenType.ON, TokenType.TOGGLE, TokenType.WAIT, TokenType.WHEN, TokenType.STAGE, TokenType.CLEARSCREEN, TokenType.ADD, TokenType.REMOVE, TokenType.LOG, TokenType.BREAK, TokenType.PRESERVE, TokenType.DECLARE, TokenType.SWITCH, TokenType.COPY, TokenType.RENAME, TokenType.DELETE, TokenType.EDIT, TokenType.RUN, TokenType.COMPILE, TokenType.LIST, TokenType.REBOOT, TokenType.SHUTDOWN, TokenType.FOR, TokenType.UNSET, TokenType.BATCH, TokenType.DEPLOY, TokenType.CURLYOPEN, TokenType.PLUSMINUS, TokenType.NOT, TokenType.INTEGER, TokenType.DOUBLE, TokenType.TRUEFALSE, TokenType.IDENTIFIER, TokenType.FILEIDENT, TokenType.BRACKETOPEN, TokenType.STRING); + tok = scanner.LookAhead(TokenType.SET, TokenType.IF, TokenType.UNTIL, TokenType.LOCK, TokenType.UNLOCK, TokenType.PRINT, TokenType.ON, TokenType.TOGGLE, TokenType.WAIT, TokenType.WHEN, TokenType.STAGE, TokenType.CLEARSCREEN, TokenType.ADD, TokenType.REMOVE, TokenType.LOG, TokenType.BREAK, TokenType.PRESERVE, TokenType.DECLARE, TokenType.RETURN, TokenType.SWITCH, TokenType.COPY, TokenType.RENAME, TokenType.DELETE, TokenType.EDIT, TokenType.RUN, TokenType.COMPILE, TokenType.LIST, TokenType.REBOOT, TokenType.SHUTDOWN, TokenType.FOR, TokenType.UNSET, TokenType.BATCH, TokenType.DEPLOY, TokenType.CURLYOPEN, TokenType.PLUSMINUS, TokenType.NOT, TokenType.INTEGER, TokenType.DOUBLE, TokenType.TRUEFALSE, TokenType.IDENTIFIER, TokenType.FILEIDENT, TokenType.BRACKETOPEN, TokenType.STRING); while (tok.Type == TokenType.SET || tok.Type == TokenType.IF || tok.Type == TokenType.UNTIL @@ -146,6 +147,7 @@ private void Parseinstruction_block(ParseNode parent) || tok.Type == TokenType.BREAK || tok.Type == TokenType.PRESERVE || tok.Type == TokenType.DECLARE + || tok.Type == TokenType.RETURN || tok.Type == TokenType.SWITCH || tok.Type == TokenType.COPY || tok.Type == TokenType.RENAME @@ -172,7 +174,7 @@ private void Parseinstruction_block(ParseNode parent) || tok.Type == TokenType.STRING) { Parseinstruction(node); - tok = scanner.LookAhead(TokenType.SET, TokenType.IF, TokenType.UNTIL, TokenType.LOCK, TokenType.UNLOCK, TokenType.PRINT, TokenType.ON, TokenType.TOGGLE, TokenType.WAIT, TokenType.WHEN, TokenType.STAGE, TokenType.CLEARSCREEN, TokenType.ADD, TokenType.REMOVE, TokenType.LOG, TokenType.BREAK, TokenType.PRESERVE, TokenType.DECLARE, TokenType.SWITCH, TokenType.COPY, TokenType.RENAME, TokenType.DELETE, TokenType.EDIT, TokenType.RUN, TokenType.COMPILE, TokenType.LIST, TokenType.REBOOT, TokenType.SHUTDOWN, TokenType.FOR, TokenType.UNSET, TokenType.BATCH, TokenType.DEPLOY, TokenType.CURLYOPEN, TokenType.PLUSMINUS, TokenType.NOT, TokenType.INTEGER, TokenType.DOUBLE, TokenType.TRUEFALSE, TokenType.IDENTIFIER, TokenType.FILEIDENT, TokenType.BRACKETOPEN, TokenType.STRING); + tok = scanner.LookAhead(TokenType.SET, TokenType.IF, TokenType.UNTIL, TokenType.LOCK, TokenType.UNLOCK, TokenType.PRINT, TokenType.ON, TokenType.TOGGLE, TokenType.WAIT, TokenType.WHEN, TokenType.STAGE, TokenType.CLEARSCREEN, TokenType.ADD, TokenType.REMOVE, TokenType.LOG, TokenType.BREAK, TokenType.PRESERVE, TokenType.DECLARE, TokenType.RETURN, TokenType.SWITCH, TokenType.COPY, TokenType.RENAME, TokenType.DELETE, TokenType.EDIT, TokenType.RUN, TokenType.COMPILE, TokenType.LIST, TokenType.REBOOT, TokenType.SHUTDOWN, TokenType.FOR, TokenType.UNSET, TokenType.BATCH, TokenType.DEPLOY, TokenType.CURLYOPEN, TokenType.PLUSMINUS, TokenType.NOT, TokenType.INTEGER, TokenType.DOUBLE, TokenType.TRUEFALSE, TokenType.IDENTIFIER, TokenType.FILEIDENT, TokenType.BRACKETOPEN, TokenType.STRING); } @@ -209,7 +211,7 @@ private void Parseinstruction(ParseNode parent) ParseNode node = parent.CreateNode(scanner.GetToken(TokenType.instruction), "instruction"); parent.Nodes.Add(node); - tok = scanner.LookAhead(TokenType.SET, TokenType.IF, TokenType.UNTIL, TokenType.LOCK, TokenType.UNLOCK, TokenType.PRINT, TokenType.ON, TokenType.TOGGLE, TokenType.WAIT, TokenType.WHEN, TokenType.STAGE, TokenType.CLEARSCREEN, TokenType.ADD, TokenType.REMOVE, TokenType.LOG, TokenType.BREAK, TokenType.PRESERVE, TokenType.DECLARE, TokenType.SWITCH, TokenType.COPY, TokenType.RENAME, TokenType.DELETE, TokenType.EDIT, TokenType.RUN, TokenType.COMPILE, TokenType.LIST, TokenType.REBOOT, TokenType.SHUTDOWN, TokenType.FOR, TokenType.UNSET, TokenType.BATCH, TokenType.DEPLOY, TokenType.CURLYOPEN, TokenType.PLUSMINUS, TokenType.NOT, TokenType.INTEGER, TokenType.DOUBLE, TokenType.TRUEFALSE, TokenType.IDENTIFIER, TokenType.FILEIDENT, TokenType.BRACKETOPEN, TokenType.STRING); + tok = scanner.LookAhead(TokenType.SET, TokenType.IF, TokenType.UNTIL, TokenType.LOCK, TokenType.UNLOCK, TokenType.PRINT, TokenType.ON, TokenType.TOGGLE, TokenType.WAIT, TokenType.WHEN, TokenType.STAGE, TokenType.CLEARSCREEN, TokenType.ADD, TokenType.REMOVE, TokenType.LOG, TokenType.BREAK, TokenType.PRESERVE, TokenType.DECLARE, TokenType.RETURN, TokenType.SWITCH, TokenType.COPY, TokenType.RENAME, TokenType.DELETE, TokenType.EDIT, TokenType.RUN, TokenType.COMPILE, TokenType.LIST, TokenType.REBOOT, TokenType.SHUTDOWN, TokenType.FOR, TokenType.UNSET, TokenType.BATCH, TokenType.DEPLOY, TokenType.CURLYOPEN, TokenType.PLUSMINUS, TokenType.NOT, TokenType.INTEGER, TokenType.DOUBLE, TokenType.TRUEFALSE, TokenType.IDENTIFIER, TokenType.FILEIDENT, TokenType.BRACKETOPEN, TokenType.STRING); switch (tok.Type) { case TokenType.SET: @@ -266,6 +268,9 @@ private void Parseinstruction(ParseNode parent) case TokenType.DECLARE: Parsedeclare_stmt(node); break; + case TokenType.RETURN: + Parsereturn_stmt(node); + break; case TokenType.SWITCH: Parseswitch_stmt(node); break; @@ -1175,7 +1180,7 @@ private void Parsedeclare_stmt(ParseNode parent) } - tok = scanner.LookAhead(TokenType.PARAMETER, TokenType.IDENTIFIER); + tok = scanner.LookAhead(TokenType.PARAMETER, TokenType.FUNCTION, TokenType.IDENTIFIER); switch (tok.Type) { case TokenType.PARAMETER: @@ -1226,10 +1231,61 @@ private void Parsedeclare_stmt(ParseNode parent) } tok = scanner.LookAhead(TokenType.COMMA); } + + + tok = scanner.Scan(TokenType.EOI); + n = node.CreateNode(tok, tok.ToString() ); + node.Token.UpdateRange(tok); + node.Nodes.Add(n); + if (tok.Type != TokenType.EOI) { + tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.EOI.ToString(), 0x1001, tok)); + return; + } + break; + case TokenType.FUNCTION: + + + tok = scanner.Scan(TokenType.FUNCTION); + n = node.CreateNode(tok, tok.ToString() ); + node.Token.UpdateRange(tok); + node.Nodes.Add(n); + if (tok.Type != TokenType.FUNCTION) { + tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.FUNCTION.ToString(), 0x1001, tok)); + return; + } + + + tok = scanner.Scan(TokenType.IDENTIFIER); + n = node.CreateNode(tok, tok.ToString() ); + node.Token.UpdateRange(tok); + node.Nodes.Add(n); + if (tok.Type != TokenType.IDENTIFIER) { + tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.IDENTIFIER.ToString(), 0x1001, tok)); + return; + } + + + Parseinstruction_block(node); + + + tok = scanner.LookAhead(TokenType.EOI); + if (tok.Type == TokenType.EOI) + { + tok = scanner.Scan(TokenType.EOI); + n = node.CreateNode(tok, tok.ToString() ); + node.Token.UpdateRange(tok); + node.Nodes.Add(n); + if (tok.Type != TokenType.EOI) { + tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.EOI.ToString(), 0x1001, tok)); + return; + } + } break; case TokenType.IDENTIFIER: + + tok = scanner.Scan(TokenType.IDENTIFIER); n = node.CreateNode(tok, tok.ToString() ); node.Token.UpdateRange(tok); @@ -1251,12 +1307,46 @@ private void Parsedeclare_stmt(ParseNode parent) Parseexpr(node); + + + tok = scanner.Scan(TokenType.EOI); + n = node.CreateNode(tok, tok.ToString() ); + node.Token.UpdateRange(tok); + node.Nodes.Add(n); + if (tok.Type != TokenType.EOI) { + tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.EOI.ToString(), 0x1001, tok)); + return; + } break; default: tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found.", 0x0002, tok)); break; } + parent.Token.UpdateRange(node.Token); + } + + private void Parsereturn_stmt(ParseNode parent) + { + Token tok; + ParseNode n; + ParseNode node = parent.CreateNode(scanner.GetToken(TokenType.return_stmt), "return_stmt"); + parent.Nodes.Add(node); + + + + tok = scanner.Scan(TokenType.RETURN); + n = node.CreateNode(tok, tok.ToString() ); + node.Token.UpdateRange(tok); + node.Nodes.Add(n); + if (tok.Type != TokenType.RETURN) { + tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.RETURN.ToString(), 0x1001, tok)); + return; + } + + + Parseexpr(node); + tok = scanner.Scan(TokenType.EOI); n = node.CreateNode(tok, tok.ToString() ); diff --git a/src/kOS.Safe/Compilation/KS/Scanner.cs b/src/kOS.Safe/Compilation/KS/Scanner.cs index 6983be0a5..fb29f7bd8 100644 --- a/src/kOS.Safe/Compilation/KS/Scanner.cs +++ b/src/kOS.Safe/Compilation/KS/Scanner.cs @@ -174,6 +174,14 @@ public Scanner() Patterns.Add(TokenType.PARAMETER, regex); Tokens.Add(TokenType.PARAMETER); + regex = new Regex(@"function"); + Patterns.Add(TokenType.FUNCTION, regex); + Tokens.Add(TokenType.FUNCTION); + + regex = new Regex(@"return"); + Patterns.Add(TokenType.RETURN, regex); + Tokens.Add(TokenType.RETURN); + regex = new Regex(@"switch"); Patterns.Add(TokenType.SWITCH, regex); Tokens.Add(TokenType.SWITCH); @@ -505,112 +513,115 @@ public enum TokenType break_stmt= 22, preserve_stmt= 23, declare_stmt= 24, - switch_stmt= 25, - copy_stmt= 26, - rename_stmt= 27, - delete_stmt= 28, - edit_stmt= 29, - run_stmt= 30, - compile_stmt= 31, - list_stmt= 32, - reboot_stmt= 33, - shutdown_stmt= 34, - for_stmt= 35, - unset_stmt= 36, - batch_stmt= 37, - deploy_stmt= 38, - arglist = 39, - expr = 40, - and_expr= 41, - compare_expr= 42, - arith_expr= 43, - multdiv_expr= 44, - factor = 45, - suffix = 46, - suffix_trailer= 47, - suffixterm= 48, - suffixterm_trailer= 49, - function_trailer= 50, - array_trailer= 51, - atom = 52, - sci_number= 53, - number = 54, - varidentifier= 55, - identifier_led_stmt= 56, - identifier_led_expr= 57, + return_stmt= 25, + switch_stmt= 26, + copy_stmt= 27, + rename_stmt= 28, + delete_stmt= 29, + edit_stmt= 30, + run_stmt= 31, + compile_stmt= 32, + list_stmt= 33, + reboot_stmt= 34, + shutdown_stmt= 35, + for_stmt= 36, + unset_stmt= 37, + batch_stmt= 38, + deploy_stmt= 39, + arglist = 40, + expr = 41, + and_expr= 42, + compare_expr= 43, + arith_expr= 44, + multdiv_expr= 45, + factor = 46, + suffix = 47, + suffix_trailer= 48, + suffixterm= 49, + suffixterm_trailer= 50, + function_trailer= 51, + array_trailer= 52, + atom = 53, + sci_number= 54, + number = 55, + varidentifier= 56, + identifier_led_stmt= 57, + identifier_led_expr= 58, //Terminal tokens: - PLUSMINUS= 58, - MULT = 59, - DIV = 60, - POWER = 61, - E = 62, - NOT = 63, - AND = 64, - OR = 65, - TRUEFALSE= 66, - COMPARATOR= 67, - SET = 68, - TO = 69, - IF = 70, - ELSE = 71, - UNTIL = 72, - LOCK = 73, - UNLOCK = 74, - PRINT = 75, - AT = 76, - ON = 77, - TOGGLE = 78, - WAIT = 79, - WHEN = 80, - THEN = 81, - OFF = 82, - STAGE = 83, - CLEARSCREEN= 84, - ADD = 85, - REMOVE = 86, - LOG = 87, - BREAK = 88, - PRESERVE= 89, - DECLARE = 90, - PARAMETER= 91, - SWITCH = 92, - COPY = 93, - FROM = 94, - RENAME = 95, - VOLUME = 96, - FILE = 97, - DELETE = 98, - EDIT = 99, - RUN = 100, - COMPILE = 101, - LIST = 102, - REBOOT = 103, - SHUTDOWN= 104, - FOR = 105, - UNSET = 106, - BATCH = 107, - DEPLOY = 108, - BRACKETOPEN= 109, - BRACKETCLOSE= 110, - CURLYOPEN= 111, - CURLYCLOSE= 112, - SQUAREOPEN= 113, - SQUARECLOSE= 114, - COMMA = 115, - COLON = 116, - IN = 117, - ARRAYINDEX= 118, - ALL = 119, - IDENTIFIER= 120, - FILEIDENT= 121, - INTEGER = 122, - DOUBLE = 123, - STRING = 124, - EOI = 125, - EOF = 126, - WHITESPACE= 127, - COMMENTLINE= 128 + PLUSMINUS= 59, + MULT = 60, + DIV = 61, + POWER = 62, + E = 63, + NOT = 64, + AND = 65, + OR = 66, + TRUEFALSE= 67, + COMPARATOR= 68, + SET = 69, + TO = 70, + IF = 71, + ELSE = 72, + UNTIL = 73, + LOCK = 74, + UNLOCK = 75, + PRINT = 76, + AT = 77, + ON = 78, + TOGGLE = 79, + WAIT = 80, + WHEN = 81, + THEN = 82, + OFF = 83, + STAGE = 84, + CLEARSCREEN= 85, + ADD = 86, + REMOVE = 87, + LOG = 88, + BREAK = 89, + PRESERVE= 90, + DECLARE = 91, + PARAMETER= 92, + FUNCTION= 93, + RETURN = 94, + SWITCH = 95, + COPY = 96, + FROM = 97, + RENAME = 98, + VOLUME = 99, + FILE = 100, + DELETE = 101, + EDIT = 102, + RUN = 103, + COMPILE = 104, + LIST = 105, + REBOOT = 106, + SHUTDOWN= 107, + FOR = 108, + UNSET = 109, + BATCH = 110, + DEPLOY = 111, + BRACKETOPEN= 112, + BRACKETCLOSE= 113, + CURLYOPEN= 114, + CURLYCLOSE= 115, + SQUAREOPEN= 116, + SQUARECLOSE= 117, + COMMA = 118, + COLON = 119, + IN = 120, + ARRAYINDEX= 121, + ALL = 122, + IDENTIFIER= 123, + FILEIDENT= 124, + INTEGER = 125, + DOUBLE = 126, + STRING = 127, + EOI = 128, + EOF = 129, + WHITESPACE= 130, + COMMENTLINE= 131 } public class Token diff --git a/src/kOS.Safe/Compilation/KS/kRISC.tpg b/src/kOS.Safe/Compilation/KS/kRISC.tpg index b7519c902..70c4e7791 100644 --- a/src/kOS.Safe/Compilation/KS/kRISC.tpg +++ b/src/kOS.Safe/Compilation/KS/kRISC.tpg @@ -39,6 +39,8 @@ BREAK -> @"break"; PRESERVE -> @"preserve"; DECLARE -> @"declare"; PARAMETER -> @"parameter"; +FUNCTION -> @"function"; +RETURN -> @"return"; SWITCH -> @"switch"; COPY -> @"copy"; FROM -> @"from"; @@ -103,6 +105,7 @@ instruction -> set_stmt | break_stmt | preserve_stmt | declare_stmt | + return_stmt | switch_stmt | copy_stmt | rename_stmt | @@ -142,7 +145,8 @@ remove_stmt -> REMOVE expr EOI; log_stmt -> LOG expr TO expr EOI; break_stmt -> BREAK EOI; preserve_stmt -> PRESERVE EOI; -declare_stmt -> DECLARE ((PARAMETER IDENTIFIER (COMMA IDENTIFIER)*)|(IDENTIFIER TO expr)) EOI; +declare_stmt -> DECLARE ( (PARAMETER IDENTIFIER (COMMA IDENTIFIER)* EOI) | (FUNCTION IDENTIFIER instruction_block EOI?) | (IDENTIFIER TO expr) EOI); +return_stmt -> RETURN expr EOI; switch_stmt -> SWITCH TO expr EOI; copy_stmt -> COPY expr (FROM | TO) expr EOI; rename_stmt -> RENAME (VOLUME | FILE)? expr TO expr EOI; diff --git a/src/kOS.Safe/Compilation/Opcode.cs b/src/kOS.Safe/Compilation/Opcode.cs index 0723fc9ee..faa6bee4a 100644 --- a/src/kOS.Safe/Compilation/Opcode.cs +++ b/src/kOS.Safe/Compilation/Opcode.cs @@ -68,14 +68,15 @@ public enum ByteCode :byte POP = 0x4f, DUP = 0x50, SWAP = 0x51, - ADDTRIGGER = 0x52, - REMOVETRIGGER = 0x53, - WAIT = 0x54, - ENDWAIT = 0x55, - GETMETHOD = 0x56, - STORELOCAL = 0x57, - PUSHSCOPE = 0x58, - POPSCOPE = 0x59, + EVAL = 0x52, + ADDTRIGGER = 0x53, + REMOVETRIGGER = 0x54, + WAIT = 0x55, + ENDWAIT = 0x56, + GETMETHOD = 0x57, + STORELOCAL = 0x58, + PUSHSCOPE = 0x59, + POPSCOPE = 0x5a, // Augmented bogus placeholder versions of the normal // opcodes: These only exist in the program temporarily @@ -1144,6 +1145,7 @@ public override void Execute(ICpu cpu) DeltaInstructionPointer = (int)functionPointer - currentPointer; var contextRecord = new SubroutineContext(currentPointer+1); cpu.PushAboveStack(contextRecord); + ReverseStackArgs(cpu); } else if (functionPointer is string) { @@ -1163,7 +1165,7 @@ public override void Execute(ICpu cpu) string.Format("kOS internal error: OpcodeCall calling a function described using {0} which is of type {1} and kOS doesn't know how to call that.", functionPointer, functionPointer.GetType().Name) ); } - + if (! Direct) { cpu.PopValue(); // consume function name, branch index, or delegate @@ -1269,6 +1271,26 @@ public static object ExecuteDelegate(ICpu cpu, Delegate dlg) throw; } } + + /// + /// Take the topmost arguments down to the ARG_MARKER_STRING, pop them off, and then + /// put them back again in reversed order so a function can read them in normal order. + /// + public void ReverseStackArgs(ICpu cpu) + { + List args = new List(); + object arg = cpu.PopStack(); + while (arg != null && (!(arg.ToString().Equals(ARG_MARKER_STRING)))) + { + args.Add(arg); + arg = cpu.PopStack(); + } + // Push the arg marker back on again. + cpu.PushStack(ARG_MARKER_STRING); + // Push the arguments back on again, which will invert their order: + foreach (object item in args) + cpu.PushStack(item); + } public override string ToString() { @@ -1289,6 +1311,24 @@ public override void Execute(ICpu cpu) // This should never happen with any user code: throw new Exception( "kOS internal error: Stack misalignment detected when returning from routine."); } + // Return value should be atop the stack - we have to pop it so that + // we can reach the arg start marker under it: + object returnVal = cpu.PopValue(); + + // The next thing on the stack under the return value should be the marker that indicated where + // the parameters started. It should be thrown away now. If the next thing is NOT the marker + // of where the parameters started, that is proof the stack is misaligned, probably because the + // number of args passed didn't match the number of DECLARE PARAMETER statements in the function: + string shouldBeArgMarker = cpu.PopStack() as string; + + if ( (shouldBeArgMarker == null) || (!(shouldBeArgMarker.Equals(OpcodeCall.ARG_MARKER_STRING))) ) + { + throw new KOSArgumentMismatchException("(detected when returning from function)"); + } + // If the proper argument marker was found, then it's all okay, so put the return value + // back, where it belongs, now that the arg start marker was popped off: + cpu.PushStack(returnVal); + var contextRecord = shouldBeContextRecord as SubroutineContext; int destinationPointer = contextRecord.CameFromInstPtr; @@ -1454,6 +1494,24 @@ public override void Execute(ICpu cpu) } } + /// + /// Replaces the topmost thing on the stack with its evaluated, + /// fully dereferenced version. For example, if the variable + /// foo contains value 4, and the top of the stack is the + /// identifier name "$foo", then this will replace the "$foo" + /// with a 4. + /// + public class OpcodeEval : Opcode + { + protected override string Name { get { return "eval"; } } + public override ByteCode Code { get { return ByteCode.EVAL; } } + + public override void Execute(ICpu cpu) + { + cpu.PushStack(cpu.PopValue()); + } + } + /// /// Pushes a new variable namespace scope (for example, when a "{" is encountered /// in a block-scoping language like C++ or Java or C#.) diff --git a/src/kOS.Safe/Exceptions/KOSArgumentMismatchException.cs b/src/kOS.Safe/Exceptions/KOSArgumentMismatchException.cs index d6926b95e..8316b6470 100644 --- a/src/kOS.Safe/Exceptions/KOSArgumentMismatchException.cs +++ b/src/kOS.Safe/Exceptions/KOSArgumentMismatchException.cs @@ -33,6 +33,17 @@ public KOSArgumentMismatchException(int expected, int actual, string message = " expectedNum = expected; actualNum = actual; } + + /// + /// Describe an error in the number of arguments, without knowing the number of args + /// + /// optional message + public KOSArgumentMismatchException(string message = "") : + base( BuildTerseMessage() + " " + message ) + { + expectedNum = 0; + actualNum = 0; + } private static string BuildTerseMessage(int expected, int actual) { @@ -40,6 +51,11 @@ private static string BuildTerseMessage(int expected, int actual) (expected==0?"no":expected.ToString()), (expected==1?"":"s"), (actual==0?"none":actual.ToString()) ); } + + private static string BuildTerseMessage() + { + return String.Format("Number of arguments passed to the function didn't match the number of DECLARE PARAMETERs encountered."); + } private string BuildVerboseMessage() { diff --git a/src/kOS.Safe/Exceptions/KOSReturnInvalidHereException.cs b/src/kOS.Safe/Exceptions/KOSReturnInvalidHereException.cs new file mode 100644 index 000000000..c1c6cae1a --- /dev/null +++ b/src/kOS.Safe/Exceptions/KOSReturnInvalidHereException.cs @@ -0,0 +1,26 @@ +namespace kOS.Safe.Exceptions +{ + /// + /// A version of KOSCommandInvalidHere describing an attempt to use + /// the RETURN command when not in the body of a user function. + /// + public class KOSReturnInvalidHereException : KOSCommandInvalidHere + { + public override string HelpURL + { + get { return "http://ksp-kos.github.io/KOS_DOC/command/flowControl/index.html#RETURN"; } + } + + public override string VerboseMessage { get { return VerbosePrefix + APPEND_TEXT; } } + + private const string APPEND_TEXT = "\n" + + "Because RETURN causes the current user function to quit\n" + + "it doesn't mean anything when it's not inside a\n" + + "user function.\n"; + + public KOSReturnInvalidHereException() : + base("RETURN", "outside a FUNCTION", "in a FUNCTION body") + { + } + } +} \ No newline at end of file diff --git a/src/kOS.Safe/Function/IFunctionManager.cs b/src/kOS.Safe/Function/IFunctionManager.cs index 8fa121d27..1a243698f 100644 --- a/src/kOS.Safe/Function/IFunctionManager.cs +++ b/src/kOS.Safe/Function/IFunctionManager.cs @@ -4,5 +4,6 @@ public interface IFunctionManager { void Load(); void CallFunction(string functionName); + bool Exists(string functionName); } } \ No newline at end of file diff --git a/src/kOS.Safe/kOS.Safe.csproj b/src/kOS.Safe/kOS.Safe.csproj index e557a07db..0658d9836 100644 --- a/src/kOS.Safe/kOS.Safe.csproj +++ b/src/kOS.Safe/kOS.Safe.csproj @@ -107,6 +107,7 @@ + diff --git a/src/kOS/Execution/CPU.cs b/src/kOS/Execution/CPU.cs index d1295bbe0..5230a50c8 100644 --- a/src/kOS/Execution/CPU.cs +++ b/src/kOS/Execution/CPU.cs @@ -969,6 +969,12 @@ public void OnLoad(ConfigNode node) try { SafeHouse.Logger.Log("Parsing Context:\n\n" + scriptBuilder); + + // TODO - make this set up compiler options and pass them in properly, so we can detect built-ins properly. + // (for the compiler to detect the difference between a user function call and a built-in, it needs to be + // passed the FunctionManager object from Shared.) + // this isn't fixed mainly because this OnLoad() code is a major bug fire already anyway and needs to be + // fixed, but that's way out of scope for the moment: programBuilder.AddRange(shared.ScriptHandler.Compile("reloaded file", 1, scriptBuilder.ToString())); List program = programBuilder.BuildProgram(); RunProgram(program, true); diff --git a/src/kOS/Function/FunctionManager.cs b/src/kOS/Function/FunctionManager.cs index c1671e8a6..c38ffbe2c 100644 --- a/src/kOS/Function/FunctionManager.cs +++ b/src/kOS/Function/FunctionManager.cs @@ -45,6 +45,17 @@ public void CallFunction(string functionName) FunctionBase function = functions[functionName]; function.Execute(shared); } + + /// + /// Find out if the function with the name given exists already in the built-in hardcoded functions set + /// (as opposed to the user functions). + /// + /// check if this function exists + /// true if it does exist (as a built-in, not as a user function) + public bool Exists(string functionName) + { + return functions.ContainsKey(functionName); + } } } diff --git a/src/kOS/Function/Misc.cs b/src/kOS/Function/Misc.cs index 53c9e661a..095198c24 100644 --- a/src/kOS/Function/Misc.cs +++ b/src/kOS/Function/Misc.cs @@ -150,7 +150,7 @@ public override void Execute(SharedObjects shared) if (shared.ProcessorMgr != null) { string filePath = string.Format("{0}/{1}", shared.VolumeMgr.GetVolumeRawIdentifier(targetVolume), fileName) ; - var options = new CompilerOptions {LoadProgramsInSameAddressSpace = true}; + var options = new CompilerOptions {LoadProgramsInSameAddressSpace = true, FuncManager = shared.FunctionManager}; List parts = shared.ScriptHandler.Compile(filePath, 1, file.StringContent, "program", options); var builder = new ProgramBuilder(); builder.AddRange(parts); @@ -168,7 +168,7 @@ public override void Execute(SharedObjects shared) // clear the "program" compilation context shared.ScriptHandler.ClearContext("program"); string filePath = shared.VolumeMgr.GetVolumeRawIdentifier(shared.VolumeMgr.CurrentVolume) + "/" + fileName ; - var options = new CompilerOptions {LoadProgramsInSameAddressSpace = true}; + var options = new CompilerOptions {LoadProgramsInSameAddressSpace = true, FuncManager = shared.FunctionManager}; var programContext = ((CPU)shared.Cpu).GetProgramContext(); List codeParts; @@ -230,7 +230,7 @@ public override void Execute(SharedObjects shared) if (shared.ScriptHandler != null) { - var options = new CompilerOptions { LoadProgramsInSameAddressSpace = true }; + var options = new CompilerOptions { LoadProgramsInSameAddressSpace = true, FuncManager = shared.FunctionManager }; string filePath = shared.VolumeMgr.GetVolumeRawIdentifier(shared.VolumeMgr.CurrentVolume) + "/" + fileName; // add this program to the address space of the parent program, // or to a file to save: diff --git a/src/kOS/Screen/Interpreter.cs b/src/kOS/Screen/Interpreter.cs index f9b7420f9..2b2945803 100644 --- a/src/kOS/Screen/Interpreter.cs +++ b/src/kOS/Screen/Interpreter.cs @@ -126,7 +126,8 @@ protected void CompileCommand(string commandText) try { - List commandParts = Shared.ScriptHandler.Compile("interpreter history", commandHistoryIndex, commandText, "interpreter"); + CompilerOptions options = new CompilerOptions { LoadProgramsInSameAddressSpace = false, FuncManager = Shared.FunctionManager }; + List commandParts = Shared.ScriptHandler.Compile("interpreter history", commandHistoryIndex, commandText, "interpreter", options); if (commandParts == null) return; var interpreterContext = ((CPU)Shared.Cpu).GetInterpreterContext(); From ca4244531e22f104fe3ee5b27353338d4fa8f9d2 Mon Sep 17 00:00:00 2001 From: Peter Goddard Date: Wed, 18 Mar 2015 13:37:45 -0400 Subject: [PATCH 304/446] Radial mounted computer Now with meagre solar power! --- .../GameData/kOS/Parts/kOSMachineRad/Model.mu | Bin 0 -> 102399 bytes .../kOS/Parts/kOSMachineRad/colorTexture.mbm | Bin 0 -> 3145748 bytes .../GameData/kOS/Parts/kOSMachineRad/part.cfg | 71 ++++++++++++++++++ 3 files changed, 71 insertions(+) create mode 100644 Resources/GameData/kOS/Parts/kOSMachineRad/Model.mu create mode 100644 Resources/GameData/kOS/Parts/kOSMachineRad/colorTexture.mbm create mode 100755 Resources/GameData/kOS/Parts/kOSMachineRad/part.cfg diff --git a/Resources/GameData/kOS/Parts/kOSMachineRad/Model.mu b/Resources/GameData/kOS/Parts/kOSMachineRad/Model.mu new file mode 100644 index 0000000000000000000000000000000000000000..4c23dbd54ee9281a01ab5b8053ebf9080d2a3f57 GIT binary patch literal 102399 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

    He&l+#I_%Z58fX6qWsYsW4)~2%ewA~ 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Π$9jb21lmCNFP2xEOmeX`AGlR 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

  • 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�rW<9$PXb9?R6CGn`UixW@Z8mP` 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

    @-TJ8t_SMfo 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 P&X+G;&eNq(xw8KUy3Dlj literal 0 HcmV?d00001 diff --git a/Resources/GameData/kOS/Parts/kOSMachineRad/part.cfg b/Resources/GameData/kOS/Parts/kOSMachineRad/part.cfg new file mode 100755 index 000000000..ff0e6a371 --- /dev/null +++ b/Resources/GameData/kOS/Parts/kOSMachineRad/part.cfg @@ -0,0 +1,71 @@ +PART +{ +// --- general parameters --- +name = kOSMachineRad +module = Part +author = Peter Goddard + +// --- asset parameters --- +mesh = model/model.mu +scale = 1 +rescaleFactor = 0.99999999999 +iconCenter = 0, 0, 0 + +// --- node definitions --- +node_attach = 0.0, 0.0, 0.0, 1, 0, 0 + +// --- Tech tree --- +TechRequired = flightControl + +// --- editor parameters --- +cost = 2200 +entryCost = 4200 +category = Control +subcategory = 0 +title = CompoMax Radial Tubeless +manufacturer = Squalid-State Devices Inc. +description = Would you trust life and limb to a mindless autopilot, powered by untested software you hastily wrote yourself? Spacefaring kerbals would! + +// attachment rules: stack, srfAttach, allowStack, allowSrfAttach, allowCollision +attachRules = 0,1,0,0,1 + +// --- standard part parameters --- +mass = 0.00001 +dragModelType = default +maximum_drag = 0.0 +minimum_drag = 0.0 +angularDrag = 0 +crashTolerance = 6 +maxTemp = 3400 + + +MODULE +{ + name = kOSProcessor + diskSpace = 60000 +} +MODULE +{ + name = ModuleDeployableSolarPanel + sunTracking = false + raycastTransformName = suncatcher + pivotName = suncatcher + isBreakable = false + resourceName = ElectricCharge + chargeRate = 0.5 + powerCurve + { + key = 206000000000 0 0 0 + key = 13599840256 1 0 0 + key = 68773560320 0.5 0 0 + key = 0 10 0 0 + } +} +} +RESOURCE +{ + name = ElectricCharge + amount = 10 + maxAmount = 10 +} +} From 9b8a3106934204a6b7d52c4b14e0fba0be40c953 Mon Sep 17 00:00:00 2001 From: Chris Woerz Date: Wed, 18 Mar 2015 13:50:16 -0600 Subject: [PATCH 305/446] attempt to fix part lists --- src/kOS/Suffixed/ResourceTransferValue.cs | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/kOS/Suffixed/ResourceTransferValue.cs b/src/kOS/Suffixed/ResourceTransferValue.cs index 82fa40094..1b2fed993 100644 --- a/src/kOS/Suffixed/ResourceTransferValue.cs +++ b/src/kOS/Suffixed/ResourceTransferValue.cs @@ -317,13 +317,22 @@ private double CalculateAvailableResource(IEnumerable fromParts) switch (type) { case TransferPartType.Part: + { + var partValue = obj as PartValue; parts.Add(partValue.Part); break; + } case TransferPartType.Parts: - var partList = (obj as ListValue).Cast(); - parts.AddRange(partList.Select(part => part.Part)); + { + var listValue = (obj as ListValue); + if (listValue != null) + { + var partValues = listValue.OfType(); + parts.AddRange(partValues.Select(partValue => partValue.Part)); + } break; + } case TransferPartType.Element: var element = obj as ElementValue; var elementParts = element.Parts.Cast(); From f1cd9249275e4f6a69a7139c0642e1e11d5587b2 Mon Sep 17 00:00:00 2001 From: Chris Woerz Date: Wed, 18 Mar 2015 13:56:49 -0600 Subject: [PATCH 306/446] moved in tech tree and increased mass --- Resources/GameData/kOS/Parts/kOSMachineRad/part.cfg | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Resources/GameData/kOS/Parts/kOSMachineRad/part.cfg b/Resources/GameData/kOS/Parts/kOSMachineRad/part.cfg index ff0e6a371..c4f313189 100755 --- a/Resources/GameData/kOS/Parts/kOSMachineRad/part.cfg +++ b/Resources/GameData/kOS/Parts/kOSMachineRad/part.cfg @@ -15,7 +15,7 @@ iconCenter = 0, 0, 0 node_attach = 0.0, 0.0, 0.0, 1, 0, 0 // --- Tech tree --- -TechRequired = flightControl +TechRequired = unmannedTech // --- editor parameters --- cost = 2200 @@ -30,7 +30,7 @@ description = Would you trust life and limb to a mindless autopilot, powered by attachRules = 0,1,0,0,1 // --- standard part parameters --- -mass = 0.00001 +mass = 0.03 dragModelType = default maximum_drag = 0.0 minimum_drag = 0.0 From 626cf37fc3c711b1306bc5510227c90463c021a4 Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Thu, 19 Mar 2015 00:32:18 -0500 Subject: [PATCH 307/446] Made FOR iterator local, and args get dereferenced. Two changes: 1: The iterator $blarg-iterator used behind the scenes in FOR loops was being made in global namespace. Now it's made in a namespace local to the loop (the for loop makes an extra scope just outside the loop's braces scope now as well, just in case the loop body is a singleton statement without local scoping braces). 2: Args were being passed in a way that would break when the function being called was in a different scope than the one doing the calling. This was because the arguments pushed onto the stack were not being dereferenced until being pulled off the stack by the function, at which point the scoping is different and it can't see those variables. Now, when calling a function, as it reverses the stack arguments, it also dereferences any of them that are identifiers and replaces them with their dereferenced value. --- src/kOS.Safe/Compilation/KS/Compiler.cs | 15 +++++++++++++-- src/kOS.Safe/Compilation/Opcode.cs | 19 ++++++++++++++++--- src/kOS/Execution/CPU.cs | 7 +++++-- 3 files changed, 34 insertions(+), 7 deletions(-) diff --git a/src/kOS.Safe/Compilation/KS/Compiler.cs b/src/kOS.Safe/Compilation/KS/Compiler.cs index d10d91c52..b8393f9ae 100644 --- a/src/kOS.Safe/Compilation/KS/Compiler.cs +++ b/src/kOS.Safe/Compilation/KS/Compiler.cs @@ -2266,11 +2266,17 @@ private void VisitForStatement(ParseNode node) string iteratorIdentifier = "$" + GetIdentifierText(node.Nodes[3]) + "-iterator"; PushBreakList(braceNestLevel); + + // Add a scope level to hold the iterator variable. This will live just "outside" the + // brace scope of the function body. + ++braceNestLevel; + AddOpcode(new OpcodePushScope()); + AddOpcode(new OpcodePush(iteratorIdentifier)); VisitNode(node.Nodes[3]); AddOpcode(new OpcodePush("iterator")); AddOpcode(new OpcodeGetMember()); - AddOpcode(new OpcodeStore()); + AddOpcode(new OpcodeStoreLocal()); // loop condition Opcode condition = AddOpcode(new OpcodePush(iteratorIdentifier)); string conditionLabel = condition.Label; @@ -2284,7 +2290,7 @@ private void VisitForStatement(ParseNode node) AddOpcode(new OpcodePush(iteratorIdentifier)); AddOpcode(new OpcodePush("value")); AddOpcode(new OpcodeGetMember()); - AddOpcode(new OpcodeStore()); + AddOpcode(new OpcodeStoreLocal()); // instructions in FOR body VisitNode(node.Nodes[4]); // jump to condition @@ -2300,6 +2306,11 @@ private void VisitForStatement(ParseNode node) AddOpcode(new OpcodeUnset()); VisitVariableNode(node.Nodes[1]); AddOpcode(new OpcodeUnset()); + + // End the scope level holding the iterator variable: + --braceNestLevel; + AddOpcode(new OpcodePopScope()); + PopBreakList(endLoop.Label); nowInALoop = remember; diff --git a/src/kOS.Safe/Compilation/Opcode.cs b/src/kOS.Safe/Compilation/Opcode.cs index faa6bee4a..94a816bd2 100644 --- a/src/kOS.Safe/Compilation/Opcode.cs +++ b/src/kOS.Safe/Compilation/Opcode.cs @@ -1141,14 +1141,17 @@ public override void Execute(ICpu cpu) if (functionPointer is int) { + ReverseStackArgs(cpu); int currentPointer = cpu.InstructionPointer; DeltaInstructionPointer = (int)functionPointer - currentPointer; var contextRecord = new SubroutineContext(currentPointer+1); cpu.PushAboveStack(contextRecord); - ReverseStackArgs(cpu); } else if (functionPointer is string) { + // Built-ins don't need to dereference the stack values because they + // don't leave the scope - they're not implemented that way. But later we + // might want to change that. var name = functionPointer as string; string functionName = name; functionName = functionName.Substring(0, functionName.Length - 2); @@ -1279,11 +1282,21 @@ public static object ExecuteDelegate(ICpu cpu, Delegate dlg) public void ReverseStackArgs(ICpu cpu) { List args = new List(); - object arg = cpu.PopStack(); + object arg = cpu.PopValue(); while (arg != null && (!(arg.ToString().Equals(ARG_MARKER_STRING)))) { args.Add(arg); - arg = cpu.PopStack(); + + // It's important to dereference with PopValue, not using PopStack, because the function + // being called might not even be able to see the variable in scope anyway. + // In other words, if calling a function like so: + // declare foo to 3. + // myfunc(foo). + // The code inside myfunc needs to see that as being identical to just saying: + // myfunc(3). + // It has to be unaware of the fact that the name of the argument was 'foo'. It just needs to + // see the contents that were inside foo. + arg = cpu.PopValue(); } // Push the arg marker back on again. cpu.PushStack(ARG_MARKER_STRING); diff --git a/src/kOS/Execution/CPU.cs b/src/kOS/Execution/CPU.cs index 5230a50c8..0f72a5487 100644 --- a/src/kOS/Execution/CPU.cs +++ b/src/kOS/Execution/CPU.cs @@ -426,10 +426,13 @@ public string DumpVariables() foreach (string ident in globalVariables.Keys) { string line; - try { + try + { Variable v = globalVariables[ident]; line = ident; - line += v.Value == null ? "= " : "= " + v.Value; + line += " is a " + v.Value.GetType().FullName; + line += " with value = "; + line += v.Value == null ? "" : "" + v.Value; } catch (Exception e) { From 791d5125eeb48b7684bba7f37fee3b9fc96227e6 Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Thu, 19 Mar 2015 00:40:25 -0500 Subject: [PATCH 308/446] Removed some debug printing. --- src/kOS.Safe/Compilation/KS/Compiler.cs | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/src/kOS.Safe/Compilation/KS/Compiler.cs b/src/kOS.Safe/Compilation/KS/Compiler.cs index b8393f9ae..d709956ca 100644 --- a/src/kOS.Safe/Compilation/KS/Compiler.cs +++ b/src/kOS.Safe/Compilation/KS/Compiler.cs @@ -1027,7 +1027,6 @@ private void VisitActualFunction(ParseNode node, bool isDirect, bool isUserFunc, { NodeStartHousekeeping(node); - Console.WriteLine("eraseme: kOS: VisitActualFunction, isDirect="+isDirect+", directName="+directName); int parameterCount = 0; ParseNode trailerNode = node; // the function_trailer rule is here. @@ -1128,54 +1127,43 @@ private void VisitSuffix(ParseNode node) string firstIdentifier = ""; bool isUserFunc = false; - Console.WriteLine("eraseme: kOS: VisitSuffix, A"); if (nodeIndex == 0) { - Console.WriteLine("eraseme: kOS: VisitSuffix, B"); firstIdentifier = GetIdentifierText(suffixTerm); if (context.Locks.Contains(firstIdentifier)) { - Console.WriteLine("eraseme: kOS: VisitSuffix, C"); Lock lockObject = context.Locks.GetLock(firstIdentifier); firstIdentifier = lockObject.PointerIdentifier; isUserFunc = true; } } - Console.WriteLine("eraseme: kOS: VisitSuffix, D"); // The term starts with either an identifier or an expression. If it's the start, then parse // it as a variable, else parse it as a raw identifier: bool rememberIsV = identifierIsVariable; identifierIsVariable = (!startsWithFunc) && nodeIndex == 0; // Push this term on the stack unless it's the name of the user function or built-in function: bool isDirect = true; - Console.WriteLine("eraseme: kOS: VisitSuffix, E"); if ( (!isUserFunc) && (nodeIndex > 0 || !startsWithFunc) ) { - Console.WriteLine("eraseme: kOS: VisitSuffix, F"); VisitNode(suffixTerm.Nodes[0]); isDirect = false; } - Console.WriteLine("eraseme: kOS: VisitSuffix, G"); identifierIsVariable = rememberIsV; if (nodeIndex != 0) { - Console.WriteLine("eraseme: kOS: VisitSuffix, H"); // when we are setting a member value we need to leave // the last object and the last suffix in the stack bool usingSetMember = (suffixTerm.Nodes.Count > 0) && (compilingSetDestination && nodeIndex == (node.Nodes.Count - 1)); if (!usingSetMember) { - Console.WriteLine("eraseme: kOS: VisitSuffix, I"); AddOpcode(startsWithFunc ? new OpcodeGetMethod() : new OpcodeGetMember()); } } - Console.WriteLine("eraseme: kOS: VisitSuffix, isDirect="+isDirect+", firstIdentifier="+firstIdentifier); // The remaining terms are a chain of function_trailers "(...)" and array_trailers "[...]" or "#.." in any arbitrary order: for (int trailerIndex = 1; trailerIndex < suffixTerm.Nodes.Count; ++trailerIndex) { - Console.WriteLine("eraseme: kOS: VisitSuffix, J"); // suffixterm_trailer is always a wrapper around either function_trailer or array_trailer, // so delve down one level to get which of them it is: ParseNode trailerTerm = suffixTerm.Nodes[trailerIndex].Nodes[0]; @@ -1184,14 +1172,12 @@ private void VisitSuffix(ParseNode node) if (isFunc || isUserFunc) { - Console.WriteLine("eraseme: kOS: VisitSuffix, K"); // direct if it's just one term like foo(aaa) but indirect // if it's a list of suffixes like foo:bar(aaa): VisitActualFunction(trailerTerm, isDirect, isUserFunc, firstIdentifier); } if (isArray) { - Console.WriteLine("eraseme: kOS: VisitSuffix, L"); VisitActualArray(trailerTerm); } } @@ -1390,10 +1376,8 @@ private void VisitIdentifier(ParseNode node) bool isVariable = (identifierIsVariable && !identifierIsSuffix); string prefix = isVariable ? "$" : String.Empty; string identifier = GetIdentifierText(node); - Console.WriteLine("eraseme: kOS: VisitIdentifier called, on identifier " + identifier ); if (isVariable && context.Locks.Contains(identifier)) { - Console.WriteLine("eraseme: kOS: It thinks it is an identifier."); Lock lockObject = context.Locks.GetLock(identifier); if (compilingSetDestination) { @@ -1770,10 +1754,6 @@ private void VisitInstructionBlock(ParseNode node) /// private void AddFunctionJumpVars(ParseNode node) { - Console.WriteLine("eraseme: AddFunctionJumpVars("+((node==null)?"null":node.Token.Type.ToString())+"), when locks is size = " + (context.Locks == null ? -1 : context.Locks.GetLockList().Count())); - /*eraseme*/ foreach ( Lock l in context.Locks.GetLockList()) { - /*eraseme*/ Console.WriteLine(" " + (l.Identifier ?? "null") + ", IsFunction=" + l.IsFunction + ", ScopeNode=" + (l.ScopeNode == null ? "null" : l.ScopeNode.Token.Type.ToString())); - /*eraseme*/ } // All the functions for which this scope is where they live: IEnumerable theseFuncs = context.Locks.GetLockList().Where((item) => item.IsFunction && item.ScopeNode == node); From 065b65a3d47278a0ce4ac6ba538ec923a23064b4 Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Thu, 19 Mar 2015 01:37:31 -0500 Subject: [PATCH 309/446] Made some initial changelog notes for this PR. These changelog edits will become true when the PR is merged. --- CHANGELOG.md | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e54a48bb9..ee0e6a68d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,79 @@ kOS Mod Changelog ================= +# v0.17.0 + +FUNCTIONS! FUNCTIONS! FUNCTIONS! +-------------------------------- +Big feature: You can make your own user-defined functions. + +###BREAKING: +- *DECLARE has a new syntax* + DECLARE _VARNAME_ now requires an initializier syntax as follows: + - DECLARE _VARNAME_ TO _VALUE_. + If you leave the TO _VALUE_ off, it will now be a syntax error. + The Kerobscript language used to leave it unspecified what the value + of a variable that has been declared but not set was. This gets rid + of that ambiguity. +- *DECLAREd variables are now local* + Using the DECLARE _VARNAME_ TO _VALUE_ statement now causes the + variable to have local scope that only exists within the local block + of curly braces ('{'...'}') that it was declared inside of. Once you + leave that block of braces, the variable doesn't exist anymore. +- *FOR iterator now is local* + The _VARIABLE_ in loops of the form FOR _VARIABLE_ IN _SOMELIST_ now + has local scope to just that loop, meaning it stops existing after + the loop is done and you can't use it outside the loop's body. + +###New Features: +- *FUNCTIONS* + It's been a long time coming, but finally the addition + of the new DECLARE FUNCTION statement now allows you to make your + own user functions you can call, which you can use to help build + your own library of common routines. + Synopsis:: + + // Silly example function to build a string of padded chars. + DECLARE FUNCTION padString { + DECLARE PARAMETER ch, howmany + + DECLARE str to "". // makes str a local variable. + + UNTIL howmany <= 0 { + set str to str + ch. + set howmany to howmany - 1. + } + RETURN str. + } + set twentySpaces to padString(" ", 20). + set threeX to padString("X", 3). + + For the full documentation, see: + http://ksp-kos.github.io/KOS/language/user_functions.html + +- *VARIABLE SCOPING (LOCALS)* + It used to be the case that all variables were global and there was + no such thing as a local variable. As part of getting functions to + work, we also implemented some local scoping rules. + Synopsis:: + + Kerboscript now uses block scoping, local to the brace scope the variable was declared inside of. + Local vars are declared with the DECLARE..TO statement. + Variables made implicitly by "lazy" use of SET will still be global like they always have been. + + The exact means of making a variable local is described here: + http://ksp-kos.github.io/KOS/language/variables.html#declare-to + and here: + http://ksp-kos.github.io/KOS/language/variables.html#scoping-rules + +###Bug Fixes: +- For iterator no longer name clashes because it's not global anymore. + It used to be that if you had two FOR _VAR_ IN _THING_'s in the same + program, and both used the same name for their _VAR_, they could + interfere and clash in strange ways because they were using the same + global variable. Now the iterator _VAR_ is local to the loop and + no longer exists outside the loop. + # v0.16.2 ##HOTFIX From 1ae448383b203823765f81f018d898e854be15d1 Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Sun, 22 Mar 2015 16:54:10 -0500 Subject: [PATCH 310/446] Implemented lexical scoping with nested functions. --- src/kOS.Safe/Compilation/KS/Compiler.cs | 131 +++++++++++++++++--- src/kOS.Safe/Compilation/KS/Context.cs | 10 ++ src/kOS.Safe/Compilation/KS/Scope.cs | 21 ++++ src/kOS.Safe/Compilation/Opcode.cs | 42 ++++++- src/kOS.Safe/Execution/VariableScope.cs | 44 +++++++ src/kOS.Safe/kOS.Safe.csproj | 2 + src/kOS/Execution/CPU.cs | 154 +++++++++++++++++------- src/kOS/Execution/Stack.cs | 38 +++++- 8 files changed, 378 insertions(+), 64 deletions(-) create mode 100644 src/kOS.Safe/Compilation/KS/Scope.cs create mode 100644 src/kOS.Safe/Execution/VariableScope.cs diff --git a/src/kOS.Safe/Compilation/KS/Compiler.cs b/src/kOS.Safe/Compilation/KS/Compiler.cs index d709956ca..65c36c1f9 100644 --- a/src/kOS.Safe/Compilation/KS/Compiler.cs +++ b/src/kOS.Safe/Compilation/KS/Compiler.cs @@ -26,7 +26,10 @@ class Compiler private bool identifierIsSuffix; private bool nowInALoop; private bool needImplicitReturn; - private int braceNestLevel; + private bool nextBraceIsFunction; + private Int16 braceNestLevel; + private readonly List scopeStack = new List(); + private readonly Dictionary scopeMap = new Dictionary(); private readonly List programParameters = new List(); private CompilerOptions options; private const bool TRACE_PARSE = false; // set to true to Debug Log each ParseNode as it's visited. @@ -60,6 +63,9 @@ private void InitCompileFlags() nowInALoop = false; needImplicitReturn = true; braceNestLevel = 0; + nextBraceIsFunction = false; + scopeStack.Clear(); + scopeMap.Clear(); programParameters.Clear(); } @@ -76,6 +82,7 @@ public CodePart Compile(int startLineNum, ParseTree tree, Context context, Compi { if (tree.Nodes.Count > 0) { + TraverseScopeBranch(tree.Nodes[0]); PreProcess(tree); CompileProgram(tree); } @@ -196,6 +203,14 @@ private void IterateLocks(ParseNode node, Action action) // case TokenType.lock_stmt: case TokenType.declare_stmt: // for DECLARE FUNCTION's + // for catching functions nested inside functions, or locks nested inside functions: + // Depth-first: Walk my children first, then iterate through me. Thus the functions nested inside + // me have already been compiled before I start compiling my own code. This allows my code to make + // forward-calls into my nested functions, because they've been compiled and we know where they live + // in memory now. + foreach (ParseNode childNode in node.Nodes) + IterateLocks(childNode, action); + action.Invoke(node); break; } @@ -469,10 +484,10 @@ private void PreProcessLockStatement(ParseNode node) // lock expression's or function body's code currentCodeSection = lockObject.GetLockFunction(expressionHash); if (isDefFunc) - PushReturnList(); + nextBraceIsFunction = true; VisitNode(bodyNode); if (isDefFunc) - PopReturnList(); + nextBraceIsFunction = false; if (needImplicitReturn) { if (isDefFunc) @@ -650,6 +665,93 @@ private int GetReturnNestLevel() { return (returnList.Count > 0) ? returnList.Last() : -1; } + + /// + /// Insert the Opcode to start a new lexical scope, handling the parent id mapping. + /// Call upon every open brace "{" + /// + private void BeginScope(ParseNode node) + { + // walk up parse tree until a node with a scope is found: + while (node != null && !scopeMap.ContainsKey(node)) + node = node.Parent; + + // defaults if the node isn't found: + Int16 scopeId = 0; + Int16 parentScopeId = 0; + braceNestLevel = 0; + + if (node != null) + { + Scope thisScope = scopeMap[node]; + scopeId = thisScope.ScopeId; + parentScopeId = thisScope.ParentScopeId; + braceNestLevel = thisScope.NestDepth; + } + AddOpcode(new OpcodePushScope(scopeId, parentScopeId)); + } + + /// + /// Insert the Opcode to finish a lexical scope + /// Call upon every close brace "}" + /// + private void EndScope(ParseNode node) + { + node = node.Parent; + + // Walk up parse tree starting with my parent, until a node with a scope is found. + // The goal here is to get the scope one level outside the current scope. + while (node != null && ! scopeMap.ContainsKey(node)) + node = node.Parent; + if (node != null) + { + Scope thisScope = scopeMap[node]; + braceNestLevel = thisScope.NestDepth; + } + else + { + braceNestLevel = 0; + } + + AddOpcode(new OpcodePopScope()); + } + + /// + /// Because the compile occurs a bit out of order (doing the most deeply nested function + /// first, then working out from there) it walks the scope nesting in the wrong order. + /// Therefore before doing the complie, run through in one pass just recording the nesting + /// levels and lexical parent tree of the scoping before we begin, so we can + /// use that information later in the parse: + /// + /// + private void TraverseScopeBranch(ParseNode node) + { + switch (node.Token.Type) + { + // List all the types of parse node that open a new variable scope here: + // --------------------------------------------------------------------- + case TokenType.for_stmt: // Here because it wraps the body inside an outer scope that holds the for-iterator variable. + case TokenType.instruction_block: + + ++braceNestLevel; + Int16 parentId = ( (scopeStack.Count == 0) ? (Int16)0 : scopeStack.Last() ); + scopeStack.Add(++context.MaxScopeIdSoFar); + scopeMap[node] = new Scope(context.MaxScopeIdSoFar, parentId, braceNestLevel); + + foreach (ParseNode childNode in node.Nodes) + TraverseScopeBranch(childNode); + + --braceNestLevel; + if (scopeStack.Count > 0) + scopeStack.RemoveAt(scopeStack.Count-1); + break; + + default: + foreach (ParseNode childNode in node.Nodes) + TraverseScopeBranch(childNode); + break; + } + } private void VisitNode(ParseNode node) { @@ -1739,12 +1841,15 @@ private void VisitComparator(ParseNode node) private void VisitInstructionBlock(ParseNode node) { - ++braceNestLevel; - AddOpcode(new OpcodePushScope()); + NodeStartHousekeeping(node); + BeginScope(node); + if (nextBraceIsFunction) + PushReturnList(); AddFunctionJumpVars(node); VisitChildNodes(node); - AddOpcode(new OpcodePopScope()); - --braceNestLevel; + if (nextBraceIsFunction) + PopReturnList(); + EndScope(node); } /// @@ -2185,9 +2290,9 @@ private void VisitReturnStatement(ParseNode node) { NodeStartHousekeeping(node); - int nestLevelJustOutsideFuncBraces = GetReturnNestLevel(); + int nestLevelOfFuncBraces = GetReturnNestLevel(); - if (nestLevelJustOutsideFuncBraces < 0) + if (nestLevelOfFuncBraces < 0) throw new KOSReturnInvalidHereException(); // Push the return expression onto the stack, or if it was a naked RETURN @@ -2207,7 +2312,7 @@ private void VisitReturnStatement(ParseNode node) // simpler than the BREAK case because RETURN already knows to use the function // call stack to figure out where to return to, so we don't have to wait until // later to decide where to jump to like we do in BREAK: - AddOpcode(new OpcodePopScope(braceNestLevel - nestLevelJustOutsideFuncBraces)); + AddOpcode(new OpcodePopScope(1 + braceNestLevel - nestLevelOfFuncBraces)); AddOpcode(new OpcodeReturn()); } @@ -2249,8 +2354,7 @@ private void VisitForStatement(ParseNode node) // Add a scope level to hold the iterator variable. This will live just "outside" the // brace scope of the function body. - ++braceNestLevel; - AddOpcode(new OpcodePushScope()); + BeginScope(node); AddOpcode(new OpcodePush(iteratorIdentifier)); VisitNode(node.Nodes[3]); @@ -2288,8 +2392,7 @@ private void VisitForStatement(ParseNode node) AddOpcode(new OpcodeUnset()); // End the scope level holding the iterator variable: - --braceNestLevel; - AddOpcode(new OpcodePopScope()); + EndScope(node); PopBreakList(endLoop.Label); diff --git a/src/kOS.Safe/Compilation/KS/Context.cs b/src/kOS.Safe/Compilation/KS/Context.cs index d6ff4ac68..2cd6f1e33 100644 --- a/src/kOS.Safe/Compilation/KS/Context.cs +++ b/src/kOS.Safe/Compilation/KS/Context.cs @@ -1,3 +1,5 @@ +using System; + namespace kOS.Safe.Compilation.KS { public class Context @@ -7,6 +9,13 @@ public class Context public SubprogramCollection Subprograms { get; private set; } public int LabelIndex { get; set; } public string LastSourceName { get; set; } + + // This has to live inside context because of the fact that more than one program + // can be compiled into the same memory space. If it was reset to zero by the + // Compile action, then when one program ran another program, it would give + // ScopeId clashes between them as they'd both live in memory together and one + // might call the functions of the other. + public Int16 MaxScopeIdSoFar { get; set; } public Context() { @@ -15,6 +24,7 @@ public Context() Subprograms = new SubprogramCollection(); LabelIndex = 0; LastSourceName = ""; + MaxScopeIdSoFar = 0; } } diff --git a/src/kOS.Safe/Compilation/KS/Scope.cs b/src/kOS.Safe/Compilation/KS/Scope.cs new file mode 100644 index 000000000..2de60c85b --- /dev/null +++ b/src/kOS.Safe/Compilation/KS/Scope.cs @@ -0,0 +1,21 @@ +using System; + +namespace kOS.Safe.Compilation.KS +{ + /// + /// Nothing more than a simple set of data for remembering what scope level a part of the parse + /// tree is at, so that data can be used in a later pass of the compiler. + /// + public class Scope + { + public Int16 ScopeId {get;set;} + public Int16 ParentScopeId {get;set;} + public Int16 NestDepth {get;set;} + public Scope( Int16 scopeId, Int16 parentScopeId, Int16 nestDepth) + { + ScopeId = scopeId; + ParentScopeId = parentScopeId; + NestDepth = nestDepth; + } + } +} diff --git a/src/kOS.Safe/Compilation/Opcode.cs b/src/kOS.Safe/Compilation/Opcode.cs index 94a816bd2..eda18b28b 100644 --- a/src/kOS.Safe/Compilation/Opcode.cs +++ b/src/kOS.Safe/Compilation/Opcode.cs @@ -1533,13 +1533,53 @@ public override void Execute(ICpu cpu) /// public class OpcodePushScope : Opcode { + [MLField(1,true)] + public Int16 ScopeId {get;set;} + [MLField(2,true)] + public Int16 ParentScopeId {get;set;} + + /// + /// Push a scope frame that knows the id of its lexical parent scope. + /// + /// the unique id of this scope frame. + /// the unique id of the scope frame this scope is inside of. + public OpcodePushScope(Int16 id, Int16 parentId) + { + ScopeId = id; + ParentScopeId = parentId; + } + + /// + /// This variant of the constructor is just for ML file save/load to use. + /// + protected OpcodePushScope() + { + ScopeId = -1; + ParentScopeId = -1; + } + + public override void PopulateFromMLFields(List fields) + { + // Expect fields in the same order as the [MLField] properties of this class: + if (fields == null || fields.Count<2) + throw new Exception("Saved field in ML file for OpcodePushScope seems to be missing. Version mismatch?"); + ScopeId = (Int16)( fields[0] ); + ParentScopeId = (Int16)( fields[1] ); + } + protected override string Name { get { return "pushscope"; } } public override ByteCode Code { get { return ByteCode.PUSHSCOPE; } } public override void Execute(ICpu cpu) { - cpu.PushAboveStack(new Dictionary()); + cpu.PushAboveStack(new VariableScope(ScopeId,ParentScopeId)); + } + + public override string ToString() + { + return String.Format("{0} {1} {2}", Name, ScopeId, ParentScopeId); } + } /// diff --git a/src/kOS.Safe/Execution/VariableScope.cs b/src/kOS.Safe/Execution/VariableScope.cs new file mode 100644 index 000000000..a139b31a6 --- /dev/null +++ b/src/kOS.Safe/Execution/VariableScope.cs @@ -0,0 +1,44 @@ +using System; +using System.Collections.Generic; + +namespace kOS.Safe.Execution +{ + /// + /// A VariableScope Object is a dictionary mapping a variable name to + /// a variable's contents. It contains an id and a parent id that are + /// used to remember the lexical scoping, which may differ from the + /// runtime scoping when subroutines call other subroutines, jumping to + /// sibling scoping levels. + /// + public class VariableScope + { + /// + /// A unique ID of this variable scope object + /// An ID of 0 means global. + /// + public Int16 ScopeId {get;set;} + + /// + /// The unique ID of this variable scope's parent scope. + /// An ID of 0 means global. + /// + public Int16 ParentScopeId {get;set;} + + /// + /// Once the ParentId has been used once to detect which VaraibleScope + /// is the parent of this scope, you can store the result here so you + /// can jump there quicker next time without scanning the scope stack. + /// + public Int16 ParentSkipLevels {get;set;} + + public Dictionary Variables; + + public VariableScope(Int16 scopeId, Int16 parentScopeId) + { + ScopeId = scopeId; + ParentScopeId = parentScopeId; + ParentSkipLevels = 1; // the default case is to just move one stack level. + Variables = new Dictionary(); + } + } +} diff --git a/src/kOS.Safe/kOS.Safe.csproj b/src/kOS.Safe/kOS.Safe.csproj index 0658d9836..1057e34ae 100644 --- a/src/kOS.Safe/kOS.Safe.csproj +++ b/src/kOS.Safe/kOS.Safe.csproj @@ -49,6 +49,7 @@ + @@ -116,6 +117,7 @@ + diff --git a/src/kOS/Execution/CPU.cs b/src/kOS/Execution/CPU.cs index 0f72a5487..9415bb254 100644 --- a/src/kOS/Execution/CPU.cs +++ b/src/kOS/Execution/CPU.cs @@ -23,14 +23,14 @@ private enum Status } private readonly Stack stack; - private readonly Dictionary globalVariables; + private readonly VariableScope globalVariables; private Status currentStatus; private double currentTime; private double timeWaitUntil; private readonly SharedObjects shared; private readonly List contexts; private ProgramContext currentContext; - private Dictionary savedPointers; + private VariableScope savedPointers; private int instructionsSoFarInUpdate; private int instructionsPerUpdate; @@ -56,7 +56,7 @@ public CPU(SharedObjects shared) this.shared = shared; this.shared.Cpu = this; stack = new Stack(); - globalVariables = new Dictionary(); + globalVariables = new VariableScope(0, -1); contexts = new List(); if (this.shared.UpdateHandler != null) this.shared.UpdateHandler.AddObserver(this); } @@ -70,10 +70,10 @@ public void Boot() currentStatus = Status.Running; currentTime = 0; timeWaitUntil = 0; - // clear stack + // clear stack (which also orphans all local variables so they can get garbage collected) stack.Clear(); - // clear variables - globalVariables.Clear(); + // clear global variables + globalVariables.Variables.Clear(); // clear interpreter if (shared.Interpreter != null) shared.Interpreter.Reset(); // load functions @@ -236,29 +236,43 @@ public Opcode GetOpcodeAt(int instructionPtr) private void SaveAndClearPointers() { - savedPointers = new Dictionary(); - var pointers = new List(globalVariables.Keys.Where(v => v.Contains('*'))); + // To be honest, I'm a little afraid of this. It appears to be doing + // something with locks (and now user functions) whenever you + // switch contexts from interpreter to program and it seems to be + // presuming the only such pointers that need to exist are going to be + // global. This was written by marianoapp before I added locals, + // and I don't understand what it's for -- Dunbaratu + + savedPointers = new VariableScope(0,-1); + var pointers = new List(globalVariables.Variables.Keys.Where(v => v.Contains('*'))); foreach (var pointerName in pointers) { - savedPointers.Add(pointerName, globalVariables[pointerName]); - globalVariables.Remove(pointerName); + savedPointers.Variables.Add(pointerName, globalVariables.Variables[pointerName]); + globalVariables.Variables.Remove(pointerName); } SafeHouse.Logger.Log(string.Format("Saving and removing {0} pointers", pointers.Count)); } private void RestorePointers() { + // To be honest, I'm a little afraid of this. It appears to be doing + // something with locks (and now user functions) whenever you + // switch contexts from program to interpreter and it seems to be + // presuming the only such pointers that need to exist are going to be + // global. This was written by marianoapp before I added locals, + // and I don't understand what it's for -- Dunbaratu + int restoredPointers = 0; int deletedPointers = 0; - foreach (var item in savedPointers) + foreach (var item in savedPointers.Variables) { - if (globalVariables.ContainsKey(item.Key)) + if (globalVariables.Variables.ContainsKey(item.Key)) { // if the pointer exists it means it was redefined from inside a program // and it's going to be invalid outside of it, so we remove it - globalVariables.Remove(item.Key); + globalVariables.Variables.Remove(item.Key); deletedPointers++; // also remove the corresponding trigger if exists if (item.Value.Value is int) @@ -266,7 +280,7 @@ private void RestorePointers() } else { - globalVariables.Add(item.Key, item.Value); + globalVariables.Variables.Add(item.Key, item.Value); restoredPointers++; } } @@ -345,44 +359,96 @@ public void MoveStackPointer(int delta) /// /// how far down the peek under the top. 0 = localmost. /// The dictionary found, or the global dictionary if peekDepth is too big. - private Dictionary GetNestedDictionary(int peekDepth) + private VariableScope GetNestedDictionary(int peekDepth) { object stackItem = true; // any non-null value will do here, just to get the loop started. for (int rawStackDepth = 0 ; stackItem != null && peekDepth >= 0; ++rawStackDepth) { stackItem = stack.Peek(-1 - rawStackDepth); - if (stackItem is Dictionary) + if (stackItem is VariableScope) --peekDepth; if (stackItem is SubroutineContext) stackItem = null; // once we hit the bottom of the current subroutine on the runtime stack - jump all the way out to global. } - return stackItem == null ? globalVariables : (Dictionary) stackItem; + return stackItem == null ? globalVariables : (VariableScope) stackItem; } /// /// Gets the dictionary that contains the given identifer, starting the /// search at the local level and scanning the scopes upward all the /// way to the global dictionary.
    - /// Does not allow the walk to go past the start of the current function scope.
    + /// Does not allow the walk to use scope frames that were not directly in this + /// scope's lexical chain. It skips over scope frames from other braches + /// of the parse tree. (i.e. if a function calls a function elsewhere).
    /// Returns null when no hit was found.
    ///
    /// identifer name to search for /// The dictionary found, or null if no dictionary contins the identifier. - private Dictionary GetNestedDictionary(string identifier) + private VariableScope GetNestedDictionary(string identifier) { - for (int rawStackDepth = 0 ; true /*all loop exits are explicit break or return stmts*/ ; ++rawStackDepth) + Int16 rawStackDepth = 0 ; + while (true) /*all of this loop's exits are explicit break or return stmts*/ { - object stackItem = stack.Peek(-1 - rawStackDepth); - if (stackItem == null) + object stackItem; + bool stackExhausted = !(stack.PeekCheck(-1 - rawStackDepth, out stackItem)); + if (stackExhausted) break; - Dictionary localDict = stackItem as Dictionary; - if (localDict != null) - if (localDict.ContainsKey(identifier)) - return localDict; - if (stackItem is SubroutineContext) - break; // once we hit the bottom of the current subroutine on the runtime stack - jump all the way out to global. + VariableScope localDict = stackItem as VariableScope; + if (localDict == null) // some items on the stack might not be variable scopes. skip them. + { + ++rawStackDepth; + continue; + } + + if (localDict.Variables.ContainsKey(identifier)) + return localDict; + + + // Get the next VariableScope that is the lexical (not runtime) parent of this one: + // ------------------------------------------------------------------------------- + + // Scan the stack until the variable scope with the right parent ID is seen: + Int16 skippedLevels = 0; + while ( !(stackExhausted)) + { + bool needsIncrement = true; + VariableScope scopeFrame = stackItem as VariableScope; + if (scopeFrame != null) // skip cases where the thing on the stack isn't a variable scope. + { + // If the scope id of this frame is my parent ID, then we found it and are done. + if (scopeFrame.ScopeId == localDict.ParentScopeId) + { + needsIncrement = false; + break; + } + + // In the case where the variable scope is the SAME lexical ID as myself, that + // means I recursively called myself and the thing on the runtime stack just before + // me is ... another instance of me. In that case just follow it's parent skip level + if (scopeFrame.ScopeId == localDict.ScopeId && scopeFrame.ParentSkipLevels > 0) + { + skippedLevels += scopeFrame.ParentSkipLevels; + rawStackDepth += scopeFrame.ParentSkipLevels; + needsIncrement = false; + } + } + + if (needsIncrement) + { + ++skippedLevels; + ++rawStackDepth; + } + stackExhausted = !(stack.PeekCheck(-1 - rawStackDepth, out stackItem)); + } + + // Record how many levels had to be skipped for that to work. In future calls of this + // method, it will know how far to jump in the stack without doing that scan. This can + // be quite a speedup when dealing with nested recursion, where the runtime stack might + // be a hundred levels deep of the same function calling itself before hitting its lexical parent. + if (stackItem != null && localDict.ParentSkipLevels == 0) + localDict.ParentSkipLevels = skippedLevels; } - if (globalVariables.ContainsKey(identifier)) + if (globalVariables.Variables.ContainsKey(identifier)) return globalVariables; else return null; @@ -423,12 +489,12 @@ public string DumpVariables() msg.AppendLine("============== STACK VARIABLES ==============="); msg.AppendLine(stack.Dump()); msg.AppendLine("============== GLOBAL VARIABLES =============="); - foreach (string ident in globalVariables.Keys) + foreach (string ident in globalVariables.Variables.Keys) { string line; try { - Variable v = globalVariables[ident]; + Variable v = globalVariables.Variables[ident]; line = ident; line += " is a " + v.Value.GetType().FullName; line += " with value = "; @@ -459,9 +525,9 @@ public string DumpVariables() private Variable GetVariable(string identifier, bool barewordOkay = false, bool failOkay = false) { identifier = identifier.ToLower(); - Dictionary foundDict = GetNestedDictionary(identifier); + VariableScope foundDict = GetNestedDictionary(identifier); if (foundDict != null) - return foundDict[identifier]; + return foundDict.Variables[identifier]; if (barewordOkay) { string strippedIdent = identifier.TrimStart('$'); @@ -490,19 +556,19 @@ public void AddVariable(Variable variable, string identifier, bool local) identifier = "$" + identifier; } - Dictionary whichDict; + VariableScope whichDict; if (local) whichDict = GetNestedDictionary(0); else whichDict = globalVariables; - if (whichDict.ContainsKey(identifier)) + if (whichDict.Variables.ContainsKey(identifier)) { - if (whichDict[identifier].Value is BoundVariable) + if (whichDict.Variables[identifier].Value is BoundVariable) throw new KOSIdentiferClashException(identifier); else - whichDict.Remove(identifier); + whichDict.Variables.Remove(identifier); } - whichDict.Add(identifier, variable); + whichDict.Variables.Add(identifier, variable); } public bool VariableIsRemovable(Variable variable) @@ -520,14 +586,14 @@ public bool VariableIsRemovable(Variable variable) public void RemoveVariable(string identifier) { identifier = identifier.ToLower(); - Dictionary foundDict = GetNestedDictionary(identifier); - if (foundDict != null && VariableIsRemovable(foundDict[identifier])) + VariableScope foundDict = GetNestedDictionary(identifier); + if (foundDict != null && VariableIsRemovable(foundDict.Variables[identifier])) { // Tell Variable to orphan its old value now. Faster than relying // on waiting several seconds for GC to eventually call ~Variable() - foundDict[identifier].Value = null; + foundDict.Variables[identifier].Value = null; - foundDict.Remove(identifier); + foundDict.Variables.Remove(identifier); } } @@ -913,11 +979,11 @@ public void OnSave(ConfigNode node) var contextNode = new ConfigNode("context"); // Save variables - if (globalVariables.Count > 0) + if (globalVariables.Variables.Count > 0) { var varNode = new ConfigNode("variables"); - foreach (var kvp in globalVariables) + foreach (var kvp in globalVariables.Variables) { if (!(kvp.Value is BoundVariable) && (kvp.Value.Name.IndexOfAny(new[] { '*', '-' }) == -1)) // variables that have this characters are internal and shouldn't be persisted diff --git a/src/kOS/Execution/Stack.cs b/src/kOS/Execution/Stack.cs index 1ebd7ffa0..01c626b11 100644 --- a/src/kOS/Execution/Stack.cs +++ b/src/kOS/Execution/Stack.cs @@ -80,11 +80,37 @@ public object Pop() /// so on. Note you CAN peek a negative number, which looks at the secret stack above the /// stack - where the subroutine contexts and local variable contexts are. /// The object at that depth. Returns null when digDepth is too large and the stack isn't - /// big enough to dig that deep. + /// big enough to dig that deep. Note that this conflates with the case where there really is a + /// null stored on the stack and makes it impossible to tell the difference between peeking too far + /// versus actually finding a null. If you need to know the difference, use PeekCheck. public object Peek(int digDepth) + { + object returnVal; + PeekCheck(digDepth, out returnVal); + return returnVal; + } + + /// + /// Slightly "cheats" and breaks out of the 'stack' model by allowing you to view the contents of + /// somewhere on the stack that is underneath the topmost thing. You can only peek, but not pop + /// values this way. It returns both the object found there (as an out parameter) and a boolean for + /// whether or not your peek attempt went out of bounds of the stack. + /// + /// How far underneath the top to look. Zero means peek at the top, + /// 1 means peek at the item just under the top, 2 means peek at the item just under that, and + /// so on. Note you CAN peek a negative number, which looks at the secret stack above the + /// stack - where the subroutine contexts and local variable contexts are. + /// The object at that depth. Will be null when digDepth is too large and the stack isn't + /// big enough to dig that deep, but it also could return null if the actual value stored there on + /// the stack really is a null. If you need to be certain of the difference, use the return value. + /// Returns true if your peek was within the bounds of the stack, or false if you tried + /// to peek too far and went past the top or bottom of the stack. + public bool PeekCheck(int digDepth, out object item) { int index = stackPointer - digDepth; - return (index < 0 || index >= stack.Count) ? null : stack[index]; + bool returnVal = (index >= 0 && index < stack.Count); + item = returnVal ? stack[index] : null; + return returnVal; } /// @@ -119,13 +145,15 @@ public string Dump() { object item = stack[index]; builder.AppendLine(string.Format("{0:000} {1,4} {2}", index, (index==stackPointer ? "SP->" : "" ), item)); - Dictionary dict = item as Dictionary; + VariableScope dict = item as VariableScope; if (dict != null) { + builder.AppendFormat(" ScopeId={0}, ParentScopeId={1}, ParentSkipLevels={2}", dict.ScopeId, dict.ParentScopeId, dict.ParentSkipLevels); + builder.AppendLine(); // Dump the local variable context stored here on the stack: - foreach (string varName in dict.Keys) + foreach (string varName in dict.Variables.Keys) { - builder.AppendFormat(" local var \"{0}\" = {1}", varName, dict[varName].Value); + builder.AppendFormat(" local var {0} is {1} with value = {2}", varName, varName.GetType().FullName, dict.Variables[varName].Value); builder.AppendLine(); } } From 3068b185fc957354f1656c6265dafea3e9c93d86 Mon Sep 17 00:00:00 2001 From: ZiwKerman Date: Mon, 23 Mar 2015 13:40:35 +0000 Subject: [PATCH 311/446] Documentation version fix Fixes #683. But docs need to be compiled and uploaded to a proper location. --- RELEASECHECKLIST.md | 4 +++- doc/source/conf.py | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/RELEASECHECKLIST.md b/RELEASECHECKLIST.md index 601df5545..f11c1b600 100644 --- a/RELEASECHECKLIST.md +++ b/RELEASECHECKLIST.md @@ -5,6 +5,7 @@ * Update AssemblyInfo for kOS project * Update AssemblyInfo for kOS.Safe project * Update Resources\GameData\kOS\kOS.version +* Update doc\source\conf.py * Update CHANGELOG.MD ### Build @@ -12,6 +13,7 @@ * Copy kOS.dll and kOS.Safe.dll to \Resources\GameData\kOS\Plugins\ * Create zip file with a root starting in the \Resources\ directory * Name the zip file with the following pattern kOS.v...zip (eg kOS.v0.14.2.zip ) +* Build the documentation in \docs\ ### Post-Build * Build Github release with changelog and title @@ -20,5 +22,5 @@ * Update Forum thread with new change log, release date and version http://forum.kerbalspaceprogram.com/threads/68089 * Post update in the forum thread * Post update on reddit board http://www.reddit.com/r/kos - +* Upload updated documentation diff --git a/doc/source/conf.py b/doc/source/conf.py index 76d8d514b..43205f719 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -57,9 +57,9 @@ # built documents. # # The short X.Y version. -version = '0.15.3' +version = '0.16.2' # The full version, including alpha/beta/rc tags. -release = '0.15.3' +release = '0.16.2' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. From f078842d051f1400da7359204552d1815c13f4b5 Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Thu, 26 Mar 2015 21:50:04 -0500 Subject: [PATCH 312/446] everything except cooked controls seems to work. --- CHANGELOG.md | 6 + doc/source/language/flow.rst | 23 ++ doc/source/language/variables.rst | 19 ++ src/kOS.Safe/Compilation/KS/Compiler.cs | 193 +++++++++++++-- src/kOS.Safe/Compilation/KS/Lock.cs | 2 +- src/kOS.Safe/Compilation/KS/ParseTree.cs | 20 ++ src/kOS.Safe/Compilation/KS/Parser.cs | 75 +++++- src/kOS.Safe/Compilation/KS/Scanner.cs | 266 +++++++++++---------- src/kOS.Safe/Compilation/KS/kRISC.tpg | 9 +- src/kOS.Safe/Compilation/Opcode.cs | 23 ++ src/kOS.Safe/Compilation/ProgramBuilder.cs | 27 +++ src/kOS.Safe/Execution/ICpu.cs | 1 + src/kOS/Binding/FlightControlManager.cs | 8 + src/kOS/Execution/CPU.cs | 20 +- src/kOS/Function/Misc.cs | 2 +- 15 files changed, 533 insertions(+), 161 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ee0e6a68d..3458c8280 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,12 @@ FUNCTIONS! FUNCTIONS! FUNCTIONS! Big feature: You can make your own user-defined functions. ###BREAKING: +- **RECOMPILE YOUR KSM FILES!!!** - changes to the kOS machine code + that were needed to support variable scoping ended up invalidating + any existing precompiled KSM files. You should be able to just + perform one compile and then use the new KSM file. If you don't do + this, you will get the error message: + ```The given key was not present in the dictionary.``` - *DECLARE has a new syntax* DECLARE _VARNAME_ now requires an initializier syntax as follows: - DECLARE _VARNAME_ TO _VALUE_. diff --git a/doc/source/language/flow.rst b/doc/source/language/flow.rst index ab45dd8d9..4b2eca5a9 100644 --- a/doc/source/language/flow.rst +++ b/doc/source/language/flow.rst @@ -75,6 +75,13 @@ Locks an identifier to an expression. Each time the identifier is used in an exp SET X TO 4. PRINT Y. // Outputs 6 +LOCK follows the same scoping rules as the SET command. If the variable +name used already exists in local scope, then the lock command creates +a lock function that only lasts as long as the current scope and then +becomes unreachable after that. If the variable name used does not exist +in local scope, then LOCK will create it as a global variable, unless +@NOLAZYGLOBAL is set to off, in which case it will be an error. + Note that a LOCK expression is extremely similar to a user function. Every time you read the value of the "variable", it executes the expression again. @@ -176,6 +183,14 @@ does not halt execution. It starts a check in the background that will keep acti The body of a ``THEN`` or an ``ON`` statement interrupts the normal flow of a **kOS** program. When the event that triggers the body happens, the main **kOS** program is paused until the body of the ``THEN`` completes. +.. warning:: + With the advent of :ref:`local variable scoping ` in kOS + version 0.17 and above, it's important to note that the variables + used within the expression of a WHEN or an ON statement should + be GLOBAL variables or the results are unpredictable. If local + variables were used, the results could change depending on where + you are within the execution at the time. + .. warning:: Do not make the body of a ``WHEN``/``THEN`` take a long time to execute. If you attempt to run code that lasts too long in the body of your ``WHEN``/``THEN`` statement, :ref:`it will cause an error `. Avoid looping during ``WHEN``/``THEN`` if you can. For details on how to deal with this, see the :ref:`tutorial on design patterns `. @@ -207,6 +222,14 @@ The ``ON`` command is almost identical to the ``WHEN``/``THEN`` command. ``ON`` Just like with the ``WHEN``/``THEN`` command, the ``PRESERVE`` command can be used inside the code block to cause the trigger to remain active and not go away. +.. warning:: + With the advent of :ref:`local variable scoping ` in kOS + version 0.17 and above, it's important to note that the variables + used within the expression of a WHEN or an ON statement should + be GLOBAL variables or the results are unpredictable. If local + variables were used, the results could change depending on where + you are within the execution at the time. + How does it differ from ``WHEN``/``THEN``? The ``WHEN``/``THEN`` triggers are executed whenever the conditional expression *becomes true*. ``ON`` triggers are executed whenever the boolean variable *changes state* either from false to true or from true to false. The body of an ``ON`` statement can be a list of commands inside curly braces, just like for ``WHEN``/``THEN``. Also just like with ``WHEN``/``THEN``, the body of the ``ON`` interrupts all of **KSP** while it runs, so it should be designed to be a short and finish quickly without getting stuck in a long loop:: diff --git a/doc/source/language/variables.rst b/doc/source/language/variables.rst index fd505bea6..a1155b91a 100644 --- a/doc/source/language/variables.rst +++ b/doc/source/language/variables.rst @@ -325,6 +325,25 @@ Nesting: if the variable isn't found at the global scope either will it be implicitly created. +.. _trigger_scope: + +Scoping and Triggers: +::::::::::::::::::::: + +Triggers such as: + + - WHEN { }. + +and + + - ON { }. + +Do not work predictably when you use local variables in the +part of them. They need to be designed to use global variables only, +because they outlive the duration of any particular scoping braces. +You can declare local variables within their in their bodies, +just don't use local variables in the trigger conditions. + .. _nolazyglobal: ``NOLAZYGLOBAL`` diff --git a/src/kOS.Safe/Compilation/KS/Compiler.cs b/src/kOS.Safe/Compilation/KS/Compiler.cs index 65c36c1f9..87450e10b 100644 --- a/src/kOS.Safe/Compilation/KS/Compiler.cs +++ b/src/kOS.Safe/Compilation/KS/Compiler.cs @@ -27,6 +27,7 @@ class Compiler private bool nowInALoop; private bool needImplicitReturn; private bool nextBraceIsFunction; + private bool allowLazyGlobal; private Int16 braceNestLevel; private readonly List scopeStack = new List(); private readonly Dictionary scopeMap = new Dictionary(); @@ -64,6 +65,7 @@ private void InitCompileFlags() needImplicitReturn = true; braceNestLevel = 0; nextBraceIsFunction = false; + allowLazyGlobal = true; scopeStack.Clear(); scopeMap.Clear(); programParameters.Clear(); @@ -82,7 +84,6 @@ public CodePart Compile(int startLineNum, ParseTree tree, Context context, Compi { if (tree.Nodes.Count > 0) { - TraverseScopeBranch(tree.Nodes[0]); PreProcess(tree); CompileProgram(tree); } @@ -170,6 +171,7 @@ private string GetNextLabel(bool increment) private void PreProcess(ParseTree tree) { ParseNode rootNode = tree.Nodes[0]; + TraverseScopeBranch(rootNode); PreProcessLocks(rootNode); PreProcessStatements(rootNode); } @@ -215,7 +217,7 @@ private void IterateLocks(ParseNode node, Action action) break; } } - + private void PreProcessStatements(ParseNode node) { @@ -448,19 +450,15 @@ private void PreProcessLockStatement(ParseNode node) // exist exactly once, and can be "forward" called from higher up in // the same scope so they get assigned when the scope is first opened. // - // TODO ? ? : Do we want to have local locks? It could be done by having them - // define the lock... but.... could mess things up for system locks. For - // now, we're defining that all locks are global? if (isLock && !lockObject.IsInitialized()) { - // initialization code currentCodeSection = lockObject.InitializationCode; - AddOpcode(new OpcodePush(lockObject.PointerIdentifier)); - AddOpcode(new OpcodePushRelocateLater(null), lockObject.DefaultLabel); - AddOpcode(new OpcodeStore()); if (lockObject.IsSystemLock()) { + AddOpcode(new OpcodePush(lockObject.PointerIdentifier)); + AddOpcode(new OpcodePushRelocateLater(null), lockObject.DefaultLabel); + AddOpcode(new OpcodeStore()); // add trigger string triggerIdentifier = "lock-" + lockObject.Identifier; Trigger triggerObject = context.Triggers.GetTrigger(triggerIdentifier); @@ -468,12 +466,27 @@ private void PreProcessLockStatement(ParseNode node) short rememberLastLine = lastLine; lastLine = -1; // special flag telling the error handler that these opcodes came from the system itself, when reporting the error currentCodeSection = triggerObject.Code; + AddOpcode(new OpcodePush(OpcodeCall.ARG_MARKER_STRING)); // need these for all locks now. AddOpcode(new OpcodePush("$" + lockObject.Identifier)); AddOpcode(new OpcodeCall(lockObject.PointerIdentifier)); - AddOpcode(new OpcodeStore()); + if (allowLazyGlobal) + AddOpcode(new OpcodeStore()); + else + AddOpcode(new OpcodeStoreExist()); AddOpcode(new OpcodeEOF()); lastLine = rememberLastLine; } + else + { + // initialization code - unfortunately the lock implementation presumed global namespace + // and insisted on inserting an initialization block in front of the entire program to set up + // the GLOBAL lock value. This assumption was thorny to remove, so for now, we'll make the init + // code consist of a dummy NOP until a better solution can be found. Note this does put a NOP + // into the code PER LOCK. Which is silly. It's because lockObject.IsInitialized() doesn't + // know how to tell the difference between initialization code that's deliberately empty versus + // initialization code being empty because the lock has never been set up properly yet. + AddOpcode(new OpcodeNOP()); + } // build default dummy function to be used when this is a LOCK: currentCodeSection = lockObject.GetLockFunction(0); @@ -560,8 +573,18 @@ private void PreProcessRunStatement(ParseNode node) Opcode callOpcode = AddOpcode(new OpcodeCall(subprogramObject.PointerIdentifier)); // set the call opcode as the destination of the previous branch branchOpcode.DestinationLabel = callOpcode.Label; - // return to the caller address - AddOpcode(new OpcodeReturn()); + // return to the caller address, after adding a dummy return val: + + // maybe TODO? Right now the RETURN command is being prevented from being used outside + // a function declaration. But in principle we could have programs return exit codes + // using the same archetecture, and in fact that is why this dummy return value is needed, + // because OpcodeReturn now expects such a return value to exist and throws an exception when it + // does not. + // If an EXIT command was implemented, it would maybe allow an exit code that can be read here: + AddOpcode(new OpcodePop()); // for now: throw away return code from subprogram. + AddOpcode(new OpcodePush(0)); // Replace it with new dummy return code. + AddOpcode(new OpcodeReturn()); // return that. + // set the function start label subprogramObject.FunctionLabel = functionStart.Label; @@ -746,6 +769,11 @@ private void TraverseScopeBranch(ParseNode node) scopeStack.RemoveAt(scopeStack.Count-1); break; + // Some Compiler directives affect variable scope rules: + case TokenType.lazyglobal_directive: + VisitLazyGlobalDirective(node); + break; + default: foreach (ParseNode childNode in node.Nodes) TraverseScopeBranch(childNode); @@ -762,8 +790,7 @@ private void VisitNode(ParseNode node) switch (node.Token.Type) { case TokenType.Start: - AddFunctionJumpVars(null); - VisitChildNodes(node); + VisitStartStatement(node); break; case TokenType.instruction: VisitChildNodes(node); @@ -947,8 +974,17 @@ private void VisitNode(ParseNode node) case TokenType.identifier_led_expr: VisitIdentifierLedExpression(node); break; + case TokenType.directive: + VisitDirective(node); + break; } } + + private void VisitStartStatement(ParseNode node) + { + AddFunctionJumpVars(null); + VisitChildNodes(node); + } private void VisitChildNodes(ParseNode node) { @@ -1378,6 +1414,10 @@ private bool IsLastmostTrailerInTerm(ParseNode node) private string GetIdentifierText(ParseNode node) { + //Prevent recursing through parenthesized sub-expressions: + if (node.Token.Type == TokenType.expr) + return string.Empty; + if (node.Token.Type == TokenType.IDENTIFIER || node.Token.Type == TokenType.FILEIDENT) { return node.Token.Text; @@ -1456,10 +1496,6 @@ private void VisitSuffixTerm(ParseNode node) { NodeStartHousekeeping(node); - // I'm not entirely convinced this method is even being called by the parser anymore. - // I think it's arranged such that it's VisitSuffix that does all the work. - // If I can find a way to prove that I might want to see this method deleted. - if (node.Nodes.Count > 1 && node.Nodes[1].Token.Type == TokenType.function_trailer) { @@ -1713,7 +1749,10 @@ private void ProcessSetOperation(ParseNode setThis, ParseNode toThis) } else { - AddOpcode(new OpcodeStore()); + if (allowLazyGlobal) + AddOpcode(new OpcodeStore()); + else + AddOpcode(new OpcodeStoreExist()); } } @@ -1897,7 +1936,10 @@ private void VisitLockStatement(ParseNode node) // lock variable AddOpcode(new OpcodePush(lockObject.PointerIdentifier)); AddOpcode(new OpcodePushRelocateLater(null), functionLabel); - AddOpcode(new OpcodeStore()); + if (allowLazyGlobal) + AddOpcode(new OpcodeStore()); + else + AddOpcode(new OpcodeStoreExist()); if (lockObject.IsSystemLock()) { @@ -1961,9 +2003,13 @@ private void UnlockIdentifier(Lock lockObject) } // unlock variable + // Really, we should unlock a variable by unsetting it's pointer var so it's an error to use it: AddOpcode(new OpcodePush(lockObject.PointerIdentifier)); AddOpcode(new OpcodePushRelocateLater(null), lockObject.DefaultLabel); - AddOpcode(new OpcodeStore()); + if (allowLazyGlobal) + AddOpcode(new OpcodeStore()); + else + AddOpcode(new OpcodeStoreExist()); } } @@ -2065,7 +2111,10 @@ private void VisitToggleStatement(ParseNode node) VisitVarIdentifier(node.Nodes[1]); AddOpcode(new OpcodeLogicToBool()); AddOpcode(new OpcodeLogicNot()); - AddOpcode(new OpcodeStore()); + if (allowLazyGlobal) + AddOpcode(new OpcodeStore()); + else + AddOpcode(new OpcodeStoreExist()); } private void VisitPrintStatement(ParseNode node) @@ -2124,6 +2173,14 @@ private void VisitRunStatement(ParseNode node) int volumeIndex = 3; // process program arguments + if (options.LoadProgramsInSameAddressSpace) + { + // If running inside the same prog, it needs the arg marker to exist twice because it will + // call a subroutine that in turn checks to see if it's loaded and then calls the real + // program, which will itself have a return as well, which outermost programs don't have: + AddOpcode(new OpcodePush(OpcodeCall.ARG_MARKER_STRING)); + AddOpcode(new OpcodePush(OpcodeCall.ARG_MARKER_STRING)); + } if (node.Nodes.Count > 3 && node.Nodes[3].Token.Type == TokenType.arglist) { VisitNode(node.Nodes[3]); @@ -2241,7 +2298,10 @@ private void VisitListStatement(ParseNode node) VisitNode(node.Nodes[1]); // build list AddOpcode(new OpcodeCall("buildlist()")); - AddOpcode(new OpcodeStore()); + if (allowLazyGlobal) + AddOpcode(new OpcodeStore()); + else + AddOpcode(new OpcodeStoreExist()); } else { @@ -2469,5 +2529,92 @@ private void VisitIdentifierLedExpression(ParseNode node) AddOpcode(new OpcodePop()); } } + + public void VisitDirective(ParseNode node) + { + // For now, let the compiler decide if the compiler directive is in the wrong place, + // not the parser. Therefore the parser treats it like a normal statement and here in + // the compiler we'll decide per-directive which directives can go where: + + ParseNode directiveNode = node.Nodes[0]; // a directive contains the exact directive node nested one step inside it. + + if (directiveNode.Nodes.Count < 2) + throw new KOSCompileException("Kerboscript compiler directive ('@') without a keyword after it."); + + + switch (directiveNode.Nodes[1].Token.Type) + { + case TokenType.LAZYGLOBAL: + VisitLazyGlobalDirective(directiveNode); + break; + + // There is room for expansion here if we want to add more compiler directives. + + default: + throw new KOSCompileException("Kerboscript compiler directive @"+directiveNode.Nodes[1].Text+" is unknown."); + } + } + + public void VisitLazyGlobalDirective(ParseNode node) + { + if (node.Nodes.Count < 3 || node.Nodes[2].Token.Type != TokenType.onoff_trailer) + throw new KOSCompileException("Kerboscript compiler directive @LAZYGLOBAL requires an ON or an OFF keyword."); + + // This particular directive is only allowed up at the top of a file, prior to any other non-directive statements. + // --------------------------------------------------------------------------------------------------------------- + + bool validLocation = true; // will change to false if this isn't where a LazyGlobalDirective is allowed. + + // Check 1 - see if I'm nested in anything other than the outermost list of statements: + ParseNode ancestor = node.Parent; + ParseNode myInstructionContainer = node.Parent; + while( ancestor != null && ancestor.Token.Type != TokenType.Start) + { + switch (ancestor.Token.Type) + { + case TokenType.instruction_block: + case TokenType.if_stmt: + case TokenType.until_stmt: + case TokenType.when_stmt: + case TokenType.for_stmt: + case TokenType.on_stmt: + validLocation = false; + break; + case TokenType.instruction: + myInstructionContainer = ancestor; + break; + default: + break; + } + ancestor = ancestor.Parent; + } + // Check 2 - see if I am at the top. The only statements allowed to preceed me are other directives: + if (validLocation && ancestor != null && ancestor.Token.Type == TokenType.Start) + { + // ancestor is now the Start node for the compile: + int myInstructionIndex = ancestor.Nodes.IndexOf(myInstructionContainer); // would be an expensive walk - except this should only exist once, near the top. + for (int i = 0; validLocation && i < myInstructionIndex; ++i) + { + // if a statement preceeding me is anything other than another directive, it's wrong: + if (ancestor.Nodes[i].Token.Type != TokenType.directive || + (ancestor.Nodes[i].Token.Type == TokenType.instruction && + ancestor.Nodes[i].Nodes[0].Token.Type != TokenType.directive) + ) + validLocation = false; + } + } + if (!validLocation) + throw new KOSCommandInvalidHere("@LAZYGLOBAL", + "after the first command in the file", + "at the start of a script file, prior to any other statements"); + + // Okay the location is fine - do the work: + ParseNode onOffValue = node.Nodes[2].Nodes[0]; + if (onOffValue.Token.Type == TokenType.ON) + allowLazyGlobal = true; // this is the default anyway, so this is just here for completeness in case we change the default. + else if (onOffValue.Token.Type == TokenType.OFF) + allowLazyGlobal = false; + // else do nothing, which really should be an impossible case. + } } } diff --git a/src/kOS.Safe/Compilation/KS/Lock.cs b/src/kOS.Safe/Compilation/KS/Lock.cs index 24c7cb786..b188ca1ee 100644 --- a/src/kOS.Safe/Compilation/KS/Lock.cs +++ b/src/kOS.Safe/Compilation/KS/Lock.cs @@ -52,7 +52,7 @@ public bool IsInitialized() { return (IsFunction || codePart.InitializationCode.Count > 0); } - + /// /// Get the label of the function body entry point, /// in other words the label of the very first Opcode diff --git a/src/kOS.Safe/Compilation/KS/ParseTree.cs b/src/kOS.Safe/Compilation/KS/ParseTree.cs index d580da374..384a79f81 100644 --- a/src/kOS.Safe/Compilation/KS/ParseTree.cs +++ b/src/kOS.Safe/Compilation/KS/ParseTree.cs @@ -187,6 +187,12 @@ internal object Eval(ParseTree tree, params object[] paramlist) case TokenType.instruction: Value = Evalinstruction(tree, paramlist); break; + case TokenType.lazyglobal_directive: + Value = Evallazyglobal_directive(tree, paramlist); + break; + case TokenType.directive: + Value = Evaldirective(tree, paramlist); + break; case TokenType.set_stmt: Value = Evalset_stmt(tree, paramlist); break; @@ -376,6 +382,20 @@ protected virtual object Evalinstruction(ParseTree tree, params object[] paramli return null; } + protected virtual object Evallazyglobal_directive(ParseTree tree, params object[] paramlist) + { + foreach (var node in Nodes) + node.Eval(tree, paramlist); + return null; + } + + protected virtual object Evaldirective(ParseTree tree, params object[] paramlist) + { + foreach (var node in Nodes) + node.Eval(tree, paramlist); + return null; + } + protected virtual object Evalset_stmt(ParseTree tree, params object[] paramlist) { foreach (var node in Nodes) diff --git a/src/kOS.Safe/Compilation/KS/Parser.cs b/src/kOS.Safe/Compilation/KS/Parser.cs index f80e7668e..73cceaf87 100644 --- a/src/kOS.Safe/Compilation/KS/Parser.cs +++ b/src/kOS.Safe/Compilation/KS/Parser.cs @@ -47,7 +47,7 @@ private void ParseStart(ParseNode parent) - tok = scanner.LookAhead(TokenType.SET, TokenType.IF, TokenType.UNTIL, TokenType.LOCK, TokenType.UNLOCK, TokenType.PRINT, TokenType.ON, TokenType.TOGGLE, TokenType.WAIT, TokenType.WHEN, TokenType.STAGE, TokenType.CLEARSCREEN, TokenType.ADD, TokenType.REMOVE, TokenType.LOG, TokenType.BREAK, TokenType.PRESERVE, TokenType.DECLARE, TokenType.RETURN, TokenType.SWITCH, TokenType.COPY, TokenType.RENAME, TokenType.DELETE, TokenType.EDIT, TokenType.RUN, TokenType.COMPILE, TokenType.LIST, TokenType.REBOOT, TokenType.SHUTDOWN, TokenType.FOR, TokenType.UNSET, TokenType.BATCH, TokenType.DEPLOY, TokenType.CURLYOPEN, TokenType.PLUSMINUS, TokenType.NOT, TokenType.INTEGER, TokenType.DOUBLE, TokenType.TRUEFALSE, TokenType.IDENTIFIER, TokenType.FILEIDENT, TokenType.BRACKETOPEN, TokenType.STRING); + tok = scanner.LookAhead(TokenType.SET, TokenType.IF, TokenType.UNTIL, TokenType.LOCK, TokenType.UNLOCK, TokenType.PRINT, TokenType.ON, TokenType.TOGGLE, TokenType.WAIT, TokenType.WHEN, TokenType.STAGE, TokenType.CLEARSCREEN, TokenType.ADD, TokenType.REMOVE, TokenType.LOG, TokenType.BREAK, TokenType.PRESERVE, TokenType.DECLARE, TokenType.RETURN, TokenType.SWITCH, TokenType.COPY, TokenType.RENAME, TokenType.DELETE, TokenType.EDIT, TokenType.RUN, TokenType.COMPILE, TokenType.LIST, TokenType.REBOOT, TokenType.SHUTDOWN, TokenType.FOR, TokenType.UNSET, TokenType.BATCH, TokenType.DEPLOY, TokenType.CURLYOPEN, TokenType.PLUSMINUS, TokenType.NOT, TokenType.INTEGER, TokenType.DOUBLE, TokenType.TRUEFALSE, TokenType.IDENTIFIER, TokenType.FILEIDENT, TokenType.BRACKETOPEN, TokenType.STRING, TokenType.ATSIGN); while (tok.Type == TokenType.SET || tok.Type == TokenType.IF || tok.Type == TokenType.UNTIL @@ -90,10 +90,11 @@ private void ParseStart(ParseNode parent) || tok.Type == TokenType.IDENTIFIER || tok.Type == TokenType.FILEIDENT || tok.Type == TokenType.BRACKETOPEN - || tok.Type == TokenType.STRING) + || tok.Type == TokenType.STRING + || tok.Type == TokenType.ATSIGN) { Parseinstruction(node); - tok = scanner.LookAhead(TokenType.SET, TokenType.IF, TokenType.UNTIL, TokenType.LOCK, TokenType.UNLOCK, TokenType.PRINT, TokenType.ON, TokenType.TOGGLE, TokenType.WAIT, TokenType.WHEN, TokenType.STAGE, TokenType.CLEARSCREEN, TokenType.ADD, TokenType.REMOVE, TokenType.LOG, TokenType.BREAK, TokenType.PRESERVE, TokenType.DECLARE, TokenType.RETURN, TokenType.SWITCH, TokenType.COPY, TokenType.RENAME, TokenType.DELETE, TokenType.EDIT, TokenType.RUN, TokenType.COMPILE, TokenType.LIST, TokenType.REBOOT, TokenType.SHUTDOWN, TokenType.FOR, TokenType.UNSET, TokenType.BATCH, TokenType.DEPLOY, TokenType.CURLYOPEN, TokenType.PLUSMINUS, TokenType.NOT, TokenType.INTEGER, TokenType.DOUBLE, TokenType.TRUEFALSE, TokenType.IDENTIFIER, TokenType.FILEIDENT, TokenType.BRACKETOPEN, TokenType.STRING); + tok = scanner.LookAhead(TokenType.SET, TokenType.IF, TokenType.UNTIL, TokenType.LOCK, TokenType.UNLOCK, TokenType.PRINT, TokenType.ON, TokenType.TOGGLE, TokenType.WAIT, TokenType.WHEN, TokenType.STAGE, TokenType.CLEARSCREEN, TokenType.ADD, TokenType.REMOVE, TokenType.LOG, TokenType.BREAK, TokenType.PRESERVE, TokenType.DECLARE, TokenType.RETURN, TokenType.SWITCH, TokenType.COPY, TokenType.RENAME, TokenType.DELETE, TokenType.EDIT, TokenType.RUN, TokenType.COMPILE, TokenType.LIST, TokenType.REBOOT, TokenType.SHUTDOWN, TokenType.FOR, TokenType.UNSET, TokenType.BATCH, TokenType.DEPLOY, TokenType.CURLYOPEN, TokenType.PLUSMINUS, TokenType.NOT, TokenType.INTEGER, TokenType.DOUBLE, TokenType.TRUEFALSE, TokenType.IDENTIFIER, TokenType.FILEIDENT, TokenType.BRACKETOPEN, TokenType.STRING, TokenType.ATSIGN); } @@ -128,7 +129,7 @@ private void Parseinstruction_block(ParseNode parent) } - tok = scanner.LookAhead(TokenType.SET, TokenType.IF, TokenType.UNTIL, TokenType.LOCK, TokenType.UNLOCK, TokenType.PRINT, TokenType.ON, TokenType.TOGGLE, TokenType.WAIT, TokenType.WHEN, TokenType.STAGE, TokenType.CLEARSCREEN, TokenType.ADD, TokenType.REMOVE, TokenType.LOG, TokenType.BREAK, TokenType.PRESERVE, TokenType.DECLARE, TokenType.RETURN, TokenType.SWITCH, TokenType.COPY, TokenType.RENAME, TokenType.DELETE, TokenType.EDIT, TokenType.RUN, TokenType.COMPILE, TokenType.LIST, TokenType.REBOOT, TokenType.SHUTDOWN, TokenType.FOR, TokenType.UNSET, TokenType.BATCH, TokenType.DEPLOY, TokenType.CURLYOPEN, TokenType.PLUSMINUS, TokenType.NOT, TokenType.INTEGER, TokenType.DOUBLE, TokenType.TRUEFALSE, TokenType.IDENTIFIER, TokenType.FILEIDENT, TokenType.BRACKETOPEN, TokenType.STRING); + tok = scanner.LookAhead(TokenType.SET, TokenType.IF, TokenType.UNTIL, TokenType.LOCK, TokenType.UNLOCK, TokenType.PRINT, TokenType.ON, TokenType.TOGGLE, TokenType.WAIT, TokenType.WHEN, TokenType.STAGE, TokenType.CLEARSCREEN, TokenType.ADD, TokenType.REMOVE, TokenType.LOG, TokenType.BREAK, TokenType.PRESERVE, TokenType.DECLARE, TokenType.RETURN, TokenType.SWITCH, TokenType.COPY, TokenType.RENAME, TokenType.DELETE, TokenType.EDIT, TokenType.RUN, TokenType.COMPILE, TokenType.LIST, TokenType.REBOOT, TokenType.SHUTDOWN, TokenType.FOR, TokenType.UNSET, TokenType.BATCH, TokenType.DEPLOY, TokenType.CURLYOPEN, TokenType.PLUSMINUS, TokenType.NOT, TokenType.INTEGER, TokenType.DOUBLE, TokenType.TRUEFALSE, TokenType.IDENTIFIER, TokenType.FILEIDENT, TokenType.BRACKETOPEN, TokenType.STRING, TokenType.ATSIGN); while (tok.Type == TokenType.SET || tok.Type == TokenType.IF || tok.Type == TokenType.UNTIL @@ -171,10 +172,11 @@ private void Parseinstruction_block(ParseNode parent) || tok.Type == TokenType.IDENTIFIER || tok.Type == TokenType.FILEIDENT || tok.Type == TokenType.BRACKETOPEN - || tok.Type == TokenType.STRING) + || tok.Type == TokenType.STRING + || tok.Type == TokenType.ATSIGN) { Parseinstruction(node); - tok = scanner.LookAhead(TokenType.SET, TokenType.IF, TokenType.UNTIL, TokenType.LOCK, TokenType.UNLOCK, TokenType.PRINT, TokenType.ON, TokenType.TOGGLE, TokenType.WAIT, TokenType.WHEN, TokenType.STAGE, TokenType.CLEARSCREEN, TokenType.ADD, TokenType.REMOVE, TokenType.LOG, TokenType.BREAK, TokenType.PRESERVE, TokenType.DECLARE, TokenType.RETURN, TokenType.SWITCH, TokenType.COPY, TokenType.RENAME, TokenType.DELETE, TokenType.EDIT, TokenType.RUN, TokenType.COMPILE, TokenType.LIST, TokenType.REBOOT, TokenType.SHUTDOWN, TokenType.FOR, TokenType.UNSET, TokenType.BATCH, TokenType.DEPLOY, TokenType.CURLYOPEN, TokenType.PLUSMINUS, TokenType.NOT, TokenType.INTEGER, TokenType.DOUBLE, TokenType.TRUEFALSE, TokenType.IDENTIFIER, TokenType.FILEIDENT, TokenType.BRACKETOPEN, TokenType.STRING); + tok = scanner.LookAhead(TokenType.SET, TokenType.IF, TokenType.UNTIL, TokenType.LOCK, TokenType.UNLOCK, TokenType.PRINT, TokenType.ON, TokenType.TOGGLE, TokenType.WAIT, TokenType.WHEN, TokenType.STAGE, TokenType.CLEARSCREEN, TokenType.ADD, TokenType.REMOVE, TokenType.LOG, TokenType.BREAK, TokenType.PRESERVE, TokenType.DECLARE, TokenType.RETURN, TokenType.SWITCH, TokenType.COPY, TokenType.RENAME, TokenType.DELETE, TokenType.EDIT, TokenType.RUN, TokenType.COMPILE, TokenType.LIST, TokenType.REBOOT, TokenType.SHUTDOWN, TokenType.FOR, TokenType.UNSET, TokenType.BATCH, TokenType.DEPLOY, TokenType.CURLYOPEN, TokenType.PLUSMINUS, TokenType.NOT, TokenType.INTEGER, TokenType.DOUBLE, TokenType.TRUEFALSE, TokenType.IDENTIFIER, TokenType.FILEIDENT, TokenType.BRACKETOPEN, TokenType.STRING, TokenType.ATSIGN); } @@ -211,7 +213,7 @@ private void Parseinstruction(ParseNode parent) ParseNode node = parent.CreateNode(scanner.GetToken(TokenType.instruction), "instruction"); parent.Nodes.Add(node); - tok = scanner.LookAhead(TokenType.SET, TokenType.IF, TokenType.UNTIL, TokenType.LOCK, TokenType.UNLOCK, TokenType.PRINT, TokenType.ON, TokenType.TOGGLE, TokenType.WAIT, TokenType.WHEN, TokenType.STAGE, TokenType.CLEARSCREEN, TokenType.ADD, TokenType.REMOVE, TokenType.LOG, TokenType.BREAK, TokenType.PRESERVE, TokenType.DECLARE, TokenType.RETURN, TokenType.SWITCH, TokenType.COPY, TokenType.RENAME, TokenType.DELETE, TokenType.EDIT, TokenType.RUN, TokenType.COMPILE, TokenType.LIST, TokenType.REBOOT, TokenType.SHUTDOWN, TokenType.FOR, TokenType.UNSET, TokenType.BATCH, TokenType.DEPLOY, TokenType.CURLYOPEN, TokenType.PLUSMINUS, TokenType.NOT, TokenType.INTEGER, TokenType.DOUBLE, TokenType.TRUEFALSE, TokenType.IDENTIFIER, TokenType.FILEIDENT, TokenType.BRACKETOPEN, TokenType.STRING); + tok = scanner.LookAhead(TokenType.SET, TokenType.IF, TokenType.UNTIL, TokenType.LOCK, TokenType.UNLOCK, TokenType.PRINT, TokenType.ON, TokenType.TOGGLE, TokenType.WAIT, TokenType.WHEN, TokenType.STAGE, TokenType.CLEARSCREEN, TokenType.ADD, TokenType.REMOVE, TokenType.LOG, TokenType.BREAK, TokenType.PRESERVE, TokenType.DECLARE, TokenType.RETURN, TokenType.SWITCH, TokenType.COPY, TokenType.RENAME, TokenType.DELETE, TokenType.EDIT, TokenType.RUN, TokenType.COMPILE, TokenType.LIST, TokenType.REBOOT, TokenType.SHUTDOWN, TokenType.FOR, TokenType.UNSET, TokenType.BATCH, TokenType.DEPLOY, TokenType.CURLYOPEN, TokenType.PLUSMINUS, TokenType.NOT, TokenType.INTEGER, TokenType.DOUBLE, TokenType.TRUEFALSE, TokenType.IDENTIFIER, TokenType.FILEIDENT, TokenType.BRACKETOPEN, TokenType.STRING, TokenType.ATSIGN); switch (tok.Type) { case TokenType.SET: @@ -327,6 +329,9 @@ private void Parseinstruction(ParseNode parent) case TokenType.STRING: Parseidentifier_led_stmt(node); break; + case TokenType.ATSIGN: + Parsedirective(node); + break; default: tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found.", 0x0002, tok)); break; @@ -335,6 +340,62 @@ private void Parseinstruction(ParseNode parent) parent.Token.UpdateRange(node.Token); } + private void Parselazyglobal_directive(ParseNode parent) + { + Token tok; + ParseNode n; + ParseNode node = parent.CreateNode(scanner.GetToken(TokenType.lazyglobal_directive), "lazyglobal_directive"); + parent.Nodes.Add(node); + + + + tok = scanner.Scan(TokenType.ATSIGN); + n = node.CreateNode(tok, tok.ToString() ); + node.Token.UpdateRange(tok); + node.Nodes.Add(n); + if (tok.Type != TokenType.ATSIGN) { + tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.ATSIGN.ToString(), 0x1001, tok)); + return; + } + + + tok = scanner.Scan(TokenType.LAZYGLOBAL); + n = node.CreateNode(tok, tok.ToString() ); + node.Token.UpdateRange(tok); + node.Nodes.Add(n); + if (tok.Type != TokenType.LAZYGLOBAL) { + tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.LAZYGLOBAL.ToString(), 0x1001, tok)); + return; + } + + + Parseonoff_trailer(node); + + + tok = scanner.Scan(TokenType.EOI); + n = node.CreateNode(tok, tok.ToString() ); + node.Token.UpdateRange(tok); + node.Nodes.Add(n); + if (tok.Type != TokenType.EOI) { + tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.EOI.ToString(), 0x1001, tok)); + return; + } + + parent.Token.UpdateRange(node.Token); + } + + private void Parsedirective(ParseNode parent) + { + Token tok; + ParseNode n; + ParseNode node = parent.CreateNode(scanner.GetToken(TokenType.directive), "directive"); + parent.Nodes.Add(node); + + Parselazyglobal_directive(node); + + parent.Token.UpdateRange(node.Token); + } + private void Parseset_stmt(ParseNode parent) { Token tok; diff --git a/src/kOS.Safe/Compilation/KS/Scanner.cs b/src/kOS.Safe/Compilation/KS/Scanner.cs index fb29f7bd8..2bc984577 100644 --- a/src/kOS.Safe/Compilation/KS/Scanner.cs +++ b/src/kOS.Safe/Compilation/KS/Scanner.cs @@ -318,6 +318,14 @@ public Scanner() Patterns.Add(TokenType.EOI, regex); Tokens.Add(TokenType.EOI); + regex = new Regex(@"@"); + Patterns.Add(TokenType.ATSIGN, regex); + Tokens.Add(TokenType.ATSIGN); + + regex = new Regex(@"lazyglobal"); + Patterns.Add(TokenType.LAZYGLOBAL, regex); + Tokens.Add(TokenType.LAZYGLOBAL); + regex = new Regex(@"^$"); Patterns.Add(TokenType.EOF, regex); Tokens.Add(TokenType.EOF); @@ -493,135 +501,139 @@ public enum TokenType Start = 2, instruction_block= 3, instruction= 4, - set_stmt= 5, - if_stmt = 6, - until_stmt= 7, - lock_stmt= 8, - unlock_stmt= 9, - print_stmt= 10, - on_stmt = 11, - toggle_stmt= 12, - wait_stmt= 13, - when_stmt= 14, - onoff_stmt= 15, - onoff_trailer= 16, - stage_stmt= 17, - clear_stmt= 18, - add_stmt= 19, - remove_stmt= 20, - log_stmt= 21, - break_stmt= 22, - preserve_stmt= 23, - declare_stmt= 24, - return_stmt= 25, - switch_stmt= 26, - copy_stmt= 27, - rename_stmt= 28, - delete_stmt= 29, - edit_stmt= 30, - run_stmt= 31, - compile_stmt= 32, - list_stmt= 33, - reboot_stmt= 34, - shutdown_stmt= 35, - for_stmt= 36, - unset_stmt= 37, - batch_stmt= 38, - deploy_stmt= 39, - arglist = 40, - expr = 41, - and_expr= 42, - compare_expr= 43, - arith_expr= 44, - multdiv_expr= 45, - factor = 46, - suffix = 47, - suffix_trailer= 48, - suffixterm= 49, - suffixterm_trailer= 50, - function_trailer= 51, - array_trailer= 52, - atom = 53, - sci_number= 54, - number = 55, - varidentifier= 56, - identifier_led_stmt= 57, - identifier_led_expr= 58, + lazyglobal_directive= 5, + directive= 6, + set_stmt= 7, + if_stmt = 8, + until_stmt= 9, + lock_stmt= 10, + unlock_stmt= 11, + print_stmt= 12, + on_stmt = 13, + toggle_stmt= 14, + wait_stmt= 15, + when_stmt= 16, + onoff_stmt= 17, + onoff_trailer= 18, + stage_stmt= 19, + clear_stmt= 20, + add_stmt= 21, + remove_stmt= 22, + log_stmt= 23, + break_stmt= 24, + preserve_stmt= 25, + declare_stmt= 26, + return_stmt= 27, + switch_stmt= 28, + copy_stmt= 29, + rename_stmt= 30, + delete_stmt= 31, + edit_stmt= 32, + run_stmt= 33, + compile_stmt= 34, + list_stmt= 35, + reboot_stmt= 36, + shutdown_stmt= 37, + for_stmt= 38, + unset_stmt= 39, + batch_stmt= 40, + deploy_stmt= 41, + arglist = 42, + expr = 43, + and_expr= 44, + compare_expr= 45, + arith_expr= 46, + multdiv_expr= 47, + factor = 48, + suffix = 49, + suffix_trailer= 50, + suffixterm= 51, + suffixterm_trailer= 52, + function_trailer= 53, + array_trailer= 54, + atom = 55, + sci_number= 56, + number = 57, + varidentifier= 58, + identifier_led_stmt= 59, + identifier_led_expr= 60, //Terminal tokens: - PLUSMINUS= 59, - MULT = 60, - DIV = 61, - POWER = 62, - E = 63, - NOT = 64, - AND = 65, - OR = 66, - TRUEFALSE= 67, - COMPARATOR= 68, - SET = 69, - TO = 70, - IF = 71, - ELSE = 72, - UNTIL = 73, - LOCK = 74, - UNLOCK = 75, - PRINT = 76, - AT = 77, - ON = 78, - TOGGLE = 79, - WAIT = 80, - WHEN = 81, - THEN = 82, - OFF = 83, - STAGE = 84, - CLEARSCREEN= 85, - ADD = 86, - REMOVE = 87, - LOG = 88, - BREAK = 89, - PRESERVE= 90, - DECLARE = 91, - PARAMETER= 92, - FUNCTION= 93, - RETURN = 94, - SWITCH = 95, - COPY = 96, - FROM = 97, - RENAME = 98, - VOLUME = 99, - FILE = 100, - DELETE = 101, - EDIT = 102, - RUN = 103, - COMPILE = 104, - LIST = 105, - REBOOT = 106, - SHUTDOWN= 107, - FOR = 108, - UNSET = 109, - BATCH = 110, - DEPLOY = 111, - BRACKETOPEN= 112, - BRACKETCLOSE= 113, - CURLYOPEN= 114, - CURLYCLOSE= 115, - SQUAREOPEN= 116, - SQUARECLOSE= 117, - COMMA = 118, - COLON = 119, - IN = 120, - ARRAYINDEX= 121, - ALL = 122, - IDENTIFIER= 123, - FILEIDENT= 124, - INTEGER = 125, - DOUBLE = 126, - STRING = 127, - EOI = 128, - EOF = 129, - WHITESPACE= 130, - COMMENTLINE= 131 + PLUSMINUS= 61, + MULT = 62, + DIV = 63, + POWER = 64, + E = 65, + NOT = 66, + AND = 67, + OR = 68, + TRUEFALSE= 69, + COMPARATOR= 70, + SET = 71, + TO = 72, + IF = 73, + ELSE = 74, + UNTIL = 75, + LOCK = 76, + UNLOCK = 77, + PRINT = 78, + AT = 79, + ON = 80, + TOGGLE = 81, + WAIT = 82, + WHEN = 83, + THEN = 84, + OFF = 85, + STAGE = 86, + CLEARSCREEN= 87, + ADD = 88, + REMOVE = 89, + LOG = 90, + BREAK = 91, + PRESERVE= 92, + DECLARE = 93, + PARAMETER= 94, + FUNCTION= 95, + RETURN = 96, + SWITCH = 97, + COPY = 98, + FROM = 99, + RENAME = 100, + VOLUME = 101, + FILE = 102, + DELETE = 103, + EDIT = 104, + RUN = 105, + COMPILE = 106, + LIST = 107, + REBOOT = 108, + SHUTDOWN= 109, + FOR = 110, + UNSET = 111, + BATCH = 112, + DEPLOY = 113, + BRACKETOPEN= 114, + BRACKETCLOSE= 115, + CURLYOPEN= 116, + CURLYCLOSE= 117, + SQUAREOPEN= 118, + SQUARECLOSE= 119, + COMMA = 120, + COLON = 121, + IN = 122, + ARRAYINDEX= 123, + ALL = 124, + IDENTIFIER= 125, + FILEIDENT= 126, + INTEGER = 127, + DOUBLE = 128, + STRING = 129, + EOI = 130, + ATSIGN = 131, + LAZYGLOBAL= 132, + EOF = 133, + WHITESPACE= 134, + COMMENTLINE= 135 } public class Token diff --git a/src/kOS.Safe/Compilation/KS/kRISC.tpg b/src/kOS.Safe/Compilation/KS/kRISC.tpg index 70c4e7791..a2a744ac1 100644 --- a/src/kOS.Safe/Compilation/KS/kRISC.tpg +++ b/src/kOS.Safe/Compilation/KS/kRISC.tpg @@ -76,6 +76,9 @@ INTEGER -> @"[0-9]+"; DOUBLE -> @"[0-9]*\.[0-9]+"; STRING -> @"@?\""(\""\""|[^\""])*\"""; EOI -> @"\."; +//Compiler Directives +ATSIGN -> @"@"; +LAZYGLOBAL -> @"lazyglobal"; //Special EOF -> @"^$"; [Skip] @@ -121,8 +124,12 @@ instruction -> set_stmt | batch_stmt | deploy_stmt | instruction_block | - identifier_led_stmt; // any statement that starts with an identifier. + identifier_led_stmt | // any statement that starts with an identifier. + directive; // allow directives anywhere for now, let the compiler decide if it's in the wrong place, not the parser. +// ------------ directives -------------------- +lazyglobal_directive -> ATSIGN LAZYGLOBAL onoff_trailer EOI; +directive -> lazyglobal_directive; // Add to this list later if we make other directives. // ------------ statements -------------------- diff --git a/src/kOS.Safe/Compilation/Opcode.cs b/src/kOS.Safe/Compilation/Opcode.cs index eda18b28b..fe83b7060 100644 --- a/src/kOS.Safe/Compilation/Opcode.cs +++ b/src/kOS.Safe/Compilation/Opcode.cs @@ -77,6 +77,7 @@ public enum ByteCode :byte STORELOCAL = 0x58, PUSHSCOPE = 0x59, POPSCOPE = 0x5a, + STOREEXIST = 0x5b, // Augmented bogus placeholder versions of the normal // opcodes: These only exist in the program temporarily @@ -459,6 +460,28 @@ public override void Execute(ICpu cpu) } } + /// + /// Consumes the topmost 2 values of the stack, storing the topmost stack + /// value into a variable described by the next value down the stack.
    + ///
    + /// Unlike OpcodeStore, OpcodeStoreExist will NOT create the variable if it + /// does not already exist. Instead it will cause an + /// error. (It corresponds to kerboscript's @LAZYGLOBAL OFF directive).
    + ///
    + ///
    + public class OpcodeStoreExist : Opcode + { + protected override string Name { get { return "storeexist"; } } + public override ByteCode Code { get { return ByteCode.STOREEXIST; } } + + public override void Execute(ICpu cpu) + { + object value = cpu.PopValue(); + var identifier = (string)cpu.PopStack(); + cpu.SetValueExists(identifier, value); + } + } + /// /// Consumes the topmost 2 values of the stack, storing the topmost stack /// value into a variable described by the next value down the stack.
    diff --git a/src/kOS.Safe/Compilation/ProgramBuilder.cs b/src/kOS.Safe/Compilation/ProgramBuilder.cs index faf5a7a69..a5a4a6843 100644 --- a/src/kOS.Safe/Compilation/ProgramBuilder.cs +++ b/src/kOS.Safe/Compilation/ProgramBuilder.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Text; //eraseme namespace kOS.Safe.Compilation { @@ -98,12 +99,14 @@ protected virtual void AddEndOfProgram(CodePart linkedObject, bool isMainProgram } else { + linkedObject.MainCode.Add(new OpcodePush(0)); // all Returns now need a dummy return value on them. linkedObject.MainCode.Add(new OpcodeReturn()); } } private void ReplaceLabels(List program) { + Console.WriteLine("eraseme: ReplaceLabels program dump:\n------------------\n" + ErasemeGetCodeFragment(program)); var labels = new Dictionary(); // get the index of every label @@ -111,7 +114,9 @@ private void ReplaceLabels(List program) { if (program[index].Label != string.Empty) { + Console.WriteLine("eraseme: ReplaceLabels about to add label="+program[index].Label); labels.Add(program[index].Label, index); + Console.WriteLine("eraseme: ReplaceLabels just did add label="+program[index].Label); } } @@ -149,6 +154,28 @@ private void ReplaceLabels(List program) objectFile.EntryPointAddress = labels[objectFile.EntryPointLabel]; } } + + public string ErasemeGetCodeFragment(List program) // eraseme - delete this entire function after debugging. + { + var codeFragment = new StringBuilder(); + + const string FORMAT_STR = "{0,-20} {1,4}:{2,-3} {3:0000} {4} {5}"; + codeFragment.AppendLine(string.Format(FORMAT_STR, "File", "Line", "Col", "IP ", "opcode", "operand" )); + codeFragment.AppendLine(string.Format(FORMAT_STR, "----", "----", "---", "----", "---------------------", "" )); + + for (int index = 0; index < program.Count; index++) + { + codeFragment.AppendLine(string.Format(FORMAT_STR, + program[index].SourceName, + program[index].SourceLine, + program[index].SourceColumn, + index, + program[index], + ("(label: "+program[index].Label+")"))); + } + + return codeFragment.ToString(); + } public int GetObjectFileEntryPointAddress(Guid objectFileId) { diff --git a/src/kOS.Safe/Execution/ICpu.cs b/src/kOS.Safe/Execution/ICpu.cs index 8339d2789..d4c4a8846 100644 --- a/src/kOS.Safe/Execution/ICpu.cs +++ b/src/kOS.Safe/Execution/ICpu.cs @@ -15,6 +15,7 @@ public interface ICpu : IUpdateObserver object PeekValue(int digDepth, bool barewordOkay = false); int GetStackSize(); void SetValue(string identifier, object value); + void SetValueExists(string identifier, object value); void SetNewLocal(string identifier, object value); string DumpVariables(); void RemoveVariable(string identifier); diff --git a/src/kOS/Binding/FlightControlManager.cs b/src/kOS/Binding/FlightControlManager.cs index 9cf65138a..1e05cc068 100644 --- a/src/kOS/Binding/FlightControlManager.cs +++ b/src/kOS/Binding/FlightControlManager.cs @@ -328,6 +328,7 @@ public void ClearValue() public void OnFlyByWire(ref FlightCtrlState c) { + Console.WriteLine("eraseme: OnFlyByWire called with value="+(value==null?"null":value.ToString())+", Enabled="+Enabled); if (value == null || !Enabled) return; var action = ChooseAction(); @@ -368,6 +369,7 @@ private Action ChooseAction() private void UpdateThrottle(FlightCtrlState c) { + Console.WriteLine("eraseme: FlightCtrlParam: name="+name+" enabled="+Enabled+" UpdateThrottle called"); if (!Enabled) return; double doubleValue = Convert.ToDouble(value); if (!double.IsNaN(doubleValue)) @@ -444,6 +446,12 @@ public void UpdateFlightControl(Vessel vessel) { control = GetControllerByVessel(vessel); } + + public override string ToString() // added to aid in debugging. + { + return "FlightCtrlParam: name="+name+" enabled="+Enabled; + } + } } } \ No newline at end of file diff --git a/src/kOS/Execution/CPU.cs b/src/kOS/Execution/CPU.cs index 9415bb254..0833f02ef 100644 --- a/src/kOS/Execution/CPU.cs +++ b/src/kOS/Execution/CPU.cs @@ -669,6 +669,24 @@ public void SetValue(string identifier, object value) Variable variable = GetOrCreateVariable(identifier); variable.Value = value; } + + /// + /// Try to set the value of the identifier at the localmost + /// level possible, by scanning up the scope stack to find + /// the local-most level at which the identifier is a variable, + /// and assigning it the value there.
    + ///
    + /// If no such value is found, an error is thrown. It only stores into + /// variables that already exist, refusing to create new variables.
    + ///
    + ///
    + /// variable name to attempt to store into + /// value to put into it + public void SetValueExists(string identifier, object value) + { + Variable variable = GetVariable(identifier); + variable.Value = value; + } /// /// Pop a value off the stack, and if it's a variable name then get its value, @@ -899,7 +917,7 @@ private bool ExecuteInstruction(ProgramContext context) if (DEBUG_EACH_OPCODE) { SafeHouse.Logger.Log("ExecuteInstruction. Opcode number " + context.InstructionPointer + " out of " + context.Program.Count + - "\n Opcode is: " + opcode.ToString() ); + "\n Opcode is: " + opcode.Label + " " + opcode.ToString() ); } if (!(opcode is OpcodeEOF || opcode is OpcodeEOP)) diff --git a/src/kOS/Function/Misc.cs b/src/kOS/Function/Misc.cs index 095198c24..105dd06d7 100644 --- a/src/kOS/Function/Misc.cs +++ b/src/kOS/Function/Misc.cs @@ -181,7 +181,7 @@ public override void Execute(SharedObjects shared) { codeParts = shared.ScriptHandler.Compile(filePath, 1, file.StringContent, "program", options); } - programContext.AddParts(codeParts); + programContext.AddParts(codeParts); } } } From fbd63dddcc5277890d68d6e2aef6b658cde7ab65 Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Fri, 27 Mar 2015 01:10:37 -0500 Subject: [PATCH 313/446] garrg. Still not handling the case of functions in other files. --- src/kOS.Safe/Compilation/KS/Compiler.cs | 6 +++-- src/kOS.Safe/Compilation/ProgramBuilder.cs | 26 ---------------------- src/kOS/Binding/FlightControlManager.cs | 2 -- src/kOS/Execution/CPU.cs | 8 ++++--- 4 files changed, 9 insertions(+), 33 deletions(-) diff --git a/src/kOS.Safe/Compilation/KS/Compiler.cs b/src/kOS.Safe/Compilation/KS/Compiler.cs index 87450e10b..62e1be1e5 100644 --- a/src/kOS.Safe/Compilation/KS/Compiler.cs +++ b/src/kOS.Safe/Compilation/KS/Compiler.cs @@ -466,8 +466,8 @@ private void PreProcessLockStatement(ParseNode node) short rememberLastLine = lastLine; lastLine = -1; // special flag telling the error handler that these opcodes came from the system itself, when reporting the error currentCodeSection = triggerObject.Code; - AddOpcode(new OpcodePush(OpcodeCall.ARG_MARKER_STRING)); // need these for all locks now. AddOpcode(new OpcodePush("$" + lockObject.Identifier)); + AddOpcode(new OpcodePush(OpcodeCall.ARG_MARKER_STRING)); // need these for all locks now. AddOpcode(new OpcodeCall(lockObject.PointerIdentifier)); if (allowLazyGlobal) AddOpcode(new OpcodeStore()); @@ -1268,7 +1268,7 @@ private void VisitSuffix(ParseNode node) if (nodeIndex == 0) { firstIdentifier = GetIdentifierText(suffixTerm); - if (context.Locks.Contains(firstIdentifier)) + if (context.Locks.Contains(firstIdentifier) && !compilingSetDestination) { Lock lockObject = context.Locks.GetLock(firstIdentifier); firstIdentifier = lockObject.PointerIdentifier; @@ -2195,6 +2195,7 @@ private void VisitRunStatement(ParseNode node) { Subprogram subprogramObject = context.Subprograms.GetSubprogram(subprogramName); AddOpcode(new OpcodeCall(null)).DestinationLabel = subprogramObject.FunctionLabel; + AddOpcode(new OpcodePop()); // ditch the dummy return value for now - maybe we can use it in a later version. } } else @@ -2209,6 +2210,7 @@ private void VisitRunStatement(ParseNode node) AddOpcode(new OpcodePush(null)); AddOpcode(new OpcodeCall("run()")); + AddOpcode(new OpcodePop()); // ditch the dummy return value for now - maybe we can use it in a later version. } } diff --git a/src/kOS.Safe/Compilation/ProgramBuilder.cs b/src/kOS.Safe/Compilation/ProgramBuilder.cs index a5a4a6843..6b2582bdb 100644 --- a/src/kOS.Safe/Compilation/ProgramBuilder.cs +++ b/src/kOS.Safe/Compilation/ProgramBuilder.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Text; //eraseme namespace kOS.Safe.Compilation { @@ -106,7 +105,6 @@ protected virtual void AddEndOfProgram(CodePart linkedObject, bool isMainProgram private void ReplaceLabels(List program) { - Console.WriteLine("eraseme: ReplaceLabels program dump:\n------------------\n" + ErasemeGetCodeFragment(program)); var labels = new Dictionary(); // get the index of every label @@ -114,9 +112,7 @@ private void ReplaceLabels(List program) { if (program[index].Label != string.Empty) { - Console.WriteLine("eraseme: ReplaceLabels about to add label="+program[index].Label); labels.Add(program[index].Label, index); - Console.WriteLine("eraseme: ReplaceLabels just did add label="+program[index].Label); } } @@ -155,28 +151,6 @@ private void ReplaceLabels(List program) } } - public string ErasemeGetCodeFragment(List program) // eraseme - delete this entire function after debugging. - { - var codeFragment = new StringBuilder(); - - const string FORMAT_STR = "{0,-20} {1,4}:{2,-3} {3:0000} {4} {5}"; - codeFragment.AppendLine(string.Format(FORMAT_STR, "File", "Line", "Col", "IP ", "opcode", "operand" )); - codeFragment.AppendLine(string.Format(FORMAT_STR, "----", "----", "---", "----", "---------------------", "" )); - - for (int index = 0; index < program.Count; index++) - { - codeFragment.AppendLine(string.Format(FORMAT_STR, - program[index].SourceName, - program[index].SourceLine, - program[index].SourceColumn, - index, - program[index], - ("(label: "+program[index].Label+")"))); - } - - return codeFragment.ToString(); - } - public int GetObjectFileEntryPointAddress(Guid objectFileId) { return objectFiles.ContainsKey(objectFileId) ? objectFiles[objectFileId].EntryPointAddress : 0; diff --git a/src/kOS/Binding/FlightControlManager.cs b/src/kOS/Binding/FlightControlManager.cs index 1e05cc068..b749894fc 100644 --- a/src/kOS/Binding/FlightControlManager.cs +++ b/src/kOS/Binding/FlightControlManager.cs @@ -328,7 +328,6 @@ public void ClearValue() public void OnFlyByWire(ref FlightCtrlState c) { - Console.WriteLine("eraseme: OnFlyByWire called with value="+(value==null?"null":value.ToString())+", Enabled="+Enabled); if (value == null || !Enabled) return; var action = ChooseAction(); @@ -369,7 +368,6 @@ private Action ChooseAction() private void UpdateThrottle(FlightCtrlState c) { - Console.WriteLine("eraseme: FlightCtrlParam: name="+name+" enabled="+Enabled+" UpdateThrottle called"); if (!Enabled) return; double doubleValue = Convert.ToDouble(value); if (!double.IsNaN(doubleValue)) diff --git a/src/kOS/Execution/CPU.cs b/src/kOS/Execution/CPU.cs index 0833f02ef..5a28a791f 100644 --- a/src/kOS/Execution/CPU.cs +++ b/src/kOS/Execution/CPU.cs @@ -496,15 +496,17 @@ public string DumpVariables() { Variable v = globalVariables.Variables[ident]; line = ident; - line += " is a " + v.Value.GetType().FullName; - line += " with value = "; - line += v.Value == null ? "" : "" + v.Value; + if (v == null || v.Value == null) + line += "is "; + else + line += " is a " + v.Value.GetType().FullName + " with value = " + v.Value; } catch (Exception e) { // This is necessary because of the deprecation exceptions that // get raised by FlightStats when you try to print all of them out: line = ident + "= \n " + e.Message; + line += "\n" + e.StackTrace; // eraseme. } msg.AppendLine(line); } From de13f4318851a50fef829243fcc20260c4b0282b Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Sun, 29 Mar 2015 04:25:19 -0500 Subject: [PATCH 314/446] READY?! Please everyone give it a go. - Renamed methods talking about locks so they say UserFunction - Tested last cases: recursion, calling a library of methods. - Refactored built-in calls to use $ now, and return dummy returns. - Added some test scripts to kerboscript_tests/user_functions See the test scripts in the PR (kerboscrit_test/user_functions) to get a feel for what the new feature does and how you use it. What I'd really like people to do is regression test it by running it on their old scripts - try it out on scripts that you knew worked in the past to ensure they still work now. One difference I see is that it has enlarged the size of the kRisc code to such a degree that now KSM files are no longer smaller than their KS sources. I'm not sure how much I still care about this given that we'll be making the limits bigger soon anyway. --- kerboscript_tests/user_functions/functest1.ks | 23 ++ kerboscript_tests/user_functions/functest2.ks | 34 +++ kerboscript_tests/user_functions/functest3.ks | 44 ++++ kerboscript_tests/user_functions/functest4.ks | 40 +++ kerboscript_tests/user_functions/functest5.ks | 12 + kerboscript_tests/user_functions/functest6.ks | 12 + kerboscript_tests/user_functions/functest7.ks | 15 ++ kerboscript_tests/user_functions/functest8.ks | 17 ++ src/kOS.Safe/Compilation/KS/Compiler.cs | 160 +++++++----- src/kOS.Safe/Compilation/KS/Context.cs | 4 +- src/kOS.Safe/Compilation/KS/KSScript.cs | 2 +- src/kOS.Safe/Compilation/KS/LockCollection.cs | 75 ------ .../KS/{Lock.cs => UserFunction.cs} | 30 +-- ...unction.cs => UserFunctionCodeFragment.cs} | 4 +- .../Compilation/KS/UserFunctionCollection.cs | 75 ++++++ src/kOS.Safe/Compilation/Opcode.cs | 24 +- src/kOS.Safe/Execution/ICpu.cs | 2 + src/kOS.Safe/kOS.Safe.csproj | 6 +- src/kOS/Execution/CPU.cs | 27 +- src/kOS/Function/BuildList.cs | 5 +- src/kOS/Function/FunctionBase.cs | 126 +++++++++ src/kOS/Function/FunctionManager.cs | 2 + src/kOS/Function/Math.cs | 103 +++++--- src/kOS/Function/Misc.cs | 87 ++++--- src/kOS/Function/Persistence.cs | 25 +- src/kOS/Function/PrintList.cs | 3 +- src/kOS/Function/Suffixed.cs | 242 ++++++++++-------- src/kOS/Function/Trigonometry.cs | 44 ++-- 28 files changed, 874 insertions(+), 369 deletions(-) create mode 100644 kerboscript_tests/user_functions/functest1.ks create mode 100644 kerboscript_tests/user_functions/functest2.ks create mode 100644 kerboscript_tests/user_functions/functest3.ks create mode 100644 kerboscript_tests/user_functions/functest4.ks create mode 100644 kerboscript_tests/user_functions/functest5.ks create mode 100644 kerboscript_tests/user_functions/functest6.ks create mode 100644 kerboscript_tests/user_functions/functest7.ks create mode 100644 kerboscript_tests/user_functions/functest8.ks delete mode 100644 src/kOS.Safe/Compilation/KS/LockCollection.cs rename src/kOS.Safe/Compilation/KS/{Lock.cs => UserFunction.cs} (77%) rename src/kOS.Safe/Compilation/KS/{LockFunction.cs => UserFunctionCodeFragment.cs} (70%) create mode 100644 src/kOS.Safe/Compilation/KS/UserFunctionCollection.cs diff --git a/kerboscript_tests/user_functions/functest1.ks b/kerboscript_tests/user_functions/functest1.ks new file mode 100644 index 000000000..f9a547ff6 --- /dev/null +++ b/kerboscript_tests/user_functions/functest1.ks @@ -0,0 +1,23 @@ +// Basic simple function define function test: + +set glob_one to 10. +set x to 0. + +lock bar to 5. +declare function foo { + declare x to 1. + print "Inside function foo: x is " + x. + + return "FooValue". +}. + +print "Before calling foo(), outside of foo, x is " + x. + +print "return value from foo() is: " + foo(). + +print "After calling foo(), outside of foo, x is " + x. + +print "using a lock, bar = " + bar. + +print "Deliberate error to force a program dump:". +set x to 1/0. diff --git a/kerboscript_tests/user_functions/functest2.ks b/kerboscript_tests/user_functions/functest2.ks new file mode 100644 index 000000000..1d1cb5ced --- /dev/null +++ b/kerboscript_tests/user_functions/functest2.ks @@ -0,0 +1,34 @@ +// Testing basic functions with args + +// Test that the declare parameter statement still +// does its job at the global level to be used with +// the RUN command like before: +declare parameter global_start_param. +declare parameter global_stop_param. + +// example of use: +// RUN FUNCTEST1(1,5). - counts from 1 to 5, and from 1^2 to 5^2. + +declare function foo { + // Test a mixture of both comma args style and separate arg + // statements style: + declare parameter a. + declare parameter b, c. + declare str to "inside foo(), ". + set str to str + " a=" + a. + set str to str + " b=" + b. + set str to str + " c=" + c. + return str. +}. + + +declare num to global_start_param. +print "num = " + num. +print "global_stop_param = " + global_stop_param. +until num > global_stop_param { + print "calling FOO: " + foo(num, num^2, sqrt(num)). + set num to num + 1. +}. + +print "deliberate errror to force a dump in the log.". +set x to 1/0. diff --git a/kerboscript_tests/user_functions/functest3.ks b/kerboscript_tests/user_functions/functest3.ks new file mode 100644 index 000000000..7ddca9c41 --- /dev/null +++ b/kerboscript_tests/user_functions/functest3.ks @@ -0,0 +1,44 @@ +// Functions: testing recursive case: note this just loads the functions +// and does nothing else. functest8.ks actually calls this. + +// ------------------------------- +// printBranch() +// ------------------------------- +declare function printBranch { + declare parameter thisPart. + declare parameter indentText. + + // print that: + print indentText + thisPart. // printing thispart's ToString(). + + // recurse into the part's children: + for childPart in thisPart:CHILDREN { + printBranch( childPart, indentText + " "). + }. +}. +// ------------------------------- +// printAllParts +// ------------------------------- +declare function printAllParts { + + // this is a function rather than just being in the global code + // because it's testing a feature - calling a function from another + // function at its "sibling" nest level: Args passed to the + // function need to be fully dereferenced so the function being + // called can see the values wihtout seeing the variables they were in. + // + + // In this example, rPart is local to this function, but we're passing it + // to printBranch(), which can't see rPart. Therefore this only works + // if rPart is being coorectly derferenced upon being put into an arg list, + // which is what is being tested here. + declare rPart to SHIP:ROOTPART. + + printBranch( rpart, ""). + +} + +print "functest3 ran successfully.". // just to prove it worked. + // a real library would probably be + // silent and say nothing. + diff --git a/kerboscript_tests/user_functions/functest4.ks b/kerboscript_tests/user_functions/functest4.ks new file mode 100644 index 000000000..339fe77ad --- /dev/null +++ b/kerboscript_tests/user_functions/functest4.ks @@ -0,0 +1,40 @@ +// functest4. +// An example of a complex function scoping situation with +// nested functions. + +declare a to 1. + +declare function foo { + declare parameter parm. + declare b to 2. + + declare function foo_bar { + declare c to 3. + + return "a is " + a + ", b is " + b + ", c is " + c + " parm is " + parm. + }. + + return foo_bar(). +}. + +print "calling foo() from global scope: " + foo(100). + +// pointless nesting +{ + + declare function more_pointless_nesting { + declare a to 5. + print "calling foo() from local scope depth 2: " + foo(100). + }. + declare a to 4. + print "calling foo() from local scope depth 1: " + foo(100). + + more_pointless_nesting(). +}. + +// Should print this every time no matter where it's called from: +// a is 1, b is 2, c is 3, parm is 100. +// not this: +// a is 4, b is 2, c is 3, parm is 100. +// nor this: +// a is 5, b is 2, c is 3, parm is 100. diff --git a/kerboscript_tests/user_functions/functest5.ks b/kerboscript_tests/user_functions/functest5.ks new file mode 100644 index 000000000..4c81fe518 --- /dev/null +++ b/kerboscript_tests/user_functions/functest5.ks @@ -0,0 +1,12 @@ +// One test of the nolazyglobal keyword. +// This should work correctly. + +set x to 1. // this should make a global x for us. + +print "next line should bomb out because lazyglobal isn't at the top.". +@lazyglobal off. + +declare function foo { + set z to 1. +}. +foo(). diff --git a/kerboscript_tests/user_functions/functest6.ks b/kerboscript_tests/user_functions/functest6.ks new file mode 100644 index 000000000..7e4d44cfa --- /dev/null +++ b/kerboscript_tests/user_functions/functest6.ks @@ -0,0 +1,12 @@ +// One test of the nolazyglobal keyword. +// This should error out because nolazyglobal isn't at global scope. + +set x to 1. // this should make a global x for us. + + +declare function foo { + print "next line should bomb out because lazyglobal is nested inside braces". + @lazyglobal off. + set z to 1. +}. +foo(). diff --git a/kerboscript_tests/user_functions/functest7.ks b/kerboscript_tests/user_functions/functest7.ks new file mode 100644 index 000000000..9ec6c1810 --- /dev/null +++ b/kerboscript_tests/user_functions/functest7.ks @@ -0,0 +1,15 @@ +// One test of the nolazyglobal keyword. +// This should work correctly. + +@lazyglobal off. // at the top - should be okay. + +declare x to 1. // this should be fine. +set x to 2. // this should be fine because x exists now. +print "Should bomb out with error because there was no 'declare y' statement and lazyglobals disabled.". +set y to 1. + +declare function foo { + set z to 1. + print "this should not get this far: z = " + z. +}. +foo(). diff --git a/kerboscript_tests/user_functions/functest8.ks b/kerboscript_tests/user_functions/functest8.ks new file mode 100644 index 000000000..2a79dcf09 --- /dev/null +++ b/kerboscript_tests/user_functions/functest8.ks @@ -0,0 +1,17 @@ +// Prove that one file can call functions defined in another file. + +run functest3. // library of functions to be used from here. + +print "------------------------------------". +print "Now printing the tree starting from all parts you named 'printme'.". +print "------------------------------------". + +set printMeParts to ship:partstagged("printme"). +if printMeParts:length = 0 { + print "You need to give at least one part the nametag of 'printme' to run this program.". +} else { + for p in printMeParts { + print "----- Branch starting with part " + p + " -----". + printBranch(p, ""). // this function is actually defined in functest3.ks + } +} diff --git a/src/kOS.Safe/Compilation/KS/Compiler.cs b/src/kOS.Safe/Compilation/KS/Compiler.cs index 62e1be1e5..e02614f3d 100644 --- a/src/kOS.Safe/Compilation/KS/Compiler.cs +++ b/src/kOS.Safe/Compilation/KS/Compiler.cs @@ -172,17 +172,17 @@ private void PreProcess(ParseTree tree) { ParseNode rootNode = tree.Nodes[0]; TraverseScopeBranch(rootNode); - PreProcessLocks(rootNode); + PreProcessUserFunctions(rootNode); PreProcessStatements(rootNode); } - private void PreProcessLocks(ParseNode node) + private void PreProcessUserFunctions(ParseNode node) { - IterateLocks(node, IdentifyLocks); - IterateLocks(node, PreProcessLockStatement); + IterateUserFunctions(node, IdentifyUserFunctions); + IterateUserFunctions(node, PreProcessUserFunctionStatement); } - private void IterateLocks(ParseNode node, Action action) + private void IterateUserFunctions(ParseNode node, Action action) { switch (node.Token.Type) { @@ -198,7 +198,7 @@ private void IterateLocks(ParseNode node, Action action) case TokenType.on_stmt: case TokenType.when_stmt: foreach (ParseNode childNode in node.Nodes) - IterateLocks(childNode, action); + IterateUserFunctions(childNode, action); break; // These are the statements we're searching for to work on here: @@ -211,7 +211,7 @@ private void IterateLocks(ParseNode node, Action action) // forward-calls into my nested functions, because they've been compiled and we know where they live // in memory now. foreach (ParseNode childNode in node.Nodes) - IterateLocks(childNode, action); + IterateUserFunctions(childNode, action); action.Invoke(node); break; @@ -372,20 +372,20 @@ private string ConcatenateNodes(ParseNode node) return concatenated; } - private void IdentifyLocks(ParseNode node) + private void IdentifyUserFunctions(ParseNode node) { if (node.Nodes.Count <= 0 ) return; - string lockIdentifier; + string funcIdentifier; if (IsLockStatement(node)) - lockIdentifier = node.Nodes[1].Token.Text; + funcIdentifier = node.Nodes[1].Token.Text; else if (IsDefineFunctionStatement(node)) - lockIdentifier = node.Nodes[2].Token.Text; + funcIdentifier = node.Nodes[2].Token.Text; else return; // not one of the types of statement we're really meant to run IdentifyLocks on. - context.Locks.GetLock(lockIdentifier); + context.UserFunctions.GetUserFunction(funcIdentifier); } private bool IsLockStatement(ParseNode node) @@ -412,12 +412,14 @@ private bool IsInsideDefineFunctionStatement(ParseNode node) return false; } - private void PreProcessLockStatement(ParseNode node) + // This is actually used for BOTH LOCK expressions and DEFINE FUNCTIONs, as they + // both end up creating, effectively, a user function. + private void PreProcessUserFunctionStatement(ParseNode node) { NodeStartHousekeeping(node); // The name of the lock or function to be executed: - string lockIdentifier; + string userFuncIdentifier; // The syntax node for the body of the lock or function: the stuff it actually executes. ParseNode bodyNode; @@ -425,18 +427,18 @@ private void PreProcessLockStatement(ParseNode node) bool isDefFunc = IsDefineFunctionStatement(node); if (isLock) { - lockIdentifier = node.Nodes[1].Token.Text; // The IDENT of: LOCK IDENT TO EXPR. + userFuncIdentifier = node.Nodes[1].Token.Text; // The IDENT of: LOCK IDENT TO EXPR. bodyNode = node.Nodes[3]; // The EXPR of: LOCK IDENT TO EXPR. } else if (isDefFunc) { - lockIdentifier = node.Nodes[2].Token.Text; // The IDENT of: DEFINE FUNCTION IDENT INSTRUCTION_BLOCK. + userFuncIdentifier = node.Nodes[2].Token.Text; // The IDENT of: DEFINE FUNCTION IDENT INSTRUCTION_BLOCK. bodyNode = node.Nodes[3]; // The INSTRUCTION_BLOCK of: DEFINE FUNCTION IDENT INSTRUCTION_BLOCK. } else return; // In principle this shouldn't have ever been called in this case. - Lock lockObject = context.Locks.GetLock(lockIdentifier); + UserFunction userFuncObject = context.UserFunctions.GetUserFunction(userFuncIdentifier); int expressionHash = ConcatenateNodes(node.Nodes[3]).GetHashCode(); needImplicitReturn = true; // Locks always need an implicit return. Functions might not if all paths have an explicit one. @@ -450,25 +452,25 @@ private void PreProcessLockStatement(ParseNode node) // exist exactly once, and can be "forward" called from higher up in // the same scope so they get assigned when the scope is first opened. // - if (isLock && !lockObject.IsInitialized()) + if (isLock && !userFuncObject.IsInitialized()) { - currentCodeSection = lockObject.InitializationCode; + currentCodeSection = userFuncObject.InitializationCode; - if (lockObject.IsSystemLock()) + if (userFuncObject.IsSystemLock()) { - AddOpcode(new OpcodePush(lockObject.PointerIdentifier)); - AddOpcode(new OpcodePushRelocateLater(null), lockObject.DefaultLabel); + AddOpcode(new OpcodePush(userFuncObject.PointerIdentifier)); + AddOpcode(new OpcodePushRelocateLater(null), userFuncObject.DefaultLabel); AddOpcode(new OpcodeStore()); // add trigger - string triggerIdentifier = "lock-" + lockObject.Identifier; + string triggerIdentifier = "lock-" + userFuncObject.Identifier; Trigger triggerObject = context.Triggers.GetTrigger(triggerIdentifier); short rememberLastLine = lastLine; lastLine = -1; // special flag telling the error handler that these opcodes came from the system itself, when reporting the error currentCodeSection = triggerObject.Code; - AddOpcode(new OpcodePush("$" + lockObject.Identifier)); + AddOpcode(new OpcodePush("$" + userFuncObject.Identifier)); AddOpcode(new OpcodePush(OpcodeCall.ARG_MARKER_STRING)); // need these for all locks now. - AddOpcode(new OpcodeCall(lockObject.PointerIdentifier)); + AddOpcode(new OpcodeCall(userFuncObject.PointerIdentifier)); if (allowLazyGlobal) AddOpcode(new OpcodeStore()); else @@ -489,13 +491,13 @@ private void PreProcessLockStatement(ParseNode node) } // build default dummy function to be used when this is a LOCK: - currentCodeSection = lockObject.GetLockFunction(0); - AddOpcode(new OpcodePush("$" + lockObject.Identifier)).Label = lockObject.DefaultLabel; + currentCodeSection = userFuncObject.GetUserFunctionOpcodes(0); + AddOpcode(new OpcodePush("$" + userFuncObject.Identifier)).Label = userFuncObject.DefaultLabel; AddOpcode(new OpcodeReturn()); } // lock expression's or function body's code - currentCodeSection = lockObject.GetLockFunction(expressionHash); + currentCodeSection = userFuncObject.GetUserFunctionOpcodes(expressionHash); if (isDefFunc) nextBraceIsFunction = true; VisitNode(bodyNode); @@ -509,8 +511,8 @@ private void PreProcessLockStatement(ParseNode node) } if (isDefFunc) { - lockObject.ScopeNode = GetContainingBlockNode(node); // This limits the scope of the function to the instruction_block the DEFINE was in. - lockObject.IsFunction = true; + userFuncObject.ScopeNode = GetContainingBlockNode(node); // This limits the scope of the function to the instruction_block the DEFINE was in. + userFuncObject.IsFunction = true; } } @@ -563,9 +565,11 @@ private void PreProcessRunStatement(ParseNode node) AddOpcode(branchOpcode); // if it wasn't then load it now AddOpcode(new OpcodePush(subprogramObject.PointerIdentifier)); + AddOpcode(new OpcodePush(OpcodeCall.ARG_MARKER_STRING)); AddOpcode(new OpcodePush(subprogramObject.SubprogramName)); AddOpcode(new OpcodePush(null)); // The output filename - only used for compile-to-file rather than for running. AddOpcode(new OpcodeCall("load()")); + AddOpcode(new OpcodePop()); // all functions now return a value even if it's a dummy we ignore. // store the address of the program in the pointer variable // (the load() function pushes the address onto the stack) AddOpcode(new OpcodeStore()); @@ -1168,13 +1172,10 @@ private void VisitActualFunction(ParseNode node, bool isDirect, bool isUserFunc, int parameterCount = 0; ParseNode trailerNode = node; // the function_trailer rule is here. - if (isUserFunc || !isDirect) - { - // Need to tell OpcodeCall where in the stack the bottom of the arg list is. - // Even if there are no arguments, it still has to be TOLD that by showing - // it the marker atop the stack with nothing above it. - AddOpcode(new OpcodePush(OpcodeCall.ARG_MARKER_STRING)); - } + // Need to tell OpcodeCall where in the stack the bottom of the arg list is. + // Even if there are no arguments, it still has to be TOLD that by showing + // it the marker atop the stack with nothing above it. + AddOpcode(new OpcodePush(OpcodeCall.ARG_MARKER_STRING)); if (trailerNode.Nodes[1].Token.Type == TokenType.arglist) { @@ -1268,10 +1269,10 @@ private void VisitSuffix(ParseNode node) if (nodeIndex == 0) { firstIdentifier = GetIdentifierText(suffixTerm); - if (context.Locks.Contains(firstIdentifier) && !compilingSetDestination) + if (context.UserFunctions.Contains(firstIdentifier) && !compilingSetDestination) { - Lock lockObject = context.Locks.GetLock(firstIdentifier); - firstIdentifier = lockObject.PointerIdentifier; + UserFunction userFuncObject = context.UserFunctions.GetUserFunction(firstIdentifier); + firstIdentifier = userFuncObject.PointerIdentifier; isUserFunc = true; } } @@ -1514,17 +1515,17 @@ private void VisitIdentifier(ParseNode node) bool isVariable = (identifierIsVariable && !identifierIsSuffix); string prefix = isVariable ? "$" : String.Empty; string identifier = GetIdentifierText(node); - if (isVariable && context.Locks.Contains(identifier)) + if (isVariable && context.UserFunctions.Contains(identifier)) { - Lock lockObject = context.Locks.GetLock(identifier); + UserFunction userFuncObject = context.UserFunctions.GetUserFunction(identifier); if (compilingSetDestination) { - UnlockIdentifier(lockObject); + UnlockIdentifier(userFuncObject); AddOpcode(new OpcodePush("$" + identifier)); } else { - AddOpcode(new OpcodeCall(lockObject.PointerIdentifier)); + AddOpcode(new OpcodeCall(userFuncObject.PointerIdentifier)); } } else @@ -1899,9 +1900,9 @@ private void VisitInstructionBlock(ParseNode node) private void AddFunctionJumpVars(ParseNode node) { // All the functions for which this scope is where they live: - IEnumerable theseFuncs = context.Locks.GetLockList().Where((item) => item.IsFunction && item.ScopeNode == node); + IEnumerable theseFuncs = context.UserFunctions.GetUserFunctionList().Where((item) => item.IsFunction && item.ScopeNode == node); - foreach (Lock func in theseFuncs) + foreach (UserFunction func in theseFuncs) { // Populate the LOCAL name with the function jump location. // By storing the mapping from identifier name to instruction jump point in @@ -1928,11 +1929,11 @@ private void VisitLockStatement(ParseNode node) NodeStartHousekeeping(node); string lockIdentifier = node.Nodes[1].Token.Text; int expressionHash = ConcatenateNodes(node.Nodes[3]).GetHashCode(); - Lock lockObject = context.Locks.GetLock(lockIdentifier); + UserFunction lockObject = context.UserFunctions.GetUserFunction(lockIdentifier); if (lockObject.IsInitialized()) { - string functionLabel = lockObject.GetLockFunction(expressionHash)[0].Label; + string functionLabel = lockObject.GetUserFunctionOpcodes(expressionHash)[0].Label; // lock variable AddOpcode(new OpcodePush(lockObject.PointerIdentifier)); AddOpcode(new OpcodePushRelocateLater(null), functionLabel); @@ -1953,6 +1954,7 @@ private void VisitLockStatement(ParseNode node) } // enable this FlyByWire parameter + AddOpcode(new OpcodePush(OpcodeCall.ARG_MARKER_STRING)); AddOpcode(new OpcodePush(lockIdentifier)); AddOpcode(new OpcodePush(true)); AddOpcode(new OpcodeCall("toggleflybywire()")); @@ -1968,24 +1970,26 @@ private void VisitUnlockStatement(ParseNode node) if (node.Nodes[1].Token.Type == TokenType.ALL) { // unlock all locks - foreach (Lock lockObject in context.Locks.GetLockList()) - UnlockIdentifier(lockObject); + foreach (UserFunction userFuncObject in context.UserFunctions.GetUserFunctionList()) + if (! userFuncObject.IsFunction) + UnlockIdentifier(userFuncObject); } else { string lockIdentifier = node.Nodes[1].Token.Text; - Lock lockObject = context.Locks.GetLock(lockIdentifier); + UserFunction lockObject = context.UserFunctions.GetUserFunction(lockIdentifier); UnlockIdentifier(lockObject); } } - private void UnlockIdentifier(Lock lockObject) + private void UnlockIdentifier(UserFunction lockObject) { if (lockObject.IsInitialized()) { if (lockObject.IsSystemLock()) { // disable this FlyByWire parameter + AddOpcode(new OpcodePush(OpcodeCall.ARG_MARKER_STRING)); AddOpcode(new OpcodePush(lockObject.Identifier)); AddOpcode(new OpcodePush(false)); AddOpcode(new OpcodeCall("toggleflybywire()")); @@ -2122,49 +2126,63 @@ private void VisitPrintStatement(ParseNode node) NodeStartHousekeeping(node); if (node.Nodes.Count == 3) { + AddOpcode(new OpcodePush(OpcodeCall.ARG_MARKER_STRING)); VisitNode(node.Nodes[1]); AddOpcode(new OpcodeCall("print()")); + AddOpcode(new OpcodePop()); // all functions now return a value even if it's a dummy we ignore. } else { + AddOpcode(new OpcodePush(OpcodeCall.ARG_MARKER_STRING)); VisitNode(node.Nodes[1]); VisitNode(node.Nodes[4]); VisitNode(node.Nodes[6]); AddOpcode(new OpcodeCall("printat()")); + AddOpcode(new OpcodePop()); // all functions now return a value even if it's a dummy we ignore. } } private void VisitStageStatement(ParseNode node) { NodeStartHousekeeping(node); + AddOpcode(new OpcodePush(OpcodeCall.ARG_MARKER_STRING)); AddOpcode(new OpcodeCall("stage()")); + AddOpcode(new OpcodePop()); // all functions now return a value even if it's a dummy we ignore. } private void VisitAddStatement(ParseNode node) { NodeStartHousekeeping(node); + AddOpcode(new OpcodePush(OpcodeCall.ARG_MARKER_STRING)); VisitNode(node.Nodes[1]); AddOpcode(new OpcodeCall("add()")); + AddOpcode(new OpcodePop()); // all functions now return a value even if it's a dummy we ignore. } private void VisitRemoveStatement(ParseNode node) { NodeStartHousekeeping(node); + AddOpcode(new OpcodePush(OpcodeCall.ARG_MARKER_STRING)); VisitNode(node.Nodes[1]); AddOpcode(new OpcodeCall("remove()")); + AddOpcode(new OpcodePop()); // all functions now return a value even if it's a dummy we ignore. } private void VisitClearStatement(ParseNode node) { NodeStartHousekeeping(node); + AddOpcode(new OpcodePush(OpcodeCall.ARG_MARKER_STRING)); AddOpcode(new OpcodeCall("clearscreen()")); + AddOpcode(new OpcodePop()); // all functions now return a value even if it's a dummy we ignore. } private void VisitEditStatement(ParseNode node) { NodeStartHousekeeping(node); + AddOpcode(new OpcodePush(OpcodeCall.ARG_MARKER_STRING)); VisitNode(node.Nodes[1]); AddOpcode(new OpcodeCall("edit()")); + AddOpcode(new OpcodePop()); // all functions now return a value even if it's a dummy we ignore. } private void VisitRunStatement(ParseNode node) @@ -2173,19 +2191,14 @@ private void VisitRunStatement(ParseNode node) int volumeIndex = 3; // process program arguments - if (options.LoadProgramsInSameAddressSpace) - { - // If running inside the same prog, it needs the arg marker to exist twice because it will - // call a subroutine that in turn checks to see if it's loaded and then calls the real - // program, which will itself have a return as well, which outermost programs don't have: - AddOpcode(new OpcodePush(OpcodeCall.ARG_MARKER_STRING)); - AddOpcode(new OpcodePush(OpcodeCall.ARG_MARKER_STRING)); - } + AddOpcode(new OpcodePush(OpcodeCall.ARG_MARKER_STRING)); // regardless of whether it's called directly or indirectly, we still need at least one. + if (node.Nodes.Count > 3 && node.Nodes[3].Token.Type == TokenType.arglist) { VisitNode(node.Nodes[3]); volumeIndex += 3; } + AddOpcode(new OpcodePush(OpcodeCall.ARG_MARKER_STRING)); // separates the RUN() args (progname, volume) from the args to the program the RUn is running. bool hasON = node.Nodes.Any(cn => cn.Token.Type == TokenType.ON); if (!hasON && options.LoadProgramsInSameAddressSpace) @@ -2210,13 +2223,18 @@ private void VisitRunStatement(ParseNode node) AddOpcode(new OpcodePush(null)); AddOpcode(new OpcodeCall("run()")); - AddOpcode(new OpcodePop()); // ditch the dummy return value for now - maybe we can use it in a later version. + + // Note: it is not an error that there are two Pop's here: There are two levels of return value - one from the program run + // and one from the function call run(): + AddOpcode(new OpcodePop()); // ditch the program exit's dummy return value for now - maybe we can use it in a later version. + AddOpcode(new OpcodePop()); // ditch the run()'s dummy return value for now - maybe we can use it in a later version. } } private void VisitCompileStatement(ParseNode node) { NodeStartHousekeeping(node); + AddOpcode(new OpcodePush(OpcodeCall.ARG_MARKER_STRING)); // for the load() function. VisitNode(node.Nodes[1]); if (node.Nodes.Count > 3) { @@ -2231,24 +2249,29 @@ private void VisitCompileStatement(ParseNode node) AddOpcode(new OpcodePush("-default-compile-out-")); } AddOpcode(new OpcodeCall("load()")); - } + AddOpcode(new OpcodePop()); // all functions now return a value even if it's a dummy we ignore. + } private void VisitSwitchStatement(ParseNode node) { NodeStartHousekeeping(node); + AddOpcode(new OpcodePush(OpcodeCall.ARG_MARKER_STRING)); VisitNode(node.Nodes[2]); AddOpcode(new OpcodeCall("switch()")); + AddOpcode(new OpcodePop()); // all functions now return a value even if it's a dummy we ignore. } private void VisitCopyStatement(ParseNode node) { NodeStartHousekeeping(node); + AddOpcode(new OpcodePush(OpcodeCall.ARG_MARKER_STRING)); VisitNode(node.Nodes[1]); AddOpcode(new OpcodePush(node.Nodes[2].Token.Type == TokenType.FROM ? "from" : "to")); VisitNode(node.Nodes[3]); AddOpcode(new OpcodeCall("copy()")); + AddOpcode(new OpcodePop()); // all functions now return a value even if it's a dummy we ignore. } private void VisitRenameStatement(ParseNode node) @@ -2257,6 +2280,7 @@ private void VisitRenameStatement(ParseNode node) int oldNameIndex = 2; int newNameIndex = 4; + AddOpcode(new OpcodePush(OpcodeCall.ARG_MARKER_STRING)); if (node.Nodes.Count == 5) { oldNameIndex--; @@ -2271,11 +2295,13 @@ private void VisitRenameStatement(ParseNode node) VisitNode(node.Nodes[oldNameIndex]); VisitNode(node.Nodes[newNameIndex]); AddOpcode(new OpcodeCall("rename()")); + AddOpcode(new OpcodePop()); // all functions now return a value even if it's a dummy we ignore. } private void VisitDeleteStatement(ParseNode node) { NodeStartHousekeeping(node); + AddOpcode(new OpcodePush(OpcodeCall.ARG_MARKER_STRING)); VisitNode(node.Nodes[1]); if (node.Nodes.Count == 5) @@ -2284,6 +2310,7 @@ private void VisitDeleteStatement(ParseNode node) AddOpcode(new OpcodePush(null)); AddOpcode(new OpcodeCall("delete()")); + AddOpcode(new OpcodePop()); // all functions now return a value even if it's a dummy we ignore. } private void VisitListStatement(ParseNode node) @@ -2297,6 +2324,7 @@ private void VisitListStatement(ParseNode node) // destination variable VisitVariableNode(node.Nodes[3]); // list type + AddOpcode(new OpcodePush(OpcodeCall.ARG_MARKER_STRING)); VisitNode(node.Nodes[1]); // build list AddOpcode(new OpcodeCall("buildlist()")); @@ -2307,20 +2335,24 @@ private void VisitListStatement(ParseNode node) } else { + AddOpcode(new OpcodePush(OpcodeCall.ARG_MARKER_STRING)); // list type if (hasIdentifier) VisitNode(node.Nodes[1]); else AddOpcode(new OpcodePush("files")); // print list AddOpcode(new OpcodeCall("printlist()")); + AddOpcode(new OpcodePop()); // all functions now return a value even if it's a dummy we ignore. } } private void VisitLogStatement(ParseNode node) { NodeStartHousekeeping(node); + AddOpcode(new OpcodePush(OpcodeCall.ARG_MARKER_STRING)); VisitNode(node.Nodes[1]); VisitNode(node.Nodes[3]); AddOpcode(new OpcodeCall("logfile()")); + AddOpcode(new OpcodePop()); // all functions now return a value even if it's a dummy we ignore. } private void VisitBreakStatement(ParseNode node) @@ -2394,13 +2426,17 @@ private void VisitPreserveStatement(ParseNode node) private void VisitRebootStatement(ParseNode node) { NodeStartHousekeeping(node); + AddOpcode(new OpcodePush(OpcodeCall.ARG_MARKER_STRING)); AddOpcode(new OpcodeCall("reboot()")); + AddOpcode(new OpcodePop()); // all functions now return a value even if we ignore it. Not sure it matters in the case of reboot() though. } private void VisitShutdownStatement(ParseNode node) { NodeStartHousekeeping(node); + AddOpcode(new OpcodePush(OpcodeCall.ARG_MARKER_STRING)); AddOpcode(new OpcodeCall("shutdown()")); + AddOpcode(new OpcodePop()); // all functions now return a value even if we ignore it. Not sure it matters in the case of shutdown() though. } private void VisitForStatement(ParseNode node) diff --git a/src/kOS.Safe/Compilation/KS/Context.cs b/src/kOS.Safe/Compilation/KS/Context.cs index 2cd6f1e33..512775484 100644 --- a/src/kOS.Safe/Compilation/KS/Context.cs +++ b/src/kOS.Safe/Compilation/KS/Context.cs @@ -4,7 +4,7 @@ namespace kOS.Safe.Compilation.KS { public class Context { - public LockCollection Locks { get; private set; } + public UserFunctionCollection UserFunctions { get; private set; } public TriggerCollection Triggers { get; private set; } public SubprogramCollection Subprograms { get; private set; } public int LabelIndex { get; set; } @@ -19,7 +19,7 @@ public class Context public Context() { - Locks = new LockCollection(); + UserFunctions = new UserFunctionCollection(); Triggers = new TriggerCollection(); Subprograms = new SubprogramCollection(); LabelIndex = 0; diff --git a/src/kOS.Safe/Compilation/KS/KSScript.cs b/src/kOS.Safe/Compilation/KS/KSScript.cs index b8d8c0c32..d597edb5e 100644 --- a/src/kOS.Safe/Compilation/KS/KSScript.cs +++ b/src/kOS.Safe/Compilation/KS/KSScript.cs @@ -41,7 +41,7 @@ public override List Compile(string filePath, int startLineNum, string CodePart mainPart = compiler.Compile(startLineNum, parseTree, currentContext, options); // add locks and triggers - parts.AddRange(currentContext.Locks.GetNewParts()); + parts.AddRange(currentContext.UserFunctions.GetNewParts()); parts.AddRange(currentContext.Triggers.GetNewParts()); parts.AddRange(currentContext.Subprograms.GetNewParts()); diff --git a/src/kOS.Safe/Compilation/KS/LockCollection.cs b/src/kOS.Safe/Compilation/KS/LockCollection.cs deleted file mode 100644 index 5750ad07c..000000000 --- a/src/kOS.Safe/Compilation/KS/LockCollection.cs +++ /dev/null @@ -1,75 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; - -namespace kOS.Safe.Compilation.KS -{ - public class LockCollection - { - private readonly Dictionary locks; - private readonly List newLocks; - - public LockCollection() - { - locks = new Dictionary(StringComparer.OrdinalIgnoreCase); - newLocks = new List(); - } - - public bool Contains(string lockIdentifier) - { - return locks.ContainsKey(lockIdentifier); - } - - public Lock GetLock(string lockIdentifier) - { - if (locks.ContainsKey(lockIdentifier)) - { - return locks[lockIdentifier]; - } - var lockObject = new Lock(lockIdentifier); - locks.Add(lockIdentifier, lockObject); - newLocks.Add(lockObject); - return lockObject; - } - - public IEnumerable GetLockList() - { - return locks.Values.ToList(); - } - - public List GetParts(IEnumerable lockList) - { - return lockList.Select(lockObject => lockObject.GetCodePart()).ToList(); - } - - public List GetParts() - { - return GetParts(locks.Values.ToList()); - } - - public IEnumerable GetNewParts() - { - // new locks - List parts = GetParts(newLocks); - - // updated locks - foreach (Lock lockObject in locks.Values) - { - // if the lock is new then clear the new functions list - if (newLocks.Contains(lockObject)) - { - lockObject.ClearNewFunctions(); - } - else if (lockObject.HasNewFunctions()) - { - // if the lock has new functions then create a new code part for them - parts.Add(lockObject.GetNewFunctionsCodePart()); - } - } - - newLocks.Clear(); - - return parts; - } - } -} \ No newline at end of file diff --git a/src/kOS.Safe/Compilation/KS/Lock.cs b/src/kOS.Safe/Compilation/KS/UserFunction.cs similarity index 77% rename from src/kOS.Safe/Compilation/KS/Lock.cs rename to src/kOS.Safe/Compilation/KS/UserFunction.cs index b188ca1ee..1eaba5536 100644 --- a/src/kOS.Safe/Compilation/KS/Lock.cs +++ b/src/kOS.Safe/Compilation/KS/UserFunction.cs @@ -3,13 +3,13 @@ namespace kOS.Safe.Compilation.KS { - public class Lock + public class UserFunction { private static readonly List systemLocks = new List { "throttle", "steering", "wheelthrottle", "wheelsteering" }; private readonly CodePart codePart; - private readonly Dictionary functions; - private readonly List newFunctions; + private readonly Dictionary functions; + private readonly List newFunctions; public string Identifier { get; private set; } public string PointerIdentifier{ get; private set; } @@ -33,17 +33,17 @@ public List MainCode get { return codePart.MainCode; } } - public Lock() + public UserFunction() { codePart = new CodePart(); - functions = new Dictionary(); - newFunctions = new List(); + functions = new Dictionary(); + newFunctions = new List(); } - public Lock(string lockIdentifier) + public UserFunction(string userFuncIdentifier) : this() { - Identifier = lockIdentifier; + Identifier = userFuncIdentifier; PointerIdentifier = "$" + Identifier + "*"; DefaultLabel = Identifier + "-default"; } @@ -69,16 +69,16 @@ public string GetFuncLabel() return functions.Values.FirstOrDefault().Code[0].Label; } - public List GetLockFunction(int expressionHash) + public List GetUserFunctionOpcodes(int expressionHash) { if (functions.ContainsKey(expressionHash)) { return functions[expressionHash].Code; } - var newLockFunction = new LockFunction(); - functions.Add(expressionHash, newLockFunction); - newFunctions.Add(newLockFunction); - return newLockFunction.Code; + var newUserFuncFragment = new UserFunctionCodeFragment(); + functions.Add(expressionHash, newUserFuncFragment); + newFunctions.Add(newUserFuncFragment); + return newUserFuncFragment.Code; } public CodePart GetCodePart() @@ -89,7 +89,7 @@ public CodePart GetCodePart() MainCode = codePart.MainCode }; - foreach (LockFunction function in functions.Values) + foreach (UserFunctionCodeFragment function in functions.Values) { mergedPart.FunctionsCode.AddRange(function.Code); } @@ -111,7 +111,7 @@ public CodePart GetNewFunctionsCodePart() { var newFunctionsPart = new CodePart(); - foreach (LockFunction function in newFunctions) + foreach (UserFunctionCodeFragment function in newFunctions) { newFunctionsPart.FunctionsCode.AddRange(function.Code); } diff --git a/src/kOS.Safe/Compilation/KS/LockFunction.cs b/src/kOS.Safe/Compilation/KS/UserFunctionCodeFragment.cs similarity index 70% rename from src/kOS.Safe/Compilation/KS/LockFunction.cs rename to src/kOS.Safe/Compilation/KS/UserFunctionCodeFragment.cs index db397a5a8..71873e75e 100644 --- a/src/kOS.Safe/Compilation/KS/LockFunction.cs +++ b/src/kOS.Safe/Compilation/KS/UserFunctionCodeFragment.cs @@ -2,11 +2,11 @@ namespace kOS.Safe.Compilation.KS { - public class LockFunction + public class UserFunctionCodeFragment { public List Code { get; private set; } - public LockFunction() + public UserFunctionCodeFragment() { Code = new List(); } diff --git a/src/kOS.Safe/Compilation/KS/UserFunctionCollection.cs b/src/kOS.Safe/Compilation/KS/UserFunctionCollection.cs new file mode 100644 index 000000000..29f4c510f --- /dev/null +++ b/src/kOS.Safe/Compilation/KS/UserFunctionCollection.cs @@ -0,0 +1,75 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace kOS.Safe.Compilation.KS +{ + public class UserFunctionCollection + { + private readonly Dictionary userFuncs; + private readonly List newUserFuncs; + + public UserFunctionCollection() + { + userFuncs = new Dictionary(StringComparer.OrdinalIgnoreCase); + newUserFuncs = new List(); + } + + public bool Contains(string userFuncIdentifier) + { + return userFuncs.ContainsKey(userFuncIdentifier); + } + + public UserFunction GetUserFunction(string userFuncIdentifier) + { + if (userFuncs.ContainsKey(userFuncIdentifier)) + { + return userFuncs[userFuncIdentifier]; + } + var userFuncObject = new UserFunction(userFuncIdentifier); + userFuncs.Add(userFuncIdentifier, userFuncObject); + newUserFuncs.Add(userFuncObject); + return userFuncObject; + } + + public IEnumerable GetUserFunctionList() + { + return userFuncs.Values.ToList(); + } + + public List GetParts(IEnumerable userFuncList) + { + return userFuncList.Select(userFunctionObject => userFunctionObject.GetCodePart()).ToList(); + } + + public List GetParts() + { + return GetParts(userFuncs.Values.ToList()); + } + + public IEnumerable GetNewParts() + { + // new locks or functions + List parts = GetParts(newUserFuncs); + + // updated locks or functions + foreach (UserFunction userFuncObject in userFuncs.Values) + { + // if the lock or function is new then clear the new functions list + if (newUserFuncs.Contains(userFuncObject)) + { + userFuncObject.ClearNewFunctions(); + } + else if (userFuncObject.HasNewFunctions()) + { + // if the lock has new functions then create a new code part for them + parts.Add(userFuncObject.GetNewFunctionsCodePart()); + } + } + + newUserFuncs.Clear(); + + return parts; + } + } +} \ No newline at end of file diff --git a/src/kOS.Safe/Compilation/Opcode.cs b/src/kOS.Safe/Compilation/Opcode.cs index fe83b7060..31a603751 100644 --- a/src/kOS.Safe/Compilation/Opcode.cs +++ b/src/kOS.Safe/Compilation/Opcode.cs @@ -1160,8 +1160,25 @@ public override void Execute(ICpu cpu) return; } } - - + + // If it's a string it might not really be a built-in, it might still be a user func. + // Detect whether it's built-in, and if it's not, then convert it into the equivalent + // user func call by making it be an integer instruction pointer instead: + if (functionPointer is string) + { + string functionName = functionPointer as string; + if (functionName.EndsWith("()")) + functionName = functionName.Substring(0, functionName.Length - 2); + if (!(cpu.BuiltInExists(functionName))) + { + // It is not a built-in, so instead get its value as a user function pointer variable, despite + // the fact that it's being called AS IF it was direct. + if (!functionName.EndsWith("*")) functionName = functionName + "*"; + if (!functionName.StartsWith("$")) functionName = "$" + functionName; + functionPointer = cpu.GetValue(functionName); + } + } + if (functionPointer is int) { ReverseStackArgs(cpu); @@ -1177,7 +1194,8 @@ public override void Execute(ICpu cpu) // might want to change that. var name = functionPointer as string; string functionName = name; - functionName = functionName.Substring(0, functionName.Length - 2); + if (functionName.EndsWith("()")) + functionName = functionName.Substring(0, functionName.Length - 2); cpu.CallBuiltinFunction(functionName); } else if (functionPointer is Delegate) diff --git a/src/kOS.Safe/Execution/ICpu.cs b/src/kOS.Safe/Execution/ICpu.cs index d4c4a8846..5fc4a6c52 100644 --- a/src/kOS.Safe/Execution/ICpu.cs +++ b/src/kOS.Safe/Execution/ICpu.cs @@ -13,6 +13,7 @@ public interface ICpu : IUpdateObserver object GetValue(object testValue, bool barewordOkay = false); object PopValue(bool barewordOkay = false); object PeekValue(int digDepth, bool barewordOkay = false); + object PeekRaw(int digDepth, out bool checkOkay); int GetStackSize(); void SetValue(string identifier, object value); void SetValueExists(string identifier, object value); @@ -26,6 +27,7 @@ public interface ICpu : IUpdateObserver void StartWait(double waitTime); void EndWait(); void CallBuiltinFunction(string functionName); + bool BuiltInExists(string functionName); void BreakExecution(bool manual); void AddVariable(Variable variable, string identifier, bool local); Opcode GetOpcodeAt(int instructionPtr); diff --git a/src/kOS.Safe/kOS.Safe.csproj b/src/kOS.Safe/kOS.Safe.csproj index 1057e34ae..95414b042 100644 --- a/src/kOS.Safe/kOS.Safe.csproj +++ b/src/kOS.Safe/kOS.Safe.csproj @@ -52,9 +52,9 @@ - - - + + + diff --git a/src/kOS/Execution/CPU.cs b/src/kOS/Execution/CPU.cs index 5a28a791f..1f16a09fa 100644 --- a/src/kOS/Execution/CPU.cs +++ b/src/kOS/Execution/CPU.cs @@ -506,7 +506,6 @@ public string DumpVariables() // This is necessary because of the deprecation exceptions that // get raised by FlightStats when you try to print all of them out: line = ident + "= \n " + e.Message; - line += "\n" + e.StackTrace; // eraseme. } msg.AppendLine(line); } @@ -705,7 +704,11 @@ public object PopValue(bool barewordOkay = false) /// /// Peek at a value atop the stack without popping it, and if it's a variable name then get its value, - /// else just return it as it is. + /// else just return it as it is.
    + ///
    + /// NOTE: Evaluating variables when you don't really need to is pointlessly expensive, as it + /// needs to walk the scoping stack to exhaust a search. If you don't need to evaluate variables, + /// then consider using PeekRaw() instead.
    ///
    /// Peek at the element this far down the stack (0 means top, 1 means just under the top, etc) /// Is this a context in which it's acceptable for @@ -716,6 +719,21 @@ public object PeekValue(int digDepth, bool barewordOkay = false) { return GetValue(stack.Peek(digDepth), barewordOkay); } + + /// + /// Peek at a value atop the stack without popping it, and without evaluating it to get the variable's + /// value. (i.e. if the thing in the stack is $foo, and the variable foo has value 5, you'll get the string + /// "$foo" returned, not the integer 5). + /// + /// Peek at the element this far down the stack (0 means top, 1 means just under the top, etc) + /// Tells you whether or not the stack was exhausted. If it's false, then the peek went too deep. + /// value off the stack + public object PeekRaw(int digDepth, out bool checkOkay) + { + object returnValue; + checkOkay = stack.PeekCheck(digDepth,out returnValue); + return returnValue; + } public int GetStackSize() { @@ -953,6 +971,11 @@ public void CallBuiltinFunction(string functionName) { shared.FunctionManager.CallFunction(functionName); } + + public bool BuiltInExists(string functionName) + { + return shared.FunctionManager.Exists(functionName); + } public void ToggleFlyByWire(string paramName, bool enabled) { diff --git a/src/kOS/Function/BuildList.cs b/src/kOS/Function/BuildList.cs index 8ab014d1b..cb2477303 100644 --- a/src/kOS/Function/BuildList.cs +++ b/src/kOS/Function/BuildList.cs @@ -13,7 +13,7 @@ public class FunctionBuildList : FunctionBase { public override void Execute(SharedObjects shared) { - string listType = shared.Cpu.PopValue().ToString(); + string listType = PopValueAssert(shared).ToString(); var list = new ListValue(); switch (listType) @@ -45,8 +45,9 @@ public override void Execute(SharedObjects shared) default: throw new ArgumentOutOfRangeException(); } + AssertArgBottomAndConsume(shared); - shared.Cpu.PushStack(list); + ReturnValue = list; } } } diff --git a/src/kOS/Function/FunctionBase.cs b/src/kOS/Function/FunctionBase.cs index fd3927725..b67715e7f 100644 --- a/src/kOS/Function/FunctionBase.cs +++ b/src/kOS/Function/FunctionBase.cs @@ -1,11 +1,48 @@ using System; +using System.Linq; using kOS.Suffixed; using kOS.Safe.Exceptions; +using kOS.Safe.Compilation; +using kOS.Safe.Function; namespace kOS.Function { public class FunctionBase { + /// + /// ALL FUNCTIONS in kOS will always have exactly one return value. We have no + /// "void" functions, to keep the execution logic consistent and simple. Therefore + /// even a function that never explicitly picks a return value still gets one by + /// default anyway that will be pushed on the stack after its Execute() is called. + /// That is what this property is for. If you wish your built-in function to put a + /// specific return value on the stack set its ReturnValue property in its Execute() + /// method, and the pushing of it onto the stack will be handled for you. Don't push + /// it onto the stack manually, as that would result in a double-push. + /// If you decline to set ReturnValue, it will get a default value of zero anyway. + /// + public object ReturnValue {get; set;} + + /// + /// In the *extremely* rare case where a built-in function is NOT supposed to + /// push a value onto the stack as its return value, and these are very uncommon, + /// it should set this to false. By default it will be true. + /// Cases where this might occur are cases where the function will artificially mangle + /// the execution order by jumping the instruction pointer to somewhere else, in a way + /// other than with an actual proper jump or call opcode. Right now the function run() is the only + /// one that does this and needs the exception.
    + /// Think very carefully before setting this to false in your function, and only do so if + /// you really know what you're doing and have fully understood the system.
    + /// If you set this to false, it means you are manually manipulating the stack to give it your own + /// wierd return behavior. + ///
    + public bool UsesAutoReturn {get; set;} + + public FunctionBase() + { + ReturnValue = (int)0; // default return value ALL built-ins will have if they don't set it. + UsesAutoReturn = true; + } + public virtual void Execute(SharedObjects shared) { } @@ -85,5 +122,94 @@ protected double RadiansToDegrees(double radians) { return radians * 180 / Math.PI; } + + /// + /// A utility function that a function's Execute() must use after it has popped all the + /// arguments it was expecting from the stack. It will assert that all the arguments + /// have been consumed exactly, and the next item on the stack is the arg bottom mark. + /// It will consume the arg bottom mark as well. + ///
    + /// If the assert fails, an exception is thrown. + ///
    + /// + protected void AssertArgBottomAndConsume(SharedObjects shared) + { + object shouldBeBottom = shared.Cpu.PopStack(); + if (shouldBeBottom is string && ((string)shouldBeBottom).Equals(OpcodeCall.ARG_MARKER_STRING)) + return; // Assert passed. + + throw new KOSArgumentMismatchException("Too many arguments were passed to " + GetFuncName()); + } + + /// + /// A utility function that a function's Execute() may use if it wishes to, to get a count of + /// how many args passed to it that it has not yet consumed still remain on the stack. + /// + /// + /// Number of args as yet unpopped. returns zero if there are no args, or -1 if there's a bug and the argstart marker is missing. + protected int CountRemainingArgs(SharedObjects shared) + { + int depth = 0; + bool found = false; + bool stillInStack = true; + while (stillInStack && !found) + { + object peekItem = shared.Cpu.PeekRaw(depth, out stillInStack); + if (stillInStack && peekItem is string && ((string)peekItem).Equals(OpcodeCall.ARG_MARKER_STRING)) + found = true; + else + ++depth; + } + if (found) + return depth; + else + return -1; + } + + /// + /// A utility function that a function's Execute() should use in place of cpu.PopValue(), + /// because it will assert that the value being popped is NOT an ARG_MARKER_STRING, and if it + /// is, it will throw the appropriate error. + /// + /// + protected object PopValueAssert(SharedObjects shared, bool barewordOkay = false) + { + object returnValue = shared.Cpu.PopValue(barewordOkay); + if (returnValue is string && ((string)returnValue).Equals(OpcodeCall.ARG_MARKER_STRING)) + throw new KOSArgumentMismatchException("Too few arguments were passed to " + GetFuncName()); + return returnValue; + } + + /// + /// A utility function that a function's Execute() should use in place of cpu.PopStack(), + /// because it will assert that the value being popped is NOT an ARG_MARKER_STRING, and if it + /// is, it will throw the appropriate error. + /// + /// + protected object PopStackAssert(SharedObjects shared) + { + object returnValue = shared.Cpu.PopStack(); + if (returnValue is string && ((string)returnValue).Equals(OpcodeCall.ARG_MARKER_STRING)) + throw new KOSArgumentMismatchException("Too few arguments were passed to " + GetFuncName()); + return returnValue; + } + + protected string GetFuncName() + { + // The following is all just to extract the function name from the attribute. + // That really should be easier + string funcName = ""; // hopefully this cannot ever get seen by the user because of the next lines. + FunctionAttribute attr = (FunctionAttribute)GetType().GetCustomAttributes(typeof(FunctionAttribute), true).FirstOrDefault(); + if (attr != null) + { + // Of all the possible alias names, lets pick the longest one, as the most verbose description: + string longestOne = ""; + foreach (string name in attr.Names) + if (name.Length > longestOne.Length) + longestOne = name; + funcName = longestOne; + } + return funcName; + } } } diff --git a/src/kOS/Function/FunctionManager.cs b/src/kOS/Function/FunctionManager.cs index c38ffbe2c..2aa3f819e 100644 --- a/src/kOS/Function/FunctionManager.cs +++ b/src/kOS/Function/FunctionManager.cs @@ -44,6 +44,8 @@ public void CallFunction(string functionName) FunctionBase function = functions[functionName]; function.Execute(shared); + if (function.UsesAutoReturn) + shared.Cpu.PushStack(function.ReturnValue); } /// diff --git a/src/kOS/Function/Math.cs b/src/kOS/Function/Math.cs index 48498e545..5ae582ff2 100644 --- a/src/kOS/Function/Math.cs +++ b/src/kOS/Function/Math.cs @@ -2,6 +2,7 @@ using kOS.Safe.Compilation; using kOS.Safe.Function; using kOS.Suffixed; +using kOS.Safe.Exceptions; namespace kOS.Function { @@ -10,9 +11,10 @@ public class FunctionAbs : FunctionBase { public override void Execute(SharedObjects shared) { - double argument = GetDouble(shared.Cpu.PopValue()); + double argument = GetDouble(PopValueAssert(shared)); + AssertArgBottomAndConsume(shared); double result = Math.Abs(argument); - shared.Cpu.PushStack(result); + ReturnValue = result; } } @@ -21,10 +23,11 @@ public class FunctionMod : FunctionBase { public override void Execute(SharedObjects shared) { - double divisor = GetDouble(shared.Cpu.PopValue()); - double dividend = GetDouble(shared.Cpu.PopValue()); + double divisor = GetDouble(PopValueAssert(shared)); + double dividend = GetDouble(PopValueAssert(shared)); + AssertArgBottomAndConsume(shared); double result = dividend % divisor; - shared.Cpu.PushStack(result); + ReturnValue = result; } } @@ -33,9 +36,10 @@ public class FunctionFloor : FunctionBase { public override void Execute(SharedObjects shared) { - double argument = GetDouble(shared.Cpu.PopValue()); + double argument = GetDouble(PopValueAssert(shared)); + AssertArgBottomAndConsume(shared); double result = Math.Floor(argument); - shared.Cpu.PushStack(result); + ReturnValue = result; } } @@ -44,9 +48,10 @@ public class FunctionCeiling : FunctionBase { public override void Execute(SharedObjects shared) { - double argument = GetDouble(shared.Cpu.PopValue()); + double argument = GetDouble(PopValueAssert(shared)); + AssertArgBottomAndConsume(shared); double result = Math.Ceiling(argument); - shared.Cpu.PushStack(result); + ReturnValue = result; } } @@ -55,9 +60,10 @@ public class FunctionRoundNearest : FunctionBase { public override void Execute(SharedObjects shared) { - double argument = GetDouble(shared.Cpu.PopValue()); + double argument = GetDouble(PopValueAssert(shared)); + AssertArgBottomAndConsume(shared); double result = Math.Round(argument); - shared.Cpu.PushStack(result); + ReturnValue = result; } } @@ -66,10 +72,11 @@ public class FunctionRound : FunctionBase { public override void Execute(SharedObjects shared) { - int decimals = GetInt(shared.Cpu.PopValue()); - double argument = GetDouble(shared.Cpu.PopValue()); + int decimals = GetInt(PopValueAssert(shared)); + double argument = GetDouble(PopValueAssert(shared)); + AssertArgBottomAndConsume(shared); double result = Math.Round(argument, decimals); - shared.Cpu.PushStack(result); + ReturnValue = result; } } @@ -78,9 +85,10 @@ public class FunctionSqrt : FunctionBase { public override void Execute(SharedObjects shared) { - double argument = GetDouble(shared.Cpu.PopValue()); + double argument = GetDouble(PopValueAssert(shared)); + AssertArgBottomAndConsume(shared); double result = Math.Sqrt(argument); - shared.Cpu.PushStack(result); + ReturnValue = result; } } @@ -89,9 +97,10 @@ public class FunctionLn : FunctionBase { public override void Execute(SharedObjects shared) { - double argument = GetDouble(shared.Cpu.PopValue()); + double argument = GetDouble(PopValueAssert(shared)); + AssertArgBottomAndConsume(shared); double result = Math.Log(argument); - shared.Cpu.PushStack(result); + ReturnValue = result; } } @@ -100,9 +109,10 @@ public class FunctionLog10 : FunctionBase { public override void Execute(SharedObjects shared) { - double argument = GetDouble(shared.Cpu.PopValue()); + double argument = GetDouble(PopValueAssert(shared)); + AssertArgBottomAndConsume(shared); double result = Math.Log10(argument); - shared.Cpu.PushStack(result); + ReturnValue = result; } } @@ -111,12 +121,13 @@ public class FunctionMin : FunctionBase { public override void Execute(SharedObjects shared) { - object argument1 = shared.Cpu.PopValue(); - object argument2 = shared.Cpu.PopValue(); + object argument1 = PopValueAssert(shared); + object argument2 = PopValueAssert(shared); + AssertArgBottomAndConsume(shared); Calculator calculator = Calculator.GetCalculator(argument1, argument2); object result = calculator.Min(argument1, argument2); - shared.Cpu.PushStack(result); + ReturnValue = result; } } @@ -125,12 +136,13 @@ public class FunctionMax : FunctionBase { public override void Execute(SharedObjects shared) { - object argument1 = shared.Cpu.PopValue(); - object argument2 = shared.Cpu.PopValue(); + object argument1 = PopValueAssert(shared); + object argument2 = PopValueAssert(shared); + AssertArgBottomAndConsume(shared); Calculator calculator = Calculator.GetCalculator(argument1, argument2); object result = calculator.Max(argument1, argument2); - shared.Cpu.PushStack(result); + ReturnValue = result; } } @@ -141,7 +153,8 @@ public class FunctionRandom : FunctionBase public override void Execute(SharedObjects shared) { - shared.Cpu.PushStack(random.NextDouble()); + AssertArgBottomAndConsume(shared); + ReturnValue = random.NextDouble(); } } @@ -150,14 +163,17 @@ public class FunctionVectorCross : FunctionBase { public override void Execute(SharedObjects shared) { - var vector2 = GetVector(shared.Cpu.PopValue()); - var vector1 = GetVector(shared.Cpu.PopValue()); + var vector2 = GetVector(PopValueAssert(shared)); + var vector1 = GetVector(PopValueAssert(shared)); + AssertArgBottomAndConsume(shared); if (vector1 != null && vector2 != null) { object result = new Vector(Vector3d.Cross(vector1, vector2)); - shared.Cpu.PushStack(result); + ReturnValue = result; } + else + throw new KOSException("vector cross product attempted with a non-vector value"); } } @@ -166,14 +182,17 @@ public class FunctionVectorDot : FunctionBase { public override void Execute(SharedObjects shared) { - var vector2 = GetVector(shared.Cpu.PopValue()); - var vector1 = GetVector(shared.Cpu.PopValue()); + var vector2 = GetVector(PopValueAssert(shared)); + var vector1 = GetVector(PopValueAssert(shared)); + AssertArgBottomAndConsume(shared); if (vector1 != null && vector2 != null) { object result = Vector3d.Dot(vector1, vector2); - shared.Cpu.PushStack(result); + ReturnValue = result; } + else + throw new KOSException("vector dot product attempted with a non-vector value"); } } @@ -182,14 +201,17 @@ public class FunctionVectorExclude : FunctionBase { public override void Execute(SharedObjects shared) { - var vector2 = GetVector(shared.Cpu.PopValue()); - var vector1 = GetVector(shared.Cpu.PopValue()); + var vector2 = GetVector(PopValueAssert(shared)); + var vector1 = GetVector(PopValueAssert(shared)); + AssertArgBottomAndConsume(shared); if (vector1 != null && vector2 != null) { object result = new Vector(Vector3d.Exclude(vector1, vector2)); - shared.Cpu.PushStack(result); + ReturnValue = result; } + else + throw new KOSException("vector exclude attempted with a non-vector value"); } } @@ -198,14 +220,17 @@ public class FunctionVectorAngle : FunctionBase { public override void Execute(SharedObjects shared) { - var vector2 = GetVector(shared.Cpu.PopValue()); - var vector1 = GetVector(shared.Cpu.PopValue()); + var vector2 = GetVector(PopValueAssert(shared)); + var vector1 = GetVector(PopValueAssert(shared)); + AssertArgBottomAndConsume(shared); if (vector1 != null && vector2 != null) { object result = Vector3d.Angle(vector1, vector2); - shared.Cpu.PushStack(result); + ReturnValue = result; } + else + throw new KOSException("vector angle calculation attempted with a non-vector value"); } } } diff --git a/src/kOS/Function/Misc.cs b/src/kOS/Function/Misc.cs index 105dd06d7..a9bdcb14f 100644 --- a/src/kOS/Function/Misc.cs +++ b/src/kOS/Function/Misc.cs @@ -16,6 +16,7 @@ public class FunctionClearScreen : FunctionBase { public override void Execute(SharedObjects shared) { + AssertArgBottomAndConsume(shared); shared.Window.ClearScreen(); } } @@ -25,7 +26,8 @@ public class FunctionPrint : FunctionBase { public override void Execute(SharedObjects shared) { - string textToPrint = shared.Cpu.PopValue().ToString(); + string textToPrint = PopValueAssert(shared).ToString(); + AssertArgBottomAndConsume(shared); shared.Screen.Print(textToPrint); } } @@ -36,12 +38,13 @@ public class FunctionHudText : FunctionBase public override void Execute (SharedObjects shared) { - bool echo = Convert.ToBoolean(shared.Cpu.PopValue()); - RgbaColor rgba = GetRgba(shared.Cpu.PopValue()); - int size = Convert.ToInt32 (shared.Cpu.PopValue ()); - int style = Convert.ToInt32 (shared.Cpu.PopValue ()); - int delay = Convert.ToInt32 (shared.Cpu.PopValue ()); - string textToHud = shared.Cpu.PopValue ().ToString (); + bool echo = Convert.ToBoolean(PopValueAssert(shared)); + RgbaColor rgba = GetRgba(PopValueAssert(shared)); + int size = Convert.ToInt32 (PopValueAssert(shared)); + int style = Convert.ToInt32 (PopValueAssert(shared)); + int delay = Convert.ToInt32 (PopValueAssert(shared)); + string textToHud = PopValueAssert(shared).ToString(); + AssertArgBottomAndConsume(shared); string htmlColour = rgba.ToHexNotation(); switch (style) { @@ -72,9 +75,10 @@ public class FunctionPrintAt : FunctionBase { public override void Execute(SharedObjects shared) { - int row = Convert.ToInt32(shared.Cpu.PopValue()); - int column = Convert.ToInt32(shared.Cpu.PopValue()); - string textToPrint = shared.Cpu.PopValue().ToString(); + int row = Convert.ToInt32(PopValueAssert(shared)); + int column = Convert.ToInt32(PopValueAssert(shared)); + string textToPrint = PopValueAssert(shared).ToString(); + AssertArgBottomAndConsume(shared); shared.Screen.PrintAt(textToPrint, row, column); } } @@ -84,13 +88,10 @@ public class FunctionToggleFlyByWire : FunctionBase { public override void Execute(SharedObjects shared) { - bool enabled = Convert.ToBoolean(shared.Cpu.PopValue()); - string paramName = shared.Cpu.PopValue().ToString(); + bool enabled = Convert.ToBoolean(PopValueAssert(shared)); + string paramName = PopValueAssert(shared).ToString(); + AssertArgBottomAndConsume(shared); ((CPU)shared.Cpu).ToggleFlyByWire(paramName, enabled); - // Work around to prevent the pop error following toggle fly by wire directly. - // The VisitIdentifierLedExpression method in the Compiler class purposfully throws away the returned value of a function. - ((CPU)shared.Cpu).PushStack(0); - } } @@ -99,11 +100,9 @@ public class FunctionSelectAutopilotMode : FunctionBase { public override void Execute(SharedObjects shared) { - string autopilotMode = shared.Cpu.PopValue().ToString(); + string autopilotMode = PopValueAssert(shared).ToString(); + AssertArgBottomAndConsume(shared); ((CPU)shared.Cpu).SelectAutopilotMode(autopilotMode); - // The VisitIdentifierLedExpression method in the Compiler class purposfully throws away the returned value of a function. - ((CPU)shared.Cpu).PushStack(0); - } } @@ -112,6 +111,7 @@ public class FunctionStage : FunctionBase { public override void Execute(SharedObjects shared) { + AssertArgBottomAndConsume(shared); if (Staging.separate_ready && shared.Vessel.isActiveVessel) { Staging.ActivateNextStage(); @@ -132,9 +132,19 @@ public class FunctionRun : FunctionBase { public override void Execute(SharedObjects shared) { - object volumeId = shared.Cpu.PopValue(true); - string fileName = shared.Cpu.PopValue(true).ToString(); + // run() is strange. It needs two levels of args - the args to itself, and the args it is meant to + // pass on to the program it's invoking. First, these are the args to run itself: + object volumeId = PopValueAssert(shared, true); + string fileName = PopValueAssert(shared, true).ToString(); + AssertArgBottomAndConsume(shared); + // Now the args it is going to be passing on to the program: + List prog_args = new List(); + int argc = CountRemainingArgs(shared); + for (int i = 0 ; i < argc ; ++i) + prog_args.Add(PopValueAssert(shared, true)); + AssertArgBottomAndConsume(shared); + if (shared.VolumeMgr == null) return; if (shared.VolumeMgr.CurrentVolume == null) throw new Exception("Volume not found"); @@ -183,6 +193,17 @@ public override void Execute(SharedObjects shared) } programContext.AddParts(codeParts); } + + // Because run() returns FIRST, and THEN the CPU jumps to the new program's first instruction that it set up, + // it needs to put the return stack in a weird order. Its return value needs to be buried UNDER the args to the + // program it's calling: + UsesAutoReturn = false; + + shared.Cpu.PushStack(0); // dummy return that all functions have. + + // Put the args for the program being called back on in the same order they were in before (so read the list backward): + for (int i = argc-1 ; i >= 0 ; --i) + shared.Cpu.PushStack(prog_args[i]); } } @@ -194,7 +215,7 @@ public override void Execute(SharedObjects shared) bool defaultOutput = false; bool justCompiling = false; // is this load() happening to compile, or to run? string fileNameOut = null; - object topStack = shared.Cpu.PopValue(true); // null if there's no output file (output file means compile, not run). + object topStack = PopValueAssert(shared, true); // null if there's no output file (output file means compile, not run). if (topStack != null) { justCompiling = true; @@ -206,9 +227,11 @@ public override void Execute(SharedObjects shared) } string fileName = null; - topStack = shared.Cpu.PopValue(true); + topStack = PopValueAssert(shared, true); if (topStack != null) fileName = topStack.ToString(); + + AssertArgBottomAndConsume(shared); if (fileName == null) throw new KOSFileException("No filename to load was given."); @@ -265,7 +288,8 @@ public class FunctionAddNode : FunctionBase { public override void Execute(SharedObjects shared) { - var node = (Node)shared.Cpu.PopValue(); + var node = (Node)PopValueAssert(shared); + AssertArgBottomAndConsume(shared); node.AddToVessel(shared.Vessel); } } @@ -275,7 +299,8 @@ public class FunctionRemoveNode : FunctionBase { public override void Execute(SharedObjects shared) { - var node = (Node)shared.Cpu.PopValue(); + var node = (Node)PopValueAssert(shared); + AssertArgBottomAndConsume(shared); node.Remove(); } } @@ -285,8 +310,9 @@ public class FunctionLogFile : FunctionBase { public override void Execute(SharedObjects shared) { - string fileName = shared.Cpu.PopValue(true).ToString(); - string expressionResult = shared.Cpu.PopValue().ToString(); + string fileName = PopValueAssert(shared, true).ToString(); + string expressionResult = PopValueAssert(shared).ToString(); + AssertArgBottomAndConsume(shared); if (shared.VolumeMgr != null) { @@ -310,6 +336,7 @@ public override void Execute(SharedObjects shared) { if (shared.Processor != null) { + AssertArgBottomAndConsume(shared); // not sure if this matters when rebooting anwyway. shared.Processor.SetMode(ProcessorModes.OFF); shared.Processor.SetMode(ProcessorModes.READY); } @@ -321,6 +348,7 @@ public class FunctionShutdown : FunctionBase { public override void Execute(SharedObjects shared) { + AssertArgBottomAndConsume(shared); // not sure if this matters when shutting down anwyway. if (shared.Processor != null) shared.Processor.SetMode(ProcessorModes.OFF); } } @@ -330,7 +358,8 @@ public class DebugDump : FunctionBase { public override void Execute(SharedObjects shared) { - shared.Cpu.PushStack(shared.Cpu.DumpVariables()); + AssertArgBottomAndConsume(shared); + ReturnValue = shared.Cpu.DumpVariables(); } } } diff --git a/src/kOS/Function/Persistence.cs b/src/kOS/Function/Persistence.cs index f583c9758..9d953a276 100644 --- a/src/kOS/Function/Persistence.cs +++ b/src/kOS/Function/Persistence.cs @@ -11,7 +11,8 @@ public class FunctionSwitch : FunctionBase { public override void Execute(SharedObjects shared) { - object volumeId = shared.Cpu.PopValue(true); + object volumeId = PopValueAssert(shared, true); + AssertArgBottomAndConsume(shared); if (shared.VolumeMgr != null) { @@ -33,7 +34,8 @@ public class FunctionEdit : FunctionBase { public override void Execute(SharedObjects shared) { - string fileName = shared.Cpu.PopValue(true).ToString(); + string fileName = PopValueAssert(shared, true).ToString(); + AssertArgBottomAndConsume(shared); // If no filename extension, then give it one: fileName = PersistenceUtilities.CookedFilename(fileName, Volume.KERBOSCRIPT_EXTENSION); @@ -51,9 +53,10 @@ public class FunctionCopy : FunctionBase { public override void Execute(SharedObjects shared) { - object volumeId = shared.Cpu.PopValue(true); - string direction = shared.Cpu.PopValue().ToString(); - string fileName = shared.Cpu.PopValue(true).ToString(); + object volumeId = PopValueAssert(shared, true); + string direction = PopValueAssert(shared).ToString(); + string fileName = PopValueAssert(shared, true).ToString(); + AssertArgBottomAndConsume(shared); SafeHouse.Logger.Log(string.Format("FunctionCopy: Volume: {0} Direction: {1} Filename: {2}", volumeId, direction, fileName)); @@ -106,9 +109,10 @@ public class FunctionRename : FunctionBase { public override void Execute(SharedObjects shared) { - string newName = shared.Cpu.PopValue(true).ToString(); - object oldName = shared.Cpu.PopValue(true); - string objectToRename = shared.Cpu.PopValue().ToString(); + string newName = PopValueAssert(shared, true).ToString(); + object oldName = PopValueAssert(shared, true); + string objectToRename = PopValueAssert(shared).ToString(); + AssertArgBottomAndConsume(shared); if (shared.VolumeMgr != null) { @@ -162,8 +166,9 @@ public class FunctionDelete : FunctionBase { public override void Execute(SharedObjects shared) { - object volumeId = shared.Cpu.PopValue(true); - string fileName = shared.Cpu.PopValue(true).ToString(); + object volumeId = PopValueAssert(shared, true); + string fileName = PopValueAssert(shared, true).ToString(); + AssertArgBottomAndConsume(shared); if (shared.VolumeMgr != null) { diff --git a/src/kOS/Function/PrintList.cs b/src/kOS/Function/PrintList.cs index e82c30bf7..a40c299d9 100644 --- a/src/kOS/Function/PrintList.cs +++ b/src/kOS/Function/PrintList.cs @@ -14,7 +14,8 @@ public class FunctionPrintList : FunctionBase { public override void Execute(SharedObjects shared) { - string listType = shared.Cpu.PopValue().ToString(); + string listType = PopValueAssert(shared).ToString(); + AssertArgBottomAndConsume(shared); if (shared.Screen == null) return; diff --git a/src/kOS/Function/Suffixed.cs b/src/kOS/Function/Suffixed.cs index a9f631181..c241b82d0 100644 --- a/src/kOS/Function/Suffixed.cs +++ b/src/kOS/Function/Suffixed.cs @@ -3,6 +3,7 @@ using System.Linq; using kOS.Safe.Encapsulation; using kOS.Safe.Function; +using kOS.Safe.Exceptions; using kOS.Suffixed; using kOS.Utilities; using FinePrint; @@ -14,13 +15,14 @@ public class FunctionNode : FunctionBase { public override void Execute(SharedObjects shared) { - double prograde = GetDouble(shared.Cpu.PopValue()); - double normal = GetDouble(shared.Cpu.PopValue()); - double radial = GetDouble(shared.Cpu.PopValue()); - double time = GetDouble(shared.Cpu.PopValue()); + double prograde = GetDouble(PopValueAssert(shared)); + double normal = GetDouble(PopValueAssert(shared)); + double radial = GetDouble(PopValueAssert(shared)); + double time = GetDouble(PopValueAssert(shared)); + AssertArgBottomAndConsume(shared); var result = new Node(time, radial, normal, prograde, shared); - shared.Cpu.PushStack(result); + ReturnValue = result; } } @@ -29,12 +31,13 @@ public class FunctionVector : FunctionBase { public override void Execute(SharedObjects shared) { - double z = GetDouble(shared.Cpu.PopValue()); - double y = GetDouble(shared.Cpu.PopValue()); - double x = GetDouble(shared.Cpu.PopValue()); + double z = GetDouble(PopValueAssert(shared)); + double y = GetDouble(PopValueAssert(shared)); + double x = GetDouble(PopValueAssert(shared)); + AssertArgBottomAndConsume(shared); var result = new Vector(x, y, z); - shared.Cpu.PushStack(result); + ReturnValue = result; } } @@ -43,12 +46,13 @@ public class FunctionRotation : FunctionBase { public override void Execute(SharedObjects shared) { - double roll = GetDouble(shared.Cpu.PopValue()); - double yaw = GetDouble(shared.Cpu.PopValue()); - double pitch = GetDouble(shared.Cpu.PopValue()); + double roll = GetDouble(PopValueAssert(shared)); + double yaw = GetDouble(PopValueAssert(shared)); + double pitch = GetDouble(PopValueAssert(shared)); + AssertArgBottomAndConsume(shared); var result = new Direction(new Vector3d(pitch, yaw, roll), true); - shared.Cpu.PushStack(result); + ReturnValue = result; } } @@ -57,13 +61,14 @@ public class FunctionQuaternion : FunctionBase { public override void Execute(SharedObjects shared) { - double angle = GetDouble(shared.Cpu.PopValue()); - double roll = GetDouble(shared.Cpu.PopValue()); - double yaw = GetDouble(shared.Cpu.PopValue()); - double pitch = GetDouble(shared.Cpu.PopValue()); + double angle = GetDouble(PopValueAssert(shared)); + double roll = GetDouble(PopValueAssert(shared)); + double yaw = GetDouble(PopValueAssert(shared)); + double pitch = GetDouble(PopValueAssert(shared)); + AssertArgBottomAndConsume(shared); var result = new Direction(new UnityEngine.Quaternion((float)pitch, (float)yaw, (float)roll, (float)angle)); - shared.Cpu.PushStack(result); + ReturnValue = result; } } @@ -72,11 +77,12 @@ public class FunctionRotateFromTo : FunctionBase { public override void Execute(SharedObjects shared) { - Vector toVector = GetVector(shared.Cpu.PopValue()); - Vector fromVector = GetVector(shared.Cpu.PopValue()); + Vector toVector = GetVector(PopValueAssert(shared)); + Vector fromVector = GetVector(PopValueAssert(shared)); + AssertArgBottomAndConsume(shared); var result = Direction.FromVectorToVector(fromVector, toVector); - shared.Cpu.PushStack(result); + ReturnValue = result; } } @@ -85,11 +91,12 @@ public class FunctionLookDirUp : FunctionBase { public override void Execute(SharedObjects shared) { - Vector topVector = GetVector(shared.Cpu.PopValue()); - Vector lookVector = GetVector(shared.Cpu.PopValue()); + Vector topVector = GetVector(PopValueAssert(shared)); + Vector lookVector = GetVector(PopValueAssert(shared)); + AssertArgBottomAndConsume(shared); var result = Direction.LookRotation(lookVector, topVector); - shared.Cpu.PushStack(result); + ReturnValue = result; } } @@ -98,11 +105,12 @@ public class FunctionAngleAxis : FunctionBase { public override void Execute(SharedObjects shared) { - Vector axisVector = GetVector(shared.Cpu.PopValue()); - double degrees = GetDouble(shared.Cpu.PopValue()); + Vector axisVector = GetVector(PopValueAssert(shared)); + double degrees = GetDouble(PopValueAssert(shared)); + AssertArgBottomAndConsume(shared); var result = Direction.AngleAxis(degrees, axisVector); - shared.Cpu.PushStack(result); + ReturnValue = result; } } @@ -111,11 +119,12 @@ public class FunctionLatLng : FunctionBase { public override void Execute(SharedObjects shared) { - double longitude = GetDouble(shared.Cpu.PopValue()); - double latitude = GetDouble(shared.Cpu.PopValue()); + double longitude = GetDouble(PopValueAssert(shared)); + double latitude = GetDouble(PopValueAssert(shared)); + AssertArgBottomAndConsume(shared); var result = new GeoCoordinates(shared, latitude, longitude); - shared.Cpu.PushStack(result); + ReturnValue = result; } } @@ -124,9 +133,10 @@ public class FunctionVessel : FunctionBase { public override void Execute(SharedObjects shared) { - string vesselName = shared.Cpu.PopValue().ToString(); + string vesselName = PopValueAssert(shared).ToString(); + AssertArgBottomAndConsume(shared); var result = new VesselTarget(VesselUtils.GetVesselByName(vesselName, shared.Vessel), shared); - shared.Cpu.PushStack(result); + ReturnValue = result; } } @@ -135,9 +145,10 @@ public class FunctionBody : FunctionBase { public override void Execute(SharedObjects shared) { - string bodyName = shared.Cpu.PopValue().ToString(); + string bodyName = PopValueAssert(shared).ToString(); + AssertArgBottomAndConsume(shared); var result = new BodyTarget(bodyName, shared); - shared.Cpu.PushStack(result); + ReturnValue = result; } } @@ -146,9 +157,10 @@ public class FunctionBodyAtmosphere : FunctionBase { public override void Execute(SharedObjects shared) { - string bodyName = shared.Cpu.PopValue().ToString(); + string bodyName = PopValueAssert(shared).ToString(); + AssertArgBottomAndConsume(shared); var result = new BodyAtmosphere(VesselUtils.GetBodyByName(bodyName)); - shared.Cpu.PushStack(result); + ReturnValue = result; } } @@ -157,15 +169,16 @@ public class FunctionHeading : FunctionBase { public override void Execute(SharedObjects shared) { - double pitchAboveHorizon = GetDouble(shared.Cpu.PopValue()); - double degreesFromNorth = GetDouble(shared.Cpu.PopValue()); + double pitchAboveHorizon = GetDouble(PopValueAssert(shared)); + double degreesFromNorth = GetDouble(PopValueAssert(shared)); + AssertArgBottomAndConsume(shared); Vessel currentVessel = shared.Vessel; var q = UnityEngine.Quaternion.LookRotation(VesselUtils.GetNorthVector(currentVessel), currentVessel.upAxis); q *= UnityEngine.Quaternion.Euler(new UnityEngine.Vector3((float)-pitchAboveHorizon, (float)degreesFromNorth, 0)); var result = new Direction(q); - shared.Cpu.PushStack(result); + ReturnValue = result; } } @@ -174,8 +187,9 @@ public class FunctionList : FunctionBase { public override void Execute(SharedObjects shared) { + AssertArgBottomAndConsume(shared); var listValue = new ListValue(); - shared.Cpu.PushStack(listValue); + ReturnValue = listValue; } } @@ -184,10 +198,11 @@ public class FunctionHsv : FunctionBase { public override void Execute(SharedObjects shared) { - var v = (float) GetDouble(shared.Cpu.PopValue()); - var s = (float) GetDouble(shared.Cpu.PopValue()); - var h = (float) GetDouble(shared.Cpu.PopValue()); - shared.Cpu.PushStack( new HsvColor(h,s,v) ); + var v = (float) GetDouble(PopValueAssert(shared)); + var s = (float) GetDouble(PopValueAssert(shared)); + var h = (float) GetDouble(PopValueAssert(shared)); + AssertArgBottomAndConsume(shared); + ReturnValue = new HsvColor(h,s,v); } } @@ -196,11 +211,12 @@ public class FunctionHsva : FunctionBase { public override void Execute(SharedObjects shared) { - var a = (float) GetDouble(shared.Cpu.PopValue()); - var v = (float) GetDouble(shared.Cpu.PopValue()); - var s = (float) GetDouble(shared.Cpu.PopValue()); - var h = (float) GetDouble(shared.Cpu.PopValue()); - shared.Cpu.PushStack( new HsvColor(h,s,v,a) ); + var a = (float) GetDouble(PopValueAssert(shared)); + var v = (float) GetDouble(PopValueAssert(shared)); + var s = (float) GetDouble(PopValueAssert(shared)); + var h = (float) GetDouble(PopValueAssert(shared)); + AssertArgBottomAndConsume(shared); + ReturnValue = new HsvColor(h,s,v,a); } } @@ -209,10 +225,11 @@ public class FunctionRgb : FunctionBase { public override void Execute(SharedObjects shared) { - var b = (float) GetDouble(shared.Cpu.PopValue()); - var g = (float) GetDouble(shared.Cpu.PopValue()); - var r = (float) GetDouble(shared.Cpu.PopValue()); - shared.Cpu.PushStack( new RgbaColor(r,g,b) ); + var b = (float) GetDouble(PopValueAssert(shared)); + var g = (float) GetDouble(PopValueAssert(shared)); + var r = (float) GetDouble(PopValueAssert(shared)); + AssertArgBottomAndConsume(shared); + ReturnValue = new RgbaColor(r,g,b); } } @@ -221,11 +238,12 @@ public class FunctionRgba : FunctionBase { public override void Execute(SharedObjects shared) { - var a = (float) GetDouble(shared.Cpu.PopValue()); - var b = (float) GetDouble(shared.Cpu.PopValue()); - var g = (float) GetDouble(shared.Cpu.PopValue()); - var r = (float) GetDouble(shared.Cpu.PopValue()); - shared.Cpu.PushStack( new RgbaColor(r,g,b,a) ); + var a = (float) GetDouble(PopValueAssert(shared)); + var b = (float) GetDouble(PopValueAssert(shared)); + var g = (float) GetDouble(PopValueAssert(shared)); + var r = (float) GetDouble(PopValueAssert(shared)); + AssertArgBottomAndConsume(shared); + ReturnValue = new RgbaColor(r,g,b,a); } } @@ -233,34 +251,49 @@ public override void Execute(SharedObjects shared) // vecdraw() // or with // vecdrawargs(,vector,vector,rgba,double,bool) - // If varying args were more easily supported, this could - // be done with just one function that counts how many args it - // was given. // - [Function("vecdraw")] + // Note: vecdraw now counts the args and changes its behavior accordingly. + // For backward compatibility, vecdrawargs has been aliased to vecdraw. + // + [Function("vecdraw", "vecdrawargs")] public class FunctionVecDrawNull : FunctionBase { public override void Execute(SharedObjects shared) + { + int argc = CountRemainingArgs(shared); + // If I was called with arguments, then run the version of the constructor that takes args + if (argc == 6) + { + bool show = Convert.ToBoolean(PopValueAssert(shared)); + double scale = GetDouble(PopValueAssert(shared)); + string str = PopValueAssert(shared).ToString(); + RgbaColor rgba = GetRgba(PopValueAssert(shared)); + Vector vec = GetVector(PopValueAssert(shared)); + Vector start = GetVector(PopValueAssert(shared)); + AssertArgBottomAndConsume(shared); + DoExecuteWork(shared, start, vec, rgba, str, scale, show); + } + else if (argc == 0) + { + AssertArgBottomAndConsume(shared); // no args + DoExecuteWork(shared); // default constructor: + } + else + { + throw new KOSArgumentMismatchException("Vecdraw() expected either 0 or 6 arguments passed, but got " + argc +" instead."); + } + } + + public void DoExecuteWork(SharedObjects shared) { var vRend = new VectorRenderer( shared.UpdateHandler, shared ); vRend.SetShow( false ); - shared.Cpu.PushStack( vRend ); + ReturnValue = vRend; } - } - [Function("vecdrawargs")] - public class FunctionVecDraw : FunctionBase - { - public override void Execute(SharedObjects shared) + public void DoExecuteWork(SharedObjects shared, Vector start, Vector vec, RgbaColor rgba, string str, double scale, bool show) { - bool show = Convert.ToBoolean(shared.Cpu.PopValue()); - double scale = GetDouble(shared.Cpu.PopValue()); - string str = shared.Cpu.PopValue().ToString(); - RgbaColor rgba = GetRgba(shared.Cpu.PopValue()); - Vector vec = GetVector(shared.Cpu.PopValue()); - Vector start = GetVector(shared.Cpu.PopValue()); - var vRend = new VectorRenderer( shared.UpdateHandler, shared ) { Vector = vec, @@ -271,7 +304,7 @@ public override void Execute(SharedObjects shared) vRend.SetLabel( str ); vRend.SetShow( show ); - shared.Cpu.PushStack( vRend ); + ReturnValue = vRend; } } @@ -280,12 +313,11 @@ public class FunctionPositionAt : FunctionBase { public override void Execute(SharedObjects shared) { - var when = GetTimeSpan(shared.Cpu.PopValue()); - var what = GetOrbitable(shared.Cpu.PopValue()); + var when = GetTimeSpan(PopValueAssert(shared)); + var what = GetOrbitable(PopValueAssert(shared)); + AssertArgBottomAndConsume(shared); - var pos = what.GetPositionAtUT(when); - - shared.Cpu.PushStack(pos); + ReturnValue = what.GetPositionAtUT(when); } } @@ -294,12 +326,11 @@ public class FunctionVelocityAt : FunctionBase { public override void Execute(SharedObjects shared) { - var when = GetTimeSpan(shared.Cpu.PopValue()); - var what = GetOrbitable(shared.Cpu.PopValue()); + var when = GetTimeSpan(PopValueAssert(shared)); + var what = GetOrbitable(PopValueAssert(shared)); + AssertArgBottomAndConsume(shared); - var vels = what.GetVelocitiesAtUT(when); - - shared.Cpu.PushStack(vels); + ReturnValue = what.GetVelocitiesAtUT(when); } } @@ -308,11 +339,11 @@ public class FunctionHightlight : FunctionBase { public override void Execute(SharedObjects shared) { - var color = GetRgba(shared.Cpu.PopValue()); - var obj = shared.Cpu.PopValue(); + var color = GetRgba(PopValueAssert(shared)); + var obj = PopValueAssert(shared); + AssertArgBottomAndConsume(shared); - var toPush = new HighlightStructure(shared.UpdateHandler, obj, color); - shared.Cpu.PushStack(toPush); + ReturnValue = new HighlightStructure(shared.UpdateHandler, obj, color); } } @@ -321,12 +352,11 @@ public class FunctionOrbitAt : FunctionBase { public override void Execute(SharedObjects shared) { - var when = GetTimeSpan(shared.Cpu.PopValue()); - var what = GetOrbitable(shared.Cpu.PopValue()); + var when = GetTimeSpan(PopValueAssert(shared)); + var what = GetOrbitable(PopValueAssert(shared)); + AssertArgBottomAndConsume(shared); - var orb = new OrbitInfo( what.GetOrbitAtUT(when.ToUnixStyleTime()), shared ); - - shared.Cpu.PushStack(orb); + ReturnValue = new OrbitInfo( what.GetOrbitAtUT(when.ToUnixStyleTime()), shared ); } } @@ -335,8 +365,8 @@ public class FunctionCareer : FunctionBase { public override void Execute(SharedObjects shared) { - var career = new Career(); - shared.Cpu.PushStack(career); + AssertArgBottomAndConsume(shared); // no args + ReturnValue = new Career(); } } @@ -345,8 +375,8 @@ public class FunctionConstant : FunctionBase { public override void Execute(SharedObjects shared) { - var constants = new ConstantValue(); - shared.Cpu.PushStack(constants); + AssertArgBottomAndConsume(shared); // no args + ReturnValue = new ConstantValue(); } } @@ -355,6 +385,8 @@ public class FunctionAllWaypoints : FunctionBase { public override void Execute(SharedObjects shared) { + AssertArgBottomAndConsume(shared); // no args + // ReSharper disable SuggestUseVarKeywordEvident ListValue returnList = new ListValue(); // ReSharper enable SuggestUseVarKeywordEvident @@ -362,11 +394,10 @@ public override void Execute(SharedObjects shared) WaypointManager wpm = WaypointManager.Instance(); if (wpm == null) { - shared.Cpu.PushStack(returnList); // When no waypoints exist, there isn't even a waypoint manager at all. + ReturnValue = returnList; // When no waypoints exist, there isn't even a waypoint manager at all. return; } - List points = wpm.AllWaypoints(); // If the code below gets used in more places it may be worth moving into a factory method @@ -375,7 +406,7 @@ public override void Execute(SharedObjects shared) foreach (Waypoint point in points) returnList.Add(new WaypointValue(point, shared)); - shared.Cpu.PushStack(returnList); + ReturnValue = returnList; } } @@ -384,12 +415,13 @@ public class FunctionWaypoint : FunctionBase { public override void Execute(SharedObjects shared) { - string pointName = shared.Cpu.PopValue().ToString(); + string pointName = PopValueAssert(shared).ToString(); + AssertArgBottomAndConsume(shared); WaypointManager wpm = WaypointManager.Instance(); if (wpm == null) // When zero waypoints exist, there might not even be a waypoint manager. { - shared.Cpu.PushStack(null); + ReturnValue = null; // I don't like returning null here without the user being able to test for that, but // we don't have another way to communicate "no such waypoint". We really need to address // that problem once and for all. @@ -402,7 +434,7 @@ public override void Execute(SharedObjects shared) Waypoint point = wpm.AllWaypoints().FirstOrDefault( p => String.Equals(p.name, baseName,StringComparison.CurrentCultureIgnoreCase) && (!hasGreek || p.index == index)); - shared.Cpu.PushStack(new WaypointValue(point, shared)); + ReturnValue = new WaypointValue(point, shared); } } } diff --git a/src/kOS/Function/Trigonometry.cs b/src/kOS/Function/Trigonometry.cs index bfe912dcc..5088736b2 100644 --- a/src/kOS/Function/Trigonometry.cs +++ b/src/kOS/Function/Trigonometry.cs @@ -8,10 +8,11 @@ public class FunctionSin : FunctionBase { public override void Execute(SharedObjects shared) { - double degrees = GetDouble(shared.Cpu.PopValue()); + double degrees = GetDouble(PopValueAssert(shared)); + AssertArgBottomAndConsume(shared); double radians = DegreesToRadians(degrees); double result = Math.Sin(radians); - shared.Cpu.PushStack(result); + ReturnValue = result; } } @@ -20,10 +21,11 @@ public class FunctionCos : FunctionBase { public override void Execute(SharedObjects shared) { - double degrees = GetDouble(shared.Cpu.PopValue()); + double degrees = GetDouble(PopValueAssert(shared)); + AssertArgBottomAndConsume(shared); double radians = DegreesToRadians(degrees); double result = Math.Cos(radians); - shared.Cpu.PushStack(result); + ReturnValue = result; } } @@ -32,10 +34,11 @@ public class FunctionTan : FunctionBase { public override void Execute(SharedObjects shared) { - double degrees = GetDouble(shared.Cpu.PopValue()); + double degrees = GetDouble(PopValueAssert(shared)); + AssertArgBottomAndConsume(shared); double radians = DegreesToRadians(degrees); double result = Math.Tan(radians); - shared.Cpu.PushStack(result); + ReturnValue = result; } } @@ -44,9 +47,10 @@ public class FunctionArcSin : FunctionBase { public override void Execute(SharedObjects shared) { - double argument = GetDouble(shared.Cpu.PopValue()); + double argument = GetDouble(PopValueAssert(shared)); + AssertArgBottomAndConsume(shared); double result = RadiansToDegrees(Math.Asin(argument)); - shared.Cpu.PushStack(result); + ReturnValue = result; } } @@ -55,9 +59,10 @@ public class FunctionArcCos : FunctionBase { public override void Execute(SharedObjects shared) { - double argument = GetDouble(shared.Cpu.PopValue()); + double argument = GetDouble(PopValueAssert(shared)); + AssertArgBottomAndConsume(shared); double result = RadiansToDegrees(Math.Acos(argument)); - shared.Cpu.PushStack(result); + ReturnValue = result; } } @@ -66,9 +71,10 @@ public class FunctionArcTan : FunctionBase { public override void Execute(SharedObjects shared) { - double argument = GetDouble(shared.Cpu.PopValue()); + double argument = GetDouble(PopValueAssert(shared)); + AssertArgBottomAndConsume(shared); double result = RadiansToDegrees(Math.Atan(argument)); - shared.Cpu.PushStack(result); + ReturnValue = result; } } @@ -77,10 +83,11 @@ public class FunctionArcTan2 : FunctionBase { public override void Execute(SharedObjects shared) { - double x = GetDouble(shared.Cpu.PopValue()); - double y = GetDouble(shared.Cpu.PopValue()); + double x = GetDouble(PopValueAssert(shared)); + double y = GetDouble(PopValueAssert(shared)); + AssertArgBottomAndConsume(shared); double result = RadiansToDegrees(Math.Atan2(y, x)); - shared.Cpu.PushStack(result); + ReturnValue = result; } } @@ -89,10 +96,11 @@ public class FunctionAngleDiff : FunctionBase { public override void Execute(SharedObjects shared) { - double ang2 = GetDouble(shared.Cpu.PopValue()); - double ang1 = GetDouble(shared.Cpu.PopValue()); + double ang2 = GetDouble(PopValueAssert(shared)); + double ang1 = GetDouble(PopValueAssert(shared)); + AssertArgBottomAndConsume(shared); double result = kOS.Utilities.Utils.DegreeFix( ang2 - ang1, -180 ); - shared.Cpu.PushStack(result); + ReturnValue = result; } } } From 1ea2e94e9615f7333d12d3530cbd7dc8286f3237 Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Sun, 29 Mar 2015 04:48:15 -0500 Subject: [PATCH 315/446] Clarifications to CHANGELOG --- CHANGELOG.md | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3458c8280..a80e73068 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,10 @@ kOS Mod Changelog FUNCTIONS! FUNCTIONS! FUNCTIONS! -------------------------------- -Big feature: You can make your own user-defined functions. +Big feature: You can make your own user-defined functions, that +can handle recursion, and can use local variable scoping. You can +build a library of your own function calls and load them into your +script. ###BREAKING: - **RECOMPILE YOUR KSM FILES!!!** - changes to the kOS machine code @@ -14,6 +17,12 @@ Big feature: You can make your own user-defined functions. perform one compile and then use the new KSM file. If you don't do this, you will get the error message: ```The given key was not present in the dictionary.``` +- **KSM FILES ARE BIGGER** - compiled KSM files are now larger than + they used to be, due to extra code generated for dealing with + variable scoping and more universal function calling techniques. + Compiling to a KSM file will probably no longer be a reliable way + to make your code smaller, but we also intend to increase the volume + capacity to compensate. - *DECLARE has a new syntax* DECLARE _VARNAME_ now requires an initializier syntax as follows: - DECLARE _VARNAME_ TO _VALUE_. @@ -30,6 +39,9 @@ Big feature: You can make your own user-defined functions. The _VARIABLE_ in loops of the form FOR _VARIABLE_ IN _SOMELIST_ now has local scope to just that loop, meaning it stops existing after the loop is done and you can't use it outside the loop's body. + In the past you could try using it after the loop body, but this + was poor practice and was only allowed because we didn't have + variable scoping set up right. ###New Features: - *FUNCTIONS* @@ -54,6 +66,11 @@ Big feature: You can make your own user-defined functions. set twentySpaces to padString(" ", 20). set threeX to padString("X", 3). + If you'd like to create a library of utility functions for + yourself, you can make a kerboscript file that contains only + DECLARE FUNCTION statements, and then RUN it from the top of + your other scripts to load in all the functions it contains. + For the full documentation, see: http://ksp-kos.github.io/KOS/language/user_functions.html From 0192bd08bc0fa5a73a7f6898149f89b75a12ac1f Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Sun, 29 Mar 2015 23:17:45 -0500 Subject: [PATCH 316/446] Added my test scripts I ran to the branch. --- .../structures/misc/resource_transfer.rst | 2 +- .../resource_transfer/testtransfer1.ks | 36 ++++++++++ .../resource_transfer/testtransfer2.ks | 72 +++++++++++++++++++ .../resource_transfer/testtransfer3.ks | 38 ++++++++++ 4 files changed, 147 insertions(+), 1 deletion(-) create mode 100644 kerboscript_tests/resource_transfer/testtransfer1.ks create mode 100644 kerboscript_tests/resource_transfer/testtransfer2.ks create mode 100644 kerboscript_tests/resource_transfer/testtransfer3.ks diff --git a/doc/source/structures/misc/resource_transfer.rst b/doc/source/structures/misc/resource_transfer.rst index 94de1f3b0..7a30a7d29 100644 --- a/doc/source/structures/misc/resource_transfer.rst +++ b/doc/source/structures/misc/resource_transfer.rst @@ -22,7 +22,7 @@ Structure * - :attr:`STATUS` - string - Get only - - The string status of the transfer (eg "Inactive", "Transferring", "Failed") + - The string status of the transfer (eg "Inactive", "Transferring", "Failed", "Finished") * - :attr:`MESSAGE` - string - Get only diff --git a/kerboscript_tests/resource_transfer/testtransfer1.ks b/kerboscript_tests/resource_transfer/testtransfer1.ks new file mode 100644 index 000000000..b861412f9 --- /dev/null +++ b/kerboscript_tests/resource_transfer/testtransfer1.ks @@ -0,0 +1,36 @@ +print "THIS SCRIPT TESTS RESOURCE TRANSFER". +print "WHEN DOING IT BY LIST() of PARTS". + +set fromparts to ship:partstagged("from_us"). +set toparts to ship:partstagged("to_us"). + +if fromparts:length = 0 { + print "You need to pick some parts and give them nametag 'from_us'.". + print "deliberate error to die". + set x to 1/0. +}. + +if toparts:length = 0 { + print "You need to pick some parts and give them nametag 'to_us'.". + print "deliberate error to die". + set x to 1/0. +} + +print "Now transferring 90 liquidfuel from parts to parts". +set foo to transfer("liquidfuel",fromparts,toparts,90). +set foo:active to true. +until foo:status = "Finished" or foo:status = "Failed" { + print "transferred " + foo:transferred + " " + foo:resource + " so far. " + foo:status + " ...". + wait 0.2. +}. +print "transferred " + foo:transferred + " in total.". + + +print "Now transferring 110 oxidizer from parts to parts". +set foo to transfer("oxidizer",fromparts,toparts,110). +set foo:active to true. +until foo:status = "Finished" or foo:status = "Failed" { + print "transferred " + foo:transferred + " " + foo:resource + " so far. " + foo:status + " ...". + wait 0.2. +}. +print "transferred " + foo:transferred + " in total.". diff --git a/kerboscript_tests/resource_transfer/testtransfer2.ks b/kerboscript_tests/resource_transfer/testtransfer2.ks new file mode 100644 index 000000000..e276c13ca --- /dev/null +++ b/kerboscript_tests/resource_transfer/testtransfer2.ks @@ -0,0 +1,72 @@ +print "THIS SCRIPT TESTS RESOURCE TRANSFER". +print "WHEN DOING IT BY ELEMENTS.". +print " ". +print "To select which element to transfer from,". +print "just assign nametag 'from_this' to any of". +print "the parts inisde it.". +print " ". +print "To select which element to transfer to,". +print "just assign nametag 'to_this' to any of". +print "the parts inisde it.". + +set fromparts to ship:partstagged("from_this"). +set toparts to ship:partstagged("to_this"). + +if fromparts:length = 0 { + print "You need to a part, and give it nametag 'from_this'.". + print "deliberate error to die". set x to 1/0. +}. +set frompart to fromparts[0]. + +if toparts:length = 0 { + print "You need to a part, and give it nametag 'to_this'.". + print "deliberate error to die". set x to 1/0. +} +set topart to toparts[0]. + +// Now calculate which element contains those parts: +set fromElementNum to -1. +set toElementNum to -1. +LIST ELEMENTS IN eList. +set i to 0. +until i >= eLIst:length { + set ele to eList[i]. + for pt in ele:parts { + if pt = frompart { // this is an indirect test of part equals operator + set fromElementNum to i. + }. + if pt = topart { // this is an indirect test of part equals operator + set toElementNum to i. + }. + }. + set i to i + 1. +}. + +if fromElementNum < 0 or toElementNum < 0 { + print "error calculating element. Dying now". + set x to 1/0. +} +if fromElementNum = toElementNum { + print "error: from and to element are the same element.". + print "dying now". + set x to 1/0. +} + +print "Now transferring 90 liquidfuel from element " + fromelementNum + " to element " + toElementNum. +set foo to transfer("liquidfuel", eList[fromElementNum], eList[toElementNum], 90). +set foo:active to true. +until foo:status = "Finished" or foo:status = "Failed" { + print "transferred " + foo:transferred + " " + foo:resource + " so far. " + foo:status + " ...". + wait 0.2. +}. +print "transferred " + foo:transferred + " in total. " + foo:status. + + +print "Now transferring 110 oxidizer from element " + fromelementNum + " to element " + toElementNum. +set foo to transfer("oxidizer", eList[fromElementNum], eList[toElementNum], 110). +set foo:active to true. +until foo:status = "Finished" or foo:status = "Failed" { + print "transferred " + foo:transferred + " " + foo:resource + " so far. " + foo:status + " ...". + wait 0.2. +}. +print "transferred " + foo:transferred + " in total. " + foo:status. diff --git a/kerboscript_tests/resource_transfer/testtransfer3.ks b/kerboscript_tests/resource_transfer/testtransfer3.ks new file mode 100644 index 000000000..71364bea6 --- /dev/null +++ b/kerboscript_tests/resource_transfer/testtransfer3.ks @@ -0,0 +1,38 @@ +print "THIS SCRIPT TESTS RESOURCE TRANSFER". +print "WHEN DOING IT BY SINGLE PART TO SINGLE PART". + +set fromparts to ship:partstagged("from_this"). +set toparts to ship:partstagged("to_this"). + +if fromparts:length <> 1 { + print "You need to pick exactly one part, no more no less, and give it nametag 'from_this'.". + print "deliberate error to die". + set x to 1/0. +}. +set frompart to fromparts[0]. + +if toparts:length <> 1 { + print "You need to pick exactly one part, no more no less, and give it nametag 'to_this'.". + print "deliberate error to die". + set x to 1/0. +} +set topart to toparts[0]. + +print "Now transferring 90 liquidfuel from part to part". +set foo to transfer("liquidfuel",frompart,topart,90). +set foo:active to true. +until foo:status = "Finished" or foo:status = "Failed" { + print "transferred " + foo:transferred + " " + foo:resource + " so far. " + foo:status + " ...". + wait 0.2. +}. +print "transferred " + foo:transferred + " in total.". + + +print "Now transferring 110 oxidizer from part to part". +set foo to transfer("oxidizer",frompart,topart,110). +set foo:active to true. +until foo:status = "Finished" or foo:status = "Failed" { + print "transferred " + foo:transferred + " " + foo:resource + " so far. " + foo:status + " ...". + wait 0.2. +}. +print "transferred " + foo:transferred + " in total.". From 9fb4ddbfba7585d0a11e3592647bf1a885efb5cc Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Mon, 30 Mar 2015 05:21:24 -0500 Subject: [PATCH 317/446] Fixed a bug when a script calls another with args. When one script called another script with args, the args were getting shifted off by one because of improper use of $. This was actually a problem I had fixed before, but then I messed it up again when I did that large refactor for builtins. Now it's back to working. --- src/kOS.Safe/Compilation/KS/Compiler.cs | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/kOS.Safe/Compilation/KS/Compiler.cs b/src/kOS.Safe/Compilation/KS/Compiler.cs index e02614f3d..9424746d1 100644 --- a/src/kOS.Safe/Compilation/KS/Compiler.cs +++ b/src/kOS.Safe/Compilation/KS/Compiler.cs @@ -2192,15 +2192,22 @@ private void VisitRunStatement(ParseNode node) // process program arguments AddOpcode(new OpcodePush(OpcodeCall.ARG_MARKER_STRING)); // regardless of whether it's called directly or indirectly, we still need at least one. + bool hasON = node.Nodes.Any(cn => cn.Token.Type == TokenType.ON); + if (!hasON && options.LoadProgramsInSameAddressSpace) + { + // When running in the same address space, we need an extra arg marker under the args, because + // of the double-indirect call where we call the subroutine that was built in PreProcessRunStatement, + // and IT in turn calls the actual subprogram (after deciding whether or not it needs to compile it + // into existence). + AddOpcode(new OpcodePush(OpcodeCall.ARG_MARKER_STRING)); + } if (node.Nodes.Count > 3 && node.Nodes[3].Token.Type == TokenType.arglist) { VisitNode(node.Nodes[3]); volumeIndex += 3; } - AddOpcode(new OpcodePush(OpcodeCall.ARG_MARKER_STRING)); // separates the RUN() args (progname, volume) from the args to the program the RUn is running. - bool hasON = node.Nodes.Any(cn => cn.Token.Type == TokenType.ON); if (!hasON && options.LoadProgramsInSameAddressSpace) { string subprogramName = node.Nodes[1].Token.Text; // This assumption that the filenames are known at compile-time is why we can't do RUN expr @@ -2213,6 +2220,11 @@ private void VisitRunStatement(ParseNode node) } else { + // When running in a new address space, we also need a second arg marker, but in this + // case it has to go over the top of the other args, not under them, to tell the RUN + // builtin function where its arguments end and the progs arguments start: + AddOpcode(new OpcodePush(OpcodeCall.ARG_MARKER_STRING)); + // program name VisitNode(node.Nodes[1]); From ff88b535ac9591cc39f2a95b38fb62552e138f84 Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Tue, 31 Mar 2015 00:36:57 -0500 Subject: [PATCH 318/446] fixed by moving the for loop's code around a bit. --- src/kOS.Safe/Compilation/KS/Compiler.cs | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/src/kOS.Safe/Compilation/KS/Compiler.cs b/src/kOS.Safe/Compilation/KS/Compiler.cs index af16d844a..785b00d31 100644 --- a/src/kOS.Safe/Compilation/KS/Compiler.cs +++ b/src/kOS.Safe/Compilation/KS/Compiler.cs @@ -2460,12 +2460,12 @@ private void VisitForStatement(ParseNode node) string iteratorIdentifier = "$" + GetIdentifierText(node.Nodes[3]) + "-iterator"; - PushBreakList(braceNestLevel); - // Add a scope level to hold the iterator variable. This will live just "outside" the // brace scope of the function body. BeginScope(node); + PushBreakList(braceNestLevel); + AddOpcode(new OpcodePush(iteratorIdentifier)); VisitNode(node.Nodes[3]); AddOpcode(new OpcodePush("iterator")); @@ -2490,21 +2490,14 @@ private void VisitForStatement(ParseNode node) // jump to condition Opcode jump = AddOpcode(new OpcodeBranchJump()); jump.DestinationLabel = conditionLabel; - // end of loop, cleanup - Opcode endLoop = AddOpcode(new OpcodePush(iteratorIdentifier)); - AddOpcode(new OpcodePush("reset")); - AddOpcode(new OpcodeGetMember()); - AddOpcode(new OpcodePop()); // removes the "true" returned by the previous getmember - // unset of iterator and iteration variable - AddOpcode(new OpcodePush(iteratorIdentifier)); - AddOpcode(new OpcodeUnset()); - VisitVariableNode(node.Nodes[1]); - AddOpcode(new OpcodeUnset()); + + // end of loop, give NOP destination to land at for breaks and end-loop condition: + Opcode endLoop = AddOpcode(new OpcodeNOP()); + PopBreakList(endLoop.Label); // End the scope level holding the iterator variable: EndScope(node); - PopBreakList(endLoop.Label); nowInALoop = remember; } From e53a3c9d16c6a860f1cca1c55ab2605aaf1fc49b Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Tue, 31 Mar 2015 21:21:24 -0500 Subject: [PATCH 319/446] made cleaner way to print the debug_each_opcode. --- src/kOS.Safe/Compilation/Opcode.cs | 5 +++- src/kOS/Execution/CPU.cs | 38 +++++++++++++++++++++--------- 2 files changed, 31 insertions(+), 12 deletions(-) diff --git a/src/kOS.Safe/Compilation/Opcode.cs b/src/kOS.Safe/Compilation/Opcode.cs index 31a603751..7adfe73f1 100644 --- a/src/kOS.Safe/Compilation/Opcode.cs +++ b/src/kOS.Safe/Compilation/Opcode.cs @@ -1377,7 +1377,10 @@ public override void Execute(ICpu cpu) if ( (shouldBeArgMarker == null) || (!(shouldBeArgMarker.Equals(OpcodeCall.ARG_MARKER_STRING))) ) { - throw new KOSArgumentMismatchException("(detected when returning from function)"); + cpu.DumpVariables(); // eraseme. + throw new KOSArgumentMismatchException( + "(detected when returning from function and the stack still had " + + (shouldBeArgMarker ?? "a non-string value") + " on it)"); } // If the proper argument marker was found, then it's all okay, so put the return value // back, where it belongs, now that the arg start marker was popped off: diff --git a/src/kOS/Execution/CPU.cs b/src/kOS/Execution/CPU.cs index 1f16a09fa..9485477ba 100644 --- a/src/kOS/Execution/CPU.cs +++ b/src/kOS/Execution/CPU.cs @@ -41,6 +41,7 @@ private enum Status private double totalExecutionTime; private int maxMainlineInstructionsSoFar; private int maxTriggerInstructionsSoFar; + private StringBuilder executeLog = new StringBuilder(); public int InstructionPointer { @@ -895,11 +896,14 @@ private void ProcessTriggers() currentContext.InstructionPointer = triggerPointer; bool executeNext = true; + executeLog.Remove(0,executeLog.Length); // why doesn't StringBuilder just have a Clear() operator? while (executeNext && instructionsSoFarInUpdate < instructionsPerUpdate) { executeNext = ExecuteInstruction(currentContext); instructionsSoFarInUpdate++; } + if (executeLog.Length > 0) + SafeHouse.Logger.Log(executeLog.ToString()); } catch (Exception e) { @@ -918,7 +922,7 @@ private void ProcessTriggers() private void ContinueExecution() { bool executeNext = true; - + executeLog.Remove(0,executeLog.Length); // why doesn't StringBuilder just have a Clear() operator? while (currentStatus == Status.Running && instructionsSoFarInUpdate < instructionsPerUpdate && executeNext && @@ -927,6 +931,8 @@ private void ContinueExecution() executeNext = ExecuteInstruction(currentContext); instructionsSoFarInUpdate++; } + if (executeLog.Length > 0) + SafeHouse.Logger.Log(executeLog.ToString()); } private bool ExecuteInstruction(ProgramContext context) @@ -936,20 +942,30 @@ private bool ExecuteInstruction(ProgramContext context) Opcode opcode = context.Program[context.InstructionPointer]; if (DEBUG_EACH_OPCODE) { - SafeHouse.Logger.Log("ExecuteInstruction. Opcode number " + context.InstructionPointer + " out of " + context.Program.Count + - "\n Opcode is: " + opcode.Label + " " + opcode.ToString() ); + executeLog.Append(String.Format("Executing Opcode {0:0000}/{1:0000} {2} {3}\n", + context.InstructionPointer, context.Program.Count, opcode.Label, opcode.ToString())); } - - if (!(opcode is OpcodeEOF || opcode is OpcodeEOP)) + try { - opcode.Execute(this); - context.InstructionPointer += opcode.DeltaInstructionPointer; - return true; + if (!(opcode is OpcodeEOF || opcode is OpcodeEOP)) + { + opcode.Execute(this); + context.InstructionPointer += opcode.DeltaInstructionPointer; + return true; + } + if (opcode is OpcodeEOP) + { + BreakExecution(false); + SafeHouse.Logger.Log("Execution Broken"); + } } - if (opcode is OpcodeEOP) + catch (Exception e) { - BreakExecution(false); - SafeHouse.Logger.Log("Execution Broken"); + // exception will skip the normal printing of the log buffer, + // so print what we have so far before throwing up the exception: + if (executeLog.Length > 0) + SafeHouse.Logger.Log(executeLog.ToString()); + throw e; } return false; } From 9cbecb4e243dbc7ac069ee9abc365cb1cf1e9a87 Mon Sep 17 00:00:00 2001 From: Chris Woerz Date: Wed, 1 Apr 2015 09:35:52 -0600 Subject: [PATCH 320/446] changed RT integration default --- src/kOS/Suffixed/Config.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kOS/Suffixed/Config.cs b/src/kOS/Suffixed/Config.cs index 29e2add5f..03e69904b 100644 --- a/src/kOS/Suffixed/Config.cs +++ b/src/kOS/Suffixed/Config.cs @@ -41,7 +41,7 @@ private void BuildValuesDictionary() AddConfigKey(PropId.InstructionsPerUpdate, new ConfigKey("InstructionsPerUpdate", "IPU", "Instructions per update", 150, 50, 2000, typeof(int))); AddConfigKey(PropId.UseCompressedPersistence, new ConfigKey("UseCompressedPersistence", "UCP", "Use compressed persistence", false, false, true, typeof(bool))); AddConfigKey(PropId.ShowStatistics, new ConfigKey("ShowStatistics", "STAT", "Show execution statistics", false, false, true, typeof(bool))); - AddConfigKey(PropId.EnableRTIntegration, new ConfigKey("EnableRTIntegration", "RT", "Enable RT integration", false, false, true, typeof(bool))); + AddConfigKey(PropId.EnableRTIntegration, new ConfigKey("EnableRTIntegration", "RT", "Enable RT integration", true, false, true, typeof(bool))); AddConfigKey(PropId.StartOnArchive, new ConfigKey("StartOnArchive", "ARCH", "Start on Archive volume", false, false, true, typeof(bool))); AddConfigKey(PropId.EnableSafeMode, new ConfigKey("EnableSafeMode", "SAFE", "Enable safe mode", true, false, true, typeof(bool))); AddConfigKey(PropId.VerboseExceptions, new ConfigKey("VerboseExceptions", "VERBOSE", "Enable verbose exception msgs", true, false, true, typeof(bool))); From 8638bf1e393ab3c552fe6bbb854ce40352fd99b7 Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Wed, 1 Apr 2015 20:57:09 -0500 Subject: [PATCH 321/446] added ability for trigger hashcodes to differ per compile. Thus the compiler will not treat the hashcodes from one program compile as identical to the ones from another program compile. --- src/kOS.Safe/Compilation/KS/Compiler.cs | 18 ++++++++++++++++-- src/kOS.Safe/Compilation/KS/Context.cs | 2 ++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/kOS.Safe/Compilation/KS/Compiler.cs b/src/kOS.Safe/Compilation/KS/Compiler.cs index 785b00d31..4bc9b29d0 100644 --- a/src/kOS.Safe/Compilation/KS/Compiler.cs +++ b/src/kOS.Safe/Compilation/KS/Compiler.cs @@ -79,6 +79,8 @@ public CodePart Compile(int startLineNum, ParseTree tree, Context context, Compi this.context = context; this.options = options; this.startLineNum = startLineNum; + + ++context.NumCompilesSoFar; try { @@ -359,14 +361,26 @@ private void PreProcessWaitStatement(ParseNode node) branchOpcode.DestinationLabel = eofOpcode.Label; } } + + /// + /// Create a unique string out of a sub-branch of the parse tree that + /// can be used to uniquely identify it. The purpose is so that two + /// sub-branches of the parse tree can be compared to see if they are + /// the exact same code as each other.
    + ///
    private string ConcatenateNodes(ParseNode node) { - string concatenated = node.Token.Text; + return context.NumCompilesSoFar.ToString() + ConcatenateNodesRecurse(node); + } + + private string ConcatenateNodesRecurse(ParseNode node) + { + string concatenated = context.NumCompilesSoFar.ToString() + node.Token.Text; if (node.Nodes.Any()) { - return node.Nodes.Aggregate(concatenated, (current, childNode) => current + ConcatenateNodes(childNode)); + return node.Nodes.Aggregate(concatenated, (current, childNode) => current + ConcatenateNodesRecurse(childNode)); } return concatenated; diff --git a/src/kOS.Safe/Compilation/KS/Context.cs b/src/kOS.Safe/Compilation/KS/Context.cs index 512775484..c3a6b2051 100644 --- a/src/kOS.Safe/Compilation/KS/Context.cs +++ b/src/kOS.Safe/Compilation/KS/Context.cs @@ -7,6 +7,7 @@ public class Context public UserFunctionCollection UserFunctions { get; private set; } public TriggerCollection Triggers { get; private set; } public SubprogramCollection Subprograms { get; private set; } + public int NumCompilesSoFar {get; set;} public int LabelIndex { get; set; } public string LastSourceName { get; set; } @@ -25,6 +26,7 @@ public Context() LabelIndex = 0; LastSourceName = ""; MaxScopeIdSoFar = 0; + NumCompilesSoFar = 0; } } From 27351d779c75ded7923b6b64024d11df84a35654 Mon Sep 17 00:00:00 2001 From: Chris Woerz Date: Thu, 2 Apr 2015 10:24:46 -0600 Subject: [PATCH 322/446] review for #703 --- src/kOS.Safe/Compilation/Opcode.cs | 10 +++++----- src/kOS/Execution/CPU.cs | 16 ++++++++-------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/kOS.Safe/Compilation/Opcode.cs b/src/kOS.Safe/Compilation/Opcode.cs index 7adfe73f1..614459e05 100644 --- a/src/kOS.Safe/Compilation/Opcode.cs +++ b/src/kOS.Safe/Compilation/Opcode.cs @@ -147,7 +147,7 @@ public abstract class Opcode private static int lastId; private readonly int id = ++lastId; - // SHOUD-BE-STATIC MEMBERS: + // SHOULD-BE-STATIC MEMBERS: // ======================== // // There are places in this class where a static abstract member was the intent, @@ -158,7 +158,7 @@ public abstract class Opcode // Name="jump", and so on.) // // But C# cannot support this, apparently, due to a limitation in how it implements class - // inheritences. It doesn't know how to store overrides at the static level where there's just + // inheritances. It doesn't know how to store overrides at the static level where there's just // one instance per subclass definition. It only knows how to override dynamic members. Because of // this the compiler will call it an error to try to make a member be both abstract and static. // @@ -1377,10 +1377,10 @@ public override void Execute(ICpu cpu) if ( (shouldBeArgMarker == null) || (!(shouldBeArgMarker.Equals(OpcodeCall.ARG_MARKER_STRING))) ) { - cpu.DumpVariables(); // eraseme. throw new KOSArgumentMismatchException( - "(detected when returning from function and the stack still had " + - (shouldBeArgMarker ?? "a non-string value") + " on it)"); + string.Format("(detected when returning from function and the stack still had {0} on it)", + (shouldBeArgMarker ?? "a non-string value")) + ); } // If the proper argument marker was found, then it's all okay, so put the return value // back, where it belongs, now that the arg start marker was popped off: diff --git a/src/kOS/Execution/CPU.cs b/src/kOS/Execution/CPU.cs index 9485477ba..cee586b82 100644 --- a/src/kOS/Execution/CPU.cs +++ b/src/kOS/Execution/CPU.cs @@ -41,7 +41,7 @@ private enum Status private double totalExecutionTime; private int maxMainlineInstructionsSoFar; private int maxTriggerInstructionsSoFar; - private StringBuilder executeLog = new StringBuilder(); + private readonly StringBuilder executeLog = new StringBuilder(); public int InstructionPointer { @@ -375,20 +375,20 @@ private VariableScope GetNestedDictionary(int peekDepth) } /// - /// Gets the dictionary that contains the given identifer, starting the + /// Gets the dictionary that contains the given identifier, starting the /// search at the local level and scanning the scopes upward all the /// way to the global dictionary.
    /// Does not allow the walk to use scope frames that were not directly in this - /// scope's lexical chain. It skips over scope frames from other braches + /// scope's lexical chain. It skips over scope frames from other branches /// of the parse tree. (i.e. if a function calls a function elsewhere).
    /// Returns null when no hit was found.
    ///
    - /// identifer name to search for - /// The dictionary found, or null if no dictionary contins the identifier. + /// identifier name to search for + /// The dictionary found, or null if no dictionary contains the identifier. private VariableScope GetNestedDictionary(string identifier) { Int16 rawStackDepth = 0 ; - while (true) /*all of this loop's exits are explicit break or return stmts*/ + while (true) /*all of this loop's exits are explicit break or return statements*/ { object stackItem; bool stackExhausted = !(stack.PeekCheck(-1 - rawStackDepth, out stackItem)); @@ -959,13 +959,13 @@ private bool ExecuteInstruction(ProgramContext context) SafeHouse.Logger.Log("Execution Broken"); } } - catch (Exception e) + catch (Exception) { // exception will skip the normal printing of the log buffer, // so print what we have so far before throwing up the exception: if (executeLog.Length > 0) SafeHouse.Logger.Log(executeLog.ToString()); - throw e; + throw; } return false; } From 7b06dc07b939f305a8166bd6f3cdd2f61c1bb041 Mon Sep 17 00:00:00 2001 From: Chris Woerz Date: Thu, 2 Apr 2015 10:41:34 -0600 Subject: [PATCH 323/446] review for #707 --- src/kOS.Safe/Compilation/KS/Compiler.cs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/kOS.Safe/Compilation/KS/Compiler.cs b/src/kOS.Safe/Compilation/KS/Compiler.cs index 4bc9b29d0..915884a39 100644 --- a/src/kOS.Safe/Compilation/KS/Compiler.cs +++ b/src/kOS.Safe/Compilation/KS/Compiler.cs @@ -3,7 +3,6 @@ using System.Linq; using kOS.Safe.Exceptions; using kOS.Safe.Utilities; -using kOS.Safe.Function; namespace kOS.Safe.Compilation.KS { @@ -367,16 +366,16 @@ private void PreProcessWaitStatement(ParseNode node) /// Create a unique string out of a sub-branch of the parse tree that /// can be used to uniquely identify it. The purpose is so that two /// sub-branches of the parse tree can be compared to see if they are - /// the exact same code as each other.
    + /// the exact same code as each other. /// private string ConcatenateNodes(ParseNode node) { - return context.NumCompilesSoFar.ToString() + ConcatenateNodesRecurse(node); + return string.Format("{0}{1}", context.NumCompilesSoFar, ConcatenateNodesRecurse(node)); } private string ConcatenateNodesRecurse(ParseNode node) { - string concatenated = context.NumCompilesSoFar.ToString() + node.Token.Text; + string concatenated = string.Format("{0}{1}", context.NumCompilesSoFar, node.Token.Text); if (node.Nodes.Any()) { @@ -1163,7 +1162,7 @@ private void VisitTrueFalse(ParseNode node) private void VisitOnOffTrailer(ParseNode node) { NodeStartHousekeeping(node); - AddOpcode(new OpcodePush((node.Nodes[0].Token.Type == TokenType.ON) ? true : false)); + AddOpcode(new OpcodePush((node.Nodes[0].Token.Type == TokenType.ON))); } /// @@ -1914,7 +1913,7 @@ private void VisitInstructionBlock(ParseNode node) private void AddFunctionJumpVars(ParseNode node) { // All the functions for which this scope is where they live: - IEnumerable theseFuncs = context.UserFunctions.GetUserFunctionList().Where((item) => item.IsFunction && item.ScopeNode == node); + IEnumerable theseFuncs = context.UserFunctions.GetUserFunctionList().Where(item => item.IsFunction && item.ScopeNode == node); foreach (UserFunction func in theseFuncs) { From 2ca2c23066e1036816391943bfde51f6e54f2581 Mon Sep 17 00:00:00 2001 From: Chris Woerz Date: Fri, 3 Apr 2015 11:28:09 -0600 Subject: [PATCH 324/446] fixes #527 fixes #526 fixes #539 --- src/kOS.Safe/Execution/ICpu.cs | 2 +- src/kOS/Execution/CPU.cs | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/kOS.Safe/Execution/ICpu.cs b/src/kOS.Safe/Execution/ICpu.cs index 5fc4a6c52..000885f55 100644 --- a/src/kOS.Safe/Execution/ICpu.cs +++ b/src/kOS.Safe/Execution/ICpu.cs @@ -3,7 +3,7 @@ namespace kOS.Safe.Execution { - public interface ICpu : IUpdateObserver + public interface ICpu : IFixedUpdateObserver { void PushStack(object item); object PopStack(); diff --git a/src/kOS/Execution/CPU.cs b/src/kOS/Execution/CPU.cs index 778cd4e2b..f7359010c 100644 --- a/src/kOS/Execution/CPU.cs +++ b/src/kOS/Execution/CPU.cs @@ -59,7 +59,7 @@ public CPU(SharedObjects shared) stack = new Stack(); globalVariables = new VariableScope(0, -1); contexts = new List(); - if (this.shared.UpdateHandler != null) this.shared.UpdateHandler.AddObserver(this); + if (this.shared.UpdateHandler != null) this.shared.UpdateHandler.AddFixedObserver(this); } public void Boot() @@ -772,7 +772,7 @@ public void EndWait() currentStatus = Status.Running; } - public void KOSUpdate(double deltaTime) + public void KOSFixedUpdate(double deltaTime) { bool showStatistics = Config.Instance.ShowStatistics; Stopwatch updateWatch = null; @@ -1120,7 +1120,7 @@ public void OnLoad(ConfigNode node) public void Dispose() { - shared.UpdateHandler.RemoveObserver(this); + shared.UpdateHandler.RemoveFixedObserver(this); } } } From 536e1ae6984da765d71a01db45e54c383feb8fb5 Mon Sep 17 00:00:00 2001 From: Chris Woerz Date: Sat, 4 Apr 2015 00:38:31 -0600 Subject: [PATCH 325/446] updated MM --- Resources/GameData/ModuleManager.2.5.10.dll | Bin 50688 -> 0 bytes Resources/GameData/ModuleManager.2.5.13.dll | Bin 0 -> 53760 bytes 2 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 Resources/GameData/ModuleManager.2.5.10.dll create mode 100644 Resources/GameData/ModuleManager.2.5.13.dll diff --git a/Resources/GameData/ModuleManager.2.5.10.dll b/Resources/GameData/ModuleManager.2.5.10.dll deleted file mode 100644 index 97851ed73951d990169942d0adac6ed6e770eee0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 50688 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 diff --git a/Resources/GameData/ModuleManager.2.5.13.dll b/Resources/GameData/ModuleManager.2.5.13.dll new file mode 100644 index 0000000000000000000000000000000000000000..797ffa71a434d52d19edbe00634c3e14f282c98d GIT binary patch literal 53760 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 f**04_JF=#~{o8*bi<)?odf?3kCW9B literal 0 HcmV?d00001 From 16f715fc244e78989669c425ce73bb04b10f032c Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Sat, 4 Apr 2015 04:03:18 -0500 Subject: [PATCH 326/446] Resolves #688, #722 - WAIT is no longer a trigger. --- doc/source/general/cpu_hardware.rst | 20 ++++++++-- doc/source/language/flow.rst | 8 ++++ src/kOS.Safe/Compilation/KS/Compiler.cs | 49 +++++-------------------- src/kOS.Safe/Compilation/Opcode.cs | 32 ++-------------- src/kOS/Execution/CPU.cs | 7 +--- 5 files changed, 39 insertions(+), 77 deletions(-) diff --git a/doc/source/general/cpu_hardware.rst b/doc/source/general/cpu_hardware.rst index ec1e65a13..a284500c8 100644 --- a/doc/source/general/cpu_hardware.rst +++ b/doc/source/general/cpu_hardware.rst @@ -43,6 +43,14 @@ Triggers are all of the following: - ON condition { some commands }. - WHEN condition THEN { some commands }. +.. note:: + + The :ref:`WAIT ` command only causes mainline code + to be suspended. Trigger code such as WHEN, ON, LOCK STEERING, + and LOCK THROTTLE, will continue executing while your program + is sitting still on the WAIT command. + + The way these work is that once per **update tick**, all the LOCK expressions which directly affect flight control are re-executed, and then each conditional trigger's condition is checked, and if true, then the entire body of the trigger is executed all the way to the bottom \*before any more instructions of the main body are executed\*. This means that execution of a trigger never gets interleaved with the main code. Once a trigger happens, the entire trigger occurs all in one go before the rest of the main body continues. Do Not Loop a Long Time in a Trigger Body! @@ -82,6 +90,14 @@ But the duration of the next update tick is actually 0.09 seconds, then you will Then even though the condition is immediately true, it will still wait one update tick to discover this fact and continue. +.. note:: + + The :ref:`WAIT ` command only causes mainline code + to be suspended. Trigger code such as WHEN, ON, LOCK STEERING, + and LOCK THROTTLE, will continue executing while your program + is sitting still on the WAIT command. + + The Frozen Universe ------------------- @@ -161,7 +177,3 @@ forums. You may put this code up near the top of your script:: PRESERVE. } -An Even Better Solution -~~~~~~~~~~~~~~~~~~~~~~~ - -There has been talk of instituting a special command: WAIT UNTIL PHYSICS that will sleep until there has been a physics update, and it's a good idea but it hasn't been implemented yet. diff --git a/doc/source/language/flow.rst b/doc/source/language/flow.rst index 4b2eca5a9..7295ee965 100644 --- a/doc/source/language/flow.rst +++ b/doc/source/language/flow.rst @@ -172,6 +172,14 @@ Halts execution for a specified amount of time, or until a specific set of crite Note that any ``WAIT`` statement, no matter what the actual expression is, will always result in a wait time that lasts at least :ref:`one physics tick `. +.. note:: + + The :ref:`WAIT ` command only causes mainline code + to be suspended. Trigger code such as WHEN, ON, LOCK STEERING, + and LOCK THROTTLE, will continue executing while your program + is sitting still on the WAIT command. + + .. index:: WHEN .. _when: diff --git a/src/kOS.Safe/Compilation/KS/Compiler.cs b/src/kOS.Safe/Compilation/KS/Compiler.cs index 915884a39..2cde99b8e 100644 --- a/src/kOS.Safe/Compilation/KS/Compiler.cs +++ b/src/kOS.Safe/Compilation/KS/Compiler.cs @@ -245,9 +245,6 @@ private void PreProcessStatements(ParseNode node) PreProcessChildNodes(node); PreProcessWhenStatement(node); break; - case TokenType.wait_stmt: - PreProcessWaitStatement(node); - break; case TokenType.declare_stmt: PreProcessProgramParameters(node); break; @@ -340,28 +337,6 @@ private void PreProcessWhenStatement(ParseNode node) skipRemoval.DestinationLabel = eofOpcode.Label; } - private void PreProcessWaitStatement(ParseNode node) - { - NodeStartHousekeeping(node); - if (node.Nodes.Count == 4) - { - // wait condition - int expressionHash = ConcatenateNodes(node).GetHashCode(); - string triggerIdentifier = "wait-" + expressionHash.ToString(); - Trigger triggerObject = context.Triggers.GetTrigger(triggerIdentifier); - - currentCodeSection = triggerObject.Code; - VisitNode(node.Nodes[2]); - Opcode branchOpcode = AddOpcode(new OpcodeBranchIfFalse()); - AddOpcode(new OpcodeEndWait()); - AddOpcode(new OpcodePushRelocateLater(null), triggerObject.GetFunctionLabel()); - AddOpcode(new OpcodeRemoveTrigger()); - Opcode eofOpcode = AddOpcode(new OpcodeEOF()); - branchOpcode.DestinationLabel = eofOpcode.Label; - } - } - - /// /// Create a unique string out of a sub-branch of the parse tree that /// can be used to uniquely identify it. The purpose is so that two @@ -1963,7 +1938,7 @@ private void VisitLockStatement(ParseNode node) { Trigger triggerObject = context.Triggers.GetTrigger(triggerIdentifier); AddOpcode(new OpcodePushRelocateLater(null), triggerObject.GetFunctionLabel()); - AddOpcode(new OpcodeAddTrigger(false)); + AddOpcode(new OpcodeAddTrigger()); } // enable this FlyByWire parameter @@ -2043,7 +2018,7 @@ private void VisitOnStatement(ParseNode node) AddOpcode(new OpcodePush(triggerObject.VariableName)); AddOpcode(new OpcodeStore()); AddOpcode(new OpcodePushRelocateLater(null), triggerObject.GetFunctionLabel()); - AddOpcode(new OpcodeAddTrigger(false)); + AddOpcode(new OpcodeAddTrigger()); } } @@ -2057,7 +2032,7 @@ private void VisitWhenStatement(ParseNode node) if (triggerObject.IsInitialized()) { AddOpcode(new OpcodePushRelocateLater(null), triggerObject.GetFunctionLabel()); - AddOpcode(new OpcodeAddTrigger(false)); + AddOpcode(new OpcodeAddTrigger()); } } @@ -2070,22 +2045,18 @@ private void VisitWaitStatement(ParseNode node) if (node.Nodes.Count == 3) { - // wait time + // For commands of the form: WAIT N. where N is a number: VisitNode(node.Nodes[1]); AddOpcode(new OpcodeWait()); } else { - // wait condition - int expressionHash = ConcatenateNodes(node).GetHashCode(); - string triggerIdentifier = "wait-" + expressionHash.ToString(); - Trigger triggerObject = context.Triggers.GetTrigger(triggerIdentifier); - - if (triggerObject.IsInitialized()) - { - AddOpcode(new OpcodePushRelocateLater(null), triggerObject.GetFunctionLabel()); - AddOpcode(new OpcodeAddTrigger(true)); - } + // For commands of the form: WAIT UNTIL expr. where expr is any boolean expression: + Opcode waitLoopStart = AddOpcode(new OpcodePush(0)); // Loop start: Gives OpcodeWait an argument of zero. + AddOpcode(new OpcodeWait()); // Avoid busy polling. Even a WAIT 0 still forces 1 fixedupdate 'tick'. + VisitNode(node.Nodes[2]); // Inserts instructions here to evaluate the expression + AddOpcode(new OpcodeBranchIfFalse(), waitLoopStart.Label); // Repeat the loop as long as expression is false. + // Falls through to whatever comes next when expression is true. } } diff --git a/src/kOS.Safe/Compilation/Opcode.cs b/src/kOS.Safe/Compilation/Opcode.cs index 614459e05..b5d4f1f53 100644 --- a/src/kOS.Safe/Compilation/Opcode.cs +++ b/src/kOS.Safe/Compilation/Opcode.cs @@ -1680,41 +1680,18 @@ public override string ToString() public class OpcodeAddTrigger : Opcode { - [MLField(1,false)] - private bool ShouldWait { get; set; } - protected override string Name { get { return "addtrigger"; } } public override ByteCode Code { get { return ByteCode.ADDTRIGGER; } } - public OpcodeAddTrigger(bool shouldWait) - { - ShouldWait = shouldWait; - } - - /// - /// This variant of the constructor is just for ML save/load to use. - /// - protected OpcodeAddTrigger() { } - - public override void PopulateFromMLFields(List fields) - { - // Expect fields in the same order as the [MLField] properties of this class: - if (fields == null || fields.Count<1) - throw new Exception("Saved field in ML file for OpcodeAddTrigger seems to be missing. Version mismatch?"); - ShouldWait = (bool)(fields[0]); // should throw error if it's not a bool. - } - public override void Execute(ICpu cpu) { var functionPointer = (int)cpu.PopValue(); cpu.AddTrigger(functionPointer); - if (ShouldWait) - cpu.StartWait(0); } public override string ToString() { - return Name + " " + ShouldWait.ToString().ToLower(); + return Name; } } @@ -1739,11 +1716,8 @@ public class OpcodeWait : Opcode public override void Execute(ICpu cpu) { - object waitTime = cpu.PopValue(); - if (waitTime is double) - cpu.StartWait((double)waitTime); - else if (waitTime is int) - cpu.StartWait((int)waitTime); + object arg = cpu.PopValue(); + cpu.StartWait(Convert.ToDouble(arg)); } } diff --git a/src/kOS/Execution/CPU.cs b/src/kOS/Execution/CPU.cs index cee586b82..7d6e64cf0 100644 --- a/src/kOS/Execution/CPU.cs +++ b/src/kOS/Execution/CPU.cs @@ -759,10 +759,7 @@ public void RemoveTrigger(int triggerFunctionPointer) public void StartWait(double waitTime) { - if (waitTime > 0) - { - timeWaitUntil = currentTime + waitTime; - } + timeWaitUntil = currentTime + waitTime; currentStatus = Status.Waiting; } @@ -873,7 +870,7 @@ private void PostUpdateBindings() private void ProcessWait() { - if (currentStatus == Status.Waiting && timeWaitUntil > 0) + if (currentStatus == Status.Waiting) { if (currentTime >= timeWaitUntil) { From e057cf842a2669db5c76ca9177e18920b724234c Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Sun, 5 Apr 2015 03:47:09 -0500 Subject: [PATCH 327/446] Resolves #733 and Resolves #547. Changed the order of operations to this instead: Unary opertors such as: ``` not foo -foo +foo ``` Now happen AFTER mult,div,add,sub, but BEFORE power,suffix,function. --- src/kOS.Safe/Compilation/KS/Compiler.cs | 28 ++-- src/kOS.Safe/Compilation/KS/ParseTree.cs | 10 ++ src/kOS.Safe/Compilation/KS/Parser.cs | 108 +++++++------- src/kOS.Safe/Compilation/KS/Scanner.cs | 177 ++++++++++++----------- src/kOS.Safe/Compilation/KS/kRISC.tpg | 16 +- 5 files changed, 182 insertions(+), 157 deletions(-) diff --git a/src/kOS.Safe/Compilation/KS/Compiler.cs b/src/kOS.Safe/Compilation/KS/Compiler.cs index 915884a39..c359a9a1d 100644 --- a/src/kOS.Safe/Compilation/KS/Compiler.cs +++ b/src/kOS.Safe/Compilation/KS/Compiler.cs @@ -931,6 +931,9 @@ private void VisitNode(ParseNode node) case TokenType.suffix: VisitSuffix(node); break; + case TokenType.unary_expr: + VisitUnaryExpression(node); + break; case TokenType.atom: VisitAtom(node); break; @@ -1048,7 +1051,7 @@ private void VisitExpression(ParseNode node) } } - private void VisitAtom(ParseNode node) + private void VisitUnaryExpression(ParseNode node) { NodeStartHousekeeping(node); if (node.Nodes.Count <= 0) return; @@ -1070,23 +1073,30 @@ private void VisitAtom(ParseNode node) nodeIndex++; addNot = true; } + + VisitNode(node.Nodes[nodeIndex]); - if (node.Nodes[nodeIndex].Token.Type == TokenType.BRACKETOPEN) + if (addNegation) { - VisitNode(node.Nodes[nodeIndex + 1]); + AddOpcode(new OpcodeMathNegate()); } - else + if (addNot) { - VisitNode(node.Nodes[nodeIndex]); + AddOpcode(new OpcodeLogicNot()); } + } - if (addNegation) + private void VisitAtom(ParseNode node) + { + NodeStartHousekeeping(node); + + if (node.Nodes[0].Token.Type == TokenType.BRACKETOPEN) { - AddOpcode(new OpcodeMathNegate()); + VisitNode(node.Nodes[1]); } - if (addNot) + else { - AddOpcode(new OpcodeLogicNot()); + VisitNode(node.Nodes[0]); } } diff --git a/src/kOS.Safe/Compilation/KS/ParseTree.cs b/src/kOS.Safe/Compilation/KS/ParseTree.cs index 384a79f81..299479c65 100644 --- a/src/kOS.Safe/Compilation/KS/ParseTree.cs +++ b/src/kOS.Safe/Compilation/KS/ParseTree.cs @@ -316,6 +316,9 @@ internal object Eval(ParseTree tree, params object[] paramlist) case TokenType.multdiv_expr: Value = Evalmultdiv_expr(tree, paramlist); break; + case TokenType.unary_expr: + Value = Evalunary_expr(tree, paramlist); + break; case TokenType.factor: Value = Evalfactor(tree, paramlist); break; @@ -683,6 +686,13 @@ protected virtual object Evalmultdiv_expr(ParseTree tree, params object[] paraml return null; } + protected virtual object Evalunary_expr(ParseTree tree, params object[] paramlist) + { + foreach (var node in Nodes) + node.Eval(tree, paramlist); + return null; + } + protected virtual object Evalfactor(ParseTree tree, params object[] paramlist) { foreach (var node in Nodes) diff --git a/src/kOS.Safe/Compilation/KS/Parser.cs b/src/kOS.Safe/Compilation/KS/Parser.cs index 73cceaf87..2a03f5e5a 100644 --- a/src/kOS.Safe/Compilation/KS/Parser.cs +++ b/src/kOS.Safe/Compilation/KS/Parser.cs @@ -47,7 +47,7 @@ private void ParseStart(ParseNode parent) - tok = scanner.LookAhead(TokenType.SET, TokenType.IF, TokenType.UNTIL, TokenType.LOCK, TokenType.UNLOCK, TokenType.PRINT, TokenType.ON, TokenType.TOGGLE, TokenType.WAIT, TokenType.WHEN, TokenType.STAGE, TokenType.CLEARSCREEN, TokenType.ADD, TokenType.REMOVE, TokenType.LOG, TokenType.BREAK, TokenType.PRESERVE, TokenType.DECLARE, TokenType.RETURN, TokenType.SWITCH, TokenType.COPY, TokenType.RENAME, TokenType.DELETE, TokenType.EDIT, TokenType.RUN, TokenType.COMPILE, TokenType.LIST, TokenType.REBOOT, TokenType.SHUTDOWN, TokenType.FOR, TokenType.UNSET, TokenType.BATCH, TokenType.DEPLOY, TokenType.CURLYOPEN, TokenType.PLUSMINUS, TokenType.NOT, TokenType.INTEGER, TokenType.DOUBLE, TokenType.TRUEFALSE, TokenType.IDENTIFIER, TokenType.FILEIDENT, TokenType.BRACKETOPEN, TokenType.STRING, TokenType.ATSIGN); + tok = scanner.LookAhead(TokenType.SET, TokenType.IF, TokenType.UNTIL, TokenType.LOCK, TokenType.UNLOCK, TokenType.PRINT, TokenType.ON, TokenType.TOGGLE, TokenType.WAIT, TokenType.WHEN, TokenType.STAGE, TokenType.CLEARSCREEN, TokenType.ADD, TokenType.REMOVE, TokenType.LOG, TokenType.BREAK, TokenType.PRESERVE, TokenType.DECLARE, TokenType.RETURN, TokenType.SWITCH, TokenType.COPY, TokenType.RENAME, TokenType.DELETE, TokenType.EDIT, TokenType.RUN, TokenType.COMPILE, TokenType.LIST, TokenType.REBOOT, TokenType.SHUTDOWN, TokenType.FOR, TokenType.UNSET, TokenType.BATCH, TokenType.DEPLOY, TokenType.CURLYOPEN, TokenType.INTEGER, TokenType.DOUBLE, TokenType.TRUEFALSE, TokenType.IDENTIFIER, TokenType.FILEIDENT, TokenType.BRACKETOPEN, TokenType.STRING, TokenType.ATSIGN); while (tok.Type == TokenType.SET || tok.Type == TokenType.IF || tok.Type == TokenType.UNTIL @@ -82,8 +82,6 @@ private void ParseStart(ParseNode parent) || tok.Type == TokenType.BATCH || tok.Type == TokenType.DEPLOY || tok.Type == TokenType.CURLYOPEN - || tok.Type == TokenType.PLUSMINUS - || tok.Type == TokenType.NOT || tok.Type == TokenType.INTEGER || tok.Type == TokenType.DOUBLE || tok.Type == TokenType.TRUEFALSE @@ -94,7 +92,7 @@ private void ParseStart(ParseNode parent) || tok.Type == TokenType.ATSIGN) { Parseinstruction(node); - tok = scanner.LookAhead(TokenType.SET, TokenType.IF, TokenType.UNTIL, TokenType.LOCK, TokenType.UNLOCK, TokenType.PRINT, TokenType.ON, TokenType.TOGGLE, TokenType.WAIT, TokenType.WHEN, TokenType.STAGE, TokenType.CLEARSCREEN, TokenType.ADD, TokenType.REMOVE, TokenType.LOG, TokenType.BREAK, TokenType.PRESERVE, TokenType.DECLARE, TokenType.RETURN, TokenType.SWITCH, TokenType.COPY, TokenType.RENAME, TokenType.DELETE, TokenType.EDIT, TokenType.RUN, TokenType.COMPILE, TokenType.LIST, TokenType.REBOOT, TokenType.SHUTDOWN, TokenType.FOR, TokenType.UNSET, TokenType.BATCH, TokenType.DEPLOY, TokenType.CURLYOPEN, TokenType.PLUSMINUS, TokenType.NOT, TokenType.INTEGER, TokenType.DOUBLE, TokenType.TRUEFALSE, TokenType.IDENTIFIER, TokenType.FILEIDENT, TokenType.BRACKETOPEN, TokenType.STRING, TokenType.ATSIGN); + tok = scanner.LookAhead(TokenType.SET, TokenType.IF, TokenType.UNTIL, TokenType.LOCK, TokenType.UNLOCK, TokenType.PRINT, TokenType.ON, TokenType.TOGGLE, TokenType.WAIT, TokenType.WHEN, TokenType.STAGE, TokenType.CLEARSCREEN, TokenType.ADD, TokenType.REMOVE, TokenType.LOG, TokenType.BREAK, TokenType.PRESERVE, TokenType.DECLARE, TokenType.RETURN, TokenType.SWITCH, TokenType.COPY, TokenType.RENAME, TokenType.DELETE, TokenType.EDIT, TokenType.RUN, TokenType.COMPILE, TokenType.LIST, TokenType.REBOOT, TokenType.SHUTDOWN, TokenType.FOR, TokenType.UNSET, TokenType.BATCH, TokenType.DEPLOY, TokenType.CURLYOPEN, TokenType.INTEGER, TokenType.DOUBLE, TokenType.TRUEFALSE, TokenType.IDENTIFIER, TokenType.FILEIDENT, TokenType.BRACKETOPEN, TokenType.STRING, TokenType.ATSIGN); } @@ -129,7 +127,7 @@ private void Parseinstruction_block(ParseNode parent) } - tok = scanner.LookAhead(TokenType.SET, TokenType.IF, TokenType.UNTIL, TokenType.LOCK, TokenType.UNLOCK, TokenType.PRINT, TokenType.ON, TokenType.TOGGLE, TokenType.WAIT, TokenType.WHEN, TokenType.STAGE, TokenType.CLEARSCREEN, TokenType.ADD, TokenType.REMOVE, TokenType.LOG, TokenType.BREAK, TokenType.PRESERVE, TokenType.DECLARE, TokenType.RETURN, TokenType.SWITCH, TokenType.COPY, TokenType.RENAME, TokenType.DELETE, TokenType.EDIT, TokenType.RUN, TokenType.COMPILE, TokenType.LIST, TokenType.REBOOT, TokenType.SHUTDOWN, TokenType.FOR, TokenType.UNSET, TokenType.BATCH, TokenType.DEPLOY, TokenType.CURLYOPEN, TokenType.PLUSMINUS, TokenType.NOT, TokenType.INTEGER, TokenType.DOUBLE, TokenType.TRUEFALSE, TokenType.IDENTIFIER, TokenType.FILEIDENT, TokenType.BRACKETOPEN, TokenType.STRING, TokenType.ATSIGN); + tok = scanner.LookAhead(TokenType.SET, TokenType.IF, TokenType.UNTIL, TokenType.LOCK, TokenType.UNLOCK, TokenType.PRINT, TokenType.ON, TokenType.TOGGLE, TokenType.WAIT, TokenType.WHEN, TokenType.STAGE, TokenType.CLEARSCREEN, TokenType.ADD, TokenType.REMOVE, TokenType.LOG, TokenType.BREAK, TokenType.PRESERVE, TokenType.DECLARE, TokenType.RETURN, TokenType.SWITCH, TokenType.COPY, TokenType.RENAME, TokenType.DELETE, TokenType.EDIT, TokenType.RUN, TokenType.COMPILE, TokenType.LIST, TokenType.REBOOT, TokenType.SHUTDOWN, TokenType.FOR, TokenType.UNSET, TokenType.BATCH, TokenType.DEPLOY, TokenType.CURLYOPEN, TokenType.INTEGER, TokenType.DOUBLE, TokenType.TRUEFALSE, TokenType.IDENTIFIER, TokenType.FILEIDENT, TokenType.BRACKETOPEN, TokenType.STRING, TokenType.ATSIGN); while (tok.Type == TokenType.SET || tok.Type == TokenType.IF || tok.Type == TokenType.UNTIL @@ -164,8 +162,6 @@ private void Parseinstruction_block(ParseNode parent) || tok.Type == TokenType.BATCH || tok.Type == TokenType.DEPLOY || tok.Type == TokenType.CURLYOPEN - || tok.Type == TokenType.PLUSMINUS - || tok.Type == TokenType.NOT || tok.Type == TokenType.INTEGER || tok.Type == TokenType.DOUBLE || tok.Type == TokenType.TRUEFALSE @@ -176,7 +172,7 @@ private void Parseinstruction_block(ParseNode parent) || tok.Type == TokenType.ATSIGN) { Parseinstruction(node); - tok = scanner.LookAhead(TokenType.SET, TokenType.IF, TokenType.UNTIL, TokenType.LOCK, TokenType.UNLOCK, TokenType.PRINT, TokenType.ON, TokenType.TOGGLE, TokenType.WAIT, TokenType.WHEN, TokenType.STAGE, TokenType.CLEARSCREEN, TokenType.ADD, TokenType.REMOVE, TokenType.LOG, TokenType.BREAK, TokenType.PRESERVE, TokenType.DECLARE, TokenType.RETURN, TokenType.SWITCH, TokenType.COPY, TokenType.RENAME, TokenType.DELETE, TokenType.EDIT, TokenType.RUN, TokenType.COMPILE, TokenType.LIST, TokenType.REBOOT, TokenType.SHUTDOWN, TokenType.FOR, TokenType.UNSET, TokenType.BATCH, TokenType.DEPLOY, TokenType.CURLYOPEN, TokenType.PLUSMINUS, TokenType.NOT, TokenType.INTEGER, TokenType.DOUBLE, TokenType.TRUEFALSE, TokenType.IDENTIFIER, TokenType.FILEIDENT, TokenType.BRACKETOPEN, TokenType.STRING, TokenType.ATSIGN); + tok = scanner.LookAhead(TokenType.SET, TokenType.IF, TokenType.UNTIL, TokenType.LOCK, TokenType.UNLOCK, TokenType.PRINT, TokenType.ON, TokenType.TOGGLE, TokenType.WAIT, TokenType.WHEN, TokenType.STAGE, TokenType.CLEARSCREEN, TokenType.ADD, TokenType.REMOVE, TokenType.LOG, TokenType.BREAK, TokenType.PRESERVE, TokenType.DECLARE, TokenType.RETURN, TokenType.SWITCH, TokenType.COPY, TokenType.RENAME, TokenType.DELETE, TokenType.EDIT, TokenType.RUN, TokenType.COMPILE, TokenType.LIST, TokenType.REBOOT, TokenType.SHUTDOWN, TokenType.FOR, TokenType.UNSET, TokenType.BATCH, TokenType.DEPLOY, TokenType.CURLYOPEN, TokenType.INTEGER, TokenType.DOUBLE, TokenType.TRUEFALSE, TokenType.IDENTIFIER, TokenType.FILEIDENT, TokenType.BRACKETOPEN, TokenType.STRING, TokenType.ATSIGN); } @@ -213,7 +209,7 @@ private void Parseinstruction(ParseNode parent) ParseNode node = parent.CreateNode(scanner.GetToken(TokenType.instruction), "instruction"); parent.Nodes.Add(node); - tok = scanner.LookAhead(TokenType.SET, TokenType.IF, TokenType.UNTIL, TokenType.LOCK, TokenType.UNLOCK, TokenType.PRINT, TokenType.ON, TokenType.TOGGLE, TokenType.WAIT, TokenType.WHEN, TokenType.STAGE, TokenType.CLEARSCREEN, TokenType.ADD, TokenType.REMOVE, TokenType.LOG, TokenType.BREAK, TokenType.PRESERVE, TokenType.DECLARE, TokenType.RETURN, TokenType.SWITCH, TokenType.COPY, TokenType.RENAME, TokenType.DELETE, TokenType.EDIT, TokenType.RUN, TokenType.COMPILE, TokenType.LIST, TokenType.REBOOT, TokenType.SHUTDOWN, TokenType.FOR, TokenType.UNSET, TokenType.BATCH, TokenType.DEPLOY, TokenType.CURLYOPEN, TokenType.PLUSMINUS, TokenType.NOT, TokenType.INTEGER, TokenType.DOUBLE, TokenType.TRUEFALSE, TokenType.IDENTIFIER, TokenType.FILEIDENT, TokenType.BRACKETOPEN, TokenType.STRING, TokenType.ATSIGN); + tok = scanner.LookAhead(TokenType.SET, TokenType.IF, TokenType.UNTIL, TokenType.LOCK, TokenType.UNLOCK, TokenType.PRINT, TokenType.ON, TokenType.TOGGLE, TokenType.WAIT, TokenType.WHEN, TokenType.STAGE, TokenType.CLEARSCREEN, TokenType.ADD, TokenType.REMOVE, TokenType.LOG, TokenType.BREAK, TokenType.PRESERVE, TokenType.DECLARE, TokenType.RETURN, TokenType.SWITCH, TokenType.COPY, TokenType.RENAME, TokenType.DELETE, TokenType.EDIT, TokenType.RUN, TokenType.COMPILE, TokenType.LIST, TokenType.REBOOT, TokenType.SHUTDOWN, TokenType.FOR, TokenType.UNSET, TokenType.BATCH, TokenType.DEPLOY, TokenType.CURLYOPEN, TokenType.INTEGER, TokenType.DOUBLE, TokenType.TRUEFALSE, TokenType.IDENTIFIER, TokenType.FILEIDENT, TokenType.BRACKETOPEN, TokenType.STRING, TokenType.ATSIGN); switch (tok.Type) { case TokenType.SET: @@ -318,8 +314,6 @@ private void Parseinstruction(ParseNode parent) case TokenType.CURLYOPEN: Parseinstruction_block(node); break; - case TokenType.PLUSMINUS: - case TokenType.NOT: case TokenType.INTEGER: case TokenType.DOUBLE: case TokenType.TRUEFALSE: @@ -2338,7 +2332,7 @@ private void Parsemultdiv_expr(ParseNode parent) - Parsefactor(node); + Parseunary_expr(node); tok = scanner.LookAhead(TokenType.MULT, TokenType.DIV); @@ -2376,13 +2370,61 @@ private void Parsemultdiv_expr(ParseNode parent) } - Parsefactor(node); + Parseunary_expr(node); tok = scanner.LookAhead(TokenType.MULT, TokenType.DIV); } parent.Token.UpdateRange(node.Token); } + private void Parseunary_expr(ParseNode parent) + { + Token tok; + ParseNode n; + ParseNode node = parent.CreateNode(scanner.GetToken(TokenType.unary_expr), "unary_expr"); + parent.Nodes.Add(node); + + + + tok = scanner.LookAhead(TokenType.PLUSMINUS, TokenType.NOT); + if (tok.Type == TokenType.PLUSMINUS + || tok.Type == TokenType.NOT) + { + tok = scanner.LookAhead(TokenType.PLUSMINUS, TokenType.NOT); + switch (tok.Type) + { + case TokenType.PLUSMINUS: + tok = scanner.Scan(TokenType.PLUSMINUS); + n = node.CreateNode(tok, tok.ToString() ); + node.Token.UpdateRange(tok); + node.Nodes.Add(n); + if (tok.Type != TokenType.PLUSMINUS) { + tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.PLUSMINUS.ToString(), 0x1001, tok)); + return; + } + break; + case TokenType.NOT: + tok = scanner.Scan(TokenType.NOT); + n = node.CreateNode(tok, tok.ToString() ); + node.Token.UpdateRange(tok); + node.Nodes.Add(n); + if (tok.Type != TokenType.NOT) { + tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.NOT.ToString(), 0x1001, tok)); + return; + } + break; + default: + tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found.", 0x0002, tok)); + break; + } + } + + + Parsefactor(node); + + parent.Token.UpdateRange(node.Token); + } + private void Parsefactor(ParseNode parent) { Token tok; @@ -2649,53 +2691,15 @@ private void Parseatom(ParseNode parent) ParseNode node = parent.CreateNode(scanner.GetToken(TokenType.atom), "atom"); parent.Nodes.Add(node); - tok = scanner.LookAhead(TokenType.PLUSMINUS, TokenType.NOT, TokenType.INTEGER, TokenType.DOUBLE, TokenType.TRUEFALSE, TokenType.IDENTIFIER, TokenType.FILEIDENT, TokenType.BRACKETOPEN, TokenType.STRING); + tok = scanner.LookAhead(TokenType.INTEGER, TokenType.DOUBLE, TokenType.TRUEFALSE, TokenType.IDENTIFIER, TokenType.FILEIDENT, TokenType.BRACKETOPEN, TokenType.STRING); switch (tok.Type) { - case TokenType.PLUSMINUS: - case TokenType.NOT: case TokenType.INTEGER: case TokenType.DOUBLE: case TokenType.TRUEFALSE: case TokenType.IDENTIFIER: case TokenType.FILEIDENT: case TokenType.BRACKETOPEN: - - - tok = scanner.LookAhead(TokenType.PLUSMINUS, TokenType.NOT); - if (tok.Type == TokenType.PLUSMINUS - || tok.Type == TokenType.NOT) - { - tok = scanner.LookAhead(TokenType.PLUSMINUS, TokenType.NOT); - switch (tok.Type) - { - case TokenType.PLUSMINUS: - tok = scanner.Scan(TokenType.PLUSMINUS); - n = node.CreateNode(tok, tok.ToString() ); - node.Token.UpdateRange(tok); - node.Nodes.Add(n); - if (tok.Type != TokenType.PLUSMINUS) { - tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.PLUSMINUS.ToString(), 0x1001, tok)); - return; - } - break; - case TokenType.NOT: - tok = scanner.Scan(TokenType.NOT); - n = node.CreateNode(tok, tok.ToString() ); - node.Token.UpdateRange(tok); - node.Nodes.Add(n); - if (tok.Type != TokenType.NOT) { - tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.NOT.ToString(), 0x1001, tok)); - return; - } - break; - default: - tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found.", 0x0002, tok)); - break; - } - } - - tok = scanner.LookAhead(TokenType.INTEGER, TokenType.DOUBLE, TokenType.TRUEFALSE, TokenType.IDENTIFIER, TokenType.FILEIDENT, TokenType.BRACKETOPEN); switch (tok.Type) { diff --git a/src/kOS.Safe/Compilation/KS/Scanner.cs b/src/kOS.Safe/Compilation/KS/Scanner.cs index 2bc984577..bb5c34f36 100644 --- a/src/kOS.Safe/Compilation/KS/Scanner.cs +++ b/src/kOS.Safe/Compilation/KS/Scanner.cs @@ -544,96 +544,97 @@ public enum TokenType compare_expr= 45, arith_expr= 46, multdiv_expr= 47, - factor = 48, - suffix = 49, - suffix_trailer= 50, - suffixterm= 51, - suffixterm_trailer= 52, - function_trailer= 53, - array_trailer= 54, - atom = 55, - sci_number= 56, - number = 57, - varidentifier= 58, - identifier_led_stmt= 59, - identifier_led_expr= 60, + unary_expr= 48, + factor = 49, + suffix = 50, + suffix_trailer= 51, + suffixterm= 52, + suffixterm_trailer= 53, + function_trailer= 54, + array_trailer= 55, + atom = 56, + sci_number= 57, + number = 58, + varidentifier= 59, + identifier_led_stmt= 60, + identifier_led_expr= 61, //Terminal tokens: - PLUSMINUS= 61, - MULT = 62, - DIV = 63, - POWER = 64, - E = 65, - NOT = 66, - AND = 67, - OR = 68, - TRUEFALSE= 69, - COMPARATOR= 70, - SET = 71, - TO = 72, - IF = 73, - ELSE = 74, - UNTIL = 75, - LOCK = 76, - UNLOCK = 77, - PRINT = 78, - AT = 79, - ON = 80, - TOGGLE = 81, - WAIT = 82, - WHEN = 83, - THEN = 84, - OFF = 85, - STAGE = 86, - CLEARSCREEN= 87, - ADD = 88, - REMOVE = 89, - LOG = 90, - BREAK = 91, - PRESERVE= 92, - DECLARE = 93, - PARAMETER= 94, - FUNCTION= 95, - RETURN = 96, - SWITCH = 97, - COPY = 98, - FROM = 99, - RENAME = 100, - VOLUME = 101, - FILE = 102, - DELETE = 103, - EDIT = 104, - RUN = 105, - COMPILE = 106, - LIST = 107, - REBOOT = 108, - SHUTDOWN= 109, - FOR = 110, - UNSET = 111, - BATCH = 112, - DEPLOY = 113, - BRACKETOPEN= 114, - BRACKETCLOSE= 115, - CURLYOPEN= 116, - CURLYCLOSE= 117, - SQUAREOPEN= 118, - SQUARECLOSE= 119, - COMMA = 120, - COLON = 121, - IN = 122, - ARRAYINDEX= 123, - ALL = 124, - IDENTIFIER= 125, - FILEIDENT= 126, - INTEGER = 127, - DOUBLE = 128, - STRING = 129, - EOI = 130, - ATSIGN = 131, - LAZYGLOBAL= 132, - EOF = 133, - WHITESPACE= 134, - COMMENTLINE= 135 + PLUSMINUS= 62, + MULT = 63, + DIV = 64, + POWER = 65, + E = 66, + NOT = 67, + AND = 68, + OR = 69, + TRUEFALSE= 70, + COMPARATOR= 71, + SET = 72, + TO = 73, + IF = 74, + ELSE = 75, + UNTIL = 76, + LOCK = 77, + UNLOCK = 78, + PRINT = 79, + AT = 80, + ON = 81, + TOGGLE = 82, + WAIT = 83, + WHEN = 84, + THEN = 85, + OFF = 86, + STAGE = 87, + CLEARSCREEN= 88, + ADD = 89, + REMOVE = 90, + LOG = 91, + BREAK = 92, + PRESERVE= 93, + DECLARE = 94, + PARAMETER= 95, + FUNCTION= 96, + RETURN = 97, + SWITCH = 98, + COPY = 99, + FROM = 100, + RENAME = 101, + VOLUME = 102, + FILE = 103, + DELETE = 104, + EDIT = 105, + RUN = 106, + COMPILE = 107, + LIST = 108, + REBOOT = 109, + SHUTDOWN= 110, + FOR = 111, + UNSET = 112, + BATCH = 113, + DEPLOY = 114, + BRACKETOPEN= 115, + BRACKETCLOSE= 116, + CURLYOPEN= 117, + CURLYCLOSE= 118, + SQUAREOPEN= 119, + SQUARECLOSE= 120, + COMMA = 121, + COLON = 122, + IN = 123, + ARRAYINDEX= 124, + ALL = 125, + IDENTIFIER= 126, + FILEIDENT= 127, + INTEGER = 128, + DOUBLE = 129, + STRING = 130, + EOI = 131, + ATSIGN = 132, + LAZYGLOBAL= 133, + EOF = 134, + WHITESPACE= 135, + COMMENTLINE= 136 } public class Token diff --git a/src/kOS.Safe/Compilation/KS/kRISC.tpg b/src/kOS.Safe/Compilation/KS/kRISC.tpg index a2a744ac1..4746169c6 100644 --- a/src/kOS.Safe/Compilation/KS/kRISC.tpg +++ b/src/kOS.Safe/Compilation/KS/kRISC.tpg @@ -177,9 +177,9 @@ expr -> and_expr (OR and_expr)*; and_expr -> compare_expr (AND compare_expr)*; compare_expr -> arith_expr (COMPARATOR arith_expr)*; arith_expr -> multdiv_expr (PLUSMINUS multdiv_expr)*; -multdiv_expr -> factor ((MULT|DIV) factor)*; +multdiv_expr -> unary_expr ((MULT|DIV) unary_expr)*; +unary_expr -> (PLUSMINUS|NOT)? factor; factor -> suffix (POWER suffix)*; - suffix -> suffixterm (suffix_trailer)*; suffix_trailer -> (COLON suffixterm); @@ -189,12 +189,12 @@ suffixterm_trailer -> (function_trailer | array_trailer); function_trailer -> (BRACKETOPEN arglist? BRACKETCLOSE); array_trailer -> ( (ARRAYINDEX (IDENTIFIER | INTEGER)) | (SQUAREOPEN expr SQUARECLOSE) ); -atom -> (PLUSMINUS|NOT)? ( sci_number | - TRUEFALSE | - IDENTIFIER | - FILEIDENT | - BRACKETOPEN expr BRACKETCLOSE - ) | STRING; +atom -> ( sci_number | + TRUEFALSE | + IDENTIFIER | + FILEIDENT | + BRACKETOPEN expr BRACKETCLOSE + ) | STRING; sci_number -> number (E PLUSMINUS? INTEGER)?; number -> (INTEGER | DOUBLE); From ee10dd6bc5e66af757362e06656d064b595519b7 Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Sun, 5 Apr 2015 09:24:54 -0500 Subject: [PATCH 328/446] Smallest. change. ever. Paren in ToString text. --- src/kOS/Function/HighlightStructure.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kOS/Function/HighlightStructure.cs b/src/kOS/Function/HighlightStructure.cs index bbe288f31..73a97ae3e 100644 --- a/src/kOS/Function/HighlightStructure.cs +++ b/src/kOS/Function/HighlightStructure.cs @@ -117,7 +117,7 @@ public void Dispose() public override string ToString() { - return string.Format("HIGHLIGHT( Item: {0} Color: {1} Enabled: {2}", toHighlight, color, enabled); + return string.Format("HIGHLIGHT( Item: {0} Color: {1} Enabled: {2})", toHighlight, color, enabled); } } } \ No newline at end of file From 278345c25d60145b558045bd3ef030ec2b339fc0 Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Sun, 5 Apr 2015 11:46:45 -0500 Subject: [PATCH 329/446] commit so I can re-merge the latest develop --- src/kOS.Safe/Compilation/Opcode.cs | 13 +++++++++++-- src/kOS/Suffixed/Direction.cs | 5 +++++ src/kOS/Suffixed/Vector.cs | 4 ++++ 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/kOS.Safe/Compilation/Opcode.cs b/src/kOS.Safe/Compilation/Opcode.cs index 614459e05..cca689d76 100644 --- a/src/kOS.Safe/Compilation/Opcode.cs +++ b/src/kOS.Safe/Compilation/Opcode.cs @@ -6,7 +6,6 @@ using kOS.Safe.Execution; using kOS.Safe.Exceptions; using kOS.Safe.Utilities; - namespace kOS.Safe.Compilation { /// A very short numerical ID for the opcode.
    @@ -893,7 +892,17 @@ public override void Execute(ICpu cpu) else if (value is double) result = -((double)value); else - throw new KOSUnaryOperandTypeException("negate", value); + { + // Generic last-ditch to catch any sort of object that has + // overloaded the unary negate operator '-'. + // (For example, kOS.Suffixed.Vector and kOS.Suffixed.Direction) + Type t = value.GetType(); + MethodInfo negateMe = t.GetMethod("op_UnaryNegation", BindingFlags.Static | BindingFlags.Public); // C#'s alternate name for '-' operator + if (negateMe != null && t.IsSpecialName) + result = negateMe.Invoke(null, new[]{value}); // value is an arg, not the 'this'. (Method is static.) + else + throw new KOSUnaryOperandTypeException("negate", value); + } cpu.PushStack(result); } diff --git a/src/kOS/Suffixed/Direction.cs b/src/kOS/Suffixed/Direction.cs index 36ffe2e51..51f405ea3 100644 --- a/src/kOS/Suffixed/Direction.cs +++ b/src/kOS/Suffixed/Direction.cs @@ -158,6 +158,11 @@ private void DirectionInitializeSuffixes() return new Direction(a.Euler - b.Euler, true); } + public static Direction operator -(Direction a) + { + return new Direction(a.rotation.Inverse()); + } + public override object TryOperation(string op, object other, bool reverseOrder) { var otherVector = other as Vector; diff --git a/src/kOS/Suffixed/Vector.cs b/src/kOS/Suffixed/Vector.cs index f449004e2..1a238c936 100644 --- a/src/kOS/Suffixed/Vector.cs +++ b/src/kOS/Suffixed/Vector.cs @@ -163,5 +163,9 @@ public static explicit operator Direction(Vector d) { return new Vector(a.ToVector3D() - b.ToVector3D()); } + public static Vector operator -(Vector a) + { + return a*(-1); + } } } From 5b1700fc3d4939d3c4eb80cc1242443ef7efbdc1 Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Sun, 5 Apr 2015 12:44:18 -0500 Subject: [PATCH 330/446] Documented unary minus Vector and Direction. --- doc/source/math/direction.rst | 1 + doc/source/math/vector.rst | 28 +++++++++++++++++++++------- src/kOS.Safe/Compilation/Opcode.cs | 2 +- 3 files changed, 23 insertions(+), 8 deletions(-) diff --git a/doc/source/math/direction.rst b/doc/source/math/direction.rst index d51561614..bf1304aed 100644 --- a/doc/source/math/direction.rst +++ b/doc/source/math/direction.rst @@ -126,6 +126,7 @@ Structure :attr:`STARVECTOR` :struct:`Vector` This Direction's starboard vector (z axis after rotation). RIGHTVECTOR :struct:`Vector` Alias synonym for :attr:`STARVECTOR` :attr:`INVERSE` :struct:`Direction` The inverse of this direction. + :attr:`unary minus` :struct:`Direction` Using the negation operator "-" on a Direction does the same thing as using the :INVERSE suffix on it. ========================= =================== ================================ The :struct:`Direction` object exists primarily to enable automated steering. You can initialize a :struct:`Direction` using a :struct:`Vector` or a ``Rotation``. :struct:`Direction` objects represent a rotation starting from an initial point in **KSP**'s coordinate system where the initial state was looking down the :math:`+z` axis, with the camera "up" being the :math:`+y` axis. So for example, a :struct:`Direction` pointing along the :math:`x` axis might be represented as ``R(0,90,0)``, meaning the initial :math:`z`-axis direction was rotated *90 degrees* around the :math:`y` axis. diff --git a/doc/source/math/vector.rst b/doc/source/math/vector.rst index 5958f7787..a68058815 100644 --- a/doc/source/math/vector.rst +++ b/doc/source/math/vector.rst @@ -135,13 +135,14 @@ Operations and Methods ============================================================= ============= Method / Operator Return Type ============================================================= ============= - :ref:`* (asterisk) ` scalar or :struct:`Vector` - :ref:`+ (plus) ` :struct:`Vector` - :ref:`- (minus) ` :struct:`Vector` - :func:`VDOT`, :func:`VECTORDOTPRODUCT`, :ref:`* ` scalar - :func:`VCRS`, :func:`VECTORCROSSPRODUCT` :struct:`Vector` - :func:`VANG`, :func:`VECTORANGLE` scalar (deg) - :func:`VXCL`, :func:`VECTOREXCLUDE` :struct:`Vector` + :ref:`* (asterisk) ` scalar or :struct:`Vector` + :ref:`+ (plus) ` :struct:`Vector` + :ref:`- (minus) ` :struct:`Vector` + :ref:`- (unary) ` :struct:`Vector` + :func:`VDOT`, :func:`VECTORDOTPRODUCT`, :ref:`* ` scalar + :func:`VCRS`, :func:`VECTORCROSSPRODUCT` :struct:`Vector` + :func:`VANG`, :func:`VECTORANGLE` scalar (deg) + :func:`VXCL`, :func:`VECTOREXCLUDE` :struct:`Vector` ============================================================= ============= .. index:: vector multiplication @@ -156,6 +157,12 @@ Method / Operator Return Type PRINT a * vec1. // prints: V(2,4,6) PRINT vec1 * vec2. // prints: 20 + Note that the *unary* minus operator is really a multiplication of + the vector by a scalar of (-1):: + + PRINT -vec1. // these two both print the + PRINT (-1)*vec1. // exact same thing. + .. index:: vector addition .. index:: vector subtraction .. _Vector +-: @@ -169,6 +176,13 @@ Method / Operator Return Type PRINT vec1 + vec2. // prints: V(3,5,7) PRINT vec2 - vec1. // prints: V(1,1,1) + Note that the *unary* minus operator is the same thing as multiplying + the vector by a scalar of (-1), and is not technically an addition or + subtraction operator:: + + PRINT -vec1. // these two both print the + PRINT (-1)*vec1. // exact same thing. + .. function:: VDOT(v1,v2) Same as :func:`VECTORDOTPRODUCT(v1,v2)` and :ref:`v1 * v2 `. diff --git a/src/kOS.Safe/Compilation/Opcode.cs b/src/kOS.Safe/Compilation/Opcode.cs index 918a18395..3027beb88 100644 --- a/src/kOS.Safe/Compilation/Opcode.cs +++ b/src/kOS.Safe/Compilation/Opcode.cs @@ -898,7 +898,7 @@ public override void Execute(ICpu cpu) // (For example, kOS.Suffixed.Vector and kOS.Suffixed.Direction) Type t = value.GetType(); MethodInfo negateMe = t.GetMethod("op_UnaryNegation", BindingFlags.Static | BindingFlags.Public); // C#'s alternate name for '-' operator - if (negateMe != null && t.IsSpecialName) + if (negateMe != null) result = negateMe.Invoke(null, new[]{value}); // value is an arg, not the 'this'. (Method is static.) else throw new KOSUnaryOperandTypeException("negate", value); From 20d0ff33bc0910b38aa309b8caa38c6275327a42 Mon Sep 17 00:00:00 2001 From: Chris Woerz Date: Sun, 5 Apr 2015 20:04:45 -0600 Subject: [PATCH 331/446] fixes #193 --- src/kOS.Safe/Binding/BoundVariable.cs | 19 +------------------ src/kOS/Binding/BindingManager.cs | 12 +----------- 2 files changed, 2 insertions(+), 29 deletions(-) diff --git a/src/kOS.Safe/Binding/BoundVariable.cs b/src/kOS.Safe/Binding/BoundVariable.cs index 983c140ab..8a98a2beb 100644 --- a/src/kOS.Safe/Binding/BoundVariable.cs +++ b/src/kOS.Safe/Binding/BoundVariable.cs @@ -9,7 +9,6 @@ public class BoundVariable : Variable public BindingGetDlg Get; private object currentValue; - private bool wasUpdated; public override object Value { @@ -31,23 +30,7 @@ public override object Value set { if (Set == null) return; - - currentValue = value; - wasUpdated = true; - } - } - - public void ClearValue() - { - currentValue = null; - wasUpdated = false; - } - - public void SaveValue() - { - if (wasUpdated && currentValue != null) - { - Set(currentValue); + Set(value); } } } diff --git a/src/kOS/Binding/BindingManager.cs b/src/kOS/Binding/BindingManager.cs index 093cfd461..de18b0682 100644 --- a/src/kOS/Binding/BindingManager.cs +++ b/src/kOS/Binding/BindingManager.cs @@ -89,21 +89,11 @@ public void PreUpdate() { b.Update(); } - - // clear bound variables values - foreach (var variable in variables.Values) - { - variable.ClearValue(); - } } public void PostUpdate() { - // save bound variables values - foreach (BoundVariable variable in variables.Values) - { - variable.SaveValue(); - } + } public void ToggleFlyByWire(string paramName, bool enabled) From 31042a8e2c8f77b1a7ebc2038ca80b743dcedae4 Mon Sep 17 00:00:00 2001 From: Chris Woerz Date: Mon, 6 Apr 2015 21:46:36 -0600 Subject: [PATCH 332/446] fixed binding cache clearing --- src/kOS.Safe/Binding/BoundVariable.cs | 5 +++++ src/kOS/Binding/BindingManager.cs | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/src/kOS.Safe/Binding/BoundVariable.cs b/src/kOS.Safe/Binding/BoundVariable.cs index 8a98a2beb..e00f3a7ff 100644 --- a/src/kOS.Safe/Binding/BoundVariable.cs +++ b/src/kOS.Safe/Binding/BoundVariable.cs @@ -33,5 +33,10 @@ public override object Value Set(value); } } + + public void ClearCache() + { + currentValue = null; + } } } diff --git a/src/kOS/Binding/BindingManager.cs b/src/kOS/Binding/BindingManager.cs index de18b0682..c9c5218c5 100644 --- a/src/kOS/Binding/BindingManager.cs +++ b/src/kOS/Binding/BindingManager.cs @@ -84,6 +84,10 @@ public void AddSetter(string name, BindingSetDlg dlg) public void PreUpdate() { + foreach (var variable in variables) + { + variable.Value.ClearCache(); + } // update the bindings foreach (var b in bindings) { From 37a002673e3ef0e6c55150174fe0f03f8442ce4a Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Tue, 7 Apr 2015 03:11:12 -0500 Subject: [PATCH 333/446] lock scoping now exists. --- src/kOS.Safe/Compilation/KS/Compiler.cs | 12 ++- src/kOS.Safe/Compilation/Opcode.cs | 87 +++++++++++++++++++++- src/kOS.Safe/Compilation/ProgramBuilder.cs | 6 +- src/kOS.Safe/Execution/ICpu.cs | 2 + src/kOS.Safe/Execution/VariableScope.cs | 8 ++ src/kOS.Safe/kOS.Safe.csproj | 2 + src/kOS/Execution/CPU.cs | 49 ++++++++++-- src/kOS/Execution/Stack.cs | 53 ++++++------- src/kOS/kOS.csproj | 1 + 9 files changed, 176 insertions(+), 44 deletions(-) diff --git a/src/kOS.Safe/Compilation/KS/Compiler.cs b/src/kOS.Safe/Compilation/KS/Compiler.cs index b02213a7d..fe401b977 100644 --- a/src/kOS.Safe/Compilation/KS/Compiler.cs +++ b/src/kOS.Safe/Compilation/KS/Compiler.cs @@ -486,11 +486,18 @@ private void PreProcessUserFunctionStatement(ParseNode node) // lock expression's or function body's code currentCodeSection = userFuncObject.GetUserFunctionOpcodes(expressionHash); + if (isLock) // locks need to behave as if they had braces even though they don't - so they get lexical scope ids for closure reasons: + BeginScope(node); if (isDefFunc) nextBraceIsFunction = true; + VisitNode(bodyNode); + if (isDefFunc) nextBraceIsFunction = false; + if (isLock) // locks need to behave as if they had braces even though they don't - so they get lexical scope ids for closure reasons: + EndScope(node); + if (needImplicitReturn) { if (isDefFunc) @@ -745,7 +752,8 @@ private void TraverseScopeBranch(ParseNode node) { // List all the types of parse node that open a new variable scope here: // --------------------------------------------------------------------- - case TokenType.for_stmt: // Here because it wraps the body inside an outer scope that holds the for-iterator variable. + case TokenType.for_stmt: // Here because it wraps the body inside an outer scope that holds the for-iterator variable. + case TokenType.lock_stmt: // here because the lock body needs a scope in order to work with closures. The scope remembers the lexical id. case TokenType.instruction_block: ++braceNestLevel; @@ -1934,7 +1942,7 @@ private void VisitLockStatement(ParseNode node) string functionLabel = lockObject.GetUserFunctionOpcodes(expressionHash)[0].Label; // lock variable AddOpcode(new OpcodePush(lockObject.PointerIdentifier)); - AddOpcode(new OpcodePushRelocateLater(null), functionLabel); + AddOpcode(new OpcodePushDelegateRelocateLater(null), functionLabel); if (allowLazyGlobal) AddOpcode(new OpcodeStore()); else diff --git a/src/kOS.Safe/Compilation/Opcode.cs b/src/kOS.Safe/Compilation/Opcode.cs index b5d4f1f53..0bb66b736 100644 --- a/src/kOS.Safe/Compilation/Opcode.cs +++ b/src/kOS.Safe/Compilation/Opcode.cs @@ -78,12 +78,14 @@ public enum ByteCode :byte PUSHSCOPE = 0x59, POPSCOPE = 0x5a, STOREEXIST = 0x5b, + PUSHDELEGATE = 0x5c, // Augmented bogus placeholder versions of the normal // opcodes: These only exist in the program temporarily // or in the ML file but never actually can be executed. PUSHRELOCATELATER = 0xce, + PUSHDELEGATERELOCATELATER = 0xcd, LABELRESET = 0xf0 // for storing the fact that the Opcode.Label's positional index jumps weirdly. } @@ -1178,14 +1180,23 @@ public override void Execute(ICpu cpu) functionPointer = cpu.GetValue(functionName); } } - - if (functionPointer is int) + IUserDelegate userDelegate = functionPointer as IUserDelegate; + if (userDelegate != null) + functionPointer = userDelegate.EntryPoint; + + if (functionPointer is int) { ReverseStackArgs(cpu); int currentPointer = cpu.InstructionPointer; DeltaInstructionPointer = (int)functionPointer - currentPointer; var contextRecord = new SubroutineContext(currentPointer+1); cpu.PushAboveStack(contextRecord); + if (userDelegate != null) + { + // Reverse-push the closure's scope record, just after the function return context got put on the stack. + for (int i = userDelegate.Closure.Count - 1 ; i >= 0 ; --i) + cpu.PushAboveStack(userDelegate.Closure[i]); + } } else if (functionPointer is string) { @@ -1359,12 +1370,26 @@ public class OpcodeReturn : Opcode public override void Execute(ICpu cpu) { + // The only thing on the "above stack" now that is allowed to get in the way of + // finding the context record that tells us where to jump back to, are the potential + // closure scope frames that might have been pushed if this subroutine was + // called via a delegate reference. Consume any of those that are in + // the way, then expect the context record. Any other pattern encountered + // is proof the stack alignment got screwed up: + bool okay; + VariableScope peeked = cpu.PeekRaw(-1, out okay) as VariableScope; + while (okay && peeked != null && peeked.IsClosure) + { + cpu.PopAboveStack(1); + peeked = cpu.PeekRaw(-1, out okay) as VariableScope; + } object shouldBeContextRecord = cpu.PopAboveStack(1); if ( !(shouldBeContextRecord is SubroutineContext) ) { // This should never happen with any user code: throw new Exception( "kOS internal error: Stack misalignment detected when returning from routine."); } + // Return value should be atop the stack - we have to pop it so that // we can reach the arg start marker under it: object returnVal = cpu.PopValue(); @@ -1665,14 +1690,70 @@ public override void Execute(ICpu cpu) { cpu.PopAboveStack(NumLevels); } - + public override string ToString() { return Name + " " + NumLevels; } } + + public class OpcodePushDelegate : Opcode + { + [MLField(1,false)] + private int EntryPoint { get; set; } + + protected override string Name { get { return "pushdelegate"; } } + public override ByteCode Code { get { return ByteCode.PUSHDELEGATE; } } + + public OpcodePushDelegate(int entryPoint) + { + EntryPoint = entryPoint; + } + + /// + /// This variant of the constructor is just for ML file save/load to use. + /// + protected OpcodePushDelegate() { } + + public override void PopulateFromMLFields(List fields) + { + // Expect fields in the same order as the [MLField] properties of this class: + if (fields == null || fields.Count<1) + throw new Exception("Saved field in ML file for OpcodePush seems to be missing. Version mismatch?"); + EntryPoint = (int)fields[0]; + } + + public override void Execute(ICpu cpu) + { + cpu.PushStack(cpu.MakeUserDelegate(EntryPoint)); + } + + public override string ToString() + { + return Name + " " + EntryPoint.ToString(); + } + } + + /// + /// This serves the same purpose as OpcodePushRelocateLater, except it's for + /// use with UserDelegates instead of raw integer IP calls. + /// + public class OpcodePushDelegateRelocateLater : OpcodePushRelocateLater + { + protected override string Name { get { return "PushDelegateRelocateLater"; } } + public override ByteCode Code { get { return ByteCode.PUSHDELEGATERELOCATELATER; } } + + public OpcodePushDelegateRelocateLater(string destLabel) : base(destLabel) + { + } + /// + /// This variant of the constructor is just for ML file save/load to use. + /// + protected OpcodePushDelegateRelocateLater() : base() { } + } + #endregion #region Wait / Trigger diff --git a/src/kOS.Safe/Compilation/ProgramBuilder.cs b/src/kOS.Safe/Compilation/ProgramBuilder.cs index 6b2582bdb..90361cad1 100644 --- a/src/kOS.Safe/Compilation/ProgramBuilder.cs +++ b/src/kOS.Safe/Compilation/ProgramBuilder.cs @@ -130,7 +130,11 @@ private void ReplaceLabels(List program) else if (opcode is OpcodePushRelocateLater) { // Replace the OpcodePushRelocateLater with the proper OpcodePush: - OpcodePush newOp = new OpcodePush(destinationIndex); + Opcode newOp; + if (opcode is OpcodePushDelegateRelocateLater) + newOp = new OpcodePushDelegate(destinationIndex); + else + newOp = new OpcodePush(destinationIndex); newOp.SourceName = opcode.SourceName; newOp.SourceLine = opcode.SourceLine; newOp.SourceColumn = opcode.SourceColumn; diff --git a/src/kOS.Safe/Execution/ICpu.cs b/src/kOS.Safe/Execution/ICpu.cs index 000885f55..147c0fb31 100644 --- a/src/kOS.Safe/Execution/ICpu.cs +++ b/src/kOS.Safe/Execution/ICpu.cs @@ -10,6 +10,8 @@ public interface ICpu : IFixedUpdateObserver void MoveStackPointer(int delta); void PushAboveStack(object thing); object PopAboveStack(int howMany); + List GetCurrentClosure(); + IUserDelegate MakeUserDelegate(int entryPoint); object GetValue(object testValue, bool barewordOkay = false); object PopValue(bool barewordOkay = false); object PeekValue(int digDepth, bool barewordOkay = false); diff --git a/src/kOS.Safe/Execution/VariableScope.cs b/src/kOS.Safe/Execution/VariableScope.cs index a139b31a6..6d039af29 100644 --- a/src/kOS.Safe/Execution/VariableScope.cs +++ b/src/kOS.Safe/Execution/VariableScope.cs @@ -30,6 +30,13 @@ public class VariableScope /// can jump there quicker next time without scanning the scope stack. /// public Int16 ParentSkipLevels {get;set;} + + /// + /// Set this to true to indicate that this scope is part of a closure + /// call. That lets OpcodePushStack and OpcodePopStack to know it + /// needs to be treated specially. + /// + public bool IsClosure {get;set;} public Dictionary Variables; @@ -39,6 +46,7 @@ public VariableScope(Int16 scopeId, Int16 parentScopeId) ParentScopeId = parentScopeId; ParentSkipLevels = 1; // the default case is to just move one stack level. Variables = new Dictionary(); + IsClosure = false; } } } diff --git a/src/kOS.Safe/kOS.Safe.csproj b/src/kOS.Safe/kOS.Safe.csproj index 7d4c944cc..8089ae762 100644 --- a/src/kOS.Safe/kOS.Safe.csproj +++ b/src/kOS.Safe/kOS.Safe.csproj @@ -116,6 +116,8 @@ + + diff --git a/src/kOS/Execution/CPU.cs b/src/kOS/Execution/CPU.cs index 28e6cdb65..3b779967e 100644 --- a/src/kOS/Execution/CPU.cs +++ b/src/kOS/Execution/CPU.cs @@ -22,7 +22,7 @@ private enum Status Waiting = 2 } - private readonly Stack stack; + private readonly IStack stack; private readonly VariableScope globalVariables; private Status currentStatus; private double currentTime; @@ -205,6 +205,32 @@ private void PopFirstContext() PopContext(); } } + + /// + /// Build a clone of the current state of the scope stack, for the sake of capturing a closure. + /// + /// A stripped down copy of the stack with just the relevant closure frames in it. + public List GetCurrentClosure() + { + List closureList = new List(); + GetNestedDictionary("", closureList); + // The closure's variable scopes need to be marked as such, so the + // 'popscope' opcode knows to pop them off in one go when it hits + // them on the stack: + foreach (VariableScope scope in closureList) + scope.IsClosure = true; + return closureList; + } + + /// + /// Build a delegate call for the given function entry point, in which it will capture a closure of the current + /// runtime scoping state to be used when that function gets called later by OpcodeCall: + /// + /// The delegate object you can store in a variable. + public IUserDelegate MakeUserDelegate(int entryPoint) + { + return (IUserDelegate) new UserDelegate(this, entryPoint, true); + } // only two contexts exist now, one for the interpreter and one for the programs public ProgramContext GetInterpreterContext() @@ -373,7 +399,7 @@ private VariableScope GetNestedDictionary(int peekDepth) } return stackItem == null ? globalVariables : (VariableScope) stackItem; } - + /// /// Gets the dictionary that contains the given identifier, starting the /// search at the local level and scanning the scopes upward all the @@ -383,10 +409,16 @@ private VariableScope GetNestedDictionary(int peekDepth) /// of the parse tree. (i.e. if a function calls a function elsewhere).
    /// Returns null when no hit was found.
    ///
    - /// identifier name to search for + /// identifier name to search for. Pass an empty string to guarentee no hits will + /// be found (which is useful to do when using the searchReport argument). + /// If you want to see the list of all the scopes that constituted the search + /// path, not just the final hit, pass an empty list here and this method will fill it for you with + /// that report. Pass in a null to not get a report. /// The dictionary found, or null if no dictionary contains the identifier. - private VariableScope GetNestedDictionary(string identifier) + private VariableScope GetNestedDictionary(string identifier, List searchReport = null) { + if (searchReport != null) + searchReport.Clear(); Int16 rawStackDepth = 0 ; while (true) /*all of this loop's exits are explicit break or return statements*/ { @@ -401,11 +433,14 @@ private VariableScope GetNestedDictionary(string identifier) continue; } + if (searchReport != null) + searchReport.Add(localDict); + if (localDict.Variables.ContainsKey(identifier)) return localDict; - - // Get the next VariableScope that is the lexical (not runtime) parent of this one: + // Get the next VariableScope that is valid, where valid means: + // It is the lexical (not runtime) parent of this scope. // ------------------------------------------------------------------------------- // Scan the stack until the variable scope with the right parent ID is seen: @@ -422,7 +457,6 @@ private VariableScope GetNestedDictionary(string identifier) needsIncrement = false; break; } - // In the case where the variable scope is the SAME lexical ID as myself, that // means I recursively called myself and the thing on the runtime stack just before // me is ... another instance of me. In that case just follow it's parent skip level @@ -433,7 +467,6 @@ private VariableScope GetNestedDictionary(string identifier) needsIncrement = false; } } - if (needsIncrement) { ++skippedLevels; diff --git a/src/kOS/Execution/Stack.cs b/src/kOS/Execution/Stack.cs index 01c626b11..c6b69a1c3 100644 --- a/src/kOS/Execution/Stack.cs +++ b/src/kOS/Execution/Stack.cs @@ -6,7 +6,7 @@ namespace kOS.Execution { - public class Stack + public class Stack : IStack { private const int MAX_STACK_SIZE = 1000; private readonly List stack = new List(); @@ -17,27 +17,25 @@ public void Push(object item) ThrowIfInvalid(item); stackPointer++; - if (stackPointer < MAX_STACK_SIZE) - { + if (stackPointer < MAX_STACK_SIZE) { stack.Insert(stackPointer, ProcessItem(item)); - } - else + } else // TODO: make an IKOSException for this: throw new Exception("Stack overflow!!"); } private void ThrowIfInvalid(object item) { - if (!Config.Instance.EnableSafeMode) return; - if (!(item is double)) return; + if (!Config.Instance.EnableSafeMode) + return; + if (!(item is double)) + return; - if (Double.IsNaN((double)item)) - { + if (Double.IsNaN((double)item)) { // TODO: make an IKOSException for this: throw new Exception("Tried to push NaN into the stack."); } - if (Double.IsInfinity((double)item)) - { + if (Double.IsInfinity((double)item)) { // TODO: make an IKOSException for this: throw new Exception("Tried to push Infinity into the stack."); } @@ -60,8 +58,7 @@ public object Pop() { object item = null; - if (stack.Count > 0) - { + if (stack.Count > 0) { item = stack[stackPointer]; stack.RemoveAt(stackPointer); stackPointer--; @@ -69,7 +66,7 @@ public object Pop() return item; } - + /// /// Slightly "cheats" and breaks out of the 'stack' model by allowing you to view the contents of /// somewhere on the stack that is underneath the topmost thing. You can only peek, but not pop @@ -121,7 +118,7 @@ public int GetLogicalSize() { return stackPointer + 1; } - + public void MoveStackPointer(int delta) { stackPointer += delta; @@ -141,28 +138,26 @@ public string Dump() // Print in reverse order so the top of the stack is on top of the printout: // (actually given the double nature of the stack, one of the two sub-stacks // inside it will always be backwardly printed): - for (int index = stack.Count-1 ; index >= 0 ; --index) - { + for (int index = stack.Count - 1; index >= 0; --index) { object item = stack[index]; - builder.AppendLine(string.Format("{0:000} {1,4} {2}", index, (index==stackPointer ? "SP->" : "" ), item)); + builder.AppendLine(string.Format("{0:000} {1,4} {2}", index, (index == stackPointer ? "SP->" : ""), item)); VariableScope dict = item as VariableScope; - if (dict != null) - { - builder.AppendFormat(" ScopeId={0}, ParentScopeId={1}, ParentSkipLevels={2}", dict.ScopeId, dict.ParentScopeId, dict.ParentSkipLevels); + if (dict != null) { + builder.AppendFormat(" ScopeId={0}, ParentScopeId={1}, ParentSkipLevels={2} IsClosure={3}", + dict.ScopeId, dict.ParentScopeId, dict.ParentSkipLevels, dict.IsClosure); builder.AppendLine(); // Dump the local variable context stored here on the stack: - foreach (string varName in dict.Variables.Keys) - { + foreach (string varName in dict.Variables.Keys) { builder.AppendFormat(" local var {0} is {1} with value = {2}", varName, varName.GetType().FullName, dict.Variables[varName].Value); builder.AppendLine(); } } - + } return builder.ToString(); } - + /// /// Return the subroutine call trace of how the code got to where it is right now. /// @@ -171,11 +166,9 @@ public string Dump() public List GetCallTrace() { var trace = new List(); - for (int index = stackPointer+1 ; index < stack.Count ; ++index) - { - if (stack[index] is SubroutineContext) - { - trace.Add( ((SubroutineContext)(stack[index])).CameFromInstPtr - 1 ); + for (int index = stackPointer + 1; index < stack.Count; ++index) { + if (stack[index] is SubroutineContext) { + trace.Add(((SubroutineContext)(stack[index])).CameFromInstPtr - 1); } } return trace; diff --git a/src/kOS/kOS.csproj b/src/kOS/kOS.csproj index dfb044378..97221a667 100644 --- a/src/kOS/kOS.csproj +++ b/src/kOS/kOS.csproj @@ -73,6 +73,7 @@ + From f184a3b0a755f81b030964aaba699919466f7089 Mon Sep 17 00:00:00 2001 From: Chris Woerz Date: Wed, 8 Apr 2015 07:42:36 -0600 Subject: [PATCH 334/446] fixes #747, fixes #731 --- src/kOS.Safe/Persistence/Volume.cs | 35 +++++++++++++++++------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/src/kOS.Safe/Persistence/Volume.cs b/src/kOS.Safe/Persistence/Volume.cs index 47eebeff5..98d34cd2a 100644 --- a/src/kOS.Safe/Persistence/Volume.cs +++ b/src/kOS.Safe/Persistence/Volume.cs @@ -40,16 +40,6 @@ protected Volume() InitializeVolumeSuffixes(); } - private void InitializeVolumeSuffixes() - { - AddSuffix("FREESPACE" , new Suffix(() => GetFreeSpace())); - AddSuffix("CAPACITY" , new Suffix(() => Capacity)); - AddSuffix("NAME" , new Suffix(() => Name)); - AddSuffix("RENAMEABLE" , new Suffix(() => Name)); - AddSuffix("FILES" , new Suffix>(() => new ListValue(GetFileList()))); - AddSuffix("POWERREQUIREMENT" , new Suffix(RequiredPower)); - } - /// /// Get a file given its name /// @@ -173,11 +163,6 @@ public virtual List GetFileList() returnList.Sort(FileInfoComparer); // make sure files will print in sorted form. return returnList; } - - private int FileInfoComparer(FileInfo a, FileInfo b) - { - return String.CompareOrdinal(a.Name, b.Name); - } public virtual float RequiredPower() { @@ -187,6 +172,21 @@ public virtual float RequiredPower() return powerRequired; } + public override string ToString() + { + return "Volume( " + Name + ", " + Capacity + ")"; + } + + private void InitializeVolumeSuffixes() + { + AddSuffix("FREESPACE" , new Suffix(() => GetFreeSpace())); + AddSuffix("CAPACITY" , new Suffix(() => Capacity)); + AddSuffix("NAME" , new Suffix(() => Name)); + AddSuffix("RENAMEABLE" , new Suffix(() => Renameable)); + AddSuffix("FILES" , new Suffix>(() => new ListValue(GetFileList()))); + AddSuffix("POWERREQUIREMENT" , new Suffix(RequiredPower)); + } + private ProgramFile FileSearch(string name, bool ksmDefault = false) { SafeHouse.Logger.SuperVerbose("Volume: FileSearch: " + files.Count); @@ -211,5 +211,10 @@ private ProgramFile FileSearch(string name, bool ksmDefault = false) } return null; } + + private int FileInfoComparer(FileInfo a, FileInfo b) + { + return String.CompareOrdinal(a.Name, b.Name); + } } } From 1c0bf4e73fdd72243c19fb02fe865e3c9c4b9fad Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Wed, 8 Apr 2015 22:55:26 -0500 Subject: [PATCH 335/446] Added buffer boolean so it won't inherit to child braces. --- src/kOS.Safe/Compilation/KS/Compiler.cs | 16 +++++++--- src/kOS.Safe/Execution/IStack.cs | 20 +++++++++++++ src/kOS.Safe/Execution/IUserDelegate.cs | 17 +++++++++++ src/kOS/Execution/UserDelegate.cs | 40 +++++++++++++++++++++++++ 4 files changed, 89 insertions(+), 4 deletions(-) create mode 100644 src/kOS.Safe/Execution/IStack.cs create mode 100644 src/kOS.Safe/Execution/IUserDelegate.cs create mode 100644 src/kOS/Execution/UserDelegate.cs diff --git a/src/kOS.Safe/Compilation/KS/Compiler.cs b/src/kOS.Safe/Compilation/KS/Compiler.cs index b02213a7d..93ed5aa69 100644 --- a/src/kOS.Safe/Compilation/KS/Compiler.cs +++ b/src/kOS.Safe/Compilation/KS/Compiler.cs @@ -1881,15 +1881,23 @@ private void VisitInstructionBlock(ParseNode node) { NodeStartHousekeeping(node); BeginScope(node); - if (nextBraceIsFunction) + + // Ensure the flag doesn't stay on for inner braces unless they too are really functions and turn it back on: + bool nextBraceWasFunction = nextBraceIsFunction; + nextBraceIsFunction = false; + + if (nextBraceWasFunction) PushReturnList(); + AddFunctionJumpVars(node); - VisitChildNodes(node); - if (nextBraceIsFunction) + VisitChildNodes(node); // nextBraceIsFunction state would get incorrectly inherited by my children here if it wasn't turned off up above. + + if (nextBraceWasFunction) PopReturnList(); + EndScope(node); } - + /// /// Add all the variables at this local scope for holding the jump addresses to go to /// for the given function names defined in this scope. Pass a NULL to mean global scope. diff --git a/src/kOS.Safe/Execution/IStack.cs b/src/kOS.Safe/Execution/IStack.cs new file mode 100644 index 000000000..0b376104a --- /dev/null +++ b/src/kOS.Safe/Execution/IStack.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Text; +using kOS.Safe.Execution; + +namespace kOS.Safe.Execution +{ + public interface IStack + { + void Push(object item); + object Pop(); + object Peek(int digDepth); + bool PeekCheck(int digDepth, out object item); + int GetLogicalSize(); + void MoveStackPointer(int delta); + void Clear(); + string Dump(); + List GetCallTrace(); + } +} diff --git a/src/kOS.Safe/Execution/IUserDelegate.cs b/src/kOS.Safe/Execution/IUserDelegate.cs new file mode 100644 index 000000000..c6de0b1ce --- /dev/null +++ b/src/kOS.Safe/Execution/IUserDelegate.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using kOS.Safe.Execution; + +namespace kOS.Safe.Execution +{ + /// + /// A callback reference to a user-land function, implemented in kRISC code
    + ///
    + /// (As opposed to being a C# delegate, implemented in C# code).
    + ///
    + public interface IUserDelegate + { + int EntryPoint {get;} + List Closure {get;} + } +} diff --git a/src/kOS/Execution/UserDelegate.cs b/src/kOS/Execution/UserDelegate.cs new file mode 100644 index 000000000..2dc913aee --- /dev/null +++ b/src/kOS/Execution/UserDelegate.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; +using kOS.Safe.Execution; + +namespace kOS.Execution +{ + /// + /// A callback reference to a user-land function, implemented in kRISC code
    + ///
    + /// (As opposed to being a C# delegate, implemented in C# code).
    + ///
    + public class UserDelegate : IUserDelegate + { + public int EntryPoint {get; private set;} + private ICpu cpu; + public List Closure {get; private set;} + + /// + /// Make a new UserDelegate given the current state of the CPU and its stack, and + /// the entry point location of the function to call. + /// + /// the CPU on which this program is running. + /// instruction address where OpcodeCall should jump to to call the function. + /// If true, then a snapshot of the current scoping stack, and thus a persistent ref to its variables, + /// will be kept in the delegate so it can be called later as a callback with closure. Set to false if the + /// function is only getting called instantly using whatever the scope is at the time of the call. + public UserDelegate(ICpu cpu, int entryPoint, bool useClosure) + { + this.cpu = cpu; + EntryPoint = entryPoint; + if (useClosure) + CaptureClosure(); + } + + private void CaptureClosure() + { + Closure = cpu.GetCurrentClosure(); + } + } +} From e1f047678fa6f01808e235d4516ec7fbe10569f5 Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Wed, 8 Apr 2015 23:21:13 -0500 Subject: [PATCH 336/446] Added missing files, which includes fix to #756 --- .../user_functions/functest10.ks | 12 ++++ .../user_functions/functest10_inner.ks | 8 +++ kerboscript_tests/user_functions/functest9.ks | 27 ++++++++ .../user_functions/testclosure1.ks | 15 ++++ .../user_functions/testclosure2.ks | 41 +++++++++++ .../user_functions/testclosure3.ks | 40 +++++++++++ .../user_functions/testreturn1.ks | 68 +++++++++++++++++++ 7 files changed, 211 insertions(+) create mode 100644 kerboscript_tests/user_functions/functest10.ks create mode 100644 kerboscript_tests/user_functions/functest10_inner.ks create mode 100644 kerboscript_tests/user_functions/functest9.ks create mode 100644 kerboscript_tests/user_functions/testclosure1.ks create mode 100644 kerboscript_tests/user_functions/testclosure2.ks create mode 100644 kerboscript_tests/user_functions/testclosure3.ks create mode 100644 kerboscript_tests/user_functions/testreturn1.ks diff --git a/kerboscript_tests/user_functions/functest10.ks b/kerboscript_tests/user_functions/functest10.ks new file mode 100644 index 000000000..abcd4b459 --- /dev/null +++ b/kerboscript_tests/user_functions/functest10.ks @@ -0,0 +1,12 @@ +// Testing a script calling a script with arguments. + +declare parameter arg1,arg2,arg3. + +print "Outer script (functest10) called with arguments:". +print " arg1=" + arg1. +print " arg2=" + arg2. +print " arg3=" + arg3. + +print "Now functest10 is going to call functest10_inner,". +print "Giving it the same args in the same order:". +run functest10_inner(arg1,arg2,arg3). diff --git a/kerboscript_tests/user_functions/functest10_inner.ks b/kerboscript_tests/user_functions/functest10_inner.ks new file mode 100644 index 000000000..6c5e2522a --- /dev/null +++ b/kerboscript_tests/user_functions/functest10_inner.ks @@ -0,0 +1,8 @@ +declare parameter inner1, inner2, inner3. + +print "This is functest10_inner talking.". +print "I think my args are:". + +print " arg1="+arg1. +print " arg2="+arg2. +print " arg3="+arg3. diff --git a/kerboscript_tests/user_functions/functest9.ks b/kerboscript_tests/user_functions/functest9.ks new file mode 100644 index 000000000..860663271 --- /dev/null +++ b/kerboscript_tests/user_functions/functest9.ks @@ -0,0 +1,27 @@ +print "THIS IS A DELIBERATE TEST OF INFINITE RECURSION.". +print "Let's see how long this goes before KSP barfs.". +print "And let's make sure KSP barfs in a 'clean' way.". + +// Give some time to hit ctrl-C before the big spew of scrolling starts: +print "Starting recurse in....". +print "5 seconds". +wait 1. +print "4 seconds". +wait 1. +print "3 seconds". +wait 1. +print "2 seconds". +wait 1. +print "1 seconds". +wait 1. +print "now". + +recurse(0). + +declare function recurse { + declare parameter depth. + + print " Recurse depth="+depth. + + return recurse(depth+1). +}. diff --git a/kerboscript_tests/user_functions/testclosure1.ks b/kerboscript_tests/user_functions/testclosure1.ks new file mode 100644 index 000000000..381b2d283 --- /dev/null +++ b/kerboscript_tests/user_functions/testclosure1.ks @@ -0,0 +1,15 @@ +// Simple test of lock closures +// Test 1: one scope level, not in a function: + +set x to 1. +lock testlock to x. + +print "testlock before scope = " + testlock. +if true { // pointless 'if' to have an excuse for a set of braces + declare local_x to 4. + + lock testlock to x + local_x. // a mix of both local and global things in the expression. + + print "testlock inside scope = " + testlock. +}. +print "testlock after scope = " + testlock. diff --git a/kerboscript_tests/user_functions/testclosure2.ks b/kerboscript_tests/user_functions/testclosure2.ks new file mode 100644 index 000000000..40c4e56a1 --- /dev/null +++ b/kerboscript_tests/user_functions/testclosure2.ks @@ -0,0 +1,41 @@ +// Simple test of lock closures +// Test 2: nested scope levels, not in a function: + +set x to 1. +set indent to " ". +lock testlock to x. + +declare function printindent{ + declare parameter indent. + print indent + "testlock = " + testlock. +} + +printindent(indent + " before, "). + +// The 'if true' commands are just here to allow valid braces to exist: +if true { + declare local_x to 2. + declare indent to indent + " ". // indent with a longer indent string + + lock testlock to x + local_x. + printindent(indent + " before, "). + + if true { + declare localer_x to 3. + declare indent to indent + " ". + + lock testlock to x + local_x + localer_x. + printindent(indent + " before, "). + + if true { + declare localest_x to 4. + declare indent to indent + " ". + + lock testlock to x + local_x + localer_x + localest_x. + printindent(indent + " innermost, "). + }. + printindent(indent + " after, "). + }. + printindent(indent + " after, "). +}. +printindent(indent + " after, "). diff --git a/kerboscript_tests/user_functions/testclosure3.ks b/kerboscript_tests/user_functions/testclosure3.ks new file mode 100644 index 000000000..6517c9d72 --- /dev/null +++ b/kerboscript_tests/user_functions/testclosure3.ks @@ -0,0 +1,40 @@ +// Test of lock closures in which the thing being locked +// is cooked control values 'steering' and 'throttle': + + +// silly example to set the throttle to a +// random value within a clamped range: +declare function set_throt_to_clamped_random { + declare parameter minVal, maxVal. + + declare variance to random(). + + lock throttle to minVal + (maxVal-minVal)*variance. +}. + +// silly example to set the steering to a +// random rotation: +declare function set_steering_random +{ + declare xrot to random()*360. + declare yrot to random()*360. + declare zrot to random()*360. + + lock steering to R(xrot,yrot,zrot). +} + +print "Fiddling with the controls randomly for a few seconds:". +set iteration to 0. +until iteration >= 3 { + set_throt_to_clamped_random(0,0.5). + set_steering_random. + print "Keeping these new values for 5 seconds:". + print " trottle = " + round(throttle, 3) + " (clamped from 0 to 0.5).". + print " steering = " + steering. + wait 5. + set iteration to iteration + 1. +}. + +print "Now leaving controls alone at whatever they were.". +print "For 10 seconds before quitting program.". +wait 10. diff --git a/kerboscript_tests/user_functions/testreturn1.ks b/kerboscript_tests/user_functions/testreturn1.ks new file mode 100644 index 000000000..36c88cec1 --- /dev/null +++ b/kerboscript_tests/user_functions/testreturn1.ks @@ -0,0 +1,68 @@ +// Testing some deeply nested returns + +declare function outer1 { + print "function outer1: before for loop". + set foo to list(). + foo:add(1). + foo:add(2). + foo:add(3). + for thing in foo { + print "thing is " + thing. + if thing = 3 { + return true. + }. + }. + print "function outer1: after for loop". + return false. +}. + +declare function outer2 { + print "function outer2: before inner function". + + print "function outer2 is now calling function outer1 again.". + + if outer1() { + print "outer returned early.". + } else { + print "outer executed all the way to the bottom.". + } + + print "function outer2 is done with function outer1.". + + declare function inner { + set foo to list(). + foo:add(1). + foo:add(2). + foo:add(3). + for thing in foo { + print "inner: thing is " + thing. + if thing = 3 { + return true. + }. + }. + return false. + }. + + print "function outer2 is going to now call inner.". + if inner() { + print "inner returned early.". + } else { + print "inner executed all the way to the bottom.". + } + print "function outer2 is done calling inner.". + + print "function outer2: after inner function". +}. + +print "before calling function outer1.". +if outer1() { + print "outer returned early.". +} else { + print "outer executed all the way to the bottom.". +} +print "after calling function outer1.". + +print "before calling function outer2.". +outer2(). +print "done calling function outer2.". + From badb83f273fae920ff75e9a0cc2ca0a7fa3da69f Mon Sep 17 00:00:00 2001 From: Chris Woerz Date: Wed, 8 Apr 2015 22:42:22 -0600 Subject: [PATCH 337/446] removed unused code --- src/kOS.Safe/Compilation/KS/Compiler.cs | 130 +----------------------- src/kOS.Safe/Execution/IStack.cs | 5 +- src/kOS/Function/Suffixed.cs | 1 - 3 files changed, 4 insertions(+), 132 deletions(-) diff --git a/src/kOS.Safe/Compilation/KS/Compiler.cs b/src/kOS.Safe/Compilation/KS/Compiler.cs index f33250c2e..252cb90cf 100644 --- a/src/kOS.Safe/Compilation/KS/Compiler.cs +++ b/src/kOS.Safe/Compilation/KS/Compiler.cs @@ -1167,11 +1167,9 @@ private void VisitOnOffTrailer(ParseNode node) /// the name to the left of the parentheses will be the name of the function call. If isDirect is false, then it will /// ignore the name to the left of the parentheses and presume the function name, delegate, or branch index was /// already placed atop the stack by other parts of this compiler. - /// true if this is a function call that will jump to user instructions in the code (LOCK and DECLARE FUNCTION), rather - /// than execute using C# code. /// In the case where it's a direct function, what's the name of it? In the case /// where it's not direct, this argument doesn't matter. - private void VisitActualFunction(ParseNode node, bool isDirect, bool isUserFunc, string directName = "") + private void VisitActualFunction(ParseNode node, bool isDirect, string directName = "") { NodeStartHousekeeping(node); @@ -1319,7 +1317,7 @@ private void VisitSuffix(ParseNode node) { // direct if it's just one term like foo(aaa) but indirect // if it's a list of suffixes like foo:bar(aaa): - VisitActualFunction(trailerTerm, isDirect, isUserFunc, firstIdentifier); + VisitActualFunction(trailerTerm, isDirect, firstIdentifier); } if (isArray) { @@ -1439,66 +1437,6 @@ private string GetIdentifierText(ParseNode node) return string.Empty; } - /// - /// The suffixterm parse node contains both actual function calls - /// (with parentheses) and just plain vanilla terms. This - /// determines if it's REALLY a function call or not. - /// - /// the node to test - /// true if it's really a function call. False otherwise. - private bool IsActualFunctionCall(ParseNode node) - { - // This can be called at the level of the parent of the function node, so get down to it first: - ParseNode child = node; - while (child != null && - (child.Token.Type != TokenType.function_trailer && - child.Token.Type != TokenType.identifier_led_expr)) - { - if (child.Nodes.Count > 1) - child = child.Nodes[1]; - else if (child.Nodes.Count == 1) - child = child.Nodes[0]; - else - child = null; - } - if (child == null) - return false; - - // If it has the optional function_trailer node tacked on to it, then it's really a function call with - // parentheses, not just using the function node as a dummy wrapper around a plain array node. - return child.Nodes.Count > 1; - } - - /// - /// The Array parse node contains both actual Array calls - /// (with index given) and just plain vanilla terms. This - /// determines if it's REALLY an array index call or not. - /// - /// The node to test - /// true if it's really an array index reference call. False otherwise. - private bool IsActualArrayIndexing(ParseNode node) - { - // This can be called at the level of the parent of the array node, so get down to it first: - ParseNode child = node; - while (child != null && - (child.Token.Type != TokenType.array_trailer && - child.Token.Type != TokenType.identifier_led_expr)) - { - if (child.Nodes.Count > 1) - child = child.Nodes[1]; - else if (child.Nodes.Count == 1) - child = child.Nodes[0]; - else - child = null; - } - if (child == null) - return false; - - // If it has the optional array_trailer node tacked on to it, then it's really an array index, not just using array as - // a dummy wrapper around a plain atom node - return child.Nodes.Count > 1; - } - private void VisitSuffixTerm(ParseNode node) { NodeStartHousekeeping(node); @@ -1507,7 +1445,7 @@ private void VisitSuffixTerm(ParseNode node) node.Nodes[1].Token.Type == TokenType.function_trailer) { // if a bracket follows an identifier then its a function call - VisitActualFunction(node.Nodes[1], true, false, GetIdentifierText(node)); + VisitActualFunction(node.Nodes[1], true, GetIdentifierText(node)); } else { @@ -1553,37 +1491,6 @@ private void VisitString(ParseNode node) AddOpcode(new OpcodePush(node.Token.Text.Trim('"'))); } - /// - /// Check for if the var_identifer node has a suffix term as its very next neighbor - /// to the right. i.e. in the following syntax:
    - /// AAA:BBB:CCC[0]:DDD:EEE[0]
    - /// This method should return true if called on the AAA, BBB, or DDD nodes, - /// but not when called on the CCC or EEE nodes. - ///
    - /// The node to test - /// - private bool VarIdentifierPreceedsSuffix(ParseNode node) - { - // If it's a var_identifier being worked on, drop down one level first - // to get into the actual meat of the syntax tree it represents: - if (node.Token.Type == TokenType.varidentifier) - return VarIdentifierPreceedsSuffix(node.Nodes.First()); - - if (node.Token.Type == TokenType.suffix_trailer || - node.Nodes.Count > 1 && node.Nodes[1].Token.Type == TokenType.suffix_trailer) - { - return true; - } - // Descend into child nodes to try them but don't parse too far over to the right, just the immediate neighbor only. - if (node.Nodes.Count > 1) - { - ParseNode child = node.Nodes[0]; - if (VarIdentifierPreceedsSuffix(child)) - return true; - } - return false; - } - /// /// Check for if the rightmost thing in the var_identifier node /// is a suffix term. i.e. return true if the var_identifier is:
    @@ -1626,37 +1533,6 @@ private bool VarIdentifierEndsWithSuffix(ParseNode node) prevChild.Token.Type == TokenType.suffixterm); } - /// - /// Check for if the var_identifer node has an array index as its very next neighbor - /// to the right. i.e. in the following syntax:
    - /// AAA:BBB:CCC[0]:DDD:EEE[0]
    - /// This method should return true if called on the CCC node or the EEE node, - /// but not when called on the AAA, BBB, or DDD nodes. - ///
    - /// The node to test - /// - private bool VarIdentifierPreceedsIndex(ParseNode node) - { - // If it's a var_identifier being worked on, drop down one level first - // to get into the actual meat of the syntax tree it represents: - if (node.Token.Type == TokenType.varidentifier) - return VarIdentifierPreceedsIndex(node.Nodes.First()); - - if (node.Token.Type == TokenType.array_trailer || - node.Nodes.Count > 1 && node.Nodes[1].Token.Type == TokenType.array_trailer) - { - return true; - } - // Descend into child nodes to try them but don't parse too far over to the right, just the immediate neighbor only. - if (node.Nodes.Count > 1) - { - ParseNode child = node.Nodes[0]; - if (VarIdentifierPreceedsIndex(child)) - return true; - } - return false; - } - /// /// Check for if the rightmost thing in the var_identifier node /// is an array indexer. i.e. return true if the var_identifier is:
    diff --git a/src/kOS.Safe/Execution/IStack.cs b/src/kOS.Safe/Execution/IStack.cs index 0b376104a..53e9b75b1 100644 --- a/src/kOS.Safe/Execution/IStack.cs +++ b/src/kOS.Safe/Execution/IStack.cs @@ -1,7 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Text; -using kOS.Safe.Execution; +using System.Collections.Generic; namespace kOS.Safe.Execution { diff --git a/src/kOS/Function/Suffixed.cs b/src/kOS/Function/Suffixed.cs index 2cc78fbda..3374736f5 100644 --- a/src/kOS/Function/Suffixed.cs +++ b/src/kOS/Function/Suffixed.cs @@ -5,7 +5,6 @@ using kOS.Safe.Encapsulation; using kOS.Safe.Exceptions; using kOS.Safe.Function; -using kOS.Safe.Exceptions; using kOS.Suffixed; using kOS.Utilities; using FinePrint; From 2ce403dffba81938f4e1e7e47c08e7c4b1e0ab31 Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Wed, 8 Apr 2015 23:49:30 -0500 Subject: [PATCH 338/446] Fixes #767 with a simple one-liner in kRISC.tpg The code in the compiler to handle the case where the expression was left off actually already existed, but the parser never allowed such a pattern to be considered valid. --- .../user_functions/testreturn1.ks | 68 +++++++++++++++++++ .../user_functions/testreturn2.ks | 23 +++++++ src/kOS.Safe/Compilation/KS/Parser.cs | 14 +++- src/kOS.Safe/Compilation/KS/kRISC.tpg | 2 +- 4 files changed, 105 insertions(+), 2 deletions(-) create mode 100644 kerboscript_tests/user_functions/testreturn1.ks create mode 100644 kerboscript_tests/user_functions/testreturn2.ks diff --git a/kerboscript_tests/user_functions/testreturn1.ks b/kerboscript_tests/user_functions/testreturn1.ks new file mode 100644 index 000000000..36c88cec1 --- /dev/null +++ b/kerboscript_tests/user_functions/testreturn1.ks @@ -0,0 +1,68 @@ +// Testing some deeply nested returns + +declare function outer1 { + print "function outer1: before for loop". + set foo to list(). + foo:add(1). + foo:add(2). + foo:add(3). + for thing in foo { + print "thing is " + thing. + if thing = 3 { + return true. + }. + }. + print "function outer1: after for loop". + return false. +}. + +declare function outer2 { + print "function outer2: before inner function". + + print "function outer2 is now calling function outer1 again.". + + if outer1() { + print "outer returned early.". + } else { + print "outer executed all the way to the bottom.". + } + + print "function outer2 is done with function outer1.". + + declare function inner { + set foo to list(). + foo:add(1). + foo:add(2). + foo:add(3). + for thing in foo { + print "inner: thing is " + thing. + if thing = 3 { + return true. + }. + }. + return false. + }. + + print "function outer2 is going to now call inner.". + if inner() { + print "inner returned early.". + } else { + print "inner executed all the way to the bottom.". + } + print "function outer2 is done calling inner.". + + print "function outer2: after inner function". +}. + +print "before calling function outer1.". +if outer1() { + print "outer returned early.". +} else { + print "outer executed all the way to the bottom.". +} +print "after calling function outer1.". + +print "before calling function outer2.". +outer2(). +print "done calling function outer2.". + diff --git a/kerboscript_tests/user_functions/testreturn2.ks b/kerboscript_tests/user_functions/testreturn2.ks new file mode 100644 index 000000000..b54218930 --- /dev/null +++ b/kerboscript_tests/user_functions/testreturn2.ks @@ -0,0 +1,23 @@ +// Testing returns without arguments. + +print "testing return statements without an argument". + +declare function outer1 { + print "function outer1: before for loop". + set foo to list(). + foo:add(1). + foo:add(2). + foo:add(3). + for thing in foo { + print "thing is " + thing. + if thing = 3 { + return. + }. + }. + print "function outer1: after for loop". + return. +}. + +print "before calling function outer1.". +outer1(). + diff --git a/src/kOS.Safe/Compilation/KS/Parser.cs b/src/kOS.Safe/Compilation/KS/Parser.cs index 2a03f5e5a..088843e5c 100644 --- a/src/kOS.Safe/Compilation/KS/Parser.cs +++ b/src/kOS.Safe/Compilation/KS/Parser.cs @@ -1400,7 +1400,19 @@ private void Parsereturn_stmt(ParseNode parent) } - Parseexpr(node); + tok = scanner.LookAhead(TokenType.PLUSMINUS, TokenType.NOT, TokenType.INTEGER, TokenType.DOUBLE, TokenType.TRUEFALSE, TokenType.IDENTIFIER, TokenType.FILEIDENT, TokenType.BRACKETOPEN, TokenType.STRING); + if (tok.Type == TokenType.PLUSMINUS + || tok.Type == TokenType.NOT + || tok.Type == TokenType.INTEGER + || tok.Type == TokenType.DOUBLE + || tok.Type == TokenType.TRUEFALSE + || tok.Type == TokenType.IDENTIFIER + || tok.Type == TokenType.FILEIDENT + || tok.Type == TokenType.BRACKETOPEN + || tok.Type == TokenType.STRING) + { + Parseexpr(node); + } tok = scanner.Scan(TokenType.EOI); diff --git a/src/kOS.Safe/Compilation/KS/kRISC.tpg b/src/kOS.Safe/Compilation/KS/kRISC.tpg index 4746169c6..3603289ef 100644 --- a/src/kOS.Safe/Compilation/KS/kRISC.tpg +++ b/src/kOS.Safe/Compilation/KS/kRISC.tpg @@ -153,7 +153,7 @@ log_stmt -> LOG expr TO expr EOI; break_stmt -> BREAK EOI; preserve_stmt -> PRESERVE EOI; declare_stmt -> DECLARE ( (PARAMETER IDENTIFIER (COMMA IDENTIFIER)* EOI) | (FUNCTION IDENTIFIER instruction_block EOI?) | (IDENTIFIER TO expr) EOI); -return_stmt -> RETURN expr EOI; +return_stmt -> RETURN expr? EOI; switch_stmt -> SWITCH TO expr EOI; copy_stmt -> COPY expr (FROM | TO) expr EOI; rename_stmt -> RENAME (VOLUME | FILE)? expr TO expr EOI; From ade0aa64e08b68a0a2dd1f766a6a53d781391aff Mon Sep 17 00:00:00 2001 From: Chris Woerz Date: Wed, 8 Apr 2015 22:57:33 -0600 Subject: [PATCH 339/446] more review --- src/kOS.Safe/Compilation/Opcode.cs | 4 ++-- src/kOS.Safe/Execution/IUserDelegate.cs | 4 +--- src/{kOS => kOS.Safe}/Execution/UserDelegate.cs | 8 +++----- src/kOS.Safe/kOS.Safe.csproj | 1 + src/kOS/Execution/CPU.cs | 3 +-- src/kOS/kOS.csproj | 1 - 6 files changed, 8 insertions(+), 13 deletions(-) rename src/{kOS => kOS.Safe}/Execution/UserDelegate.cs (92%) diff --git a/src/kOS.Safe/Compilation/Opcode.cs b/src/kOS.Safe/Compilation/Opcode.cs index 20fb02be7..6e7abc2ba 100644 --- a/src/kOS.Safe/Compilation/Opcode.cs +++ b/src/kOS.Safe/Compilation/Opcode.cs @@ -104,7 +104,7 @@ public enum ByteCode :byte /// WARNING! BE SURE TO EDIT CompiledObject.InitTypeData() if you add any new [MLField]'s that /// refer to argument types that haven't already been mentioned in CompiledObject.InitTypeData(). ///
    - [AttributeUsage(AttributeTargets.Property, Inherited=true)] + [AttributeUsage(AttributeTargets.Property)] public class MLField : Attribute { public int Ordering { get; private set; } @@ -294,7 +294,7 @@ public static void InitMachineCodeData() catch (MissingMethodException) { SafeHouse.Logger.Log( String.Format(forceDefaultConstructorMsg, opType.Name) ); - Utilities.Debug.AddNagMessage( Utilities.Debug.NagType.NAGFOREVER, "ERROR IN OPCODE DEFINITION " + opType.Name ); + Debug.AddNagMessage( Debug.NagType.NAGFOREVER, "ERROR IN OPCODE DEFINITION " + opType.Name ); return; } diff --git a/src/kOS.Safe/Execution/IUserDelegate.cs b/src/kOS.Safe/Execution/IUserDelegate.cs index c6de0b1ce..c713fbf3a 100644 --- a/src/kOS.Safe/Execution/IUserDelegate.cs +++ b/src/kOS.Safe/Execution/IUserDelegate.cs @@ -1,6 +1,4 @@ -using System; -using System.Collections.Generic; -using kOS.Safe.Execution; +using System.Collections.Generic; namespace kOS.Safe.Execution { diff --git a/src/kOS/Execution/UserDelegate.cs b/src/kOS.Safe/Execution/UserDelegate.cs similarity index 92% rename from src/kOS/Execution/UserDelegate.cs rename to src/kOS.Safe/Execution/UserDelegate.cs index 2dc913aee..96d8222d2 100644 --- a/src/kOS/Execution/UserDelegate.cs +++ b/src/kOS.Safe/Execution/UserDelegate.cs @@ -1,8 +1,6 @@ -using System; -using System.Collections.Generic; -using kOS.Safe.Execution; +using System.Collections.Generic; -namespace kOS.Execution +namespace kOS.Safe.Execution { /// /// A callback reference to a user-land function, implemented in kRISC code
    @@ -12,7 +10,7 @@ namespace kOS.Execution public class UserDelegate : IUserDelegate { public int EntryPoint {get; private set;} - private ICpu cpu; + private readonly ICpu cpu; public List Closure {get; private set;} /// diff --git a/src/kOS.Safe/kOS.Safe.csproj b/src/kOS.Safe/kOS.Safe.csproj index 8089ae762..f5185d72e 100644 --- a/src/kOS.Safe/kOS.Safe.csproj +++ b/src/kOS.Safe/kOS.Safe.csproj @@ -119,6 +119,7 @@ + diff --git a/src/kOS/Execution/CPU.cs b/src/kOS/Execution/CPU.cs index 3b779967e..b1ae9bf55 100644 --- a/src/kOS/Execution/CPU.cs +++ b/src/kOS/Execution/CPU.cs @@ -229,7 +229,7 @@ public List GetCurrentClosure() /// The delegate object you can store in a variable. public IUserDelegate MakeUserDelegate(int entryPoint) { - return (IUserDelegate) new UserDelegate(this, entryPoint, true); + return new UserDelegate(this, entryPoint, true); } // only two contexts exist now, one for the interpreter and one for the programs @@ -454,7 +454,6 @@ private VariableScope GetNestedDictionary(string identifier, List // If the scope id of this frame is my parent ID, then we found it and are done. if (scopeFrame.ScopeId == localDict.ParentScopeId) { - needsIncrement = false; break; } // In the case where the variable scope is the SAME lexical ID as myself, that diff --git a/src/kOS/kOS.csproj b/src/kOS/kOS.csproj index 6a3087d01..d7b6a3d97 100644 --- a/src/kOS/kOS.csproj +++ b/src/kOS/kOS.csproj @@ -73,7 +73,6 @@ - From 95bed5fb7cf7199e6f0a1cb839fe19a072de14a0 Mon Sep 17 00:00:00 2001 From: ZiwKerman Date: Thu, 9 Apr 2015 08:13:29 +0100 Subject: [PATCH 340/446] Minor Fixes --- src/kOS/Module/kOSProcessor.cs | 3 ++- src/kOS/Screen/KOSToolBarWindow.cs | 9 ++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/kOS/Module/kOSProcessor.cs b/src/kOS/Module/kOSProcessor.cs index 3a3e43f92..7a4dfbd47 100644 --- a/src/kOS/Module/kOSProcessor.cs +++ b/src/kOS/Module/kOSProcessor.cs @@ -231,6 +231,7 @@ private void InitUI() var temp = new Archive(); var files = temp.GetFileList(); var maxchoice = 0; + bootFiles.Add("None"); foreach (FileInfo file in files) { if (!file.Name.StartsWith("boot", StringComparison.InvariantCultureIgnoreCase)) continue; @@ -291,7 +292,7 @@ public void InitObjects() { HardDisk = new Harddisk(Mathf.Min(diskSpace, PROCESSOR_HARD_CAP)); // populate it with the boot file, but only if using a new disk and in PRELAUNCH situation: - if (vessel.situation == Vessel.Situations.PRELAUNCH) + if (vessel.situation == Vessel.Situations.PRELAUNCH && bootFile != "None") { var bootProgramFile = archive.GetByName(bootFile); if (bootProgramFile != null) diff --git a/src/kOS/Screen/KOSToolBarWindow.cs b/src/kOS/Screen/KOSToolBarWindow.cs index 6ef778151..b8905e514 100644 --- a/src/kOS/Screen/KOSToolBarWindow.cs +++ b/src/kOS/Screen/KOSToolBarWindow.cs @@ -104,8 +104,6 @@ public class KOSToolBarWindow : MonoBehaviour public KOSToolBarWindow() { - // This really needs fixing - the name ambiguity between UnityEngine's Debug and ours forces this long fully qualified name: - SafeHouse.Logger.SuperVerbose("KOSToolbarWindow: PROOF that constructor was called."); launcherButtonTexture = new Texture2D(0, 0, TextureFormat.DXT1, false); terminalClosedIconTexture = new Texture2D(0, 0, TextureFormat.DXT1, false); terminalOpenIconTexture = new Texture2D(0, 0, TextureFormat.DXT1, false); @@ -173,7 +171,12 @@ public void RunWhenReady() SafeHouse.Logger.SuperVerbose("KOSToolBarWindow: Instance number " + myInstanceNum + " will now actually make its hooks"); - if (!Config.Instance.UseBlizzyToolbarOnly) + var useBlizzyOnly = false; + + if (ToolbarManager.ToolbarAvailable) + useBlizzyOnly = Config.Instance.UseBlizzyToolbarOnly; + + if (!useBlizzyOnly) { ApplicationLauncher launcher = ApplicationLauncher.Instance; From ed20a52ef8c9ef14c90eff16e8ec60ae520d788f Mon Sep 17 00:00:00 2001 From: ZiwKerman Date: Thu, 9 Apr 2015 10:21:34 +0100 Subject: [PATCH 341/446] kOSToolBarWindow cleanup --- src/kOS/Screen/KOSToolBarWindow.cs | 170 +++++++++++------------------ src/packages/repositories.config | 7 +- 2 files changed, 67 insertions(+), 110 deletions(-) diff --git a/src/kOS/Screen/KOSToolBarWindow.cs b/src/kOS/Screen/KOSToolBarWindow.cs index b8905e514..1eb1fa8f4 100644 --- a/src/kOS/Screen/KOSToolBarWindow.cs +++ b/src/kOS/Screen/KOSToolBarWindow.cs @@ -38,11 +38,11 @@ public class KOSToolBarWindow : MonoBehaviour ApplicationLauncher.AppScenes.VAB | ApplicationLauncher.AppScenes.MAPVIEW; - private readonly Texture2D launcherButtonTexture; - private readonly Texture2D terminalClosedIconTexture; - private readonly Texture2D terminalOpenIconTexture; - private readonly Texture2D terminalClosedTelnetIconTexture; - private readonly Texture2D terminalOpenTelnetIconTexture; + private static Texture2D launcherButtonTexture; + private static Texture2D terminalClosedIconTexture; + private static Texture2D terminalOpenIconTexture; + private static Texture2D terminalClosedTelnetIconTexture; + private static Texture2D terminalOpenTelnetIconTexture; // ReSharper disable once RedundantDefaultFieldInitializer private bool clickedOn = false; @@ -55,17 +55,17 @@ public class KOSToolBarWindow : MonoBehaviour // ReSharper restore RedundantDefaultFieldInitializer private Vector2 scrollPos = new Vector2(200,350); - private Rect windowRect; + private static Rect windowRect; private const int UNIQUE_ID = 8675309; // Jenny, I've got your number. - private GUISkin panelSkin; - private GUIStyle headingLabelStyle; - private GUIStyle vesselNameStyle; - private GUIStyle partNameStyle; - private GUIStyle tooltipLabelStyle; - private GUIStyle boxDisabledStyle; - private GUIStyle boxOffStyle; - private GUIStyle boxOnStyle; - private string versionString; + private static GUISkin panelSkin; + private static GUIStyle headingLabelStyle; + private static GUIStyle vesselNameStyle; + private static GUIStyle partNameStyle; + private static GUIStyle tooltipLabelStyle; + private static GUIStyle boxDisabledStyle; + private static GUIStyle boxOffStyle; + private static GUIStyle boxOnStyle; + private static string versionString; ///Which CPU part description in the gui panel was the mouse hovering over during the current OnGUI call? private Part newHoverPart; @@ -80,103 +80,65 @@ public class KOSToolBarWindow : MonoBehaviour /// Our highlight color for kOS panel's part highlighting. private readonly Color ourPartHighlightColor = new Color(1.0f, 0.5f, 1.0f); // Bright purple. - // Some of these are for just debug messages, and others are - // necessary for tracking things to make it not spawn too many - // buttons or spawn them at the wrong times. For now I want to - // keep the debug logging in the code so users have something they - // can show in bug reports until I'm more confident this is working - // perfectly: - - // ReSharper disable RedundantDefaultFieldInitializer private bool alreadyAwake = false; - private static int countInstances = 0; - private int myInstanceNum = 0; - private bool thisInstanceHasHooks = false; - private static bool someInstanceHasHooks = false; private bool isOpen = false; - private bool onGUICalledThisInstance = false; - private bool onGUIWasOpenThisInstance = false; - // ReSharper enable RedundantDefaultFieldInitializer - + private DateTime prevConfigTimeStamp = DateTime.MinValue; private List backingConfigInts; public KOSToolBarWindow() { - launcherButtonTexture = new Texture2D(0, 0, TextureFormat.DXT1, false); - terminalClosedIconTexture = new Texture2D(0, 0, TextureFormat.DXT1, false); - terminalOpenIconTexture = new Texture2D(0, 0, TextureFormat.DXT1, false); - terminalClosedTelnetIconTexture = new Texture2D(0, 0, TextureFormat.DXT1, false); - terminalOpenTelnetIconTexture = new Texture2D(0, 0, TextureFormat.DXT1, false); + } /// /// Unity hates it when a MonoBehaviour has a constructor, /// so all the construction work is here instead: /// - public void FirstTimeSetup() + public static void FirstTimeSetup() { - ++countInstances; - myInstanceNum = countInstances; - SafeHouse.Logger.SuperVerbose("KOSToolBarWindow: Now making instance number "+myInstanceNum+" of KOSToolBarWindow"); - - const string LAUNCHER_BUTTON_PNG = "GameData/kOS/GFX/launcher-button.png"; - const string TERMINAL_OPEN_ICON_PNG = "GameData/kOS/GFX/terminal-icon-open.png"; - const string TERMINAL_CLOSED_ICON_PNG = "GameData/kOS/GFX/terminal-icon-closed.png"; - const string TERMINAL_OPEN_TELNET_ICON_PNG = "GameData/kOS/GFX/terminal-icon-open-telnet.png"; - const string TERMINAL_CLOSED_TELNET_ICON_PNG = "GameData/kOS/GFX/terminal-icon-closed-telnet.png"; - - // ReSharper disable SuggestUseVarKeywordEvident - WWW launcherButtonImage = new WWW("file://" + KSPUtil.ApplicationRootPath.Replace("\\", "/") + LAUNCHER_BUTTON_PNG); - WWW terminalOpenIconImage = new WWW("file://" + KSPUtil.ApplicationRootPath.Replace("\\", "/") + TERMINAL_OPEN_ICON_PNG); - WWW terminalClosedIconImage = new WWW("file://" + KSPUtil.ApplicationRootPath.Replace("\\", "/") + TERMINAL_CLOSED_ICON_PNG); - WWW terminalOpenTelnetIconImage = new WWW("file://" + KSPUtil.ApplicationRootPath.Replace("\\", "/") + TERMINAL_OPEN_TELNET_ICON_PNG); - WWW terminalClosedTelnetIconImage = new WWW("file://" + KSPUtil.ApplicationRootPath.Replace("\\", "/") + TERMINAL_CLOSED_TELNET_ICON_PNG); - // ReSharper enable SuggestUseVarKeywordEvident - launcherButtonImage.LoadImageIntoTexture(launcherButtonTexture); - terminalOpenIconImage.LoadImageIntoTexture(terminalOpenIconTexture); - terminalClosedIconImage.LoadImageIntoTexture(terminalClosedIconTexture); - terminalOpenTelnetIconImage.LoadImageIntoTexture(terminalOpenTelnetIconTexture); - terminalClosedTelnetIconImage.LoadImageIntoTexture(terminalClosedTelnetIconTexture); - - windowRect = new Rect(0,0,width,height); // this origin point will move when opened/closed. + launcherButtonTexture = GameDatabase.Instance.GetTexture ("kOS/GFX/launcher-button",false); + terminalOpenIconTexture = GameDatabase.Instance.GetTexture ("kOS/GFX/terminal-icon-open", false); + terminalClosedIconTexture = GameDatabase.Instance.GetTexture ("kOS/GFX/terminal-icon-closed", false); + terminalOpenTelnetIconTexture = GameDatabase.Instance.GetTexture ("kOS/GFX/terminal-icon-open-telnet", false); + terminalClosedTelnetIconTexture = GameDatabase.Instance.GetTexture ("kOS/GFX/terminal-icon-closed-telnet", false); + + windowRect = new Rect(0,0,1f,1f); // this origin point will move when opened/closed. panelSkin = BuildPanelSkin(); versionString = Utils.GetAssemblyFileVersion(); + //UnityEngine.Debug.Log("[kOSToolBarWindow] FirstTimeSetup Finished, v=" + versionString); + } + + public void Awake () + { - GameEvents.onGUIApplicationLauncherReady.Add(RunWhenReady); - GameEvents.onGUIApplicationLauncherDestroyed.Add(GoAway); } public void Start() { - SafeHouse.Logger.SuperVerbose("KOSToolbarWindow: PROOF that Start() was called."); // Prevent multiple calls of this: if (alreadyAwake) return; alreadyAwake = true; FirstTimeSetup(); + + GameEvents.onGUIApplicationLauncherReady.Add(RunWhenReady); + GameEvents.onGUIApplicationLauncherDestroyed.Add(GoAway); + + SafeHouse.Logger.SuperVerbose("[kOSToolBarWindow] Start succesful"); } public void RunWhenReady() { - SafeHouse.Logger.SuperVerbose("KOSToolBarWindow: Instance number " + myInstanceNum + " is trying to ready the hooks"); - // KSP claims the hook ApplicationLauncherReady.Add will not run until - // the application is ready, even though this is emphatically false. It actually - // fires the event a few times before the one that "sticks" and works: if (!ApplicationLauncher.Ready) return; - if (someInstanceHasHooks) return; - thisInstanceHasHooks = true; - someInstanceHasHooks = true; - - SafeHouse.Logger.SuperVerbose("KOSToolBarWindow: Instance number " + myInstanceNum + " will now actually make its hooks"); var useBlizzyOnly = false; if (ToolbarManager.ToolbarAvailable) useBlizzyOnly = Config.Instance.UseBlizzyToolbarOnly; - if (!useBlizzyOnly) + if (!useBlizzyOnly && launcherButton == null) { ApplicationLauncher launcher = ApplicationLauncher.Instance; @@ -195,10 +157,10 @@ public void RunWhenReady() launcher.EnableMutuallyExclusive(launcherButton); } - //Will show button on Blizzy's toolbar anyway AddBlizzyButton(); SetupBackingConfigInts(); + SafeHouse.Logger.SuperVerbose("[kOSToolBarWindow] Launcher Icon init successful"); } public void AddBlizzyButton() @@ -235,31 +197,39 @@ public void SetupBackingConfigInts() public void GoAway() { - SafeHouse.Logger.SuperVerbose("KOSToolBarWindow: PROOF: Instance " + myInstanceNum + " is in GoAway()."); - if (thisInstanceHasHooks) + if (isOpen) Close(); + clickedOn = false; + + try { - SafeHouse.Logger.SuperVerbose("KOSToolBarWindow: PROOF: Instance " + myInstanceNum + " has hooks and is entering the guts of GoAway()."); - if (isOpen) Close(); - clickedOn = false; - thisInstanceHasHooks = false; - someInstanceHasHooks = false; // if this is the instance that had hooks and it's going away, let another instance have a go. - - ApplicationLauncher launcher = ApplicationLauncher.Instance; - - launcher.DisableMutuallyExclusive(launcherButton); - launcher.RemoveOnRepositionCallback(CallbackOnShow); - launcher.RemoveOnHideCallback(CallbackOnHide); - launcher.RemoveOnShowCallback(CallbackOnShow); - - launcher.RemoveModApplication(launcherButton); + GameEvents.onGUIApplicationLauncherReady.Remove(RunWhenReady); + GameEvents.onGUIApplicationLauncherDestroyed.Remove(GoAway); + + if (launcherButton != null && ApplicationLauncher.Instance != null) + { + ApplicationLauncher launcher = ApplicationLauncher.Instance; + + launcher.DisableMutuallyExclusive(launcherButton); + launcher.RemoveOnRepositionCallback(CallbackOnShow); + launcher.RemoveOnHideCallback(CallbackOnHide); + launcher.RemoveOnShowCallback(CallbackOnShow); + launcher.RemoveModApplication(launcherButton); + launcherButton = null; + } + } + catch (Exception e) + { + SafeHouse.Logger.SuperVerbose("[kOSToolBarWindow] Failed unregistering AppLauncher handlers," + e.Message); } + if(BlizzyButton != null) BlizzyButton.Destroy(); } - + public void OnDestroy() { GoAway(); + SafeHouse.Logger.SuperVerbose("[kOSToolBarWindow] OnDestroy successful"); } public void CallbackOnClickBlizzy() @@ -273,7 +243,6 @@ public void CallbackOnClickBlizzy() /// Callback for when the button is toggled on public void CallbackOnTrue() { - SafeHouse.Logger.SuperVerbose("KOSToolBarWindow: PROOF: CallbackOnTrue()"); clickedOn = true; Open(); } @@ -281,7 +250,6 @@ public void CallbackOnTrue() /// Callback for when the button is toggled off public void CallbackOnFalse() { - SafeHouse.Logger.SuperVerbose("KOSToolBarWindow: PROOF: CallbackOnFalse()"); clickedOn = false; Close(); } @@ -371,20 +339,8 @@ public void OnGUI() horizontalSectionCount = 0; verticalSectionCount = 0; - if (!onGUICalledThisInstance) // I want proof it was called, but without spamming the log: - { - SafeHouse.Logger.SuperVerbose("KOSToolBarWindow: PROOF: OnGUI() was called at least once on instance number " + myInstanceNum); - onGUICalledThisInstance = true; - } - if (!isOpen ) return; - if (!onGUIWasOpenThisInstance) // I want proof it was called, but without spamming the log: - { - SafeHouse.Logger.SuperVerbose("KOSToolBarWindow: PROOF: OnGUI() was called while the window was supposed to be open at least once on instance number " + myInstanceNum); - onGUIWasOpenThisInstance = true; - } - GUI.skin = HighLogic.Skin; windowRect = GUILayout.Window(UNIQUE_ID, windowRect, DrawWindow, "kOS " + versionString); @@ -721,7 +677,7 @@ private void CountEndHorizontal(string debugHelp="") } - private GUISkin BuildPanelSkin() + private static GUISkin BuildPanelSkin() { GUISkin theSkin = Utils.GetSkinCopy(HighLogic.Skin); // theSkin won't actually be used directly anymore because GetSkinCopy is missing a few key diff --git a/src/packages/repositories.config b/src/packages/repositories.config index 94596777a..4644e02bc 100644 --- a/src/packages/repositories.config +++ b/src/packages/repositories.config @@ -1,4 +1,5 @@ - - - + + + + \ No newline at end of file From 51d614068d08f79b5af28eed6346b862254330ae Mon Sep 17 00:00:00 2001 From: SirDiazo Date: Thu, 9 Apr 2015 10:03:56 -0600 Subject: [PATCH 342/446] Update AGX.rst Documentation tweaks --- doc/source/addons/AGX.rst | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/doc/source/addons/AGX.rst b/doc/source/addons/AGX.rst index cf1cbc0d1..167764492 100644 --- a/doc/source/addons/AGX.rst +++ b/doc/source/addons/AGX.rst @@ -13,7 +13,10 @@ Adds action groups AG11 through AG250 to kOS that are interacted with the same w Anywhere you use ``AG1``, you can use ``AG15`` in exactly the same way. -Caution: Sometimes, AGX will return an unexpected value for a group's state (On/Off), see below for the explination. (Action State Monitoring) +**Behavior changes to be aware of:** +All action groups (from 1 through 250) now have their on/off state monitored and is based on the state of the actions in the group. See Action State Montioring below for how animations affect the on/off state of an action group. + +For Action Groups 11 through 250 there must be an action assigned in order to toggle their state on/off. The Script Trigger object on the kOS computer is provided for this purpse. Action Groups 1 through 10 can still be triggered even in empty as per stock behavior. **Basic Quick Start:** From 96b99dfb11320ff5d4176e364fcd0d98dea7d4aa Mon Sep 17 00:00:00 2001 From: SirDiazo Date: Thu, 9 Apr 2015 10:07:58 -0600 Subject: [PATCH 343/446] Update AGX.rst --- doc/source/addons/AGX.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/source/addons/AGX.rst b/doc/source/addons/AGX.rst index 167764492..8e0507641 100644 --- a/doc/source/addons/AGX.rst +++ b/doc/source/addons/AGX.rst @@ -11,12 +11,12 @@ Includes a Script Trigger action that can be used to control a running program a **Usage:** Adds action groups AG11 through AG250 to kOS that are interacted with the same way as the AG1 through AG10 bindings in base kOS are. -Anywhere you use ``AG1``, you can use ``AG15`` in exactly the same way. +Anywhere you use ``AG1``, you can use ``AG15`` in the same way. **Behavior changes to be aware of:** -All action groups (from 1 through 250) now have their on/off state monitored and is based on the state of the actions in the group. See Action State Montioring below for how animations affect the on/off state of an action group. +All action groups (from 1 through 250) now have their on/off state monitored and is based on the state of the actions in the group. See Action State Montioring below for how animations affect the on/off state of an action group. Note this means that an action assigned to one action group can change the on/off state of a second action group when the same action is present in both action groups. -For Action Groups 11 through 250 there must be an action assigned in order to toggle their state on/off. The Script Trigger object on the kOS computer is provided for this purpse. Action Groups 1 through 10 can still be triggered even in empty as per stock behavior. +For Action Groups 11 through 250 there must be an action assigned to the group in order to toggle their state on/off. The Script Trigger action on the kOS computer is provided for this purpse. Action Groups 1 through 10 can still be triggered even if empty as per stock behavior. **Basic Quick Start:** From f16a5a631d1432e64f03f394a0b46cce4e2f0f0d Mon Sep 17 00:00:00 2001 From: SirDiazo Date: Thu, 9 Apr 2015 10:16:37 -0600 Subject: [PATCH 344/446] Update AGX.rst --- doc/source/addons/AGX.rst | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/doc/source/addons/AGX.rst b/doc/source/addons/AGX.rst index 8e0507641..8494c94d1 100644 --- a/doc/source/addons/AGX.rst +++ b/doc/source/addons/AGX.rst @@ -28,15 +28,15 @@ For Action Groups 11 through 250 there must be an action assigned to the group i Note that this mod only adds action grousp 11 through 250, it does not change how action groups 1 through 10 behave in any way. -**Known limitations:** +**Known limitations (Action groups 11 through 250 only):** - For an action group to be useable, it must have an action assigned to it. When installed, AGX adds a "Script Trigger" action to the kOS computer part that serves this purpose if you want an "empty" action group to trigger kOS scripts with. -- Be aware that if you query an empty action group, it will always return a state of False and trying to turn an emtpy action group On will do nothing and silently fail without any sort of error message. (Groups AG11 through AG250 only. Groups AG1 through AG10 can be empty and will turn On and Off when commanded to.) -- At this point, AG11 through AG250 do not support RemoteTech. Triggering those action groups will bypass the signal delay and execute those actions immediately. (On the immediate fix list.) +- Be aware that if you query an empty action group, it will always return a state of False and trying to turn an emtpy action group On will do nothing and silently fail without any sort of error message. +- At this point, AG11 through AG250 do not officially support RemoteTech through kOS. (Support will happen once all three mods involved have updated to KSP version 1.0 and made any internal changes necessary.) All three mods can be installed at the same time without issue, just be aware there may be unexpected behavior when using action groups 11 through 250 from a kOS script in terms of RemoteTech signal delay and connection state. **Action state monitoring** -Note that the state of action groups is tracked on a per-action basis, rather then on a per-group basis. This results in the group state being handled differently. (AG 11 through AG250 only.) +Note that the state of action groups is tracked on a per-action basis, rather then on a per-group basis. This results in the group state being handled differently. - The Script Trigger action found on the kOS computer module is not subject to the below considerations and is the recommended action to use when interacting with a running kOS script. - The state of actions are monitored on the part and updated automatically. A closed solar panel will return a state of false for all it's actions. (Extend Panels, Retract Panels, Toggle Panels) When you extend the solar panel with either the Extend Panels or Toggle Panels action, all three actions will change to a state of True. Retract the panels and the state of all three actions will become False. Note that this state will update in any action group that contains that action, not just the action group that was activated. @@ -57,7 +57,8 @@ Print to the terminal anytime you activate action group 15. Use this to change v } -- Player activates AG15, AG15's state goes from false to true and the actions are triggered. ``AG15 False -> True`` and prints to the terminal. +**Animation Delay:** +- Using the above code on a stock solar panel's Toggle Panels action, the player activates AG15, AG15's state goes from false to true and the actions are triggered. ``AG15 False -> True`` and prints to the terminal. - On it's next update pass (100ms to 250ms later), AGX checks AG15's state and sees the solar panel is still deploying which means that AG15's state is false and so sets it that way. ``AG15 True -> False`` and prints to the terminal. - A few seconds later, the solar panel finishes it's deployment animation. On it's next update pass AGX checks AG15's state and sees the solar panel is now deployed which means that AG15's state is now true and so sets it that way. ``AG15 False -> True`` and prints to the terminal a third time. @@ -72,7 +73,7 @@ As a workaround, you need to add a cooldown:: preserve. } -Note the 10 in the second line, that is your cooldown time in seconds. Set this to a number of seconds that is longer then your animation time and the above code will limit AG15 so it can only activate after 10 seconds have passed since the previous activation and not activate multiple times on the same activation. +Note the 10 in the second line, that is your cooldown time in seconds. Set this to a number of seconds that is longer then your animation time and the above code will limit whatever is inside the IF statement so it can only activate after 10 seconds have passed since the previous activation and will not try to activate a second time while the solar panel animation is still playing. From 0b9240820210a9a457bd6c861e9951566f3a7af6 Mon Sep 17 00:00:00 2001 From: SirDiazo Date: Thu, 9 Apr 2015 10:17:04 -0600 Subject: [PATCH 345/446] Update AGX.rst --- doc/source/addons/AGX.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/addons/AGX.rst b/doc/source/addons/AGX.rst index 8494c94d1..33b9c4edb 100644 --- a/doc/source/addons/AGX.rst +++ b/doc/source/addons/AGX.rst @@ -14,7 +14,7 @@ Adds action groups AG11 through AG250 to kOS that are interacted with the same w Anywhere you use ``AG1``, you can use ``AG15`` in the same way. **Behavior changes to be aware of:** -All action groups (from 1 through 250) now have their on/off state monitored and is based on the state of the actions in the group. See Action State Montioring below for how animations affect the on/off state of an action group. Note this means that an action assigned to one action group can change the on/off state of a second action group when the same action is present in both action groups. +All action groups (from 1 through 250) now have their on/off state monitored and it is based on the state of the actions in the group. See Action State Montioring below for how animations affect the on/off state of an action group. Note this means that an action assigned to one action group can change the on/off state of a second action group when the same action is present in both action groups. For Action Groups 11 through 250 there must be an action assigned to the group in order to toggle their state on/off. The Script Trigger action on the kOS computer is provided for this purpse. Action Groups 1 through 10 can still be triggered even if empty as per stock behavior. From b08e6c2eab52ab1b6da6a2b3949520a1a5d46b98 Mon Sep 17 00:00:00 2001 From: SirDiazo Date: Thu, 9 Apr 2015 10:17:51 -0600 Subject: [PATCH 346/446] Update AGX.rst --- doc/source/addons/AGX.rst | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/doc/source/addons/AGX.rst b/doc/source/addons/AGX.rst index 33b9c4edb..842a27e8c 100644 --- a/doc/source/addons/AGX.rst +++ b/doc/source/addons/AGX.rst @@ -14,7 +14,7 @@ Adds action groups AG11 through AG250 to kOS that are interacted with the same w Anywhere you use ``AG1``, you can use ``AG15`` in the same way. **Behavior changes to be aware of:** -All action groups (from 1 through 250) now have their on/off state monitored and it is based on the state of the actions in the group. See Action State Montioring below for how animations affect the on/off state of an action group. Note this means that an action assigned to one action group can change the on/off state of a second action group when the same action is present in both action groups. +All action groups (from 1 through 250) now have their on/off state monitored and it is based on the state of the actions in the group. See Action State Montioring below for how animations affect this. Note this means that an action assigned to one action group can change the on/off state of a second action group when the same action is present in both action groups. For Action Groups 11 through 250 there must be an action assigned to the group in order to toggle their state on/off. The Script Trigger action on the kOS computer is provided for this purpse. Action Groups 1 through 10 can still be triggered even if empty as per stock behavior. @@ -24,8 +24,6 @@ For Action Groups 11 through 250 there must be an action assigned to the group i .. figure:: /_images/addons/AGExtQuickStart2.jpg -**Overview Walkthrough:** (Video, imagur album, animated gif, something) - Note that this mod only adds action grousp 11 through 250, it does not change how action groups 1 through 10 behave in any way. **Known limitations (Action groups 11 through 250 only):** From ddadfce202b779d0342cbdaf2125aac02b589777 Mon Sep 17 00:00:00 2001 From: SirDiazo Date: Thu, 9 Apr 2015 10:22:03 -0600 Subject: [PATCH 347/446] Update AGX.rst --- doc/source/addons/AGX.rst | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/doc/source/addons/AGX.rst b/doc/source/addons/AGX.rst index 842a27e8c..dc4d7100a 100644 --- a/doc/source/addons/AGX.rst +++ b/doc/source/addons/AGX.rst @@ -14,7 +14,7 @@ Adds action groups AG11 through AG250 to kOS that are interacted with the same w Anywhere you use ``AG1``, you can use ``AG15`` in the same way. **Behavior changes to be aware of:** -All action groups (from 1 through 250) now have their on/off state monitored and it is based on the state of the actions in the group. See Action State Montioring below for how animations affect this. Note this means that an action assigned to one action group can change the on/off state of a second action group when the same action is present in both action groups. +All action groups (from 1 through 250) now have their on/off state monitored and it is based on the state of the actions in the group. See Action State Montioring and Animation Delay below for how animations affect this. Note this means that an action assigned to one action group can change the on/off state of a second action group when the same action is present in both action groups. For Action Groups 11 through 250 there must be an action assigned to the group in order to toggle their state on/off. The Script Trigger action on the kOS computer is provided for this purpse. Action Groups 1 through 10 can still be triggered even if empty as per stock behavior. @@ -49,13 +49,15 @@ Print to the terminal anytime you activate action group 15. Use this to change v AG15 on. // Activate action group 15. print AG15. // Print action group 15's state to the terminal. (True/False) - on AG15 { + + on AG15 { //Prints "Action group 15 clicked!" to the console when AG15 is toggled, either via "AG15 on." or in-game with an assigned key. print "Action group 15 clicked!". preserve. } **Animation Delay:** + - Using the above code on a stock solar panel's Toggle Panels action, the player activates AG15, AG15's state goes from false to true and the actions are triggered. ``AG15 False -> True`` and prints to the terminal. - On it's next update pass (100ms to 250ms later), AGX checks AG15's state and sees the solar panel is still deploying which means that AG15's state is false and so sets it that way. ``AG15 True -> False`` and prints to the terminal. - A few seconds later, the solar panel finishes it's deployment animation. On it's next update pass AGX checks AG15's state and sees the solar panel is now deployed which means that AG15's state is now true and so sets it that way. ``AG15 False -> True`` and prints to the terminal a third time. From fe9bca04fd12b1b0d07d0df341f35497b5a829aa Mon Sep 17 00:00:00 2001 From: SirDiazo Date: Thu, 9 Apr 2015 11:36:49 -0600 Subject: [PATCH 348/446] Update AGX.rst --- doc/source/addons/AGX.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/addons/AGX.rst b/doc/source/addons/AGX.rst index dc4d7100a..0112d640a 100644 --- a/doc/source/addons/AGX.rst +++ b/doc/source/addons/AGX.rst @@ -16,7 +16,7 @@ Anywhere you use ``AG1``, you can use ``AG15`` in the same way. **Behavior changes to be aware of:** All action groups (from 1 through 250) now have their on/off state monitored and it is based on the state of the actions in the group. See Action State Montioring and Animation Delay below for how animations affect this. Note this means that an action assigned to one action group can change the on/off state of a second action group when the same action is present in both action groups. -For Action Groups 11 through 250 there must be an action assigned to the group in order to toggle their state on/off. The Script Trigger action on the kOS computer is provided for this purpse. Action Groups 1 through 10 can still be triggered even if empty as per stock behavior. +For Action Groups 11 through 250 there must be an action assigned to the group in order to toggle their state on/off. The Script Trigger action on the kOS computer is provided for this purpse. Assigning the Script Trigger action this way will also allow you to name the action group on AGX's GUI so you can remember what it does and allow you trigger that action group via mouse-click. Action Groups 1 through 10 can still be triggered even if empty as per stock behavior. **Basic Quick Start:** From 030f58f155b962daf131e4d1d423e664ca8e2640 Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Thu, 9 Apr 2015 14:25:55 -0500 Subject: [PATCH 349/446] Resolves #732 and Resolves #746. Same problem. It turns out that issue #732 and issue #746 were in fact the same identical problem. Both the RUN command and the WHEN/ON trigger commands need to be seen during the first pass through the compiler when it does PreProcessStatements, and function bodies were getting skipped over in this pass. The fix was in two places: 1 - The entire branch of the parse tree from the Define Function node, downward wasn't being recursed down into. --- .../user_functions/functest10.ks | 12 ++++++ .../user_functions/functest10_inner.ks | 8 ++++ .../user_functions/functest11.ks | 12 ++++++ .../user_functions/functest12.ks | 39 +++++++++++++++++++ src/kOS.Safe/Compilation/KS/Compiler.cs | 5 ++- 5 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 kerboscript_tests/user_functions/functest10.ks create mode 100644 kerboscript_tests/user_functions/functest10_inner.ks create mode 100644 kerboscript_tests/user_functions/functest11.ks create mode 100644 kerboscript_tests/user_functions/functest12.ks diff --git a/kerboscript_tests/user_functions/functest10.ks b/kerboscript_tests/user_functions/functest10.ks new file mode 100644 index 000000000..abcd4b459 --- /dev/null +++ b/kerboscript_tests/user_functions/functest10.ks @@ -0,0 +1,12 @@ +// Testing a script calling a script with arguments. + +declare parameter arg1,arg2,arg3. + +print "Outer script (functest10) called with arguments:". +print " arg1=" + arg1. +print " arg2=" + arg2. +print " arg3=" + arg3. + +print "Now functest10 is going to call functest10_inner,". +print "Giving it the same args in the same order:". +run functest10_inner(arg1,arg2,arg3). diff --git a/kerboscript_tests/user_functions/functest10_inner.ks b/kerboscript_tests/user_functions/functest10_inner.ks new file mode 100644 index 000000000..6c5e2522a --- /dev/null +++ b/kerboscript_tests/user_functions/functest10_inner.ks @@ -0,0 +1,8 @@ +declare parameter inner1, inner2, inner3. + +print "This is functest10_inner talking.". +print "I think my args are:". + +print " arg1="+arg1. +print " arg2="+arg2. +print " arg3="+arg3. diff --git a/kerboscript_tests/user_functions/functest11.ks b/kerboscript_tests/user_functions/functest11.ks new file mode 100644 index 000000000..c3be8b245 --- /dev/null +++ b/kerboscript_tests/user_functions/functest11.ks @@ -0,0 +1,12 @@ +// Testing the case of a function that calls a RUN +// command from inside of itself: + +declare function foo { + print "Inside function: about to run functest10". + run functest10(10,20,30). + print "Inside function: done running functest10". +}. + +print "Outside function: about to call function". +foo(). +print "Outside function: done calling function". diff --git a/kerboscript_tests/user_functions/functest12.ks b/kerboscript_tests/user_functions/functest12.ks new file mode 100644 index 000000000..f37ce41b4 --- /dev/null +++ b/kerboscript_tests/user_functions/functest12.ks @@ -0,0 +1,39 @@ +// Testing the case of a function that contains a WHEN trigger +// inside of itself: + +set x to 0. + +// Try this twice to ensure it gets re-enabled in the second +// function call too. +reinit_triggers(). +print "pass 1: triggers initialized... ". +wait 1. +set x to 1. +wait 1. +set x to 2. + +wait 1. + +reinit_triggers(). +print "pass 2: triggers initialized... ". +wait 1. +set x to 1. +wait 1. +set x to 2. +wait 1. + +print "done with test". + +declare function reinit_triggers { + set x to 0. + + when x = 1 then { + print "When x = 1 trigger has been invoked.". + }. + + when x = 2 then { + print "When x = 2 trigger has been invoked.". + }. +}. + + diff --git a/src/kOS.Safe/Compilation/KS/Compiler.cs b/src/kOS.Safe/Compilation/KS/Compiler.cs index b02213a7d..a07e628bf 100644 --- a/src/kOS.Safe/Compilation/KS/Compiler.cs +++ b/src/kOS.Safe/Compilation/KS/Compiler.cs @@ -173,8 +173,8 @@ private void PreProcess(ParseTree tree) { ParseNode rootNode = tree.Nodes[0]; TraverseScopeBranch(rootNode); - PreProcessUserFunctions(rootNode); PreProcessStatements(rootNode); + PreProcessUserFunctions(rootNode); } private void PreProcessUserFunctions(ParseNode node) @@ -246,6 +246,7 @@ private void PreProcessStatements(ParseNode node) PreProcessWhenStatement(node); break; case TokenType.declare_stmt: + PreProcessChildNodes(node); PreProcessProgramParameters(node); break; case TokenType.run_stmt: @@ -529,6 +530,8 @@ private void PreProcessProgramParameters(ParseNode node) programParameters.Add(node.Nodes[index]); } } + // If it's any other sort of Declare statement, do nothing and instead + // allow the PreProcessChildNodes handle all the work. } private void PreProcessRunStatement(ParseNode node) From 5b0763f32a914b3652c23c4c83b26f177cc4e887 Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Thu, 9 Apr 2015 14:54:32 -0500 Subject: [PATCH 350/446] Resolves #732 and Resolves #746. function bodies preparse now. Function bodies previously didn't get preparsed for triggers properly. Now it recurses down into themto ensure it finds the triggers inside. This fixes both the problems because RUN and WHEN are both in need of a preprocess pass to work properly, and it was the lack of that preprocess pass that was causing the problem in both these cases. --- src/kOS.Safe/Compilation/KS/Compiler.cs | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/kOS.Safe/Compilation/KS/Compiler.cs b/src/kOS.Safe/Compilation/KS/Compiler.cs index a07e628bf..88d535750 100644 --- a/src/kOS.Safe/Compilation/KS/Compiler.cs +++ b/src/kOS.Safe/Compilation/KS/Compiler.cs @@ -173,14 +173,9 @@ private void PreProcess(ParseTree tree) { ParseNode rootNode = tree.Nodes[0]; TraverseScopeBranch(rootNode); + IterateUserFunctions(rootNode, IdentifyUserFunctions); PreProcessStatements(rootNode); - PreProcessUserFunctions(rootNode); - } - - private void PreProcessUserFunctions(ParseNode node) - { - IterateUserFunctions(node, IdentifyUserFunctions); - IterateUserFunctions(node, PreProcessUserFunctionStatement); + IterateUserFunctions(rootNode, PreProcessUserFunctionStatement); } private void IterateUserFunctions(ParseNode node, Action action) From 450752f5fc37308e6edec4650849e1710ddd6ac1 Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Thu, 9 Apr 2015 14:57:28 -0500 Subject: [PATCH 351/446] Forgot to git -add one of the example scripts I used. --- .../user_functions/functest13.ks | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 kerboscript_tests/user_functions/functest13.ks diff --git a/kerboscript_tests/user_functions/functest13.ks b/kerboscript_tests/user_functions/functest13.ks new file mode 100644 index 000000000..ef89832b7 --- /dev/null +++ b/kerboscript_tests/user_functions/functest13.ks @@ -0,0 +1,24 @@ +// Testing the nesting of function calls and locks inside triggers. + +declare function do_print { + declare parameter str. + print("doprint: printing: " + str). +}. + +when x = 1 then { + do_print("trigger body, when x = 1, y = " + y). +}. + +when x = 2 then { + do_print("trigger body, when x = 2, y = " + y). +}. + +set x to 0. +// Also need to ensure that locks compile correctly here: +lock y to -x. + +wait 1. +set x to 1. +wait 1. +set x to 2. +wait 1. From 4ce204d691068227c699402c9de9f2870577592f Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Thu, 9 Apr 2015 15:16:18 -0500 Subject: [PATCH 352/446] I suspect that this Resolves #575. My reason for saying "suspect" is that the conditions to test to actually see if it's right are so picky and fiddly that I just don't have time to craft a cnnvoluted example to try it right now. If I'm right, then Vessel:ISDEAD will return TRUE in the rare case where a vessel handle you have refers to a vessel that *just* died in the last update a moment ago. (i.e. crashed into the ground after you obtained the handle to it). --- src/kOS/Suffixed/VesselTarget.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/kOS/Suffixed/VesselTarget.cs b/src/kOS/Suffixed/VesselTarget.cs index fe91dc6e2..c15a3cd8d 100644 --- a/src/kOS/Suffixed/VesselTarget.cs +++ b/src/kOS/Suffixed/VesselTarget.cs @@ -421,6 +421,7 @@ private void InitializeSuffixes() AddSuffix("PACKDISTANCE", new SetSuffix( () => System.Math.Min(Vessel.distanceLandedPackThreshold, Vessel.distancePackThreshold), value => { Vessel.distanceLandedPackThreshold = Vessel.distancePackThreshold = value; })); + AddSuffix("ISDEAD", new NoArgsSuffix(() => (Vessel.state == Vessel.State.DEAD) )); //// Although there is an implementation of lat/long/alt in Orbitible, //// it's better to use the methods for vessels that are faster if they're From 6ecc5ca93d81e7007b70b051876e16279390c969 Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Thu, 9 Apr 2015 15:36:53 -0500 Subject: [PATCH 353/446] Added docs for Vessel:ISDEAD --- doc/source/structures/vessels/vessel.rst | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/doc/source/structures/vessels/vessel.rst b/doc/source/structures/vessels/vessel.rst index 3e14a485a..29fdbc786 100644 --- a/doc/source/structures/vessels/vessel.rst +++ b/doc/source/structures/vessels/vessel.rst @@ -49,6 +49,7 @@ All vessels share a structure. To get a variable referring to any vessel you can :attr:`ANGULARVEL` :struct:`Vector` In :ref:`SHIP_RAW ` :attr:`SENSORS` :struct:`VesselSensors` Sensor data :attr:`LOADED` Boolean loaded into KSP physics engine or "on rails" + :attr:`ISDEAD` Boolean True if the vessel refers to a ship that has gone away. :attr:`PATCHES` :struct:`List` :struct:`Orbit` patches :attr:`ROOTPART` :struct:`Part` Root :struct:`Part` of this vessel :attr:`PARTS` :struct:`List` all :struct:`Parts ` @@ -205,6 +206,19 @@ All vessels share a structure. To get a variable referring to any vessel you can true if the vessel is fully loaded into the complete KSP physics engine (false if it's "on rails"). +.. attribute:: Vessel:ISDEAD + + :type: Boolean + :access: Get only + + It is possible to have a variable that refers to a vessel that + doesn't exist in the Kerbal Space Program universe anymore, but + did back when you first got it. For example: you could do: + SET VES TO VESSEL("OTHER"). WAIT 10. And in that intervening + waiting time, the vessel might have crashed into the ground. + Checking :ISDEAD lets you see if the vessel that was previously + valid isn't valid anymore. + .. attribute:: Vessel:PATCHES :type: :struct:`List` From cbf26ce34cebb980024f1f3777bec8d8af36060c Mon Sep 17 00:00:00 2001 From: SirDiazo Date: Thu, 9 Apr 2015 19:52:14 -0600 Subject: [PATCH 354/446] Update AGX.rst --- doc/source/addons/AGX.rst | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/doc/source/addons/AGX.rst b/doc/source/addons/AGX.rst index 0112d640a..1f2ff88fb 100644 --- a/doc/source/addons/AGX.rst +++ b/doc/source/addons/AGX.rst @@ -11,12 +11,17 @@ Includes a Script Trigger action that can be used to control a running program a **Usage:** Adds action groups AG11 through AG250 to kOS that are interacted with the same way as the AG1 through AG10 bindings in base kOS are. -Anywhere you use ``AG1``, you can use ``AG15`` in the same way. +Anywhere you use ``AG1``, you can use ``AG15`` in the same way. (AG11 through AG250 explicitly behave the same as the 10 stock groups. Please file a bug report if they do not.) -**Behavior changes to be aware of:** -All action groups (from 1 through 250) now have their on/off state monitored and it is based on the state of the actions in the group. See Action State Montioring and Animation Delay below for how animations affect this. Note this means that an action assigned to one action group can change the on/off state of a second action group when the same action is present in both action groups. +**Script Trigger action:** +Installing AGX adds the "Script Trigger" action to all kOS computer parts. This action is a null action that does not activate anything but serves as a placeholder to enhance action groups in kOS. + +When an action group has the Script Trigger action assigned, on that action gorup you can now: + +-Name the action group so you remember what that action group does in your code when you trigger it. +-Activate the action group with a mouse click on-screen, no more tying up your entire keyboard with various script trigger keys. +-Enable group state feedback so you can have your script change the groups state as feedback as to what the script is doing. Green being On and Red being Off. (Toggle option in AGX.) -For Action Groups 11 through 250 there must be an action assigned to the group in order to toggle their state on/off. The Script Trigger action on the kOS computer is provided for this purpse. Assigning the Script Trigger action this way will also allow you to name the action group on AGX's GUI so you can remember what it does and allow you trigger that action group via mouse-click. Action Groups 1 through 10 can still be triggered even if empty as per stock behavior. **Basic Quick Start:** @@ -24,12 +29,11 @@ For Action Groups 11 through 250 there must be an action assigned to the group i .. figure:: /_images/addons/AGExtQuickStart2.jpg -Note that this mod only adds action grousp 11 through 250, it does not change how action groups 1 through 10 behave in any way. +Note that this mod only adds action grousp 11 through 250, it does not change how action groups 1 through 10 behave in any way and groups 11 through 250 should behave the same way. **Known limitations (Action groups 11 through 250 only):** -- For an action group to be useable, it must have an action assigned to it. When installed, AGX adds a "Script Trigger" action to the kOS computer part that serves this purpose if you want an "empty" action group to trigger kOS scripts with. -- Be aware that if you query an empty action group, it will always return a state of False and trying to turn an emtpy action group On will do nothing and silently fail without any sort of error message. +- On a nearby vessel that is not your current focus, an action group with no actions assigned will always return a state of False and can not be set to a state of true via the "AG15 on." command. Assign the Script Trigger action as a work-around for this. - At this point, AG11 through AG250 do not officially support RemoteTech through kOS. (Support will happen once all three mods involved have updated to KSP version 1.0 and made any internal changes necessary.) All three mods can be installed at the same time without issue, just be aware there may be unexpected behavior when using action groups 11 through 250 from a kOS script in terms of RemoteTech signal delay and connection state. **Action state monitoring** From ec2d1e96ab11d68754d048eb4305a2173151776b Mon Sep 17 00:00:00 2001 From: SirDiazo Date: Thu, 9 Apr 2015 19:54:16 -0600 Subject: [PATCH 355/446] Update AGX.rst --- doc/source/addons/AGX.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/source/addons/AGX.rst b/doc/source/addons/AGX.rst index 1f2ff88fb..a0ebc83e3 100644 --- a/doc/source/addons/AGX.rst +++ b/doc/source/addons/AGX.rst @@ -18,9 +18,9 @@ Installing AGX adds the "Script Trigger" action to all kOS computer parts. This When an action group has the Script Trigger action assigned, on that action gorup you can now: --Name the action group so you remember what that action group does in your code when you trigger it. --Activate the action group with a mouse click on-screen, no more tying up your entire keyboard with various script trigger keys. --Enable group state feedback so you can have your script change the groups state as feedback as to what the script is doing. Green being On and Red being Off. (Toggle option in AGX.) +- Name the action group so you remember what that action group does in your code when you trigger it. +- Activate the action group with a mouse click on-screen, no more tying up your entire keyboard with various script trigger keys. +- Enable group state feedback so you can have your script change the groups state as feedback as to what the script is doing. Green being On and Red being Off. (Toggle option in AGX.) **Basic Quick Start:** From 3d30b458b993daf8524d0c69390f628e23ff581f Mon Sep 17 00:00:00 2001 From: SirDiazo Date: Thu, 9 Apr 2015 21:55:37 -0600 Subject: [PATCH 356/446] Update AGX.rst --- doc/source/addons/AGX.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/addons/AGX.rst b/doc/source/addons/AGX.rst index a0ebc83e3..53bcbe879 100644 --- a/doc/source/addons/AGX.rst +++ b/doc/source/addons/AGX.rst @@ -16,7 +16,7 @@ Anywhere you use ``AG1``, you can use ``AG15`` in the same way. (AG11 through AG **Script Trigger action:** Installing AGX adds the "Script Trigger" action to all kOS computer parts. This action is a null action that does not activate anything but serves as a placeholder to enhance action groups in kOS. -When an action group has the Script Trigger action assigned, on that action gorup you can now: +When an action group has the Script Trigger action assigned, on that action group you can now: - Name the action group so you remember what that action group does in your code when you trigger it. - Activate the action group with a mouse click on-screen, no more tying up your entire keyboard with various script trigger keys. From 01cbdaf5ef2e50eaff9e4119865b37a375a82ca4 Mon Sep 17 00:00:00 2001 From: ZiwKerman Date: Sat, 11 Apr 2015 15:09:48 +0100 Subject: [PATCH 357/446] A very short tutorial base on exenode script. --- doc/source/tutorials/exenode.rst | 91 ++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 doc/source/tutorials/exenode.rst diff --git a/doc/source/tutorials/exenode.rst b/doc/source/tutorials/exenode.rst new file mode 100644 index 000000000..b75ef10aa --- /dev/null +++ b/doc/source/tutorials/exenode.rst @@ -0,0 +1,91 @@ +.. _exenode: + +Advanced Tutorial +================= + +Let's try to automate one of the most common tasks in orbital maneuvering - execution of the maneuver node. In this tutorial I'll try to show you how to write a script for precise maneuver node execution. + +So to start our script we need to get the next available :ref:`maneuver node <_maneuver node>`:: + + set nd to nextnode(). + +Our next step is to calculate how much time our vessel needs to burn at full throttle to execute the node:: + + //print out node's basic parameters - ETA and deltaV + print "Node in: " + round(nd:eta) + ", DeltaV: " + round(nd:deltav:mag). + + //calculate ship's max acceleration + set max_acc to ship:maxthrust/ship:mass. + + //now we just need to divide deltav:mag by our ship's max acceleration + set burn_duration to nd:deltav:mag/max_acc. + print "Estimated burn duration: " + round(burn_duration) + "s". + +So now we have our node's deltav vector, ETA to the node and we calculated our burn duration. All that is left for us to do is wait until we are close to node's ETA less half of our burn duration. But we want to write a universal script, and some of our current and/or future ships can be quite slow to turn, so let's give us some time, 60 seconds, to prepare for the maneuver burn:: + + wait until node:eta <= (burn_duration/2 + 60). + +This wait can be tedious and you'll most likely end up warping some time, but we'll leave kOS automation of warping for a given period of time to our readers. + +The wait has finished, and now we need to start turning our ship in the direction of the burn. + + set np to lookdirup(nd:deltav, ship:facing:topvector). //points to node, keeping roll the same. + lock steering to np. + + //now we need to wait until the burn vector and ship's facing are aligned + wait until abs(np:pitch - facing:pitch) < 0.15 and abs(np:yaw - facing:yaw) < 0.15. + + //the ship is facing the right direction, let's wait for our burn time + wait until node:eta <= (burn_duration/2) + +Now we are ready to burn. It is usually done in the `until` loop, checking main parameters of the burn every iteration until the burn is complete:: + + //we only need to lock throttle once to a certain variable in the beginning of the loop, and adjust only the variable itself inside it + set tset to 0. + lock throttle to tset. + + set done to False. + //initial deltav + set dv0 to nd:deltav. + until done + { + //recalculate current max_acceleration, as it changes while we burn through fuel + set max_acc to ship:maxthrust/ship:mass. + + //throttle is 100% until there is less than 1 second of time left to burn + //when there is less than 1 second - decrease the throttle linearly + set tset to min(nd:deltav:mag/maxa_acc, 1). + + //here's the tricky part, we need to cut the throttle as soon as our nd:deltav and initial deltav start facing opposite directions + //this check is done via checking the dot product of those 2 vectors + if vdot(dv0, nd:deltav) < 0 + { + print "End burn, remain dv " + round(nd:deltav:mag,1) + "m/s, vdot: " + round(vdot(dv0, nd:deltav),1). + lock throttle to 0. + break. + } + + //we have very little left to burn, less then 0.1m/s + if nd:deltav:mag < 0.1 + { + print "Finalizing burn, remain dv " + round(nd:deltav:mag,1) + "m/s, vdot: " + round(vdot(dv0, nd:deltav),1). + //we burn slowly until our node vector starts to drift significantly from initial vector + //this usually means we are on point + wait until vdot(dv0, nd:deltav) < 0.5. + + lock throttle to 0. + print "End burn, remain dv " + round(nd:deltav:mag,1) + "m/s, vdot: " + round(vdot(dv0, nd:deltav),1). + set done to True. + } + } + unlock steering. + unlock throttle. + wait 1. + + //we no longer need the maneuver node + remove nd. + + //set throttle to 0 just in case. + SET SHIP:CONTROL:PILOTMAINTHROTTLE TO 0. + +That is all, this short script can execute any maneuver node with 0.1 m/s dv precision or even better. From b77f2060f966f5f60f80a42388a1dfefd64269c2 Mon Sep 17 00:00:00 2001 From: ZiwKerman Date: Sat, 11 Apr 2015 15:11:41 +0100 Subject: [PATCH 358/446] Typo --- doc/source/tutorials/exenode.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/tutorials/exenode.rst b/doc/source/tutorials/exenode.rst index b75ef10aa..3b93e427b 100644 --- a/doc/source/tutorials/exenode.rst +++ b/doc/source/tutorials/exenode.rst @@ -27,7 +27,7 @@ So now we have our node's deltav vector, ETA to the node and we calculated our b This wait can be tedious and you'll most likely end up warping some time, but we'll leave kOS automation of warping for a given period of time to our readers. -The wait has finished, and now we need to start turning our ship in the direction of the burn. +The wait has finished, and now we need to start turning our ship in the direction of the burn:: set np to lookdirup(nd:deltav, ship:facing:topvector). //points to node, keeping roll the same. lock steering to np. From 667327277dd3adca80e0dd7dce5e726f19887d57 Mon Sep 17 00:00:00 2001 From: ZiwKerman Date: Sun, 12 Apr 2015 20:15:08 +0100 Subject: [PATCH 359/446] First Pass --- .../AddOns/InfernalRobotics/IRControlGroup.cs | 87 +++ .../AddOns/InfernalRobotics/IRFunctions.cs | 66 ++ src/kOS/AddOns/InfernalRobotics/IRHandler.cs | 25 + .../AddOns/InfernalRobotics/IRServoWrapper.cs | 83 +++ src/kOS/AddOns/InfernalRobotics/IRWrapper.cs | 571 ++++++++++++++++++ src/kOS/kOS.csproj | 5 + 6 files changed, 837 insertions(+) create mode 100644 src/kOS/AddOns/InfernalRobotics/IRControlGroup.cs create mode 100644 src/kOS/AddOns/InfernalRobotics/IRFunctions.cs create mode 100644 src/kOS/AddOns/InfernalRobotics/IRHandler.cs create mode 100644 src/kOS/AddOns/InfernalRobotics/IRServoWrapper.cs create mode 100644 src/kOS/AddOns/InfernalRobotics/IRWrapper.cs diff --git a/src/kOS/AddOns/InfernalRobotics/IRControlGroup.cs b/src/kOS/AddOns/InfernalRobotics/IRControlGroup.cs new file mode 100644 index 000000000..de7e48c9c --- /dev/null +++ b/src/kOS/AddOns/InfernalRobotics/IRControlGroup.cs @@ -0,0 +1,87 @@ +using kOS.Safe.Encapsulation; +using kOS.Safe.Encapsulation.Suffixes; +using kOS.Safe.Utilities; +using kOS.Suffixed; +using System; +using System.Collections.Generic; +using System.Linq; +using kOS.AddOns.InfernalRobotics; + +namespace kOS.AddOns.InfernalRobotics +{ + public class IRControlGroupWrapper : Structure + { + private readonly IRWrapper.IRAPI.IRControlGroup cg; + private readonly SharedObjects shared; + + public IRControlGroupWrapper(IRWrapper.IRAPI.IRControlGroup init, SharedObjects shared) + { + cg = init; + this.shared = shared; + InitializeSuffixes(); + } + + private void InitializeSuffixes() + { + AddSuffix("NAME", new SetSuffix(() => cg.Name, value => cg.Name = value)); + AddSuffix("SPEED", new SetSuffix(() => cg.Speed, value => cg.Speed = value)); + AddSuffix("EXPANDED", new SetSuffix(() => cg.Expanded, value => cg.Expanded = value)); + AddSuffix("FORWARDKEY", new SetSuffix(() => cg.ForwardKey, value => cg.ForwardKey = value)); + AddSuffix("REVERSEKEY", new SetSuffix(() => cg.ReverseKey, value => cg.ReverseKey = value)); + + AddSuffix("SERVOS", new NoArgsSuffix (GetServos)); + + AddSuffix("MOVERIGHT", new NoArgsSuffix(MoveRight)); + AddSuffix("MOVELEFT", new NoArgsSuffix(MoveLeft)); + AddSuffix("MOVECENTER", new NoArgsSuffix(MoveCenter)); + AddSuffix("MOVENEXTPRESET", new NoArgsSuffix(MoveNextPreset)); + AddSuffix("MOVEPREVPRESET", new NoArgsSuffix(MovePrevPreset)); + AddSuffix("STOP", new NoArgsSuffix(Stop)); + } + + public ListValue GetServos() + { + var list = new List (); + + if(IRWrapper.APIReady) + { + foreach(IRWrapper.IRAPI.IRServo s in cg.Servos) + { + list.Add(new IRServoWrapper(s, shared)); + } + } + + return ListValue.CreateList(list); + } + + public void MoveRight() + { + cg.MoveRight(); + } + + public void MoveLeft() + { + cg.MoveLeft(); + } + + public void MoveCenter() + { + cg.MoveCenter(); + } + + public void MoveNextPreset() + { + cg.MoveNextPreset(); + } + + public void MovePrevPreset() + { + cg.MovePrevPreset(); + } + + public void Stop() + { + cg.Stop(); + } + } +} \ No newline at end of file diff --git a/src/kOS/AddOns/InfernalRobotics/IRFunctions.cs b/src/kOS/AddOns/InfernalRobotics/IRFunctions.cs new file mode 100644 index 000000000..722ea0bd2 --- /dev/null +++ b/src/kOS/AddOns/InfernalRobotics/IRFunctions.cs @@ -0,0 +1,66 @@ +using kOS.Function; +using kOS.Safe.Encapsulation; +using kOS.Safe.Exceptions; +using kOS.Safe.Function; +using kOS.Safe.Utilities; +using System; +using System.Linq; + +namespace kOS.AddOns.InfernalRobotics +{ + [Function("IR_listServos")] + public class FunctionListServos : FunctionBase + { + public override void Execute(SharedObjects shared) + { + var list = new ListValue(); + if (!IRWrapper.APIReady) + { + shared.Cpu.PushStack(list); + //throw new KOSUnavailableAddonException("IR_listServos()", "Infernal Robotics"); + return; + } + + IRWrapper.IRAPI.IRControlGroup controlGroup = (IRWrapper.IRAPI.IRControlGroup) shared.Cpu.PopValue(); + + if (controlGroup == null) + { + shared.Cpu.PushStack(list); + return; + } + + IRWrapper.IRAPI.IRServosList servos = controlGroup.Servos; + + foreach (IRWrapper.IRAPI.IRServo s in servos) + { + list.Add(new IRServoWrapper(s, shared)); + } + + shared.Cpu.PushStack(list); + } + } + + [Function("IR_listControlGroups")] + public class FunctionListControlGroups : FunctionBase + { + public override void Execute(SharedObjects shared) + { + var list = new ListValue(); + if (!IRWrapper.APIReady) + { + shared.Cpu.PushStack(list); + //throw new KOSUnavailableAddonException("listControlGroups()", "Kerbal Alarm Clock"); + return; + } + + IRWrapper.IRAPI.IRServoGroupsList controlGroups = IRWrapper.IRController.ServoGroups; + + foreach (IRWrapper.IRAPI.IRControlGroup cg in controlGroups) + { + list.Add(new IRControlGroupWrapper(cg, shared)); + } + + shared.Cpu.PushStack(list); + } + } +} \ No newline at end of file diff --git a/src/kOS/AddOns/InfernalRobotics/IRHandler.cs b/src/kOS/AddOns/InfernalRobotics/IRHandler.cs new file mode 100644 index 000000000..cfed6bc96 --- /dev/null +++ b/src/kOS/AddOns/InfernalRobotics/IRHandler.cs @@ -0,0 +1,25 @@ +using UnityEngine; +using Debug = UnityEngine.Debug; + +namespace kOS.AddOns.InfernalRobotics +{ + [KSPAddon(KSPAddon.Startup.EveryScene, false)] + public class KACEventHandler : MonoBehaviour + { + public void Start() + { + IRWrapper.InitWrapper(); + if (IRWrapper.APIReady) + { + + } + } + + public void OnDestroy() + { + if (IRWrapper.APIReady) + { + } + } + } +} \ No newline at end of file diff --git a/src/kOS/AddOns/InfernalRobotics/IRServoWrapper.cs b/src/kOS/AddOns/InfernalRobotics/IRServoWrapper.cs new file mode 100644 index 000000000..197af4b62 --- /dev/null +++ b/src/kOS/AddOns/InfernalRobotics/IRServoWrapper.cs @@ -0,0 +1,83 @@ +using kOS.Safe.Encapsulation; +using kOS.Safe.Encapsulation.Suffixes; +using kOS.Safe.Utilities; +using kOS.Suffixed; +using System; +using System.Linq; + +namespace kOS.AddOns.InfernalRobotics +{ + public class IRServoWrapper : Structure + { + private readonly IRWrapper.IRAPI.IRServo servo; + private readonly SharedObjects shared; + + public IRServoWrapper(IRWrapper.IRAPI.IRServo init, SharedObjects shared) + { + servo = init; + this.shared = shared; + InitializeSuffixes(); + } + + private void InitializeSuffixes() + { + AddSuffix("NAME", new SetSuffix(() => servo.Name, value => servo.Name = value)); + AddSuffix("HIGHLIGHT", new SetSuffix(() => true, value => servo.Highlight = value)); + + AddSuffix("POSITION", new Suffix(() => servo.Position)); + AddSuffix("MINCFGPOSITION", new Suffix(() => servo.MinConfigPosition)); + AddSuffix("MAXCFGPOSITION", new Suffix(() => servo.MaxConfigPosition)); + AddSuffix("MINPOSITION", new SetSuffix(() => servo.MinPosition, value => servo.MinPosition = value)); + AddSuffix("MAXPOSITION", new SetSuffix(() => servo.MaxPosition, value => servo.MaxPosition = value)); + AddSuffix("CONFIGSPEED", new Suffix(() => servo.ConfigSpeed)); + AddSuffix("CURRENTSPEED", new SetSuffix(() => servo.CurrentSpeed, value => servo.CurrentSpeed = value)); + AddSuffix("SPEED", new SetSuffix(() => servo.Speed, value => servo.Speed = value)); + AddSuffix("ACCELERATION", new SetSuffix(() => servo.Acceleration, value => servo.Acceleration = value)); + + AddSuffix("MOVERIGHT", new NoArgsSuffix(MoveRight)); + AddSuffix("MOVELEFT", new NoArgsSuffix(MoveLeft)); + AddSuffix("MOVECENTER", new NoArgsSuffix(MoveCenter)); + AddSuffix("MOVENEXTPRESET", new NoArgsSuffix(MoveNextPreset)); + AddSuffix("MOVEPREVPRESET", new NoArgsSuffix(MovePrevPreset)); + AddSuffix("STOP", new NoArgsSuffix(Stop)); + + AddSuffix("MOVETO", new TwoArgsSuffix(MoveTo)); + } + + + public void MoveRight() + { + servo.MoveRight(); + } + + public void MoveLeft() + { + servo.MoveLeft(); + } + + public void MoveCenter() + { + servo.MoveCenter(); + } + + public void MoveNextPreset() + { + servo.MoveNextPreset(); + } + + public void MovePrevPreset() + { + servo.MovePrevPreset(); + } + + public void Stop() + { + servo.Stop(); + } + + public void MoveTo(float position, float speed) + { + servo.MoveTo(position, speed); + } + } +} \ No newline at end of file diff --git a/src/kOS/AddOns/InfernalRobotics/IRWrapper.cs b/src/kOS/AddOns/InfernalRobotics/IRWrapper.cs new file mode 100644 index 000000000..132908757 --- /dev/null +++ b/src/kOS/AddOns/InfernalRobotics/IRWrapper.cs @@ -0,0 +1,571 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Reflection; +using System.Text; + +// TODO: Change this namespace to something specific to your plugin here. +namespace kOS.AddOns.InfernalRobotics +{ + + public class IRWrapper + { + protected static System.Type IRServoControllerType; + protected static System.Type IRControlGroupType; + protected static System.Type IRServoType; + protected static System.Type IRServoPartType; + protected static System.Type IRServoMechanismType; + + protected static Object actualServoController = null; + + public static IRAPI IRController = null; + public static Boolean AssemblyExists { get { return (IRServoControllerType != null); } } + public static Boolean InstanceExists { get { return (IRController != null); } } + private static Boolean isWrapped = false; + public static Boolean APIReady { get { return isWrapped && IRController.APIReady; } } + + public static Boolean InitWrapper() + { + isWrapped = false; + actualServoController = null; + IRController = null; + LogFormatted("Attempting to Grab IR Types..."); + + IRServoControllerType = AssemblyLoader.loadedAssemblies + .Select(a => a.assembly.GetExportedTypes()) + .SelectMany(t => t) + .FirstOrDefault(t => t.FullName == "InfernalRobotics.Command.ServoController"); + + if (IRServoControllerType == null) + { + return false; + } + + LogFormatted("IR Version:{0}", IRServoControllerType.Assembly.GetName().Version.ToString()); + + IRServoMechanismType = AssemblyLoader.loadedAssemblies + .Select(a => a.assembly.GetExportedTypes()) + .SelectMany(t => t) + .FirstOrDefault(t => t.FullName == "InfernalRobotics.Control.IMechanism"); + + if (IRServoMechanismType == null) + { + LogFormatted("[IR Wrapper] Failed to grab Mechanism Type"); + return false; + } + + IRServoType = AssemblyLoader.loadedAssemblies + .Select(a => a.assembly.GetExportedTypes()) + .SelectMany(t => t) + .FirstOrDefault(t => t.FullName == "InfernalRobotics.Control.IServo"); + + if (IRServoType == null) + { + LogFormatted("[IR Wrapper] Failed to grab Servo Type"); + return false; + } + + IRServoPartType = AssemblyLoader.loadedAssemblies + .Select(a => a.assembly.GetExportedTypes()) + .SelectMany(t => t) + .FirstOrDefault(t => t.FullName == "InfernalRobotics.Control.IPart"); + + if (IRServoType == null) + { + LogFormatted("[IR Wrapper] Failed to grab ServoPart Type"); + return false; + } + + IRControlGroupType = AssemblyLoader.loadedAssemblies + .Select(a => a.assembly.GetExportedTypes()) + .SelectMany(t => t) + .FirstOrDefault(t => t.FullName == "InfernalRobotics.Command.ServoController+ControlGroup"); + + if (IRControlGroupType == null) + { + var irassembly = AssemblyLoader.loadedAssemblies.FirstOrDefault(a => a.assembly.FullName.Contains("InfernalRobotics")); + if (irassembly == null) + { + LogFormatted("[IR Wrapper] cannot find InvernalRobotics.dll"); + return false; + } + foreach (Type t in irassembly.assembly.GetExportedTypes()) + { + LogFormatted("[IR Wrapper] Exported type: " + t.FullName); + } + + LogFormatted("[IR Wrapper] Failed to grab ControlGroup Type"); + return false; + } + + LogFormatted("Got Assembly Types, grabbing Instance"); + + try + { + var fi = IRServoControllerType.GetProperty("Instance", BindingFlags.Public | BindingFlags.Static); + + if (fi == null) + LogFormatted("[IR Wrapper] Cannot find Instance Property"); + actualServoController = fi.GetValue(null, null); + } + catch (Exception e) + { + LogFormatted("No Instance found, " + e.Message); + } + + if (actualServoController == null) + { + LogFormatted("Failed grabbing Instance"); + return false; + } + + LogFormatted("Got Instance, Creating Wrapper Objects"); + IRController = new IRAPI(actualServoController); + isWrapped = true; + return true; + } + + public class IRAPI + { + internal IRAPI(Object IRServoController) + { + actualServoController = IRServoController; + + LogFormatted("Getting APIReady Object"); + APIReadyProperty = IRServoControllerType.GetProperty("APIReady", BindingFlags.Public | BindingFlags.Static); + LogFormatted("Success: " + (APIReadyProperty != null).ToString()); + + LogFormatted("Getting ServoGroups Object"); + ServoGroupsField = IRServoControllerType.GetField("ServoGroups"); + if (ServoGroupsField == null) + LogFormatted("Failed Getting ServoGroups fieldinfo"); + actualServoGroups = ServoGroupsField.GetValue(actualServoController); + LogFormatted("Success: " + (actualServoGroups != null).ToString()); + + } + + private Object actualServoController; + + private PropertyInfo APIReadyProperty; + public Boolean APIReady + { + get + { + if (APIReadyProperty == null) + return false; + + return (Boolean)APIReadyProperty.GetValue(null, null); + } + } + + private Object actualServoGroups; + private FieldInfo ServoGroupsField; + + internal IRServoGroupsList ServoGroups + { + get + { + return ExtractServoGroups(actualServoGroups); + } + } + + private IRServoGroupsList ExtractServoGroups(Object actualServoGroups) + { + IRServoGroupsList ListToReturn = new IRServoGroupsList(); + try + { + //iterate each "value" in the dictionary + foreach (var item in (IList)actualServoGroups) + { + IRControlGroup r1 = new IRControlGroup(item); + ListToReturn.Add(r1); + } + } + catch (Exception) + { + //LogFormatted("Arrggg: {0}", ex.Message); + //throw ex; + // + } + return ListToReturn; + } + + public class IRControlGroup + { + internal IRControlGroup(Object cg) + { + actualControlGroup = cg; + NameProperty = IRControlGroupType.GetProperty("Name"); + ForwardKeyProperty = IRControlGroupType.GetProperty("ForwardKey"); + ReverseKeyProperty = IRControlGroupType.GetProperty("ReverseKey"); + SpeedProperty = IRControlGroupType.GetProperty("Speed"); + ExpandedProperty = IRControlGroupType.GetProperty("Expanded"); + + ServosProperty = IRControlGroupType.GetProperty("Servos"); + actualServos = ServosProperty.GetValue(actualControlGroup, null); + + MoveRightMethod = IRControlGroupType.GetMethod("MoveRight", BindingFlags.Public | BindingFlags.Instance); + MoveLeftMethod = IRControlGroupType.GetMethod("MoveLeft", BindingFlags.Public | BindingFlags.Instance); + MoveCenterMethod = IRControlGroupType.GetMethod("MoveCenter", BindingFlags.Public | BindingFlags.Instance); + MoveNextPresetMethod = IRControlGroupType.GetMethod("MoveNextPreset", BindingFlags.Public | BindingFlags.Instance); + MovePrevPresetMethod = IRControlGroupType.GetMethod("MovePrevPreset", BindingFlags.Public | BindingFlags.Instance); + StopMethod = IRControlGroupType.GetMethod("Stop", BindingFlags.Public | BindingFlags.Instance); + } + private Object actualControlGroup; + + private PropertyInfo NameProperty; + public String Name + { + get { return (String)NameProperty.GetValue(actualControlGroup, null); } + set { NameProperty.SetValue(actualControlGroup, value, null); } + } + + private PropertyInfo ForwardKeyProperty; + public String ForwardKey + { + get { return (String)ForwardKeyProperty.GetValue(actualControlGroup, null); } + set { ForwardKeyProperty.SetValue(actualControlGroup, value, null); } + } + + private PropertyInfo ReverseKeyProperty; + public String ReverseKey + { + get { return (String)ReverseKeyProperty.GetValue(actualControlGroup, null); } + set { ReverseKeyProperty.SetValue(actualControlGroup, value, null); } + } + + private PropertyInfo SpeedProperty; + public float Speed + { + get { return (float)SpeedProperty.GetValue(actualControlGroup, null); } + set { SpeedProperty.SetValue(actualControlGroup, value, null); } + } + + private PropertyInfo ExpandedProperty; + public bool Expanded + { + get { return (bool)ExpandedProperty.GetValue(actualControlGroup, null); } + set { ExpandedProperty.SetValue(actualControlGroup, value, null); } + } + + private Object actualServos; + private PropertyInfo ServosProperty; + + internal IRServosList Servos + { + get + { + return ExtractServos(actualServos); + } + } + + private IRServosList ExtractServos(Object actualServos) + { + IRServosList ListToReturn = new IRServosList(); + try + { + //iterate each "value" in the dictionary + foreach (var item in (IList)actualServos) + { + IRServo r1 = new IRServo(item); + ListToReturn.Add(r1); + } + } + catch (Exception) + { + //LogFormatted("Arrggg: {0}", ex.Message); + //throw ex; + // + } + return ListToReturn; + } + + private MethodInfo MoveRightMethod; + internal void MoveRight() + { + MoveRightMethod.Invoke(actualControlGroup, new System.Object[] { }); + } + + private MethodInfo MoveLeftMethod; + internal void MoveLeft() + { + MoveLeftMethod.Invoke(actualControlGroup, new System.Object[] { }); + } + + private MethodInfo MoveCenterMethod; + internal void MoveCenter() + { + MoveCenterMethod.Invoke(actualControlGroup, new System.Object[] { }); + } + + private MethodInfo MoveNextPresetMethod; + internal void MoveNextPreset() + { + MoveNextPresetMethod.Invoke(actualControlGroup, new System.Object[] { }); + } + + private MethodInfo MovePrevPresetMethod; + internal void MovePrevPreset() + { + MovePrevPresetMethod.Invoke(actualControlGroup, new System.Object[] { }); + } + + private MethodInfo StopMethod; + internal void Stop() + { + StopMethod.Invoke(actualControlGroup, new System.Object[] { }); + } + } + + public class IRServo + { + + internal IRServo(Object s) + { + actualServo = s; + + NameProperty = IRServoPartType.GetProperty("Name"); + HighlightProperty = IRServoPartType.GetProperty("Highlight"); + + MechanismProperty = IRServoType.GetProperty("Mechanism"); + actualServoMechanism = MechanismProperty.GetValue(actualServo, null); + + PositionProperty = IRServoMechanismType.GetProperty("Position"); + MinPositionProperty = IRServoMechanismType.GetProperty("MinPositionLimit"); + MaxPositionProperty = IRServoMechanismType.GetProperty("MaxPositionLimit"); + + MinConfigPositionProperty = IRServoMechanismType.GetProperty("MinPosition"); + MaxConfigPositionProperty = IRServoMechanismType.GetProperty("MaxPosition"); + + SpeedProperty = IRServoMechanismType.GetProperty("SpeedLimit"); + ConfigSpeedProperty = IRServoMechanismType.GetProperty("DefaultSpeed"); + CurrentSpeedProperty = IRServoMechanismType.GetProperty("CurrentSpeed"); + AccelerationProperty = IRServoMechanismType.GetProperty("AccelerationLimit"); + IsMovingProperty = IRServoMechanismType.GetProperty("IsMoving"); + IsFreeMovingProperty = IRServoMechanismType.GetProperty("IsFreeMoving"); + IsLockedProperty = IRServoMechanismType.GetProperty("IsLocked"); + IsAxisInvertedProperty = IRServoMechanismType.GetProperty("IsAxisInverted"); + + MoveRightMethod = IRServoMechanismType.GetMethod("MoveRight", BindingFlags.Public | BindingFlags.Instance); + MoveLeftMethod = IRServoMechanismType.GetMethod("MoveLeft", BindingFlags.Public | BindingFlags.Instance); + MoveCenterMethod = IRServoMechanismType.GetMethod("MoveCenter", BindingFlags.Public | BindingFlags.Instance); + MoveNextPresetMethod = IRServoMechanismType.GetMethod("MoveNextPreset", BindingFlags.Public | BindingFlags.Instance); + MovePrevPresetMethod = IRServoMechanismType.GetMethod("MovePrevPreset", BindingFlags.Public | BindingFlags.Instance); + StopMethod = IRServoMechanismType.GetMethod("Stop", BindingFlags.Public | BindingFlags.Instance); + + MoveToMethod = IRServoMechanismType.GetMethod("MoveTo", new Type[] { typeof(float), typeof(float) }); + } + private Object actualServo; + + private PropertyInfo MechanismProperty; + private Object actualServoMechanism; + + private PropertyInfo NameProperty; + public String Name + { + get { return (String)NameProperty.GetValue(actualServo, null); } + set { NameProperty.SetValue(actualServo, value, null); } + } + + private PropertyInfo HighlightProperty; + public bool Highlight + { + //get { return (bool)HighlightProperty.GetValue(actualServo, null); } + set { HighlightProperty.SetValue(actualServo, value, null); } + } + + private PropertyInfo PositionProperty; + public float Position + { + get { return (float)PositionProperty.GetValue(actualServoMechanism, null); } + } + + private PropertyInfo MinConfigPositionProperty; + public float MinConfigPosition + { + get { return (float)MinConfigPositionProperty.GetValue(actualServoMechanism, null); } + } + + private PropertyInfo MaxConfigPositionProperty; + public float MaxConfigPosition + { + get { return (float)MaxConfigPositionProperty.GetValue(actualServoMechanism, null); } + } + + private PropertyInfo MinPositionProperty; + public float MinPosition + { + get { return (float)MinPositionProperty.GetValue(actualServoMechanism, null); } + set { MinPositionProperty.SetValue(actualServoMechanism, value, null); } + } + + private PropertyInfo MaxPositionProperty; + public float MaxPosition + { + get { return (float)MaxPositionProperty.GetValue(actualServoMechanism, null); } + set { MaxPositionProperty.SetValue(actualServoMechanism, value, null); } + } + + private PropertyInfo ConfigSpeedProperty; + public float ConfigSpeed + { + get { return (float)ConfigSpeedProperty.GetValue(actualServoMechanism, null); } + } + + private PropertyInfo SpeedProperty; + public float Speed + { + get { return (float)SpeedProperty.GetValue(actualServoMechanism, null); } + set { SpeedProperty.SetValue(actualServoMechanism, value, null); } + } + + private PropertyInfo CurrentSpeedProperty; + public float CurrentSpeed + { + get { return (float)CurrentSpeedProperty.GetValue(actualServoMechanism, null); } + set { CurrentSpeedProperty.SetValue(actualServoMechanism, value, null); } + } + + private PropertyInfo AccelerationProperty; + public float Acceleration + { + get { return (float)AccelerationProperty.GetValue(actualServoMechanism, null); } + set { AccelerationProperty.SetValue(actualServoMechanism, value, null); } + } + + private PropertyInfo IsMovingProperty; + public bool IsMoving + { + get { return (bool)IsMovingProperty.GetValue(actualServoMechanism, null); } + } + + private PropertyInfo IsFreeMovingProperty; + public bool IsFreeMoving + { + get { return (bool)IsFreeMovingProperty.GetValue(actualServoMechanism, null); } + } + + private PropertyInfo IsLockedProperty; + public bool IsLocked + { + get { return (bool)IsLockedProperty.GetValue(actualServoMechanism, null); } + set { IsLockedProperty.SetValue(actualServoMechanism, value, null); } + } + + private PropertyInfo IsAxisInvertedProperty; + public bool IsAxisInverted + { + get { return (bool)IsAxisInvertedProperty.GetValue(actualServoMechanism, null); } + set { IsAxisInvertedProperty.SetValue(actualServoMechanism, value, null); } + } + + private MethodInfo MoveRightMethod; + internal void MoveRight() + { + MoveRightMethod.Invoke(actualServoMechanism, new System.Object[] { }); + } + + private MethodInfo MoveLeftMethod; + internal void MoveLeft() + { + MoveLeftMethod.Invoke(actualServoMechanism, new System.Object[] { }); + } + + private MethodInfo MoveCenterMethod; + internal void MoveCenter() + { + MoveCenterMethod.Invoke(actualServoMechanism, new System.Object[] { }); + } + + private MethodInfo MoveNextPresetMethod; + internal void MoveNextPreset() + { + MoveNextPresetMethod.Invoke(actualServoMechanism, new System.Object[] { }); + } + + private MethodInfo MovePrevPresetMethod; + internal void MovePrevPreset() + { + MovePrevPresetMethod.Invoke(actualServoMechanism, new System.Object[] { }); + } + + private MethodInfo MoveToMethod; + internal void MoveTo(float position, float speed) + { + MoveToMethod.Invoke(actualServoMechanism, new System.Object[] {position, speed }); + } + + private MethodInfo StopMethod; + internal void Stop() + { + StopMethod.Invoke(actualServoMechanism, new System.Object[] { }); + } + + public override bool Equals(object o) + { + var servo = o as IRServo; + return servo != null && actualServo.Equals(servo.actualServo); + } + + public override int GetHashCode() + { + return (actualServo != null ? actualServo.GetHashCode() : 0); + } + + public static bool operator ==(IRServo left, IRServo right) + { + return Equals(left, right); + } + + public static bool operator !=(IRServo left, IRServo right) + { + return !Equals(left, right); + } + + protected bool Equals(IRServo other) + { + return Equals(actualServo, other.actualServo); + } + } + + public class IRServoGroupsList : List + { + + } + + public class IRServosList : List + { + + } + } + + #region Logging Stuff + /// + /// Some Structured logging to the debug file - ONLY RUNS WHEN DLL COMPILED IN DEBUG MODE + /// + /// Text to be printed - can be formatted as per String.format + /// Objects to feed into a String.format + [System.Diagnostics.Conditional("DEBUG")] + internal static void LogFormatted_DebugOnly(String Message, params Object[] strParams) + { + LogFormatted(Message, strParams); + } + + /// + /// Some Structured logging to the debug file + /// + /// Text to be printed - can be formatted as per String.format + /// Objects to feed into a String.format + internal static void LogFormatted(String Message, params Object[] strParams) + { + Message = String.Format(Message, strParams); + String strMessageLine = String.Format("{0},{2}-{3},{1}", + DateTime.Now, Message, System.Reflection.Assembly.GetExecutingAssembly().GetName().Name, + System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name); + UnityEngine.Debug.Log(strMessageLine); + } + #endregion + } +} \ No newline at end of file diff --git a/src/kOS/kOS.csproj b/src/kOS/kOS.csproj index d7b6a3d97..d754f85d1 100644 --- a/src/kOS/kOS.csproj +++ b/src/kOS/kOS.csproj @@ -54,6 +54,11 @@ + + + + + From 15af1849ebc7359d73dc316e7fc05e02add362c1 Mon Sep 17 00:00:00 2001 From: abenkovskii Date: Mon, 13 Apr 2015 00:37:16 +0300 Subject: [PATCH 360/446] Should solve #782 --- src/kOS/Suffixed/Part/PartValue.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kOS/Suffixed/Part/PartValue.cs b/src/kOS/Suffixed/Part/PartValue.cs index e53c59ddc..e7f37de12 100644 --- a/src/kOS/Suffixed/Part/PartValue.cs +++ b/src/kOS/Suffixed/Part/PartValue.cs @@ -34,7 +34,7 @@ private void PartInitializeSuffixes() AddSuffix("FUELCROSSFEED", new Suffix(() => Part.fuelCrossFeed)); AddSuffix("TITLE", new Suffix(() => Part.partInfo.title)); AddSuffix("STAGE", new Suffix(() => Part.inverseStage)); - AddSuffix("UID", new Suffix(() => Part.uid().ToString())); + AddSuffix("UID", new Suffix(() => Part.flightID.ToString)); AddSuffix("ROTATION", new Suffix(() => new Direction( Part.transform.rotation) )); AddSuffix("POSITION", new Suffix(() => new Vector( Part.transform.position - shared.Vessel.findWorldCenterOfMass() ))); AddSuffix("TAG", new SetSuffix(GetTagName, SetTagName)); From a3867ce2fb790075bfa7629a9d7389dff5785db8 Mon Sep 17 00:00:00 2001 From: abenkovskii Date: Mon, 13 Apr 2015 07:52:23 +0300 Subject: [PATCH 361/446] Update PartValue.cs --- src/kOS/Suffixed/Part/PartValue.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kOS/Suffixed/Part/PartValue.cs b/src/kOS/Suffixed/Part/PartValue.cs index e7f37de12..c721836af 100644 --- a/src/kOS/Suffixed/Part/PartValue.cs +++ b/src/kOS/Suffixed/Part/PartValue.cs @@ -34,7 +34,7 @@ private void PartInitializeSuffixes() AddSuffix("FUELCROSSFEED", new Suffix(() => Part.fuelCrossFeed)); AddSuffix("TITLE", new Suffix(() => Part.partInfo.title)); AddSuffix("STAGE", new Suffix(() => Part.inverseStage)); - AddSuffix("UID", new Suffix(() => Part.flightID.ToString)); + AddSuffix("UID", new Suffix(Part.flightID.ToString)); AddSuffix("ROTATION", new Suffix(() => new Direction( Part.transform.rotation) )); AddSuffix("POSITION", new Suffix(() => new Vector( Part.transform.position - shared.Vessel.findWorldCenterOfMass() ))); AddSuffix("TAG", new SetSuffix(GetTagName, SetTagName)); From ef79ac2dae0ec1011ca5d1bf50410ea8bd4021d9 Mon Sep 17 00:00:00 2001 From: Chris Woerz Date: Sun, 12 Apr 2015 23:03:48 -0600 Subject: [PATCH 362/446] bumped version and fixed build --- Resources/GameData/kOS/kOS.version | 4 ++-- src/kOS.Safe/Properties/AssemblyInfo.cs | 4 ++-- src/kOS/Core.cs | 2 +- src/kOS/Properties/AssemblyInfo.cs | 6 +++--- src/kOS/Suffixed/Part/PartValue.cs | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Resources/GameData/kOS/kOS.version b/Resources/GameData/kOS/kOS.version index 1be9bb437..9063fc145 100644 --- a/Resources/GameData/kOS/kOS.version +++ b/Resources/GameData/kOS/kOS.version @@ -10,8 +10,8 @@ }, "VERSION": { "MAJOR": 0, - "MINOR": 16, - "PATCH": 2 + "MINOR": 17, + "PATCH": 0 }, "KSP_VERSION": { "MAJOR": 0, diff --git a/src/kOS.Safe/Properties/AssemblyInfo.cs b/src/kOS.Safe/Properties/AssemblyInfo.cs index 5d640375d..779d43b9c 100644 --- a/src/kOS.Safe/Properties/AssemblyInfo.cs +++ b/src/kOS.Safe/Properties/AssemblyInfo.cs @@ -31,5 +31,5 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.1.2.0")] -[assembly: AssemblyFileVersion("1.1.2.0")] +[assembly: AssemblyVersion("1.2.0.0")] +[assembly: AssemblyFileVersion("1.2.0.0")] diff --git a/src/kOS/Core.cs b/src/kOS/Core.cs index d067389ab..681112fec 100644 --- a/src/kOS/Core.cs +++ b/src/kOS/Core.cs @@ -5,7 +5,7 @@ namespace kOS { public class Core : MonoBehaviour { - public static VersionInfo VersionInfo = new VersionInfo(0, 16, 2); + public static VersionInfo VersionInfo = new VersionInfo(0, 17, 0); public static Core Fetch; diff --git a/src/kOS/Properties/AssemblyInfo.cs b/src/kOS/Properties/AssemblyInfo.cs index 885e80501..5eed03dac 100644 --- a/src/kOS/Properties/AssemblyInfo.cs +++ b/src/kOS/Properties/AssemblyInfo.cs @@ -31,6 +31,6 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyFileVersion("0.16.2.0")] -[assembly: AssemblyVersion("0.16.2.0")] -[assembly: KSPAssembly("kOS", 0, 16)] +[assembly: AssemblyFileVersion("0.17.0.0")] +[assembly: AssemblyVersion("0.17.0.0")] +[assembly: KSPAssembly("kOS", 0, 17)] diff --git a/src/kOS/Suffixed/Part/PartValue.cs b/src/kOS/Suffixed/Part/PartValue.cs index e7f37de12..4bdc17f23 100644 --- a/src/kOS/Suffixed/Part/PartValue.cs +++ b/src/kOS/Suffixed/Part/PartValue.cs @@ -34,7 +34,7 @@ private void PartInitializeSuffixes() AddSuffix("FUELCROSSFEED", new Suffix(() => Part.fuelCrossFeed)); AddSuffix("TITLE", new Suffix(() => Part.partInfo.title)); AddSuffix("STAGE", new Suffix(() => Part.inverseStage)); - AddSuffix("UID", new Suffix(() => Part.flightID.ToString)); + AddSuffix("UID", new Suffix(() => Part.flightID.ToString())); AddSuffix("ROTATION", new Suffix(() => new Direction( Part.transform.rotation) )); AddSuffix("POSITION", new Suffix(() => new Vector( Part.transform.position - shared.Vessel.findWorldCenterOfMass() ))); AddSuffix("TAG", new SetSuffix(GetTagName, SetTagName)); From 968d633c545409448ba3c360ce18987285cd9708 Mon Sep 17 00:00:00 2001 From: ZiwKerman Date: Mon, 13 Apr 2015 11:49:11 +0100 Subject: [PATCH 363/446] Working Prototype --- .../AddOns/InfernalRobotics/IRFunctions.cs | 33 ++++++++++++------- src/kOS/AddOns/InfernalRobotics/IRHandler.cs | 2 +- 2 files changed, 23 insertions(+), 12 deletions(-) diff --git a/src/kOS/AddOns/InfernalRobotics/IRFunctions.cs b/src/kOS/AddOns/InfernalRobotics/IRFunctions.cs index 722ea0bd2..4e9018c6c 100644 --- a/src/kOS/AddOns/InfernalRobotics/IRFunctions.cs +++ b/src/kOS/AddOns/InfernalRobotics/IRFunctions.cs @@ -9,23 +9,23 @@ namespace kOS.AddOns.InfernalRobotics { [Function("IR_listServos")] - public class FunctionListServos : FunctionBase + public class FunctionIRListServos : FunctionBase { public override void Execute(SharedObjects shared) { - var list = new ListValue(); + var list = new ListValue(); if (!IRWrapper.APIReady) { - shared.Cpu.PushStack(list); + ReturnValue = list; //throw new KOSUnavailableAddonException("IR_listServos()", "Infernal Robotics"); return; } - IRWrapper.IRAPI.IRControlGroup controlGroup = (IRWrapper.IRAPI.IRControlGroup) shared.Cpu.PopValue(); - + var controlGroup = (IRWrapper.IRAPI.IRControlGroup) PopValueAssert(shared); + AssertArgBottomAndConsume(shared); if (controlGroup == null) { - shared.Cpu.PushStack(list); + ReturnValue = list; return; } @@ -36,31 +36,42 @@ public override void Execute(SharedObjects shared) list.Add(new IRServoWrapper(s, shared)); } - shared.Cpu.PushStack(list); + ReturnValue = list; } } [Function("IR_listControlGroups")] - public class FunctionListControlGroups : FunctionBase + public class FunctionIRListControlGroups : FunctionBase { public override void Execute(SharedObjects shared) { - var list = new ListValue(); + var list = new ListValue(); + + AssertArgBottomAndConsume(shared); + if (!IRWrapper.APIReady) { - shared.Cpu.PushStack(list); + SafeHouse.Logger.SuperVerbose ("IRAPI not ready."); + ReturnValue = list; //throw new KOSUnavailableAddonException("listControlGroups()", "Kerbal Alarm Clock"); return; } IRWrapper.IRAPI.IRServoGroupsList controlGroups = IRWrapper.IRController.ServoGroups; + if (controlGroups == null) + { + ReturnValue = list; + //throw new KOSUnavailableAddonException("listControlGroups()", "Kerbal Alarm Clock"); + return; + } + foreach (IRWrapper.IRAPI.IRControlGroup cg in controlGroups) { list.Add(new IRControlGroupWrapper(cg, shared)); } - shared.Cpu.PushStack(list); + ReturnValue = list; } } } \ No newline at end of file diff --git a/src/kOS/AddOns/InfernalRobotics/IRHandler.cs b/src/kOS/AddOns/InfernalRobotics/IRHandler.cs index cfed6bc96..09eae83b1 100644 --- a/src/kOS/AddOns/InfernalRobotics/IRHandler.cs +++ b/src/kOS/AddOns/InfernalRobotics/IRHandler.cs @@ -4,7 +4,7 @@ namespace kOS.AddOns.InfernalRobotics { [KSPAddon(KSPAddon.Startup.EveryScene, false)] - public class KACEventHandler : MonoBehaviour + public class IRHandler : MonoBehaviour { public void Start() { From a79fbe20c7c56a850775504d5cbc63c609b7ab89 Mon Sep 17 00:00:00 2001 From: ZiwKerman Date: Mon, 13 Apr 2015 14:59:10 +0100 Subject: [PATCH 364/446] Updated KAC integration functions with latest function changes. --- .../AddOns/KerbalAlarmClock/KACFunctions.cs | 29 ++++++++++--------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/src/kOS/AddOns/KerbalAlarmClock/KACFunctions.cs b/src/kOS/AddOns/KerbalAlarmClock/KACFunctions.cs index d57850750..bdf200c22 100644 --- a/src/kOS/AddOns/KerbalAlarmClock/KACFunctions.cs +++ b/src/kOS/AddOns/KerbalAlarmClock/KACFunctions.cs @@ -13,10 +13,11 @@ public class FunctionAddAlarm : FunctionBase { public override void Execute(SharedObjects shared) { - string alarmNotes = shared.Cpu.PopValue().ToString(); - string alarmName = shared.Cpu.PopValue().ToString(); - double alarmUT = GetDouble(shared.Cpu.PopValue()); - string alarmType = shared.Cpu.PopValue().ToString(); //alarm type is read-only, you cannot change it afterwards + string alarmNotes = PopValueAssert(shared).ToString(); + string alarmName = PopValueAssert(shared).ToString(); + double alarmUT = GetDouble(PopValueAssert(shared)); + string alarmType = PopValueAssert(shared).ToString(); //alarm type is read-only, you cannot change it afterwards + AssertArgBottomAndConsume(shared); if (KACWrapper.APIReady) { @@ -48,18 +49,18 @@ public override void Execute(SharedObjects shared) var result = new KACAlarmWrapper(a, shared); - shared.Cpu.PushStack(result); + ReturnValue = result; } else { - shared.Cpu.PushStack(string.Empty); + ReturnValue = string.Empty; SafeHouse.Logger.Log(string.Format("Failed creating KAC Alarm, UT={0}, Name={1}, Type= {2}", alarmUT, alarmName, alarmType)); } } else { //KAC integration not present. - shared.Cpu.PushStack(string.Empty); + ReturnValue = string.Empty; throw new KOSUnavailableAddonException("addAlarm()", "Kerbal Alarm Clock"); } } @@ -72,11 +73,12 @@ public override void Execute(SharedObjects shared) { var list = new ListValue(); - string alarmTypes = shared.Cpu.PopValue().ToString(); + string alarmTypes = PopValueAssert(shared).ToString(); + AssertArgBottomAndConsume(shared); if (!KACWrapper.APIReady) { - shared.Cpu.PushStack(list); + ReturnValue = list; throw new KOSUnavailableAddonException("listAlarms()", "Kerbal Alarm Clock"); } @@ -94,7 +96,7 @@ public override void Execute(SharedObjects shared) if (alarmTypes.ToUpperInvariant() == "ALL" || alarm.AlarmTime.ToString() == alarmTypes) list.Add(new KACAlarmWrapper(alarm, shared)); } - shared.Cpu.PushStack(list); + ReturnValue = list; } } @@ -103,16 +105,17 @@ public class FunctionDeleteAlarm : FunctionBase { public override void Execute(SharedObjects shared) { - string alarmID = shared.Cpu.PopValue().ToString(); + string alarmID = PopValueAssert(shared).ToString(); + AssertArgBottomAndConsume(shared); if (KACWrapper.APIReady) { bool result = KACWrapper.KAC.DeleteAlarm(alarmID); - shared.Cpu.PushStack(result); + ReturnValue = result; } else { - shared.Cpu.PushStack(false); + ReturnValue = false; throw new KOSUnavailableAddonException("deleteAlarm()", "Kerbal Alarm Clock"); } } From aee5ff1acb1eb313d79e08b7c4b2d87f5122a5a6 Mon Sep 17 00:00:00 2001 From: Chris Woerz Date: Mon, 13 Apr 2015 11:45:00 -0600 Subject: [PATCH 365/446] fixes #786 --- src/kOS/Suffixed/FlightControl.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kOS/Suffixed/FlightControl.cs b/src/kOS/Suffixed/FlightControl.cs index 9ff6167a1..dc804f650 100644 --- a/src/kOS/Suffixed/FlightControl.cs +++ b/src/kOS/Suffixed/FlightControl.cs @@ -183,7 +183,7 @@ private void InitializeSuffixes() //OTHER AddSuffix(new[] { "BOUND" }, new SetSuffix(() => bound, value => bound = value)); - AddSuffix(new[] { "NEUTRAL" }, new Suffix>(() => neutral)); + AddSuffix(new[] { "NEUTRAL" }, new Suffix(() => neutral.Value)); } From 4443c65f66f64ca9897fc4bdebef81480556f129 Mon Sep 17 00:00:00 2001 From: Chris Woerz Date: Mon, 13 Apr 2015 15:34:30 -0600 Subject: [PATCH 366/446] extra strong clamps on timewarp. Fixes #674 Fixes #712 --- src/kOS/Binding/BindingsUniverse.cs | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/src/kOS/Binding/BindingsUniverse.cs b/src/kOS/Binding/BindingsUniverse.cs index fe06ddb0d..6a066694e 100644 --- a/src/kOS/Binding/BindingsUniverse.cs +++ b/src/kOS/Binding/BindingsUniverse.cs @@ -3,6 +3,7 @@ using kOS.Suffixed; using System; using System.Collections.Generic; +using UnityEngine; namespace kOS.Binding { @@ -19,7 +20,7 @@ public override void AddTo(SharedObjects shared) QuickSaveLoad.QuickSave(); return true; }); - + shared.BindingMgr.AddGetter("QUICKLOAD", () => { if (!HighLogic.CurrentGame.Parameters.Flight.CanQuickLoad) return false; @@ -37,7 +38,7 @@ public override void AddTo(SharedObjects shared) shared.BindingMgr.AddSetter("SAVETO", val => { - if (reservedSaveNames.Contains(val.ToString().ToLower())) return; + if (reservedSaveNames.Contains(val.ToString().ToLower())) return; Game game = HighLogic.CurrentGame.Updated(); game.startScene = GameScenes.FLIGHT; @@ -102,7 +103,17 @@ public override void AddTo(SharedObjects shared) int newRate; if (int.TryParse(val.ToString(), out newRate)) { - TimeWarp.SetRate(newRate, false); + switch (TimeWarp.WarpMode) + { + case TimeWarp.Modes.HIGH: + SetWarpRate(newRate, TimeWarp.fetch.warpRates.Length - 1); + break; + case TimeWarp.Modes.LOW: + SetWarpRate(newRate, TimeWarp.fetch.maxPhysicsRate_index); + break; + default: + throw new Exception(string.Format("WARPMODE '{0}' is unknown to kOS, please contact the devs", val)); + } } }); shared.BindingMgr.AddGetter("MAPVIEW", () => MapView.MapIsEnabled); @@ -125,5 +136,15 @@ public override void AddTo(SharedObjects shared) shared.BindingMgr.AddGetter("VERSION", () => Core.VersionInfo); } + + private static void SetWarpRate(int newRate, int maxRate) + { + var clampedValue = Mathf.Clamp(maxRate, 0, newRate); + if (clampedValue != maxRate) + { + SafeHouse.Logger.Log(string.Format("Clamped Timewarp rate. Was: {0} Is: {1}", clampedValue, maxRate)); + } + TimeWarp.SetRate(clampedValue, false); + } } } \ No newline at end of file From f446fe4dd35b4411623f285bf638bcefad7a61ac Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Mon, 13 Apr 2015 17:37:01 -0500 Subject: [PATCH 367/446] Resolves #750 - the global/local keyword issues. Also found a lot of bugs in how it dealt with local scoping and when and lock interactions in the compiler. --- kerboscript_tests/lib/lib_physics.ks | 14 + kerboscript_tests/lib/lib_pid.ks | 95 ++++ kerboscript_tests/lib/testlibpid.ks | 67 +++ .../user_functions/functest14.ks | 19 + .../user_functions/functest15.ks | 55 ++ .../user_functions/functest16.ks | 8 + .../user_functions/functest17.ks | 5 + .../user_functions/functest18.ks | 7 + .../user_functions/functest19.ks | 18 + .../user_functions/functest20.ks | 29 + .../user_functions/functest21-inner.ks | 10 + .../user_functions/functest21.ks | 15 + .../user_functions/functest21_inner.ks | 10 + .../user_functions/functest22.ks | 20 + src/kOS.Safe/Compilation/KS/Compiler.cs | 451 +++++++++++---- src/kOS.Safe/Compilation/KS/ParseTree.cs | 50 +- src/kOS.Safe/Compilation/KS/Parser.cs | 515 ++++++++++++------ src/kOS.Safe/Compilation/KS/Scanner.cs | 272 ++++----- src/kOS.Safe/Compilation/KS/UserFunction.cs | 62 ++- .../Compilation/KS/UserFunctionCollection.cs | 78 ++- src/kOS.Safe/Compilation/KS/kRISC.tpg | 31 +- src/kOS.Safe/Compilation/Opcode.cs | 39 +- src/kOS.Safe/Compilation/ProgramBuilder.cs | 2 +- src/kOS.Safe/Execution/ICpu.cs | 3 +- src/kOS.Safe/Utilities/Debug.cs | 29 + src/kOS/Execution/CPU.cs | 30 +- src/kOS/Utilities/Utils.cs | 28 - 27 files changed, 1490 insertions(+), 472 deletions(-) create mode 100644 kerboscript_tests/lib/lib_physics.ks create mode 100644 kerboscript_tests/lib/lib_pid.ks create mode 100644 kerboscript_tests/lib/testlibpid.ks create mode 100644 kerboscript_tests/user_functions/functest14.ks create mode 100644 kerboscript_tests/user_functions/functest15.ks create mode 100644 kerboscript_tests/user_functions/functest16.ks create mode 100644 kerboscript_tests/user_functions/functest17.ks create mode 100644 kerboscript_tests/user_functions/functest18.ks create mode 100644 kerboscript_tests/user_functions/functest19.ks create mode 100644 kerboscript_tests/user_functions/functest20.ks create mode 100644 kerboscript_tests/user_functions/functest21-inner.ks create mode 100644 kerboscript_tests/user_functions/functest21.ks create mode 100644 kerboscript_tests/user_functions/functest21_inner.ks create mode 100644 kerboscript_tests/user_functions/functest22.ks diff --git a/kerboscript_tests/lib/lib_physics.ks b/kerboscript_tests/lib/lib_physics.ks new file mode 100644 index 000000000..7f0ee3c84 --- /dev/null +++ b/kerboscript_tests/lib/lib_physics.ks @@ -0,0 +1,14 @@ +// A library of routines to help do basic physics calculations + +@LAZYGLOBAL off. + +// Return the gravity acceleration at SHIP's current location. +declare function g_here { + return constant():G * ((ship:body:mass)/((ship:altitude + body:radius)^2)). +}. + +// Return the force on SHIP due to gravity acceleration at SHIP's current location. +declare function Fg_here { + return ship:mass*g_here(). +}. + diff --git a/kerboscript_tests/lib/lib_pid.ks b/kerboscript_tests/lib/lib_pid.ks new file mode 100644 index 000000000..32fe10c2b --- /dev/null +++ b/kerboscript_tests/lib/lib_pid.ks @@ -0,0 +1,95 @@ +// A generic PID controller routine to be used by other scripts. +// This controller operates without being aware of the math +// to perform the integral or derivative operations. Instead +// you just keep updating it with the position information and +// it derives them from it as it goes. + +@LAZYGLOBAL off. + +// Make a list of pid tuning parameters Kp, Ki, Kd. +declare function pid_init { + parameter + Kp, // gain of position + Ki, // gain of integral + Kd. // gain of derivative + + local SeekP is 0. // desired value for P (will get set later). + local P is 0. // phenomenon P being affected. + local I is 0. // crude approximation of Integral of P. + local D is 0. // crude approximation of Derivative of P. + local oldT is -1. // (old time) start value flags the fact that it hasn't been calculated + local oldInput is 0. // previous return value of PID controller. + + // Because we don't have proper user structures in kOS (yet?) + // I'll store the pid tracking values in a list like so: + // + local pid_array is list(). + pid_array:add(Kp). // [0] + pid_array:add(Ki). // [1] + pid_array:add(Kd). // [2] + pid_array:add(SeekP). // [3] + pid_array:add(P). // [4] + pid_array:add(I). // [5] + pid_array:add(D). // [6] + pid_array:add(oldT). // [7] + pid_array:add(oldInput). // [8]. + + return pid_array. +}. + +// Given a list of the tuning params made with pid_init, and +// the desired value of the phenomenon, and the current value +// for the phenomenon, it will automatically return what you should +// set the controlling thing for that phenomenon to. +declare function pid_seek { + parameter + pid_array, // array built with pid_init, and updated with each call to me (pid_seek). + seekVal, // value we want. + curVal. // value we currently have. + + // We have no "static locals" so I'm doing a trick here. + // Since LIST()s are passed by ref instead of by value, + // I'm going to store the data needed between calls in the + // LIST(), so it gets persisted between calls of me. + + local Kp is pid_array[0]. + local Ki is pid_array[1]. + local Kd is pid_array[2]. + local oldS is pid_array[3]. + local oldP is pid_array[4]. + local oldI is pid_array[5]. + local oldD is pid_array[6]. + local oldT is pid_array[7]. // Old Time + local oldInput is pid_array[8]. // prev return value, just in case we have to do nothing and return it again. + + local P is seekVal - curVal. + local D is 0. // default if we do no work this time. + local I is 0. // default if we do no work this time. + local newInput is oldInput. // default if we do no work this time. + + local t is time:seconds. + local dT is t - oldT. + + if oldT < 0 { + // I have never been called yet - so don't trust any + // of the settings yet. + } else { + if dT = 0 { // Do nothing if no physics tick has passed from prev call to now. + set newInput to oldInput. + } else { + set D to (P - oldP)/dT. // crude fake derivative of P + set I to oldI + P*dT. // crude fake integral of P + set newInput to Kp*P + Ki*I + Kd*D. + }. + }. + + // remember old values for next time. + set pid_array[3] to seekVal. + set pid_array[4] to P. + set pid_array[5] to I. + set pid_array[6] to D. + set pid_array[7] to t. + set pid_array[8] to newInput. + + return newInput. +}. diff --git a/kerboscript_tests/lib/testlibpid.ks b/kerboscript_tests/lib/testlibpid.ks new file mode 100644 index 000000000..be9262771 --- /dev/null +++ b/kerboscript_tests/lib/testlibpid.ks @@ -0,0 +1,67 @@ +clearscreen. +set seekAlt to 95. +set done to false. +on ag9 { set done to true. }. + +print "A simple test of libpid.". +print "Does a hover script at " + seekAlt + "m AGL.". +print " ". +print " Try flying around with WASD while it hovers.". +print " (steering is unlocked. under your control.". +print " ". +print " Keys:". +print " Action Group 1 : lower hover altitude". +print " Action Group 2 : raise hover altitude". +print " LANDING LEGS : Deploy to exit script". +print " ". +print " Seek ALT_RADAR = ". +print " Cur ALT_RADAR = ". +print " ". +print " Throttle = ". + +// load the functions I'm using: +run lib_pid. + +on ag1 { set seekAlt to seekAlt - 1. preserve. }. +on ag2 { set seekAlt to seekAlt + 1. preserve. }. + +set ship:control:pilotmainthrottle to 0. + +// hit "stage" until there's an active engine: +until ship:availablethrust > 0 { + wait 0.5. + stage. +}. + +// Call to update the display of numbers: +declare function display_block { + declare parameter + startCol, startRow. // define where the block of text should be positioned + + print round(seekAlt,2) + "m " at (startCol,startRow). + print round(alt_radar,2) + "m " at (startCol,startRow+1). + print round(myth,3) + " " at (startCol,startRow+3). +}. + +// thOffset is how far off from midThrottle to be. +// It's the value I'll be letting the PID controller +// adjust for me. +set myTh to 0. + +lock throttle to myTh. + +set hoverPID to pid_init( 0.05, 0.01, 0.1 ). // Kp, Ki, Kd vals. + +gear on. gear off. // on then off because of the weird KSP 'have to hit g twice' bug. + +until gear { + set myTh to pid_seek( hoverPID, seekAlt, alt_radar ). + display_block(18,11). + wait 0.001. +}. + +set ship:control:pilotmainthrottle to throttle. +print "------------------------------". +print "Releasing control back to you.". +print "------------------------------". + diff --git a/kerboscript_tests/user_functions/functest14.ks b/kerboscript_tests/user_functions/functest14.ks new file mode 100644 index 000000000..bca832653 --- /dev/null +++ b/kerboscript_tests/user_functions/functest14.ks @@ -0,0 +1,19 @@ +// An example testing nesting a function inside a function +// when both of them end up having the same name: +// Proper nesting rules should mask the outer function +// with the inner function. + +declare function samename { + declare x to 1. + print "outer function samename() has x = " + x. + + declare function samename { + declare x to 2. + print "inner function samename() has x = " + x. + }. + + samename(). + +}. + +samename(). diff --git a/kerboscript_tests/user_functions/functest15.ks b/kerboscript_tests/user_functions/functest15.ks new file mode 100644 index 000000000..5f14c5198 --- /dev/null +++ b/kerboscript_tests/user_functions/functest15.ks @@ -0,0 +1,55 @@ +// Testing the use of syntax modifiers: + +set a to -1. +set b to -1. +set c to -1. +set d to -1. +set e to -1. +set f to -1. +set g to -1. +set h to -1. +set i to -1. +set j to -1. + +{ + declare a to 1. + declare b is 2. + declare local c to 3. + declare local d is 4. + declare global e to 5. + declare global f is 6. + global g to 7. + global h is 8. + local i is 9. + local j is 10. + + print "In the list below. you should see ". + print "[a] through [j] getting values 1 to 10:". + print "---------------------------------------". + print "in local scope, a = " + a. + print "in local scope, b = " + b. + print "in local scope, c = " + c. + print "in local scope, d = " + d. + print "in local scope, e = " + e. + print "in local scope, f = " + f. + print "in local scope, g = " + g. + print "in local scope, h = " + h. + print "in local scope, i = " + i. + print "in local scope, j = " + j. +} + +print "In the list below. you should see ". +print "that everything reverted to -1 except". +print "for e,f,g, and h, which were being globally". +print "edited, not locally edited". +print "---------------------------------------". +print "in global scope, a = " + a. +print "in global scope, b = " + b. +print "in global scope, c = " + c. +print "in global scope, d = " + d. +print "in global scope, e = " + e. +print "in global scope, f = " + f. +print "in global scope, g = " + g. +print "in global scope, h = " + h. +print "in global scope, i = " + i. +print "in global scope, j = " + j. diff --git a/kerboscript_tests/user_functions/functest16.ks b/kerboscript_tests/user_functions/functest16.ks new file mode 100644 index 000000000..7e2fe841f --- /dev/null +++ b/kerboscript_tests/user_functions/functest16.ks @@ -0,0 +1,8 @@ +// Testing the illegal use of modifiers. + +print "This should complain that you can't use global with function:". +declare global function foo { + print "hello". +}. + +foo(). diff --git a/kerboscript_tests/user_functions/functest17.ks b/kerboscript_tests/user_functions/functest17.ks new file mode 100644 index 000000000..dcc98f973 --- /dev/null +++ b/kerboscript_tests/user_functions/functest17.ks @@ -0,0 +1,5 @@ +// Testing the illegal use of modifiers. + +print "This should complain that you can't use global with parameter:". +declare global parameter foo. +print "I was passed " + foo. diff --git a/kerboscript_tests/user_functions/functest18.ks b/kerboscript_tests/user_functions/functest18.ks new file mode 100644 index 000000000..ea724dca3 --- /dev/null +++ b/kerboscript_tests/user_functions/functest18.ks @@ -0,0 +1,7 @@ +// Testing the illegal use of modifiers. + +@lazyglobal off. + +print "This should complain that you can't leave local or global implicit with @lazyglobal off". +declare foo is 1. // This should require local or global and be an error. +print "foo is " + foo. diff --git a/kerboscript_tests/user_functions/functest19.ks b/kerboscript_tests/user_functions/functest19.ks new file mode 100644 index 000000000..865b9412d --- /dev/null +++ b/kerboscript_tests/user_functions/functest19.ks @@ -0,0 +1,18 @@ +// Testing local locks. + + +lock xx to "global lock x". + +{ + global lock yy to "global lock y". + local lock zz to "local lock z". + + print "inside scope: xx = " + xx. + print "inside scope: yy = " + yy. + print "inside scope: zz = " + zz. +} + +print "outside scope: xx = " + xx. +print "outside scope: yy = " + yy. +print "next line should barf - zz undefined.". +print "outside scope: zz = " + zz. diff --git a/kerboscript_tests/user_functions/functest20.ks b/kerboscript_tests/user_functions/functest20.ks new file mode 100644 index 000000000..e56b8f0aa --- /dev/null +++ b/kerboscript_tests/user_functions/functest20.ks @@ -0,0 +1,29 @@ +// Testing local locks with repetition. + + +lock xx to "global lock x". + +{ + global lock yy to "global lock y". + local lock zz to "local lock z". + + print "inside scope part 1: xx = " + xx. + print "inside scope part 1: yy = " + yy. + print "inside scope part 1: zz = " + zz. + + // Now relocking the values to something new + global lock yy to "global lock y-part2". + local lock zz to "local lock z-part2". + + print "inside scope part 2: xx = " + xx. + print "inside scope part 2: yy = " + yy. + print "inside scope part 2: zz = " + zz. + +} + +lock xx to "global lock part 2". + +print "outside scope: xx = " + xx. +print "outside scope: yy = " + yy. +print "next line should barf - zz undefined.". +print "outside scope: zz = " + zz. diff --git a/kerboscript_tests/user_functions/functest21-inner.ks b/kerboscript_tests/user_functions/functest21-inner.ks new file mode 100644 index 000000000..aa11edba3 --- /dev/null +++ b/kerboscript_tests/user_functions/functest21-inner.ks @@ -0,0 +1,10 @@ +// this is supposed to be called by functest21. + + +// Nothing more than a program designed to ensure that +// an update tick must occur while it is running because +// it executes a lot of instructions: +set counter to 0. +until counter >= 5000 { + set counter to counter + 1. +}. diff --git a/kerboscript_tests/user_functions/functest21.ks b/kerboscript_tests/user_functions/functest21.ks new file mode 100644 index 000000000..a709001e1 --- /dev/null +++ b/kerboscript_tests/user_functions/functest21.ks @@ -0,0 +1,15 @@ +// Test a case where the same variable is used as both a lock +// and a set, but at two different scopes: + +lock x to 1. +lock y to x/3. +print "Testing that locks don't get broken when running ". +print " a long sub-program that outlasts an IPU boundary.". +print "This program runs a long time counting in its head.". +print "Expect it to take a few seconds.". +print "before: x is " + x. +lock steering to up. +lock throttle to y. // indirect levels of locks to get to a value of 0.3333. + +run functest21_inner. +print "If it got this far, then it worked.". diff --git a/kerboscript_tests/user_functions/functest21_inner.ks b/kerboscript_tests/user_functions/functest21_inner.ks new file mode 100644 index 000000000..aa11edba3 --- /dev/null +++ b/kerboscript_tests/user_functions/functest21_inner.ks @@ -0,0 +1,10 @@ +// this is supposed to be called by functest21. + + +// Nothing more than a program designed to ensure that +// an update tick must occur while it is running because +// it executes a lot of instructions: +set counter to 0. +until counter >= 5000 { + set counter to counter + 1. +}. diff --git a/kerboscript_tests/user_functions/functest22.ks b/kerboscript_tests/user_functions/functest22.ks new file mode 100644 index 000000000..84108a556 --- /dev/null +++ b/kerboscript_tests/user_functions/functest22.ks @@ -0,0 +1,20 @@ +// Testing the case of a WHEN trigger containing a lock statement. + +print "If this test operates properly, then". +print "you should see the script print '0' over ". +print "and over for 5 seconds, then start ". +print "printing the current time:seconds over ". +print "and over after that for another 5 ". +print "seconds.". + +lock t to 0. +set ut to time:seconds. +when time:seconds > ut + 5 then { + lock t to time:seconds. +} + +until time:seconds > ut + 10 { + print t. + wait 0.5. +} +print "done with test". diff --git a/src/kOS.Safe/Compilation/KS/Compiler.cs b/src/kOS.Safe/Compilation/KS/Compiler.cs index ec1acbcc0..28943eca3 100644 --- a/src/kOS.Safe/Compilation/KS/Compiler.cs +++ b/src/kOS.Safe/Compilation/KS/Compiler.cs @@ -27,6 +27,8 @@ class Compiler private bool needImplicitReturn; private bool nextBraceIsFunction; private bool allowLazyGlobal; + /// Used when you want to set the next opcode's label but there's many places the next AddOpcode call might happen in the code + private string forcedNextLabel; private Int16 braceNestLevel; private readonly List scopeStack = new List(); private readonly Dictionary scopeMap = new Dictionary(); @@ -40,6 +42,14 @@ class Compiler { "round|2", "round"} }; + private enum StorageModifier { + /// The storage will definitely be at the localmost scope. + LOCAL, + /// The storage will definitely be at the globalmost scope. + GLOBAL, + /// The storage will be whatever scope it happens to find the first hit, or global if not found. + LAZYGLOBAL + }; // Because the Compiler object can be re-used, with its Compile() // method called a second time, we can't rely on the constructor or C#'s rules about default // variable values to guarantee these are all set properly. They might be leftover values @@ -65,6 +75,7 @@ private void InitCompileFlags() braceNestLevel = 0; nextBraceIsFunction = false; allowLazyGlobal = true; + forcedNextLabel = String.Empty; scopeStack.Clear(); scopeMap.Clear(); programParameters.Clear(); @@ -101,7 +112,7 @@ public CodePart Compile(int startLineNum, ParseTree tree, Context context, Compi SafeHouse.Logger.Log(kosException.StackTrace); throw; // throw it up in addition to logging the stack trace, so the kOS terminal will also give the user some message. } - + return part; } @@ -159,7 +170,15 @@ private Opcode AddOpcode(Opcode opcode, string destinationLabel) private Opcode AddOpcode(Opcode opcode) { - return AddOpcode(opcode, string.Empty); + Opcode code = AddOpcode(opcode, string.Empty); + + if (! String.IsNullOrEmpty(forcedNextLabel)) + { + code.Label = forcedNextLabel; + forcedNextLabel = String.Empty; + } + + return code; } private string GetNextLabel(bool increment) @@ -193,13 +212,13 @@ private void IterateUserFunctions(ParseNode node, Action action) case TokenType.until_stmt: case TokenType.on_stmt: case TokenType.when_stmt: + case TokenType.declare_function_clause: foreach (ParseNode childNode in node.Nodes) IterateUserFunctions(childNode, action); break; // These are the statements we're searching for to work on here: // - case TokenType.lock_stmt: case TokenType.declare_stmt: // for DECLARE FUNCTION's // for catching functions nested inside functions, or locks nested inside functions: // Depth-first: Walk my children first, then iterate through me. Thus the functions nested inside @@ -230,6 +249,7 @@ private void PreProcessStatements(ParseNode node) case TokenType.if_stmt: case TokenType.until_stmt: case TokenType.for_stmt: + case TokenType.declare_function_clause: PreProcessChildNodes(node); break; case TokenType.on_stmt: @@ -279,7 +299,7 @@ private void PreProcessOnStatement(ParseNode node) PushTriggerRemoveName(triggerRemoveVarName); AddOpcode(new OpcodePush(triggerRemoveVarName)); AddOpcode(new OpcodePush(true)); - AddOpcode(new OpcodeStore()); + AddOpcode(new OpcodeStoreGlobal()); VisitNode(node.Nodes[2]); @@ -317,7 +337,7 @@ private void PreProcessWhenStatement(ParseNode node) PushTriggerRemoveName(triggerRemoveVarName); AddOpcode(new OpcodePush(triggerRemoveVarName)); AddOpcode(new OpcodePush(true)); - AddOpcode(new OpcodeStore()); + AddOpcode(new OpcodeStoreGlobal()); VisitNode(node.Nodes[3]); @@ -341,7 +361,7 @@ private void PreProcessWhenStatement(ParseNode node) /// private string ConcatenateNodes(ParseNode node) { - return string.Format("{0}{1}", context.NumCompilesSoFar, ConcatenateNodesRecurse(node)); + return string.Format("{0}{1}{2}", context.NumCompilesSoFar, GetContainingScopeId(node), ConcatenateNodesRecurse(node)); } private string ConcatenateNodesRecurse(ParseNode node) @@ -362,27 +382,70 @@ private void IdentifyUserFunctions(ParseNode node) return; string funcIdentifier; + StorageModifier storageType = GetStorageModifierFor(node); + ParseNode bodyNode; + + ParseNode lastSubNode = node.Nodes[node.Nodes.Count-1]; if (IsLockStatement(node)) - funcIdentifier = node.Nodes[1].Token.Text; + { + funcIdentifier = lastSubNode.Nodes[1].Token.Text; + bodyNode = lastSubNode.Nodes[3]; + } else if (IsDefineFunctionStatement(node)) - funcIdentifier = node.Nodes[2].Token.Text; + { + funcIdentifier = lastSubNode.Nodes[1].Token.Text; + bodyNode = lastSubNode.Nodes[2]; + } else return; // not one of the types of statement we're really meant to run IdentifyLocks on. - context.UserFunctions.GetUserFunction(funcIdentifier); + UserFunction userFuncObject = + context.UserFunctions.GetUserFunction(funcIdentifier, storageType == StorageModifier.GLOBAL ? (Int16)0 : GetContainingScopeId(node), node); + int expressionHash = ConcatenateNodes(bodyNode).GetHashCode(); + userFuncObject.GetUserFunctionOpcodes(expressionHash); + } + + /// + /// Walk up the parent chain finding the first instance of a + /// ParseNode for which a scope ID has been assigned to it, and + /// return that scope ID. Returns 0 (the global scope) when no + /// hit was found. + ///
    + /// That will usually be the containing instruction_block braces, + /// but might not be, if dealing with file scoping, or the + /// hidden extra scopes of FOR loops and so on. + ///
    + /// + /// + private Int16 GetContainingScopeId(ParseNode node) + { + ParseNode current = node; + while (current != null) + { + Scope hitScope; + if (scopeMap.TryGetValue(current, out hitScope)) + return hitScope.ScopeId; + current = current.Parent; + } + return (Int16)0; } private bool IsLockStatement(ParseNode node) { - return node.Nodes[0].Token.Type == TokenType.LOCK; + return + node.Token.Type == TokenType.declare_stmt && + node.Nodes[node.Nodes.Count-1].Token.Type == TokenType.declare_lock_clause; } private bool IsDefineFunctionStatement(ParseNode node) { - return - node.Nodes[0].Token.Type == TokenType.DECLARE && - ( (node.Nodes.Count > 1) && node.Nodes[1].Token.Type == TokenType.FUNCTION ) && - ( (node.Nodes.Count > 2) && node.Nodes[2].Token.Type == TokenType.IDENTIFIER ); + if (node.Nodes.Count > 0) + { + ParseNode lastSubNode = node.Nodes[node.Nodes.Count-1]; + if (lastSubNode.Token.Type == TokenType.declare_function_clause) + return true; + } + return false; } private bool IsInsideDefineFunctionStatement(ParseNode node) @@ -409,21 +472,27 @@ private void PreProcessUserFunctionStatement(ParseNode node) bool isLock = IsLockStatement(node); bool isDefFunc = IsDefineFunctionStatement(node); + StorageModifier storageType = GetStorageModifierFor(node); + + ParseNode lastSubNode = node.Nodes[node.Nodes.Count-1]; if (isLock) { - userFuncIdentifier = node.Nodes[1].Token.Text; // The IDENT of: LOCK IDENT TO EXPR. - bodyNode = node.Nodes[3]; // The EXPR of: LOCK IDENT TO EXPR. + userFuncIdentifier = lastSubNode.Nodes[1].Token.Text; // The IDENT of: LOCK IDENT TO EXPR. + bodyNode = lastSubNode.Nodes[3]; // The EXPR of: LOCK IDENT TO EXPR. } else if (isDefFunc) { - userFuncIdentifier = node.Nodes[2].Token.Text; // The IDENT of: DEFINE FUNCTION IDENT INSTRUCTION_BLOCK. - bodyNode = node.Nodes[3]; // The INSTRUCTION_BLOCK of: DEFINE FUNCTION IDENT INSTRUCTION_BLOCK. + userFuncIdentifier = lastSubNode.Nodes[1].Token.Text; // The IDENT of: DEFINE FUNCTION IDENT INSTRUCTION_BLOCK. + bodyNode = lastSubNode.Nodes[2]; // The INSTRUCTION_BLOCK of: DEFINE FUNCTION IDENT INSTRUCTION_BLOCK. } else return; // In principle this shouldn't have ever been called in this case. - UserFunction userFuncObject = context.UserFunctions.GetUserFunction(userFuncIdentifier); - int expressionHash = ConcatenateNodes(node.Nodes[3]).GetHashCode(); + UserFunction userFuncObject = context.UserFunctions.GetUserFunction( + userFuncIdentifier, + (storageType == StorageModifier.GLOBAL ? (Int16)0 : GetContainingScopeId(node)), + node ); + int expressionHash = ConcatenateNodes(bodyNode).GetHashCode(); needImplicitReturn = true; // Locks always need an implicit return. Functions might not if all paths have an explicit one. @@ -442,19 +511,19 @@ private void PreProcessUserFunctionStatement(ParseNode node) if (userFuncObject.IsSystemLock()) { - AddOpcode(new OpcodePush(userFuncObject.PointerIdentifier)); + AddOpcode(new OpcodePush(userFuncObject.ScopelessPointerIdentifier)); AddOpcode(new OpcodePushRelocateLater(null), userFuncObject.DefaultLabel); AddOpcode(new OpcodeStore()); // add trigger - string triggerIdentifier = "lock-" + userFuncObject.Identifier; + string triggerIdentifier = "lock-" + userFuncObject.ScopelessIdentifier; Trigger triggerObject = context.Triggers.GetTrigger(triggerIdentifier); short rememberLastLine = lastLine; lastLine = -1; // special flag telling the error handler that these opcodes came from the system itself, when reporting the error currentCodeSection = triggerObject.Code; - AddOpcode(new OpcodePush("$" + userFuncObject.Identifier)); + AddOpcode(new OpcodePush("$" + userFuncObject.ScopelessIdentifier)); AddOpcode(new OpcodePush(OpcodeCall.ARG_MARKER_STRING)); // need these for all locks now. - AddOpcode(new OpcodeCall(userFuncObject.PointerIdentifier)); + AddOpcode(new OpcodeCall(userFuncObject.ScopelessPointerIdentifier)); if (allowLazyGlobal) AddOpcode(new OpcodeStore()); else @@ -476,32 +545,35 @@ private void PreProcessUserFunctionStatement(ParseNode node) // build default dummy function to be used when this is a LOCK: currentCodeSection = userFuncObject.GetUserFunctionOpcodes(0); - AddOpcode(new OpcodePush("$" + userFuncObject.Identifier)).Label = userFuncObject.DefaultLabel; + AddOpcode(new OpcodePush("$" + userFuncObject.ScopelessIdentifier)).Label = userFuncObject.DefaultLabel; AddOpcode(new OpcodeReturn()); } // lock expression's or function body's code currentCodeSection = userFuncObject.GetUserFunctionOpcodes(expressionHash); - if (isLock) // locks need to behave as if they had braces even though they don't - so they get lexical scope ids for closure reasons: - BeginScope(node); - if (isDefFunc) - nextBraceIsFunction = true; + bool secondInstanceSameLock = currentCodeSection.Count > 0; + if (! secondInstanceSameLock) + { + forcedNextLabel = userFuncObject.GetUserFunctionLabel(expressionHash); - VisitNode(bodyNode); + if (isLock) // locks need to behave as if they had braces even though they don't - so they get lexical scope ids for closure reasons: + BeginScope(bodyNode); + if (isDefFunc) + nextBraceIsFunction = true; - if (isDefFunc) - nextBraceIsFunction = false; - if (isLock) // locks need to behave as if they had braces even though they don't - so they get lexical scope ids for closure reasons: - EndScope(node); + VisitNode(bodyNode); - if (needImplicitReturn) - { if (isDefFunc) - AddOpcode(new OpcodePush(0)); // Functions must push a dummy return val when making implicit returns. Locks already leave an expr atop the stack. - AddOpcode(new OpcodeReturn()); - } - if (isDefFunc) - { + nextBraceIsFunction = false; + if (isLock) // locks need to behave as if they had braces even though they don't - so they get lexical scope ids for closure reasons: + EndScope(bodyNode); + + if (needImplicitReturn) + { + if (isDefFunc) + AddOpcode(new OpcodePush(0)); // Functions must push a dummy return val when making implicit returns. Locks already leave an expr atop the stack. + AddOpcode(new OpcodeReturn()); + } userFuncObject.ScopeNode = GetContainingBlockNode(node); // This limits the scope of the function to the instruction_block the DEFINE was in. userFuncObject.IsFunction = true; } @@ -521,15 +593,16 @@ private ParseNode GetContainingBlockNode(ParseNode node) private void PreProcessProgramParameters(ParseNode node) { NodeStartHousekeeping(node); + ParseNode lastSubNode = node.Nodes[node.Nodes.Count-1]; // if the declaration is a parameter, // and this is NOT contained inside a DEFINE FUNCTION block and // is therefore a global program paramter (for the run statement): - if (node.Nodes[1].Token.Type == TokenType.PARAMETER && + if (lastSubNode.Token.Type == TokenType.declare_parameter_clause && (!(IsInsideDefineFunctionStatement(node)))) { - for (int index = 2; index < node.Nodes.Count; index += 2) + for (int index = 1; index < lastSubNode.Nodes.Count; index += 2) { - programParameters.Add(node.Nodes[index]); + programParameters.Add(lastSubNode.Nodes[index]); } } // If it's any other sort of Declare statement, do nothing and instead @@ -751,15 +824,23 @@ private void TraverseScopeBranch(ParseNode node) // List all the types of parse node that open a new variable scope here: // --------------------------------------------------------------------- case TokenType.for_stmt: // Here because it wraps the body inside an outer scope that holds the for-iterator variable. - case TokenType.lock_stmt: // here because the lock body needs a scope in order to work with closures. The scope remembers the lexical id. + case TokenType.declare_lock_clause: // here because the lock body needs a scope in order to work with closures. The scope remembers the lexical id. case TokenType.instruction_block: ++braceNestLevel; Int16 parentId = ( (scopeStack.Count == 0) ? (Int16)0 : scopeStack.Last() ); scopeStack.Add(++context.MaxScopeIdSoFar); - scopeMap[node] = new Scope(context.MaxScopeIdSoFar, parentId, braceNestLevel); + ParseNode mapNode = node; + if (node.Token.Type == TokenType.declare_lock_clause) + { + // use the expression of: LOCK foo TO expr EOI as the holder of the scope, + // not the lock statement itself. Thus the foo being locked is in the outer + // scope and only the expression is in a nested scope: + mapNode = node.Nodes[node.Nodes.Count - 2]; + } + scopeMap[mapNode] = new Scope(context.MaxScopeIdSoFar, parentId, braceNestLevel); - foreach (ParseNode childNode in node.Nodes) + foreach (ParseNode childNode in mapNode.Nodes) TraverseScopeBranch(childNode); --braceNestLevel; @@ -805,9 +886,6 @@ private void VisitNode(ParseNode node) case TokenType.until_stmt: VisitUntilStatement(node); break; - case TokenType.lock_stmt: - VisitLockStatement(node); - break; case TokenType.return_stmt: VisitReturnStatement(node); break; @@ -1271,10 +1349,10 @@ private void VisitSuffix(ParseNode node) if (nodeIndex == 0) { firstIdentifier = GetIdentifierText(suffixTerm); - if (context.UserFunctions.Contains(firstIdentifier) && !compilingSetDestination) + UserFunction userFuncObject = GetUserFunctionWithScopeWalk(firstIdentifier, node); + if (userFuncObject != null && !compilingSetDestination) { - UserFunction userFuncObject = context.UserFunctions.GetUserFunction(firstIdentifier); - firstIdentifier = userFuncObject.PointerIdentifier; + firstIdentifier = userFuncObject.ScopelessPointerIdentifier; isUserFunc = true; } } @@ -1457,9 +1535,15 @@ private void VisitIdentifier(ParseNode node) bool isVariable = (identifierIsVariable && !identifierIsSuffix); string prefix = isVariable ? "$" : String.Empty; string identifier = GetIdentifierText(node); - if (isVariable && context.UserFunctions.Contains(identifier)) + + // Special case when the identifier is known to be a lock. + // Note that this only works when the lock is defined in the SAME + // file. When one script calls another one, the compiler won't know + // that the identifier is a lock, and you'll have to use empty parens + // to make it a real function call like var(): + UserFunction userFuncObject = GetUserFunctionWithScopeWalk(identifier, node); + if (isVariable && userFuncObject != null) { - UserFunction userFuncObject = context.UserFunctions.GetUserFunction(identifier); if (compilingSetDestination) { UnlockIdentifier(userFuncObject); @@ -1467,7 +1551,7 @@ private void VisitIdentifier(ParseNode node) } else { - AddOpcode(new OpcodeCall(userFuncObject.PointerIdentifier)); + AddOpcode(new OpcodeCall(userFuncObject.ScopelessPointerIdentifier)); } } else @@ -1475,6 +1559,36 @@ private void VisitIdentifier(ParseNode node) AddOpcode(new OpcodePush(prefix + identifier)); } } + + /// + /// Get the User function with the given the identifier, performing a + /// scope walk from here up to the root of the parse tree until a hit + /// is seen. If none are seen, then return null. This can only "see" + /// the functions that are defined in this same compile, not ones from + /// other scripts this script ran. + /// + /// + /// + /// + private UserFunction GetUserFunctionWithScopeWalk(string identifier, ParseNode node) + { + ParseNode current = node; + while (current != null) + { + Scope nodeScope; + if (scopeMap.TryGetValue(current, out nodeScope)) + if (context.UserFunctions.Contains(identifier, nodeScope.ScopeId)) + return context.UserFunctions.GetUserFunction(identifier, nodeScope.ScopeId, current); + current = current.Parent; + } + + // One more try at global scope: + if (context.UserFunctions.Contains(identifier, 0)) + return context.UserFunctions.GetUserFunction(identifier, 0, node); + + // Okay give up then: + return null; + } private void VisitFileIdent(ParseNode node) { @@ -1787,9 +1901,22 @@ private void VisitInstructionBlock(ParseNode node) /// private void AddFunctionJumpVars(ParseNode node) { - // All the functions for which this scope is where they live: - IEnumerable theseFuncs = context.UserFunctions.GetUserFunctionList().Where(item => item.IsFunction && item.ScopeNode == node); - + // All the functions for which this scope is where they live, and this file is where they live: + IEnumerable theseFuncs = + context.UserFunctions.GetUserFunctionList().Where( + item => + item.IsFunction && // This might be redundant? + item.ScopeNode == node && // Preprocessing found this function here in this set of scope braces. + (node != null || context.UserFunctions.IsNew(item))); // If global, ensure it's not from a previously compiled script's global scope. + + // NOTE: IF WE EVER IMPLEMENT FILE SCOPING! + // ---------------------------------------- + // That last check above is needed because the "scope" of a global function in one script and + // a global function in another script are the same scope, since we don't nest files in their own scope. + // If we ever change the design to create file scoping, the lastmost check above can probably go away. + // + // That last check deliberately takes advantage of short-curcuiting to avoid the expense of IsNew() if it can. + foreach (UserFunction func in theseFuncs) { // Populate the LOCAL name with the function jump location. @@ -1803,52 +1930,55 @@ private void AddFunctionJumpVars(ParseNode node) // This is typical of an OOP langauge. The physical code is always static for all // methods and functions, and always has exactly one copy in memory whether there are // one, many, or zero "instances" of it present in scope at the moment. - AddOpcode(new OpcodePush(func.PointerIdentifier)); + AddOpcode(new OpcodePush(func.ScopelessPointerIdentifier)); AddOpcode(new OpcodePushRelocateLater(null), func.GetFuncLabel()); - if (node == null) // global scope, sO use a normal Store: + if (node == null) // global scope, so unconditionally use a normal Store: AddOpcode(new OpcodeStore()); // else - AddOpcode(new OpcodeStoreLocal()); // OpcodeStoreLOCAL to force a local var. OpcodeStore would follow up the nest to more global scopes. + { + StorageModifier whereToPut = GetStorageModifierFor(func.OriginalNode); + AddOpcode(CreateAppropriateStoreCode(whereToPut, true)); + } } } - private void VisitLockStatement(ParseNode node) + // This is no longer called directly from parse because it now is called from + // VisitDeclareStatement, which reads the storage modifier keywords and + // passes them on to here. + private void VisitLockStatement(ParseNode node, StorageModifier whereToStore) { NodeStartHousekeeping(node); string lockIdentifier = node.Nodes[1].Token.Text; int expressionHash = ConcatenateNodes(node.Nodes[3]).GetHashCode(); - UserFunction lockObject = context.UserFunctions.GetUserFunction(lockIdentifier); - - if (lockObject.IsInitialized()) - { - string functionLabel = lockObject.GetUserFunctionOpcodes(expressionHash)[0].Label; - // lock variable - AddOpcode(new OpcodePush(lockObject.PointerIdentifier)); - AddOpcode(new OpcodePushDelegateRelocateLater(null), functionLabel); - if (allowLazyGlobal) - AddOpcode(new OpcodeStore()); - else - AddOpcode(new OpcodeStoreExist()); - - if (lockObject.IsSystemLock()) + UserFunction lockObject = context.UserFunctions.GetUserFunction( + lockIdentifier, + whereToStore == StorageModifier.GLOBAL ? (Int16)0 : GetContainingScopeId(node), + node); + + string functionLabel = lockObject.GetUserFunctionLabel(expressionHash); + // lock variable + AddOpcode(new OpcodePush(lockObject.ScopelessPointerIdentifier)); + AddOpcode(new OpcodePushDelegateRelocateLater(null), functionLabel); + AddOpcode(CreateAppropriateStoreCode(whereToStore, allowLazyGlobal)); + + if (lockObject.IsSystemLock()) + { + // add update trigger + string triggerIdentifier = "lock-" + lockIdentifier; + if (context.Triggers.Contains(triggerIdentifier)) { - // add update trigger - string triggerIdentifier = "lock-" + lockIdentifier; - if (context.Triggers.Contains(triggerIdentifier)) - { - Trigger triggerObject = context.Triggers.GetTrigger(triggerIdentifier); - AddOpcode(new OpcodePushRelocateLater(null), triggerObject.GetFunctionLabel()); - AddOpcode(new OpcodeAddTrigger()); - } - - // enable this FlyByWire parameter - AddOpcode(new OpcodePush(OpcodeCall.ARG_MARKER_STRING)); - AddOpcode(new OpcodePush(lockIdentifier)); - AddOpcode(new OpcodePush(true)); - AddOpcode(new OpcodeCall("toggleflybywire()")); - // add a pop to clear out the dummy return value from toggleflybywire() - AddOpcode(new OpcodePop()); + Trigger triggerObject = context.Triggers.GetTrigger(triggerIdentifier); + AddOpcode(new OpcodePushRelocateLater(null), triggerObject.GetFunctionLabel()); + AddOpcode(new OpcodeAddTrigger()); } + + // enable this FlyByWire parameter + AddOpcode(new OpcodePush(OpcodeCall.ARG_MARKER_STRING)); + AddOpcode(new OpcodePush(lockIdentifier)); + AddOpcode(new OpcodePush(true)); + AddOpcode(new OpcodeCall("toggleflybywire()")); + // add a pop to clear out the dummy return value from toggleflybywire() + AddOpcode(new OpcodePop()); } } @@ -1865,7 +1995,7 @@ private void VisitUnlockStatement(ParseNode node) else { string lockIdentifier = node.Nodes[1].Token.Text; - UserFunction lockObject = context.UserFunctions.GetUserFunction(lockIdentifier); + UserFunction lockObject = context.UserFunctions.GetUserFunction(lockIdentifier, GetContainingScopeId(node), node); UnlockIdentifier(lockObject); } } @@ -1878,14 +2008,14 @@ private void UnlockIdentifier(UserFunction lockObject) { // disable this FlyByWire parameter AddOpcode(new OpcodePush(OpcodeCall.ARG_MARKER_STRING)); - AddOpcode(new OpcodePush(lockObject.Identifier)); + AddOpcode(new OpcodePush(lockObject.ScopelessIdentifier)); AddOpcode(new OpcodePush(false)); AddOpcode(new OpcodeCall("toggleflybywire()")); // add a pop to clear out the dummy return value from toggleflybywire() AddOpcode(new OpcodePop()); // remove update trigger - string triggerIdentifier = "lock-" + lockObject.Identifier; + string triggerIdentifier = "lock-" + lockObject.ScopelessIdentifier; if (context.Triggers.Contains(triggerIdentifier)) { Trigger triggerObject = context.Triggers.GetTrigger(triggerIdentifier); @@ -1896,7 +2026,7 @@ private void UnlockIdentifier(UserFunction lockObject) // unlock variable // Really, we should unlock a variable by unsetting it's pointer var so it's an error to use it: - AddOpcode(new OpcodePush(lockObject.PointerIdentifier)); + AddOpcode(new OpcodePush(lockObject.ScopelessPointerIdentifier)); AddOpcode(new OpcodePushRelocateLater(null), lockObject.DefaultLabel); if (allowLazyGlobal) AddOpcode(new OpcodeStore()); @@ -1963,14 +2093,19 @@ private void VisitWaitStatement(ParseNode node) private void VisitDeclareStatement(ParseNode node) { NodeStartHousekeeping(node); + ParseNode lastSubNode = node.Nodes[node.Nodes.Count-1]; + + StorageModifier whereToStore = GetStorageModifierFor(node); + // If the declare statement is of the form: - // DECLARE identifier TO expr. - if (node.Nodes.Count > 1 && node.Nodes[1].Token.Type == TokenType.IDENTIFIER) + // DECLARE [GLOBAL|LOCAL] identifier TO expr. + if (lastSubNode.Token.Type == TokenType.declare_identifier_clause) { - VisitNode(node.Nodes[1]); - VisitNode(node.Nodes[3]); - AddOpcode(new OpcodeStoreLocal()); + VisitNode(lastSubNode.Nodes[0]); + VisitNode(lastSubNode.Nodes[2]); + AddOpcode(CreateAppropriateStoreCode(whereToStore, true)); } + // If the declare statement is of the form: // DECLARE PARAMETER ident. // or @@ -1978,19 +2113,123 @@ private void VisitDeclareStatement(ParseNode node) // AND this is inside a function definition rather than being at the global script level. // (at the global script level a DEFINE PARAMETER statement is for RUN parameters, which // get handled differently.) - else if (node.Nodes.Count > 1 && node.Nodes[1].Token.Type == TokenType.PARAMETER && + else if (lastSubNode.Token.Type == TokenType.declare_parameter_clause && IsInsideDefineFunctionStatement(node)) { - for (int i = 2 ; i < node.Nodes.Count ; i += 2) + for (int i = 1 ; i < lastSubNode.Nodes.Count ; i += 2) { - VisitNode(node.Nodes[i]); + VisitNode(lastSubNode.Nodes[i]); AddOpcode(new OpcodeSwap()); - AddOpcode(new OpcodeStoreLocal()); + AddOpcode(CreateAppropriateStoreCode(whereToStore, true)); } } + + // If the declare statement is of the form: + // DECLARE [GLOBAL|LOCAL] LOCK FOO TO expr. + else if (lastSubNode.Token.Type == TokenType.declare_lock_clause) + { + VisitLockStatement(lastSubNode, whereToStore); + } + // Note: DECLARE FUNCTION is dealt with entirely during // PreprocessDeclareStatement, with nothing for VisitNode to do. } + + /// + /// Make the right sort of opcodestore-ish opcode for what storage + /// mode we're in. + /// + /// which sort of storage is this + /// true if store should make a lazyglobal, + /// false if it should not. NOTE that it should always be true when + /// doing DECLARE operations and only vary when doing SET operations. + /// the new opcode you should add + private Opcode CreateAppropriateStoreCode(StorageModifier kind, bool lazyGlobal) + { + switch (kind) + { + case StorageModifier.LOCAL: + return new OpcodeStoreLocal(); + case StorageModifier.GLOBAL: + return new OpcodeStoreGlobal(); + default: + if (lazyGlobal) + return AddOpcode(new OpcodeStore()); + else + return AddOpcode(new OpcodeStoreExist()); + } + } + + // Return the storage modifier enum to go with this declare or set statement. + // i.e. "global, local, any". + // Will throw a syntax error of the storage type is invalid for this + // variety of declare statement. + private StorageModifier GetStorageModifierFor(ParseNode node) + { + // The default case for anything not explicitly mentioned below. + // i.e. if you call this on a SET statement, you'll get this: + StorageModifier modifier = StorageModifier.LAZYGLOBAL; + + if (node.Nodes.Count == 0) // sanity check - really should never be called on terminal nodes like this. + return modifier; + + // It may look wierd to do this as a switch when there's only one condition and it + // looks like it should be an if. It's leaving room for expansion later if the need + // arises: + switch (node.Token.Type) + { + case TokenType.declare_stmt: + modifier = GetStorageModifierForDeclare(node); + break; + default: + break; + } + + return modifier; + } + + private StorageModifier GetStorageModifierForDeclare(ParseNode node) + { + ParseNode lastSubNode = node.Nodes[node.Nodes.Count-1]; + + // Default varies depending on which kind of statement it is. + // locks are default global while everything else is + // default local: + StorageModifier modifier = + (lastSubNode.Token.Type == TokenType.declare_lock_clause ? StorageModifier.GLOBAL : StorageModifier.LOCAL); + bool storageKeywordMissing = true; + + for (int i = 0 ; i < node.Nodes.Count ; ++i) + { + switch (node.Nodes[i].Token.Type) + { + case TokenType.GLOBAL: + modifier = StorageModifier.GLOBAL; + storageKeywordMissing = false; + break; + case TokenType.LOCAL: + modifier = StorageModifier.LOCAL; + storageKeywordMissing = false; + break; + default: + break; + } + } + if (storageKeywordMissing && + lastSubNode.Token.Type == TokenType.declare_identifier_clause && + !allowLazyGlobal) + { + throw new KOSCommandInvalidHere("a bare DECLARE identifier, without a GLOBAL or LOCAL keyword", + "in an identifier initialization while under a @LAZYGLOBAL OFF directive", + "in a file where the default @LAZYGLOBAL behavior is on"); + } + if (modifier == StorageModifier.GLOBAL && lastSubNode.Token.Type == TokenType.declare_function_clause) + throw new KOSCommandInvalidHere("GLOBAL", "in a function declaration", "in a variable declaration"); + if (modifier == StorageModifier.GLOBAL && lastSubNode.Token.Type == TokenType.declare_parameter_clause) + throw new KOSCommandInvalidHere("GLOBAL", "in a parameter declaration", "in a variable declaration"); + + return modifier; + } private void VisitToggleStatement(ParseNode node) { diff --git a/src/kOS.Safe/Compilation/KS/ParseTree.cs b/src/kOS.Safe/Compilation/KS/ParseTree.cs index 299479c65..68eee8f0f 100644 --- a/src/kOS.Safe/Compilation/KS/ParseTree.cs +++ b/src/kOS.Safe/Compilation/KS/ParseTree.cs @@ -202,9 +202,6 @@ internal object Eval(ParseTree tree, params object[] paramlist) case TokenType.until_stmt: Value = Evaluntil_stmt(tree, paramlist); break; - case TokenType.lock_stmt: - Value = Evallock_stmt(tree, paramlist); - break; case TokenType.unlock_stmt: Value = Evalunlock_stmt(tree, paramlist); break; @@ -250,6 +247,18 @@ internal object Eval(ParseTree tree, params object[] paramlist) case TokenType.preserve_stmt: Value = Evalpreserve_stmt(tree, paramlist); break; + case TokenType.declare_identifier_clause: + Value = Evaldeclare_identifier_clause(tree, paramlist); + break; + case TokenType.declare_parameter_clause: + Value = Evaldeclare_parameter_clause(tree, paramlist); + break; + case TokenType.declare_function_clause: + Value = Evaldeclare_function_clause(tree, paramlist); + break; + case TokenType.declare_lock_clause: + Value = Evaldeclare_lock_clause(tree, paramlist); + break; case TokenType.declare_stmt: Value = Evaldeclare_stmt(tree, paramlist); break; @@ -420,13 +429,6 @@ protected virtual object Evaluntil_stmt(ParseTree tree, params object[] paramlis return null; } - protected virtual object Evallock_stmt(ParseTree tree, params object[] paramlist) - { - foreach (var node in Nodes) - node.Eval(tree, paramlist); - return null; - } - protected virtual object Evalunlock_stmt(ParseTree tree, params object[] paramlist) { foreach (var node in Nodes) @@ -532,6 +534,34 @@ protected virtual object Evalpreserve_stmt(ParseTree tree, params object[] param return null; } + protected virtual object Evaldeclare_identifier_clause(ParseTree tree, params object[] paramlist) + { + foreach (var node in Nodes) + node.Eval(tree, paramlist); + return null; + } + + protected virtual object Evaldeclare_parameter_clause(ParseTree tree, params object[] paramlist) + { + foreach (var node in Nodes) + node.Eval(tree, paramlist); + return null; + } + + protected virtual object Evaldeclare_function_clause(ParseTree tree, params object[] paramlist) + { + foreach (var node in Nodes) + node.Eval(tree, paramlist); + return null; + } + + protected virtual object Evaldeclare_lock_clause(ParseTree tree, params object[] paramlist) + { + foreach (var node in Nodes) + node.Eval(tree, paramlist); + return null; + } + protected virtual object Evaldeclare_stmt(ParseTree tree, params object[] paramlist) { foreach (var node in Nodes) diff --git a/src/kOS.Safe/Compilation/KS/Parser.cs b/src/kOS.Safe/Compilation/KS/Parser.cs index 088843e5c..a813113f9 100644 --- a/src/kOS.Safe/Compilation/KS/Parser.cs +++ b/src/kOS.Safe/Compilation/KS/Parser.cs @@ -47,11 +47,10 @@ private void ParseStart(ParseNode parent) - tok = scanner.LookAhead(TokenType.SET, TokenType.IF, TokenType.UNTIL, TokenType.LOCK, TokenType.UNLOCK, TokenType.PRINT, TokenType.ON, TokenType.TOGGLE, TokenType.WAIT, TokenType.WHEN, TokenType.STAGE, TokenType.CLEARSCREEN, TokenType.ADD, TokenType.REMOVE, TokenType.LOG, TokenType.BREAK, TokenType.PRESERVE, TokenType.DECLARE, TokenType.RETURN, TokenType.SWITCH, TokenType.COPY, TokenType.RENAME, TokenType.DELETE, TokenType.EDIT, TokenType.RUN, TokenType.COMPILE, TokenType.LIST, TokenType.REBOOT, TokenType.SHUTDOWN, TokenType.FOR, TokenType.UNSET, TokenType.BATCH, TokenType.DEPLOY, TokenType.CURLYOPEN, TokenType.INTEGER, TokenType.DOUBLE, TokenType.TRUEFALSE, TokenType.IDENTIFIER, TokenType.FILEIDENT, TokenType.BRACKETOPEN, TokenType.STRING, TokenType.ATSIGN); + tok = scanner.LookAhead(TokenType.SET, TokenType.IF, TokenType.UNTIL, TokenType.UNLOCK, TokenType.PRINT, TokenType.ON, TokenType.TOGGLE, TokenType.WAIT, TokenType.WHEN, TokenType.STAGE, TokenType.CLEARSCREEN, TokenType.ADD, TokenType.REMOVE, TokenType.LOG, TokenType.BREAK, TokenType.PRESERVE, TokenType.PARAMETER, TokenType.FUNCTION, TokenType.LOCK, TokenType.DECLARE, TokenType.LOCAL, TokenType.GLOBAL, TokenType.RETURN, TokenType.SWITCH, TokenType.COPY, TokenType.RENAME, TokenType.DELETE, TokenType.EDIT, TokenType.RUN, TokenType.COMPILE, TokenType.LIST, TokenType.REBOOT, TokenType.SHUTDOWN, TokenType.FOR, TokenType.UNSET, TokenType.BATCH, TokenType.DEPLOY, TokenType.CURLYOPEN, TokenType.INTEGER, TokenType.DOUBLE, TokenType.TRUEFALSE, TokenType.IDENTIFIER, TokenType.FILEIDENT, TokenType.BRACKETOPEN, TokenType.STRING, TokenType.ATSIGN); while (tok.Type == TokenType.SET || tok.Type == TokenType.IF || tok.Type == TokenType.UNTIL - || tok.Type == TokenType.LOCK || tok.Type == TokenType.UNLOCK || tok.Type == TokenType.PRINT || tok.Type == TokenType.ON @@ -65,7 +64,12 @@ private void ParseStart(ParseNode parent) || tok.Type == TokenType.LOG || tok.Type == TokenType.BREAK || tok.Type == TokenType.PRESERVE + || tok.Type == TokenType.PARAMETER + || tok.Type == TokenType.FUNCTION + || tok.Type == TokenType.LOCK || tok.Type == TokenType.DECLARE + || tok.Type == TokenType.LOCAL + || tok.Type == TokenType.GLOBAL || tok.Type == TokenType.RETURN || tok.Type == TokenType.SWITCH || tok.Type == TokenType.COPY @@ -92,7 +96,7 @@ private void ParseStart(ParseNode parent) || tok.Type == TokenType.ATSIGN) { Parseinstruction(node); - tok = scanner.LookAhead(TokenType.SET, TokenType.IF, TokenType.UNTIL, TokenType.LOCK, TokenType.UNLOCK, TokenType.PRINT, TokenType.ON, TokenType.TOGGLE, TokenType.WAIT, TokenType.WHEN, TokenType.STAGE, TokenType.CLEARSCREEN, TokenType.ADD, TokenType.REMOVE, TokenType.LOG, TokenType.BREAK, TokenType.PRESERVE, TokenType.DECLARE, TokenType.RETURN, TokenType.SWITCH, TokenType.COPY, TokenType.RENAME, TokenType.DELETE, TokenType.EDIT, TokenType.RUN, TokenType.COMPILE, TokenType.LIST, TokenType.REBOOT, TokenType.SHUTDOWN, TokenType.FOR, TokenType.UNSET, TokenType.BATCH, TokenType.DEPLOY, TokenType.CURLYOPEN, TokenType.INTEGER, TokenType.DOUBLE, TokenType.TRUEFALSE, TokenType.IDENTIFIER, TokenType.FILEIDENT, TokenType.BRACKETOPEN, TokenType.STRING, TokenType.ATSIGN); + tok = scanner.LookAhead(TokenType.SET, TokenType.IF, TokenType.UNTIL, TokenType.UNLOCK, TokenType.PRINT, TokenType.ON, TokenType.TOGGLE, TokenType.WAIT, TokenType.WHEN, TokenType.STAGE, TokenType.CLEARSCREEN, TokenType.ADD, TokenType.REMOVE, TokenType.LOG, TokenType.BREAK, TokenType.PRESERVE, TokenType.PARAMETER, TokenType.FUNCTION, TokenType.LOCK, TokenType.DECLARE, TokenType.LOCAL, TokenType.GLOBAL, TokenType.RETURN, TokenType.SWITCH, TokenType.COPY, TokenType.RENAME, TokenType.DELETE, TokenType.EDIT, TokenType.RUN, TokenType.COMPILE, TokenType.LIST, TokenType.REBOOT, TokenType.SHUTDOWN, TokenType.FOR, TokenType.UNSET, TokenType.BATCH, TokenType.DEPLOY, TokenType.CURLYOPEN, TokenType.INTEGER, TokenType.DOUBLE, TokenType.TRUEFALSE, TokenType.IDENTIFIER, TokenType.FILEIDENT, TokenType.BRACKETOPEN, TokenType.STRING, TokenType.ATSIGN); } @@ -127,11 +131,10 @@ private void Parseinstruction_block(ParseNode parent) } - tok = scanner.LookAhead(TokenType.SET, TokenType.IF, TokenType.UNTIL, TokenType.LOCK, TokenType.UNLOCK, TokenType.PRINT, TokenType.ON, TokenType.TOGGLE, TokenType.WAIT, TokenType.WHEN, TokenType.STAGE, TokenType.CLEARSCREEN, TokenType.ADD, TokenType.REMOVE, TokenType.LOG, TokenType.BREAK, TokenType.PRESERVE, TokenType.DECLARE, TokenType.RETURN, TokenType.SWITCH, TokenType.COPY, TokenType.RENAME, TokenType.DELETE, TokenType.EDIT, TokenType.RUN, TokenType.COMPILE, TokenType.LIST, TokenType.REBOOT, TokenType.SHUTDOWN, TokenType.FOR, TokenType.UNSET, TokenType.BATCH, TokenType.DEPLOY, TokenType.CURLYOPEN, TokenType.INTEGER, TokenType.DOUBLE, TokenType.TRUEFALSE, TokenType.IDENTIFIER, TokenType.FILEIDENT, TokenType.BRACKETOPEN, TokenType.STRING, TokenType.ATSIGN); + tok = scanner.LookAhead(TokenType.SET, TokenType.IF, TokenType.UNTIL, TokenType.UNLOCK, TokenType.PRINT, TokenType.ON, TokenType.TOGGLE, TokenType.WAIT, TokenType.WHEN, TokenType.STAGE, TokenType.CLEARSCREEN, TokenType.ADD, TokenType.REMOVE, TokenType.LOG, TokenType.BREAK, TokenType.PRESERVE, TokenType.PARAMETER, TokenType.FUNCTION, TokenType.LOCK, TokenType.DECLARE, TokenType.LOCAL, TokenType.GLOBAL, TokenType.RETURN, TokenType.SWITCH, TokenType.COPY, TokenType.RENAME, TokenType.DELETE, TokenType.EDIT, TokenType.RUN, TokenType.COMPILE, TokenType.LIST, TokenType.REBOOT, TokenType.SHUTDOWN, TokenType.FOR, TokenType.UNSET, TokenType.BATCH, TokenType.DEPLOY, TokenType.CURLYOPEN, TokenType.INTEGER, TokenType.DOUBLE, TokenType.TRUEFALSE, TokenType.IDENTIFIER, TokenType.FILEIDENT, TokenType.BRACKETOPEN, TokenType.STRING, TokenType.ATSIGN); while (tok.Type == TokenType.SET || tok.Type == TokenType.IF || tok.Type == TokenType.UNTIL - || tok.Type == TokenType.LOCK || tok.Type == TokenType.UNLOCK || tok.Type == TokenType.PRINT || tok.Type == TokenType.ON @@ -145,7 +148,12 @@ private void Parseinstruction_block(ParseNode parent) || tok.Type == TokenType.LOG || tok.Type == TokenType.BREAK || tok.Type == TokenType.PRESERVE + || tok.Type == TokenType.PARAMETER + || tok.Type == TokenType.FUNCTION + || tok.Type == TokenType.LOCK || tok.Type == TokenType.DECLARE + || tok.Type == TokenType.LOCAL + || tok.Type == TokenType.GLOBAL || tok.Type == TokenType.RETURN || tok.Type == TokenType.SWITCH || tok.Type == TokenType.COPY @@ -172,7 +180,7 @@ private void Parseinstruction_block(ParseNode parent) || tok.Type == TokenType.ATSIGN) { Parseinstruction(node); - tok = scanner.LookAhead(TokenType.SET, TokenType.IF, TokenType.UNTIL, TokenType.LOCK, TokenType.UNLOCK, TokenType.PRINT, TokenType.ON, TokenType.TOGGLE, TokenType.WAIT, TokenType.WHEN, TokenType.STAGE, TokenType.CLEARSCREEN, TokenType.ADD, TokenType.REMOVE, TokenType.LOG, TokenType.BREAK, TokenType.PRESERVE, TokenType.DECLARE, TokenType.RETURN, TokenType.SWITCH, TokenType.COPY, TokenType.RENAME, TokenType.DELETE, TokenType.EDIT, TokenType.RUN, TokenType.COMPILE, TokenType.LIST, TokenType.REBOOT, TokenType.SHUTDOWN, TokenType.FOR, TokenType.UNSET, TokenType.BATCH, TokenType.DEPLOY, TokenType.CURLYOPEN, TokenType.INTEGER, TokenType.DOUBLE, TokenType.TRUEFALSE, TokenType.IDENTIFIER, TokenType.FILEIDENT, TokenType.BRACKETOPEN, TokenType.STRING, TokenType.ATSIGN); + tok = scanner.LookAhead(TokenType.SET, TokenType.IF, TokenType.UNTIL, TokenType.UNLOCK, TokenType.PRINT, TokenType.ON, TokenType.TOGGLE, TokenType.WAIT, TokenType.WHEN, TokenType.STAGE, TokenType.CLEARSCREEN, TokenType.ADD, TokenType.REMOVE, TokenType.LOG, TokenType.BREAK, TokenType.PRESERVE, TokenType.PARAMETER, TokenType.FUNCTION, TokenType.LOCK, TokenType.DECLARE, TokenType.LOCAL, TokenType.GLOBAL, TokenType.RETURN, TokenType.SWITCH, TokenType.COPY, TokenType.RENAME, TokenType.DELETE, TokenType.EDIT, TokenType.RUN, TokenType.COMPILE, TokenType.LIST, TokenType.REBOOT, TokenType.SHUTDOWN, TokenType.FOR, TokenType.UNSET, TokenType.BATCH, TokenType.DEPLOY, TokenType.CURLYOPEN, TokenType.INTEGER, TokenType.DOUBLE, TokenType.TRUEFALSE, TokenType.IDENTIFIER, TokenType.FILEIDENT, TokenType.BRACKETOPEN, TokenType.STRING, TokenType.ATSIGN); } @@ -209,7 +217,7 @@ private void Parseinstruction(ParseNode parent) ParseNode node = parent.CreateNode(scanner.GetToken(TokenType.instruction), "instruction"); parent.Nodes.Add(node); - tok = scanner.LookAhead(TokenType.SET, TokenType.IF, TokenType.UNTIL, TokenType.LOCK, TokenType.UNLOCK, TokenType.PRINT, TokenType.ON, TokenType.TOGGLE, TokenType.WAIT, TokenType.WHEN, TokenType.STAGE, TokenType.CLEARSCREEN, TokenType.ADD, TokenType.REMOVE, TokenType.LOG, TokenType.BREAK, TokenType.PRESERVE, TokenType.DECLARE, TokenType.RETURN, TokenType.SWITCH, TokenType.COPY, TokenType.RENAME, TokenType.DELETE, TokenType.EDIT, TokenType.RUN, TokenType.COMPILE, TokenType.LIST, TokenType.REBOOT, TokenType.SHUTDOWN, TokenType.FOR, TokenType.UNSET, TokenType.BATCH, TokenType.DEPLOY, TokenType.CURLYOPEN, TokenType.INTEGER, TokenType.DOUBLE, TokenType.TRUEFALSE, TokenType.IDENTIFIER, TokenType.FILEIDENT, TokenType.BRACKETOPEN, TokenType.STRING, TokenType.ATSIGN); + tok = scanner.LookAhead(TokenType.SET, TokenType.IF, TokenType.UNTIL, TokenType.UNLOCK, TokenType.PRINT, TokenType.ON, TokenType.TOGGLE, TokenType.WAIT, TokenType.WHEN, TokenType.STAGE, TokenType.CLEARSCREEN, TokenType.ADD, TokenType.REMOVE, TokenType.LOG, TokenType.BREAK, TokenType.PRESERVE, TokenType.PARAMETER, TokenType.FUNCTION, TokenType.LOCK, TokenType.DECLARE, TokenType.LOCAL, TokenType.GLOBAL, TokenType.RETURN, TokenType.SWITCH, TokenType.COPY, TokenType.RENAME, TokenType.DELETE, TokenType.EDIT, TokenType.RUN, TokenType.COMPILE, TokenType.LIST, TokenType.REBOOT, TokenType.SHUTDOWN, TokenType.FOR, TokenType.UNSET, TokenType.BATCH, TokenType.DEPLOY, TokenType.CURLYOPEN, TokenType.INTEGER, TokenType.DOUBLE, TokenType.TRUEFALSE, TokenType.IDENTIFIER, TokenType.FILEIDENT, TokenType.BRACKETOPEN, TokenType.STRING, TokenType.ATSIGN); switch (tok.Type) { case TokenType.SET: @@ -221,9 +229,6 @@ private void Parseinstruction(ParseNode parent) case TokenType.UNTIL: Parseuntil_stmt(node); break; - case TokenType.LOCK: - Parselock_stmt(node); - break; case TokenType.UNLOCK: Parseunlock_stmt(node); break; @@ -263,7 +268,12 @@ private void Parseinstruction(ParseNode parent) case TokenType.PRESERVE: Parsepreserve_stmt(node); break; + case TokenType.PARAMETER: + case TokenType.FUNCTION: + case TokenType.LOCK: case TokenType.DECLARE: + case TokenType.LOCAL: + case TokenType.GLOBAL: Parsedeclare_stmt(node); break; case TokenType.RETURN: @@ -538,60 +548,6 @@ private void Parseuntil_stmt(ParseNode parent) parent.Token.UpdateRange(node.Token); } - private void Parselock_stmt(ParseNode parent) - { - Token tok; - ParseNode n; - ParseNode node = parent.CreateNode(scanner.GetToken(TokenType.lock_stmt), "lock_stmt"); - parent.Nodes.Add(node); - - - - tok = scanner.Scan(TokenType.LOCK); - n = node.CreateNode(tok, tok.ToString() ); - node.Token.UpdateRange(tok); - node.Nodes.Add(n); - if (tok.Type != TokenType.LOCK) { - tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.LOCK.ToString(), 0x1001, tok)); - return; - } - - - tok = scanner.Scan(TokenType.IDENTIFIER); - n = node.CreateNode(tok, tok.ToString() ); - node.Token.UpdateRange(tok); - node.Nodes.Add(n); - if (tok.Type != TokenType.IDENTIFIER) { - tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.IDENTIFIER.ToString(), 0x1001, tok)); - return; - } - - - tok = scanner.Scan(TokenType.TO); - n = node.CreateNode(tok, tok.ToString() ); - node.Token.UpdateRange(tok); - node.Nodes.Add(n); - if (tok.Type != TokenType.TO) { - tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.TO.ToString(), 0x1001, tok)); - return; - } - - - Parseexpr(node); - - - tok = scanner.Scan(TokenType.EOI); - n = node.CreateNode(tok, tok.ToString() ); - node.Token.UpdateRange(tok); - node.Nodes.Add(n); - if (tok.Type != TokenType.EOI) { - tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.EOI.ToString(), 0x1001, tok)); - return; - } - - parent.Token.UpdateRange(node.Token); - } - private void Parseunlock_stmt(ParseNode parent) { Token tok; @@ -1216,161 +1172,366 @@ private void Parsepreserve_stmt(ParseNode parent) parent.Token.UpdateRange(node.Token); } - private void Parsedeclare_stmt(ParseNode parent) + private void Parsedeclare_identifier_clause(ParseNode parent) { Token tok; ParseNode n; - ParseNode node = parent.CreateNode(scanner.GetToken(TokenType.declare_stmt), "declare_stmt"); + ParseNode node = parent.CreateNode(scanner.GetToken(TokenType.declare_identifier_clause), "declare_identifier_clause"); parent.Nodes.Add(node); - tok = scanner.Scan(TokenType.DECLARE); + tok = scanner.Scan(TokenType.IDENTIFIER); n = node.CreateNode(tok, tok.ToString() ); node.Token.UpdateRange(tok); node.Nodes.Add(n); - if (tok.Type != TokenType.DECLARE) { - tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.DECLARE.ToString(), 0x1001, tok)); + if (tok.Type != TokenType.IDENTIFIER) { + tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.IDENTIFIER.ToString(), 0x1001, tok)); return; } - tok = scanner.LookAhead(TokenType.PARAMETER, TokenType.FUNCTION, TokenType.IDENTIFIER); + tok = scanner.LookAhead(TokenType.TO, TokenType.IS); switch (tok.Type) { - case TokenType.PARAMETER: - - - tok = scanner.Scan(TokenType.PARAMETER); + case TokenType.TO: + tok = scanner.Scan(TokenType.TO); n = node.CreateNode(tok, tok.ToString() ); node.Token.UpdateRange(tok); node.Nodes.Add(n); - if (tok.Type != TokenType.PARAMETER) { - tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.PARAMETER.ToString(), 0x1001, tok)); + if (tok.Type != TokenType.TO) { + tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.TO.ToString(), 0x1001, tok)); return; } - - - tok = scanner.Scan(TokenType.IDENTIFIER); + break; + case TokenType.IS: + tok = scanner.Scan(TokenType.IS); n = node.CreateNode(tok, tok.ToString() ); node.Token.UpdateRange(tok); node.Nodes.Add(n); - if (tok.Type != TokenType.IDENTIFIER) { - tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.IDENTIFIER.ToString(), 0x1001, tok)); + if (tok.Type != TokenType.IS) { + tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.IS.ToString(), 0x1001, tok)); return; } + break; + default: + tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found.", 0x0002, tok)); + break; + } - - tok = scanner.LookAhead(TokenType.COMMA); - while (tok.Type == TokenType.COMMA) - { + + Parseexpr(node); - - tok = scanner.Scan(TokenType.COMMA); - n = node.CreateNode(tok, tok.ToString() ); - node.Token.UpdateRange(tok); - node.Nodes.Add(n); - if (tok.Type != TokenType.COMMA) { - tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.COMMA.ToString(), 0x1001, tok)); - return; - } + + tok = scanner.Scan(TokenType.EOI); + n = node.CreateNode(tok, tok.ToString() ); + node.Token.UpdateRange(tok); + node.Nodes.Add(n); + if (tok.Type != TokenType.EOI) { + tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.EOI.ToString(), 0x1001, tok)); + return; + } - - tok = scanner.Scan(TokenType.IDENTIFIER); - n = node.CreateNode(tok, tok.ToString() ); - node.Token.UpdateRange(tok); - node.Nodes.Add(n); - if (tok.Type != TokenType.IDENTIFIER) { - tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.IDENTIFIER.ToString(), 0x1001, tok)); - return; - } - tok = scanner.LookAhead(TokenType.COMMA); - } + parent.Token.UpdateRange(node.Token); + } - - tok = scanner.Scan(TokenType.EOI); - n = node.CreateNode(tok, tok.ToString() ); - node.Token.UpdateRange(tok); - node.Nodes.Add(n); - if (tok.Type != TokenType.EOI) { - tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.EOI.ToString(), 0x1001, tok)); - return; - } - break; - case TokenType.FUNCTION: + private void Parsedeclare_parameter_clause(ParseNode parent) + { + Token tok; + ParseNode n; + ParseNode node = parent.CreateNode(scanner.GetToken(TokenType.declare_parameter_clause), "declare_parameter_clause"); + parent.Nodes.Add(node); - - tok = scanner.Scan(TokenType.FUNCTION); - n = node.CreateNode(tok, tok.ToString() ); - node.Token.UpdateRange(tok); - node.Nodes.Add(n); - if (tok.Type != TokenType.FUNCTION) { - tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.FUNCTION.ToString(), 0x1001, tok)); - return; - } - - tok = scanner.Scan(TokenType.IDENTIFIER); - n = node.CreateNode(tok, tok.ToString() ); - node.Token.UpdateRange(tok); - node.Nodes.Add(n); - if (tok.Type != TokenType.IDENTIFIER) { - tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.IDENTIFIER.ToString(), 0x1001, tok)); - return; - } + + tok = scanner.Scan(TokenType.PARAMETER); + n = node.CreateNode(tok, tok.ToString() ); + node.Token.UpdateRange(tok); + node.Nodes.Add(n); + if (tok.Type != TokenType.PARAMETER) { + tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.PARAMETER.ToString(), 0x1001, tok)); + return; + } - - Parseinstruction_block(node); + + tok = scanner.Scan(TokenType.IDENTIFIER); + n = node.CreateNode(tok, tok.ToString() ); + node.Token.UpdateRange(tok); + node.Nodes.Add(n); + if (tok.Type != TokenType.IDENTIFIER) { + tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.IDENTIFIER.ToString(), 0x1001, tok)); + return; + } - - tok = scanner.LookAhead(TokenType.EOI); - if (tok.Type == TokenType.EOI) - { - tok = scanner.Scan(TokenType.EOI); - n = node.CreateNode(tok, tok.ToString() ); - node.Token.UpdateRange(tok); - node.Nodes.Add(n); - if (tok.Type != TokenType.EOI) { - tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.EOI.ToString(), 0x1001, tok)); - return; - } - } + + tok = scanner.LookAhead(TokenType.COMMA); + while (tok.Type == TokenType.COMMA) + { + + + tok = scanner.Scan(TokenType.COMMA); + n = node.CreateNode(tok, tok.ToString() ); + node.Token.UpdateRange(tok); + node.Nodes.Add(n); + if (tok.Type != TokenType.COMMA) { + tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.COMMA.ToString(), 0x1001, tok)); + return; + } + + + tok = scanner.Scan(TokenType.IDENTIFIER); + n = node.CreateNode(tok, tok.ToString() ); + node.Token.UpdateRange(tok); + node.Nodes.Add(n); + if (tok.Type != TokenType.IDENTIFIER) { + tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.IDENTIFIER.ToString(), 0x1001, tok)); + return; + } + tok = scanner.LookAhead(TokenType.COMMA); + } + + + tok = scanner.Scan(TokenType.EOI); + n = node.CreateNode(tok, tok.ToString() ); + node.Token.UpdateRange(tok); + node.Nodes.Add(n); + if (tok.Type != TokenType.EOI) { + tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.EOI.ToString(), 0x1001, tok)); + return; + } + + parent.Token.UpdateRange(node.Token); + } + + private void Parsedeclare_function_clause(ParseNode parent) + { + Token tok; + ParseNode n; + ParseNode node = parent.CreateNode(scanner.GetToken(TokenType.declare_function_clause), "declare_function_clause"); + parent.Nodes.Add(node); + + + + tok = scanner.Scan(TokenType.FUNCTION); + n = node.CreateNode(tok, tok.ToString() ); + node.Token.UpdateRange(tok); + node.Nodes.Add(n); + if (tok.Type != TokenType.FUNCTION) { + tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.FUNCTION.ToString(), 0x1001, tok)); + return; + } + + + tok = scanner.Scan(TokenType.IDENTIFIER); + n = node.CreateNode(tok, tok.ToString() ); + node.Token.UpdateRange(tok); + node.Nodes.Add(n); + if (tok.Type != TokenType.IDENTIFIER) { + tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.IDENTIFIER.ToString(), 0x1001, tok)); + return; + } + + + Parseinstruction_block(node); + + + tok = scanner.LookAhead(TokenType.EOI); + if (tok.Type == TokenType.EOI) + { + tok = scanner.Scan(TokenType.EOI); + n = node.CreateNode(tok, tok.ToString() ); + node.Token.UpdateRange(tok); + node.Nodes.Add(n); + if (tok.Type != TokenType.EOI) { + tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.EOI.ToString(), 0x1001, tok)); + return; + } + } + + parent.Token.UpdateRange(node.Token); + } + + private void Parsedeclare_lock_clause(ParseNode parent) + { + Token tok; + ParseNode n; + ParseNode node = parent.CreateNode(scanner.GetToken(TokenType.declare_lock_clause), "declare_lock_clause"); + parent.Nodes.Add(node); + + + + tok = scanner.Scan(TokenType.LOCK); + n = node.CreateNode(tok, tok.ToString() ); + node.Token.UpdateRange(tok); + node.Nodes.Add(n); + if (tok.Type != TokenType.LOCK) { + tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.LOCK.ToString(), 0x1001, tok)); + return; + } + + + tok = scanner.Scan(TokenType.IDENTIFIER); + n = node.CreateNode(tok, tok.ToString() ); + node.Token.UpdateRange(tok); + node.Nodes.Add(n); + if (tok.Type != TokenType.IDENTIFIER) { + tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.IDENTIFIER.ToString(), 0x1001, tok)); + return; + } + + + tok = scanner.Scan(TokenType.TO); + n = node.CreateNode(tok, tok.ToString() ); + node.Token.UpdateRange(tok); + node.Nodes.Add(n); + if (tok.Type != TokenType.TO) { + tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.TO.ToString(), 0x1001, tok)); + return; + } + + + Parseexpr(node); + + + tok = scanner.Scan(TokenType.EOI); + n = node.CreateNode(tok, tok.ToString() ); + node.Token.UpdateRange(tok); + node.Nodes.Add(n); + if (tok.Type != TokenType.EOI) { + tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.EOI.ToString(), 0x1001, tok)); + return; + } + + parent.Token.UpdateRange(node.Token); + } + + private void Parsedeclare_stmt(ParseNode parent) + { + Token tok; + ParseNode n; + ParseNode node = parent.CreateNode(scanner.GetToken(TokenType.declare_stmt), "declare_stmt"); + parent.Nodes.Add(node); + + tok = scanner.LookAhead(TokenType.PARAMETER, TokenType.FUNCTION, TokenType.LOCK, TokenType.DECLARE, TokenType.LOCAL, TokenType.GLOBAL); + switch (tok.Type) + { + case TokenType.PARAMETER: + Parsedeclare_parameter_clause(node); break; - case TokenType.IDENTIFIER: + case TokenType.FUNCTION: + Parsedeclare_function_clause(node); + break; + case TokenType.LOCK: + Parsedeclare_lock_clause(node); + break; + case TokenType.DECLARE: + case TokenType.LOCAL: + case TokenType.GLOBAL: + tok = scanner.LookAhead(TokenType.DECLARE, TokenType.LOCAL, TokenType.GLOBAL); + switch (tok.Type) + { + case TokenType.DECLARE: - - tok = scanner.Scan(TokenType.IDENTIFIER); - n = node.CreateNode(tok, tok.ToString() ); - node.Token.UpdateRange(tok); - node.Nodes.Add(n); - if (tok.Type != TokenType.IDENTIFIER) { - tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.IDENTIFIER.ToString(), 0x1001, tok)); - return; - } + + tok = scanner.Scan(TokenType.DECLARE); + n = node.CreateNode(tok, tok.ToString() ); + node.Token.UpdateRange(tok); + node.Nodes.Add(n); + if (tok.Type != TokenType.DECLARE) { + tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.DECLARE.ToString(), 0x1001, tok)); + return; + } - - tok = scanner.Scan(TokenType.TO); - n = node.CreateNode(tok, tok.ToString() ); - node.Token.UpdateRange(tok); - node.Nodes.Add(n); - if (tok.Type != TokenType.TO) { - tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.TO.ToString(), 0x1001, tok)); - return; + + tok = scanner.LookAhead(TokenType.LOCAL, TokenType.GLOBAL); + if (tok.Type == TokenType.LOCAL + || tok.Type == TokenType.GLOBAL) + { + tok = scanner.LookAhead(TokenType.LOCAL, TokenType.GLOBAL); + switch (tok.Type) + { + case TokenType.LOCAL: + tok = scanner.Scan(TokenType.LOCAL); + n = node.CreateNode(tok, tok.ToString() ); + node.Token.UpdateRange(tok); + node.Nodes.Add(n); + if (tok.Type != TokenType.LOCAL) { + tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.LOCAL.ToString(), 0x1001, tok)); + return; + } + break; + case TokenType.GLOBAL: + tok = scanner.Scan(TokenType.GLOBAL); + n = node.CreateNode(tok, tok.ToString() ); + node.Token.UpdateRange(tok); + node.Nodes.Add(n); + if (tok.Type != TokenType.GLOBAL) { + tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.GLOBAL.ToString(), 0x1001, tok)); + return; + } + break; + default: + tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found.", 0x0002, tok)); + break; + } + } + break; + case TokenType.LOCAL: + case TokenType.GLOBAL: + tok = scanner.LookAhead(TokenType.LOCAL, TokenType.GLOBAL); + switch (tok.Type) + { + case TokenType.LOCAL: + tok = scanner.Scan(TokenType.LOCAL); + n = node.CreateNode(tok, tok.ToString() ); + node.Token.UpdateRange(tok); + node.Nodes.Add(n); + if (tok.Type != TokenType.LOCAL) { + tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.LOCAL.ToString(), 0x1001, tok)); + return; + } + break; + case TokenType.GLOBAL: + tok = scanner.Scan(TokenType.GLOBAL); + n = node.CreateNode(tok, tok.ToString() ); + node.Token.UpdateRange(tok); + node.Nodes.Add(n); + if (tok.Type != TokenType.GLOBAL) { + tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.GLOBAL.ToString(), 0x1001, tok)); + return; + } + break; + default: + tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found.", 0x0002, tok)); + break; + } + break; + default: + tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found.", 0x0002, tok)); + break; } - Parseexpr(node); - - - tok = scanner.Scan(TokenType.EOI); - n = node.CreateNode(tok, tok.ToString() ); - node.Token.UpdateRange(tok); - node.Nodes.Add(n); - if (tok.Type != TokenType.EOI) { - tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.EOI.ToString(), 0x1001, tok)); - return; + tok = scanner.LookAhead(TokenType.PARAMETER, TokenType.FUNCTION, TokenType.IDENTIFIER, TokenType.LOCK); + switch (tok.Type) + { + case TokenType.PARAMETER: + Parsedeclare_parameter_clause(node); + break; + case TokenType.FUNCTION: + Parsedeclare_function_clause(node); + break; + case TokenType.IDENTIFIER: + Parsedeclare_identifier_clause(node); + break; + case TokenType.LOCK: + Parsedeclare_lock_clause(node); + break; + default: + tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found.", 0x0002, tok)); + break; } break; default: diff --git a/src/kOS.Safe/Compilation/KS/Scanner.cs b/src/kOS.Safe/Compilation/KS/Scanner.cs index bb5c34f36..cd84de946 100644 --- a/src/kOS.Safe/Compilation/KS/Scanner.cs +++ b/src/kOS.Safe/Compilation/KS/Scanner.cs @@ -86,6 +86,10 @@ public Scanner() Patterns.Add(TokenType.TO, regex); Tokens.Add(TokenType.TO); + regex = new Regex(@"is"); + Patterns.Add(TokenType.IS, regex); + Tokens.Add(TokenType.IS); + regex = new Regex(@"if"); Patterns.Add(TokenType.IF, regex); Tokens.Add(TokenType.IF); @@ -170,6 +174,14 @@ public Scanner() Patterns.Add(TokenType.DECLARE, regex); Tokens.Add(TokenType.DECLARE); + regex = new Regex(@"local"); + Patterns.Add(TokenType.LOCAL, regex); + Tokens.Add(TokenType.LOCAL); + + regex = new Regex(@"global"); + Patterns.Add(TokenType.GLOBAL, regex); + Tokens.Add(TokenType.GLOBAL); + regex = new Regex(@"parameter"); Patterns.Add(TokenType.PARAMETER, regex); Tokens.Add(TokenType.PARAMETER); @@ -506,135 +518,141 @@ public enum TokenType set_stmt= 7, if_stmt = 8, until_stmt= 9, - lock_stmt= 10, - unlock_stmt= 11, - print_stmt= 12, - on_stmt = 13, - toggle_stmt= 14, - wait_stmt= 15, - when_stmt= 16, - onoff_stmt= 17, - onoff_trailer= 18, - stage_stmt= 19, - clear_stmt= 20, - add_stmt= 21, - remove_stmt= 22, - log_stmt= 23, - break_stmt= 24, - preserve_stmt= 25, - declare_stmt= 26, - return_stmt= 27, - switch_stmt= 28, - copy_stmt= 29, - rename_stmt= 30, - delete_stmt= 31, - edit_stmt= 32, - run_stmt= 33, - compile_stmt= 34, - list_stmt= 35, - reboot_stmt= 36, - shutdown_stmt= 37, - for_stmt= 38, - unset_stmt= 39, - batch_stmt= 40, - deploy_stmt= 41, - arglist = 42, - expr = 43, - and_expr= 44, - compare_expr= 45, - arith_expr= 46, - multdiv_expr= 47, - unary_expr= 48, - factor = 49, - suffix = 50, - suffix_trailer= 51, - suffixterm= 52, - suffixterm_trailer= 53, - function_trailer= 54, - array_trailer= 55, - atom = 56, - sci_number= 57, - number = 58, - varidentifier= 59, - identifier_led_stmt= 60, - identifier_led_expr= 61, + unlock_stmt= 10, + print_stmt= 11, + on_stmt = 12, + toggle_stmt= 13, + wait_stmt= 14, + when_stmt= 15, + onoff_stmt= 16, + onoff_trailer= 17, + stage_stmt= 18, + clear_stmt= 19, + add_stmt= 20, + remove_stmt= 21, + log_stmt= 22, + break_stmt= 23, + preserve_stmt= 24, + declare_identifier_clause= 25, + declare_parameter_clause= 26, + declare_function_clause= 27, + declare_lock_clause= 28, + declare_stmt= 29, + return_stmt= 30, + switch_stmt= 31, + copy_stmt= 32, + rename_stmt= 33, + delete_stmt= 34, + edit_stmt= 35, + run_stmt= 36, + compile_stmt= 37, + list_stmt= 38, + reboot_stmt= 39, + shutdown_stmt= 40, + for_stmt= 41, + unset_stmt= 42, + batch_stmt= 43, + deploy_stmt= 44, + arglist = 45, + expr = 46, + and_expr= 47, + compare_expr= 48, + arith_expr= 49, + multdiv_expr= 50, + unary_expr= 51, + factor = 52, + suffix = 53, + suffix_trailer= 54, + suffixterm= 55, + suffixterm_trailer= 56, + function_trailer= 57, + array_trailer= 58, + atom = 59, + sci_number= 60, + number = 61, + varidentifier= 62, + identifier_led_stmt= 63, + identifier_led_expr= 64, //Terminal tokens: - PLUSMINUS= 62, - MULT = 63, - DIV = 64, - POWER = 65, - E = 66, - NOT = 67, - AND = 68, - OR = 69, - TRUEFALSE= 70, - COMPARATOR= 71, - SET = 72, - TO = 73, - IF = 74, - ELSE = 75, - UNTIL = 76, - LOCK = 77, - UNLOCK = 78, - PRINT = 79, - AT = 80, - ON = 81, - TOGGLE = 82, - WAIT = 83, - WHEN = 84, - THEN = 85, - OFF = 86, - STAGE = 87, - CLEARSCREEN= 88, - ADD = 89, - REMOVE = 90, - LOG = 91, - BREAK = 92, - PRESERVE= 93, - DECLARE = 94, - PARAMETER= 95, - FUNCTION= 96, - RETURN = 97, - SWITCH = 98, - COPY = 99, - FROM = 100, - RENAME = 101, - VOLUME = 102, - FILE = 103, - DELETE = 104, - EDIT = 105, - RUN = 106, - COMPILE = 107, - LIST = 108, - REBOOT = 109, - SHUTDOWN= 110, - FOR = 111, - UNSET = 112, - BATCH = 113, - DEPLOY = 114, - BRACKETOPEN= 115, - BRACKETCLOSE= 116, - CURLYOPEN= 117, - CURLYCLOSE= 118, - SQUAREOPEN= 119, - SQUARECLOSE= 120, - COMMA = 121, - COLON = 122, - IN = 123, - ARRAYINDEX= 124, - ALL = 125, - IDENTIFIER= 126, - FILEIDENT= 127, - INTEGER = 128, - DOUBLE = 129, - STRING = 130, - EOI = 131, - ATSIGN = 132, - LAZYGLOBAL= 133, - EOF = 134, - WHITESPACE= 135, - COMMENTLINE= 136 + PLUSMINUS= 65, + MULT = 66, + DIV = 67, + POWER = 68, + E = 69, + NOT = 70, + AND = 71, + OR = 72, + TRUEFALSE= 73, + COMPARATOR= 74, + SET = 75, + TO = 76, + IS = 77, + IF = 78, + ELSE = 79, + UNTIL = 80, + LOCK = 81, + UNLOCK = 82, + PRINT = 83, + AT = 84, + ON = 85, + TOGGLE = 86, + WAIT = 87, + WHEN = 88, + THEN = 89, + OFF = 90, + STAGE = 91, + CLEARSCREEN= 92, + ADD = 93, + REMOVE = 94, + LOG = 95, + BREAK = 96, + PRESERVE= 97, + DECLARE = 98, + LOCAL = 99, + GLOBAL = 100, + PARAMETER= 101, + FUNCTION= 102, + RETURN = 103, + SWITCH = 104, + COPY = 105, + FROM = 106, + RENAME = 107, + VOLUME = 108, + FILE = 109, + DELETE = 110, + EDIT = 111, + RUN = 112, + COMPILE = 113, + LIST = 114, + REBOOT = 115, + SHUTDOWN= 116, + FOR = 117, + UNSET = 118, + BATCH = 119, + DEPLOY = 120, + BRACKETOPEN= 121, + BRACKETCLOSE= 122, + CURLYOPEN= 123, + CURLYCLOSE= 124, + SQUAREOPEN= 125, + SQUARECLOSE= 126, + COMMA = 127, + COLON = 128, + IN = 129, + ARRAYINDEX= 130, + ALL = 131, + IDENTIFIER= 132, + FILEIDENT= 133, + INTEGER = 134, + DOUBLE = 135, + STRING = 136, + EOI = 137, + ATSIGN = 138, + LAZYGLOBAL= 139, + EOF = 140, + WHITESPACE= 141, + COMMENTLINE= 142 } public class Token diff --git a/src/kOS.Safe/Compilation/KS/UserFunction.cs b/src/kOS.Safe/Compilation/KS/UserFunction.cs index 1eaba5536..9d3652f78 100644 --- a/src/kOS.Safe/Compilation/KS/UserFunction.cs +++ b/src/kOS.Safe/Compilation/KS/UserFunction.cs @@ -1,5 +1,7 @@ using System.Collections.Generic; +using System.Text; using System.Linq; +using System; namespace kOS.Safe.Compilation.KS { @@ -14,7 +16,53 @@ public class UserFunction public string Identifier { get; private set; } public string PointerIdentifier{ get; private set; } public string DefaultLabel{ get; private set; } + + /// The node from the parse tree in which this function or lock was defined. + public ParseNode OriginalNode{ get; private set; } + /// + /// To help store the difference between the same function name at different scope + /// levels, the scope number is appened to the end of the identifier name when storing + /// things. This sanitizes that by removing the number again to get the actual variable + /// name as used by the script code: + /// + public string ScopelessDefaultLabel + { + get + { + int backTickIndex = DefaultLabel.IndexOf('`'); + return backTickIndex < 0 ? DefaultLabel : (DefaultLabel.Remove(backTickIndex) + "-default"); // reattach the "-default" on the end. + } + } + /// + /// To help store the difference between the same function name at different scope + /// levels, the scope number is appened to the end of the identifier name when storing + /// things. This sanitizes that by removing the number again to get the actual variable + /// name as used by the script code: + /// + public string ScopelessPointerIdentifier + { + get + { + int backTickIndex = PointerIdentifier.IndexOf('`'); + return backTickIndex < 0 ? PointerIdentifier : (PointerIdentifier.Remove(backTickIndex) + "*"); // reattach the '*' on the end. + } + } + /// + /// To help store the difference between the same function name at different scope + /// levels, the scope number is appened to the end of the identifier name when storing + /// things. This sanitizes that by removing the number again to get the actual variable + /// name as used by the script code: + /// + public string ScopelessIdentifier + { + get + { + int backTickIndex = Identifier.IndexOf('`'); + return backTickIndex < 0 ? Identifier : Identifier.Remove(backTickIndex); + } + } + /// /// A the thing this was defined in. (it will be part of the parse tree of the compiler). /// null = global @@ -33,15 +81,16 @@ public List MainCode get { return codePart.MainCode; } } - public UserFunction() + public UserFunction(ParseNode originalNode) { codePart = new CodePart(); functions = new Dictionary(); newFunctions = new List(); + OriginalNode = originalNode; } - public UserFunction(string userFuncIdentifier) - : this() + public UserFunction(string userFuncIdentifier, ParseNode originalNode) + : this(originalNode) { Identifier = userFuncIdentifier; PointerIdentifier = "$" + Identifier + "*"; @@ -81,6 +130,11 @@ public List GetUserFunctionOpcodes(int expressionHash) return newUserFuncFragment.Code; } + public string GetUserFunctionLabel(int expressionHash) + { + return String.Format("{0}-{1}", Identifier, expressionHash.ToString("x")); + } + public CodePart GetCodePart() { var mergedPart = new CodePart @@ -122,7 +176,7 @@ public CodePart GetNewFunctionsCodePart() public bool IsSystemLock() { - return systemLocks.Contains(Identifier.ToLower()); + return systemLocks.Contains(ScopelessIdentifier.ToLower()); } } } \ No newline at end of file diff --git a/src/kOS.Safe/Compilation/KS/UserFunctionCollection.cs b/src/kOS.Safe/Compilation/KS/UserFunctionCollection.cs index 29f4c510f..23d2446d2 100644 --- a/src/kOS.Safe/Compilation/KS/UserFunctionCollection.cs +++ b/src/kOS.Safe/Compilation/KS/UserFunctionCollection.cs @@ -6,7 +6,19 @@ namespace kOS.Safe.Compilation.KS { public class UserFunctionCollection { + /// + /// A list of all the UserFuncs the compiler knows about, from either + /// this compile or a previous compile: + /// private readonly Dictionary userFuncs; + + /// + /// A subset (a true venn-diagram subset) of userFuncs that only lists + /// the functions that have been added recently since the last call + /// to GetNewParts. Used to differentiate the user functions that + /// were added during the current compile from the ones that + /// existed in previous compiles (from other scripts, basically). + /// private readonly List newUserFuncs; public UserFunctionCollection() @@ -15,23 +27,77 @@ public UserFunctionCollection() newUserFuncs = new List(); } - public bool Contains(string userFuncIdentifier) + public bool Contains(string userFuncIdentifier, Int16 scopeId) + { + // uses backticks to differentiate different scope Id's using the same lock identifier name: + string ident = String.Format("{0}`{1}", userFuncIdentifier, scopeId); + return Contains(ident); + } + + private bool Contains(string userFuncIdentifier) { return userFuncs.ContainsKey(userFuncIdentifier); } + + /// + /// Get or create the user function give its identifying criteria + /// + /// the script id the function or lock has + /// the integer id of the containing scope it is declared in + /// the parse tree branch of the declaration. This is only + /// important when it has to construct a new user function object. It will not be used + /// to narrow down the search for an existing one. + /// + public UserFunction GetUserFunction(string userFuncIdentifier, Int16 scopeId, ParseNode declaredWith) + { + // uses backticks to differentiate different scope Id's using the same lock identifier name: + string ident = String.Format("{0}`{1}", userFuncIdentifier, scopeId); + return GetUserFunction(ident, declaredWith); + } - public UserFunction GetUserFunction(string userFuncIdentifier) + private UserFunction GetUserFunction(string userFuncIdentifier, ParseNode declaredWith) { if (userFuncs.ContainsKey(userFuncIdentifier)) { return userFuncs[userFuncIdentifier]; } - var userFuncObject = new UserFunction(userFuncIdentifier); - userFuncs.Add(userFuncIdentifier, userFuncObject); - newUserFuncs.Add(userFuncObject); - return userFuncObject; + if (declaredWith != null) + { + var userFuncObject = new UserFunction(userFuncIdentifier, declaredWith); + userFuncs.Add(userFuncIdentifier, userFuncObject); + newUserFuncs.Add(userFuncObject); + return userFuncObject; + } + return null; // shouldn't happen - must call with declaredWith = something. } + /// + /// Returns true if the given user function is one of the ones that was just + /// declared during the current compile and not one that was leftover from + /// a previous compile. + ///
    + /// Returns false if either the function exists and is old, or the function + /// doesn't even exist in the collection at all. + ///
    + /// + /// + public bool IsNew(UserFunction func) + { + // Possible opportuinity for an optimization refactor here: + // ------------------------------------------- + // newUserFuncs is purely a flat sequential list with + // no sort order or hash mapping. Therefore seeing if a + // function is new or not requires a sequential walk of all + // the functions built during the current compile. + // If people start writing library scripts containing upwards + // of 20 or more functions in one file, that could become + // inefficient. It may be possible to refactor newUserFuncs + // into some sort of hashmap or at least sorted list. That way + // Contains() would be a faster search. + + return newUserFuncs.Contains(func); + } + public IEnumerable GetUserFunctionList() { return userFuncs.Values.ToList(); diff --git a/src/kOS.Safe/Compilation/KS/kRISC.tpg b/src/kOS.Safe/Compilation/KS/kRISC.tpg index 3603289ef..88b9f262e 100644 --- a/src/kOS.Safe/Compilation/KS/kRISC.tpg +++ b/src/kOS.Safe/Compilation/KS/kRISC.tpg @@ -17,6 +17,7 @@ COMPARATOR -> @"<>|>=|<=|=|>|<"; //Instructions tokens SET -> @"set"; TO -> @"to"; +IS -> @"is"; IF -> @"if"; ELSE -> @"else"; UNTIL -> @"until"; @@ -38,6 +39,8 @@ LOG -> @"log"; BREAK -> @"break"; PRESERVE -> @"preserve"; DECLARE -> @"declare"; +LOCAL -> @"local"; +GLOBAL -> @"global"; PARAMETER -> @"parameter"; FUNCTION -> @"function"; RETURN -> @"return"; @@ -93,7 +96,6 @@ instruction_block -> CURLYOPEN instruction* CURLYCLOSE EOI?; instruction -> set_stmt | if_stmt | until_stmt | - lock_stmt | unlock_stmt | print_stmt | on_stmt | @@ -136,7 +138,6 @@ directive -> lazyglobal_directive; // Add to this list later if we ma set_stmt -> SET varidentifier TO expr EOI; if_stmt -> IF expr instruction (ELSE instruction)? EOI?; until_stmt -> UNTIL expr instruction EOI?; -lock_stmt -> LOCK IDENTIFIER TO expr EOI; unlock_stmt -> UNLOCK (IDENTIFIER | ALL) EOI; print_stmt -> PRINT expr (AT BRACKETOPEN expr COMMA expr BRACKETCLOSE)? EOI; on_stmt -> ON varidentifier instruction EOI?; @@ -152,7 +153,31 @@ remove_stmt -> REMOVE expr EOI; log_stmt -> LOG expr TO expr EOI; break_stmt -> BREAK EOI; preserve_stmt -> PRESERVE EOI; -declare_stmt -> DECLARE ( (PARAMETER IDENTIFIER (COMMA IDENTIFIER)* EOI) | (FUNCTION IDENTIFIER instruction_block EOI?) | (IDENTIFIER TO expr) EOI); +declare_identifier_clause -> IDENTIFIER (TO|IS) expr EOI; +declare_parameter_clause -> PARAMETER IDENTIFIER (COMMA IDENTIFIER)* EOI; +declare_function_clause -> FUNCTION IDENTIFIER instruction_block EOI?; +declare_lock_clause -> LOCK IDENTIFIER TO expr EOI; +declare_stmt -> // declare|global|local are all optional for function and parameter, + // but mandatory for declaring an identifier. This was the only + // way to get the LL(1) parser to understand that without barfing on + // ambiguity. + ( + declare_parameter_clause | + declare_function_clause | + declare_lock_clause | + ( + ( + (DECLARE (LOCAL|GLOBAL)?) | + (LOCAL|GLOBAL) + ) + ( + declare_parameter_clause | + declare_function_clause | + declare_identifier_clause | + declare_lock_clause + ) + ) + ); return_stmt -> RETURN expr? EOI; switch_stmt -> SWITCH TO expr EOI; copy_stmt -> COPY expr (FROM | TO) expr EOI; diff --git a/src/kOS.Safe/Compilation/Opcode.cs b/src/kOS.Safe/Compilation/Opcode.cs index 6e7abc2ba..22261d4c6 100644 --- a/src/kOS.Safe/Compilation/Opcode.cs +++ b/src/kOS.Safe/Compilation/Opcode.cs @@ -74,10 +74,11 @@ public enum ByteCode :byte ENDWAIT = 0x56, GETMETHOD = 0x57, STORELOCAL = 0x58, - PUSHSCOPE = 0x59, - POPSCOPE = 0x5a, - STOREEXIST = 0x5b, - PUSHDELEGATE = 0x5c, + STOREGLOBAL = 0x59, + PUSHSCOPE = 0x5a, + POPSCOPE = 0x5b, + STOREEXIST = 0x5c, + PUSHDELEGATE = 0x5d, // Augmented bogus placeholder versions of the normal // opcodes: These only exist in the program temporarily @@ -515,7 +516,34 @@ public override void Execute(ICpu cpu) cpu.SetNewLocal(identifier, value); } } - + + /// + /// Consumes the topmost 2 values of the stack, storing the topmost stack + /// value into a variable described by the next value down the stack.
    + ///
    + /// The variable will always be stored at a global scope, overwriting + /// whatever else was there if the variable already existed.
    + ///
    + /// It will ignore local scoping and never store the value in a local + /// variable
    + ///
    + /// It's impossible to make a variable that hasn't been given an initial value. + /// Its the act of storing a value into the variable that causues it to exist. + /// This is deliberate design. + ///
    + public class OpcodeStoreGlobal : Opcode + { + protected override string Name { get { return "storeglobal"; } } + public override ByteCode Code { get { return ByteCode.STOREGLOBAL; } } + + public override void Execute(ICpu cpu) + { + object value = cpu.PopValue(); + var identifier = (string)cpu.PopStack(); + cpu.SetGlobal(identifier, value); + } + } + public class OpcodeUnset : Opcode { protected override string Name { get { return "unset"; } } @@ -534,7 +562,6 @@ public override void Execute(ICpu cpu) } } } - public class OpcodeGetMember : Opcode { diff --git a/src/kOS.Safe/Compilation/ProgramBuilder.cs b/src/kOS.Safe/Compilation/ProgramBuilder.cs index 90361cad1..a3761f6fd 100644 --- a/src/kOS.Safe/Compilation/ProgramBuilder.cs +++ b/src/kOS.Safe/Compilation/ProgramBuilder.cs @@ -63,7 +63,7 @@ public List BuildProgram() // add the linked object to the final program program.AddRange(linkedObject.MergeSections()); } - + // replace all the labels references with the corresponding address ReplaceLabels(program); diff --git a/src/kOS.Safe/Execution/ICpu.cs b/src/kOS.Safe/Execution/ICpu.cs index 147c0fb31..d51d8bd5b 100644 --- a/src/kOS.Safe/Execution/ICpu.cs +++ b/src/kOS.Safe/Execution/ICpu.cs @@ -20,6 +20,7 @@ public interface ICpu : IFixedUpdateObserver void SetValue(string identifier, object value); void SetValueExists(string identifier, object value); void SetNewLocal(string identifier, object value); + void SetGlobal(string identifier, object value); string DumpVariables(); void RemoveVariable(string identifier); int InstructionPointer { get; set; } @@ -31,7 +32,7 @@ public interface ICpu : IFixedUpdateObserver void CallBuiltinFunction(string functionName); bool BuiltInExists(string functionName); void BreakExecution(bool manual); - void AddVariable(Variable variable, string identifier, bool local); + void AddVariable(Variable variable, string identifier, bool local, bool overwrite = false); Opcode GetOpcodeAt(int instructionPtr); void Boot(); diff --git a/src/kOS.Safe/Utilities/Debug.cs b/src/kOS.Safe/Utilities/Debug.cs index 19f5b4585..614c97ab9 100644 --- a/src/kOS.Safe/Utilities/Debug.cs +++ b/src/kOS.Safe/Utilities/Debug.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using System.Linq; using System.Runtime.Serialization; +using kOS.Safe.Compilation; namespace kOS.Safe.Utilities { @@ -63,5 +64,33 @@ public static List GetPendingNags() } public static ObjectIDGenerator IDGenerator { get; set; } + + /// + /// This is copied almost verbatim from ProgramContext, + /// It's here to help debug. + /// + public static string GetCodeFragment(List codes) + { + var codeFragment = new List(); + + const string FORMAT_STR = "{0,-20} {1,4}:{2,-3} {3:0000} {4} {5} {6} {7}"; + codeFragment.Add(string.Format(FORMAT_STR, "File", "Line", "Col", "IP ", "Label ", "opcode", "operand", "Destination" )); + codeFragment.Add(string.Format(FORMAT_STR, "----", "----", "---", "----", "-------", "---------------------", "", "" )); + + for (int index = 0; index < codes.Count; index++) + { + codeFragment.Add(string.Format(FORMAT_STR, + codes[index].SourceName ?? "null", + codes[index].SourceLine, + codes[index].SourceColumn , + index, + codes[index].Label ?? "null", + codes[index] ?? new OpcodeBogus(), + "DEST: " + (codes[index].DestinationLabel ?? "null" ), + "" ) ); + } + + return codeFragment.Aggregate(string.Empty, (current, s) => current + (s + "\n")); + } } } diff --git a/src/kOS/Execution/CPU.cs b/src/kOS/Execution/CPU.cs index b1ae9bf55..bb85ffd33 100644 --- a/src/kOS/Execution/CPU.cs +++ b/src/kOS/Execution/CPU.cs @@ -576,12 +576,14 @@ private Variable GetVariable(string identifier, bool barewordOkay = false, bool /// /// Make a new variable at either the local depth or the /// global depth depending. - /// throws exception if it already exists + /// throws exception if it already exists as a boundvariable at the desired + /// scope level, unless overwrite = true. /// /// variable to add /// name of variable to adde /// true if you want to make it at local depth - public void AddVariable(Variable variable, string identifier, bool local) + /// true if it's okay to overwrite an existing variable + public void AddVariable(Variable variable, string identifier, bool local, bool overwrite = false) { identifier = identifier.ToLower(); @@ -598,7 +600,12 @@ public void AddVariable(Variable variable, string identifier, bool local) if (whichDict.Variables.ContainsKey(identifier)) { if (whichDict.Variables[identifier].Value is BoundVariable) - throw new KOSIdentiferClashException(identifier); + { + if (!overwrite) + throw new KOSIdentiferClashException(identifier); + else + return; // no work to do - the bound variable is fine to leave in place. + } else whichDict.Variables.Remove(identifier); } @@ -684,6 +691,23 @@ public void SetNewLocal(string identifier, object value) variable.Value = value; } + /// + /// Make a new global variable at the localmost scoping level and + /// give it a starting value, or overwrite an existing variable + /// at the localmost level with a starting value.
    + ///
    + /// This does NOT scan up the scoping stack like SetValue() does. + /// It operates at the global level only.
    + ///
    + /// variable name to attempt to store into + /// value to put into it + public void SetGlobal(string identifier, object value) + { + Variable variable = new Variable {Name = identifier}; + AddVariable(variable, identifier, false, true); + variable.Value = value; + } + /// /// Try to set the value of the identifier at the localmost /// level possible, by scanning up the scope stack to find diff --git a/src/kOS/Utilities/Utils.cs b/src/kOS/Utilities/Utils.cs index c6548128d..5cfa84912 100644 --- a/src/kOS/Utilities/Utils.cs +++ b/src/kOS/Utilities/Utils.cs @@ -221,34 +221,6 @@ public static string KOSType(Type type) return type.Name; } - /// - /// This is copied almost verbatim from ProgramContext, - /// It's here to help debug. - /// - public static string GetCodeFragment(List codes) - { - var codeFragment = new List(); - - const string FORMAT_STR = "{0,-20} {1,4}:{2,-3} {3:0000} {4} {5} {6} {7}"; - codeFragment.Add(string.Format(FORMAT_STR, "File", "Line", "Col", "IP ", "Label ", "opcode", "operand", "Destination" )); - codeFragment.Add(string.Format(FORMAT_STR, "----", "----", "---", "----", "-------", "---------------------", "", "" )); - - for (int index = 0; index < codes.Count; index++) - { - codeFragment.Add(string.Format(FORMAT_STR, - codes[index].SourceName ?? "null", - codes[index].SourceLine, - codes[index].SourceColumn , - index, - codes[index].Label ?? "null", - codes[index] ?? new OpcodeBogus(), - "DEST: " + (codes[index].DestinationLabel ?? "null" ), - "" ) ); - } - - return codeFragment.Aggregate(string.Empty, (current, s) => current + (s + "\n")); - } - /// /// Meant to be an override for stock KSP's CelestialBody.GetObtVelocity(), which (literally) always /// stack overflows because it's implemented as just infinite recursion without a base case. From 172d6ea57c9991d390f1ed38ad56d8dd0915b175 Mon Sep 17 00:00:00 2001 From: TDW89 Date: Mon, 13 Apr 2015 23:52:26 +0100 Subject: [PATCH 368/446] Added :inverse detailed section --- doc/source/math/direction.rst | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/doc/source/math/direction.rst b/doc/source/math/direction.rst index bf1304aed..1bff3ecb0 100644 --- a/doc/source/math/direction.rst +++ b/doc/source/math/direction.rst @@ -185,6 +185,13 @@ Structure :struct:`Vector` of length 1 that is in the same direction as the "starboard side" of this Direction. Note that it is the same meaning as "what the X axis of the universe would be rotated to if this rotation was applied to the basis axes of the universe". When you LOCK STEERING to a direction, that direction's STARVECTOR is the vector the right wing of the ship will orient to. SHIP:FACING:STARVECTOR is the way the ship's right wing is aimed right now. +.. attribute:: Direction:INVERSE + + :type: :struct:`Direction` + :access: Get only + + :struct: The reverse of a `Direction`. So `PROGRADE:INVERSE` is the same as `RETROGRADE`. + .. note:: **The difference between a :struct:`Direction` and a ``Vector``** From 02cfdcd356bbc7a11ee3bdc71c2e747c5e24bc24 Mon Sep 17 00:00:00 2001 From: TDW89 Date: Tue, 14 Apr 2015 00:34:52 +0100 Subject: [PATCH 369/446] Added :inverse detailed section (with the correct definition this time) #652 --- doc/source/math/direction.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/math/direction.rst b/doc/source/math/direction.rst index 1bff3ecb0..6165cbad2 100644 --- a/doc/source/math/direction.rst +++ b/doc/source/math/direction.rst @@ -190,7 +190,7 @@ Structure :type: :struct:`Direction` :access: Get only - :struct: The reverse of a `Direction`. So `PROGRADE:INVERSE` is the same as `RETROGRADE`. + :struct: Gives a `Direction` with the opposite rotation around its axes. So `r(30,15,5)` becomes `r(-30,-15,-5)`. .. note:: **The difference between a :struct:`Direction` and a ``Vector``** From 458cf79220985b5c4399c6b242409760c5e3c920 Mon Sep 17 00:00:00 2001 From: TDW89 Date: Tue, 14 Apr 2015 01:14:35 +0100 Subject: [PATCH 370/446] Added RANDOM() to docs #765 --- doc/source/math/basic.rst | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/doc/source/math/basic.rst b/doc/source/math/basic.rst index 8a11cb532..35a13a902 100644 --- a/doc/source/math/basic.rst +++ b/doc/source/math/basic.rst @@ -58,6 +58,7 @@ Mathematical Functions :func:`MOD(a,b)` modulus :func:`MIN(a,b)` minimum :func:`MAX(a,b)` maximum + :func:`RANDOM()` random number :func:`ROUND(a)` round to whole number :func:`ROUND(a,b)` round to nearest place :func:`SQRT(a)` square root @@ -111,6 +112,12 @@ Mathematical Functions PRINT MAX(0,100). // prints 100 +.. function:: RANDOM() + + Returns a random floating point number in the range [0,1]:: + + PRINT RANDOM(). //prints a random number + .. function:: ROUND(a) Rounds to the nearest whole number:: From 5b1c7b17771f596f50138caf12b53c7212a511cf Mon Sep 17 00:00:00 2001 From: TDW89 Date: Tue, 14 Apr 2015 05:01:18 +0100 Subject: [PATCH 371/446] Fix for the bug part of #685 --- src/kOS/Suffixed/VesselTarget.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/kOS/Suffixed/VesselTarget.cs b/src/kOS/Suffixed/VesselTarget.cs index c15a3cd8d..3e39071f5 100644 --- a/src/kOS/Suffixed/VesselTarget.cs +++ b/src/kOS/Suffixed/VesselTarget.cs @@ -422,6 +422,7 @@ private void InitializeSuffixes() () => System.Math.Min(Vessel.distanceLandedPackThreshold, Vessel.distancePackThreshold), value => { Vessel.distanceLandedPackThreshold = Vessel.distancePackThreshold = value; })); AddSuffix("ISDEAD", new NoArgsSuffix(() => (Vessel.state == Vessel.State.DEAD) )); + AddSuffix("STATUS", new Suffix(() => shared.Vessel.situation.ToString()); //// Although there is an implementation of lat/long/alt in Orbitible, //// it's better to use the methods for vessels that are faster if they're From 040a9c614962b0bdc56f5f2906e0d1a2a62bf29d Mon Sep 17 00:00:00 2001 From: TDW89 Date: Tue, 14 Apr 2015 05:04:41 +0100 Subject: [PATCH 372/446] Fix for the doc part of #685 --- doc/source/structures/vessels/vessel.rst | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/doc/source/structures/vessels/vessel.rst b/doc/source/structures/vessels/vessel.rst index 29fdbc786..86b3cef4d 100644 --- a/doc/source/structures/vessels/vessel.rst +++ b/doc/source/structures/vessels/vessel.rst @@ -45,6 +45,8 @@ All vessels share a structure. To get a variable referring to any vessel you can :attr:`TERMVELOCITY` scalar (m/s) terminal velocity of the vessel :attr:`SHIPNAME` string The name of the vessel :attr:`NAME` string Synomym for SHIPNAME + :attr:`STATUS` string Current ship status + :attr:`TYPE` string Ship type :attr:`ANGULARMOMENTUM` :struct:`Vector` In :ref:`SHIP_RAW ` :attr:`ANGULARVEL` :struct:`Vector` In :ref:`SHIP_RAW ` :attr:`SENSORS` :struct:`VesselSensors` Sensor data @@ -159,6 +161,13 @@ All vessels share a structure. To get a variable referring to any vessel you can Same as :attr:`Vessel:SHIPNAME`. +.. attribute:: Vessel:STATUS + + :type: string + :access: get only + + The current status of the vessel possible results are: `LANDED`, `SPLASHED`, `PRELAUNCH`, `FLYING`, `SUB_ORBITAL`, `ORBITING`, `ESCAPING` and `DOCKED`. + .. attribute:: Vessel:TYPE :type: string From 609244c7e96d208797c652a83c533a898961c2ea Mon Sep 17 00:00:00 2001 From: TDW89 Date: Tue, 14 Apr 2015 05:20:45 +0100 Subject: [PATCH 373/446] Missed on of the ) off the end. --- src/kOS/Suffixed/VesselTarget.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kOS/Suffixed/VesselTarget.cs b/src/kOS/Suffixed/VesselTarget.cs index 3e39071f5..5b2b4f7e6 100644 --- a/src/kOS/Suffixed/VesselTarget.cs +++ b/src/kOS/Suffixed/VesselTarget.cs @@ -422,7 +422,7 @@ private void InitializeSuffixes() () => System.Math.Min(Vessel.distanceLandedPackThreshold, Vessel.distancePackThreshold), value => { Vessel.distanceLandedPackThreshold = Vessel.distancePackThreshold = value; })); AddSuffix("ISDEAD", new NoArgsSuffix(() => (Vessel.state == Vessel.State.DEAD) )); - AddSuffix("STATUS", new Suffix(() => shared.Vessel.situation.ToString()); + AddSuffix("STATUS", new Suffix(() => shared.Vessel.situation.ToString())); //// Although there is an implementation of lat/long/alt in Orbitible, //// it's better to use the methods for vessels that are faster if they're From 3ec031426285e9767a91d1415cb9e51088cfd6c9 Mon Sep 17 00:00:00 2001 From: ZiwKerman Date: Tue, 14 Apr 2015 10:31:05 +0100 Subject: [PATCH 374/446] AddonList and Addon refactor + minor doc changes. Made Addon class abstract and now require each AddOn create its own child of kOS.Suffixed.Addon implementing at least Available suffix, but each child may implement other suffixes as demonstrated in the code. --- doc/source/addons/KAC.rst | 71 +++++++++++---- src/kOS/AddOns/ActionGroupsExtended/Addon.cs | 25 ++++++ src/kOS/AddOns/KerbalAlarmClock/Addon.cs | 45 ++++++++++ src/kOS/AddOns/RemoteTech/Addon.cs | 81 +++++++++++++++++ src/kOS/Binding/BindingConfig.cs | 2 +- src/kOS/Suffixed/Addon.cs | 95 +++----------------- src/kOS/Suffixed/AddonList.cs | 17 ++-- src/kOS/kOS.csproj | 3 + 8 files changed, 232 insertions(+), 107 deletions(-) create mode 100644 src/kOS/AddOns/ActionGroupsExtended/Addon.cs create mode 100644 src/kOS/AddOns/KerbalAlarmClock/Addon.cs create mode 100644 src/kOS/AddOns/RemoteTech/Addon.cs diff --git a/doc/source/addons/KAC.rst b/doc/source/addons/KAC.rst index fb44c3746..3052be904 100644 --- a/doc/source/addons/KAC.rst +++ b/doc/source/addons/KAC.rst @@ -13,6 +13,45 @@ The Kerbal Alarm Clock is a plugin that allows you to create reminder alarms at Creator of the KAC provides API for integration with other mods. In KOS we provide limited access to KAC alarms via following structure and functions. +Access structure KACAddon via `ADDONS:KAC`. + +.. structure:: KACAddon + + ===================================== ========================= ============= + Suffix Type Description + ===================================== ========================= ============= + :attr:`AVAILABLE` bool(readonly) True if KAC is installed and KAC integration enabled. + :meth:`ALARMS()` List List all alarms + ===================================== ========================= ============= + + + +.. attribute:: KACAddon:AVAILABLE + + :type: bool + :access: Get only + + True if KAC is installed and KAC integration enabled. + Example of use:: + + if ADDONS:KAC:AVAILABLE + { + //some KAC dependent code + } + +.. method:: KACAddon:ALARMS() + + :return: List of :struct:`KACAlarm` objects + + List **all** the alarms set up in Kerbal Alarm Clock. Example of use:: + + for i in ADDONS:KAC:ALARMS + { + print i:NAME + " - " + i:REMAINING + " - " + i:TYPE+ " - " + i:ACTION. + } + + + .. structure:: KACAlarm ===================================== ========================= ============= @@ -64,7 +103,7 @@ Creator of the KAC provides API for integration with other mods. In KOS we provi :access: Get only Can only be set at Alarm creation. - Could be one of the following as per API + Could be one of the following as per API * Raw (default) * Maneuver @@ -82,17 +121,17 @@ Creator of the KAC provides API for integration with other mods. In KOS we provi * Distance * Crew * EarthTime - - **Warning** Unless you are 100% certain you know what you're doing, create only "Raw" AlarmTypes to avoid unnecessary complications. + + **Warning**: Unless you are 100% certain you know what you're doing, create only "Raw" AlarmTypes to avoid unnecessary complications. .. attribute:: KACAlarm:NOTES :type: string :access: Get/Set - Long description of the alarm. Can be seen when alarm pops or by doubleclicking alarm in UI. + Long description of the alarm. Can be seen when alarm pops or by double-clicking alarm in UI. - **Warning** This field may be reserved in the fututre version of KAC-KOS integration for automated script execution upon triggering of the alarm. + **Warning**: This field may be reserved in the future version of KAC-KOS integration for automated script execution upon triggering of the alarm. .. attribute:: KACAlarm:REMAINING @@ -137,7 +176,7 @@ Available Functions ============================================= =================================================== Function Description ============================================= =================================================== - :func:`ADDALARM(AlarmType, UT, Name, Notes)` Create new alarm of AlarmType at UT + :func:`ADDALARM(AlarmType, UT, Name, Notes)` Create new alarm of AlarmType at UT :func:`LISTALARMS(alarmType)` List alarms with type `alarmType`. :func:`DELETEALARM(alarmID)` Delete alarm with ID = alarmID ============================================= =================================================== @@ -146,7 +185,7 @@ Available Functions Creates alarm of type `KACAlarm:ALARMTYPE` at `UT` with `Name` and `Notes` attributes set. Attaches alarm to current :ref:`CPU Vessel `. Returns :struct:`KACAlarm` object if creation was successful and empty string otherwise:: - set na to addAlarm("Raw",time:seconds+300, "Test", "Notes"). + set na to addAlarm("Raw",time:seconds+300, "Test", "Notes"). print na:NAME. //prints 'Test' set na:NOTES to "New Description". print na:NOTES. //prints 'New Description' @@ -157,17 +196,17 @@ Available Functions Otherwise returns :struct:`List` of all :struct:`KACAlarm` objects with `KACAlarm:TYPE` equeal to `alarmType' and attached to current vessel or have no vessel attached.:: set al to listAlarms("All"). - for i in al - { - print i:ID + " - " + i:name. - } + for i in al + { + print i:ID + " - " + i:name. + } .. function:: DELETEALARM(alarmID) Deletes alarm with ID equal to alarmID. Returns True if successful, false otherwise:: - set na to addAlarm("Raw",time:seconds+300, "Test", "Notes"). - if (DELETEALARM(na:ID)) - { - print "Alarm Deleted". - } + set na to addAlarm("Raw",time:seconds+300, "Test", "Notes"). + if (DELETEALARM(na:ID)) + { + print "Alarm Deleted". + } diff --git a/src/kOS/AddOns/ActionGroupsExtended/Addon.cs b/src/kOS/AddOns/ActionGroupsExtended/Addon.cs new file mode 100644 index 000000000..f91da9ae7 --- /dev/null +++ b/src/kOS/AddOns/ActionGroupsExtended/Addon.cs @@ -0,0 +1,25 @@ +using kOS.Safe.Encapsulation; +using kOS.Safe.Encapsulation.Suffixes; +using kOS.Suffixed; +using System; + +namespace kOS.AddOns.ActionGroupsExtended +{ + public class Addon : kOS.Suffixed.Addon + { + public Addon(SharedObjects shared) : base ("AGX", shared) + { + InitializeSuffixes(); + } + + private void InitializeSuffixes() + { + //AddSuffix("DELAY", new OneArgsSuffix(RTGetDelay, "Get current Shortest Signal Delay for Vessel")); + } + + public override bool Available() + { + return ActionGroupsExtendedAPI.Instance.Installed (); + } + } +} \ No newline at end of file diff --git a/src/kOS/AddOns/KerbalAlarmClock/Addon.cs b/src/kOS/AddOns/KerbalAlarmClock/Addon.cs new file mode 100644 index 000000000..c3757e73f --- /dev/null +++ b/src/kOS/AddOns/KerbalAlarmClock/Addon.cs @@ -0,0 +1,45 @@ +using kOS.Safe.Encapsulation; +using kOS.Safe.Encapsulation.Suffixes; +using kOS.Suffixed; +using System; + +namespace kOS.AddOns.KerbalAlarmClock +{ + public class Addon : kOS.Suffixed.Addon + { + public Addon(SharedObjects shared) : base ("KAC", shared) + { + InitializeSuffixes(); + } + + private void InitializeSuffixes() + { + AddSuffix("ALARMS", new Suffix(GetAlarms, "List all alarms")); + } + + private ListValue GetAlarms() + { + var list = new ListValue(); + + if (!KACWrapper.APIReady) + { + return list; + } + + //Get the list of alarms from the KAC Object + KACWrapper.KACAPI.KACAlarmList alarms = KACWrapper.KAC.Alarms; + + foreach (KACWrapper.KACAPI.KACAlarm alarm in alarms) + { + list.Add(new KACAlarmWrapper(alarm, shared)); + } + return list; + } + + public override bool Available() + { + return KACWrapper.APIReady; + } + + } +} \ No newline at end of file diff --git a/src/kOS/AddOns/RemoteTech/Addon.cs b/src/kOS/AddOns/RemoteTech/Addon.cs new file mode 100644 index 000000000..d7a841d08 --- /dev/null +++ b/src/kOS/AddOns/RemoteTech/Addon.cs @@ -0,0 +1,81 @@ +using kOS.Safe.Encapsulation; +using kOS.Safe.Encapsulation.Suffixes; +using kOS.Suffixed; +using System; + +namespace kOS.AddOns.RemoteTech +{ + public class Addon : kOS.Suffixed.Addon + { + public Addon(SharedObjects shared) : base ("RT", shared) + { + InitializeSuffixes(); + } + + private void InitializeSuffixes() + { + AddSuffix("DELAY", new OneArgsSuffix(RTGetDelay, "Get current Shortest Signal Delay for Vessel")); + + AddSuffix("KSCDELAY", new OneArgsSuffix(RTGetKSCDelay, "Get current KSC Signal Delay")); + + AddSuffix("HASCONNECTION", new OneArgsSuffix(RTHasConnection, "True if ship has any connection")); + + AddSuffix("HASKSCCONNECTION", new OneArgsSuffix(RTHasKSCConnection, "True if ship has connection to KSC")); + + } + + private static double RTGetDelay(VesselTarget tgtVessel) + { + double waitTotal = 0; + + if (RemoteTechHook.IsAvailable(tgtVessel.Vessel.id) && tgtVessel.Vessel.GetVesselCrew().Count == 0) + { + waitTotal = RemoteTechHook.Instance.GetShortestSignalDelay(tgtVessel.Vessel.id); + } + + return waitTotal; + } + + private static double RTGetKSCDelay(VesselTarget tgtVessel) + { + double waitTotal = 0; + + if (RemoteTechHook.IsAvailable(tgtVessel.Vessel.id) && tgtVessel.Vessel.GetVesselCrew().Count == 0) + { + waitTotal = RemoteTechHook.Instance.GetSignalDelayToKSC(tgtVessel.Vessel.id); + } + + return waitTotal; + } + + private static bool RTHasConnection(VesselTarget tgtVessel) + { + bool result = false; + + if (RemoteTechHook.IsAvailable(tgtVessel.Vessel.id)) + { + result = RemoteTechHook.Instance.HasAnyConnection(tgtVessel.Vessel.id); + } + + return result; + } + + private static bool RTHasKSCConnection(VesselTarget tgtVessel) + { + bool result = false; + + if (RemoteTechHook.IsAvailable(tgtVessel.Vessel.id)) + { + result = RemoteTechHook.Instance.HasConnectionToKSC(tgtVessel.Vessel.id); + } + + return result; + } + + public override bool Available() + { + return RemoteTechHook.IsAvailable(); + } + + } +} \ No newline at end of file diff --git a/src/kOS/Binding/BindingConfig.cs b/src/kOS/Binding/BindingConfig.cs index 51ca102ce..9486c1e90 100644 --- a/src/kOS/Binding/BindingConfig.cs +++ b/src/kOS/Binding/BindingConfig.cs @@ -9,7 +9,7 @@ public class BindingConfig : Binding public override void AddTo(SharedObjects shared) { shared.BindingMgr.AddGetter("CONFIG", () => Config.Instance); - shared.BindingMgr.AddGetter("ADDONS", () => new AddonList()); + shared.BindingMgr.AddGetter("ADDONS", () => new AddonList(shared)); } } } diff --git a/src/kOS/Suffixed/Addon.cs b/src/kOS/Suffixed/Addon.cs index 8eb60d100..00ca7c2f8 100644 --- a/src/kOS/Suffixed/Addon.cs +++ b/src/kOS/Suffixed/Addon.cs @@ -4,103 +4,32 @@ namespace kOS.Suffixed { - public class Addon : Structure + /// + /// A generic addon description class for use in AddonList + /// Addons must inherit from this one to implement functions + /// + public abstract class Addon : Structure { - private readonly string addonName; + protected readonly string addonName; + protected readonly SharedObjects shared; - public Addon(string name) + protected Addon(string name, SharedObjects shared) { addonName = name; - + this.shared = shared; InitializeSuffixes(); } private void InitializeSuffixes() { AddSuffix("AVAILABLE", new Suffix(Available)); - - if (addonName == "RT") - { - AddSuffix("DELAY", new OneArgsSuffix(RTGetDelay, "Get current Shortest Signal Delay for Vessel")); - - AddSuffix("KSCDELAY", new OneArgsSuffix(RTGetKSCDelay, "Get current KSC Signal Delay")); - - AddSuffix("HASCONNECTION", new OneArgsSuffix(RTHasConnection, "True if ship has any connection")); - - AddSuffix("HASKSCCONNECTION", new OneArgsSuffix(RTHasKSCConnection, "True if ship has connection to KSC")); - } - } - - private static double RTGetDelay(VesselTarget tgtVessel) - { - double waitTotal = 0; - - if (AddOns.RemoteTech.RemoteTechHook.IsAvailable(tgtVessel.Vessel.id) && tgtVessel.Vessel.GetVesselCrew().Count == 0) - { - waitTotal = AddOns.RemoteTech.RemoteTechHook.Instance.GetShortestSignalDelay(tgtVessel.Vessel.id); - } - - return waitTotal; - } - - private static double RTGetKSCDelay(VesselTarget tgtVessel) - { - double waitTotal = 0; - - if (AddOns.RemoteTech.RemoteTechHook.IsAvailable(tgtVessel.Vessel.id) && tgtVessel.Vessel.GetVesselCrew().Count == 0) - { - waitTotal = AddOns.RemoteTech.RemoteTechHook.Instance.GetSignalDelayToKSC(tgtVessel.Vessel.id); - } - - return waitTotal; - } - - private static bool RTHasConnection(VesselTarget tgtVessel) - { - bool result = false; - - if (AddOns.RemoteTech.RemoteTechHook.IsAvailable(tgtVessel.Vessel.id)) - { - result = AddOns.RemoteTech.RemoteTechHook.Instance.HasAnyConnection(tgtVessel.Vessel.id); - } - - return result; - } - - private static bool RTHasKSCConnection(VesselTarget tgtVessel) - { - bool result = false; - - if (AddOns.RemoteTech.RemoteTechHook.IsAvailable(tgtVessel.Vessel.id)) - { - result = AddOns.RemoteTech.RemoteTechHook.Instance.HasConnectionToKSC(tgtVessel.Vessel.id); - } - - return result; - } - - public Boolean Available() - { - if (addonName == "AGX") - { - return AddOns.ActionGroupsExtended.ActionGroupsExtendedAPI.Instance.Installed(); - } - - if (addonName == "KAC") - { - return AddOns.KerbalAlarmClock.KACWrapper.APIReady; - } - - if (addonName == "RT") - { - return AddOns.RemoteTech.RemoteTechHook.IsAvailable(); - } - return false; } + public abstract bool Available (); + public override string ToString() { - return string.Format("{0} Addon", base.ToString()); + return string.Format("{0} Addon, name = " + addonName, base.ToString()); } } } \ No newline at end of file diff --git a/src/kOS/Suffixed/AddonList.cs b/src/kOS/Suffixed/AddonList.cs index 630e3f5ca..6d893e873 100644 --- a/src/kOS/Suffixed/AddonList.cs +++ b/src/kOS/Suffixed/AddonList.cs @@ -1,19 +1,22 @@ using kOS.Safe.Encapsulation; using kOS.Safe.Encapsulation.Suffixes; + namespace kOS.Suffixed { public class AddonList : Structure { - private readonly Addon kacAddon; - private readonly Addon rtAddon; - private readonly Addon agxAddon; + private readonly SharedObjects shared; + private readonly kOS.AddOns.KerbalAlarmClock.Addon kacAddon; + private readonly kOS.AddOns.RemoteTech.Addon rtAddon; + private readonly kOS.AddOns.ActionGroupsExtended.Addon agxAddon; - public AddonList() + public AddonList(SharedObjects shared) { - kacAddon = new Addon("KAC"); - rtAddon = new Addon("RT"); - agxAddon = new Addon("AGX"); + this.shared = shared; + kacAddon = new kOS.AddOns.KerbalAlarmClock.Addon(shared); + rtAddon = new kOS.AddOns.RemoteTech.Addon(shared); + agxAddon = new kOS.AddOns.ActionGroupsExtended.Addon(shared); InitializeSuffixes(); } diff --git a/src/kOS/kOS.csproj b/src/kOS/kOS.csproj index c41dbc2c5..680448a14 100644 --- a/src/kOS/kOS.csproj +++ b/src/kOS/kOS.csproj @@ -165,6 +165,9 @@ + + + From c8de17bb6d1b3dda011bc927c42a36cc1e753088 Mon Sep 17 00:00:00 2001 From: TDW89 Date: Tue, 14 Apr 2015 12:02:17 +0100 Subject: [PATCH 375/446] Removed `shaired.` was failing to build with `shaired.` removed and tested. This fixes #685 --- src/kOS/Suffixed/VesselTarget.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kOS/Suffixed/VesselTarget.cs b/src/kOS/Suffixed/VesselTarget.cs index 5b2b4f7e6..b1c37b3d0 100644 --- a/src/kOS/Suffixed/VesselTarget.cs +++ b/src/kOS/Suffixed/VesselTarget.cs @@ -422,7 +422,7 @@ private void InitializeSuffixes() () => System.Math.Min(Vessel.distanceLandedPackThreshold, Vessel.distancePackThreshold), value => { Vessel.distanceLandedPackThreshold = Vessel.distancePackThreshold = value; })); AddSuffix("ISDEAD", new NoArgsSuffix(() => (Vessel.state == Vessel.State.DEAD) )); - AddSuffix("STATUS", new Suffix(() => shared.Vessel.situation.ToString())); + AddSuffix("STATUS", new Suffix(() => Vessel.situation.ToString())); //// Although there is an implementation of lat/long/alt in Orbitible, //// it's better to use the methods for vessels that are faster if they're From fcd4e7e1cebf8257adc2a13947fd707c3723a27b Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Tue, 14 Apr 2015 08:16:28 -0500 Subject: [PATCH 376/446] I merged a PR without seeing it if compiled. It didn't. This is the fix. --- src/kOS/Suffixed/VesselTarget.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kOS/Suffixed/VesselTarget.cs b/src/kOS/Suffixed/VesselTarget.cs index 5b2b4f7e6..b1c37b3d0 100644 --- a/src/kOS/Suffixed/VesselTarget.cs +++ b/src/kOS/Suffixed/VesselTarget.cs @@ -422,7 +422,7 @@ private void InitializeSuffixes() () => System.Math.Min(Vessel.distanceLandedPackThreshold, Vessel.distancePackThreshold), value => { Vessel.distanceLandedPackThreshold = Vessel.distancePackThreshold = value; })); AddSuffix("ISDEAD", new NoArgsSuffix(() => (Vessel.state == Vessel.State.DEAD) )); - AddSuffix("STATUS", new Suffix(() => shared.Vessel.situation.ToString())); + AddSuffix("STATUS", new Suffix(() => Vessel.situation.ToString())); //// Although there is an implementation of lat/long/alt in Orbitible, //// it's better to use the methods for vessels that are faster if they're From f3aeb43edf326ae9287875449f6a02ceab444b81 Mon Sep 17 00:00:00 2001 From: Chris Woerz Date: Tue, 14 Apr 2015 09:03:03 -0600 Subject: [PATCH 377/446] review comments --- doc/source/addons.rst | 10 ++++---- doc/source/addons/AGX.rst | 8 +++---- src/kOS/AddOns/KerbalAlarmClock/Addon.cs | 6 ++--- .../KerbalAlarmClock/KACAlarmWrapper.cs | 23 ++----------------- .../AddOns/KerbalAlarmClock/KACFunctions.cs | 16 ++++++------- src/kOS/AddOns/RemoteTech/Addon.cs | 6 ++--- src/kOS/Suffixed/AddonList.cs | 12 +++------- 7 files changed, 26 insertions(+), 55 deletions(-) diff --git a/doc/source/addons.rst b/doc/source/addons.rst index 0294c011a..2fca3d76c 100644 --- a/doc/source/addons.rst +++ b/doc/source/addons.rst @@ -4,8 +4,8 @@ Addon Reference =============== This section is for ways in which kOS has special case - exceptions to its normal generic behaviors, in order to - accomdate other KSP mods. If you don't use any of KSP mods mentioned, + exceptions to its normal generic behaviours, in order to + accommodate other KSP mods. If you don't use any of KSP mods mentioned, you don't need to read this section. @@ -20,16 +20,16 @@ To help KOS scripts identify whether or not certain mod is installed and availab ``ADDONS:AGX:AVAILABLE`` ------------------------ -Returns True if mod Action Groupd Extended is istalled and available to KOS. +Returns True if mod Action Group Extended is installed and available to KOS. ``ADDONS:RT:AVAILABLE`` ------------------------ -Returns True if mod Remote Tech is istalled and available to KOS. See more Remote Tech functions here . +Returns True if mod RemoteTech is installed and available to KOS. See more RemoteTech functions here . ``ADDONS:KAC:AVAILABLE`` ------------------------ -Returns True if mod Kerbal Alarm Clock is istalled and available to KOS. \ No newline at end of file +Returns True if mod Kerbal Alarm Clock is installed and available to KOS. \ No newline at end of file diff --git a/doc/source/addons/AGX.rst b/doc/source/addons/AGX.rst index 53bcbe879..a0edca0f9 100644 --- a/doc/source/addons/AGX.rst +++ b/doc/source/addons/AGX.rst @@ -29,12 +29,12 @@ When an action group has the Script Trigger action assigned, on that action grou .. figure:: /_images/addons/AGExtQuickStart2.jpg -Note that this mod only adds action grousp 11 through 250, it does not change how action groups 1 through 10 behave in any way and groups 11 through 250 should behave the same way. +Note that this mod only adds action groups 11 through 250, it does not change how action groups 1 through 10 behave in any way and groups 11 through 250 should behave the same way. **Known limitations (Action groups 11 through 250 only):** - On a nearby vessel that is not your current focus, an action group with no actions assigned will always return a state of False and can not be set to a state of true via the "AG15 on." command. Assign the Script Trigger action as a work-around for this. -- At this point, AG11 through AG250 do not officially support RemoteTech through kOS. (Support will happen once all three mods involved have updated to KSP version 1.0 and made any internal changes necessary.) All three mods can be installed at the same time without issue, just be aware there may be unexpected behavior when using action groups 11 through 250 from a kOS script in terms of RemoteTech signal delay and connection state. +- At this point, AG11 through AG250 do not officially support RemoteTech through kOS. (Support will happen once all three mods involved have updated to KSP version 1.0 and made any internal changes necessary.) All three mods can be installed at the same time without issue, just be aware there may be unexpected behaviour when using action groups 11 through 250 from a kOS script in terms of RemoteTech signal delay and connection state. **Action state monitoring** @@ -45,11 +45,11 @@ Note that the state of action groups is tracked on a per-action basis, rather th - This can result in an action group have actions in a mixed state where some actions are on and some are off. In this case querying the group state will result in a state of False. For the purposes of the group state being True or False, if *all* actions in the action group are true, the group state will return true. If *any* actions in the group are false,the group state with return False. - When an action triggers an animation, the state of the action will be uncertain until the animation finishes playing. Some parts will report True during the animation and some will report False. It depends on how the part creator set things up and not something AGX can control. - For clarity, visual feedback can be provided of the current state of an action group. When editing action groups, find the "Toggle Grp." button just below the text entry field for the group name in the main AGX window and enable it. (It is enabled/disabled for the current action group when you click the button.) Once you do this, the text displaying that group will change from gray to colored. Green: Group is activated (state True). Red: Group is deactivated (state False). Yellow: Group is in a mixed state, will return a state False when queried. -- It is okay to activate an already activated group and deactivate a non-activated group. Actions in the group will still try to execute as normal. Exact behavior of a specific action will depend on how the action's creator set things up. +- It is okay to activate an already activated group and deactivate a non-activated group. Actions in the group will still try to execute as normal. Exact behaviour of a specific action will depend on how the action's creator set things up. **Example code:** -Print to the terminal anytime you activate action group 15. Use this to change variables within a running kOS script and the "Script Trigger" action found on the kOS computer part:: +Print to the terminal any time you activate action group 15. Use this to change variables within a running kOS script and the "Script Trigger" action found on the kOS computer part:: AG15 on. // Activate action group 15. print AG15. // Print action group 15's state to the terminal. (True/False) diff --git a/src/kOS/AddOns/KerbalAlarmClock/Addon.cs b/src/kOS/AddOns/KerbalAlarmClock/Addon.cs index c3757e73f..1b7b8d80c 100644 --- a/src/kOS/AddOns/KerbalAlarmClock/Addon.cs +++ b/src/kOS/AddOns/KerbalAlarmClock/Addon.cs @@ -1,11 +1,9 @@ using kOS.Safe.Encapsulation; using kOS.Safe.Encapsulation.Suffixes; -using kOS.Suffixed; -using System; namespace kOS.AddOns.KerbalAlarmClock { - public class Addon : kOS.Suffixed.Addon + public class Addon : Suffixed.Addon { public Addon(SharedObjects shared) : base ("KAC", shared) { @@ -31,7 +29,7 @@ private ListValue GetAlarms() foreach (KACWrapper.KACAPI.KACAlarm alarm in alarms) { - list.Add(new KACAlarmWrapper(alarm, shared)); + list.Add(new KACAlarmWrapper(alarm)); } return list; } diff --git a/src/kOS/AddOns/KerbalAlarmClock/KACAlarmWrapper.cs b/src/kOS/AddOns/KerbalAlarmClock/KACAlarmWrapper.cs index 5645a0da7..f336abc43 100644 --- a/src/kOS/AddOns/KerbalAlarmClock/KACAlarmWrapper.cs +++ b/src/kOS/AddOns/KerbalAlarmClock/KACAlarmWrapper.cs @@ -1,7 +1,6 @@ using kOS.Safe.Encapsulation; using kOS.Safe.Encapsulation.Suffixes; using kOS.Safe.Utilities; -using kOS.Suffixed; using System; using System.Linq; @@ -10,19 +9,16 @@ namespace kOS.AddOns.KerbalAlarmClock public class KACAlarmWrapper : Structure { private readonly KACWrapper.KACAPI.KACAlarm alarm; - private readonly SharedObjects shared; - public KACAlarmWrapper(KACWrapper.KACAPI.KACAlarm init, SharedObjects shared) + public KACAlarmWrapper(KACWrapper.KACAPI.KACAlarm init) { alarm = init; - this.shared = shared; InitializeSuffixes(); } - public KACAlarmWrapper(String alarmID, SharedObjects shared) + public KACAlarmWrapper(String alarmID) { alarm = KACWrapper.KAC.Alarms.First(z => z.ID == alarmID); - this.shared = shared; InitializeSuffixes(); } @@ -50,21 +46,6 @@ private void InitializeSuffixes() AddSuffix("TARGETBODY", new SetSuffix(() => alarm.XferTargetBodyName, value => alarm.XferTargetBodyName = value)); } - private VesselTarget GetVesselByID(string vesselID) - { - if (string.IsNullOrEmpty(vesselID)) - return null; - - var g = new Guid(vesselID); - Vessel v = FlightGlobals.Vessels.First(z => z.id == g); - return v != null ? new VesselTarget(v, shared) : null; - } - - private void SetVesselID(VesselTarget v) - { - alarm.VesselID = v.Vessel == null ? "" : v.Vessel.id.ToString(); - } - private double GetRemaining() { /*SafeHouse.Logger.LogWarning (string.Format ("Trying to get remaining time, {0}", alarm.Remaining));*/ diff --git a/src/kOS/AddOns/KerbalAlarmClock/KACFunctions.cs b/src/kOS/AddOns/KerbalAlarmClock/KACFunctions.cs index bdf200c22..5bb6c3cb4 100644 --- a/src/kOS/AddOns/KerbalAlarmClock/KACFunctions.cs +++ b/src/kOS/AddOns/KerbalAlarmClock/KACFunctions.cs @@ -33,21 +33,21 @@ public override void Execute(SharedObjects shared) newAlarmType = KACWrapper.KACAPI.AlarmTypeEnum.Raw; } - String aID = KACWrapper.KAC.CreateAlarm(newAlarmType, alarmName, alarmUT); + string alarmId = KACWrapper.KAC.CreateAlarm(newAlarmType, alarmName, alarmUT); SafeHouse.Logger.Log(string.Format("Trying to create KAC Alarm, UT={0}, Name={1}, Type= {2}", alarmUT, alarmName, alarmType)); - if (!string.IsNullOrEmpty(aID)) + if (!string.IsNullOrEmpty(alarmId)) { //if the alarm was made get the object so we can update it - KACWrapper.KACAPI.KACAlarm a = KACWrapper.KAC.Alarms.First(z => z.ID == aID); + KACWrapper.KACAPI.KACAlarm alarm = KACWrapper.KAC.Alarms.First(z => z.ID == alarmId); //Now update some of the other properties - a.Notes = alarmNotes; - a.AlarmAction = KACWrapper.KACAPI.AlarmActionEnum.PauseGame; - a.VesselID = shared.Vessel.id.ToString(); + alarm.Notes = alarmNotes; + alarm.AlarmAction = KACWrapper.KACAPI.AlarmActionEnum.PauseGame; + alarm.VesselID = shared.Vessel.id.ToString(); - var result = new KACAlarmWrapper(a, shared); + var result = new KACAlarmWrapper(alarm); ReturnValue = result; } @@ -94,7 +94,7 @@ public override void Execute(SharedObjects shared) } if (alarmTypes.ToUpperInvariant() == "ALL" || alarm.AlarmTime.ToString() == alarmTypes) - list.Add(new KACAlarmWrapper(alarm, shared)); + list.Add(new KACAlarmWrapper(alarm)); } ReturnValue = list; } diff --git a/src/kOS/AddOns/RemoteTech/Addon.cs b/src/kOS/AddOns/RemoteTech/Addon.cs index d7a841d08..db123112c 100644 --- a/src/kOS/AddOns/RemoteTech/Addon.cs +++ b/src/kOS/AddOns/RemoteTech/Addon.cs @@ -1,11 +1,9 @@ -using kOS.Safe.Encapsulation; -using kOS.Safe.Encapsulation.Suffixes; +using kOS.Safe.Encapsulation.Suffixes; using kOS.Suffixed; -using System; namespace kOS.AddOns.RemoteTech { - public class Addon : kOS.Suffixed.Addon + public class Addon : Suffixed.Addon { public Addon(SharedObjects shared) : base ("RT", shared) { diff --git a/src/kOS/Suffixed/AddonList.cs b/src/kOS/Suffixed/AddonList.cs index 6d893e873..156d4f472 100644 --- a/src/kOS/Suffixed/AddonList.cs +++ b/src/kOS/Suffixed/AddonList.cs @@ -7,25 +7,19 @@ namespace kOS.Suffixed public class AddonList : Structure { private readonly SharedObjects shared; - private readonly kOS.AddOns.KerbalAlarmClock.Addon kacAddon; - private readonly kOS.AddOns.RemoteTech.Addon rtAddon; - private readonly kOS.AddOns.ActionGroupsExtended.Addon agxAddon; public AddonList(SharedObjects shared) { this.shared = shared; - kacAddon = new kOS.AddOns.KerbalAlarmClock.Addon(shared); - rtAddon = new kOS.AddOns.RemoteTech.Addon(shared); - agxAddon = new kOS.AddOns.ActionGroupsExtended.Addon(shared); InitializeSuffixes(); } private void InitializeSuffixes() { - AddSuffix("KAC", new Suffix(() => kacAddon)); - AddSuffix("RT", new Suffix(() => rtAddon)); - AddSuffix("AGX", new Suffix(() => agxAddon)); + AddSuffix("KAC", new Suffix(() => new AddOns.KerbalAlarmClock.Addon(shared))); + AddSuffix("RT", new Suffix(() => new AddOns.RemoteTech.Addon(shared))); + AddSuffix("AGX", new Suffix(() => new AddOns.ActionGroupsExtended.Addon(shared))); } public override string ToString() From 6a31601368c45ac4edbbba5819392e734d35ed98 Mon Sep 17 00:00:00 2001 From: TDW89 Date: Tue, 14 Apr 2015 18:06:28 +0100 Subject: [PATCH 378/446] Removed example due to uncertainty (and so the issue can be closed) --- doc/source/math/direction.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/math/direction.rst b/doc/source/math/direction.rst index 6165cbad2..3922b6398 100644 --- a/doc/source/math/direction.rst +++ b/doc/source/math/direction.rst @@ -190,7 +190,7 @@ Structure :type: :struct:`Direction` :access: Get only - :struct: Gives a `Direction` with the opposite rotation around its axes. So `r(30,15,5)` becomes `r(-30,-15,-5)`. + :struct: Gives a `Direction` with the opposite rotation around its axes. .. note:: **The difference between a :struct:`Direction` and a ``Vector``** From e528b1cbf9e5ec813976a4fe4018b841a761e612 Mon Sep 17 00:00:00 2001 From: ZiwKerman Date: Tue, 14 Apr 2015 19:24:41 +0100 Subject: [PATCH 379/446] Fixing issue #714 #714 --- doc/source/conf.py | 2 +- doc/source/copyright.rst | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) create mode 100644 doc/source/copyright.rst diff --git a/doc/source/conf.py b/doc/source/conf.py index 43205f719..b1a451c9b 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -50,7 +50,7 @@ # General information about the project. project = u'kOS' -copyright = u'2014, Dunbaratu, erendrake, Originally By Nivekk' +copyright = u'2014-2015, Developed and maintained by KOS Team, Originally By Nivekk' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the diff --git a/doc/source/copyright.rst b/doc/source/copyright.rst new file mode 100644 index 000000000..9bfe0ad03 --- /dev/null +++ b/doc/source/copyright.rst @@ -0,0 +1,8 @@ +.. _copyright: + +License Information and Credits +=============================== + +kOS is developed and maintained by `kOS Team `_ and is licensed under terms of GNU General Public License Version 3, 29 June 2007 + +Copyright © 2007 `Free Software Foundation, Inc. `_ From 9fa72c69149efa8b82716aded780baa685f177e8 Mon Sep 17 00:00:00 2001 From: ZiwKerman Date: Tue, 14 Apr 2015 19:30:42 +0100 Subject: [PATCH 380/446] Minor fixes to copyright. --- doc/source/conf.py | 2 +- doc/source/copyright.rst | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/doc/source/conf.py b/doc/source/conf.py index b1a451c9b..9c3c8b544 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -50,7 +50,7 @@ # General information about the project. project = u'kOS' -copyright = u'2014-2015, Developed and maintained by KOS Team, Originally By Nivekk' +copyright = u'2013-2015, Developed and maintained by kOS Team, Originally By Nivekk' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the diff --git a/doc/source/copyright.rst b/doc/source/copyright.rst index 9bfe0ad03..15c4eaac8 100644 --- a/doc/source/copyright.rst +++ b/doc/source/copyright.rst @@ -3,6 +3,4 @@ License Information and Credits =============================== -kOS is developed and maintained by `kOS Team `_ and is licensed under terms of GNU General Public License Version 3, 29 June 2007 - -Copyright © 2007 `Free Software Foundation, Inc. `_ +kOS is developed and maintained by `kOS Team `_ and is licensed under terms of GNU General Public License Version 3, 29 June 2007, Copyright © 2007 `Free Software Foundation, Inc. `_ From 658553fd021a0f61abcd20799bb6754e19f74e49 Mon Sep 17 00:00:00 2001 From: ZiwKerman Date: Tue, 14 Apr 2015 20:18:15 +0100 Subject: [PATCH 381/446] Removing old docs Updating RT docs, solving #496 --- doc/source/addons.rst | 7 +-- doc/source/addons/RemoteTech.rst | 36 +++++++----- doc/source/general.rst | 8 +-- doc/source/general/comm_range.rst | 91 ------------------------------- 4 files changed, 28 insertions(+), 114 deletions(-) delete mode 100644 doc/source/general/comm_range.rst diff --git a/doc/source/addons.rst b/doc/source/addons.rst index 2fca3d76c..944eead49 100644 --- a/doc/source/addons.rst +++ b/doc/source/addons.rst @@ -3,10 +3,7 @@ Addon Reference =============== - This section is for ways in which kOS has special case - exceptions to its normal generic behaviours, in order to - accommodate other KSP mods. If you don't use any of KSP mods mentioned, - you don't need to read this section. + This section is for ways in which kOS has special case exceptions to its normal generic behaviours, in order to accommodate other KSP mods. If you don't use any of KSP mods mentioned, you don't need to read this section. .. toctree:: @@ -32,4 +29,4 @@ Returns True if mod RemoteTech is installed and available to KOS. See more Remot ``ADDONS:KAC:AVAILABLE`` ------------------------ -Returns True if mod Kerbal Alarm Clock is installed and available to KOS. \ No newline at end of file +Returns True if mod Kerbal Alarm Clock is installed and available to KOS. diff --git a/doc/source/addons/RemoteTech.rst b/doc/source/addons/RemoteTech.rst index 5abe644ef..1ad08f764 100644 --- a/doc/source/addons/RemoteTech.rst +++ b/doc/source/addons/RemoteTech.rst @@ -3,9 +3,19 @@ RemoteTech ========== -**Warning! This documentation is incomplete!** +RemoteTech is a modification for Squad’s "Kerbal Space Program" (KSP) which overhauls the unmanned space program. It does this by requiring unmanned vessels have a connection to Kerbal Space Center (KSC) to be able to be controlled. This adds a new layer of difficulty that compensates for the lack of live crew members. -Access structure RTAddon via `ADDONS:RT`. +- Download: http://kerbalstuff.com/mod/134/RemoteTech +- Sources: https://github.com/RemoteTechnologiesGroup/RemoteTech +- Documentation: http://remotetechnologiesgroup.github.io/RemoteTech/ + + +Interaction with kOS +-------------------- + +When you have RemoteTech installed you can only interact with the core's terminal when you have a connection to KSC on any unmanned craft. Scripts launched when you still had a connection will continue to execute even if your unmanned craft loses connection to KSC. But you should note, that when there is no connection to KSC the archive volume is inaccessible. This will require you to plan ahead and copy necessary scripts for your mission to probe hard disk, if your kerbals and/or other scripts need to use them while not connected. + +Starting version 0.17 of kOS you can access structure RTAddon via `ADDONS:RT`. .. structure:: RTAddon @@ -20,10 +30,10 @@ Access structure RTAddon via `ADDONS:RT`. ===================================== ========================= ============= - + .. attribute:: RTADDON:AVAILABLE - :type: bool + :type: bool :access: Get only True if RT is installed and RT integration enabled. @@ -31,27 +41,27 @@ Access structure RTAddon via `ADDONS:RT`. .. method:: RTAddon:DELAY(vessel) :parameter vessel: :struct:`Vessel` - :return: (double) seconds - + :return: (double) seconds + Returns shortest possible delay for `vessel` (Will be less than KSC delay if you have a local command post). .. method:: RTAddon:KSCDELAY(vessel) :parameter vessel: :struct:`Vessel` - :return: (double) seconds - + :return: (double) seconds + Returns delay in seconds from KSC to `vessel`. .. method:: RTAddon:HASCONNECTION(vessel) :parameter vessel: :struct:`Vessel` - :return: bool - + :return: bool + Returns True if `vessel` has any connection (including to local command posts). .. method:: RTAddon:HASKSCCONNECTION(vessel) :parameter vessel: :struct:`Vessel` - :return: bool - - Returns True if `vessel` has connection to KSC. \ No newline at end of file + :return: bool + + Returns True if `vessel` has connection to KSC. diff --git a/doc/source/general.rst b/doc/source/general.rst index bab639172..344c1c92d 100644 --- a/doc/source/general.rst +++ b/doc/source/general.rst @@ -12,17 +12,15 @@ These topics discuss the interfacing between **kOS** and **Kerbal Space Program* CPU Vessel (SHIP) CPU Hardware - + Launcher Panel Telnet Server - + Files & Volumes Machine Code - + Name Tags Parts & PartModules - - Communication Range Respecting Career Limits diff --git a/doc/source/general/comm_range.rst b/doc/source/general/comm_range.rst deleted file mode 100644 index b21c1aa10..000000000 --- a/doc/source/general/comm_range.rst +++ /dev/null @@ -1,91 +0,0 @@ -.. _comm range: - -Communication Range For Remote Updates -====================================== - -.. warning:: - .. deprecated:: 0.12.2 - The stock game and the future of this feature is still fuzzy, and will likely be related to RemoteTech2 in some way. If you don't use RemoteTech2, then there will be no check for range anymore as of version 0.12.2. The following shortcuts are now used. - - ``COMMRANGE`` - always returns a Very Big Number, and - - ``INRANGE`` - always returns true. - - If you are using a version of ``kOS >= 0.12.2``, then most of what this page says won't be true. - -Communication Range (Deprecated) --------------------------------- - -Kerbin must be within CommRange of the vessel in order for the following operations to work: - -- COPY a file from a local volume to Archive -- COPY a file from Archive to a local volume. -- LIST the files on the Archive. - -You can always find out whether or not the vessel is within transmission range of Kerbin using the following: - -- PRINT COMMRANGE. // Shows a number, in meters. -- PRINT INCOMMRANGE. // Shows a boolean true/false, for whether or not - you are in range. - -A future plan is to implement a feature that when the RemoteTech mod is installed, kOS will query RemoteTech to ask whether or not the vessel is in communications range, and allow RemoteTech to override the calculation described below. - -The system described below is meant to be used only when RemoteTech2 is not installed. - -How to calculate communications range -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Communications range is decided by how many antennae are installed, and of what type. There are three categories of antenna: - -- longAntenna: (The Communotron 16 'stick') -- mediumDishAntenna: (The Comms DTS-M1) -- commDish: (The Communotron 88-88) - -The number of meters of range is decided by this formula: - -max range = ( (100,000 + L\ \*1,000,000) \*\ 100^M \* 200^D ) meters Where: \* L = number of longAntenna's on the vessel. \* M = number of mediumDishAntenna's on the vessel. \* D = number of commDish's on the vessel. - - -+----------------+----------------+-----------------------------------+ -|No. of Antennae | | | -+----+------+----+Max range |Context for comparison | -| |Medium| | | | -|Long|Dish |Dish| | | -+====+======+====+================+===================================+ -|0 |0 |0 |100 km | | -+----+------+----+----------------+-----------------------------------+ -|1 |0 |0 |1100 km | | -+----+------+----+----------------+-----------------------------------+ -|2 |0 |0 |2100 km | | -+----+------+----+----------------+-----------------------------------+ -|0 |1 |0 |10,000 km | | -+----+------+----+----------------+-----------------------------------+ -|0 |0 |1 |20,000 km |Mun-to-Kerbin = 12,000 km | -+----+------+----+----------------+-----------------------------------+ -|1 |0 |1 |220,000 km | | -+----+------+----+----------------+-----------------------------------+ -|2 |0 |1 |420,000 km | | -+----+------+----+----------------+-----------------------------------+ -|0 |2 |0 |1,000,000 km | | -+----+------+----+----------------+-----------------------------------+ -|0 |0 |2 |4,000,000 km |Almost the closest distance | -| | | | |Moho gets to the Sun | -+----+------+----+----------------+-----------------------------------+ -|1 |1 |1 |22,000,000 km | | -+----+------+----+----------------+-----------------------------------+ -|1 |0 |2 |44,000,000 km |A bit bigger than the 'diameter' | -| | | | |of Duna's orbit of the Sun | -+----+------+----+----------------+-----------------------------------+ -|2 |0 |2 |84,000,000 km |A bit bigger than the biggest | -| | | | |distance between Jool and the Sun | -+----+------+----+----------------+-----------------------------------+ -|3 |0 |2 |124,000,000 km |A bit bigger than the biggest | -| | | | |distance between Eeloo and the Sun | -+----+------+----+----------------+-----------------------------------+ -|1 |2 |1 |2,200,000,000 km| | -+----+------+----+----------------+-----------------------------------+ -|1 |0 |3 |8,800,000,000 km|Larger than any distance in the | -| | | | |Kerbal system | -+----+------+----+----------------+-----------------------------------+ From 0182bdb83a44d6ac6c13fadc903529153a177dee Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Tue, 14 Apr 2015 14:37:55 -0500 Subject: [PATCH 382/446] Fixes #779 lock steering/throttle in triggers. Moved the compilation around such that it will set up the triggers properly even when the lock is only mentioned in another trigger. --- .../user_functions/functest23.ks | 28 ++++++++++ src/kOS.Safe/Compilation/KS/Compiler.cs | 52 ++++++++++++------- src/kOS.Safe/Compilation/Opcode.cs | 6 ++- src/kOS.Safe/Execution/UserDelegate.cs | 8 +++ src/kOS/Execution/CPU.cs | 20 +++---- 5 files changed, 83 insertions(+), 31 deletions(-) create mode 100644 kerboscript_tests/user_functions/functest23.ks diff --git a/kerboscript_tests/user_functions/functest23.ks b/kerboscript_tests/user_functions/functest23.ks new file mode 100644 index 000000000..c8f26777c --- /dev/null +++ b/kerboscript_tests/user_functions/functest23.ks @@ -0,0 +1,28 @@ +// Testing attempt to lock throttle and steering +// without mentioning them at the global +// scope - only in triggers. From github issue #799 +// +print "Test by launching a small rocket manually straight up ". +print "and then waiting for the script to take over at 50m up.". +print "If it works right, the craft should start deflecting down". +print "at 50m, and cut the throttle to 80%.". +print "At 500m it should just stay pointed whichever way it's ". +print "currently going at that moment.". +print " ". +print "If it fails, then the rocket will just keep going straight up.". +print "You have 30 seconds to perform the test.". + +when alt:radar > 50 then { + print "Alt:radar now >50.". + lock steering to (up + r(0,-45,0)). + lock throttle to 0.8. //added + when alt:radar > 500 then { + print "Alt:radar now >500.". + lock steering to ship:prograde:vector. + } +} +// lock steering to up. +// lock throttle to 1. +wait 30. +unlock steering. +unlock throttle. diff --git a/src/kOS.Safe/Compilation/KS/Compiler.cs b/src/kOS.Safe/Compilation/KS/Compiler.cs index 28943eca3..8a7996531 100644 --- a/src/kOS.Safe/Compilation/KS/Compiler.cs +++ b/src/kOS.Safe/Compilation/KS/Compiler.cs @@ -397,12 +397,14 @@ private void IdentifyUserFunctions(ParseNode node) bodyNode = lastSubNode.Nodes[2]; } else - return; // not one of the types of statement we're really meant to run IdentifyLocks on. + return; // not one of the types of statement we're really meant to run IdentifyUserFunctions on. UserFunction userFuncObject = context.UserFunctions.GetUserFunction(funcIdentifier, storageType == StorageModifier.GLOBAL ? (Int16)0 : GetContainingScopeId(node), node); int expressionHash = ConcatenateNodes(bodyNode).GetHashCode(); userFuncObject.GetUserFunctionOpcodes(expressionHash); + if (userFuncObject.IsSystemLock()) + BuildSystemTrigger(userFuncObject); } /// @@ -514,22 +516,6 @@ private void PreProcessUserFunctionStatement(ParseNode node) AddOpcode(new OpcodePush(userFuncObject.ScopelessPointerIdentifier)); AddOpcode(new OpcodePushRelocateLater(null), userFuncObject.DefaultLabel); AddOpcode(new OpcodeStore()); - // add trigger - string triggerIdentifier = "lock-" + userFuncObject.ScopelessIdentifier; - Trigger triggerObject = context.Triggers.GetTrigger(triggerIdentifier); - - short rememberLastLine = lastLine; - lastLine = -1; // special flag telling the error handler that these opcodes came from the system itself, when reporting the error - currentCodeSection = triggerObject.Code; - AddOpcode(new OpcodePush("$" + userFuncObject.ScopelessIdentifier)); - AddOpcode(new OpcodePush(OpcodeCall.ARG_MARKER_STRING)); // need these for all locks now. - AddOpcode(new OpcodeCall(userFuncObject.ScopelessPointerIdentifier)); - if (allowLazyGlobal) - AddOpcode(new OpcodeStore()); - else - AddOpcode(new OpcodeStoreExist()); - AddOpcode(new OpcodeEOF()); - lastLine = rememberLastLine; } else { @@ -575,10 +561,37 @@ private void PreProcessUserFunctionStatement(ParseNode node) AddOpcode(new OpcodeReturn()); } userFuncObject.ScopeNode = GetContainingBlockNode(node); // This limits the scope of the function to the instruction_block the DEFINE was in. - userFuncObject.IsFunction = true; + userFuncObject.IsFunction = !(isLock);; } } + + /// + /// Build the system trigger to go with a user function (lock) + /// such as LOCK STEERING or LOCK THROTTLE + /// + /// Represents the lock object, which might not be fully populated yet. + private void BuildSystemTrigger(UserFunction func) + { + string triggerIdentifier = "lock-" + func.ScopelessIdentifier; + Trigger triggerObject = context.Triggers.GetTrigger(triggerIdentifier); + + if (triggerObject.IsInitialized()) + return; + + short rememberLastLine = lastLine; + lastLine = -1; // special flag telling the error handler that these opcodes came from the system itself, when reporting the error + List rememberCurrentCodeSection = currentCodeSection; + currentCodeSection = triggerObject.Code; + AddOpcode(new OpcodePush("$" + func.ScopelessIdentifier)); + AddOpcode(new OpcodePush(OpcodeCall.ARG_MARKER_STRING)); // need these for all locks now. + AddOpcode(new OpcodeCall(func.ScopelessPointerIdentifier)); + AddOpcode(new OpcodeStoreGlobal()); + AddOpcode(new OpcodeEOF()); + lastLine = rememberLastLine; + currentCodeSection = rememberCurrentCodeSection; + } + /// /// Get the instruction_block this node is immediately inside of. /// Gives a null if the node isn't in one (it's global). @@ -1964,7 +1977,7 @@ private void VisitLockStatement(ParseNode node, StorageModifier whereToStore) if (lockObject.IsSystemLock()) { // add update trigger - string triggerIdentifier = "lock-" + lockIdentifier; + string triggerIdentifier = "lock-" + lockObject.ScopelessIdentifier; if (context.Triggers.Contains(triggerIdentifier)) { Trigger triggerObject = context.Triggers.GetTrigger(triggerIdentifier); @@ -1976,7 +1989,6 @@ private void VisitLockStatement(ParseNode node, StorageModifier whereToStore) AddOpcode(new OpcodePush(OpcodeCall.ARG_MARKER_STRING)); AddOpcode(new OpcodePush(lockIdentifier)); AddOpcode(new OpcodePush(true)); - AddOpcode(new OpcodeCall("toggleflybywire()")); // add a pop to clear out the dummy return value from toggleflybywire() AddOpcode(new OpcodePop()); } diff --git a/src/kOS.Safe/Compilation/Opcode.cs b/src/kOS.Safe/Compilation/Opcode.cs index 22261d4c6..88da26605 100644 --- a/src/kOS.Safe/Compilation/Opcode.cs +++ b/src/kOS.Safe/Compilation/Opcode.cs @@ -1165,6 +1165,8 @@ public override void Execute(ICpu cpu) if (Direct) { functionPointer = cpu.GetValue(Destination); + if (functionPointer == null) + throw new KOSException("Attempt to call function failed - Value of function pointer for " + Destination + " is null."); } else // for indirect calls, dig down to find what's underneath the argument list in the stack and use that: { @@ -1265,7 +1267,6 @@ public override void Execute(ICpu cpu) { cpu.PushStack(delegateReturn); // And now leave the return value on the stack to be read. } - } /// @@ -1762,7 +1763,8 @@ public override void PopulateFromMLFields(List fields) public override void Execute(ICpu cpu) { - cpu.PushStack(cpu.MakeUserDelegate(EntryPoint)); + IUserDelegate pushMe = cpu.MakeUserDelegate(EntryPoint); + cpu.PushStack(pushMe); } public override string ToString() diff --git a/src/kOS.Safe/Execution/UserDelegate.cs b/src/kOS.Safe/Execution/UserDelegate.cs index 96d8222d2..8d670286f 100644 --- a/src/kOS.Safe/Execution/UserDelegate.cs +++ b/src/kOS.Safe/Execution/UserDelegate.cs @@ -28,11 +28,19 @@ public UserDelegate(ICpu cpu, int entryPoint, bool useClosure) EntryPoint = entryPoint; if (useClosure) CaptureClosure(); + else + Closure = new List(); // make sure it exists as an empty list so we don't have to have 'if null' checks everwywhere. } private void CaptureClosure() { Closure = cpu.GetCurrentClosure(); } + + public override string ToString() + { + return "UserDelegate( cpu=" + cpu.ToString() + ", entryPoint=" + EntryPoint.ToString() + ", Closure=" + Closure.ToString(); + } + } } diff --git a/src/kOS/Execution/CPU.cs b/src/kOS/Execution/CPU.cs index bb85ffd33..8f489b4c8 100644 --- a/src/kOS/Execution/CPU.cs +++ b/src/kOS/Execution/CPU.cs @@ -580,7 +580,7 @@ private Variable GetVariable(string identifier, bool barewordOkay = false, bool /// scope level, unless overwrite = true. /// /// variable to add - /// name of variable to adde + /// name of variable to add /// true if you want to make it at local depth /// true if it's okay to overwrite an existing variable public void AddVariable(Variable variable, string identifier, bool local, bool overwrite = false) @@ -600,14 +600,9 @@ public void AddVariable(Variable variable, string identifier, bool local, bool o if (whichDict.Variables.ContainsKey(identifier)) { if (whichDict.Variables[identifier].Value is BoundVariable) - { if (!overwrite) throw new KOSIdentiferClashException(identifier); - else - return; // no work to do - the bound variable is fine to leave in place. - } - else - whichDict.Variables.Remove(identifier); + whichDict.Variables.Remove(identifier); } whichDict.Variables.Add(identifier, variable); } @@ -703,8 +698,15 @@ public void SetNewLocal(string identifier, object value) /// value to put into it public void SetGlobal(string identifier, object value) { - Variable variable = new Variable {Name = identifier}; - AddVariable(variable, identifier, false, true); + Variable variable; + // Attempt to get it as a global. Make a new one if it's not found. + // This preserves the "bound-ness" of the variable if it's a + // BoundVariable, whereas unconditionally making a new Variable wouldn't: + if (! globalVariables.Variables.TryGetValue(identifier, out variable)) + { + variable = new Variable {Name = identifier}; + AddVariable(variable, identifier, false, true); + } variable.Value = value; } From ac9a30bef4b80b9f5d299866b691a658e61ff890 Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Tue, 14 Apr 2015 15:41:40 -0500 Subject: [PATCH 383/446] Fixed dumb overzealous deletion of eraseme's. (I ended up deleting an eraseme WriteLine AND the line that was adjacent to it - which removed the crucial toggleflybywire call.) Althought it wasn't the problem, when trying to fix it I also cleaned up SetLocal to be the same as SetGlobal in regards to respecting the BoundVariable-ness of existing values. I left that change in as well, even though it wasn't the problem, because that is the correct way to do it (although it would be weird for a bound variable to be LOCAL, SetLocal can end up being used on the global dictionary too if you do it from global scope, so it needs the logic there to.) --- src/kOS.Safe/Compilation/KS/Compiler.cs | 1 + src/kOS/Execution/CPU.cs | 9 +++++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/kOS.Safe/Compilation/KS/Compiler.cs b/src/kOS.Safe/Compilation/KS/Compiler.cs index 8a7996531..bab12216c 100644 --- a/src/kOS.Safe/Compilation/KS/Compiler.cs +++ b/src/kOS.Safe/Compilation/KS/Compiler.cs @@ -1989,6 +1989,7 @@ private void VisitLockStatement(ParseNode node, StorageModifier whereToStore) AddOpcode(new OpcodePush(OpcodeCall.ARG_MARKER_STRING)); AddOpcode(new OpcodePush(lockIdentifier)); AddOpcode(new OpcodePush(true)); + AddOpcode(new OpcodeCall("toggleflybywire()")); // add a pop to clear out the dummy return value from toggleflybywire() AddOpcode(new OpcodePop()); } diff --git a/src/kOS/Execution/CPU.cs b/src/kOS/Execution/CPU.cs index 8f489b4c8..d043f6e10 100644 --- a/src/kOS/Execution/CPU.cs +++ b/src/kOS/Execution/CPU.cs @@ -681,8 +681,13 @@ public object GetValue(object testValue, bool barewordOkay = false) /// value to put into it public void SetNewLocal(string identifier, object value) { - Variable variable = new Variable {Name = identifier}; - AddVariable(variable, identifier, true); + Variable variable; + VariableScope localDict = GetNestedDictionary(0); + if (! localDict.Variables.TryGetValue(identifier, out variable)) + { + variable = new Variable {Name = identifier}; + AddVariable(variable, identifier, true); + } variable.Value = value; } From f098d3dfedd94869e404582b7703233d2a2cbf65 Mon Sep 17 00:00:00 2001 From: TDW89 Date: Wed, 15 Apr 2015 00:30:07 +0100 Subject: [PATCH 384/446] AVAILABLETHRUST added to docs #713 --- doc/source/structures/vessels/vessel.rst | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/doc/source/structures/vessels/vessel.rst b/doc/source/structures/vessels/vessel.rst index 86b3cef4d..49b1243ee 100644 --- a/doc/source/structures/vessels/vessel.rst +++ b/doc/source/structures/vessels/vessel.rst @@ -35,6 +35,7 @@ All vessels share a structure. To get a variable referring to any vessel you can :attr:`BEARING` scalar (deg) relative heading to this vessel :attr:`HEADING` scalar (deg) Absolute heading to this vessel :attr:`MAXTHRUST` scalar Sum of active maximum thrusts + :attr:`AVAILABLETHRUST` scalar Sum of active limited maximum thrusts :attr:`FACING` :struct:`Direction` The way the vessel is pointed :attr:`MASS` scalar (metric tons) Mass of the ship :attr:`WETMASS` scalar (metric tons) Mass of the ship fully fuelled @@ -93,6 +94,13 @@ All vessels share a structure. To get a variable referring to any vessel you can :access: Get only Sum of all the Max thrust of all the currently active engines In Kilonewtons. + +.. attribute:: vessel:AVAILABLETHRUST + + :type: scalar + :access: Get only + + Sum of all the Max thrust of all the currently active engines taking into acount their throttlelimits. Result is in Kilonewtons. .. attribute:: Vessel:FACING From 4c30da54b4c58524e3a4617aa8fe7ea20a4564e0 Mon Sep 17 00:00:00 2001 From: TDW89 Date: Wed, 15 Apr 2015 00:41:37 +0100 Subject: [PATCH 385/446] Correcting sensors docs --- doc/source/bindings.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/bindings.rst b/doc/source/bindings.rst index 189fc279f..938a19ed0 100644 --- a/doc/source/bindings.rst +++ b/doc/source/bindings.rst @@ -66,7 +66,7 @@ VESSELNAME Same as SHIP:VESSELNAME ALTITUDE Same as SHIP:ALTITUDE APOAPSIS Same as SHIP:APOAPSIS PERIAPSIS Same as SHIP:PERIAPSIS -SENSOR Same as SHIP:SENSOR +SENSORS Same as SHIP:SENSORS SRFPROGRADE Same as SHIP:SRFPROGRADE SRFREROGRADE Same as SHIP:SRFREROGRADE OBT Same as SHIP:OBT From 73b1097edfc385b90cc65f75dbf50547bb8314bd Mon Sep 17 00:00:00 2001 From: TDW89 Date: Wed, 15 Apr 2015 00:56:46 +0100 Subject: [PATCH 386/446] Correcting sensor docs --- doc/source/structures/vessels/sensor.rst | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/doc/source/structures/vessels/sensor.rst b/doc/source/structures/vessels/sensor.rst index bbad06b8a..4a96b45e0 100644 --- a/doc/source/structures/vessels/sensor.rst +++ b/doc/source/structures/vessels/sensor.rst @@ -11,7 +11,7 @@ The type of structures returned by :ref:`LIST SENSORS IN SOMEVARIABLE Date: Wed, 15 Apr 2015 01:17:55 +0100 Subject: [PATCH 387/446] Sticking a pilot in front of the controls #633 --- doc/source/commands/flight/pilot.rst | 32 ++++++++++++++-------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/doc/source/commands/flight/pilot.rst b/doc/source/commands/flight/pilot.rst index 2734e6535..9a4383be9 100644 --- a/doc/source/commands/flight/pilot.rst +++ b/doc/source/commands/flight/pilot.rst @@ -84,39 +84,39 @@ Will ensure that the throttle will be 0 when execution stops. These suffixes all Returns the pilot's input for the throttle. This is the only ``PILOT`` variable that is settable and is used to set the throttle upon termination of the current **kOS** program. .. _SHIP CONTROL PILOTYAW: -.. object:: SHIP:CONTROL:YAW +.. object:: SHIP:CONTROL:PILOTYAW Returns the pilot's rotation input about the "up" vector as the pilot faces forward. Essentially left :math:`(-1)` or right :math:`(+1)`. .. _SHIP CONTROL PILOTPITCH: -.. object:: SHIP:CONTROL:PITCH +.. object:: SHIP:CONTROL:PILOTPITCH Returns the pilot's rotation input about the starboard vector up :math:`(+1)` or down :math:`(-1)`. .. _SHIP CONTROL PILOTROLL: -.. object:: SHIP:CONTROL:ROLL +.. object:: SHIP:CONTROL:PILOTROLL Returns the pilot's rotation input about the logintudinal axis of the ship left-wing-down :math:`(-1)` or left-wing-up :math:`(+1)`. .. _SHIP CONTROL PILOTROTATION: -.. object:: SHIP:CONTROL:ROTATION +.. object:: SHIP:CONTROL:PILOTROTATION Returns the pilot's rotation input as a :struct:`Vector` object containing ``(YAW, PITCH, ROLL)`` in that order. .. _SHIP CONTROL PILOTYAWTRIM: -.. object:: SHIP:CONTROL:YAWTRIM +.. object:: SHIP:CONTROL:PILOTYAWTRIM Returns the pilot's input for the ``YAW`` of the rotational trim. .. _SHIP CONTROL PILOTPITCHTRIM: -.. object:: SHIP:CONTROL:PITCHTRIM +.. object:: SHIP:CONTROL:PILOTPITCHTRIM Returns the pilot's input for the ``PITCH`` of the rotational trim. .. _SHIP CONTROL PILOTROLLTRIM: -.. object:: SHIP:CONTROL:ROLLTRIM +.. object:: SHIP:CONTROL:PILOTROLLTRIM Returns the pilot's input for the ``ROLL`` of the rotational trim. @@ -124,47 +124,47 @@ Will ensure that the throttle will be 0 when execution stops. These suffixes all .. _SHIP CONTROL PILOTFORE: -.. object:: SHIP:CONTROL:FORE +.. object:: SHIP:CONTROL:PILOTFORE Returns the the pilot's input for the translation of the ship forward :math:`(+1)` or backward :math:`(-1)`. .. _SHIP CONTROL PILOTSTARBOARD: -.. object:: SHIP:CONTROL:STARBOARD +.. object:: SHIP:CONTROL:PILOTSTARBOARD Returns the the pilot's input for the translation of the ship to the right :math:`(+1)` or left :math:`(-1)` from the pilot's perspective. .. _SHIP CONTROL PILOTTOP: -.. object:: SHIP:CONTROL:TOP +.. object:: SHIP:CONTROL:PILOTTOP Returns the the pilot's input for the translation of the ship up :math:`(+1)` or down :math:`(-1)` from the pilot's perspective. .. _SHIP CONTROL PILOTTRANSLATION: -.. object:: SHIP:CONTROL:TRANSLATION +.. object:: SHIP:CONTROL:PILOTTRANSLATION Returns the the pilot's input for translation as a :struct:`Vector` ``(STARBOARD, TOP, FORE)``. .. _SHIP CONTROL PILOTWHEELSTEER: -.. object:: SHIP:CONTROL:WHEELSTEER +.. object:: SHIP:CONTROL:PILOTWHEELSTEER Returns the the pilot's input for wheel steering left :math:`(-1)` or right :math:`(+1)`. .. _SHIP CONTROL PILOTWHEELTHROTTLE: -.. object:: SHIP:CONTROL:WHEELTHROTTLE +.. object:: SHIP:CONTROL:PILOTWHEELTHROTTLE Returns the the pilot's input for the wheels to move the ship forward :math:`(+1)` or backward :math:`(-1)` while on the ground. .. _SHIP CONTROL PILOTWHEELSTEERTRIM: -.. object:: SHIP:CONTROL:WHEELSTEERTRIM +.. object:: SHIP:CONTROL:PILOTWHEELSTEERTRIM Returns the the pilot's input for the trim of the wheel steering. .. _SHIP CONTROL PILOTWHEELTHROTTLETRIM: -.. object:: SHIP:CONTROL:WHEELTHROTTLETRIM +.. object:: SHIP:CONTROL:PILOTWHEELTHROTTLETRIM Returns the the pilot's input for the trim of the wheel throttle. .. _SHIP CONTROL PILOTNEUTRAL: -.. object:: SHIP:CONTROL:NEUTRAL +.. object:: SHIP:CONTROL:PILOTNEUTRAL Returns true or false if the pilot is active or not. From 4245c47bd1cf9f8c0514dd66de55e9d6a66623ce Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Tue, 14 Apr 2015 20:01:03 -0500 Subject: [PATCH 388/446] Fixes #738 - 'fixedupdate' docs. --- CHANGELOG.md | 30 ++++- doc/source/changes.rst | 31 ++++++ doc/source/general/cpu_hardware.rst | 163 +++++++++++++--------------- doc/source/index.rst | 1 + doc/source/language/flow.rst | 2 +- 5 files changed, 134 insertions(+), 93 deletions(-) create mode 100644 doc/source/changes.rst diff --git a/CHANGELOG.md b/CHANGELOG.md index a80e73068..d89794340 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,17 @@ can handle recursion, and can use local variable scoping. You can build a library of your own function calls and load them into your script. +**New Documenatation change page**: + + For those users who just want to see what new features + exist without reading the entire documentation again + from scratch, we have created a changes page in the main documentation: + + * New Changes Page: http://ksp-kos.github.io/KOS_DOC/changes.html + + For the features mentioned below, you can go to the page above + and get a more verbose description of the new features. + ###BREAKING: - **RECOMPILE YOUR KSM FILES!!!** - changes to the kOS machine code that were needed to support variable scoping ended up invalidating @@ -23,6 +34,12 @@ script. Compiling to a KSM file will probably no longer be a reliable way to make your code smaller, but we also intend to increase the volume capacity to compensate. +- *CONFIG:IPU should probably be slightly increased* + There's a few more instructions for some of the same amount of source + code, so you might need to increase your CONFIG:IPU to get the same + programs to continue working. Although the default setting for 0.17.0 + is higher, it will not overwrite your settings if you have a config file + already present from earlier installations. - *DECLARE has a new syntax* DECLARE _VARNAME_ now requires an initializier syntax as follows: - DECLARE _VARNAME_ TO _VALUE_. @@ -52,10 +69,10 @@ script. Synopsis:: // Silly example function to build a string of padded chars. - DECLARE FUNCTION padString { - DECLARE PARAMETER ch, howmany + FUNCTION padString { + PARAMETER ch, howmany - DECLARE str to "". // makes str a local variable. + LOCAL str to "". // makes str a local variable. UNTIL howmany <= 0 { set str to str + ch. @@ -89,6 +106,13 @@ script. and here: http://ksp-kos.github.io/KOS/language/variables.html#scoping-rules +- *Physics update* + In the past kOS performed its work during the animation frame + updates. Now it does so during the physics updates, as it + should. One effect of this is that if you have a frame rate + of more than 25, then you'll need to increase your CONFIG:IPU + to get the same general amount of code running in the same time. + ###Bug Fixes: - For iterator no longer name clashes because it's not global anymore. It used to be that if you had two FOR _VAR_ IN _THING_'s in the same diff --git a/doc/source/changes.rst b/doc/source/changes.rst new file mode 100644 index 000000000..9b728529e --- /dev/null +++ b/doc/source/changes.rst @@ -0,0 +1,31 @@ +.. _changes: + +Changes from version to version +=============================== + +This is a slightly more verbose version of the new features +mentioned in the CHANGELOG, specifically for new features and for +users familiar with older versions of the documenation who want +only a quick update to the docs without reading the entire set +of documenation again from scratch. + +.. contents:: + :local: + :depth: 3 + +Changes in 0.17.0 +----------------- + +Physics Ticks not Update Ticks +:::::::::::::::::::::::::::::: + +The updates have been :ref:`moved to the physics update ` +portaion of Unity, instead of the animation frame rate updates. +This may affect your preferred CONFIG:IPU setting. The new move +creates a much more uniform preformance across all users, without +penalizing the users of faster computers anymore. (Previously, +if your computer was faster, you'd be charged more electricity as +the updates came more often). + + + diff --git a/doc/source/general/cpu_hardware.rst b/doc/source/general/cpu_hardware.rst index a284500c8..a226d55ce 100644 --- a/doc/source/general/cpu_hardware.rst +++ b/doc/source/general/cpu_hardware.rst @@ -3,26 +3,81 @@ The kOS CPU hardware ==================== -While it's possible to write some software without knowing anything about the underlying computer hardware, and there are good design principles that state one should never make assumptions about the computer hardware when writing software, there are still some basic things about how computers work in general that a good programmer needs to be aware of to write good code. Along those lines, the KSP player writing a Kerboscript program needs to know a few basic things about how the simulated kOS CPU operates in order to be able to write more advanced scripts. This page contains that type of information. +While it's possible to write some software without knowing anything +about the underlying computer hardware, and there are good design +principles that state one should never make assumptions about the +computer hardware when writing software, there are still some basic +things about how computers work in general that a good programmer +needs to be aware of to write good code. Along those lines, the KSP +player writing a Kerboscript program needs to know a few basic things +about how the simulated kOS CPU operates in order to be able to write +more advanced scripts. This page contains that type of information. .. contents:: :local: :depth: 2 +.. _physics tick: + Update Ticks and Physics Ticks ------------------------------ -Kerbal Space Program simulates the universe by running the universe in small incremental time intervals that for the purpose of this document, we will call "**physics ticks**\ ". The exact length of time for a physics tick varies as the program runs. One physics tick might take 0.09 seconds while the next one might take 0.085 seconds. (The default setting for the rate of physics ticks is 25 ticks per second, just to give a ballpark figure, but you **must not** write any scripts that depend on this assumption because it's a setting the user can change, and it can also vary a bit during play depending on system load. The setting is a target goal for the game to try to achieve, not a guarantee. If it's a fast computer with a speedy animation frame rate, it will try to run physics ticks less often than it runs animation frame updates, to try to make the physics tick rate match this setting. On the other hand, If it's a slow computer, it will try to sacrifice animation frame rate to archive this number (meaning physics get calculated faster than you can see the effects.) The game will try as hard as it can to keep the physics rate matched to the setting, not faster and not slower, because when the physics rate isn't steady, the simulation breaks down and starts making erroneous things happen, like miscalculating forces on part joints and breaking ships. But however hard the game tries to stick to the setting, it can't do it 100% the same every single moment, thus the need to actually measure elapsed time in the TIME variable in your scripts. - -The entire simulated universe is utterly frozen during the duration of a physics tick. For example, if one physics tick occurs at timestamp 10.51 seconds, and the next physics tick occurs 0.08 seconds later at timestamp 10.59 seconds, then during the entire intervening time, at timestamp 10.52 seconds, 10.53 seconds, and so on, nothing moves. The clock is frozen at 10.51 seconds, and the fuel isn't being consumed, and the vessel is at the same position. On the next physics tick at 10.59 seconds, then all the numbers are updated. The full details of the physics ticks system are more complex than that, but that quick description is enough to describe what you need to know about how kOS's CPU works. - -There is another kind of time tick called an **Update tick**. It is similar to, but different from, a **physics tick**. *Update ticks* often occur a bit more often than *physics ticks*. Update ticks are exactly the same thing as your game's Frame Rate. Each time your game renders another animation frame, it performs another Update tick. On a good gaming computer with fast speed and a good graphics card, It is typical to have about 2 or even 3 *Update ticks* happen within the time it takes to have one *physics tick* happen. On a slower computer, it is also possible to go the other way and have *Update ticks* happening *less* frequently than *physics tics*. Basically, look at your frame rate. Is it higher than 25 fps? If so, then your *update ticks* happen faster than your *physics ticks*, otherwise its the other way around. +.. note:: + .. versionadded:: 0.17 + Previous versions of kOS used to execute program code during the + Update phase, rather than the more correct Physics Update phase. + +Kerbal Space Program simulates the universe by running the universe in +small incremental time intervals that for the purpose of this +document, we will call "**physics ticks**". The exact length of time +for a physics tick varies as the program runs. One physics tick might +take 0.09 seconds while the next one might take 0.085 seconds. (The +default setting for the rate of physics ticks is 25 ticks per second, +just to give a ballpark figure, but you **must not** write any scripts +that depend on this assumption because it's a setting the user can +change, and it can also vary a bit during play depending on system +load. The setting is a target goal for the game to try to achieve, not +a guarantee. If it's a fast computer with a speedy animation frame +rate, it will try to run physics ticks less often than it runs +animation frame updates, to try to make the physics tick rate match +this setting. On the other hand, If it's a slow computer, it will try +to sacrifice animation frame rate to archive this number (meaning +physics get calculated faster than you can see the effects.) + +When calculating physics formulas, you need to actually measure +elapsed time in the TIME:SECONDS variable in your scripts. + +The entire simulated universe is utterly frozen during the duration of +a physics tick. For example, if one physics tick occurs at timestamp +10.51 seconds, and the next physics tick occurs 0.08 seconds later at +timestamp 10.59 seconds, then during the entire intervening time, at +timestamp 10.52 seconds, 10.53 seconds, and so on, nothing moves. The +clock is frozen at 10.51 seconds, and the fuel isn't being consumed, +and the vessel is at the same position. On the next physics tick at +10.59 seconds, then all the numbers are updated. The full details of +the physics ticks system are more complex than that, but that quick +description is enough to describe what you need to know about how +kOS's CPU works. + +There is another kind of time tick called an **Update tick**. It is +similar to, but different from, a **physics tick**. *Update ticks* +often occur a bit more often than *physics ticks*. Update ticks are +exactly the same thing as your game's Frame Rate. Each time your game +renders another animation frame, it performs another Update tick. On a +good gaming computer with fast speed and a good graphics card, It is +typical to have about 2 or even 3 *Update ticks* happen within the +time it takes to have one *physics tick* happen. On a slower computer, +it is also possible to go the other way and have *Update ticks* +happening *less* frequently than *physics tics*. Basically, look at +your frame rate. Is it higher than 25 fps? If so, then your *update +ticks* happen faster than your *physics ticks*, otherwise its the +other way around. .. note:: - The kOS CPU runs every **update tick** rather than every **physics tick**. + As of version 0.17.0, The kOS CPU runs every *physics tick*. -On each update tick, each kOS CPU that's within physics range (i.e. 2.5 km), wakes up and performs the following steps, in this order: +On each physics tick, each kOS CPU that's within physics range (i.e. 2.5 km), wakes up and performs the following steps, in this order: 1. Run the conditional checks of all TRIGGERS (see below) 2. For any TRIGGERS who's conditional checks are true, execute the entire body of the trigger. @@ -51,14 +106,14 @@ Triggers are all of the following: is sitting still on the WAIT command. -The way these work is that once per **update tick**, all the LOCK expressions which directly affect flight control are re-executed, and then each conditional trigger's condition is checked, and if true, then the entire body of the trigger is executed all the way to the bottom \*before any more instructions of the main body are executed\*. This means that execution of a trigger never gets interleaved with the main code. Once a trigger happens, the entire trigger occurs all in one go before the rest of the main body continues. +The way these work is that once per **physics tick**, all the LOCK expressions which directly affect flight control are re-executed, and then each conditional trigger's condition is checked, and if true, then the entire body of the trigger is executed all the way to the bottom \*before any more instructions of the main body are executed\*. This means that execution of a trigger never gets interleaved with the main code. Once a trigger happens, the entire trigger occurs all in one go before the rest of the main body continues. Do Not Loop a Long Time in a Trigger Body! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Because the entire body of a trigger will execute all the way to the bottom on *within a single* **update tick**, *before* any other code continues, it is vital that you not write code in a trigger body that takes a long time to execute. The body of a trigger must be kept quick. An infinite loop in a trigger body could literally freeze all of KSP, because the kOS mod will never finish executing its update. +Because the entire body of a trigger will execute all the way to the bottom on *within a single* **physics tick**, *before* any other code continues, it is vital that you not write code in a trigger body that takes a long time to execute. The body of a trigger must be kept quick. An infinite loop in a trigger body could literally freeze all of KSP, because the kOS mod will never finish executing its update. -*As of kOS version 0.14 and higher, this condition is now being checked for* and the script will be **terminated with a runtime error** if the triggers like WHEN/THEN and ON take more than :attr:`Config:IPU` instructions to execute. The sum total of all the code within your WHEN/THEN and ON code blocks MUST be designed to complete within one update tick. +*As of kOS version 0.14 and higher, this condition is now being checked for* and the script will be **terminated with a runtime error** if the triggers like WHEN/THEN and ON take more than :attr:`Config:IPU` instructions to execute. The sum total of all the code within your WHEN/THEN and ON code blocks MUST be designed to complete within one physicd tick. **This may seem harsh**. Ideally, kOS would only generate a runtime error if it thought your script was stuck in an **infinite loop**, and allow it to exceed the :attr:`Config:IPU` number of instructions if it was going to finish and just needed a little longer to to finish its work. But, because of a well known problem in computer science called `the halting problem `__, it's literally impossible for kOS, or any other software for that matter, to detect the difference between another program's infinite loop versus another program's loop that will end soon. kOS only knows how long your triggers have taken so far, not how long they're going to take before they're done, or even if they'll be done. @@ -69,26 +124,26 @@ If it does not make the error go away, then you will need to redesign your scrip But I Want a Loop!! ~~~~~~~~~~~~~~~~~~~ -If you want a trigger body that is meant to loop, the only acceptable way to do it is to design it to execute just once, but then use the PRESERVE keyword to keep the trigger around for the next update. Thus your trigger becomes a sort of "loop" that executes one iteration per **update tick**. +If you want a trigger body that is meant to loop, the only acceptable way to do it is to design it to execute just once, but then use the PRESERVE keyword to keep the trigger around for the next physics update. Thus your trigger becomes a sort of "loop" that executes one iteration per **physics tick**. -It is also important to consider the way triggers execute for performance reasons too. Every time you write an expression for a trigger, you are creating a bit of code that gets executed fully to the end before your main body will continue, once each **update tick**. A complex expression in a trigger condition, which in turn calls other complex LOCK expressions, which call other complex LOCK expressions, and so on, may cause kOS to bog itself down during each update. (And as of version 0.14, it may cause kOS to stop your program and issue a runtime error if it's taking too long.) +It is also important to consider the way triggers execute for performance reasons too. Every time you write an expression for a trigger, you are creating a bit of code that gets executed fully to the end before your main body will continue, once each **physics tick**. A complex expression in a trigger condition, which in turn calls other complex LOCK expressions, which call other complex LOCK expressions, and so on, may cause kOS to bog itself down during each physics tick. (And as of version 0.14, it may cause kOS to stop your program and issue a runtime error if it's taking too long.) -Because of how WAIT works, you cannot put a WAIT statement inside a trigger. If you try, it will have no effect. This is because WAIT requires the ability of the program to go to sleep and then in a later update tick, continue from where it left off. Because triggers run to the bottom entirely within one update tick, they can't do that. +Because of how WAIT works, you cannot put a WAIT statement inside a trigger. If you try, it will have no effect. This is because WAIT requires the ability of the program to go to sleep and then in a later physics tick, continue from where it left off. Because triggers run to the bottom entirely within one physics tick, they can't do that. Wait!!! ~~~~~~~ -Any WAIT statement causes the kerboscript program to immediately stop executing the main program where it is, even if far fewer than :attr:`Config:IPU` instructions have been executed in this **update tick**. It will not continue the execution until at least the next **update tick**, when it will check to see if the WAIT condition is satisfied and it's time to wake up and continue. +Any WAIT statement causes the kerboscript program to immediately stop executing the main program where it is, even if far fewer than :attr:`Config:IPU` instructions have been executed in this **physics tick**. It will not continue the execution until at least the next **physics tick**, when it will check to see if the WAIT condition is satisfied and it's time to wake up and continue. -Therefore ANY WAIT of any kind will guarantee that your program will allow at least one **update tick** to have happened before continuing. If you attempt to:: +Therefore ANY WAIT of any kind will guarantee that your program will allow at least one **physics tick** to have happened before continuing. If you attempt to:: WAIT 0.001. -But the duration of the next update tick is actually 0.09 seconds, then you will actually end up waiting at least 0.09 seconds. It is impossible to wait a unit of time smaller than one update tick. Using a very small unit of time in a WAIT statement is an effective way to force the CPU to allow a update tick to occur before continuing to the next line of code. Similarly, if you just say:: +But the duration of the next physics tick is actually 0.09 seconds, then you will actually end up waiting at least 0.09 seconds. It is impossible to wait a unit of time smaller than one physics tick. Using a very small unit of time in a WAIT statement is an effective way to force the CPU to allow a physics tick to occur before continuing to the next line of code. Similarly, if you just say:: WAIT UNTIL TRUE. -Then even though the condition is immediately true, it will still wait one update tick to discover this fact and continue. +Then even though the condition is immediately true, it will still wait one physics tick to discover this fact and continue. .. note:: @@ -101,79 +156,9 @@ Then even though the condition is immediately true, it will still wait one updat The Frozen Universe ------------------- -Each **update** *tick*, the kOS mod wakes up and runs through all the currently loaded CPU parts that are in "physics range" (i.e. 2.5 km), and executes a batch of instructions from your script code that's on them. It is important to note that during the running of this batch of instructions, because no **physics ticks** are happening during it, none of the values that you might query from the KSP system will change. The clock time returned from the TIME variable will keep the same value throughout. The amount of fuel left will remain fixed throughout. The position and velocity of the vessel will remaining fixed throughout. It's not until the next physics tick occurs that those values will change to new numbers. It's typical that several lines of your kerboscript code will run during a single update tick. +Each **physics** *tick*, the kOS mod wakes up and runs through all the currently loaded CPU parts that are in "physics range" (i.e. 2.5 km), and executes a batch of instructions from your script code that's on them. It is important to note that during the running of this batch of instructions, because no **physics ticks** are happening during it, none of the values that you might query from the KSP system will change. The clock time returned from the TIME variable will keep the same value throughout. The amount of fuel left will remain fixed throughout. The position and velocity of the vessel will remaining fixed throughout. It's not until the next physics tick occurs that those values will change to new numbers. It's typical that several lines of your kerboscript code will run during a single physics tick. Effectively, as far as the *simulated* universe can tell, it's as if your script runs several instructions in literally zero amount of time, and then pauses for a fraction of a second, and then runs more instructions in literally zero amount of time, then pauses for a fraction of a second, and so on, rather than running the program in a smoothed out continuous way. -If your animation rate is slow enough, it gets even weirder. If your animation *update ticks* occur less often than your *physics ticks*, then it's as if your program spends the majority of the time paused, and only occasionally wakes up to execute a short burst of instructions. - -Because of the difference between *update ticks* and *physics ticks*, it's entirely possible that your kOS script runs multiple updates in a row while the universe is still frozen, or it's possible to go the other way around and have the universe move more than one physics tick before your program has time to notice and react. A well written kOS script should be able to handle both cases. - This is a vital difference between how a kOS CPU behaves versus how a real world computer behaves. In a real world computer, you would know for certain that time will pass, even if it's just a few picoseconds, between the execution of one statement and the next. -So Why Does This Matter? -~~~~~~~~~~~~~~~~~~~~~~~~ - -The reason this matters is because of code that tries to do things like this: Imagine something like this inside a script designed to hover in place:: - - PRINT "Waiting until altitude is". - PRINT "holding stable within 0.1 meters.". - - SET PREV_ALT TO -99999. // bogus start value - UNTIL ABS( PREV_ALT - SHIP:ALTITUDE ) < 0.1 { - - SET PREV_ALT TO SHIP:ALTITUDE. - - // Assume there's fancy PID controller - // commands here, omitted for this example. - - } - -This bit of code, if you assume you've written a nice bit of code where the comment is, looks like it would make sense at first. It looks like it should work. It records the previous altitude at the start of the loop body, and if the altitude hasn't changed by much by the start of the next loop, it assumes the altitude has become stable and it stops. - -BUT, due to the frozen nature of the measurements during a **physics tick**, it's entirely possible, and quite likely, that the loop would exit prematurely because no simulation time has passed between the two altitude measurements. The previous altitude and the current altitude are the same. Not because the vessel has no vertical motion, but because the loop is executing fast enough to finish more than one iteration within the same **physics tick**. The two altitude measurements are the same because no time has passed in the simulated universe. - -The Fix: Wait for Time to Change -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -If you are executing a loop like the one above in which it is absolutely vital that the next iteration of the loop must occur in a *different* **physics tick** than the previous one, so that it can take *new* measurements that are different, the solution is to use a WAIT statement that will delay until there's evidence that the physics clock has moved a tick. - -The most effective way to do that is to check the :ref:`time` and see if it's different than it was before. As long as you are still within the same *physics tick*, the TIME will not move:: - - PRINT "Waiting until altitude is holding stable within 0.1 meters.". - - SET PREV_ALT TO -99999. // bogus start value - UNTIL ABS( PREV_ALT - SHIP:ALTITUDE ) < 0.1 { - - SET PREV_ALT TO SHIP:ALTITUDE. - - // Assume there's fancy PID controller - // commands here, omitted for this example. - - SET TIMESTAMP TO TIME:SECONDS. - WAIT UNTIL TIME:SECONDS > TIMESTAMP. // clock will not move - // until we are in a new - // physics tick. - } - -A More Elegant Solution -~~~~~~~~~~~~~~~~~~~~~~~ - -Thanks to user *Cairan*, who suggested this very good idea in the -forums. You may put this code up near the top of your script:: - - // force it to trigger immediately the first time through - SET LASTPHYS TO -99999. - - LOCK PHYSICS TO MIN(1,FLOOR((TIME:SECONDS-LASTPHYS) / 0.04 )). - - WHEN PHYSICS THEN { - SET LASTPHYS TO TIME:SECONDS. - - // Store your measurements from - // the physical world here during - // the body of this WHEN - - PRESERVE. - } - diff --git a/doc/source/index.rst b/doc/source/index.rst index 3868f6e45..c583d2699 100644 --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -20,6 +20,7 @@ Welcome to the **kOS** Documentation Website! Structures Addons Contribute + Changes About Introduction to **kOS** and **KerboScript** diff --git a/doc/source/language/flow.rst b/doc/source/language/flow.rst index 7295ee965..97869b049 100644 --- a/doc/source/language/flow.rst +++ b/doc/source/language/flow.rst @@ -87,7 +87,7 @@ Every time you read the value of the "variable", it executes the expression again. .. note:: - If a ``LOCK`` expression is used with a flight control such as ``THROTTLE`` or ``STEERING``, then it will get continually evaluated in the background :ref:`each update tick `. + If a ``LOCK`` expression is used with a flight control such as ``THROTTLE`` or ``STEERING``, then it will get continually evaluated in the background :ref:`each physics tick `. .. index:: UNLOCK .. _unlock: From f5658f9add69dac4afee294cc5cd9594a150ae31 Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Tue, 14 Apr 2015 20:14:30 -0500 Subject: [PATCH 389/446] Changed the 'about' document to match the copyright document. --- doc/source/about.rst | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/doc/source/about.rst b/doc/source/about.rst index 45f536ca8..7b0d1e362 100644 --- a/doc/source/about.rst +++ b/doc/source/about.rst @@ -3,8 +3,7 @@ About **kOS** and **KerboScript** ================================= -kOS was originally created by Nivekk. It is under `active development`_ by `Chris Woerz`_ and `Steven Mading`_. +kOS was originally created by Nivekk. +It is under `active development`_ by the +`kOS Team `_ and is licensed under terms of GNU General Public License Version 3, 29 June 2007, Copyright © 2007 `Free Software Foundation, Inc. `_ -.. _active development: https://github.com/KSP-KOS -.. _Chris Woerz: https://github.com/erendrake -.. _Steven Mading: https://github.com/Dunbaratu From 7b5a4bcb22d1c55d0a159ca2841b76f50c303596 Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Tue, 14 Apr 2015 20:35:15 -0500 Subject: [PATCH 390/446] Added mention of WARPMODE, and made warp table. --- doc/source/bindings.rst | 6 ++++ doc/source/commands/flight/warp.rst | 44 +++++++++++++++++++++++++++-- 2 files changed, 48 insertions(+), 2 deletions(-) diff --git a/doc/source/bindings.rst b/doc/source/bindings.rst index 189fc279f..1d3cf81b5 100644 --- a/doc/source/bindings.rst +++ b/doc/source/bindings.rst @@ -251,6 +251,12 @@ TIME is the time since the entire saved game campaign started, in the kerbal universe's time. i.e. TIME = 0 means a brand new campaign was just started. +WARPING +~~~~~~~ + +Time warp can be controlled with WARP, and WARPMODE. See +:ref:`WARP ` + Config ------ diff --git a/doc/source/commands/flight/warp.rst b/doc/source/commands/flight/warp.rst index 28280a62a..e42bc5891 100644 --- a/doc/source/commands/flight/warp.rst +++ b/doc/source/commands/flight/warp.rst @@ -6,7 +6,47 @@ Time Warping .. global:: WARP - The :global:`WARP` global variable can be set to change the game warp to a value between 0 and 7:: + The :global:`WARP` global variable can be set to change the game warp to a value between 0 and 7 (for rails warp) or 0 to 3 (for physics warp):: SET WARP TO 5. // Sets warp to 1000x - SET WARP TO 0. // Sets warp to 0x (real time) + SET WARP TO 0. // Sets warp to 1x (real time) + + You may also choose which warp mode you wish the WARP command + to invoke- physics warp (capped at 4x) or rails warp:: + + SET WARPMODE TO "PHYSICS". + SET WARPMODE TO "RAILS". + + WARPMODE can be set to a string to choose the warp. It must be + one of the two strings mentioned above. + + The difference is the same as that experienced in the game between + physics warp and 'rails' warp (sometimes called 'time warp') allthough + that term is confusingly ambiguous. + +.. table:: RAILS WARP MODES + + ==== ======= + MODE MEANING + ==== ======= + 0 1x + 1 5x + 2 10x + 3 50x + 4 100x + 5 1000x + 6 10000x + 7 100000x + ==== ======= + +.. table:: PHYSICS WARP MODES + + ==== ======= + MODE MEANING + ==== ======= + 0 1x + 1 2x + 2 3x + 3 4x + ==== ======= + From d761549dc5b5f48f38115270af258d7577514823 Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Tue, 14 Apr 2015 21:08:26 -0500 Subject: [PATCH 391/446] Fixes 659 - documenting lefthandedness --- doc/source/math/direction.rst | 12 ++++++++++++ doc/source/math/ref_frame.rst | 33 ++++++++++++++++++++++++++++++++- doc/source/math/vector.rst | 10 ++++++++++ 3 files changed, 54 insertions(+), 1 deletion(-) diff --git a/doc/source/math/direction.rst b/doc/source/math/direction.rst index 3922b6398..9109356de 100644 --- a/doc/source/math/direction.rst +++ b/doc/source/math/direction.rst @@ -11,6 +11,12 @@ Directions In your thinking, you can largely think of Directions as being Rotations and Rotations as being Directions. The two concepts can be used interchangably. Used on its own to steer by, a rotation from the default XYZ axes of the universe into a new rotation does in fact provide an absolute direction, thus the name Direction for these objects even though in reality they are just Rotations. It's important to know that Directions are just rotations because you can use them to modify other directions or vectors. +.. note:: + When dealing with Directions (which are Rotations) in kOS, it is + important to remember that KSP uses a :ref:`left-handed ` + coordinate system. This affects the convention of which rotation + direction is positive when calculating angles. + Creation -------- @@ -70,6 +76,12 @@ Creation SET newDir to pitchUp30*SHIP:FACING. LOCK STEERING TO newDir. +.. note:: + The fact that KSP is using a :ref:`left-handed ` + coordinate system is important to keep in mind when visualizing + the meaning of an ANGLEAXIS function call. It affects which + direction is positive when calculating angles. + .. function:: ROTATEFROMTO(fromVec,toVec) A :struct:`Direction` can be created with the ROTATEFROMTO function. It is *one of the infinite number of* rotatations that could rotate vector *fromVec* to become vector *toVec* (or at least pointing in the same direction as toVec, since fromVec and toVec need not be the same magnitude). Note the use of the phrase "**infinite number of**". Because there's no guarantee about the roll information, there are an infinite number of rotations that could qualify as getting you from one vector to another, because there's an infinite number of roll angles that could result and all still fit the requirement:: diff --git a/doc/source/math/ref_frame.rst b/doc/source/math/ref_frame.rst index 521928061..507367fbd 100644 --- a/doc/source/math/ref_frame.rst +++ b/doc/source/math/ref_frame.rst @@ -3,7 +3,38 @@ Reference Frames ================ -This page describes the :math:`(x,y,z)` reference frame used for most of **kOS**'s vectors. The coordinate system of Kerbal Space Program does some strange things that don't make a lot of sense at first. For nomenclature, the following terms are used in this documentation: +This page describes the :math:`(x,y,z)` reference frame used for most +of **kOS**'s vectors. kOS inherits its reference frame mostly from the +base Kerbal Space Program game itself. The coordinate system of Kerbal +Space Program does some strange things that don't make a lot of sense +at first. For nomenclature, the following terms are used in this +documentation: + + +.. _left-handed: + +.. note:: + Be aware that Kerbal Space program (and in fact many of the games + based on the Unity game engine) uses a **LEFT-handed** coordinate + system. kOS inherits this behavior from KSP. + +In all the the reference frames mentioned below, the orientation of +the axes is **left-handed**. This means that if you imagine opening your +palm and pointing your fingers down the x-axis, then curling your fingers +in the direction of the y-axis, then sticking your thumb up, that the +direction your thumb would have to be pointing to accomplish this task +is the direction of the z-axis **if and only if** you used your left +hand to perform those steps. (If you do those steps with your right +hand, you get a z-axis in the opposite direction and that is known as +a **right handed** coordinate system). + +This is an important thing to keep in mind, as most mathematics +and physics textbooks tend to draw examples using a right handed +coordinate system, and most students become familiar with that +convention first. But for a variety of reasons, many computer +graphics systems have a tradition of using left-handed systems +instead, and Kerbal Space Program is one of them. + .. _ship-raw: .. index:: SHIP-RAW (Reference Frame) diff --git a/doc/source/math/vector.rst b/doc/source/math/vector.rst index a68058815..0e636566d 100644 --- a/doc/source/math/vector.rst +++ b/doc/source/math/vector.rst @@ -21,6 +21,10 @@ Creation Here, a new :struct:`Vector` called ``vec`` is created . The object :struct:`Vector` represents a `three-dimensional euclidean vector `__ To deeply understand most vectors in kOS, you have to understand a bit about the :ref:`underlying coordinate system of KSP `. If you are having trouble making sense of the direction the axes point in, go read that page. +.. note:: + Remember that the XYZ grid in Kerbal Space Program uses a + :ref:`left-handed ` coordinate system. + Structure --------- @@ -224,6 +228,12 @@ Method / Operator Return Type PRINT VCRS(vec1, vec2). PRINT VECTORCROSSPRODUCT(vec1, vec2). + When visualizing the direction that a vector cross product will + point, remember that KSP is using a :ref:`left-handed ` + coordinate system, and this means a cross-product of two vectors + will point in the opposite direction of what it would had KSP been + using a right-handed coordinate system. + .. function:: VANG(v1,v2):: Same as :func:`VECTORANGLE(v1,v2)`. From 31aa48016cc2d0a3c4f18624837963f894d1ca79 Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Wed, 15 Apr 2015 00:01:47 -0500 Subject: [PATCH 392/446] Fixes_791_and_Fixes_811_with_docs_overhaul --- doc/source/language/user_functions.rst | 211 ++++++++--- doc/source/language/variables.rst | 490 +++++++++++++++++++------ 2 files changed, 543 insertions(+), 158 deletions(-) diff --git a/doc/source/language/user_functions.rst b/doc/source/language/user_functions.rst index b9b1b9751..0858a7e14 100644 --- a/doc/source/language/user_functions.rst +++ b/doc/source/language/user_functions.rst @@ -18,6 +18,7 @@ Help for the new user - What is a Function? - 1. Create a chunk of program instructions that you don't intend to execute YET. - 2. Later, when executing other parts of the program, do the following: + - A. Remember the current location in the program. - B. Jump to the previously created chunk of code from (1) above. - C. Run the instructions there. @@ -37,7 +38,27 @@ Help for the new user - What is a Function? In kerboscript, you can make your own user functions using the DECLARE FUNCTION command, which has syntax as follows: - ``declare function`` *identifier* ``{`` *statements* ``}`` *optional dot (.)* + [``declare``] [``local``|``global``] ``function`` *identifier* ``{`` *statements* ``}`` *optional dot (.)* + +The statement is called a "declare function" statement even when the optional +word "declare" was left off. + +The following are all identical in meaning:: + + declare function hi { print "hello". } + declare local function hi { print "hello". } + local function hi { print "hello". } + function hi { print "hello". } + +Functions are presumed to have local scope when the explicit scope +keyword is missing. + +While it is valid syntax to use a global keyword with a declare +function statement, it is not well defined yet in kOS 0.17.0 what +exactly that is supposed to mean, if anything. + +It is best to just leave all the optional keywords of and merely say +``function`` by itself. example:: @@ -46,12 +67,12 @@ example:: // mode = 1 for upper-left, 2 for upper-right, 3 // for lower-left, and 4 for lower-right: // - declare function print_corner { - declare parameter mode. - declare parameter text. + function print_corner { + parameter mode. + parameter text. - declare row to 0. - declare col to 0. + local row is 0. + local col is 0. if mode = 2 or mode = 4 { set col to terminal:width - text:length. @@ -67,7 +88,7 @@ example:: print_corner(4,"That's me in the corner"). -``Declare function`` can appear anywhere in a kerboscript program, +A declare function command can appear anywhere in a kerboscript program, and once its been "parsed" by the compiler, the function can be called from anywhere in the program. @@ -93,18 +114,74 @@ the parameter to be for that function, not for the whole script. An example of using ``declare parameter`` can be seen in the example above, where it is used for the ``mode`` and ``text`` parameters. -``DECLARE .. TO`` +(Again, even when the word 'declare' is missing, we still call them +'declare parameter' commands.) + +Calling a function +------------------ + +To call a function you created, you call it the same way you +call a built-in function, by putting a pair of parentheses +to the right of it, as shown here:: + + function example_function { + print "hello, this is my example.". + } + + example_function(). + +If the function takes parameters, then you put them in the parentheses +just like when running a program. You can see an example of this above +in the previous example where it said:: + + print_corner(4,"That's me in the corner"). + +Calling a function without parentheses (please don't) +::::::::::::::::::::::::::::::::::::::::::::::::::::: + +In some cases it is possible to call a function with the +parentheses off, as shown below, but this is not recommended:: + + function example_function { + print "hello, this is my example.". + } + + example_function. // please don't do this, even if it works. + +This is a holdover from the fact that functions and locks are +really the same thing, and you need to be able to call a lock +without the parentheses for old scripts written prior to kOS +version 0.17.0 to continue working. + +Omitting parentheses only works in the same file +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +One reason to avoid the above technique (of leaving the parentheses +off) is that it really only works when you try to call a function +that was declared in the same file. If you want to call a *library* +function (a function you made for yourself in another file) then it +does not work, for complex reason involving the compiler and late-time +binding. + +``LOCAL .. TO`` ----------------- (aka: **local variables**) -Syntax: ``DECLARE`` *identifier* ``TO`` *expression* *dot* +Syntax: + + ``DECLARE`` *identifier* ``TO`` *expression* *dot* + ``LOCAL`` *identifier* ``IS`` *expression* *dot* + ``DECLARE LOCAL`` *identifier* ``IS`` *expression* *dot* + +The above are all the same, although the version that +just says ``LOCAL identifier IS expr.`` is preferred. Examples:: declare x to 5. - declare y to 2*x - 1. - declare halfSpeed to SHIP:VELOCITY:ORBIT:MAG / 2. + local y is 2*x - 1. + declare local halfSpeed to SHIP:VELOCITY:ORBIT:MAG / 2. If your function needs to make a local variable, it can do so using the :ref:`DECLARE ` command. Whenever the DECLARE command is @@ -114,7 +191,7 @@ If you recursively call a function again and again, there will be new copies stacked up of all the local variables made with DECLARE, but not of the variables implicitly made global without DECLARE. -An example of using ``declare`` for a local variable can be seen in +An example of using ``local`` for a local variable can be seen in the example above, where it is used for the ``row`` and ``col`` variables. A more in-depth explanation of kerboscript's scoping rules and how they @@ -136,7 +213,7 @@ This is now **illegal** syntax:: you wanted to.) In order to avoid the issue of having uninitialized variables in -kerboscript, the declare command *requires* the use of the +kerboscript, any declare statement *requires* the use of the initializer clause. *This is especially important as kerboscript is a late typing @@ -151,17 +228,17 @@ Difference between declare and set You may think that:: - declare x to 5. + local x is 5. -is identical to just not using a ``declare`` statement +is identical to just not using a declare local statement at all, and just performing ``set x to 5.`` alone, but -it is not. With ``declare``, a NEW variable called ``x`` will be made -at the current local scope, temporarily hiding any existing ``x`` -variables that may otherwise have been reachable in a more global scope. -With ``set``, if there already is an ``x`` variable you can use in a -different scope higher than this scope, it will be used, and only -if it doesn't exist will a new ``x`` be made (and that new ``x`` will -be global, not local). +it is not. With ``declare local`` (or just ``declare`` or just ``local``), +a NEW variable called ``x`` will be made at the current local scope, +temporarily hiding any existing ``x`` variables that may otherwise have +been reachable in a more global scope. With ``set``, if there already +is an ``x`` variable you can use in a different scope higher than this +scope, it will be used, and only if it doesn't exist will a new ``x`` +be made (and that new ``x`` will be global, not local). .. _return: @@ -186,6 +263,11 @@ returned values are useful and meaningful. example:: + // Note, in this example, the keyword 'declare' is + // spelled out explicitly. You can choose to do so + // if you wish. It's up to you what you aestetically + // prefer. + // Cacluate what component of a vessel's surface // velocity is Northward: declare function north_velocity { @@ -203,8 +285,8 @@ working on a copy of the variable you passed in, rather than the original variable. This matters when the function tries to change the value of the parameter, as in this example:: - declare function embiggen { - declare parameter x. + function embiggen { + parameter x. set x to x + 10. @@ -235,8 +317,8 @@ number, then the copy in the function is *really* a copy of the reference pointing to the object, so changes you make in the object really WILL change it, as shown here:: - define function half_vector { - define parameter vec. //vector passed in. + function half_vector { + parameter vec. //vector passed in. print "full vector is " + vec. @@ -272,15 +354,52 @@ make a deep copy of the object for the function to use. implemented on top of C#, which is one of several OOP languages that work like this.* +Nesting functions inside functions +---------------------------------- + +You are allowed to make a local function existing inside another function. + +This means that the containing function is the only place the +nested function can be called from. + +Example:: + + function getMean { + parameter aList. + + function getSum { + parameter aList. // note, this is a local aList MASKING the other one. + + local sum is 0. + for num in aList { + set sum to sum + num. + }. + return sum. + }. + + return getSum(aList) / aList:LENGTH. + }. + + set L to LIST(); + L:ADD(10). + L:ADD(9). + print "mean average is " + getMean(L). + + // The following line will give an error becasue + // getSum is local inside of getMean, and isn't allowed + // to be called from here: + // + print "getSum is " + getSum(L). + + Recursion --------- -Recursive algorithms (TODO: wikipedia link) are possible with kerboscript -functions, provided you remember to always exclusively use local variables -made with the ``declare .. to`` statement in the body of the function, and -never use global variables for something that you intended to be -different per recursive call. - +Recursive algorithms ( http://en.wikipedia.org/wiki/Recursion#In_computer_science ) +are possible with kerboscript functions, provided you remember to +always exclusively use local variables made with a declare statement +in the body of the function, and never use global variables for +something that you intended to be different per recursive call. User Function Gotchas --------------------- @@ -325,9 +444,9 @@ when you didn't meant to, just because you made a typo. For example:: - define function mean { - declare parameter the_list. - declare sum to 0. + function mean { + parameter the_list. + local sum is 0. for item in the_list { set dum to sum + item. // typo - said 'dum' instead of 'sum'. @@ -349,24 +468,22 @@ declaring them first. Most such languages have provided a way to catch the problem, and allow you to instruct the compiler "please don't let me do that. Please force me to declare everything". -The way that is done in kerboscript is by using a ``NOLAZYGLOBAL`` -section, :ref:`as described here `. +The way that is done in kerboscript is by using a ``@LAZYGLOBAL`` +compiler directive, :ref:`as described here `. -Had the function above been wrapped inside a NOLAZYGLOBAL section, +Had the function above been wrapped inside a ``@LAZYGLOBAL off.`` section, the typo would be noticed:: - nolazyglobal { - - define function mean { - declare parameter the_list. - declare sum to 0. + @lazyglobal off. - for item in the_list { - set dum to sum + item. // error - 'dum' is an unknown identifier. - }. + local function mean { + local parameter the_list. + local sum is 0. - return sum / the_list:length. + for item in the_list { + set dum to sum + item. // error - 'dum' is an unknown identifier. }. + return sum / the_list:length. }. diff --git a/doc/source/language/variables.rst b/doc/source/language/variables.rst index a1155b91a..a73541081 100644 --- a/doc/source/language/variables.rst +++ b/doc/source/language/variables.rst @@ -7,10 +7,36 @@ Variables & Statements .. _declare: -``DECLARE .. TO`` ------------------ +``DECLARE .. TO/IS`` +-------------------- -Syntax: ``DECLARE`` *identifier* ``TO`` *expression* *dot* +What it does: +::::::::::::: + +Declares a variable, explicitly or implicitly defining what scope it +has, and gives it an initial value. + +Allowed Syntax: +::::::::::::::: + +All the following are legal "declare" statements: +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The following alternate versions have identical meaning to each other: + + * ``DECLARE`` *identifier* ``TO`` *expression* *dot* + * ``DECLARE`` *identifier* ``IS`` *expression* *dot* + * ``DECLARE`` ``LOCAL`` *identifier* ``TO`` *expression* *dot* + * ``DECLARE`` ``LOCAL`` *identifier* ``IS`` *expression* *dot* + * ``LOCAL`` *identifier* ``TO`` *expression* *dot* + * ``LOCAL`` *identifier* ``IS`` *expression* *dot* + +The following alternate versions have identical meaning to each other: + + * ``DECLARE`` ``GLOBAL`` *identifier* ``TO`` *expression* *dot* + * ``DECLARE`` ``GLOBAL`` *identifier* ``IS`` *expression* *dot* + * ``GLOBAL`` *identifier* ``TO`` *expression* *dot* + * ``GLOBAL`` *identifier* ``IS`` *expression* *dot* .. warning:: .. versionadded:: 0.17 @@ -20,30 +46,68 @@ Syntax: ``DECLARE`` *identifier* ``TO`` *expression* *dot* global variables no matter where it appeared in the script. See 'initialier required' below. -Declares a variable that is limited in scope to the code block it appears -in, and gives it an initial value:: - - DECLARE X TO 1. - -(A "code block" is any section of statements that begins with a -left-curly-brace "{" and ends with its closing right-curly-brace "}".) - -Any variable declared with DECLARE will only exist inside the code block -section it was created in. After that code block is finished, the variable -will no longer exist. +Detailed Description of the syntax: +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + * The statement must begin with either the word ``DECLARE``, ``LOCAL``, + or ``GLOBAL``. If it begins with the word ``DECLARE`` it may optionally + also contain the word ``LOCAL`` or ``GLOBAL`` afterward. *Note that if + neither* ``GLOBAL`` *nor* ``LOCAL`` *is used, the behavior of* + ``LOCAL`` *will be assumed implicitly. Therefore* ``DECLARE LOCAL`` + *and just* ``DECLARE`` *and just* ``LOCAL`` *mean the same thing.* + * After that it must contain an identifier. + * After that it must contain either the word ``TO`` or the word ``IS``, + which mean the same thing here. + * After that it must contain some expression for the initial starting + value of the variable. + * After that it must contain a dot ("period"), like all commands in + kerboscript. + + :: + + // These all do the exact same thing - make a local variable: + DECLARE X TO 1. // assumes local when unspecified. + LOCAL X IS 1. + DECLARE LOCAL X IS 1. + + // These do the exact same thing - make a global variable: + GLOBAL X IS 1. + DECLARE GLOBAL X IS 1. + +If neither the scope word ``GLOBAL`` nor the scope word ``LOCAL`` +appear, a declare statement assumes ``LOCAL`` by default. + +Any variable declared with ``DECLARE``, ``DECLARE LOCAL``, or ``LOCAL`` +will only exist inside the code block section it was created in. +After that code block is finished, the variable will no longer exist. + +See Scoping: +:::::::::::: + + If you don't know what the terms "global" or "local" mean, it's + important to read the :ref:`section below about scoping. ` .. note:: - There is an implicit outer scope block around a whole kerboscript - program, such that if you use a DECLARE .. TO statement inside - a script, it will be one nesting level "higher" than the implicit - globals you make with SET. In other words, using DECLARE always - makes a variable that is at least limited to the program script - it is inside of. + It is implied that the outermost scope of a program file is + the global scope. Therefore if you make a LOCAL variable at + the outermost nesting level of your program it really ends up + being GLOBAL. Note that GLOBAL variables are not only shared + between functions of your script, but also can be seen by + other programs you run from the current program, and visa + versa. Alternatively, a variable can be implicitly declared by any ``SET`` or ``LOCK`` statement, however doing so causes the variable to always have global scope. **The only way to make a variable be local instead of -global is to declare it explicitly with DECLARE**. +global is to declare it explicitly with one of these DECLARE statements**. + +.. note:: + **Terminology: "declare statement"**: Note that the documentation + will often refer to the phrase "declare statement" even when + referring to a statement in which the optional keyword "declare" + was left off. A statement such as ``LOCAL X IS 1.`` Will still + be referred to as a "declare statement", even though the word + "declare" never explicitly appeared in it. Initializer required in DECLARE ::::::::::::::::::::::::::::::: @@ -73,11 +137,16 @@ If you put this statement inside of a :ref:`Function body `, then it declares variables to be used as a parameter that can be passed in to that function when calling the function. +Just as with a :ref:`declare itentifier statement `, +in a ``declare parameter`` statement, the actual keyword +``declare`` need not be used. The word ``parameter`` may +be used alone and that is legal syntax. + Program 1:: // This is the contents of program1: DECLARE PARAMETER X. - DECLARE PARAMETER Y. + PARAMETER Y. // omitting the word "DECLARE" - it still means the same thing. PRINT "X times Y is " + X*Y. Program 2:: @@ -94,17 +163,25 @@ It is also possible to put more than one parameter into a single ``DECLARE PARAM DECLARE PARAMETER X, Y, CheckFlag. -This is exactly equivalent to:: + // Or you could leave "DECLARE" off like so: + PARAMETER X, Y, CheckFlag. - DECLARE PARAMETER X. - DECLARE PARAMETER Y. - DECLARE PARAMETER CheckFlag. +Either of the above is exactly equivalent to:: + + PARAMETER X. + PARAMETER Y. + PARAMETER CheckFlag. -Note: Unlike normal variables, Parameter variables are local to the program. When program A calls program B and passes parameters to it, program B can alter their values without affecting the values of the variables in program A. +Note: Unlike normal variables, Parameter variables are always local to the program. When program A calls program B and passes parameters to it, program B can alter their values without affecting the values of the variables in program A. Caveat This is only true if the values are primitive singleton values like numbers or booleans. If the values are Structures like Vectors or Lists, then they do end up behaving as if they were passed by reference, in the usual way that should be familiar to people who have used languages like Java or C# before. + +**Illegal to say** ``DECLARE GLOBAL PARAMETER`` : Becasue parameters +are always local to the location they were declared at, the keyword +``GLOBAL`` is illegal to use in a ``DECLARE PARAMETER`` statement. + The ``DECLARE PARAMETER`` statements can appear anywhere in a program as long as they are in the file at a point earlier than the point at which the parameter is being used. The order the arguments need to be passed in by the caller is the order the ``DECLARE PARAMETER`` statements appear in the program being called. .. note:: @@ -129,35 +206,51 @@ This follows the :ref:`scoping rules explained below `. If the variable can be found in the current local scope, or any scope higher up, then it won't be created and instead the existing one will be used. -Difference between SET and DECLARE -:::::::::::::::::::::::::::::::::: +Difference between SET and DECLARE LOCAL and DECLARE GLOBAL +::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: -The following two look very similar and you might ask why you'd pick -one instead of the other:: +The following three examples look very similar and you might ask +why you'd pick one instead of the other:: - DECLARE X TO 1. SET X TO 1. + DECLARE LOCAL X TO 1. + DECLARE GLOBAL X TO 1. + +They are slightly different, as follows: + +``SET X TO 1.`` Performs the following activity: + + 1. Attempt to find an already existing local X. If found, set it to 1. + 2. Try again for each scoping level outside the current one. + 3. If and only if it gets all the way out to global scope and it still + hasn't found an X, then create a new X with value 1, and do so at + global scope. This behavior is called making a "lazy global". + +``DECLARE LOCAL X TO 1.`` Performs the following activity: + + 1. Immediately make a new X right here at the local-most scope. + Set it to 1. + +``DECLARE GLOBAL X TO 1.`` Performs the following activity: -The difference is that ``SET`` attempts to store the value in the -variable that already exists, if it can find one, and it only -creates a new variable if it *has* to because there isn't one that -already exists. *(That's the first difference)*. Because ``SET`` -doesn't make a new variable until it has exhausted the attempts to -find an existing one by looking up the "scope stack", ``SET`` only -is capable of creating **global** variables. *(That's the second -difference.)* + 1. Ignore whether or not there are any existing X's in a local scope. + 2. Immediately go all the way to global scope and make a new X there. + Set it to 1. -Also, be aware that DECLARE, in effect, is actually *incapable* of -creating global variables. There is an implicit scope block -of "limited to the current script file" or "limited to the -interpreter" when the DECLARE statement is used even at the outermost -nesting level of a script. +When to use GLOBAL +:::::::::::::::::: + +You should use a ``DECLARE GLOBAL`` statement only sparingly. It +mostly exists so that a function can store values "in the caller" +for the caller to get its hands on. It's generally a "sloppy" design +pattern to use, and it's much better to keep everything local +and only pass back things to the caller as return values. ``LOCK`` -------- -Declares that the idenifier will refer to an expression that is always re-evaluated on the fly every time it is used (See also :ref:`Flow Control documentation `):: +Declares that the identifier will refer to an expression that is always re-evaluated on the fly every time it is used (See also :ref:`Flow Control documentation `):: SET Y TO 1. LOCK X TO Y + 1. @@ -168,6 +261,82 @@ Declares that the idenifier will refer to an expression that is always re-evalua Note that because of how LOCK expressions are in fact implemented as mini functions, they cannot have local scope. A LOCK *always* has global scope. +By default a ``LOCK`` expression is ``GLOBAL`` when made. This is +neccesary for backward compatibility with older scripts that use +LOCK STEERING from inside triggers, loops, etc, and expect it to +affect the global steering value. + +Calling a LOCK that was created in another file +::::::::::::::::::::::::::::::::::::::::::::::: + +If you try to call a lock that is declared in another program +file you run, it does not work, and has never worked prior to kOS +0.17.0: + +File1.ks:: + + run File2. + print "x's locked value is " + x. + +File2.ks:: + + lock x to "this is x". + +But now with the kerboscript of kOS 0.17.0, you can make it work +by inserting empty parentheses after the lock name to help give +the compiler the hint that you expected x to be a function call +(which is what a lock really is): + +Change this line:: + + print "x's locked value is " + x. + +To this instead:: + + print "x's locked value is " + x(). + +and it should work. + +Local lock +:::::::::: + +You can explicitly make a ``LOCK`` statement be LOCAL with the ``LOCAL`` +keyword, like so: + +``LOCK LOCAL`` identifier ``TO`` expression. + +But be aware that doing so with a cooked steering control such +as THROTTLE or STEERING will not actually affect your ship. The +automated cooked steering control is only reading the GLOBAL locks +for these settings. + +The purpose of making a LOCAL lock is if you only need to use the +value temporarily for the duration of a function call, loop, or +if-statement body, and then you don't care about it anymore after +that. + +Why do I care about a local lock? +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +You care because in order to make a LOCK work even after the variables +it's using in its expression go out of scope (which is necessary +for LOCK STEERING or LOCK THROTTLE to work if done from inside +a user function call or trigger body), locks need to preserve +a thing called a "closure". +( http://en.wikipedia.org/wiki/Closure_(computer_programming) + +When they do this, it means none of the local variables used +in the function body they were declared in truly "go away" from +memory. They live on, taking up space until the lock disappears. +Making the lock be local tells the computer that it can make the lock +disappear when it goes out of scope, and thus it doesn't need to +hold that "closure" around forever. + +The tl;dr version: It's more efficient for memory. If you know +for sure that your lock isn't getting used after your current +section of code is over, make it a local lock. + + .. _toggle: ``TOGGLE`` @@ -211,7 +380,7 @@ variable. .. _scope: -Scoping rules +Scoping terms ------------- .. note:: @@ -236,12 +405,7 @@ Global scope beginners, this is often enough and you don't have to read the rest of this topic until you start advancing to more intermediate scripts. -If you need to have variables that only have local scope, either just -to keep your code more manageable, or because you literally need -local scope to allow for recursive function calls, then you use the -DECLARE statement to create the variables. - -DECLARE statements are in block scope +Local Scope Kerboscript uses block scoping to keep track of local variable scope. This means you can have variables that are not only local to a function, but are in fact actually local to JUST @@ -249,23 +413,6 @@ DECLARE statements are in block scope of statements is, say, the body of an IF check, or the body of an UNTIL loop. - Be aware that whenever you use the DECLARE..TO statement, you are - making a variable that is local to the scope in which it appears. - If you use DECLARE in the live interpreter, it makes a variable - that doesn't exist from inside a program. If you use DECLARE in - a program script at the outermost nesting level of that script, it - still makes a variable that can only be seen from inside THAT - program script. If you have gotten used to the easy 'sloppy' - feature of being able to just SET a variable anywhere and then - see its value even after the program ends, be aware that this will - NOT happen with variables you created with DECLARE..TO. After the - script ends, the variables made with DECLARE..TO will no longer exist. - - Or to put it another way, variables created implicitly with SET - are **even more global** than ones created by the explict use - of DECLARE. The implicit variables made by SET end up existing - even after the program ends. - Why limit scope? You might be wondering why it's useful to limit the scope of a variable. Wouldn't it be easier just to make all variables @@ -275,25 +422,97 @@ Why limit scope? variables, can be a large unmanagable chore, especially with programs written by more than one person collaborating together. (2) Even if you can keep track of all that in your head, there's - a certain programming technique known as recursion (TODO - wiki - link) in which you actually NEED to have local variable scope for + a certain programming technique known as recursion + ( http://en.wikipedia.org/wiki/Recursion#In_computer_science ) + in which you actually NEED to have local variable scope for the technique to even work at all. +If you need to have variables that only have local scope, either just +to keep your code more manageable, or because you literally need +local scope to allow for recursive function calls, then you use the +``DECLARE LOCAL`` statement (or just ``LOCAL`` for short) to create +the variables. + +Scoping syntax +-------------- + +Presumed defaults +::::::::::::::::: + +The DECLARE keyword and the LOCK keyword have some default +presumed scoping behaviors: + +``DECLARE`` Is assumed to always be LOCAL when not otherwise specified. + +``FUNCTION`` Is assumed to always be LOCAL when not otherwise specified. + +``PARAMETER`` Cannot be anything but LOCAL to the location it's mentioned. +It is an error to attempt to declare a parameter with the GLOBAL keyword. + +``LOCK`` Is assumed to always be GLOBAL when not otherwise specified. +this is necessary to preserve backward compatibility with how cooked +controls such as LOCK STEERING and LOCK THROTTLE work. + +Note that when operating under the :ref:`@LAZYGLOBAL OFF ` +directive the keywords LOCAL and GLOBAL are no longer optional, and are +in fact required. You are not allowed to rely on these presumed defaults +when you've turned off LAZYGLOBAL. + +Explicit scoping keywords +::::::::::::::::::::::::: + +The ``DECLARE``, ``FUNCTION``, and ``LOCK`` commands can be given +explicit ``GLOBAL`` or ``LOCAL`` keywords to define their intended +scoping level:: + + // + // These are all synonymous with each other: + // + DECLARE X TO 1. + DECLARE LOCAL X TO 1. + LOCAL X TO 1. // 'declare' is implied and optional when scoping words are used + LOCAL X IS 1. // 'declare' is implied and optional when scoping words are used + // + // These are all synonymous with each other: + // + DECLARE GLOBAL X TO 1. + GLOBAL X TO 1. // 'declare' is implied and optional when scoping words are used + GLOBAL X IS 1. // 'declare' is implied and optional when scoping words are used + +Even when the word 'DECLARE' is left off, the statement can still be +referred to as a "declare statement". The word "declare" is implied +by the use of LOCAL or GLOBAL and you are allowed to leave it off +merely to reduce verbosity. + + +Locals stated at the global level are global +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Note that if you put a statement at the outermost scope +of the program, then there is effectively no difference +between a ``DECLARE LOCAL`` (or just ``LOCAL`` for short) +and a ``DECLARE GLOBAL`` (or just ``GLOBAL`` for short) statement. +They are both goihg to make a variable at global scope because that's +the scope the program was in when the statement was encoutnered. + + Examples:: - DECLARE x TO 10. // X is now a global variable with value 10. + GLOBAL x IS 10. // X is now a global variable with value 10, SET y TO 20. // Y is now a global variable (implicitly) with value 20. - DECLARE z TO 0. // Z is now a global variable. + LOCAL z IS 0. // Z is now a global variable + // because even though this says LOCAL, it was + // stated at the outermost, global scope. SET sum to -1. // sum is now an implicitly made global variable, containing -1. // A function to return the mean average of all the items in the list // passed into it, under the assumption all the items in the list are // numbers of some sort: - DECLARE FUNCTION calcAverage { - DECLARE PARAMETER inputList. + FUNCTION calcAverage { + PARAMETER inputList. - DECLARE sum TO 0. // sum is now local to this function's body. + LOCAL sum IS 0. // sum is now local to this function's body. FOR val IN inputList { SET sum TO sum + val. }. @@ -317,13 +536,15 @@ This example will print:: Thus proving that the variable called SUM inside the function is NOT the same variable as the one called SUM out in the global main code. -Nesting: - The scoping rules are nested as well. If you attempt to use a - variable that doesn't exist in the local scope, the next scope "outside" - it wil be used, and if it doesn't exist there, the next scope "outside" - that will be used and so on, all the way up to the global scope. Only - if the variable isn't found at the global scope either will it be - implicitly created. +Nesting +~~~~~~~ + +The scoping rules are nested as well. If you attempt to use a +variable that doesn't exist in the local scope, the next scope "outside" +it wil be used, and if it doesn't exist there, the next scope "outside" +that will be used and so on, all the way up to the global scope. Only +if the variable isn't found at the global scope either will it be +implicitly created. .. _trigger_scope: @@ -344,10 +565,10 @@ because they outlive the duration of any particular scoping braces. You can declare local variables within their in their bodies, just don't use local variables in the trigger conditions. -.. _nolazyglobal: +.. _lazyglobal: -``NOLAZYGLOBAL`` -:::::::::::::::: +``@LAZYGLOBAL`` directive +::::::::::::::::::::::::: Often the fact that you can get an implicit global variable declared without intending to can lead to a lot of code maintenence headaches @@ -357,36 +578,85 @@ forget to mark the variable as local when you intended to. If you wish to instruct kerboscript to alter its behavior and disable its normal implicit globals, and instead demand that all -variables MUST be mentioned in a DECLARE statement, you can do so -using the ``NOLAZYGLOBAL`` syntax. Everything that occurs inside -a NOLAZYGLOBAL code block will use the rule that varibles MUST already -exist before being encountered. SET will no longer automatically create -variables for you when inside this section. +variables MUST be explicitly declared and may not use implied +lazy scoping, the ``@LAZYGLOBAL`` compiler directive allows you to +do that. + +If you place the words:: + + @LAZYGLOBAL OFF. + +At the start of your program, you will turn off the compiler's +lazy global feature and it will require you to explicitly mention +all variables you use in a declaration somewhere (with the +exception of the built-in variables such as THROTTLE, STEERING, +SHIP, and so on.) + +@LAZYGLOBAL Can only exist at the top of your code. +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The @LAZYGLOBAL compile directive is only allowed as the first +non-comment thing in the program file. This is because it +instructs the compiler to change its default behavior for the +duration of the entire file's compile. + +@LAZYGLOBAL Makes ``LOCAL`` and ``GLOBAL`` mandatory +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Normally the keywords ``local`` and ``global`` can be left off +as optional in declare statements. But when you turn LAZYGLOBAL +off, the compiler starts requiring them to be explicitly stated. + +For example, this program, which is valid:: + + function foo {print "foo ". } + local x is 1. + + print foo() + x. + +Starts giving errors when you add @LAZYGLOBAL OFF to the top:: + + @LAZYGLOBAL OFF. + function foo {print "foo ". } + declare x is 1. + + print foo() + x. + +Wich you fix by explicitly stating the local keyword, as follows:: + + @LAZYGLOBAL OFF. + local function foo {print "foo ". } + declare local x is 1. + + print foo() + x. + + + +Longer Example of use +~~~~~~~~~~~~~~~~~~~~~ Example:: - NOLAZYGLOBAL { - SET num TO 1. - IF TRUE { - DECLARE Y TO 2. - SET num TO num + Y. // This is fine. num exists already as a global and - // you're adding the local Y to it. - SET nim TO 20. // This typo generates an error. There is - // no such variable "nim" and NOLAZYGLOBAL - // says not to implicitly make it. - }. + @LAZYGLOBAL off. + global num TO 1. + IF TRUE { + LOCAL Y IS 2. + SET num TO num + Y. // This is fine. num exists already as a global and + // you're adding the local Y to it. + SET nim TO 20. // This typo generates an error. There is + // no such variable "nim" and @LAZYGLOBAL OFF + // says not to implicitly make it. }. - SET nim TO 20. // HERE, on the other hand, this doesn't generate an - // error. When outside the NOLAZYGLOBAL section, - // it just makes a new varible called nim - -Why NOLAZYGLOBAL? - The rationale behind NOLAZYGLOBAL is to primarily be used in cases - where you're writing a libary of function calls you intend to +Why ``LAZYGLOBAL OFF``? + The rationale behind ``LAZYGLOBAL OFF.`` is to primarily be used in + cases where you're writing a libary of function calls you intend to use elsewhere, and want to be careful not to accidentally make them dependant on globals outside the function itself. +The ``@LAZYGLOBAL OFF.`` directive is meant to mimic Perl's ``use strict;`` +directive. + ~~~~~~ History: @@ -407,5 +677,3 @@ History: global so that people who wish to keep programming that way don't need to understand or deal with scope. - The NOLAZYGLOBAL keyword is meant to mimic Perl's ``use strict;`` - directive. From 9c05082c2c729919d471bbb9de443ee0b03c36e9 Mon Sep 17 00:00:00 2001 From: Chris Woerz Date: Tue, 14 Apr 2015 23:38:00 -0600 Subject: [PATCH 393/446] spell check --- CHANGELOG.md | 260 ++++++++++++++++++++--------------------- doc/source/changes.rst | 8 +- 2 files changed, 134 insertions(+), 134 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d89794340..993d6da33 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,24 +10,24 @@ can handle recursion, and can use local variable scoping. You can build a library of your own function calls and load them into your script. -**New Documenatation change page**: +**New Documentation change page**: - For those users who just want to see what new features - exist without reading the entire documentation again - from scratch, we have created a changes page in the main documentation: + For those users who just want to see what new features + exist without reading the entire documentation again + from scratch, we have created a changes page in the main documentation: - * New Changes Page: http://ksp-kos.github.io/KOS_DOC/changes.html + * New Changes Page: http://ksp-kos.github.io/KOS_DOC/changes.html - For the features mentioned below, you can go to the page above - and get a more verbose description of the new features. + For the features mentioned below, you can go to the page above + and get a more verbose description of the new features. ###BREAKING: - **RECOMPILE YOUR KSM FILES!!!** - changes to the kOS machine code that were needed to support variable scoping ended up invalidating - any existing precompiled KSM files. You should be able to just + any existing compiled KSM files. You should be able to just perform one compile and then use the new KSM file. If you don't do this, you will get the error message: - ```The given key was not present in the dictionary.``` + ```The given key was not present in the dictionary.``` - **KSM FILES ARE BIGGER** - compiled KSM files are now larger than they used to be, due to extra code generated for dealing with variable scoping and more universal function calling techniques. @@ -41,10 +41,10 @@ script. is higher, it will not overwrite your settings if you have a config file already present from earlier installations. - *DECLARE has a new syntax* - DECLARE _VARNAME_ now requires an initializier syntax as follows: + DECLARE _VARNAME_ now requires an initializer syntax as follows: - DECLARE _VARNAME_ TO _VALUE_. If you leave the TO _VALUE_ off, it will now be a syntax error. - The Kerobscript language used to leave it unspecified what the value + The Kerboscript language used to leave it unspecified what the value of a variable that has been declared but not set was. This gets rid of that ambiguity. - *DECLAREd variables are now local* @@ -68,20 +68,20 @@ script. your own library of common routines. Synopsis:: - // Silly example function to build a string of padded chars. - FUNCTION padString { - PARAMETER ch, howmany + // Silly example function to build a string of padded chars. + FUNCTION padString { + PARAMETER ch, howmany - LOCAL str to "". // makes str a local variable. + LOCAL str to "". // makes str a local variable. - UNTIL howmany <= 0 { - set str to str + ch. - set howmany to howmany - 1. - } - RETURN str. - } - set twentySpaces to padString(" ", 20). - set threeX to padString("X", 3). + UNTIL howmany <= 0 { + set str to str + ch. + set howmany to howmany - 1. + } + RETURN str. + } + set twentySpaces to padString(" ", 20). + set threeX to padString("X", 3). If you'd like to create a library of utility functions for yourself, you can make a kerboscript file that contains only @@ -97,9 +97,9 @@ script. work, we also implemented some local scoping rules. Synopsis:: - Kerboscript now uses block scoping, local to the brace scope the variable was declared inside of. - Local vars are declared with the DECLARE..TO statement. - Variables made implicitly by "lazy" use of SET will still be global like they always have been. + Kerboscript now uses block scoping, local to the brace scope the variable was declared inside of. + Local vars are declared with the DECLARE..TO statement. + Variables made implicitly by "lazy" use of SET will still be global like they always have been. The exact means of making a variable local is described here: http://ksp-kos.github.io/KOS/language/variables.html#declare-to @@ -144,16 +144,16 @@ this fixes #603 the mess that I made of the Node structure, thanks Tabris from t ### New Features * TELNET SERVER. The biggest new feature this update is the introduction of a **telnet server** you can use to access the terminals in game. For security, it's turned off by default, but you can enable it with the config radio button. Full documentation on this new feature is at http://ksp-kos.github.io/KOS_DOC/general/telnet.html - * Synopsis: - * Telnet to 127.0.0.1, port 5410 - * Select CPU from welcome menu by typing a number and hitting Return. - * Your telnet client is now a clone of that CPU's terminal window and can control it. - * If you want to open it up to others to use (i.e. controlling your KSP game from a second computer), - you can use an ssh tunnel to access the local loopback address, or if you just want to throw - caution to the wind, you can tell it to stop using loopback and use your real IP address. - Be aware of the security risk if you choose this. + * Synopsis: + * Telnet to 127.0.0.1, port 5410 + * Select CPU from welcome menu by typing a number and hitting Return. + * Your telnet client is now a clone of that CPU's terminal window and can control it. + * If you want to open it up to others to use (i.e. controlling your KSP game from a second computer), + you can use an ssh tunnel to access the local loopback address, or if you just want to throw + caution to the wind, you can tell it to stop using loopback and use your real IP address. + Be aware of the security risk if you choose this. * Added HUDTEXT that lets you add text to the screen. Thanks @pgodd ! - * more information here: http://ksp-kos.github.io/KOS_DOC/commands/terminal.html#HUDTEXT + * more information here: http://ksp-kos.github.io/KOS_DOC/commands/terminal.html#HUDTEXT * #72 - Added STAGE:NUMBER and STAGE:READY to allow for staging very close together * #522 - Added BODY:GEOPOSITIONOF and BODY:ALTITUDEOF for getting body-relative info about a 3D point in space. * #524 and #523 - mission waypoints now have 3d positions @@ -183,8 +183,8 @@ this fixes #603 the mess that I made of the Node structure, thanks Tabris from t ### New Features * (AGX) Action Groups Extended Support! Thanks @SirDiazo - * Getting or setting groups 11-250 should behave the same as the stock groups if you have AGX installed. - * Groundwork is laid for getting parts and modules by the new action groups. + * Getting or setting groups 11-250 should behave the same as the stock groups if you have AGX installed. + * Groundwork is laid for getting parts and modules by the new action groups. * Gimbals are now a well known module. providing read access to its state * Added PART:GETMODULEBYINDEX(int). This is most useful when you have a part with the same module twice. Thanks @jwvanderbeck * More documentation work. http://ksp-kos.github.io/KOS_DOC/ @@ -214,8 +214,8 @@ to make sure everything works.) * Added new :POSITION and :ALTITUDEPOSITION suffixes to [Geocoordinates](http://ksp-kos.github.io/KOS/math/geocoordinates.html) to obtain 3D vectors of their positions in ship-raw coordinate space. * ADDED muliple new ways to deal with resources. - * STAGE:RESOURCES, SHIP:RESOURCES and TARGET:RESOURCES will let you get a list of the resources for the craft, the difference being that SHIP: and TARGET: includes all resources and STAGE: includes only the resoures that are for "this stage". All three of these will let you get a list of :PARTS that can contain that resource. - * Part resources now gives you access to the resource's tweakable :ENABLE and :TOGGLEABLE can let you remove add a resource to the normal resource flow. + * STAGE:RESOURCES, SHIP:RESOURCES and TARGET:RESOURCES will let you get a list of the resources for the craft, the difference being that SHIP: and TARGET: includes all resources and STAGE: includes only the resoures that are for "this stage". All three of these will let you get a list of :PARTS that can contain that resource. + * Part resources now gives you access to the resource's tweakable :ENABLE and :TOGGLEABLE can let you remove add a resource to the normal resource flow. ###Bug Fixes * Better handling of range checking and loading the boot file when remotetech is installed (thanks to hvacengi for this contribution) @@ -277,51 +277,51 @@ Please follow the links to see the full information on the new features. * [Added pilot input to flight controls](http://ksp-kos.github.io/KOS_DOC/structure/control/index.html#pilot-commands) which lets you read/write the users control state, you can use this to set the exit behavior for the mainthrottle. * Several suffixes are now [methods that you can call](ksp-kos.github.io/KOS_DOC/#structure_methods) with arguments. - * eg before to add to a list it was SET LIST:ADD TO "FOO". Now it would be LIST:ADD("FOO"). + * eg before to add to a list it was SET LIST:ADD TO "FOO". Now it would be LIST:ADD("FOO"). * Suffix methods that perform an action do not need to be assigned to anything. No more having to say *SET DUMMY TO MYLIST:CLEAR.* You can now just say *MYLIST:CLEAR.* like it was a statement. * Added suffixes to OBT for [walking orbit conic patches](http://ksp-kos.github.io/KOS_DOC/structure/orbit/index.html) - * ORB:HASNEXTPATCH - A boolean that shows the presence of a future patch - * ORB:NEXTPATCH - The next OBT patch + * ORB:HASNEXTPATCH - A boolean that shows the presence of a future patch + * ORB:NEXTPATCH - The next OBT patch * Added better techniques for selecting the Part you want from a Vessel: * Ability to give any part any name you like with the [new nametag feature](http://ksp-kos.github.io/KOS_DOC/summary_topics/nametag/index.html). * [Directly querying a vessel for parts](http://ksp-kos.github.io/KOS_DOC/summary_topics/ship_parts_and_modules/index.html#parts), searching for [nametags](http://ksp-kos.github.io/KOS_DOC/summary_topics/nametag/index.html), or part names or part titles. - * SHIP:PARTSDUBBED(string) - * SHIP:PARTSNAMED(string) - * SHIP:PARTSTAGGED(string) - * SHIP:PARTSTITLED(string) - * SHIP:PARTSINGROUP(string) - * SHIP:MODULESNAMED(string) + * SHIP:PARTSDUBBED(string) + * SHIP:PARTSNAMED(string) + * SHIP:PARTSTAGGED(string) + * SHIP:PARTSTITLED(string) + * SHIP:PARTSINGROUP(string) + * SHIP:MODULESNAMED(string) * [Walking the parts Tree](http://ksp-kos.github.io/KOS_DOC/structure/part/index.html): - * PART:CHILDREN - A ListValue of parts that are descendant from the current part - * PART:PARENT - A PART that is the ancestor of the current part - * PART:HASPARENT - A boolean that shows the presence of a Parent PART - * SHIP:ROOTPART - The first part of a ship. The start of the tree of parts. identical to SHIP:PARTS[0]. + * PART:CHILDREN - A ListValue of parts that are descendant from the current part + * PART:PARENT - A PART that is the ancestor of the current part + * PART:HASPARENT - A boolean that shows the presence of a Parent PART + * SHIP:ROOTPART - The first part of a ship. The start of the tree of parts. identical to SHIP:PARTS[0]. * *SET MyList TO SHIP:PARTS.* now does the same thing as *LIST PARTS IN MyList.* * A [new system lets you access the PartModules](http://ksp-kos.github.io/KOS_DOC/structure/partmodule/index.html) that the stock game and modders put on the various parts. Through this, you now have the ability to manipulate a lot of the things that are on the rightclick menus of parts: * PART Suffixes: - * GETMODULE(string) - * ALLMODULES. + * GETMODULE(string) + * ALLMODULES. * PartModule Suffixes: - * GETFIELD(field_name) - read a value from a rightclick menu - * SETFIELD(field_name, new value) - change a value on a rightclick menu, if it would normally be adjustable via a tweakable control. - * DOACTION(name_of_action_) - cause one of the actions that would normally be available to action groups *even if it hasn't been assigned to an action group*. - * DOEVENT(event_name) - "presses a button" on the rightclick part menu. - * Several others.. + * GETFIELD(field_name) - read a value from a rightclick menu + * SETFIELD(field_name, new value) - change a value on a rightclick menu, if it would normally be adjustable via a tweakable control. + * DOACTION(name_of_action_) - cause one of the actions that would normally be available to action groups *even if it hasn't been assigned to an action group*. + * DOEVENT(event_name) - "presses a button" on the rightclick part menu. + * Several others.. * [Lists are now saner to work with](http://ksp-kos.github.io/KOS_DOC/structure/list/index.html) with no longer needing to use weird side effects to get things done, now that there's proper methods available: * :ADD has changed: - * Old Way: *SET MyList:ADD TO NewVal.* - * New Way: *MyList:ADD(NewVal).* + * Old Way: *SET MyList:ADD TO NewVal.* + * New Way: *MyList:ADD(NewVal).* * :REMOVE has changed: - * Old Way: *SET MyList:REMOVE TO indexnumber.* - * New Way: *MyList:REMOVE(indexnumber).* + * Old Way: *SET MyList:REMOVE TO indexnumber.* + * New Way: *MyList:REMOVE(indexnumber).* * :CLEAR has changed: - * Old Way: *SET Dummy to MyList:CLEAR.* - * New Way: *MyList:CLEAR().* + * Old Way: *SET Dummy to MyList:CLEAR.* + * New Way: *MyList:CLEAR().* * Added ENGINE:AVAILABLETHRUST suffix. A value that respects the thrust limiter @@ -382,17 +382,17 @@ Please follow the links to see the full information on the new features. * Updated fonts, Thanks @MrOnak * Now runtime errors show source location and call stack trace (Github issues #186 and #210). Example: ~~~ - Tried To push Infinity into the stack. - At MyProgramFile2 on Archive, line 12 - PRINT var1/var2. - ^ - Called from MyProgramFile1 on Archive, line 213 - RUN MyProgramFIle2("hello"). - ^ - Called from StartMission on Archive, line 2. - RUN MyProgramFile1. - ^ - _ + Tried To push Infinity into the stack. + At MyProgramFile2 on Archive, line 12 + PRINT var1/var2. + ^ + Called from MyProgramFile1 on Archive, line 213 + RUN MyProgramFIle2("hello"). + ^ + Called from StartMission on Archive, line 2. + RUN MyProgramFile1. + ^ + _ ~~~ * (WHEN and ON) Triggers that are taking longer than an Update is meant to take, and thus can freeze KSP are caught and reported (Github issue #104). Gives the user an explanatory message about the problem. * WARNING: Because of a change that had to be done for this, it is **_Highly_ recommended that you increase your *InstructionsPerUpdate* setting in config.xml to 150% as much** as it was before (i.e. from 100 to 150, or if it was 200, make it 300.). @@ -434,9 +434,9 @@ Please follow the links to see the full information on the new features. * you can now get the FACING of all parts. * ITERATOR:END is now split into :NEXT and :ATEND * Direction can now always return a proper vector. - * IE SHIP:FACING returned V(0,0,0) before + * IE SHIP:FACING returned V(0,0,0) before * Added a 3d Drawing tool for letting you draw lines and labels. - * Tour: https://www.youtube.com/watch?v=Vn6lUozVUHA + * Tour: https://www.youtube.com/watch?v=Vn6lUozVUHA * Added a new and improved file editor so the edit command actually works again in game! * Added the ability to switch to MapView and back in code * ACTIVESHIP alias links to the ship that is currently under user direct control @@ -521,28 +521,28 @@ Bug fixes * Added Ctrl+Shift+X hotkey to close the terminal window (jwvanderbeck) * Improved RemoteTech integration (jwvanderbeck) Current state is discussed https://github.com/erendrake/KOS/pull/51 * Added engine stats to the enginevalue - * ACTIVE (get/set) - * ALLOWRESTART (get - * ALLOWSHUTDOWN (get) - * THROTTLELOCK (get) - * THRUSTLIMIT (get/set) + * ACTIVE (get/set) + * ALLOWRESTART (get + * ALLOWSHUTDOWN (get) + * THROTTLELOCK (get) + * THRUSTLIMIT (get/set) * Added to BODY:ATM:SEALEVELPRESSURE * Added a DockingPort Part Type, You can access it by "LIST DOCKINGPORTS IN ..." * Added PART:CONTROLFROM which centers the transform on that part. * Vector now has two new Suffixes - * NORMALIZED - Vector keeps same direction, but will have a magnitude of 1. - * SQRMAGNITUDE - https://docs.unity3d.com/Documentation/ScriptReference/Vector3-sqrMagnitude.html + * NORMALIZED - Vector keeps same direction, but will have a magnitude of 1. + * SQRMAGNITUDE - https://docs.unity3d.com/Documentation/ScriptReference/Vector3-sqrMagnitude.html * New math operators involving Vectors - * VECTORCROSSPRODUCT (VCRS) - * VECTORDOTPRODUCT (VDOT) - * VECTOREXCLUDE (VXCL) - projects one vector onto another - * VECTORANGLE (VANG) - Returns the angle in degrees between from and to. + * VECTORCROSSPRODUCT (VCRS) + * VECTORDOTPRODUCT (VDOT) + * VECTOREXCLUDE (VXCL) - projects one vector onto another + * VECTORANGLE (VANG) - Returns the angle in degrees between from and to. * Direct control of vessel and nearby vessels (SHIP:CONTROL, TARGET:CONTROL) - * __GETTERS__ + * __GETTERS__ * YAW - Rotation (1 to -1) * PITCH - Rotation (1 to -1) * ROLL - Rotation (1 to -1) @@ -555,7 +555,7 @@ Bug fixes * MAINTHROTTLE (1 to -1) * WHEELTHROTTLE (1 to -1) * WHEELSTEER (1 to -1) - * __SETTERS__ + * __SETTERS__ * YAW - Rotation (1 to -1) * PITCH - Rotation (1 to -1) * ROLL - Rotation (1 to -1) @@ -569,9 +569,9 @@ Bug fixes * WHEELTHROTTLE (1 to -1) * WHEELSTEER (1 to -1) * changing systems vessel load distance - * LOADDISTANCE get/set for adjusting load distance for every vessel - * VESSELTARGET:LOAD bool - is the vessel loaded - * VESSELTARGET:PACKDISTANCE - Setter for pack distance for every vessel. + * LOADDISTANCE get/set for adjusting load distance for every vessel + * VESSELTARGET:LOAD bool - is the vessel loaded + * VESSELTARGET:PACKDISTANCE - Setter for pack distance for every vessel. * Added RANDOM() generator (0 - 1) * Power requirements are now directly tied to the active volume's size, the ARCHIVE's size is unlimited so it is capped at the equivalent of 50KB. @@ -586,13 +586,13 @@ Bug fixes - Basic RemoveTech Intergration - Added VOLUME:NAME to getting the current volume - Lists can now be populated with basic data that you can loop over or index [Full Info](/wiki/List/) - - Bodies (eg Kerbin, Mun, Duna) - - Targets - All Vessels other than current - - Engines - Engines on the craft - - Resources - All Ship Resources - - Parts - All Ship Parts (slow) - - Sensors - (eg Pres, Grav, Accel) - - Elements - All flights connected to the active vessel + - Bodies (eg Kerbin, Mun, Duna) + - Targets - All Vessels other than current + - Engines - Engines on the craft + - Resources - All Ship Resources + - Parts - All Ship Parts (slow) + - Sensors - (eg Pres, Grav, Accel) + - Elements - All flights connected to the active vessel - A Lot of bug fixes and refactoring - Constants (eg G, E, PI) are now retrieved using CONSTANT() rather than spreadout. - Commands resolve in order of descending specificity, rather than in the pseudorandom order they were in before @@ -602,39 +602,39 @@ Bug fixes - Compatible with KSP 0.23 Thanks to Logris and MaHuJa for Commits - Added List() which creates a collection and the following commands - - ADD - Adds the value of any variable - - CONTAINS - Tests and returns if the value exists in the list - - REMOVE - removes the item from the list if the list contains the item - - LENGTH - returns a count of the items in the list - - COPY - creates a copy of the list - - You can also index into a list with # (ie LIST#1 gives you the second item in the list). + - ADD - Adds the value of any variable + - CONTAINS - Tests and returns if the value exists in the list + - REMOVE - removes the item from the list if the list contains the item + - LENGTH - returns a count of the items in the list + - COPY - creates a copy of the list + - You can also index into a list with # (ie LIST#1 gives you the second item in the list). - Added the following stats - - OBT:PERIOD - http://en.wikipedia.org/wiki/Orbital_period - - OBT:INCLINATION - http://en.wikipedia.org/wiki/Orbital_inclination - - OBT:ECCENTRICITY - http://en.wikipedia.org/wiki/Orbital_eccentricity - - OBT:SEMIMAJORAXIS - http://en.wikipedia.org/wiki/Semi-major_axis - - OBT:SEMIMINORAXIS - http://en.wikipedia.org/wiki/Semi-major_axis - - VOLUME:NAME - Name of the current Volume - - ETA:TRANSITION - Seconds until next patch - - OBT:TRANSITION - Type of next patch: possibilities are - - FINAL - - ENCOUNTER - - ESCAPE - - MANEUVER + - OBT:PERIOD - http://en.wikipedia.org/wiki/Orbital_period + - OBT:INCLINATION - http://en.wikipedia.org/wiki/Orbital_inclination + - OBT:ECCENTRICITY - http://en.wikipedia.org/wiki/Orbital_eccentricity + - OBT:SEMIMAJORAXIS - http://en.wikipedia.org/wiki/Semi-major_axis + - OBT:SEMIMINORAXIS - http://en.wikipedia.org/wiki/Semi-major_axis + - VOLUME:NAME - Name of the current Volume + - ETA:TRANSITION - Seconds until next patch + - OBT:TRANSITION - Type of next patch: possibilities are + - FINAL + - ENCOUNTER + - ESCAPE + - MANEUVER - Adding a few BODY members - - RADIUS - - MU - G * Body Mass - - G - Gravitational Constant - - ATM atmosphere info with sub elements - - EXISTS - - HASOXYGEN - - SCALE - - HEIGHT - + - RADIUS + - MU - G * Body Mass + - G - Gravitational Constant + - ATM atmosphere info with sub elements + - EXISTS + - HASOXYGEN + - SCALE + - HEIGHT + - Added ORBIT to NODE - Added the following commands - - UNSET #VARIABLE - remove the variable, ALL removes all variables Thanks a1070 - - FOR #USERVARIABLE IN #LIST takes a list and loops over it, exposing each item in the collection as a user defined variable + - UNSET #VARIABLE - remove the variable, ALL removes all variables Thanks a1070 + - FOR #USERVARIABLE IN #LIST takes a list and loops over it, exposing each item in the collection as a user defined variable - New close window action binding - Performance fixes diff --git a/doc/source/changes.rst b/doc/source/changes.rst index 9b728529e..1ac020e72 100644 --- a/doc/source/changes.rst +++ b/doc/source/changes.rst @@ -5,9 +5,9 @@ Changes from version to version This is a slightly more verbose version of the new features mentioned in the CHANGELOG, specifically for new features and for -users familiar with older versions of the documenation who want +users familiar with older versions of the documentation who want only a quick update to the docs without reading the entire set -of documenation again from scratch. +of documentation again from scratch. .. contents:: :local: @@ -20,9 +20,9 @@ Physics Ticks not Update Ticks :::::::::::::::::::::::::::::: The updates have been :ref:`moved to the physics update ` -portaion of Unity, instead of the animation frame rate updates. +portion of Unity, instead of the animation frame rate updates. This may affect your preferred CONFIG:IPU setting. The new move -creates a much more uniform preformance across all users, without +creates a much more uniform performance across all users, without penalizing the users of faster computers anymore. (Previously, if your computer was faster, you'd be charged more electricity as the updates came more often). From 7f2cfdfd6f03c2afa1c0cbd1f210fb4f4e93cb22 Mon Sep 17 00:00:00 2001 From: Chris Woerz Date: Wed, 15 Apr 2015 00:02:00 -0600 Subject: [PATCH 394/446] spelling --- doc/source/bindings.rst | 12 ++++++------ doc/source/commands/flight/warp.rst | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/doc/source/bindings.rst b/doc/source/bindings.rst index 1d3cf81b5..a9b3e4047 100644 --- a/doc/source/bindings.rst +++ b/doc/source/bindings.rst @@ -123,7 +123,7 @@ ALT ALIAS --------- The special variable ALT is a unique exception. It behaves like a -structure with suffixes but it's acually a bit "fake" in that it's not +structure with suffixes but it's actually a bit "fake" in that it's not really a structure. The following terms are just exceptions that don't fit anywhere else: @@ -139,7 +139,7 @@ ETA ALIAS --------- The special variable ETA is a unique exception. It behaves like a -structure with suffixes but it's acually a bit "fake" in that it's not +structure with suffixes but it's actually a bit "fake" in that it's not really a structure. The following terms are just exceptions that don't fit anywhere else: @@ -204,7 +204,7 @@ Flight Control There are bound variables used in controlling the flight of a ship, which can be found at the following links: -If you want to let kOS do a lot of the work of alignging to a desired +If you want to let kOS do a lot of the work of aligning to a desired heading for you, use `Cooked Control `__. If you want your script to manipulate the controls directly (as in "set @@ -227,8 +227,8 @@ Controls that must be used with LOCK THROTTLE // Lock to a decimal value between 0 and 1. STEERING // Lock to a direction, either a Vector or a Direction. - WHEELTHROTTLE // Seperate throttle for wheels - WHEELSTEERING // Seperate steering system for wheels + WHEELTHROTTLE // Separate throttle for wheels + WHEELSTEERING // Separate steering system for wheels System Variables ---------------- @@ -281,7 +281,7 @@ MAPVIEW boolean Both settable and gettable. If TIME is a useful system variable for calculating the passage of time between taking -physical measurements (i.e. to calulate how fast a phenomenon is +physical measurements (i.e. to calculate how fast a phenomenon is changing in a loop). It returns the KSP *simulated* time, rather than the actual realtime sitting in the diff --git a/doc/source/commands/flight/warp.rst b/doc/source/commands/flight/warp.rst index e42bc5891..d8a4348bb 100644 --- a/doc/source/commands/flight/warp.rst +++ b/doc/source/commands/flight/warp.rst @@ -21,7 +21,7 @@ Time Warping one of the two strings mentioned above. The difference is the same as that experienced in the game between - physics warp and 'rails' warp (sometimes called 'time warp') allthough + physics warp and 'rails' warp (sometimes called 'time warp') although that term is confusingly ambiguous. .. table:: RAILS WARP MODES From e6d75c073c718ca699775dd0e93d4cc5586a6967 Mon Sep 17 00:00:00 2001 From: Chris Woerz Date: Wed, 15 Apr 2015 00:06:36 -0600 Subject: [PATCH 395/446] spelling --- doc/source/math/direction.rst | 4 ++-- doc/source/math/ref_frame.rst | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/doc/source/math/direction.rst b/doc/source/math/direction.rst index 9109356de..6681b847e 100644 --- a/doc/source/math/direction.rst +++ b/doc/source/math/direction.rst @@ -9,7 +9,7 @@ Directions :struct:`Direction` objects represent a rotation starting from an initial point in **KSP**'s coordinate system where the initial state was looking down the :math:`+z` axis, with the camera "up" being the :math:`+y` axis. This exists primarily to enable automated steering. -In your thinking, you can largely think of Directions as being Rotations and Rotations as being Directions. The two concepts can be used interchangably. Used on its own to steer by, a rotation from the default XYZ axes of the universe into a new rotation does in fact provide an absolute direction, thus the name Direction for these objects even though in reality they are just Rotations. It's important to know that Directions are just rotations because you can use them to modify other directions or vectors. +In your thinking, you can largely think of Directions as being Rotations and Rotations as being Directions. The two concepts can be used interchangeably. Used on its own to steer by, a rotation from the default XYZ axes of the universe into a new rotation does in fact provide an absolute direction, thus the name Direction for these objects even though in reality they are just Rotations. It's important to know that Directions are just rotations because you can use them to modify other directions or vectors. .. note:: When dealing with Directions (which are Rotations) in kOS, it is @@ -84,7 +84,7 @@ Creation .. function:: ROTATEFROMTO(fromVec,toVec) - A :struct:`Direction` can be created with the ROTATEFROMTO function. It is *one of the infinite number of* rotatations that could rotate vector *fromVec* to become vector *toVec* (or at least pointing in the same direction as toVec, since fromVec and toVec need not be the same magnitude). Note the use of the phrase "**infinite number of**". Because there's no guarantee about the roll information, there are an infinite number of rotations that could qualify as getting you from one vector to another, because there's an infinite number of roll angles that could result and all still fit the requirement:: + A :struct:`Direction` can be created with the ROTATEFROMTO function. It is *one of the infinite number of* rotations that could rotate vector *fromVec* to become vector *toVec* (or at least pointing in the same direction as toVec, since fromVec and toVec need not be the same magnitude). Note the use of the phrase "**infinite number of**". Because there's no guarantee about the roll information, there are an infinite number of rotations that could qualify as getting you from one vector to another, because there's an infinite number of roll angles that could result and all still fit the requirement:: SET myDir to ROTATEFROMTO( v1, v2 ). diff --git a/doc/source/math/ref_frame.rst b/doc/source/math/ref_frame.rst index 507367fbd..c5bf5470b 100644 --- a/doc/source/math/ref_frame.rst +++ b/doc/source/math/ref_frame.rst @@ -18,7 +18,7 @@ documentation: based on the Unity game engine) uses a **LEFT-handed** coordinate system. kOS inherits this behavior from KSP. -In all the the reference frames mentioned below, the orientation of +In all the reference frames mentioned below, the orientation of the axes is **left-handed**. This means that if you imagine opening your palm and pointing your fingers down the x-axis, then curling your fingers in the direction of the y-axis, then sticking your thumb up, that the @@ -52,17 +52,17 @@ instead, and Kerbal Space Program is one of them. .. index:: RAW-RAW (Reference Frame) .. object:: RAW-RAW - The name of the reference fraem in which both the origin point and the rotation of the axes is identical to **KSP**'s native raw coordinate grid. This is never exposed to the **KerbalScript** program, because the origin point is meaningless to work with. + The name of the reference frame in which both the origin point and the rotation of the axes is identical to **KSP**'s native raw coordinate grid. This is never exposed to the **KerbalScript** program, because the origin point is meaningless to work with. .. note:: It is hoped that this may be expanded in the future, and conversion routines provided to let people pick a reference frame that makes sense depending on what the script is trying to do. At the moment the only reference frames used are SHIP-RAW and SOI-RAW, as they match closely to what **KSP** is using internally. -Raw Orienatation +Raw Orientation ---------------- .. figure:: /_images/reference/math/KSP_body_coords.png -The Y axis of **KSP** is the only consistent thing. Imagine a ray starting in the center of the SOI body and pointing upward out through the north pole. That is the direction of the Y axis. (If you move to the SOI of a body with an inclinded spin, presumably it will also change the angle of the Y axis to point in the new direction of the body's spin axis). +The Y axis of **KSP** is the only consistent thing. Imagine a ray starting in the center of the SOI body and pointing upward out through the north pole. That is the direction of the Y axis. (If you move to the SOI of a body with an inclined spin, presumably it will also change the angle of the Y axis to point in the new direction of the body's spin axis). The X and Z axes of the coordinate grid are then consequently aligned with the equator plane of the SOI body, 90 degrees to each other. **KSP** uses a left-handed coordinate system, so the Z axis will always be rotated 90 degrees to the east of the X axis. From bff712380dfa1f5b3487b1a909c6486cad1aced2 Mon Sep 17 00:00:00 2001 From: Chris Woerz Date: Wed, 15 Apr 2015 00:11:22 -0600 Subject: [PATCH 396/446] spelling --- doc/source/language/user_functions.rst | 12 +++++------ doc/source/language/variables.rst | 28 +++++++++++++------------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/doc/source/language/user_functions.rst b/doc/source/language/user_functions.rst index 0858a7e14..7f2ffa97d 100644 --- a/doc/source/language/user_functions.rst +++ b/doc/source/language/user_functions.rst @@ -254,7 +254,7 @@ examples:: return. If your function needs to exit early, and/or if it needs to pass a -return value back to the user, you can use the RETURN staement to +return value back to the user, you can use the RETURN statement to do so. RETURN accepts an optional argument - the value to pass back to the caller. Note that functions in kerboscript are very weakly typed with late binding. You cannot declare the expected return @@ -265,10 +265,10 @@ example:: // Note, in this example, the keyword 'declare' is // spelled out explicitly. You can choose to do so - // if you wish. It's up to you what you aestetically + // if you wish. It's up to you what you aesthetically // prefer. - // Cacluate what component of a vessel's surface + // Calculate what component of a vessel's surface // velocity is Northward: declare function north_velocity { declare parameter which_vessel. @@ -312,7 +312,7 @@ Important exception to passing by value - structures If the value being sent to the function as its parameter is a complex structure consisting of sub-parts (i.e. if it has -suffxes) rather than being a simple single scalar value like a +suffixes) rather than being a simple single scalar value like a number, then the copy in the function is *really* a copy of the reference pointing to the object, so changes you make in the object really WILL change it, as shown here:: @@ -385,7 +385,7 @@ Example:: L:ADD(9). print "mean average is " + getMean(L). - // The following line will give an error becasue + // The following line will give an error because // getSum is local inside of getMean, and isn't allowed // to be called from here: // @@ -457,7 +457,7 @@ For example:: The above example contains a typo that causes a global variable to be made where you didn't mean to. You wanted to say "sum" but said "dum" -and insted of that being an error, kerboscript happily said "okay, +and instead of that being an error, kerboscript happily said "okay, well since you're setting a variable name that doesn't exist yet, I'll make it for you implicitly" (and it ends up being a global). diff --git a/doc/source/language/variables.rst b/doc/source/language/variables.rst index a73541081..e409d4822 100644 --- a/doc/source/language/variables.rst +++ b/doc/source/language/variables.rst @@ -44,7 +44,7 @@ The following alternate versions have identical meaning to each other: The meaning, and syntax, of this statement changed considerably in this update. Prior to this version, DECLARE always created global variables no matter where it appeared in the script. - See 'initialier required' below. + See 'initializer required' below. Detailed Description of the syntax: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -121,7 +121,7 @@ The syntax without the initializer, looking like so:: is **no longer legal syntax**. Kerboscript now requires the use of the initializer clause (the "TO" -keyword) after the identifer name so as to make it impossible for +keyword) after the identifier name so as to make it impossible for there to exist any uninitialized variables in a script. .. _declare parameter: @@ -137,7 +137,7 @@ If you put this statement inside of a :ref:`Function body `, then it declares variables to be used as a parameter that can be passed in to that function when calling the function. -Just as with a :ref:`declare itentifier statement `, +Just as with a :ref:`declare identifier statement `, in a ``declare parameter`` statement, the actual keyword ``declare`` need not be used. The word ``parameter`` may be used alone and that is legal syntax. @@ -178,7 +178,7 @@ Caveat This is only true if the values are primitive singleton values like numbers or booleans. If the values are Structures like Vectors or Lists, then they do end up behaving as if they were passed by reference, in the usual way that should be familiar to people who have used languages like Java or C# before. -**Illegal to say** ``DECLARE GLOBAL PARAMETER`` : Becasue parameters +**Illegal to say** ``DECLARE GLOBAL PARAMETER`` : Because parameters are always local to the location they were declared at, the keyword ``GLOBAL`` is illegal to use in a ``DECLARE PARAMETER`` statement. @@ -262,7 +262,7 @@ Note that because of how LOCK expressions are in fact implemented as mini functions, they cannot have local scope. A LOCK *always* has global scope. By default a ``LOCK`` expression is ``GLOBAL`` when made. This is -neccesary for backward compatibility with older scripts that use +necessary for backward compatibility with older scripts that use LOCK STEERING from inside triggers, loops, etc, and expect it to affect the global steering value. @@ -419,7 +419,7 @@ Why limit scope? global? The answer is twofold: (1) Once a program becomes large enough, trying to remember the name of every variable in the program, and having to keep coming up with new names for new - variables, can be a large unmanagable chore, especially with + variables, can be a large unmanageable chore, especially with programs written by more than one person collaborating together. (2) Even if you can keep track of all that in your head, there's a certain programming technique known as recursion @@ -492,8 +492,8 @@ Note that if you put a statement at the outermost scope of the program, then there is effectively no difference between a ``DECLARE LOCAL`` (or just ``LOCAL`` for short) and a ``DECLARE GLOBAL`` (or just ``GLOBAL`` for short) statement. -They are both goihg to make a variable at global scope because that's -the scope the program was in when the statement was encoutnered. +They are both going to make a variable at global scope because that's +the scope the program was in when the statement was encountered. Examples:: @@ -541,7 +541,7 @@ Nesting The scoping rules are nested as well. If you attempt to use a variable that doesn't exist in the local scope, the next scope "outside" -it wil be used, and if it doesn't exist there, the next scope "outside" +it will be used, and if it doesn't exist there, the next scope "outside" that will be used and so on, all the way up to the global scope. Only if the variable isn't found at the global scope either will it be implicitly created. @@ -571,7 +571,7 @@ just don't use local variables in the trigger conditions. ::::::::::::::::::::::::: Often the fact that you can get an implicit global variable declared -without intending to can lead to a lot of code maintenence headaches +without intending to can lead to a lot of code maintenance headaches down the road. If you make a typo in a variable name, you end up creating a new variable instead of generating an error. Or you may just forget to mark the variable as local when you intended to. @@ -650,9 +650,9 @@ Example:: Why ``LAZYGLOBAL OFF``? The rationale behind ``LAZYGLOBAL OFF.`` is to primarily be used in - cases where you're writing a libary of function calls you intend to + cases where you're writing a library of function calls you intend to use elsewhere, and want to be careful not to accidentally make - them dependant on globals outside the function itself. + them dependent on globals outside the function itself. The ``@LAZYGLOBAL OFF.`` directive is meant to mimic Perl's ``use strict;`` directive. @@ -664,9 +664,9 @@ History: declare a variable if you don't want to. You can just create any variable implicitly by just using it in a SET statement. - There are a variety of programming langauges that work like this, + There are a variety of programming languages that work like this, such as Perl, Javascript, and Lua. However, they all share one - thing in common - once you want to allow the possiblity of having + thing in common - once you want to allow the possibility of having local variables, you have to figure out how this should work with the implicit variable declaration feature. From d577064274023321108dd4d139a063aa69103735 Mon Sep 17 00:00:00 2001 From: abenkovskii Date: Wed, 15 Apr 2015 15:19:15 +0300 Subject: [PATCH 397/446] Added documentation for uid --- doc/source/structures/vessels/part.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/source/structures/vessels/part.rst b/doc/source/structures/vessels/part.rst index e853eff99..0142c7079 100644 --- a/doc/source/structures/vessels/part.rst +++ b/doc/source/structures/vessels/part.rst @@ -41,7 +41,7 @@ These are the generic properties every PART has. You can obtain a list of values - The stage this is associated with * - :attr:`UID` - string - - Unique identifying number + - Unique identifying number of this part * - :attr:`ROTATION` - :struct:`Direction` - The rotation of this part's :math:`x`-axis @@ -148,7 +148,7 @@ These are the generic properties every PART has. You can obtain a list of values :access: Get only :type: string - All parts have a unique ID number. Test if two parts are the same part by seeing if this is the same between them. + All parts have a unique ID number. Part's uid never changes because it is the same value as stored in persistent.sfs. Although you can compare parts by comparing their uid it is recomended to compare parts directly if possible. .. attribute:: Part:ROTATION From 871018542ce40302985863d62384e9af962e128a Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Wed, 15 Apr 2015 09:35:51 -0500 Subject: [PATCH 398/446] Better explanation of local/global keywords under @lazyglobal off. --- doc/source/language/user_functions.rst | 11 +++++----- doc/source/language/variables.rst | 30 +++++++++++++++++--------- 2 files changed, 25 insertions(+), 16 deletions(-) diff --git a/doc/source/language/user_functions.rst b/doc/source/language/user_functions.rst index 7f2ffa97d..55ada5da7 100644 --- a/doc/source/language/user_functions.rst +++ b/doc/source/language/user_functions.rst @@ -38,7 +38,7 @@ Help for the new user - What is a Function? In kerboscript, you can make your own user functions using the DECLARE FUNCTION command, which has syntax as follows: - [``declare``] [``local``|``global``] ``function`` *identifier* ``{`` *statements* ``}`` *optional dot (.)* + [``declare``] [``local``] ``function`` *identifier* ``{`` *statements* ``}`` *optional dot (.)* The statement is called a "declare function" statement even when the optional word "declare" was left off. @@ -50,12 +50,11 @@ The following are all identical in meaning:: local function hi { print "hello". } function hi { print "hello". } -Functions are presumed to have local scope when the explicit scope -keyword is missing. +Functions are presumed to have scope local to the location where +they are declareed when the explicit local scope keyword is missing. -While it is valid syntax to use a global keyword with a declare -function statement, it is not well defined yet in kOS 0.17.0 what -exactly that is supposed to mean, if anything. +At the moment, it is redundant to mention the ``local`` keyword, +althogh it is allowed. It is best to just leave all the optional keywords of and merely say ``function`` by itself. diff --git a/doc/source/language/variables.rst b/doc/source/language/variables.rst index e409d4822..12a732f7a 100644 --- a/doc/source/language/variables.rst +++ b/doc/source/language/variables.rst @@ -453,11 +453,6 @@ It is an error to attempt to declare a parameter with the GLOBAL keyword. this is necessary to preserve backward compatibility with how cooked controls such as LOCK STEERING and LOCK THROTTLE work. -Note that when operating under the :ref:`@LAZYGLOBAL OFF ` -directive the keywords LOCAL and GLOBAL are no longer optional, and are -in fact required. You are not allowed to rely on these presumed defaults -when you've turned off LAZYGLOBAL. - Explicit scoping keywords ::::::::::::::::::::::::: @@ -484,6 +479,17 @@ referred to as a "declare statement". The word "declare" is implied by the use of LOCAL or GLOBAL and you are allowed to leave it off merely to reduce verbosity. +Explicit Scoping required for @lazyglobal off +::::::::::::::::::::::::::::::::::::::::::::: + +Note that when operating under the :ref:`@LAZYGLOBAL OFF ` +directive the keywords LOCAL and GLOBAL are no longer optional for +**declare identifier** satements, and are in fact required. You +are not allowed to rely on these presumed defaults when you've +turned off LAZYGLOBAL. (This only applies to trying to make +a variable with **declare identifier to value**, and not to +``declare parameter`` or ``declare funcion``.) + Locals stated at the global level are global ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -604,8 +610,10 @@ duration of the entire file's compile. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Normally the keywords ``local`` and ``global`` can be left off -as optional in declare statements. But when you turn LAZYGLOBAL -off, the compiler starts requiring them to be explicitly stated. +as optional in declare **identifier** statements. But when you +turn LAZYGLOBAL off, the compiler starts requiring them to be +explicitly stated for **declare identifier** statements, to +force yourself to be clear and explicit about the difference. For example, this program, which is valid:: @@ -625,12 +633,14 @@ Starts giving errors when you add @LAZYGLOBAL OFF to the top:: Wich you fix by explicitly stating the local keyword, as follows:: @LAZYGLOBAL OFF. - local function foo {print "foo ". } - declare local x is 1. + function foo {print "foo ". } // This does not need the 'local' keyword added + declare local x is 1. // But this does because it is a declare *identifier* statememt. print foo() + x. - +If you get in the habit of just writing your **declare identifier** +statements like ``local x is 1.`` or ``global x is 1.``, which is +probably nicer to read anyway, the issue won't come up. Longer Example of use ~~~~~~~~~~~~~~~~~~~~~ From 3aa175984a4bc098ca2726a21a0b81fb88fbc952 Mon Sep 17 00:00:00 2001 From: Chris Woerz Date: Wed, 15 Apr 2015 08:48:38 -0600 Subject: [PATCH 399/446] spelling --- doc/source/language/user_functions.rst | 4 ++-- doc/source/language/variables.rst | 8 ++++---- doc/source/structures/vessels/part.rst | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/doc/source/language/user_functions.rst b/doc/source/language/user_functions.rst index 55ada5da7..108dee567 100644 --- a/doc/source/language/user_functions.rst +++ b/doc/source/language/user_functions.rst @@ -51,10 +51,10 @@ The following are all identical in meaning:: function hi { print "hello". } Functions are presumed to have scope local to the location where -they are declareed when the explicit local scope keyword is missing. +they are declared when the explicit local scope keyword is missing. At the moment, it is redundant to mention the ``local`` keyword, -althogh it is allowed. +although it is allowed. It is best to just leave all the optional keywords of and merely say ``function`` by itself. diff --git a/doc/source/language/variables.rst b/doc/source/language/variables.rst index 12a732f7a..8a46e470f 100644 --- a/doc/source/language/variables.rst +++ b/doc/source/language/variables.rst @@ -484,11 +484,11 @@ Explicit Scoping required for @lazyglobal off Note that when operating under the :ref:`@LAZYGLOBAL OFF ` directive the keywords LOCAL and GLOBAL are no longer optional for -**declare identifier** satements, and are in fact required. You +**declare identifier** statements, and are in fact required. You are not allowed to rely on these presumed defaults when you've turned off LAZYGLOBAL. (This only applies to trying to make a variable with **declare identifier to value**, and not to -``declare parameter`` or ``declare funcion``.) +``declare parameter`` or ``declare function``.) Locals stated at the global level are global @@ -630,11 +630,11 @@ Starts giving errors when you add @LAZYGLOBAL OFF to the top:: print foo() + x. -Wich you fix by explicitly stating the local keyword, as follows:: +Which you fix by explicitly stating the local keyword, as follows:: @LAZYGLOBAL OFF. function foo {print "foo ". } // This does not need the 'local' keyword added - declare local x is 1. // But this does because it is a declare *identifier* statememt. + declare local x is 1. // But this does because it is a declare *identifier* statement. print foo() + x. diff --git a/doc/source/structures/vessels/part.rst b/doc/source/structures/vessels/part.rst index 0142c7079..a48e0c2d8 100644 --- a/doc/source/structures/vessels/part.rst +++ b/doc/source/structures/vessels/part.rst @@ -148,7 +148,7 @@ These are the generic properties every PART has. You can obtain a list of values :access: Get only :type: string - All parts have a unique ID number. Part's uid never changes because it is the same value as stored in persistent.sfs. Although you can compare parts by comparing their uid it is recomended to compare parts directly if possible. + All parts have a unique ID number. Part's uid never changes because it is the same value as stored in persistent.sfs. Although you can compare parts by comparing their uid it is recommended to compare parts directly if possible. .. attribute:: Part:ROTATION From b313cbcdafd28cdfdde04f2a01d0c187689cfbb4 Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Wed, 15 Apr 2015 12:57:08 -0500 Subject: [PATCH 400/446] Fixes #806 Fixes #085 Fixes #718 They're all part of the KOSNameTagWindow so I changed them all in one go. --- src/kOS/Screen/KOSNameTagWindow.cs | 48 +++++++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/src/kOS/Screen/KOSNameTagWindow.cs b/src/kOS/Screen/KOSNameTagWindow.cs index beecff00f..ce0bfdb3c 100644 --- a/src/kOS/Screen/KOSNameTagWindow.cs +++ b/src/kOS/Screen/KOSNameTagWindow.cs @@ -1,6 +1,7 @@ using kOS.Utilities; using UnityEngine; using kOS.Module; +using System; namespace kOS.Screen { @@ -12,12 +13,17 @@ public class KOSNameTagWindow : MonoBehaviour // ReSharper disable RedundantDefaultFieldInitializer private bool wasFocusedOnce = false; // "explicit", not "redundant". private int numberOfRepaints = 0; // "explicit", not "redundant". + private bool gameEventHooksExist = false; // "explicit", not "redundant". + private int myWindowId; // must be unique for Unity to not mash two nametag windows togehter. + // ReSharper enable RedundantDefaultFieldInitializer public void Invoke(KOSNameTag module, string oldValue) { + Console.WriteLine("eraseme: KOsNameTagWindow (instance="+GetInstanceID()+") .Invoke() called with module = " + module.GetInstanceID() ); attachedModule = module; tagValue = oldValue; + myWindowId = GetInstanceID(); // Use the Id of this MonoBehaviour to guarantee unique window ID. Vector3 screenPos = GetViewportPosFor(attachedModule.part.transform.position); @@ -44,6 +50,22 @@ public void Invoke(KOSNameTag module, string oldValue) if (HighLogic.LoadedSceneIsEditor) attachedModule.part.SetHighlight(false, false); + + } + + /// + /// Catch the event of the part disappearing, from crashing or + /// from unloading from distance or scene change, and ensure + /// the window closes if it was open when that happens: + /// + /// The callback is called for EVERY part + /// that ever goes away, so we have to check if it's the right one + public void GoAwayEventCallback(Part whichPartWentAway) + { + if (whichPartWentAway != attachedModule.part) + return; + + Close(); } /// @@ -58,6 +80,25 @@ private void SetEnabled(bool newVal) // ReSharper disable once RedundantCheckBeforeAssignment if (newVal != enabled) enabled = newVal; + + if (enabled) + { + if (! gameEventHooksExist) + { + GameEvents.onPartDestroyed.Add(GoAwayEventCallback); + GameEvents.onPartDie.Add(GoAwayEventCallback); + gameEventHooksExist = true; + } + } + else + { + if (gameEventHooksExist) + { + GameEvents.onPartDestroyed.Remove(GoAwayEventCallback); + GameEvents.onPartDie.Remove(GoAwayEventCallback); + gameEventHooksExist = false; + } + } } /// @@ -84,7 +125,7 @@ public void OnGUI() EditorLogic.fetch.Lock(false, false, false, "KOSNameTagLock"); GUI.skin = HighLogic.Skin; - GUILayout.Window(0, windowRect, DrawWindow,"KOS nametag"); + GUILayout.Window(myWindowId, windowRect, DrawWindow,"KOS nametag"); // Ensure that the first time the window is made, it gets keybaord focus, // but allow the focus to leave the window after that: @@ -148,5 +189,10 @@ public void Close() if (HighLogic.LoadedSceneIsEditor) attachedModule.part.SetHighlight(false, false); } + + public void OnDestroy() + { + SetEnabled(false); + } } } \ No newline at end of file From 898df23a5bcebe82cce40bb170f19a4f37602c69 Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Wed, 15 Apr 2015 13:24:26 -0500 Subject: [PATCH 401/446] upped config:ipu default for new users to 200. --- src/kOS/Suffixed/Config.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kOS/Suffixed/Config.cs b/src/kOS/Suffixed/Config.cs index 63e00231e..1f8857f22 100644 --- a/src/kOS/Suffixed/Config.cs +++ b/src/kOS/Suffixed/Config.cs @@ -40,7 +40,7 @@ private Config() private void BuildValuesDictionary() { - AddConfigKey(PropId.InstructionsPerUpdate, new ConfigKey("InstructionsPerUpdate", "IPU", "Instructions per update", 150, 50, 2000, typeof(int))); + AddConfigKey(PropId.InstructionsPerUpdate, new ConfigKey("InstructionsPerUpdate", "IPU", "Instructions per update", 200, 50, 2000, typeof(int))); AddConfigKey(PropId.UseCompressedPersistence, new ConfigKey("UseCompressedPersistence", "UCP", "Use compressed persistence", false, false, true, typeof(bool))); AddConfigKey(PropId.ShowStatistics, new ConfigKey("ShowStatistics", "STAT", "Show execution statistics", false, false, true, typeof(bool))); AddConfigKey(PropId.EnableRTIntegration, new ConfigKey("EnableRTIntegration", "RT", "Enable RT integration", true, false, true, typeof(bool))); From 9c83226f0fc6ccb7f367a0cfd750f9a18a126d82 Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Wed, 15 Apr 2015 13:59:15 -0500 Subject: [PATCH 402/446] The previous terminal limits were a bit too small. --- src/kOS.Safe/Encapsulation/TerminalStruct.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/kOS.Safe/Encapsulation/TerminalStruct.cs b/src/kOS.Safe/Encapsulation/TerminalStruct.cs index d0903ea61..a66fa4ae0 100644 --- a/src/kOS.Safe/Encapsulation/TerminalStruct.cs +++ b/src/kOS.Safe/Encapsulation/TerminalStruct.cs @@ -10,9 +10,9 @@ public class TerminalStruct : Structure // They may have to change after experimentation. protected const int MINROWS = 3; - protected const int MAXROWS = 80; + protected const int MAXROWS = 160; protected const int MINCOLUMNS = 15; - protected const int MAXCOLUMNS = 160; + protected const int MAXCOLUMNS = 255; // TODO: To implement IsOpen, we'd have to make a kOS.Safe interface wrapper around TermWindow first. // That's more than I want to do in this update, I'm leaving it as a TODO for me or someone else: @@ -52,4 +52,4 @@ public override string ToString() return string.Format("{0} Terminal", base.ToString()); } } -} \ No newline at end of file +} From 1de6c5af0a8cf208d75ae6ea56639687e48ad9a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Xavi=20Ondo=C3=B1o?= Date: Wed, 15 Apr 2015 23:18:56 +0200 Subject: [PATCH 403/446] Update bindings.rst Issue #799 --- doc/source/bindings.rst | 1 - 1 file changed, 1 deletion(-) diff --git a/doc/source/bindings.rst b/doc/source/bindings.rst index 97ac606a0..451203c0b 100644 --- a/doc/source/bindings.rst +++ b/doc/source/bindings.rst @@ -72,7 +72,6 @@ SRFREROGRADE Same as SHIP:SRFREROGRADE OBT Same as SHIP:OBT STATUS Same as SHIP:STATUS VESSELNAME Same as SHIP:NAME -*Any resource* Same as SHIP:*resourcename*, eg. LIQUIDFUEL is the same as SHIP:LIQUIDFUEL ================ ============================================================================== Resource Types From 8aaf2212447a7dd543148073a35972a770eda797 Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Wed, 15 Apr 2015 16:21:02 -0500 Subject: [PATCH 404/446] oops - left an 'eraseme' printout in there. --- src/kOS/Screen/KOSNameTagWindow.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/kOS/Screen/KOSNameTagWindow.cs b/src/kOS/Screen/KOSNameTagWindow.cs index ce0bfdb3c..2a6b462c2 100644 --- a/src/kOS/Screen/KOSNameTagWindow.cs +++ b/src/kOS/Screen/KOSNameTagWindow.cs @@ -20,7 +20,6 @@ public class KOSNameTagWindow : MonoBehaviour public void Invoke(KOSNameTag module, string oldValue) { - Console.WriteLine("eraseme: KOsNameTagWindow (instance="+GetInstanceID()+") .Invoke() called with module = " + module.GetInstanceID() ); attachedModule = module; tagValue = oldValue; myWindowId = GetInstanceID(); // Use the Id of this MonoBehaviour to guarantee unique window ID. From a97a09b79a2b32e0daae580a17b1c810b4073bb3 Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Wed, 15 Apr 2015 17:37:40 -0500 Subject: [PATCH 405/446] Fixes #676 no more second error on syntax errors. When I examined it, I saw that this is how it's meant to work in normal cases: There are two instruction pointers - one for where you are in the interpreter context and another for where you are in the program context. When you run a program, it does this: 1. Interpreter context has an OpcodeCall that calls built-in function run(). 2. Function run() tells CPU it should switch to program context on the next instruction. 3. Function run() calls compiler, and populates the CPU's program context with the resulting program. 4. Function run() finishes. 5. CPU, like it does for all opcode executions, updates the instruction pointer of the current context to the next opcode. 6. CPU finishes loop iteration, and begins new loop. 7. CPU now is in the new program context, and is running the program. 8. When program finishes or errors out, CPU returns to interpreter context and picks up where it left the instruction pointer for the interpreter. The problem is when step 3 barfs and throws an exception, the CPU was *already* told in step 2 that it is no longer going to be in interpreter context, so when it handles the error it's handling it as if it had come from a program instead of from the interpreter, and thus is does NOT advance the interpreter's instruction pointer, thinking that had already been done before in step 5 of the previous iteration just before it had jumped into the "program" it thought it was running. Thus the interpreter tries to run the same Opcode a second time, and gets the new error because the stack was already popped in the first attempt to call the run() function. The second time it tries to call run(), the args it needs aren't there on the stack anymore, thus the null ref error. The fix was to detect when the compiler failed in step 3, and when it did, to undo the "you are now in program context" setup it did in step 2, so the CPU knows it's still in interpreter context and it does therefore need to advance the interpreter's instruction pointer. --- src/kOS/Execution/CPU.cs | 4 ++-- src/kOS/Function/Misc.cs | 18 +++++++++++++++--- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/kOS/Execution/CPU.cs b/src/kOS/Execution/CPU.cs index d043f6e10..cb163de57 100644 --- a/src/kOS/Execution/CPU.cs +++ b/src/kOS/Execution/CPU.cs @@ -112,7 +112,7 @@ public void Boot() else { shared.ScriptHandler.ClearContext("program"); - var programContext = ((CPU)shared.Cpu).GetProgramContext(); + var programContext = ((CPU)shared.Cpu).SwitchToProgramContext(); programContext.Silent = true; var options = new CompilerOptions { LoadProgramsInSameAddressSpace = true }; string filePath = shared.VolumeMgr.GetVolumeRawIdentifier(shared.VolumeMgr.CurrentVolume) + "/" + "boot"; @@ -238,7 +238,7 @@ public ProgramContext GetInterpreterContext() return contexts[0]; } - public ProgramContext GetProgramContext() + public ProgramContext SwitchToProgramContext() { if (contexts.Count == 1) { diff --git a/src/kOS/Function/Misc.cs b/src/kOS/Function/Misc.cs index a9bdcb14f..e4eced3c3 100644 --- a/src/kOS/Function/Misc.cs +++ b/src/kOS/Function/Misc.cs @@ -179,7 +179,7 @@ public override void Execute(SharedObjects shared) shared.ScriptHandler.ClearContext("program"); string filePath = shared.VolumeMgr.GetVolumeRawIdentifier(shared.VolumeMgr.CurrentVolume) + "/" + fileName ; var options = new CompilerOptions {LoadProgramsInSameAddressSpace = true, FuncManager = shared.FunctionManager}; - var programContext = ((CPU)shared.Cpu).GetProgramContext(); + var programContext = ((CPU)shared.Cpu).SwitchToProgramContext(); List codeParts; if (file.Category == FileCategory.KSM) @@ -189,7 +189,19 @@ public override void Execute(SharedObjects shared) } else { - codeParts = shared.ScriptHandler.Compile(filePath, 1, file.StringContent, "program", options); + try + { + codeParts = shared.ScriptHandler.Compile(filePath, 1, file.StringContent, "program", options); + } + catch (Exception e) + { + // If it died due to a compile error, then we won't really be able to switch to program context + // as was implied by calling Cpu.SwitchToProgramContext() up above. The CPU needs to be + // told that it's still in interpreter context, or else it fails to advance the interpreter's + // instruction pointer and it will just try the "call run()" instruction again: + shared.Cpu.BreakExecution(false); + throw; + } } programContext.AddParts(codeParts); } @@ -264,7 +276,7 @@ public override void Execute(SharedObjects shared) } else { - var programContext = ((CPU)shared.Cpu).GetProgramContext(); + var programContext = ((CPU)shared.Cpu).SwitchToProgramContext(); List parts; if (file.Category == FileCategory.KSM) { From aa8e1ff913974fa4ee955db5d593cb63f306b02f Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Wed, 15 Apr 2015 18:49:48 -0500 Subject: [PATCH 406/446] An error @teleksterling found in the phrasing. --- doc/source/language/user_functions.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/source/language/user_functions.rst b/doc/source/language/user_functions.rst index 108dee567..f0153f58e 100644 --- a/doc/source/language/user_functions.rst +++ b/doc/source/language/user_functions.rst @@ -470,8 +470,8 @@ don't let me do that. Please force me to declare everything". The way that is done in kerboscript is by using a ``@LAZYGLOBAL`` compiler directive, :ref:`as described here `. -Had the function above been wrapped inside a ``@LAZYGLOBAL off.`` section, -the typo would be noticed:: +Had the function above been compiled under a ``@LAZYGLOBAL off.`` +compiler directive, the typo would be noticed:: @lazyglobal off. From c185da2e443eb5f9ae6e0a35a34c46424ceb8472 Mon Sep 17 00:00:00 2001 From: Brad White Date: Thu, 16 Apr 2015 09:44:12 -0400 Subject: [PATCH 407/446] 1st draft of the sasmode documentation Updated the SAS warning in flight.rst according to new SAS behavior. Added the explaination for sasmode to systems.rst. Listed right below the section for toggling sas itself to keep connected thoughts together. --- doc/source/commands/flight.rst | 2 +- doc/source/commands/flight/systems.rst | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/doc/source/commands/flight.rst b/doc/source/commands/flight.rst index 5f4996b80..fc45bf07d 100644 --- a/doc/source/commands/flight.rst +++ b/doc/source/commands/flight.rst @@ -25,4 +25,4 @@ Unless otherwise stated, all controls that a **kOS** CPU attempts will be done o .. warning:: **SAS OVERRIDES kOS** - With the current implementation of flight control, if you leave ``SAS`` turned on, it will override **kOS**'s attempts to steer the ship. In order for **kOS** to be able to turn the ship, you need to set ``SAS OFF``. In manual control, you can pilot with ``SAS ON``, because the pilot's manual controls override the ``SAS`` and "fight" against it. In **KOS** no such ability exists. If ``SAS`` is on, **kOS** won't be able to turn the ship. It is common for people writing **kOS** scripts to explicitly start them with a use of the ``SAS OFF`` command just in case you forgot to turn it off before running the script. + With the current implementation of flight control, you may now leave ``SAS`` turned on in ``"STABILITYASSIST"`` mode, and it will not override **kOS**'s attempts to steer the ship. However, it will fight and/or override **kOS**'s attempts to steer when using any other mode. In order for **kOS** to be able to turn the ship in other modes, you need to set ``SAS OFF`` or ``SET SASMODE TO "STABILITYASSIST"``. You should take care in your scripts to manage the use of ``SAS`` and ``SASMODE`` appropriately. It is common for people writing **kOS** scripts to explicitly start them with a use of the ``SAS OFF`` and/or ``SET SASMODE TO "STABILITYASSIST"`` commands just in case you forgot to turn it off before running the script. You could also store the current state in a temporary variable, and re-set it at the conclusion of your script. diff --git a/doc/source/commands/flight/systems.rst b/doc/source/commands/flight/systems.rst index 5e5d413d6..87060afbf 100644 --- a/doc/source/commands/flight/systems.rst +++ b/doc/source/commands/flight/systems.rst @@ -24,6 +24,17 @@ Ship Systems SAS ON. +.. object:: SET SASMODE TO value. + + :access: Get/Set + :type: string + + Getting this variable will return the currently selected mode. Where ``value`` is one of the valid strings listed below, this will set the stock SAS mode for the cpu vessel:: + + SET SASMODE TO value. + + It is the equivalent to clicking on the buttons next to the nav ball while manually piloting the craft, and will respect the current mode of the nav ball (orbital, surface, or target velocity). Valid strings for ``value`` are ``"PROGRADE"``, ``"RETROGRADE"``, ``"NORMAL"``, ``"ANTINORMAL"``, ``"RADIALOUT"``, ``"RADIALIN"``, ``"TARGET"``, ``"ANTITARGET"``, ``"STABILITYASSIST"``, and ``"STABILITY"``. A null or empty string will default to stability assist mode, however any other invalid string will throw an exception. This feature will respect career mode limitations, and will throw an exception if the current vessel is not able to use the mode passed to the command. An exception is also thrown if ``"TARGET"`` or ``"ANTITARGET"`` are used, but no target is selected. + .. global:: LIGHTS :access: Toggle ON/OFF From 85450af9b210755b3797dcd2c471d7ad66f7e9db Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Thu, 16 Apr 2015 20:20:55 -0500 Subject: [PATCH 408/446] added document links to the examples repo --- doc/source/index.rst | 1 + doc/source/library.rst | 26 ++++++++++++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 doc/source/library.rst diff --git a/doc/source/index.rst b/doc/source/index.rst index c583d2699..976834d3d 100644 --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -13,6 +13,7 @@ Welcome to the **kOS** Documentation Website! Home Downloads and Links Tutorials + Community Example Library General Language Mathematics diff --git a/doc/source/library.rst b/doc/source/library.rst new file mode 100644 index 000000000..c64567590 --- /dev/null +++ b/doc/source/library.rst @@ -0,0 +1,26 @@ +.. _library: + +Community Examples Library +=========================== + +Starting with version 0.17.0 of kOS, we have decided to support +a separate repository of examples and libraries that "live" entirely +in kerboscript code only. This is a useful place to find helpful +code written by other users of kOS, some of whom may be members of +the main kOS development team, and some of whom might ber users in the +community. + +The separate repository is found here: + + https://github.com/KSP-KOS/KSLib + +Some examples of useful things you can find there are: + + * A generic all-purpos PID controller function: + * `library script `, + `documentation `, and + `example ` + * A library for getting navball rotation information: + * `library script `, + `documentation `, and + `example ` From 93a6cc87c3d3e6fd551446e1620451a7229b4de1 Mon Sep 17 00:00:00 2001 From: hvacengi Date: Thu, 16 Apr 2015 23:06:47 -0400 Subject: [PATCH 409/446] I forgot maneuver, adding it here. --- doc/source/commands/flight/systems.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/commands/flight/systems.rst b/doc/source/commands/flight/systems.rst index 87060afbf..e22d72b93 100644 --- a/doc/source/commands/flight/systems.rst +++ b/doc/source/commands/flight/systems.rst @@ -33,7 +33,7 @@ Ship Systems SET SASMODE TO value. - It is the equivalent to clicking on the buttons next to the nav ball while manually piloting the craft, and will respect the current mode of the nav ball (orbital, surface, or target velocity). Valid strings for ``value`` are ``"PROGRADE"``, ``"RETROGRADE"``, ``"NORMAL"``, ``"ANTINORMAL"``, ``"RADIALOUT"``, ``"RADIALIN"``, ``"TARGET"``, ``"ANTITARGET"``, ``"STABILITYASSIST"``, and ``"STABILITY"``. A null or empty string will default to stability assist mode, however any other invalid string will throw an exception. This feature will respect career mode limitations, and will throw an exception if the current vessel is not able to use the mode passed to the command. An exception is also thrown if ``"TARGET"`` or ``"ANTITARGET"`` are used, but no target is selected. + It is the equivalent to clicking on the buttons next to the nav ball while manually piloting the craft, and will respect the current mode of the nav ball (orbital, surface, or target velocity). Valid strings for ``value`` are ``"PROGRADE"``, ``"RETROGRADE"``, ``"NORMAL"``, ``"ANTINORMAL"``, ``"RADIALOUT"``, ``"RADIALIN"``, ``"TARGET"``, ``"ANTITARGET"``, ``MANEUVER``, ``"STABILITYASSIST"``, and ``"STABILITY"``. A null or empty string will default to stability assist mode, however any other invalid string will throw an exception. This feature will respect career mode limitations, and will throw an exception if the current vessel is not able to use the mode passed to the command. An exception is also thrown if ``"TARGET"`` or ``"ANTITARGET"`` are used, but no target is selected. .. global:: LIGHTS From fb4b8693554f788b941805016b124d0389b1972e Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Thu, 16 Apr 2015 22:14:24 -0500 Subject: [PATCH 410/446] Committing so I can merge in hvacengi's branch. --- doc/source/addons/AGX.rst | 2 + doc/source/changes.rst | 83 +++++++++++++++++++++++ doc/source/commands/files.rst | 1 + doc/source/commands/flight/systems.rst | 2 + doc/source/commands/list.rst | 2 +- doc/source/commands/resource_transfer.rst | 2 + doc/source/language/variables.rst | 2 + doc/source/library.rst | 24 ++++--- doc/source/structures/misc/colors.rst | 2 + doc/source/structures/vessels/element.rst | 13 +++- 10 files changed, 121 insertions(+), 12 deletions(-) diff --git a/doc/source/addons/AGX.rst b/doc/source/addons/AGX.rst index a0edca0f9..75028b45c 100644 --- a/doc/source/addons/AGX.rst +++ b/doc/source/addons/AGX.rst @@ -1,3 +1,5 @@ +.. _AGX: + Action Groups Extended ====================== diff --git a/doc/source/changes.rst b/doc/source/changes.rst index 1ac020e72..6dc1bafbc 100644 --- a/doc/source/changes.rst +++ b/doc/source/changes.rst @@ -16,6 +16,32 @@ of documentation again from scratch. Changes in 0.17.0 ----------------- +Variables can now be local +:::::::::::::::::::::::::: + +Previously, the kOS runtime had a serious limitation in which +it could only support one flat namespace of global-only variables. +Considerable archetecture re-work has been done to now support +:ref:`block-scoping ` in the underlying runtime, which can +be controlled through the use of :ref:`local declarations ` +in your kerboscript files. + +User Functions +:::::::::::::: + +The primary reason for the local scope variables rework was in +support of the new :ref:`user functions feature ` +which has been a long-wished-for feature for kOS to support. + +Community Examples Library +:::::::::::::::::::::::::: + +There is now a :ref:`new fledgling repository of examples and library +scripts` that we hope to be something the user community +contributes to. Some of the examples shown in the kOS 0.17.0 release +video are located there. The addition of the ability to make user +functions now makes the creation of such a library a viable option. + Physics Ticks not Update Ticks :::::::::::::::::::::::::::::: @@ -27,5 +53,62 @@ penalizing the users of faster computers anymore. (Previously, if your computer was faster, you'd be charged more electricity as the updates came more often). +Blizzy ToolBar Support +:::::::::::::::::::::: + +If you have the Blizzy Toolbar mod installed, you should be able +to put the kOS control panel window under its control. + +Ability to define colors using HSV +:::::::::::::::::::::::::::::::::: + +When a color is called for, such as with VECDRAW or HIGHLIGHT, you +can now use the :ref:`HSV color system (hue, saturation, value)` +instead of RGB, if you prefer. + +Ability to highlight a part in color +:::::::::::::::::::::::::::::::::::: + +Any time your script needs to communicate something to the user about +which part or parts it's dealing with, it can use KSP's :ref:`part +highlighting feature ` to show a part. + +Better user interface for selecting boot scripts +:::::::::::::::::::::::::::::::::::::::::::::::: + +The selection of :ref:`boot scripts for your vessel ` has been +improved. + +Disks can be made bigger with tweakable slider +:::::::::::::::::::::::::::::::::::::::::::::: + +All parts that have disk space now have a slider you can use in the VAB +or SPH editors to tweak the disk space to choose whether you want it to +have 1x, 2x, or 4x as much as its default size. Increasing the size +increases its price and its weight cost. + +You Can Transfer Resources +:::::::::::::::::::::::::: + +You can now use kOS scripts to :ref:`transfer resources between +parts ` for things like fuel, in the same way +that a manual user can do by using the right-click menus. + +Kerbal Alarm Clock support +:::::::::::::::::::::::::: + +If you have the Kerbal Alarm Clock Mod isntalled, you can now +:ref:`query and manipulate its alarms ` from within your +kOS scripts. + +Query the docked elements of a vessel +::::::::::::::::::::::::::::::::::::: + +You can get the :ref:`docked components of a joined-together +vessel ` as separate collections of parts now. +Support for Action Groups Extended +:::::::::::::::::::::::::::::::::: +While there was some support for the Action Groups Extended +mod before, it has :ref:`been greatly improved `. diff --git a/doc/source/commands/files.rst b/doc/source/commands/files.rst index e59e7b512..d1eb46687 100644 --- a/doc/source/commands/files.rst +++ b/doc/source/commands/files.rst @@ -272,6 +272,7 @@ Example:: SWITCH TO AwesomeDisk. // Switch to volume 1. PRINT VOLUME:NAME. // Prints "AwesomeDisk". +.. _boot: Special handling of files starting with "boot" (example ``boot.ks``) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/doc/source/commands/flight/systems.rst b/doc/source/commands/flight/systems.rst index 87060afbf..7f35a1749 100644 --- a/doc/source/commands/flight/systems.rst +++ b/doc/source/commands/flight/systems.rst @@ -24,6 +24,8 @@ Ship Systems SAS ON. +.. _sasmode: + .. object:: SET SASMODE TO value. :access: Get/Set diff --git a/doc/source/commands/list.rst b/doc/source/commands/list.rst index 049370c7a..b6be33b35 100644 --- a/doc/source/commands/list.rst +++ b/doc/source/commands/list.rst @@ -57,7 +57,7 @@ These generate :struct:`lists ` of items on the :struct:`Vessel`: ``Sensors`` :struct:`List` of :struct:`Sensors ` ``Elements`` - ?? + :struct:`List` of :ref:`Elements ` that comprise the current vessel. ``DockingPorts`` list of `DockingPorts ` diff --git a/doc/source/commands/resource_transfer.rst b/doc/source/commands/resource_transfer.rst index e846b0ef3..3527f7df9 100644 --- a/doc/source/commands/resource_transfer.rst +++ b/doc/source/commands/resource_transfer.rst @@ -1,3 +1,5 @@ +.. _resource transfer: + Transferring resources ====================== diff --git a/doc/source/language/variables.rst b/doc/source/language/variables.rst index 8a46e470f..33c19c0d7 100644 --- a/doc/source/language/variables.rst +++ b/doc/source/language/variables.rst @@ -22,6 +22,8 @@ Allowed Syntax: All the following are legal "declare" statements: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.. _declare syntax: + The following alternate versions have identical meaning to each other: * ``DECLARE`` *identifier* ``TO`` *expression* *dot* diff --git a/doc/source/library.rst b/doc/source/library.rst index c64567590..76602859e 100644 --- a/doc/source/library.rst +++ b/doc/source/library.rst @@ -1,7 +1,7 @@ .. _library: Community Examples Library -=========================== +========================== Starting with version 0.17.0 of kOS, we have decided to support a separate repository of examples and libraries that "live" entirely @@ -12,15 +12,19 @@ community. The separate repository is found here: - https://github.com/KSP-KOS/KSLib +https://github.com/KSP-KOS/KSLib Some examples of useful things you can find there are: - * A generic all-purpos PID controller function: - * `library script `, - `documentation `, and - `example ` - * A library for getting navball rotation information: - * `library script `, - `documentation `, and - `example ` +* A generic all-purpose **PID controller** function: + `library script `_, + `documentation `_, and + `example `_ + +* A library for getting **navball orientation** information: + `library script `_, + `documentation `_, and + `example `_ + +* An example of how to use the :ref:`sasmode ` feature: + `example `_ diff --git a/doc/source/structures/misc/colors.rst b/doc/source/structures/misc/colors.rst index b232d097f..e92e873e3 100644 --- a/doc/source/structures/misc/colors.rst +++ b/doc/source/structures/misc/colors.rst @@ -94,6 +94,8 @@ Examples:: PRINT GREEN:HTML. // prints #00ff00 +.. _hsv: + .. function:: HSV(h,s,v) This global function creates a color from hue, saturation and value:: diff --git a/doc/source/structures/vessels/element.rst b/doc/source/structures/vessels/element.rst index 61a18fb61..f9b76530d 100644 --- a/doc/source/structures/vessels/element.rst +++ b/doc/source/structures/vessels/element.rst @@ -3,7 +3,18 @@ Element ====== -An element is a docked component of a :struct:`Vessel` +An element is a *docked component* of a :struct:`Vessel`. When you dock several +vessels together to create one larger vessel, you can obtain the "chunks" of the +larger vessel organized by which original vessel they came from. These "chunks" +are called elements, and they are what the Element structure refers to. + +A list of elements from the vessel can be created by using the command:: + + list elements in eList. + // now eList is a list of elements from the vessel. + +Each item of that list is one of the elements. The rest of this page describes the +elements and what they do. .. note:: Element boundries are not formed between two docking ports that were launched coupled. a craft with such an arrangement will appear as one element until you uncoupled the nodes and redocked From 5cf54d6bc509d2d4d111748d76b3dbcc088ea392 Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Thu, 16 Apr 2015 22:20:45 -0500 Subject: [PATCH 411/446] Final version of the 0.17.0 changes.rst file, I hope. --- doc/source/changes.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/source/changes.rst b/doc/source/changes.rst index 6dc1bafbc..3dd7bea98 100644 --- a/doc/source/changes.rst +++ b/doc/source/changes.rst @@ -26,8 +26,8 @@ Considerable archetecture re-work has been done to now support be controlled through the use of :ref:`local declarations ` in your kerboscript files. -User Functions -:::::::::::::: +Kerboscript has User Functions +:::::::::::::::::::::::::::::: The primary reason for the local scope variables rework was in support of the new :ref:`user functions feature ` From 1812588661b62389f22671c4ee9b0a95f7e2236e Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Thu, 16 Apr 2015 23:07:06 -0500 Subject: [PATCH 412/446] added mention of sas mode. --- doc/source/changes.rst | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/doc/source/changes.rst b/doc/source/changes.rst index 3dd7bea98..88df00160 100644 --- a/doc/source/changes.rst +++ b/doc/source/changes.rst @@ -53,6 +53,14 @@ penalizing the users of faster computers anymore. (Previously, if your computer was faster, you'd be charged more electricity as the updates came more often). +Ability to use SAS modes from KSP 0.90 +:::::::::::::::::::::::::::::::::::::: + +Added a new :ref:`third way to control the ship `, +by leaving SAS on, and just telling KSP which mode +(prograde, retrograde, normal, etc) to put the SAS +into. + Blizzy ToolBar Support :::::::::::::::::::::: From fb7c2df651e484b3e0f116513a625579cde8cc36 Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Fri, 17 Apr 2015 00:14:12 -0500 Subject: [PATCH 413/446] Transfer functions were doing it old-style. Somehow the update to change them to the new function style never stuck or got reverted or something. Warning - this is only confirmed to compile. It's not tested yet. --- src/kOS/Function/Suffixed.cs | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/kOS/Function/Suffixed.cs b/src/kOS/Function/Suffixed.cs index 3374736f5..c74698ba9 100644 --- a/src/kOS/Function/Suffixed.cs +++ b/src/kOS/Function/Suffixed.cs @@ -444,9 +444,10 @@ public class FunctionTransferAll : FunctionBase { public override void Execute(SharedObjects shared) { - var transferTo = shared.Cpu.PopValue(); - var transferFrom = shared.Cpu.PopValue(); - var resourceName = shared.Cpu.PopValue().ToString(); + var transferTo = PopValueAssert(shared); + var transferFrom = PopValueAssert(shared); + var resourceName = PopValueAssert(shared).ToString(); + AssertArgBottomAndConsume(shared); var resourceInfo = TransferManager.ParseResource(resourceName); if (resourceInfo == null) @@ -456,7 +457,7 @@ public override void Execute(SharedObjects shared) } object toPush = shared.TransferManager.CreateTransfer(resourceInfo, transferTo, transferFrom); - shared.Cpu.PushStack(toPush); + ReturnValue = toPush; } } @@ -466,10 +467,11 @@ public class FunctionTransfer : FunctionBase { public override void Execute(SharedObjects shared) { - var amount = shared.Cpu.PopValue(); - var transferTo = shared.Cpu.PopValue(); - var transferFrom = shared.Cpu.PopValue(); - var resourceName = shared.Cpu.PopValue().ToString(); + var amount = PopValueAssert(shared); + var transferTo = PopValueAssert(shared); + var transferFrom = PopValueAssert(shared); + var resourceName = PopValueAssert(shared).ToString(); + AssertArgBottomAndConsume(shared); var resourceInfo = TransferManager.ParseResource(resourceName); if (resourceInfo == null) @@ -482,7 +484,7 @@ public override void Execute(SharedObjects shared) if (Double.TryParse(amount.ToString(), out parsedAmount)) { object toPush = shared.TransferManager.CreateTransfer(resourceInfo, transferTo, transferFrom, parsedAmount); - shared.Cpu.PushStack(toPush); + ReturnValue = toPush; } } } From 79d3d2e3ebe96a20bceecadeea603a65b840c1a6 Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Fri, 17 Apr 2015 14:32:57 -0500 Subject: [PATCH 414/446] coerced some more degrees into reasonable range. Latitude can still be wonky and record things on the wrong side of the world i.e. report 60 north as instead 120 north from a longitude on the other side of the world, with a latitude so big that it is wrapping up and over the north pole to the other side. That's a nontrivial fix so it's still being left that way so at least kOS won't report false data - just ... report true data in a stupid way like the main game does. --- src/kOS/Suffixed/GeoCoordinates.cs | 54 +++++++++++++++++++++--------- src/kOS/Suffixed/Orbitable.cs | 2 +- src/kOS/Suffixed/VesselTarget.cs | 2 +- src/kOS/Utilities/VesselUtils.cs | 2 +- 4 files changed, 41 insertions(+), 19 deletions(-) diff --git a/src/kOS/Suffixed/GeoCoordinates.cs b/src/kOS/Suffixed/GeoCoordinates.cs index 1b0c9afa2..84bb3e36a 100644 --- a/src/kOS/Suffixed/GeoCoordinates.cs +++ b/src/kOS/Suffixed/GeoCoordinates.cs @@ -7,8 +7,30 @@ namespace kOS.Suffixed { public class GeoCoordinates : Structure { - public double Lat { get; private set; } - public double Lng { get; private set; } + private double lat; + private double lng; + public double Lat + { + get + { + return Utils.DegreeFix(lat,-180); + } + private set + { + lat = value; + } + } + public double Lng + { + get + { + return Utils.DegreeFix(lng,-180); + } + private set + { + lng = value; + } + } public CelestialBody Body { get; private set; } public SharedObjects Shared { get; set; } // for finding the current CPU's vessel, as per issue #107 @@ -36,12 +58,12 @@ public GeoCoordinates(Orbitable orb, SharedObjects sharedObj) /// /// A different celestial body to select a lat/long for that might not be the curent one /// to know the current CPU's running vessel - /// latitude - /// longitude - public GeoCoordinates(CelestialBody body, SharedObjects sharedObj, double lat, double lng) + /// latitude + /// longitude + public GeoCoordinates(CelestialBody body, SharedObjects sharedObj, double latitude, double longitude) { - Lat = lat; - Lng = lng; + Lat = latitude; + Lng = longitude; Shared = sharedObj; Body = body; GeoCoordsInitializeSuffixes(); @@ -51,10 +73,10 @@ public GeoCoordinates(CelestialBody body, SharedObjects sharedObj, double lat, d /// Build a GeoCoordinates from any arbitrary lat/long pair of floats. /// /// to know the current CPU's running vessel - /// latitude - /// longitude - public GeoCoordinates(SharedObjects sharedObj, float lat, float lng) : - this(sharedObj.Vessel.GetOrbit().referenceBody, sharedObj, lat, lng) + /// latitude + /// longitude + public GeoCoordinates(SharedObjects sharedObj, float latitude, float longitude) : + this(sharedObj.Vessel.GetOrbit().referenceBody, sharedObj, latitude, longitude) { } @@ -62,12 +84,12 @@ public GeoCoordinates(SharedObjects sharedObj, float lat, float lng) : /// Build a GeoCoordinates from any arbitrary lat/long pair of doubles. /// /// to know the current CPU's running vessel - /// latitude - /// longitude - public GeoCoordinates(SharedObjects sharedObj, double lat, double lng) + /// latitude + /// longitude + public GeoCoordinates(SharedObjects sharedObj, double latitude, double longitude) { - Lat = lat; - Lng = lng; + Lat = latitude; + Lng = longitude; Shared = sharedObj; Body = Shared.Vessel.GetOrbit().referenceBody; GeoCoordsInitializeSuffixes(); diff --git a/src/kOS/Suffixed/Orbitable.cs b/src/kOS/Suffixed/Orbitable.cs index c39a4dd6d..213024019 100644 --- a/src/kOS/Suffixed/Orbitable.cs +++ b/src/kOS/Suffixed/Orbitable.cs @@ -187,7 +187,7 @@ public double PositionToLatitude( Vector pos ) if (parent == null) //happens when this Orbitable is the Sun return 0.0; Vector3d unityWorldPos = GetPosition() + (Vector3d)Shared.Vessel.findWorldCenterOfMass(); - return parent.GetLatitude(unityWorldPos); + return Utils.DegreeFix(parent.GetLatitude(unityWorldPos),-180); } public double PositionToLongitude( Vector pos ) { diff --git a/src/kOS/Suffixed/VesselTarget.cs b/src/kOS/Suffixed/VesselTarget.cs index b1c37b3d0..01fdf6330 100644 --- a/src/kOS/Suffixed/VesselTarget.cs +++ b/src/kOS/Suffixed/VesselTarget.cs @@ -427,7 +427,7 @@ private void InitializeSuffixes() //// Although there is an implementation of lat/long/alt in Orbitible, //// it's better to use the methods for vessels that are faster if they're //// available: - AddSuffix("LATITUDE", new Suffix(() => VesselUtils.GetVesselLattitude(Vessel))); + AddSuffix("LATITUDE", new Suffix(() => VesselUtils.GetVesselLatitude(Vessel))); AddSuffix("LONGITUDE", new Suffix(() => VesselUtils.GetVesselLongitude(Vessel))); AddSuffix("ALTITUDE", new Suffix(() => Vessel.altitude)); } diff --git a/src/kOS/Utilities/VesselUtils.cs b/src/kOS/Utilities/VesselUtils.cs index ae69813ed..81b9acb53 100644 --- a/src/kOS/Utilities/VesselUtils.cs +++ b/src/kOS/Utilities/VesselUtils.cs @@ -365,7 +365,7 @@ public static double GetTerminalVelocity(Vessel vessel) vessel.GetTotalMass() / (GetMassDrag(vessel) * FlightGlobals.DragMultiplier * densityOfAir)); } - public static float GetVesselLattitude(Vessel vessel) + public static float GetVesselLatitude(Vessel vessel) { var retVal = (float)vessel.latitude; From 82c8a2911396c18399fbbf43bef2b88d440f28c4 Mon Sep 17 00:00:00 2001 From: Chris Woerz Date: Fri, 17 Apr 2015 14:00:08 -0600 Subject: [PATCH 415/446] review changes --- src/kOS/Suffixed/GeoCoordinates.cs | 38 +++++++++++++++--------------- src/kOS/Suffixed/VesselTarget.cs | 2 +- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/kOS/Suffixed/GeoCoordinates.cs b/src/kOS/Suffixed/GeoCoordinates.cs index 84bb3e36a..d2e5edfb8 100644 --- a/src/kOS/Suffixed/GeoCoordinates.cs +++ b/src/kOS/Suffixed/GeoCoordinates.cs @@ -9,7 +9,7 @@ public class GeoCoordinates : Structure { private double lat; private double lng; - public double Lat + public double Latitude { get { @@ -20,7 +20,7 @@ private set lat = value; } } - public double Lng + public double Longitude { get { @@ -47,8 +47,8 @@ public GeoCoordinates(Orbitable orb, SharedObjects sharedObj) { Shared = sharedObj; Vector p = orb.GetPosition(); - Lat = orb.PositionToLatitude(p); - Lng = orb.PositionToLongitude(p); + Latitude = orb.PositionToLatitude(p); + Longitude = orb.PositionToLongitude(p); Body = orb.GetParentBody(); GeoCoordsInitializeSuffixes(); } @@ -56,14 +56,14 @@ public GeoCoordinates(Orbitable orb, SharedObjects sharedObj) /// /// Build a GeoCoordinates from any arbitrary lat/long pair of floats. /// - /// A different celestial body to select a lat/long for that might not be the curent one + /// A different celestial body to select a lat/long for that might not be the current one /// to know the current CPU's running vessel /// latitude /// longitude public GeoCoordinates(CelestialBody body, SharedObjects sharedObj, double latitude, double longitude) { - Lat = latitude; - Lng = longitude; + Latitude = latitude; + Longitude = longitude; Shared = sharedObj; Body = body; GeoCoordsInitializeSuffixes(); @@ -74,7 +74,7 @@ public GeoCoordinates(CelestialBody body, SharedObjects sharedObj, double latitu /// /// to know the current CPU's running vessel /// latitude - /// longitude + /// longitude public GeoCoordinates(SharedObjects sharedObj, float latitude, float longitude) : this(sharedObj.Vessel.GetOrbit().referenceBody, sharedObj, latitude, longitude) { @@ -88,8 +88,8 @@ public GeoCoordinates(SharedObjects sharedObj, float latitude, float longitude) /// longitude public GeoCoordinates(SharedObjects sharedObj, double latitude, double longitude) { - Lat = latitude; - Lng = longitude; + Latitude = latitude; + Longitude = longitude; Shared = sharedObj; Body = Shared.Vessel.GetOrbit().referenceBody; GeoCoordsInitializeSuffixes(); @@ -138,8 +138,8 @@ public double GetTerrainAltitude() // Using that reference frame, you tell GetSurfaceHeight what the "up" vector is pointing through // the spot on the surface you're querying for. var bodyUpVector = new Vector3d(1,0,0); - bodyUpVector = QuaternionD.AngleAxis(Lat, Vector3d.forward/*around Z axis*/) * bodyUpVector; - bodyUpVector = QuaternionD.AngleAxis(Lng, Vector3d.down/*around -Y axis*/) * bodyUpVector; + bodyUpVector = QuaternionD.AngleAxis(Latitude, Vector3d.forward/*around Z axis*/) * bodyUpVector; + bodyUpVector = QuaternionD.AngleAxis(Longitude, Vector3d.down/*around -Y axis*/) * bodyUpVector; alt = bodyPQS.GetSurfaceHeight( bodyUpVector ) - bodyPQS.radius ; @@ -148,9 +148,9 @@ public double GetTerrainAltitude() const double HIGH_AGL = 1000.0; const double POINT_AGL = 800.0; // a point hopefully above the terrain: - Vector3d worldRayCastStart = Body.GetWorldSurfacePosition( Lat, Lng, alt+HIGH_AGL ); + Vector3d worldRayCastStart = Body.GetWorldSurfacePosition( Latitude, Longitude, alt+HIGH_AGL ); // a point a bit below it, to aim down to the terrain: - Vector3d worldRayCastStop = Body.GetWorldSurfacePosition( Lat, Lng, alt+POINT_AGL ); + Vector3d worldRayCastStop = Body.GetWorldSurfacePosition( Latitude, Longitude, alt+POINT_AGL ); RaycastHit hit; if (Physics.Raycast(worldRayCastStart, (worldRayCastStop - worldRayCastStart), out hit, float.MaxValue, 1<position vector public Vector GetAltitudePosition(double altitude) { - Vector3d latLongCoords = Body.GetWorldSurfacePosition(Lat, Lng, altitude); + Vector3d latLongCoords = Body.GetWorldSurfacePosition(Latitude, Longitude, altitude); Vector3d hereCoords = Shared.Vessel.findWorldCenterOfMass(); return new Vector(latLongCoords - hereCoords); } private void GeoCoordsInitializeSuffixes() { - AddSuffix("LAT", new Suffix(()=> Lat)); - AddSuffix("LNG", new Suffix(()=> Lng)); + AddSuffix("LAT", new Suffix(()=> Latitude)); + AddSuffix("LNG", new Suffix(()=> Longitude)); AddSuffix("BODY", new Suffix(()=> new BodyTarget(Body, Shared))); AddSuffix("TERRAINHEIGHT", new Suffix(GetTerrainAltitude)); AddSuffix("DISTANCE", new Suffix(GetDistanceFrom)); @@ -237,7 +237,7 @@ private void GeoCoordsInitializeSuffixes() public override string ToString() { - return "LATLNG(" + Lat + ", " + Lng + ")"; + return "LATLNG(" + Latitude + ", " + Longitude + ")"; } } } diff --git a/src/kOS/Suffixed/VesselTarget.cs b/src/kOS/Suffixed/VesselTarget.cs index 01fdf6330..4013900b9 100644 --- a/src/kOS/Suffixed/VesselTarget.cs +++ b/src/kOS/Suffixed/VesselTarget.cs @@ -453,7 +453,7 @@ private void RenameVessel(string value) /// weird exception for this one case. This transforms it back into raw universe /// axes again: /// - /// the value KSP is returning for angular velocity + /// the value KSP is returning for angular velocity /// altered velocity in the new reference frame private Vector RawAngularVelFromRelative(Vector3 angularVelFromKSP) { From 81dba08ae2662e3b561974fb6e23b6aac5b05800 Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Fri, 17 Apr 2015 16:28:33 -0500 Subject: [PATCH 416/446] Adds LIST() initializer --- doc/source/changes.rst | 8 ++++++ doc/source/language/variables.rst | 5 +--- doc/source/structures/misc/iterator.rst | 5 +--- doc/source/structures/misc/list.rst | 26 +++++++++++++++++++ kerboscript_tests/list/testlist.ks | 25 ++++++++++++++++++ .../user_functions/functest24.ks | 15 +++++++++++ src/kOS/Function/Suffixed.cs | 5 +++- 7 files changed, 80 insertions(+), 9 deletions(-) create mode 100644 kerboscript_tests/list/testlist.ks create mode 100644 kerboscript_tests/user_functions/functest24.ks diff --git a/doc/source/changes.rst b/doc/source/changes.rst index 1ac020e72..61564b500 100644 --- a/doc/source/changes.rst +++ b/doc/source/changes.rst @@ -27,5 +27,13 @@ penalizing the users of faster computers anymore. (Previously, if your computer was faster, you'd be charged more electricity as the updates came more often). +LIST constructor can now initialize lists +::::::::::::::::::::::::::::::::::::::::: +You can now do this:: + set mylist to list(2,6,1,6,21). + +to initialize a :ref:`list of values ` from the start, so +you no longer have to have a long list of list:ADD commands to +populate it. diff --git a/doc/source/language/variables.rst b/doc/source/language/variables.rst index 8a46e470f..6210ad1f0 100644 --- a/doc/source/language/variables.rst +++ b/doc/source/language/variables.rst @@ -526,10 +526,7 @@ Examples:: RETURN sum / inputList:LENGTH. }. - SET testList TO LIST(); - testList:ADD(5). - testList:ADD(10). - testList:ADD(15). + SET testList TO LIST(5,10,15); print "average is " + calcAverage(testList). print "but out here where it's global, sum is still " + sum. diff --git a/doc/source/structures/misc/iterator.rst b/doc/source/structures/misc/iterator.rst index 5a24c036c..de000c0c2 100644 --- a/doc/source/structures/misc/iterator.rst +++ b/doc/source/structures/misc/iterator.rst @@ -8,10 +8,7 @@ An iterator can be obtained from :attr:`List:ITERATOR`. Once a :struct:`List` ha A loop using an :struct:`Iterator` on a :struct:`List` might look like this:: // Starting with a list that was built like this - SET MyList To LIST(). - MyList:ADD( "Hello" ). - MyList:ADD( "Aloha" ). - MyList:ADD( "Bonjour" ). + SET MyList To LIST( "Hello", "Aloha", "Bonjour"). // It could be looped over like this SET MyCurrent TO MyList:ITERATOR. diff --git a/doc/source/structures/misc/list.rst b/doc/source/structures/misc/list.rst index 9ffb836b8..f184cd791 100644 --- a/doc/source/structures/misc/list.rst +++ b/doc/source/structures/misc/list.rst @@ -5,6 +5,31 @@ List A :struct:`List` is a collection of any type in kOS. Many places throughout the system return variables of the :struct:`List` type, and you can create your own :struct:`List` variables as well. One of the places you are likely to find that kOS gives you a :struct:`List` is when you use the :ref:`LIST command ` to list some query into one of your variables. +Constructing a list +------------------- + +Numerous built-in functions in kOS return a list. If you wish +to make your own list from scratch you can do so with the +LIST() built-in function. You pass a varying number of arguments +into it to pre-populate the list with an initial list of items: + + // Make an empty list with zero items in it: + set mylist to list(). + + // Make a list with 3 numbers in it: + set mylist to list(10,20,30). + + // Make a list with 3 strings in it: + set mylist to list("10","20","30"). + + // Make a two dimensional 2x3 list with heterogenious contents + // mixing strings and numbers: + set mylist to list( list("a","b","c"), list(1,2,3) ). + +The contents of a list can be any objects you feel like, and do not +need to be of a homogeneous type. + + Structure --------- @@ -145,6 +170,7 @@ All list indexes start counting at zero. (The list elements are numbered from 0 Examples:: + SET BAR TO LIST(5,3,6). // Creates a new list with 3 integers in it. SET FOO TO LIST(). // Creates a new empty list in FOO variable FOO:ADD(5). // Adds a new element to the end of the list FOO:ADD( ALTITUDE ). // Adds current altitude number to the end of the list diff --git a/kerboscript_tests/list/testlist.ks b/kerboscript_tests/list/testlist.ks new file mode 100644 index 000000000..366acf76a --- /dev/null +++ b/kerboscript_tests/list/testlist.ks @@ -0,0 +1,25 @@ +// Test the list constructor. + +local l1 is list(). +local l2 is list(5,10,15,20). +// 2-d test: +local m1 is list( list(10,20,30,40), list(15,25,35,45), list(11,22,33,44) ). + +print "----------------------". +print "list l1 is: (should be empty)". +for item in l1 { print item + " " . }. + +print "----------------------". +print "list l2 is: (should be 4 things)". +for item in l2 { print item + " " . }. + +print "----------------------". +print "2-D list m1 is:". +for row in m1 { + local str is "(". + for item in row { + set str to str + item + " ". + }. + set str to str + ") ". + print str. +}. diff --git a/kerboscript_tests/user_functions/functest24.ks b/kerboscript_tests/user_functions/functest24.ks new file mode 100644 index 000000000..93d30abbb --- /dev/null +++ b/kerboscript_tests/user_functions/functest24.ks @@ -0,0 +1,15 @@ +// Testing calling a built-in function from inside a double-nested fucntion. + +function outer_clamp { + function inner_clamp{ + parameter x. + parameter minval. + parameter maxval. + + return max( min( x, maxval), minval). + }. + print "clamp of 10 to rage 4,9 is ". + print inner_clamp(10,4,9). +}. + +outer_clamp(). diff --git a/src/kOS/Function/Suffixed.cs b/src/kOS/Function/Suffixed.cs index c74698ba9..753b2b8d4 100644 --- a/src/kOS/Function/Suffixed.cs +++ b/src/kOS/Function/Suffixed.cs @@ -188,8 +188,11 @@ public class FunctionList : FunctionBase { public override void Execute(SharedObjects shared) { + object[] argArray = new object[CountRemainingArgs(shared)]; + for (int i = argArray.Length - 1 ; i >= 0 ; --i) + argArray[i] = PopValueAssert(shared); // fill array in reverse order because .. stack args. AssertArgBottomAndConsume(shared); - var listValue = new ListValue(); + var listValue = new ListValue(argArray.ToList()); ReturnValue = listValue; } } From 152e0342c576470faafefec27aa423795552a644 Mon Sep 17 00:00:00 2001 From: abenkovskii Date: Sat, 18 Apr 2015 01:52:56 +0300 Subject: [PATCH 417/446] Fixed documentation for MOD function --- doc/source/math/basic.rst | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/doc/source/math/basic.rst b/doc/source/math/basic.rst index 35a13a902..73c079ca0 100644 --- a/doc/source/math/basic.rst +++ b/doc/source/math/basic.rst @@ -96,9 +96,11 @@ Mathematical Functions .. function:: MOD(a,b) - Returns remainder from integer division:: + Returns remainder from integer division. + Keep in mind that it's not a traditional mathematical Euclidean division where the result is always positive. The result has the same absolute value as mathematical modulo operation but the sign is the same as the sign of dividend:: PRINT MOD(21,6). // prints 3 + PRINT MOD(-21,6). // prints -3 .. function:: MIN(a,b) @@ -113,11 +115,11 @@ Mathematical Functions PRINT MAX(0,100). // prints 100 .. function:: RANDOM() - + Returns a random floating point number in the range [0,1]:: - + PRINT RANDOM(). //prints a random number - + .. function:: ROUND(a) Rounds to the nearest whole number:: @@ -220,4 +222,3 @@ Trigonometric Functions PRINT ARCTAN2(0.67, 0.89). // prints 36.9727625 The two parameters resolve ambiguities when taking the arctangent. See the `wikipedia page about atan2 `_ for more details. - From 8145a9c712a0455aef750c8c8913ff090b673bd2 Mon Sep 17 00:00:00 2001 From: hvacengi Date: Fri, 17 Apr 2015 20:03:08 -0400 Subject: [PATCH 418/446] Add RemoteTech warning --- doc/source/commands/flight/systems.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/source/commands/flight/systems.rst b/doc/source/commands/flight/systems.rst index e22d72b93..298f615a3 100644 --- a/doc/source/commands/flight/systems.rst +++ b/doc/source/commands/flight/systems.rst @@ -34,6 +34,10 @@ Ship Systems SET SASMODE TO value. It is the equivalent to clicking on the buttons next to the nav ball while manually piloting the craft, and will respect the current mode of the nav ball (orbital, surface, or target velocity). Valid strings for ``value`` are ``"PROGRADE"``, ``"RETROGRADE"``, ``"NORMAL"``, ``"ANTINORMAL"``, ``"RADIALOUT"``, ``"RADIALIN"``, ``"TARGET"``, ``"ANTITARGET"``, ``MANEUVER``, ``"STABILITYASSIST"``, and ``"STABILITY"``. A null or empty string will default to stability assist mode, however any other invalid string will throw an exception. This feature will respect career mode limitations, and will throw an exception if the current vessel is not able to use the mode passed to the command. An exception is also thrown if ``"TARGET"`` or ``"ANTITARGET"`` are used, but no target is selected. + +.. warning:: SASMODE does not work with RemoteTech + + Due to the way that RemoteTech disables flight control input, the built in SAS modes do not function properly when there is no connection to the KSC or a Command Center. If you are writing scripts for use with RemoteTech, make sure to take this into account. .. global:: LIGHTS From 137a26c134a028d5c4f0fbb3345227c4e8bfaa40 Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Fri, 17 Apr 2015 20:03:46 -0500 Subject: [PATCH 419/446] Hopefully the final edit to the changelog? --- CHANGELOG.md | 155 +++++++++++++++++++---------------------- doc/source/changes.rst | 6 ++ 2 files changed, 76 insertions(+), 85 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 993d6da33..ee409c495 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,105 +21,90 @@ script. For the features mentioned below, you can go to the page above and get a more verbose description of the new features. +###New Features: + +A brief list of what's new: + +* Variables can now be local +* Kerboscript has User Functions +* Community Examples Library +* LIST() now takes args to initialize the list. +* Physics Ticks not Update Ticks +* Ability to use SAS modes from KSP 0.90 +* Blizzy ToolBar Support +* Ability to define colors using HSV +* Ability to highlight a part in color +* Better user interface for selecting boot scripts +* Disks can be made bigger with tweakable slider +* You Can Transfer Resources +* Kerbal Alarm Clock support +* Query the docked elements of a vessel +* Support for Action Groups Extended +* ISDEAD suffix for Vessel + +This update is so full of new features that instead of describing all of their +details here, you can go see them on the main docs page at the following link: + +http://ksp-kos.github.io/KOS_DOC/changes.html + +###Bug Fixes: + +- Using the same FOR iterator in two loops no longer name clashes because it's not global anymore. +- Repaired a number of boot file selection bugs. +- Removed a few unnecessary debug log spamming message. +- Fixed a minor issue with the special hidden file .DS_Store that Macs insert into the Scripts folder. +- Fixed bug spamming nullrefs when panel was open in the VAB/SPH editor. +- Fixed bugs where setting warp could crash KSP. Now it clamps warp to valid values. +- Fixed bug where kOS CPU's were drawing power from the batteries even when the game was paused. +- Fixed bug where rate of power consumption varied depending on animation frame rate. +- Fixed bug where WAIT 0 crashed scripts. Now WAIT 0 waits the min. possible time (1 physics tick). +- Fixed small order of operations problem with expressions containing unary operators like '-', '+', and 'not'. +- Fixed problem where SET TARGET didn't really set it until the next physics tick. Now it sets immediately. +- Fixed some issues with the use of Action Groups above 10, when Action Groups Extended is installed. +- Fixed bug where VOLUME:RENAMABLE returned the name string, rather than a boolean. +- Fixed bun when printing a VOLUME to the screen and failing to "stringify" it properly. +- Using the unary negation '-' on vectors and directions now works. +- Fixed some major bugs in how the kOS toolbar panel was dealing with scene changes and getting "stuck" on screen. +- Fixed some bugs with the kos Name Tag typing window getting stuck on screen and locking the user out of the UI. +- Fixed bug with reboot not clearing out the state properly. +- Fixed bug where any syntax error caught by the compiler resulted in bogus additional second error message. + ###BREAKING: -- **RECOMPILE YOUR KSM FILES!!!** - changes to the kOS machine code - that were needed to support variable scoping ended up invalidating - any existing compiled KSM files. You should be able to just - perform one compile and then use the new KSM file. If you don't do - this, you will get the error message: - ```The given key was not present in the dictionary.``` + +- **RECOMPILE YOUR KSM FILES!!!** - If you used the COMPILE command in + the past, changes to the kOS machine code that were needed to support + variable scoping ended up invalidating any existing compiled KSM files. + - **KSM FILES ARE BIGGER** - compiled KSM files are now larger than - they used to be, due to extra code generated for dealing with - variable scoping and more universal function calling techniques. - Compiling to a KSM file will probably no longer be a reliable way - to make your code smaller, but we also intend to increase the volume - capacity to compensate. -- *CONFIG:IPU should probably be slightly increased* - There's a few more instructions for some of the same amount of source - code, so you might need to increase your CONFIG:IPU to get the same - programs to continue working. Although the default setting for 0.17.0 - is higher, it will not overwrite your settings if you have a config file - already present from earlier installations. + they used to be for the same source code. They might not be an + efficient way to pack your code down to a small disk footprint + anymore. + +- *CONFIG:IPU should be slightly increased* The new default + we ship with is 200, to reflect both the change in ML code, and the + movement to Unity's FixedUpdate for physics ticks. However if you + have played kOS in the past, your settings don't get automatically + overwritten. You will need to change the setting manually. + - *DECLARE has a new syntax* DECLARE _VARNAME_ now requires an initializer syntax as follows: - DECLARE _VARNAME_ TO _VALUE_. If you leave the TO _VALUE_ off, it will now be a syntax error. - The Kerboscript language used to leave it unspecified what the value - of a variable that has been declared but not set was. This gets rid - of that ambiguity. + Also, you can say LOCAL or GLOBAL instead of, or in addition to, + the word DECLARE. + - *DECLAREd variables are now local* Using the DECLARE _VARNAME_ TO _VALUE_ statement now causes the variable to have local scope that only exists within the local block - of curly braces ('{'...'}') that it was declared inside of. Once you - leave that block of braces, the variable doesn't exist anymore. + of curly braces ('{'...'}') that it was declared inside of. To get + the old behavior you can explicitly say: + DECLARE GLOBAL _VARNAME_ to _VALUE. + - *FOR iterator now is local* The _VARIABLE_ in loops of the form FOR _VARIABLE_ IN _SOMELIST_ now has local scope to just that loop, meaning it stops existing after the loop is done and you can't use it outside the loop's body. - In the past you could try using it after the loop body, but this - was poor practice and was only allowed because we didn't have - variable scoping set up right. -###New Features: -- *FUNCTIONS* - It's been a long time coming, but finally the addition - of the new DECLARE FUNCTION statement now allows you to make your - own user functions you can call, which you can use to help build - your own library of common routines. - Synopsis:: - - // Silly example function to build a string of padded chars. - FUNCTION padString { - PARAMETER ch, howmany - - LOCAL str to "". // makes str a local variable. - - UNTIL howmany <= 0 { - set str to str + ch. - set howmany to howmany - 1. - } - RETURN str. - } - set twentySpaces to padString(" ", 20). - set threeX to padString("X", 3). - - If you'd like to create a library of utility functions for - yourself, you can make a kerboscript file that contains only - DECLARE FUNCTION statements, and then RUN it from the top of - your other scripts to load in all the functions it contains. - - For the full documentation, see: - http://ksp-kos.github.io/KOS/language/user_functions.html - -- *VARIABLE SCOPING (LOCALS)* - It used to be the case that all variables were global and there was - no such thing as a local variable. As part of getting functions to - work, we also implemented some local scoping rules. - Synopsis:: - - Kerboscript now uses block scoping, local to the brace scope the variable was declared inside of. - Local vars are declared with the DECLARE..TO statement. - Variables made implicitly by "lazy" use of SET will still be global like they always have been. - - The exact means of making a variable local is described here: - http://ksp-kos.github.io/KOS/language/variables.html#declare-to - and here: - http://ksp-kos.github.io/KOS/language/variables.html#scoping-rules - -- *Physics update* - In the past kOS performed its work during the animation frame - updates. Now it does so during the physics updates, as it - should. One effect of this is that if you have a frame rate - of more than 25, then you'll need to increase your CONFIG:IPU - to get the same general amount of code running in the same time. - -###Bug Fixes: -- For iterator no longer name clashes because it's not global anymore. - It used to be that if you had two FOR _VAR_ IN _THING_'s in the same - program, and both used the same name for their _VAR_, they could - interfere and clash in strange ways because they were using the same - global variable. Now the iterator _VAR_ is local to the loop and - no longer exists outside the loop. # v0.16.2 diff --git a/doc/source/changes.rst b/doc/source/changes.rst index 1ac020e72..892cc2044 100644 --- a/doc/source/changes.rst +++ b/doc/source/changes.rst @@ -27,5 +27,11 @@ penalizing the users of faster computers anymore. (Previously, if your computer was faster, you'd be charged more electricity as the updates came more often). +ISDEAD suffix for Vessel +:::::::::::::::::::::::: +Vessels now have an :ISDEAD suffix you can use to detect if the +vessel has gone away since the last time you got the handle to it. +(for example, you LIST TARGETS IN FOO, then the ship foo[3] blows +up, then foo[3]:ISDEAD should become true to clue you in to this fact.) From fe630a9be9780136c22b9a465e6fc30d736d27f3 Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Fri, 17 Apr 2015 20:05:18 -0500 Subject: [PATCH 420/446] Markdown formatting fix --- CHANGELOG.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ee409c495..7281833eb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,14 +12,14 @@ script. **New Documentation change page**: - For those users who just want to see what new features - exist without reading the entire documentation again - from scratch, we have created a changes page in the main documentation: +For those users who just want to see what new features +exist without reading the entire documentation again +from scratch, we have created a changes page in the main documentation: - * New Changes Page: http://ksp-kos.github.io/KOS_DOC/changes.html +* New Changes Page: http://ksp-kos.github.io/KOS_DOC/changes.html - For the features mentioned below, you can go to the page above - and get a more verbose description of the new features. +For the features mentioned below, you can go to the page above +and get a more verbose description of the new features. ###New Features: From 7e15efbdf9421842f1047164ebeb005b3ee2dabb Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Fri, 17 Apr 2015 23:33:50 -0500 Subject: [PATCH 421/446] added link to the exenode script --- doc/source/tutorials.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/doc/source/tutorials.rst b/doc/source/tutorials.rst index eb8fa269e..7e96af522 100644 --- a/doc/source/tutorials.rst +++ b/doc/source/tutorials.rst @@ -26,3 +26,6 @@ Intermediate :doc:`PID Loop Tutorial ` Starts with a basic proportional feedback loop and develops, in stages, a complete PID-loop to control the throttle of a simple rocket design. + +:doc:`Execute Node script ` + Describes a generic "execute manuever node" script to be a one-size-fits-all solution to many situations in KSP. If you can make a manuever node for something, exenode will execute it. From a995ca152ff9edaa63719214c4e3a0898c27929a Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Fri, 17 Apr 2015 23:35:17 -0500 Subject: [PATCH 422/446] added ziwkerman attribution --- doc/source/tutorials.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/source/tutorials.rst b/doc/source/tutorials.rst index 7e96af522..37351347f 100644 --- a/doc/source/tutorials.rst +++ b/doc/source/tutorials.rst @@ -11,6 +11,7 @@ If you prefer the tutorial style of explanation, please see the following exampl Quick Start Design Patterns PID Loops + Execute Node script Introductory ------------ @@ -28,4 +29,4 @@ Intermediate Starts with a basic proportional feedback loop and develops, in stages, a complete PID-loop to control the throttle of a simple rocket design. :doc:`Execute Node script ` - Describes a generic "execute manuever node" script to be a one-size-fits-all solution to many situations in KSP. If you can make a manuever node for something, exenode will execute it. + ZiwKerman describes a generic "execute manuever node" script to be a one-size-fits-all solution to many situations in KSP. If you can make a manuever node for something, exenode will execute it. From bb5fea365670c11e17e0f3030dc2a19aee1b1a81 Mon Sep 17 00:00:00 2001 From: Chris Woerz Date: Sat, 18 Apr 2015 17:12:30 -0600 Subject: [PATCH 423/446] updated docs to 0.17.0 --- doc/source/conf.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/source/conf.py b/doc/source/conf.py index 9c3c8b544..888bc4a8e 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -57,9 +57,9 @@ # built documents. # # The short X.Y version. -version = '0.16.2' +version = '0.17' # The full version, including alpha/beta/rc tags. -release = '0.16.2' +release = '0.17.0' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. From 83de62bd23b9865a7c7f51767933d01505da2159 Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Sun, 19 Apr 2015 15:19:12 -0500 Subject: [PATCH 424/446] Resolves some docs issues just after 0_17_0 release. --- doc/source/language/user_functions.rst | 6 +++--- doc/source/language/variables.rst | 11 +++++++---- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/doc/source/language/user_functions.rst b/doc/source/language/user_functions.rst index f0153f58e..c1a33130b 100644 --- a/doc/source/language/user_functions.rst +++ b/doc/source/language/user_functions.rst @@ -169,9 +169,9 @@ binding. Syntax: - ``DECLARE`` *identifier* ``TO`` *expression* *dot* - ``LOCAL`` *identifier* ``IS`` *expression* *dot* - ``DECLARE LOCAL`` *identifier* ``IS`` *expression* *dot* +* ``DECLARE`` *identifier* ``TO`` *expression* *dot* +* ``LOCAL`` *identifier* ``IS`` *expression* *dot* +* ``DECLARE LOCAL`` *identifier* ``IS`` *expression* *dot* The above are all the same, although the version that just says ``LOCAL identifier IS expr.`` is preferred. diff --git a/doc/source/language/variables.rst b/doc/source/language/variables.rst index 4e87e63e6..dcd823f14 100644 --- a/doc/source/language/variables.rst +++ b/doc/source/language/variables.rst @@ -305,7 +305,7 @@ Local lock You can explicitly make a ``LOCK`` statement be LOCAL with the ``LOCAL`` keyword, like so: -``LOCK LOCAL`` identifier ``TO`` expression. +``LOCAL LOCK`` identifier ``TO`` expression. But be aware that doing so with a cooked steering control such as THROTTLE or STEERING will not actually affect your ship. The @@ -388,8 +388,8 @@ Scoping terms .. note:: .. versionadded:: 0.17 In prior versions of kerboscript, all identifiers other than - DECLARE PARAMETER identifiers were always global variables no - matter what, even if you used the DECLARE statement to make them. + DECLARE PARAMETER identifiers were always global variables no + matter what, even if you used the DECLARE statement to make them. What is Scope? The term *Scope* simply refers to asking the question "where in the @@ -617,7 +617,7 @@ force yourself to be clear and explicit about the difference. For example, this program, which is valid:: function foo {print "foo ". } - local x is 1. + declare x is 1. print foo() + x. @@ -634,6 +634,9 @@ Which you fix by explicitly stating the local keyword, as follows:: @LAZYGLOBAL OFF. function foo {print "foo ". } // This does not need the 'local' keyword added declare local x is 1. // But this does because it is a declare *identifier* statement. + // you could have also just said: + // local x is 1. + // without the 'declare' keyword. print foo() + x. From 0acf920161b7bd8349144564f2c04c87e49b3960 Mon Sep 17 00:00:00 2001 From: ZiwKerman Date: Mon, 20 Apr 2015 10:58:46 +0100 Subject: [PATCH 425/446] Fixed bug with setting KAC Alarm action to correct value The Enum in the KACWrapper was outdated leading to incorrect parsing of values received via API. Posted an issue on KAC github too --- src/kOS/AddOns/KerbalAlarmClock/KACAlarmWrapper.cs | 9 ++++++++- src/kOS/AddOns/KerbalAlarmClock/KACWrapper.cs | 5 +++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/kOS/AddOns/KerbalAlarmClock/KACAlarmWrapper.cs b/src/kOS/AddOns/KerbalAlarmClock/KACAlarmWrapper.cs index f336abc43..d192ed256 100644 --- a/src/kOS/AddOns/KerbalAlarmClock/KACAlarmWrapper.cs +++ b/src/kOS/AddOns/KerbalAlarmClock/KACAlarmWrapper.cs @@ -29,7 +29,7 @@ private void InitializeSuffixes() AddSuffix("NOTES", new SetSuffix(() => alarm.Name, value => alarm.Name = value)); - AddSuffix("ACTION", new SetSuffix(alarm.AlarmAction.ToString, SetAlarmAction)); + AddSuffix("ACTION", new SetSuffix(GetAlarmAction, SetAlarmAction)); AddSuffix("TYPE", new Suffix(alarm.AlarmType.ToString)); @@ -53,6 +53,13 @@ private double GetRemaining() return alarm.AlarmTime - Planetarium.GetUniversalTime(); } + private string GetAlarmAction() + { + //For some reason had to do it this way, otherwise ACTION suffix returned incorrect values + //SafeHouse.Logger.Log(string.Format("Actual AlarmAction eq = {0} ", alarm.AlarmAction)); + return alarm.AlarmAction.ToString(); + } + private void SetAlarmAction(string newAlarmAction) { try diff --git a/src/kOS/AddOns/KerbalAlarmClock/KACWrapper.cs b/src/kOS/AddOns/KerbalAlarmClock/KACWrapper.cs index 84a9f81ce..dad3f82fd 100644 --- a/src/kOS/AddOns/KerbalAlarmClock/KACWrapper.cs +++ b/src/kOS/AddOns/KerbalAlarmClock/KACWrapper.cs @@ -560,11 +560,12 @@ public enum AlarmTypeEnum public enum AlarmActionEnum { - + [Description("Do Nothing-Delete When Past")] DoNothingDeleteWhenPassed, + [Description("Do Nothing")] DoNothing, [Description("Message Only-No Affect on warp")] MessageOnly, [Description("Kill Warp Only-No Message")] KillWarpOnly, [Description("Kill Warp and Message")] KillWarp, - [Description("Pause Game and Message")] PauseGame + [Description("Pause Game and Message")] PauseGame, } public enum TimeEntryPrecisionEnum From fc0389105e2bc5b2be613545cfab53dead94001d Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Mon, 20 Apr 2015 08:37:15 -0500 Subject: [PATCH 426/446] removed the print message from GetPosition --- src/kOS/Suffixed/Orbitable.cs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/kOS/Suffixed/Orbitable.cs b/src/kOS/Suffixed/Orbitable.cs index 213024019..f4d04d8d2 100644 --- a/src/kOS/Suffixed/Orbitable.cs +++ b/src/kOS/Suffixed/Orbitable.cs @@ -219,11 +219,7 @@ private void InitializeSuffixes() AddSuffix("SRFPROGRADE", new Suffix(GetSurfacePrograde)); AddSuffix("SRFRETROGRADE", new Suffix(GetSurfaceRetrograde)); AddSuffix("OBT", new Suffix(GetOrbitInfo)); - AddSuffix("POSITION", new Suffix(() => - { - SafeHouse.Logger.Log("Position got Called"); - return GetPosition(); - })); + AddSuffix("POSITION", new Suffix(GetPosition)); AddSuffix("VELOCITY", new Suffix(GetVelocities)); AddSuffix("DISTANCE", new Suffix(GetDistance)); AddSuffix("DIRECTION", new Suffix(() => new Direction(GetPosition(), false))); From aa1ac77af5e80e1d5b5a7867bf52a6c8ac34b96a Mon Sep 17 00:00:00 2001 From: Chris Woerz Date: Mon, 20 Apr 2015 12:01:06 -0600 Subject: [PATCH 427/446] review changes --- src/kOS/AddOns/KerbalAlarmClock/KACAlarmWrapper.cs | 6 ++---- src/kOS/AddOns/KerbalAlarmClock/KACWrapper.cs | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/kOS/AddOns/KerbalAlarmClock/KACAlarmWrapper.cs b/src/kOS/AddOns/KerbalAlarmClock/KACAlarmWrapper.cs index d192ed256..6ea2fb82a 100644 --- a/src/kOS/AddOns/KerbalAlarmClock/KACAlarmWrapper.cs +++ b/src/kOS/AddOns/KerbalAlarmClock/KACAlarmWrapper.cs @@ -33,7 +33,7 @@ private void InitializeSuffixes() AddSuffix("TYPE", new Suffix(alarm.AlarmType.ToString)); - AddSuffix("REMAINING", new Suffix(GetRemaining)); + AddSuffix("REMAINING", new Suffix(GetTimeToAlarm)); AddSuffix("TIME", new SetSuffix(() => alarm.AlarmTime, value => alarm.AlarmTime = value)); AddSuffix("MARGIN", new SetSuffix(() => alarm.AlarmMargin, value => alarm.AlarmMargin = value)); @@ -46,9 +46,8 @@ private void InitializeSuffixes() AddSuffix("TARGETBODY", new SetSuffix(() => alarm.XferTargetBodyName, value => alarm.XferTargetBodyName = value)); } - private double GetRemaining() + private double GetTimeToAlarm() { - /*SafeHouse.Logger.LogWarning (string.Format ("Trying to get remaining time, {0}", alarm.Remaining));*/ //workaround for alarm.Remaining type mismatch return alarm.AlarmTime - Planetarium.GetUniversalTime(); } @@ -56,7 +55,6 @@ private double GetRemaining() private string GetAlarmAction() { //For some reason had to do it this way, otherwise ACTION suffix returned incorrect values - //SafeHouse.Logger.Log(string.Format("Actual AlarmAction eq = {0} ", alarm.AlarmAction)); return alarm.AlarmAction.ToString(); } diff --git a/src/kOS/AddOns/KerbalAlarmClock/KACWrapper.cs b/src/kOS/AddOns/KerbalAlarmClock/KACWrapper.cs index dad3f82fd..08eac9370 100644 --- a/src/kOS/AddOns/KerbalAlarmClock/KACWrapper.cs +++ b/src/kOS/AddOns/KerbalAlarmClock/KACWrapper.cs @@ -170,7 +170,7 @@ internal KACAPI(Object KAC) //DrawTimeEntryMethod = KACType.GetMethod("DrawTimeEntryAPI", BindingFlags.Public | BindingFlags.Instance); //LogFormatted_DebugOnly("Success: " + (DrawTimeEntryMethod != null).ToString()); - //Commenting out rubbish lines + //Commenting out rubbish lines //MethodInfo[] mis = KACType.GetMethods(BindingFlags.Public | BindingFlags.Instance); //foreach (MethodInfo mi in mis) //{ From 23c9f0d19f6d231331d44815c498b198897f575e Mon Sep 17 00:00:00 2001 From: Chris Woerz Date: Mon, 20 Apr 2015 12:34:28 -0600 Subject: [PATCH 428/446] bumped version for 0.17.1 release --- Resources/GameData/kOS/kOS.version | 2 +- doc/source/conf.py | 4 ++-- src/kOS.Safe/Properties/AssemblyInfo.cs | 4 ++-- src/kOS/Core.cs | 2 +- src/kOS/Properties/AssemblyInfo.cs | 4 ++-- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Resources/GameData/kOS/kOS.version b/Resources/GameData/kOS/kOS.version index 9063fc145..4ecb31d59 100644 --- a/Resources/GameData/kOS/kOS.version +++ b/Resources/GameData/kOS/kOS.version @@ -11,7 +11,7 @@ "VERSION": { "MAJOR": 0, "MINOR": 17, - "PATCH": 0 + "PATCH": 1 }, "KSP_VERSION": { "MAJOR": 0, diff --git a/doc/source/conf.py b/doc/source/conf.py index 888bc4a8e..462136ef1 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -57,9 +57,9 @@ # built documents. # # The short X.Y version. -version = '0.17' +version = '0.17.1 ' # The full version, including alpha/beta/rc tags. -release = '0.17.0' +release = '0.17.1' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/src/kOS.Safe/Properties/AssemblyInfo.cs b/src/kOS.Safe/Properties/AssemblyInfo.cs index 779d43b9c..75f496678 100644 --- a/src/kOS.Safe/Properties/AssemblyInfo.cs +++ b/src/kOS.Safe/Properties/AssemblyInfo.cs @@ -31,5 +31,5 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.2.0.0")] -[assembly: AssemblyFileVersion("1.2.0.0")] +[assembly: AssemblyVersion("1.17.1.0")] +[assembly: AssemblyFileVersion("1.17.1.0")] diff --git a/src/kOS/Core.cs b/src/kOS/Core.cs index 681112fec..3f50ef58b 100644 --- a/src/kOS/Core.cs +++ b/src/kOS/Core.cs @@ -5,7 +5,7 @@ namespace kOS { public class Core : MonoBehaviour { - public static VersionInfo VersionInfo = new VersionInfo(0, 17, 0); + public static VersionInfo VersionInfo = new VersionInfo(0, 17, 1); public static Core Fetch; diff --git a/src/kOS/Properties/AssemblyInfo.cs b/src/kOS/Properties/AssemblyInfo.cs index 5eed03dac..36bcd0ee9 100644 --- a/src/kOS/Properties/AssemblyInfo.cs +++ b/src/kOS/Properties/AssemblyInfo.cs @@ -31,6 +31,6 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyFileVersion("0.17.0.0")] -[assembly: AssemblyVersion("0.17.0.0")] +[assembly: AssemblyFileVersion("0.17.1.0")] +[assembly: AssemblyVersion("0.17.1.0")] [assembly: KSPAssembly("kOS", 0, 17)] From 7fda2ce2daacb6d50c9c36d11a06cb16a2089bfe Mon Sep 17 00:00:00 2001 From: Chris Woerz Date: Mon, 20 Apr 2015 12:50:39 -0600 Subject: [PATCH 429/446] updated changelog for release --- CHANGELOG.md | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7281833eb..7f6c64a69 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,23 @@ kOS Mod Changelog ================= + +# v0.17.1 + +Corrections and omissions +----------------------- + +### "New" features + +* Due to erendrake's inability to correctly use git. The new list constructor was omitted from the 0.17.0 release binaries. + +### Bug Fixes: + +* Many Doc fixes +* Fixed bug with setting KAC Alarm action to correct value +* Fixed some unneeded log spamming + + # v0.17.0 FUNCTIONS! FUNCTIONS! FUNCTIONS! @@ -21,7 +38,7 @@ from scratch, we have created a changes page in the main documentation: For the features mentioned below, you can go to the page above and get a more verbose description of the new features. -###New Features: +### New Features: A brief list of what's new: @@ -47,7 +64,7 @@ details here, you can go see them on the main docs page at the following link: http://ksp-kos.github.io/KOS_DOC/changes.html -###Bug Fixes: +### Bug Fixes: - Using the same FOR iterator in two loops no longer name clashes because it's not global anymore. - Repaired a number of boot file selection bugs. From 2aa32cb08c9e4aa5ce1a9776b6dd07f8a5405bee Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Mon, 20 Apr 2015 16:57:52 -0500 Subject: [PATCH 430/446] better explain the problem with interpteter executing functions --- doc/source/language/user_functions.rst | 47 ++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/doc/source/language/user_functions.rst b/doc/source/language/user_functions.rst index c1a33130b..9a400afb7 100644 --- a/doc/source/language/user_functions.rst +++ b/doc/source/language/user_functions.rst @@ -30,6 +30,18 @@ Help for the new user - What is a Function? feature with the term *Function*, whether it *technically* fits the mathematical definition of a "function" or not. +.. warning:: + **Functions created in programs can only be called from programs, + not from the interpreter terminal prompt**. + + If you attempt to create a function in a program, and then call it + from the interactive prompt in the interpreter instead of calling + it from inside a program, it will definitely not work properly, + but the exact error you get will depend on several "random" + factors. This may be fixed later by a later release, but for + now, don't do it. For further explanation, see the section entitled + :ref:`Functions and the interpreter terminal ` + .. _declare function: ``DECLARE FUNCTION`` @@ -134,6 +146,33 @@ just like when running a program. You can see an example of this above in the previous example where it said:: print_corner(4,"That's me in the corner"). + +.. _interpreter functions: + +Functions and the terminal interpreter +:::::::::::::::::::::::::::::::::::::: + +You **cannot** call functions from the interpreter interactive +command line if they were declared inside of script programs. +If you do, you will get seemingly "random" errors. The reasons +for this are complex, but the short version is because the +memory the script files' pseudo-machine language instructions +live in and the memory the interpreter's pseudo-machine +langauge instructions live in are two different things. + +The effect you may see if you attempt this is merely +an "Unknown Identifer" error, or worse yet, it may end +up jumping into random parts of your code that have nothing +to do with the actual function call you're trying to +make. + +As a rule of thumb, in kOS 0.17.0, make sure you only use +functions from inside script programs. Don't try to call +them interactively from the interpreter prompt. You will +get very strange and (seemingly) inexplicable errors. + +In the future we may find a way to fix this problem, +but for right now, just don't do it. Calling a function without parentheses (please don't) ::::::::::::::::::::::::::::::::::::::::::::::::::::: @@ -403,6 +442,14 @@ something that you intended to be different per recursive call. User Function Gotchas --------------------- +Calling program's functions from the interpreter +:::::::::::::::::::::::::::::::::::::::::::::::: + +As :ref:`explained above `, kOS 0.17.0 does +not support the calling of a function from the interpreter console +and if you attempt it you will get very strange and random errors +that you might waste a lot of time trying to track down. + Inconsistent returns :::::::::::::::::::: From a241eb5c98c2f13c75f4e186cf62c2f70a693ce1 Mon Sep 17 00:00:00 2001 From: Chris Woerz Date: Mon, 20 Apr 2015 21:09:33 -0600 Subject: [PATCH 431/446] resolves #889-3 --- src/kOS/Suffixed/AggregateResourceValue.cs | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/kOS/Suffixed/AggregateResourceValue.cs b/src/kOS/Suffixed/AggregateResourceValue.cs index 51c8185ec..8c63b1b18 100644 --- a/src/kOS/Suffixed/AggregateResourceValue.cs +++ b/src/kOS/Suffixed/AggregateResourceValue.cs @@ -12,10 +12,12 @@ public class AggregateResourceValue : Structure private double amount; private double capacity; private readonly ListValue parts; + private readonly float density; - public AggregateResourceValue(string name, SharedObjects shared) + public AggregateResourceValue(PartResourceDefinition definition, SharedObjects shared) { - this.name = name; + name = definition.name; + density = definition.density; this.shared = shared; amount = 0; capacity = 0; @@ -26,6 +28,7 @@ public AggregateResourceValue(string name, SharedObjects shared) private void InitializeAggregateResourceSuffixes() { AddSuffix("NAME", new Suffix(() => name, "The name of the resource (eg LiguidFuel, ElectricCharge)")); + AddSuffix("DENSITY", new Suffix(() => density, "The density of the resource")); AddSuffix("AMOUNT", new Suffix(() => amount, "The resources currently available")); AddSuffix("CAPACITY", new Suffix(() => capacity, "The total storage capacity currently available")); AddSuffix("PARTS", new Suffix>(() => parts, "The containers for this resource")); @@ -48,15 +51,15 @@ private static Dictionary ProspectResources(IEnu var resources = new Dictionary(); foreach (var part in parts) { - foreach (PartResource module in part.Resources) + foreach (PartResource resource in part.Resources) { AggregateResourceValue aggregateResourceAmount; - if (!resources.TryGetValue(module.resourceName, out aggregateResourceAmount)) + if (!resources.TryGetValue(resource.resourceName, out aggregateResourceAmount)) { - aggregateResourceAmount = new AggregateResourceValue(module.resourceName, shared); + aggregateResourceAmount = new AggregateResourceValue(resource.info, shared); } - aggregateResourceAmount.AddResource(module); - resources[module.resourceName] = aggregateResourceAmount; + aggregateResourceAmount.AddResource(resource); + resources[resource.resourceName] = aggregateResourceAmount; } } return resources; From 415799fdc6d626209392778b83654b7b5436c9e1 Mon Sep 17 00:00:00 2001 From: ZiwKerman Date: Tue, 21 Apr 2015 12:18:11 +0100 Subject: [PATCH 432/446] Final touches + docs --- doc/source/addons.rst | 9 +- doc/source/addons/IR.rst | 354 ++++++++ src/kOS/AddOns/InfernalRobotics/Addon.cs | 85 ++ .../AddOns/InfernalRobotics/IRControlGroup.cs | 6 +- .../AddOns/InfernalRobotics/IRFunctions.cs | 77 -- .../AddOns/InfernalRobotics/IRServoWrapper.cs | 5 +- src/kOS/AddOns/InfernalRobotics/IRWrapper.cs | 839 ++++++++++-------- src/kOS/Suffixed/AddonList.cs | 1 + src/kOS/kOS.csproj | 2 +- 9 files changed, 943 insertions(+), 435 deletions(-) create mode 100644 doc/source/addons/IR.rst create mode 100644 src/kOS/AddOns/InfernalRobotics/Addon.cs delete mode 100644 src/kOS/AddOns/InfernalRobotics/IRFunctions.cs diff --git a/doc/source/addons.rst b/doc/source/addons.rst index 944eead49..ab715c98c 100644 --- a/doc/source/addons.rst +++ b/doc/source/addons.rst @@ -11,6 +11,7 @@ Addon Reference Action Groups Extended RemoteTech Kerbal Alarm Clock + Infernal Robotics To help KOS scripts identify whether or not certain mod is installed and available following suffixed functions were introduced in version 0.17 @@ -23,10 +24,16 @@ Returns True if mod Action Group Extended is installed and available to KOS. ``ADDONS:RT:AVAILABLE`` ------------------------ -Returns True if mod RemoteTech is installed and available to KOS. See more RemoteTech functions here . +Returns True if mod RemoteTech is installed and available to KOS. See more RemoteTech functions :doc:`here `. ``ADDONS:KAC:AVAILABLE`` ------------------------ Returns True if mod Kerbal Alarm Clock is installed and available to KOS. + + +``ADDONS:IR:AVAILABLE`` +------------------------ + +Returns True if mod Infernal Robotics is installed, available to KOS and applicable to current craft. See more :doc:`here `. diff --git a/doc/source/addons/IR.rst b/doc/source/addons/IR.rst new file mode 100644 index 000000000..5cf064e1e --- /dev/null +++ b/doc/source/addons/IR.rst @@ -0,0 +1,354 @@ +.. _IR: + +Infernal Robotics +================= + +- Download: http://kerbal.curseforge.com/ksp-mods/220267 +- Alternative download: https://kerbalstuff.com/mod/8/Magic_Smoke_Industries_Infernal_Robotics +- Forum thread, including full instructions: http://forum.kerbalspaceprogram.com/threads/116064 + +Infernal Robotics introduces robotics parts to the game, letting you create moving or spinning contraptions that just aren't possible under stock KSP. +.. figure:: http://i.imgur.com/O94LBvF.png + +Starting version 0.20 of the Infernal Robotics, mod creators introduced API to for easier access to robotic features. + +Access structure IRAddon via `ADDONS:IR`. + +.. structure:: IRAddon + + ===================================== ========================= ============= + Suffix Type Description + ===================================== ========================= ============= + :attr:`AVAILABLE` bool(readonly) Returns True if mod Infernal Robotics is installed, available to KOS and applicable to current craft. + :attr:`GROUPS` List (readonly) Lists all Servo Groups for current focused vessel + :attr:`ALLSERVOS` List (readonly) Lists all Servos for current focused vessel + ===================================== ========================= ============= + + + +.. attribute:: IRAddon:AVAILABLE + + :type: bool + :access: Get only + + Returns True if mod Infernal Robotics is installed, available to KOS and applicable to current craft. + Example of use:: + + if ADDONS:IR:AVAILABLE + { + //some IR dependent code + } + +.. attribute:: IRAddon:GROUPS + + :type: List of :struct:`IRControlGroup` objects + :access: Get only + + Lists all Servo Groups for current focused vessel. Example of use:: + + for g in ADDONS:IR:GROUPS + { + Print g:NAME + " contains " + g:SERVOS:LENGTH + " servos". + } + + +.. attribute:: IRAddon:ALLSERVOS + + :type: List of :struct:`IRServo` objects + :access: Get only + + Lists all Servos for current focused vessel. Example of use:: + + for s in ADDONS:IR:ALLSERVOS + { + print "Name: " + s:NAME + ", position: " + s:POSITION. + } + + +.. structure:: IRControlGroup + + ===================================== ========================= ============= + Suffix Type Description + ===================================== ========================= ============= + :attr:`NAME` string Name of the Control Group + :attr:`SPEED` float Speed multiplier set in the IR UI + :attr:`EXPANDED` bool True if Group is expanded in IR UI + :attr:`FORWARDKEY` string Key assigned to forward movement + :attr:`REVERSEKEY` string Key assigned to reverse movement + :attr:`SERVOS` List (readonly) List of servos in the group + + :meth:`MOVERIGHT()` void Commands servos in the group to move in positive direction + :meth:`MOVELEFT()` void Commands servos in the group to move in negative direction + :meth:`MOVECENTER()` void Commands servos in the group to move to default position + :meth:`MOVENEXTPRESET()` void Commands servos in the group to move to next preset + :meth:`MOVEPREVPRESET()` void Commands servos in the group to move to previous preset + :meth:`STOP()` void Commands servos in the group to stop + ===================================== ========================= ============= + +.. attribute:: IRControlGroup:NAME + + :type: string + :access: Get/Set + + Name of the Control Group (cannot be empty). + +.. attribute:: IRControlGroup:SPEED + + :type: float + :access: Get/Set + + Speed multiplier as set in the IR user interface. Avoid setting it to 0. + +.. attribute:: IRControlGroup:EXPANDED + + :type: bool + :access: Get/Set + + True if Group is expanded in IR UI + +.. attribute:: IRControlGroup:FORWARDKEY + + :type: string + :access: Get/Set + + Key assigned to forward movement. Can be empty. + +.. attribute:: IRControlGroup:REVERSEKEY + + :type: string + :access: Get/Set + + Key assigned to reverse movement. Can be empty. + +.. attribute:: IRControlGroup:SERVOS + + :type: List of :struct:`IRServo` objects + :access: Get only + + Lists Servos in the Group. Example of use:: + + for g in ADDONS:IR:GROUPS + { + Print g:NAME + " contains " + g:SERVOS:LENGTH + " servos:". + for s in g:servos + { + print " " + s:NAME + ", position: " + s:POSITION. + } + } + +.. method:: IRControlGroup:MOVERIGHT() + + :return: void + + Commands servos in the group to move in positive direction. + +.. method:: IRControlGroup:MOVELEFT() + + :return: void + + Commands servos in the group to move in negative direction. + +.. method:: IRControlGroup:MOVECENTER() + + :return: void + + Commands servos in the group to move to default position. + +.. method:: IRControlGroup:MOVENEXTPRESET() + + :return: void + + Commands servos in the group to move to next preset + +.. method:: IRControlGroup:MOVEPREVPRESET() + + :return: void + + Commands servos in the group to move to previous preset + +.. method:: IRControlGroup:STOP() + + :return: void + + Commands servos in the group to stop + + +.. structure:: IRServo + + ===================================== ========================= ============= + Suffix Type Description + ===================================== ========================= ============= + :attr:`NAME` string Name of the Servo + :attr:`UID` int Unique ID of the servo part (part.flightID). + :attr:`HIGHLIGHT` bool (set-only) Set Hightlight status of the part. + :attr:`POSITION` float (readonly) Current position of the servo. + :attr:`MINCFGPOSITION` float (readonly) Minimum position for servo as defined by part creator in part.cfg + :attr:`MAXCFGPOSITION` float (readonly) Maximum position for servo as defined by part creator in part.cfg + :attr:`MINPOSITION` float Minimum position for servo, from tweakable. + :attr:`MAXPOSITION` float Maximum position for servo, from tweakable. + :attr:`CONFIGSPEED` float (readonly) Servo movement speed as defined by part creator in part.cfg + :attr:`SPEED` float Servo speed multiplier, from tweakable. + :attr:`CURRENTSPEED` float (readonly) Current Servo speed. + :attr:`ACCELERATION` float Servo acceleration multiplier, from tweakable. + + :meth:`MOVERIGHT()` void Commands servo to move in positive direction + :meth:`MOVELEFT()` void Commands servo to move in negative direction + :meth:`MOVECENTER()` void Commands servo to move to default position + :meth:`MOVENEXTPRESET()` void Commands servo to move to next preset + :meth:`MOVEPREVPRESET()` void Commands servo to move to previous preset + :meth:`STOP()` void Commands servo to stop + :meth:`MOVETO(position, speedMult)` void Commands servo to move to `position` with `speedMult` multiplier + ===================================== ========================= ============= + +.. attribute:: IRServo:NAME + + :type: string + :access: Get/Set + + Name of the Control Group (cannot be empty). + +.. attribute:: IRServo:UID + + :type: int + :access: Get + + Unique ID of the servo part (part.flightID). + +.. attribute:: IRServo:HIGHLIGHT + + :type: bool + :access: Set + + Set Hightlight status of the part. + +.. attribute:: IRServo:POSITION + + :type: float + :access: Get + + Current position of the servo. + +.. attribute:: IRServo:MINCFGPOSITION + + :type: float + :access: Get + + Minimum position for servo as defined by part creator in part.cfg + +.. attribute:: IRServo:MAXCFGPOSITION + + :type: float + :access: Get + + Maximum position for servo as defined by part creator in part.cfg + +.. attribute:: IRServo:MINPOSITION + + :type: float + :access: Get/Set + + Minimum position for servo, from tweakable. + +.. attribute:: IRServo:MAXPOSITION + + :type: float + :access: Get/Set + + Maximum position for servo, from tweakable. + +.. attribute:: IRServo:CONFIGSPEED + + :type: float + :access: Get + + Servo movement speed as defined by part creator in part.cfg + +.. attribute:: IRServo:SPEED + + :type: float + :access: Get/Set + + Servo speed multiplier, from tweakable. + +.. attribute:: IRServo:CURRENTSPEED + + :type: float + :access: Get + + Current Servo speed. + +.. attribute:: IRServo:ACCELERATION + + :type: float + :access: Get/Set + + Servo acceleration multiplier, from tweakable. + + +.. method:: IRServo:MOVERIGHT() + + :return: void + + Commands servo to move in positive direction + +.. method:: IRServo:MOVELEFT() + + :return: void + + Commands servo to move in negative direction + +.. method:: IRServo:MOVECENTER() + + :return: void + + Commands servo to move to default position + +.. method:: IRServo:MOVENEXTPRESET() + + :return: void + + Commands servo to move to next preset + +.. method:: IRServo:MOVEPREVPRESET() + + :return: void + + Commands servo to move to previous preset + +.. method:: IRServo:STOP() + + :return: void + + Commands servo to stop + +.. method:: IRServo:MOVETO(position, speedMult) + + :parameter position: (float) Position to move to + :parameter speedMult: (float) Speed multiplier + :return: void + + Commands servo to move to `position` with `speedMult` multiplier. + + +Example code:: + + print "IR Iavailable: " + ADDONS:IR:AVAILABLE. + + Print "Groups:". + + for g in ADDONS:IR:GROUPS + { + Print g:NAME + " contains " + g:SERVOS:LENGTH + " servos:". + for s in g:servos + { + print " " + s:NAME + ", position: " + s:POSITION. + if (g:NAME = "Hinges" and s:POSITION = 0) + { + s:MOVETO(30, 2). + } + else if (g:NAME = "Hinges" and s:POSITION > 0) + { + s:MOVETO(0, 1). + } + } + } diff --git a/src/kOS/AddOns/InfernalRobotics/Addon.cs b/src/kOS/AddOns/InfernalRobotics/Addon.cs new file mode 100644 index 000000000..5103a570d --- /dev/null +++ b/src/kOS/AddOns/InfernalRobotics/Addon.cs @@ -0,0 +1,85 @@ +using kOS.Safe.Encapsulation; +using kOS.Safe.Encapsulation.Suffixes; +using kOS.Safe.Exceptions; + +namespace kOS.AddOns.InfernalRobotics +{ + public class Addon : Suffixed.Addon + { + public Addon(SharedObjects shared) : base ("IR", shared) + { + InitializeSuffixes(); + } + + private void InitializeSuffixes() + { + AddSuffix("GROUPS", new Suffix(GetServoGroups, "List all ServoGroups")); + AddSuffix("ALLSERVOS", new Suffix(GetAllServos, "List all Servos")); + } + + private ListValue GetServoGroups() + { + var list = new ListValue(); + + if (!IRWrapper.APIReady) + { + throw new KOSUnavailableAddonException("IR:GROUPS", "Infernal Robotics"); + } + + var controlGroups = IRWrapper.IRController.ServoGroups; + + if (controlGroups == null) + { + //Control Groups are somehow null, just return the empty list + return list; + } + + foreach (IRWrapper.IControlGroup cg in controlGroups) + { + list.Add(new IRControlGroupWrapper(cg, shared)); + } + + + return list; + } + + private ListValue GetAllServos() + { + var list = new ListValue(); + + if (!IRWrapper.APIReady) + { + throw new KOSUnavailableAddonException("IR:ALLSERVOS", "Infernal Robotics"); + } + + var controlGroups = IRWrapper.IRController.ServoGroups; + + if (controlGroups == null) + { + //Control Groups are somehow null, just return the empty list + return list; + } + + foreach (IRWrapper.IControlGroup cg in controlGroups) + { + if (cg.Servos == null) + continue; + + foreach (IRWrapper.IServo s in cg.Servos) + { + list.Add (new IRServoWrapper (s, shared)); + } + } + + + return list; + } + + public override bool Available() + { + return IRWrapper.APIReady; + } + + } +} + diff --git a/src/kOS/AddOns/InfernalRobotics/IRControlGroup.cs b/src/kOS/AddOns/InfernalRobotics/IRControlGroup.cs index de7e48c9c..747876ade 100644 --- a/src/kOS/AddOns/InfernalRobotics/IRControlGroup.cs +++ b/src/kOS/AddOns/InfernalRobotics/IRControlGroup.cs @@ -11,10 +11,10 @@ namespace kOS.AddOns.InfernalRobotics { public class IRControlGroupWrapper : Structure { - private readonly IRWrapper.IRAPI.IRControlGroup cg; + private readonly IRWrapper.IControlGroup cg; private readonly SharedObjects shared; - public IRControlGroupWrapper(IRWrapper.IRAPI.IRControlGroup init, SharedObjects shared) + public IRControlGroupWrapper(IRWrapper.IControlGroup init, SharedObjects shared) { cg = init; this.shared = shared; @@ -45,7 +45,7 @@ public ListValue GetServos() if(IRWrapper.APIReady) { - foreach(IRWrapper.IRAPI.IRServo s in cg.Servos) + foreach(IRWrapper.IServo s in cg.Servos) { list.Add(new IRServoWrapper(s, shared)); } diff --git a/src/kOS/AddOns/InfernalRobotics/IRFunctions.cs b/src/kOS/AddOns/InfernalRobotics/IRFunctions.cs deleted file mode 100644 index 4e9018c6c..000000000 --- a/src/kOS/AddOns/InfernalRobotics/IRFunctions.cs +++ /dev/null @@ -1,77 +0,0 @@ -using kOS.Function; -using kOS.Safe.Encapsulation; -using kOS.Safe.Exceptions; -using kOS.Safe.Function; -using kOS.Safe.Utilities; -using System; -using System.Linq; - -namespace kOS.AddOns.InfernalRobotics -{ - [Function("IR_listServos")] - public class FunctionIRListServos : FunctionBase - { - public override void Execute(SharedObjects shared) - { - var list = new ListValue(); - if (!IRWrapper.APIReady) - { - ReturnValue = list; - //throw new KOSUnavailableAddonException("IR_listServos()", "Infernal Robotics"); - return; - } - - var controlGroup = (IRWrapper.IRAPI.IRControlGroup) PopValueAssert(shared); - AssertArgBottomAndConsume(shared); - if (controlGroup == null) - { - ReturnValue = list; - return; - } - - IRWrapper.IRAPI.IRServosList servos = controlGroup.Servos; - - foreach (IRWrapper.IRAPI.IRServo s in servos) - { - list.Add(new IRServoWrapper(s, shared)); - } - - ReturnValue = list; - } - } - - [Function("IR_listControlGroups")] - public class FunctionIRListControlGroups : FunctionBase - { - public override void Execute(SharedObjects shared) - { - var list = new ListValue(); - - AssertArgBottomAndConsume(shared); - - if (!IRWrapper.APIReady) - { - SafeHouse.Logger.SuperVerbose ("IRAPI not ready."); - ReturnValue = list; - //throw new KOSUnavailableAddonException("listControlGroups()", "Kerbal Alarm Clock"); - return; - } - - IRWrapper.IRAPI.IRServoGroupsList controlGroups = IRWrapper.IRController.ServoGroups; - - if (controlGroups == null) - { - ReturnValue = list; - //throw new KOSUnavailableAddonException("listControlGroups()", "Kerbal Alarm Clock"); - return; - } - - foreach (IRWrapper.IRAPI.IRControlGroup cg in controlGroups) - { - list.Add(new IRControlGroupWrapper(cg, shared)); - } - - ReturnValue = list; - } - } -} \ No newline at end of file diff --git a/src/kOS/AddOns/InfernalRobotics/IRServoWrapper.cs b/src/kOS/AddOns/InfernalRobotics/IRServoWrapper.cs index 197af4b62..c0e22078f 100644 --- a/src/kOS/AddOns/InfernalRobotics/IRServoWrapper.cs +++ b/src/kOS/AddOns/InfernalRobotics/IRServoWrapper.cs @@ -9,10 +9,10 @@ namespace kOS.AddOns.InfernalRobotics { public class IRServoWrapper : Structure { - private readonly IRWrapper.IRAPI.IRServo servo; + private readonly IRWrapper.IServo servo; private readonly SharedObjects shared; - public IRServoWrapper(IRWrapper.IRAPI.IRServo init, SharedObjects shared) + public IRServoWrapper(IRWrapper.IServo init, SharedObjects shared) { servo = init; this.shared = shared; @@ -22,6 +22,7 @@ public IRServoWrapper(IRWrapper.IRAPI.IRServo init, SharedObjects shared) private void InitializeSuffixes() { AddSuffix("NAME", new SetSuffix(() => servo.Name, value => servo.Name = value)); + AddSuffix("UID", new Suffix(() => servo.UID)); AddSuffix("HIGHLIGHT", new SetSuffix(() => true, value => servo.Highlight = value)); AddSuffix("POSITION", new Suffix(() => servo.Position)); diff --git a/src/kOS/AddOns/InfernalRobotics/IRWrapper.cs b/src/kOS/AddOns/InfernalRobotics/IRWrapper.cs index 132908757..457d99cf7 100644 --- a/src/kOS/AddOns/InfernalRobotics/IRWrapper.cs +++ b/src/kOS/AddOns/InfernalRobotics/IRWrapper.cs @@ -1,35 +1,32 @@ using System; using System.Collections; using System.Collections.Generic; -using System.ComponentModel; using System.Linq; using System.Reflection; -using System.Text; // TODO: Change this namespace to something specific to your plugin here. namespace kOS.AddOns.InfernalRobotics { - public class IRWrapper { - protected static System.Type IRServoControllerType; - protected static System.Type IRControlGroupType; - protected static System.Type IRServoType; - protected static System.Type IRServoPartType; - protected static System.Type IRServoMechanismType; + private static bool isWrapped; - protected static Object actualServoController = null; + protected internal static Type IRServoControllerType { get; set; } + protected internal static Type IRControlGroupType { get; set; } + protected internal static Type IRServoType { get; set; } + protected internal static Type IRServoPartType { get; set; } + protected internal static Type IRServoMechanismType { get; set; } + protected internal static object ActualServoController { get; set; } - public static IRAPI IRController = null; - public static Boolean AssemblyExists { get { return (IRServoControllerType != null); } } - public static Boolean InstanceExists { get { return (IRController != null); } } - private static Boolean isWrapped = false; - public static Boolean APIReady { get { return isWrapped && IRController.APIReady; } } + internal static IRAPI IRController { get; set; } + internal static bool AssemblyExists { get { return (IRServoControllerType != null); } } + internal static bool InstanceExists { get { return (IRController != null); } } + internal static bool APIReady { get { return isWrapped && IRController.Ready; } } - public static Boolean InitWrapper() + internal static bool InitWrapper() { isWrapped = false; - actualServoController = null; + ActualServoController = null; IRController = null; LogFormatted("Attempting to Grab IR Types..."); @@ -104,66 +101,75 @@ public static Boolean InitWrapper() try { - var fi = IRServoControllerType.GetProperty("Instance", BindingFlags.Public | BindingFlags.Static); - - if (fi == null) + var propertyInfo = IRServoControllerType.GetProperty("Instance", BindingFlags.Public | BindingFlags.Static); + + if (propertyInfo == null) LogFormatted("[IR Wrapper] Cannot find Instance Property"); - actualServoController = fi.GetValue(null, null); + else + ActualServoController = propertyInfo.GetValue(null, null); } catch (Exception e) { LogFormatted("No Instance found, " + e.Message); } - if (actualServoController == null) + if (ActualServoController == null) { LogFormatted("Failed grabbing Instance"); return false; } LogFormatted("Got Instance, Creating Wrapper Objects"); - IRController = new IRAPI(actualServoController); + IRController = new InfernalRoboticsAPI(ActualServoController); isWrapped = true; return true; } - public class IRAPI + #region Private Implementation + + private class InfernalRoboticsAPI : IRAPI { - internal IRAPI(Object IRServoController) - { - actualServoController = IRServoController; + private PropertyInfo apiReady; + private object actualServoGroups; - LogFormatted("Getting APIReady Object"); - APIReadyProperty = IRServoControllerType.GetProperty("APIReady", BindingFlags.Public | BindingFlags.Static); - LogFormatted("Success: " + (APIReadyProperty != null).ToString()); + public InfernalRoboticsAPI(object irServoController) + { + DetermineReady(); + BuildServoGroups(irServoController); + } + private void BuildServoGroups(object irServoController) + { LogFormatted("Getting ServoGroups Object"); - ServoGroupsField = IRServoControllerType.GetField("ServoGroups"); - if (ServoGroupsField == null) + var servoGroupsField = IRServoControllerType.GetField("ServoGroups"); + if (servoGroupsField == null) LogFormatted("Failed Getting ServoGroups fieldinfo"); - actualServoGroups = ServoGroupsField.GetValue(actualServoController); - LogFormatted("Success: " + (actualServoGroups != null).ToString()); - + else + { + actualServoGroups = servoGroupsField.GetValue(irServoController); + LogFormatted("Success: " + (actualServoGroups != null)); + } } - private Object actualServoController; + private void DetermineReady() + { + LogFormatted("Getting APIReady Object"); + apiReady = IRServoControllerType.GetProperty("APIReady", BindingFlags.Public | BindingFlags.Static); + LogFormatted("Success: " + (apiReady != null)); + } - private PropertyInfo APIReadyProperty; - public Boolean APIReady + public bool Ready { get { - if (APIReadyProperty == null) + if (apiReady == null) return false; - return (Boolean)APIReadyProperty.GetValue(null, null); + return (bool)apiReady.GetValue(null, null); } } - private Object actualServoGroups; - private FieldInfo ServoGroupsField; - - internal IRServoGroupsList ServoGroups + public IList ServoGroups { get { @@ -171,401 +177,532 @@ internal IRServoGroupsList ServoGroups } } - private IRServoGroupsList ExtractServoGroups(Object actualServoGroups) + private IList ExtractServoGroups(object servoGroups) { - IRServoGroupsList ListToReturn = new IRServoGroupsList(); + var listToReturn = new List(); + + if (servoGroups == null) + return listToReturn; + try { //iterate each "value" in the dictionary - foreach (var item in (IList)actualServoGroups) + foreach (var item in (IList)servoGroups) { - IRControlGroup r1 = new IRControlGroup(item); - ListToReturn.Add(r1); + listToReturn.Add(new IRControlGroup(item)); } } - catch (Exception) + catch (Exception ex) { - //LogFormatted("Arrggg: {0}", ex.Message); - //throw ex; - // + LogFormatted("Cannot list ServoGroups: {0}", ex.Message); } - return ListToReturn; + return listToReturn; } + } - public class IRControlGroup + private class IRControlGroup : IControlGroup + { + private readonly object actualControlGroup; + + private PropertyInfo nameProperty; + private PropertyInfo forwardKeyProperty; + private PropertyInfo expandedProperty; + private PropertyInfo speedProperty; + private PropertyInfo reverseKeyProperty; + + private MethodInfo moveRightMethod; + private MethodInfo moveLeftMethod; + private MethodInfo moveCenterMethod; + private MethodInfo moveNextPresetMethod; + private MethodInfo movePrevPresetMethod; + private MethodInfo stopMethod; + + public IRControlGroup(object cg) { - internal IRControlGroup(Object cg) - { - actualControlGroup = cg; - NameProperty = IRControlGroupType.GetProperty("Name"); - ForwardKeyProperty = IRControlGroupType.GetProperty("ForwardKey"); - ReverseKeyProperty = IRControlGroupType.GetProperty("ReverseKey"); - SpeedProperty = IRControlGroupType.GetProperty("Speed"); - ExpandedProperty = IRControlGroupType.GetProperty("Expanded"); - - ServosProperty = IRControlGroupType.GetProperty("Servos"); - actualServos = ServosProperty.GetValue(actualControlGroup, null); - - MoveRightMethod = IRControlGroupType.GetMethod("MoveRight", BindingFlags.Public | BindingFlags.Instance); - MoveLeftMethod = IRControlGroupType.GetMethod("MoveLeft", BindingFlags.Public | BindingFlags.Instance); - MoveCenterMethod = IRControlGroupType.GetMethod("MoveCenter", BindingFlags.Public | BindingFlags.Instance); - MoveNextPresetMethod = IRControlGroupType.GetMethod("MoveNextPreset", BindingFlags.Public | BindingFlags.Instance); - MovePrevPresetMethod = IRControlGroupType.GetMethod("MovePrevPreset", BindingFlags.Public | BindingFlags.Instance); - StopMethod = IRControlGroupType.GetMethod("Stop", BindingFlags.Public | BindingFlags.Instance); - } - private Object actualControlGroup; + actualControlGroup = cg; + FindProperties(); + FindMethods(); + } - private PropertyInfo NameProperty; - public String Name - { - get { return (String)NameProperty.GetValue(actualControlGroup, null); } - set { NameProperty.SetValue(actualControlGroup, value, null); } - } + private void FindProperties() + { + nameProperty = IRControlGroupType.GetProperty("Name"); + forwardKeyProperty = IRControlGroupType.GetProperty("ForwardKey"); + reverseKeyProperty = IRControlGroupType.GetProperty("ReverseKey"); + speedProperty = IRControlGroupType.GetProperty("Speed"); + expandedProperty = IRControlGroupType.GetProperty("Expanded"); + + var servosProperty = IRControlGroupType.GetProperty("Servos"); + ActualServos = servosProperty.GetValue(actualControlGroup, null); + } - private PropertyInfo ForwardKeyProperty; - public String ForwardKey - { - get { return (String)ForwardKeyProperty.GetValue(actualControlGroup, null); } - set { ForwardKeyProperty.SetValue(actualControlGroup, value, null); } - } + private void FindMethods() + { + moveRightMethod = IRControlGroupType.GetMethod("MoveRight", BindingFlags.Public | BindingFlags.Instance); + moveLeftMethod = IRControlGroupType.GetMethod("MoveLeft", BindingFlags.Public | BindingFlags.Instance); + moveCenterMethod = IRControlGroupType.GetMethod("MoveCenter", BindingFlags.Public | BindingFlags.Instance); + moveNextPresetMethod = IRControlGroupType.GetMethod("MoveNextPreset", BindingFlags.Public | BindingFlags.Instance); + movePrevPresetMethod = IRControlGroupType.GetMethod("MovePrevPreset", BindingFlags.Public | BindingFlags.Instance); + stopMethod = IRControlGroupType.GetMethod("Stop", BindingFlags.Public | BindingFlags.Instance); + } - private PropertyInfo ReverseKeyProperty; - public String ReverseKey - { - get { return (String)ReverseKeyProperty.GetValue(actualControlGroup, null); } - set { ReverseKeyProperty.SetValue(actualControlGroup, value, null); } - } + public string Name + { + get { return (string)nameProperty.GetValue(actualControlGroup, null); } + set { nameProperty.SetValue(actualControlGroup, value, null); } + } - private PropertyInfo SpeedProperty; - public float Speed - { - get { return (float)SpeedProperty.GetValue(actualControlGroup, null); } - set { SpeedProperty.SetValue(actualControlGroup, value, null); } - } + public string ForwardKey + { + get { return (string)forwardKeyProperty.GetValue(actualControlGroup, null); } + set { forwardKeyProperty.SetValue(actualControlGroup, value, null); } + } - private PropertyInfo ExpandedProperty; - public bool Expanded - { - get { return (bool)ExpandedProperty.GetValue(actualControlGroup, null); } - set { ExpandedProperty.SetValue(actualControlGroup, value, null); } - } + public string ReverseKey + { + get { return (string)reverseKeyProperty.GetValue(actualControlGroup, null); } + set { reverseKeyProperty.SetValue(actualControlGroup, value, null); } + } - private Object actualServos; - private PropertyInfo ServosProperty; + public float Speed + { + get { return (float)speedProperty.GetValue(actualControlGroup, null); } + set { speedProperty.SetValue(actualControlGroup, value, null); } + } - internal IRServosList Servos - { - get - { - return ExtractServos(actualServos); - } - } + public bool Expanded + { + get { return (bool)expandedProperty.GetValue(actualControlGroup, null); } + set { expandedProperty.SetValue(actualControlGroup, value, null); } + } - private IRServosList ExtractServos(Object actualServos) - { - IRServosList ListToReturn = new IRServosList(); - try - { - //iterate each "value" in the dictionary - foreach (var item in (IList)actualServos) - { - IRServo r1 = new IRServo(item); - ListToReturn.Add(r1); - } - } - catch (Exception) - { - //LogFormatted("Arrggg: {0}", ex.Message); - //throw ex; - // - } - return ListToReturn; - } + private object ActualServos { get; set; } - private MethodInfo MoveRightMethod; - internal void MoveRight() + public IList Servos + { + get { - MoveRightMethod.Invoke(actualControlGroup, new System.Object[] { }); + return ExtractServos(ActualServos); } + } - private MethodInfo MoveLeftMethod; - internal void MoveLeft() - { - MoveLeftMethod.Invoke(actualControlGroup, new System.Object[] { }); - } + public void MoveRight() + { + moveRightMethod.Invoke(actualControlGroup, new object[] { }); + } - private MethodInfo MoveCenterMethod; - internal void MoveCenter() - { - MoveCenterMethod.Invoke(actualControlGroup, new System.Object[] { }); - } + public void MoveLeft() + { + moveLeftMethod.Invoke(actualControlGroup, new object[] { }); + } - private MethodInfo MoveNextPresetMethod; - internal void MoveNextPreset() - { - MoveNextPresetMethod.Invoke(actualControlGroup, new System.Object[] { }); - } + public void MoveCenter() + { + moveCenterMethod.Invoke(actualControlGroup, new object[] { }); + } - private MethodInfo MovePrevPresetMethod; - internal void MovePrevPreset() + public void MoveNextPreset() + { + moveNextPresetMethod.Invoke(actualControlGroup, new object[] { }); + } + + public void MovePrevPreset() + { + movePrevPresetMethod.Invoke(actualControlGroup, new object[] { }); + } + + public void Stop() + { + stopMethod.Invoke(actualControlGroup, new object[] { }); + } + + private IList ExtractServos(object actualServos) + { + var listToReturn = new List(); + + if (actualServos == null) + return listToReturn; + + try { - MovePrevPresetMethod.Invoke(actualControlGroup, new System.Object[] { }); + //iterate each "value" in the dictionary + foreach (var item in (IList)actualServos) + { + listToReturn.Add(new IRServo(item)); + } } - - private MethodInfo StopMethod; - internal void Stop() + catch (Exception ex) { - StopMethod.Invoke(actualControlGroup, new System.Object[] { }); + LogFormatted("Error extracting from actualServos: {0}", ex.Message); } + return listToReturn; } - public class IRServo + public bool Equals(IControlGroup other) { + var controlGroup = other as IRControlGroup; + return controlGroup != null && Equals(controlGroup); + } + } - internal IRServo(Object s) - { - actualServo = s; - - NameProperty = IRServoPartType.GetProperty("Name"); - HighlightProperty = IRServoPartType.GetProperty("Highlight"); - - MechanismProperty = IRServoType.GetProperty("Mechanism"); - actualServoMechanism = MechanismProperty.GetValue(actualServo, null); - - PositionProperty = IRServoMechanismType.GetProperty("Position"); - MinPositionProperty = IRServoMechanismType.GetProperty("MinPositionLimit"); - MaxPositionProperty = IRServoMechanismType.GetProperty("MaxPositionLimit"); - - MinConfigPositionProperty = IRServoMechanismType.GetProperty("MinPosition"); - MaxConfigPositionProperty = IRServoMechanismType.GetProperty("MaxPosition"); - - SpeedProperty = IRServoMechanismType.GetProperty("SpeedLimit"); - ConfigSpeedProperty = IRServoMechanismType.GetProperty("DefaultSpeed"); - CurrentSpeedProperty = IRServoMechanismType.GetProperty("CurrentSpeed"); - AccelerationProperty = IRServoMechanismType.GetProperty("AccelerationLimit"); - IsMovingProperty = IRServoMechanismType.GetProperty("IsMoving"); - IsFreeMovingProperty = IRServoMechanismType.GetProperty("IsFreeMoving"); - IsLockedProperty = IRServoMechanismType.GetProperty("IsLocked"); - IsAxisInvertedProperty = IRServoMechanismType.GetProperty("IsAxisInverted"); - - MoveRightMethod = IRServoMechanismType.GetMethod("MoveRight", BindingFlags.Public | BindingFlags.Instance); - MoveLeftMethod = IRServoMechanismType.GetMethod("MoveLeft", BindingFlags.Public | BindingFlags.Instance); - MoveCenterMethod = IRServoMechanismType.GetMethod("MoveCenter", BindingFlags.Public | BindingFlags.Instance); - MoveNextPresetMethod = IRServoMechanismType.GetMethod("MoveNextPreset", BindingFlags.Public | BindingFlags.Instance); - MovePrevPresetMethod = IRServoMechanismType.GetMethod("MovePrevPreset", BindingFlags.Public | BindingFlags.Instance); - StopMethod = IRServoMechanismType.GetMethod("Stop", BindingFlags.Public | BindingFlags.Instance); - - MoveToMethod = IRServoMechanismType.GetMethod("MoveTo", new Type[] { typeof(float), typeof(float) }); - } - private Object actualServo; + public class IRServo : IServo + { + private object actualServoMechanism; + + private PropertyInfo maxConfigPositionProperty; + private PropertyInfo minPositionProperty; + private PropertyInfo maxPositionProperty; + private PropertyInfo configSpeedProperty; + private PropertyInfo speedProperty; + private PropertyInfo currentSpeedProperty; + private PropertyInfo accelerationProperty; + private PropertyInfo isMovingProperty; + private PropertyInfo isFreeMovingProperty; + private PropertyInfo isLockedProperty; + private PropertyInfo isAxisInvertedProperty; + private PropertyInfo nameProperty; + private PropertyInfo highlightProperty; + private PropertyInfo positionProperty; + private PropertyInfo minConfigPositionProperty; + + private PropertyInfo UIDProperty; + + private MethodInfo moveRightMethod; + private MethodInfo moveLeftMethod; + private MethodInfo moveCenterMethod; + private MethodInfo moveNextPresetMethod; + private MethodInfo movePrevPresetMethod; + private MethodInfo moveToMethod; + private MethodInfo stopMethod; + + public IRServo(object s) + { + actualServo = s; - private PropertyInfo MechanismProperty; - private Object actualServoMechanism; + FindProperties(); + FindMethods(); + } - private PropertyInfo NameProperty; - public String Name - { - get { return (String)NameProperty.GetValue(actualServo, null); } - set { NameProperty.SetValue(actualServo, value, null); } - } + private void FindProperties() + { + nameProperty = IRServoPartType.GetProperty("Name"); + highlightProperty = IRServoPartType.GetProperty("Highlight"); + UIDProperty = IRServoPartType.GetProperty ("UID"); + + var mechanismProperty = IRServoType.GetProperty("Mechanism"); + actualServoMechanism = mechanismProperty.GetValue(actualServo, null); + + positionProperty = IRServoMechanismType.GetProperty("Position"); + minPositionProperty = IRServoMechanismType.GetProperty("MinPositionLimit"); + maxPositionProperty = IRServoMechanismType.GetProperty("MaxPositionLimit"); + + minConfigPositionProperty = IRServoMechanismType.GetProperty("MinPosition"); + maxConfigPositionProperty = IRServoMechanismType.GetProperty("MaxPosition"); + + speedProperty = IRServoMechanismType.GetProperty("SpeedLimit"); + configSpeedProperty = IRServoMechanismType.GetProperty("DefaultSpeed"); + currentSpeedProperty = IRServoMechanismType.GetProperty("CurrentSpeed"); + accelerationProperty = IRServoMechanismType.GetProperty("AccelerationLimit"); + isMovingProperty = IRServoMechanismType.GetProperty("IsMoving"); + isFreeMovingProperty = IRServoMechanismType.GetProperty("IsFreeMoving"); + isLockedProperty = IRServoMechanismType.GetProperty("IsLocked"); + isAxisInvertedProperty = IRServoMechanismType.GetProperty("IsAxisInverted"); + } - private PropertyInfo HighlightProperty; - public bool Highlight - { - //get { return (bool)HighlightProperty.GetValue(actualServo, null); } - set { HighlightProperty.SetValue(actualServo, value, null); } - } + private void FindMethods() + { + moveRightMethod = IRServoMechanismType.GetMethod("MoveRight", BindingFlags.Public | BindingFlags.Instance); + moveLeftMethod = IRServoMechanismType.GetMethod("MoveLeft", BindingFlags.Public | BindingFlags.Instance); + moveCenterMethod = IRServoMechanismType.GetMethod("MoveCenter", BindingFlags.Public | BindingFlags.Instance); + moveNextPresetMethod = IRServoMechanismType.GetMethod("MoveNextPreset", BindingFlags.Public | BindingFlags.Instance); + movePrevPresetMethod = IRServoMechanismType.GetMethod("MovePrevPreset", BindingFlags.Public | BindingFlags.Instance); + stopMethod = IRServoMechanismType.GetMethod("Stop", BindingFlags.Public | BindingFlags.Instance); + moveToMethod = IRServoMechanismType.GetMethod("MoveTo", new[] { typeof(float), typeof(float) }); + } - private PropertyInfo PositionProperty; - public float Position - { - get { return (float)PositionProperty.GetValue(actualServoMechanism, null); } - } + private readonly object actualServo; - private PropertyInfo MinConfigPositionProperty; - public float MinConfigPosition - { - get { return (float)MinConfigPositionProperty.GetValue(actualServoMechanism, null); } - } + public uint UID + { + get { return (uint)UIDProperty.GetValue(actualServo, null); } + } - private PropertyInfo MaxConfigPositionProperty; - public float MaxConfigPosition - { - get { return (float)MaxConfigPositionProperty.GetValue(actualServoMechanism, null); } - } + public string Name + { + get { return (string)nameProperty.GetValue(actualServo, null); } + set { nameProperty.SetValue(actualServo, value, null); } + } - private PropertyInfo MinPositionProperty; - public float MinPosition - { - get { return (float)MinPositionProperty.GetValue(actualServoMechanism, null); } - set { MinPositionProperty.SetValue(actualServoMechanism, value, null); } - } + public bool Highlight + { + //get { return (bool)HighlightProperty.GetValue(actualServo, null); } + set { highlightProperty.SetValue(actualServo, value, null); } + } - private PropertyInfo MaxPositionProperty; - public float MaxPosition - { - get { return (float)MaxPositionProperty.GetValue(actualServoMechanism, null); } - set { MaxPositionProperty.SetValue(actualServoMechanism, value, null); } - } + public float Position + { + get { return (float)positionProperty.GetValue(actualServoMechanism, null); } + } - private PropertyInfo ConfigSpeedProperty; - public float ConfigSpeed - { - get { return (float)ConfigSpeedProperty.GetValue(actualServoMechanism, null); } - } + public float MinConfigPosition + { + get { return (float)minConfigPositionProperty.GetValue(actualServoMechanism, null); } + } - private PropertyInfo SpeedProperty; - public float Speed - { - get { return (float)SpeedProperty.GetValue(actualServoMechanism, null); } - set { SpeedProperty.SetValue(actualServoMechanism, value, null); } - } + public float MaxConfigPosition + { + get { return (float)maxConfigPositionProperty.GetValue(actualServoMechanism, null); } + } - private PropertyInfo CurrentSpeedProperty; - public float CurrentSpeed - { - get { return (float)CurrentSpeedProperty.GetValue(actualServoMechanism, null); } - set { CurrentSpeedProperty.SetValue(actualServoMechanism, value, null); } - } + public float MinPosition + { + get { return (float)minPositionProperty.GetValue(actualServoMechanism, null); } + set { minPositionProperty.SetValue(actualServoMechanism, value, null); } + } - private PropertyInfo AccelerationProperty; - public float Acceleration - { - get { return (float)AccelerationProperty.GetValue(actualServoMechanism, null); } - set { AccelerationProperty.SetValue(actualServoMechanism, value, null); } - } + public float MaxPosition + { + get { return (float)maxPositionProperty.GetValue(actualServoMechanism, null); } + set { maxPositionProperty.SetValue(actualServoMechanism, value, null); } + } - private PropertyInfo IsMovingProperty; - public bool IsMoving - { - get { return (bool)IsMovingProperty.GetValue(actualServoMechanism, null); } - } + public float ConfigSpeed + { + get { return (float)configSpeedProperty.GetValue(actualServoMechanism, null); } + } - private PropertyInfo IsFreeMovingProperty; - public bool IsFreeMoving - { - get { return (bool)IsFreeMovingProperty.GetValue(actualServoMechanism, null); } - } + public float Speed + { + get { return (float)speedProperty.GetValue(actualServoMechanism, null); } + set { speedProperty.SetValue(actualServoMechanism, value, null); } + } - private PropertyInfo IsLockedProperty; - public bool IsLocked - { - get { return (bool)IsLockedProperty.GetValue(actualServoMechanism, null); } - set { IsLockedProperty.SetValue(actualServoMechanism, value, null); } - } + public float CurrentSpeed + { + get { return (float)currentSpeedProperty.GetValue(actualServoMechanism, null); } + set { currentSpeedProperty.SetValue(actualServoMechanism, value, null); } + } - private PropertyInfo IsAxisInvertedProperty; - public bool IsAxisInverted - { - get { return (bool)IsAxisInvertedProperty.GetValue(actualServoMechanism, null); } - set { IsAxisInvertedProperty.SetValue(actualServoMechanism, value, null); } - } + public float Acceleration + { + get { return (float)accelerationProperty.GetValue(actualServoMechanism, null); } + set { accelerationProperty.SetValue(actualServoMechanism, value, null); } + } - private MethodInfo MoveRightMethod; - internal void MoveRight() - { - MoveRightMethod.Invoke(actualServoMechanism, new System.Object[] { }); - } + public bool IsMoving + { + get { return (bool)isMovingProperty.GetValue(actualServoMechanism, null); } + } - private MethodInfo MoveLeftMethod; - internal void MoveLeft() - { - MoveLeftMethod.Invoke(actualServoMechanism, new System.Object[] { }); - } + public bool IsFreeMoving + { + get { return (bool)isFreeMovingProperty.GetValue(actualServoMechanism, null); } + } - private MethodInfo MoveCenterMethod; - internal void MoveCenter() - { - MoveCenterMethod.Invoke(actualServoMechanism, new System.Object[] { }); - } + public bool IsLocked + { + get { return (bool)isLockedProperty.GetValue(actualServoMechanism, null); } + set { isLockedProperty.SetValue(actualServoMechanism, value, null); } + } - private MethodInfo MoveNextPresetMethod; - internal void MoveNextPreset() - { - MoveNextPresetMethod.Invoke(actualServoMechanism, new System.Object[] { }); - } + public bool IsAxisInverted + { + get { return (bool)isAxisInvertedProperty.GetValue(actualServoMechanism, null); } + set { isAxisInvertedProperty.SetValue(actualServoMechanism, value, null); } + } - private MethodInfo MovePrevPresetMethod; - internal void MovePrevPreset() - { - MovePrevPresetMethod.Invoke(actualServoMechanism, new System.Object[] { }); - } + public void MoveRight() + { + moveRightMethod.Invoke(actualServoMechanism, new object[] { }); + } - private MethodInfo MoveToMethod; - internal void MoveTo(float position, float speed) - { - MoveToMethod.Invoke(actualServoMechanism, new System.Object[] {position, speed }); - } + public void MoveLeft() + { + moveLeftMethod.Invoke(actualServoMechanism, new object[] { }); + } - private MethodInfo StopMethod; - internal void Stop() - { - StopMethod.Invoke(actualServoMechanism, new System.Object[] { }); - } + public void MoveCenter() + { + moveCenterMethod.Invoke(actualServoMechanism, new object[] { }); + } - public override bool Equals(object o) - { - var servo = o as IRServo; - return servo != null && actualServo.Equals(servo.actualServo); - } + public void MoveNextPreset() + { + moveNextPresetMethod.Invoke(actualServoMechanism, new object[] { }); + } - public override int GetHashCode() - { - return (actualServo != null ? actualServo.GetHashCode() : 0); - } + public void MovePrevPreset() + { + movePrevPresetMethod.Invoke(actualServoMechanism, new object[] { }); + } - public static bool operator ==(IRServo left, IRServo right) - { - return Equals(left, right); - } + public void MoveTo(float position, float speed) + { + moveToMethod.Invoke(actualServoMechanism, new object[] { position, speed }); + } - public static bool operator !=(IRServo left, IRServo right) - { - return !Equals(left, right); - } + public void Stop() + { + stopMethod.Invoke(actualServoMechanism, new object[] { }); + } - protected bool Equals(IRServo other) - { - return Equals(actualServo, other.actualServo); - } + public bool Equals(IServo other) + { + var servo = other as IRServo; + return servo != null && Equals(servo); } - public class IRServoGroupsList : List + public override bool Equals(object o) { + var servo = o as IRServo; + return servo != null && actualServo.Equals(servo.actualServo); + } + public override int GetHashCode() + { + return (actualServo != null ? actualServo.GetHashCode() : 0); } - public class IRServosList : List + public static bool operator ==(IRServo left, IRServo right) { + return Equals(left, right); + } + public static bool operator !=(IRServo left, IRServo right) + { + return !Equals(left, right); + } + + protected bool Equals(IRServo other) + { + return Equals(actualServo, other.actualServo); } } + #endregion Private Implementation + + #region API Contract + + public interface IRAPI + { + bool Ready { get; } + + IList ServoGroups { get; } + } + + public interface IControlGroup : IEquatable + { + string Name { get; set; } + + string ForwardKey { get; set; } + + string ReverseKey { get; set; } + + float Speed { get; set; } + + bool Expanded { get; set; } + + IList Servos { get; } + + void MoveRight(); + + void MoveLeft(); + + void MoveCenter(); + + void MoveNextPreset(); + + void MovePrevPreset(); + + void Stop(); + } + + public interface IServo : IEquatable + { + uint UID { get; } + + string Name { get; set; } + + bool Highlight { set; } + + float Position { get; } + + float MinConfigPosition { get; } + + float MaxConfigPosition { get; } + + float MinPosition { get; set; } + + float MaxPosition { get; set; } + + float ConfigSpeed { get; } + + float Speed { get; set; } + + float CurrentSpeed { get; set; } + + float Acceleration { get; set; } + + bool IsMoving { get; } + + bool IsFreeMoving { get; } + + bool IsLocked { get; set; } + + bool IsAxisInverted { get; set; } + + void MoveRight(); + + void MoveLeft(); + + void MoveCenter(); + + void MoveNextPreset(); + + void MovePrevPreset(); + + void MoveTo(float position, float speed); + + void Stop(); + + bool Equals(object o); + + int GetHashCode(); + } + + #endregion API Contract + #region Logging Stuff + /// /// Some Structured logging to the debug file - ONLY RUNS WHEN DLL COMPILED IN DEBUG MODE /// - /// Text to be printed - can be formatted as per String.format - /// Objects to feed into a String.format + /// Text to be printed - can be formatted as per string.format + /// Objects to feed into a string.format [System.Diagnostics.Conditional("DEBUG")] - internal static void LogFormatted_DebugOnly(String Message, params Object[] strParams) + internal static void LogFormatted_DebugOnly(string message, params object[] strParams) { - LogFormatted(Message, strParams); + LogFormatted(message, strParams); } /// /// Some Structured logging to the debug file /// - /// Text to be printed - can be formatted as per String.format - /// Objects to feed into a String.format - internal static void LogFormatted(String Message, params Object[] strParams) + /// Text to be printed - can be formatted as per string.format + /// Objects to feed into a string.format + internal static void LogFormatted(string message, params object[] strParams) { - Message = String.Format(Message, strParams); - String strMessageLine = String.Format("{0},{2}-{3},{1}", - DateTime.Now, Message, System.Reflection.Assembly.GetExecutingAssembly().GetName().Name, - System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name); + var assemblyName = Assembly.GetExecutingAssembly().GetName().Name; + var declaringType = MethodBase.GetCurrentMethod().DeclaringType; + message = string.Format(message, strParams); + + string strMessageLine = declaringType != null ? + string.Format("{0},{2}-{3},{1}", DateTime.Now, message, assemblyName, declaringType.Name) : + string.Format("{0},{2}-NO-DECLARE,{1}", DateTime.Now, message, assemblyName); + UnityEngine.Debug.Log(strMessageLine); } - #endregion + + #endregion Logging Stuff } } \ No newline at end of file diff --git a/src/kOS/Suffixed/AddonList.cs b/src/kOS/Suffixed/AddonList.cs index 156d4f472..873e0bab2 100644 --- a/src/kOS/Suffixed/AddonList.cs +++ b/src/kOS/Suffixed/AddonList.cs @@ -20,6 +20,7 @@ private void InitializeSuffixes() AddSuffix("KAC", new Suffix(() => new AddOns.KerbalAlarmClock.Addon(shared))); AddSuffix("RT", new Suffix(() => new AddOns.RemoteTech.Addon(shared))); AddSuffix("AGX", new Suffix(() => new AddOns.ActionGroupsExtended.Addon(shared))); + AddSuffix("IR", new Suffix(() => new AddOns.InfernalRobotics.Addon(shared))); } public override string ToString() diff --git a/src/kOS/kOS.csproj b/src/kOS/kOS.csproj index 28965c4d4..2ec5f634d 100644 --- a/src/kOS/kOS.csproj +++ b/src/kOS/kOS.csproj @@ -52,7 +52,6 @@ - @@ -173,6 +172,7 @@ + From 736675d2b22c9d73f1e1cda50d5fd63a9adf6983 Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Sat, 25 Apr 2015 00:24:58 -0500 Subject: [PATCH 433/446] temp checkin so hvacengi can try it. --- src/kOS.Safe/Compilation/KS/Compiler.cs | 4 +- src/kOS.Safe/Compilation/Opcode.cs | 29 +++++-- src/kOS.Safe/Compilation/ProgramBuilder.cs | 4 +- .../Exceptions/KOSInvalidDelegateContext.cs | 29 +++++++ src/kOS.Safe/Execution/ICpu.cs | 3 +- src/kOS.Safe/Execution/IProgramContext.cs | 20 +++++ src/kOS.Safe/Execution/IUserDelegate.cs | 1 + src/kOS.Safe/Execution/UserDelegate.cs | 5 +- src/kOS.Safe/kOS.Safe.csproj | 2 + src/kOS/Execution/CPU.cs | 25 +++++-- src/kOS/Execution/ProgramContext.cs | 75 +++++++------------ 11 files changed, 133 insertions(+), 64 deletions(-) create mode 100644 src/kOS.Safe/Exceptions/KOSInvalidDelegateContext.cs create mode 100644 src/kOS.Safe/Execution/IProgramContext.cs diff --git a/src/kOS.Safe/Compilation/KS/Compiler.cs b/src/kOS.Safe/Compilation/KS/Compiler.cs index bab12216c..b16a87c9f 100644 --- a/src/kOS.Safe/Compilation/KS/Compiler.cs +++ b/src/kOS.Safe/Compilation/KS/Compiler.cs @@ -1944,7 +1944,7 @@ private void AddFunctionJumpVars(ParseNode node) // methods and functions, and always has exactly one copy in memory whether there are // one, many, or zero "instances" of it present in scope at the moment. AddOpcode(new OpcodePush(func.ScopelessPointerIdentifier)); - AddOpcode(new OpcodePushRelocateLater(null), func.GetFuncLabel()); + AddOpcode(new OpcodePushDelegateRelocateLater(null,false), func.GetFuncLabel()); if (node == null) // global scope, so unconditionally use a normal Store: AddOpcode(new OpcodeStore()); // else @@ -1971,7 +1971,7 @@ private void VisitLockStatement(ParseNode node, StorageModifier whereToStore) string functionLabel = lockObject.GetUserFunctionLabel(expressionHash); // lock variable AddOpcode(new OpcodePush(lockObject.ScopelessPointerIdentifier)); - AddOpcode(new OpcodePushDelegateRelocateLater(null), functionLabel); + AddOpcode(new OpcodePushDelegateRelocateLater(null,true), functionLabel); AddOpcode(CreateAppropriateStoreCode(whereToStore, allowLazyGlobal)); if (lockObject.IsSystemLock()) diff --git a/src/kOS.Safe/Compilation/Opcode.cs b/src/kOS.Safe/Compilation/Opcode.cs index 88da26605..5c81b630d 100644 --- a/src/kOS.Safe/Compilation/Opcode.cs +++ b/src/kOS.Safe/Compilation/Opcode.cs @@ -1231,6 +1231,7 @@ public override void Execute(ICpu cpu) cpu.PushAboveStack(contextRecord); if (userDelegate != null) { + cpu.AssertValidDelegateCall(userDelegate); // Reverse-push the closure's scope record, just after the function return context got put on the stack. for (int i = userDelegate.Closure.Count - 1 ; i >= 0 ; --i) cpu.PushAboveStack(userDelegate.Closure[i]); @@ -1739,13 +1740,16 @@ public class OpcodePushDelegate : Opcode { [MLField(1,false)] private int EntryPoint { get; set; } + [MLField(2,false)] + private bool WithClosure { get; set; } protected override string Name { get { return "pushdelegate"; } } public override ByteCode Code { get { return ByteCode.PUSHDELEGATE; } } - public OpcodePushDelegate(int entryPoint) + public OpcodePushDelegate(int entryPoint, bool withClosure) { EntryPoint = entryPoint; + WithClosure = withClosure; } /// @@ -1756,14 +1760,15 @@ protected OpcodePushDelegate() { } public override void PopulateFromMLFields(List fields) { // Expect fields in the same order as the [MLField] properties of this class: - if (fields == null || fields.Count<1) - throw new Exception("Saved field in ML file for OpcodePush seems to be missing. Version mismatch?"); + if (fields == null || fields.Count<2) + throw new Exception("Saved field in ML file for OpcodePushDelegate seems to be missing. Version mismatch?"); EntryPoint = (int)fields[0]; + WithClosure = (bool)fields[1]; } public override void Execute(ICpu cpu) { - IUserDelegate pushMe = cpu.MakeUserDelegate(EntryPoint); + IUserDelegate pushMe = cpu.MakeUserDelegate(EntryPoint, WithClosure); cpu.PushStack(pushMe); } @@ -1779,17 +1784,29 @@ public override string ToString() /// public class OpcodePushDelegateRelocateLater : OpcodePushRelocateLater { + [MLField(1,false)] + public bool WithClosure { get; set; } + protected override string Name { get { return "PushDelegateRelocateLater"; } } public override ByteCode Code { get { return ByteCode.PUSHDELEGATERELOCATELATER; } } - public OpcodePushDelegateRelocateLater(string destLabel) : base(destLabel) + public OpcodePushDelegateRelocateLater(string destLabel, bool withClosure) : base(destLabel) { + WithClosure = withClosure; } /// /// This variant of the constructor is just for ML file save/load to use. /// - protected OpcodePushDelegateRelocateLater() : base() { } + protected OpcodePushDelegateRelocateLater() : base() {} + + public override void PopulateFromMLFields(List fields) + { + // Expect fields in the same order as the [MLField] properties of this class: + if (fields == null || fields.Count<1) + throw new Exception("Saved field in ML file for OpcodePushDelegateRelocatelater seems to be missing. Version mismatch?"); + WithClosure = (bool)fields[0]; + } } #endregion diff --git a/src/kOS.Safe/Compilation/ProgramBuilder.cs b/src/kOS.Safe/Compilation/ProgramBuilder.cs index a3761f6fd..d4a3f70ce 100644 --- a/src/kOS.Safe/Compilation/ProgramBuilder.cs +++ b/src/kOS.Safe/Compilation/ProgramBuilder.cs @@ -132,7 +132,9 @@ private void ReplaceLabels(List program) // Replace the OpcodePushRelocateLater with the proper OpcodePush: Opcode newOp; if (opcode is OpcodePushDelegateRelocateLater) - newOp = new OpcodePushDelegate(destinationIndex); + { + newOp = new OpcodePushDelegate(destinationIndex, ((OpcodePushDelegateRelocateLater)opcode).WithClosure); + } else newOp = new OpcodePush(destinationIndex); newOp.SourceName = opcode.SourceName; diff --git a/src/kOS.Safe/Exceptions/KOSInvalidDelegateContext.cs b/src/kOS.Safe/Exceptions/KOSInvalidDelegateContext.cs new file mode 100644 index 000000000..457ff1e93 --- /dev/null +++ b/src/kOS.Safe/Exceptions/KOSInvalidDelegateContext.cs @@ -0,0 +1,29 @@ +using System; + +namespace kOS.Safe.Exceptions +{ + /// + /// Thrown when you attempt to call a user delegate from an invalid context + /// where it cannot access the delegate from. + /// + public class KOSInvalidDelegateContext : KOSException + { + private const string TERSE_MSG_FMT = "Cannot call this lock or function from {0} when it was declared in {1}."; + private const string HELP_URL = "http://ksp-kos.github.io/KOS_DOC/language/user_functions.html#functions-and-the-terminal-interpreter"; + + public KOSInvalidDelegateContext(string currentContextName, string intendedContextName) : + base(String.Format(TERSE_MSG_FMT, currentContextName, intendedContextName)) + { + } + + public virtual string VerboseMessage + { + get { return base.Message; } + } + + public virtual string HelpURL + { + get { return HELP_URL; } + } + } +} diff --git a/src/kOS.Safe/Execution/ICpu.cs b/src/kOS.Safe/Execution/ICpu.cs index d51d8bd5b..60664fc0c 100644 --- a/src/kOS.Safe/Execution/ICpu.cs +++ b/src/kOS.Safe/Execution/ICpu.cs @@ -11,7 +11,8 @@ public interface ICpu : IFixedUpdateObserver void PushAboveStack(object thing); object PopAboveStack(int howMany); List GetCurrentClosure(); - IUserDelegate MakeUserDelegate(int entryPoint); + IUserDelegate MakeUserDelegate(int entryPoint, bool withClosure); + void AssertValidDelegateCall(IUserDelegate userDelegate); object GetValue(object testValue, bool barewordOkay = false); object PopValue(bool barewordOkay = false); object PeekValue(int digDepth, bool barewordOkay = false); diff --git a/src/kOS.Safe/Execution/IProgramContext.cs b/src/kOS.Safe/Execution/IProgramContext.cs new file mode 100644 index 000000000..38416b39d --- /dev/null +++ b/src/kOS.Safe/Execution/IProgramContext.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using kOS.Safe.Compilation; +using kOS.Safe.Execution; + +namespace kOS.Safe.Execution +{ + public interface IProgramContext + { + void AddParts(IEnumerable parts); + int AddObjectParts(IEnumerable parts); + void ToggleFlyByWire(string paramName, bool enabled); + List GetCodeFragment(int contextLines); + List GetCodeFragment(int start, int stop); + List Program { get; set; } + int InstructionPointer { get; set; } + List Triggers { get; set; } + bool Silent { get; set; } + } +} diff --git a/src/kOS.Safe/Execution/IUserDelegate.cs b/src/kOS.Safe/Execution/IUserDelegate.cs index c713fbf3a..609f19f4b 100644 --- a/src/kOS.Safe/Execution/IUserDelegate.cs +++ b/src/kOS.Safe/Execution/IUserDelegate.cs @@ -9,6 +9,7 @@ namespace kOS.Safe.Execution /// public interface IUserDelegate { + IProgramContext ProgContext {get;} int EntryPoint {get;} List Closure {get;} } diff --git a/src/kOS.Safe/Execution/UserDelegate.cs b/src/kOS.Safe/Execution/UserDelegate.cs index 8d670286f..d7fb62346 100644 --- a/src/kOS.Safe/Execution/UserDelegate.cs +++ b/src/kOS.Safe/Execution/UserDelegate.cs @@ -9,6 +9,7 @@ namespace kOS.Safe.Execution /// public class UserDelegate : IUserDelegate { + public IProgramContext ProgContext {get; private set;} public int EntryPoint {get; private set;} private readonly ICpu cpu; public List Closure {get; private set;} @@ -18,13 +19,15 @@ public class UserDelegate : IUserDelegate /// the entry point location of the function to call. /// /// the CPU on which this program is running. + /// The IProgramContext in which the entryPoint is stored. Entry point 27 in the interpreter is not the same as entrypoint 27 in program context. /// instruction address where OpcodeCall should jump to to call the function. /// If true, then a snapshot of the current scoping stack, and thus a persistent ref to its variables, /// will be kept in the delegate so it can be called later as a callback with closure. Set to false if the /// function is only getting called instantly using whatever the scope is at the time of the call. - public UserDelegate(ICpu cpu, int entryPoint, bool useClosure) + public UserDelegate(ICpu cpu, IProgramContext context, int entryPoint, bool useClosure) { this.cpu = cpu; + ProgContext = context; EntryPoint = entryPoint; if (useClosure) CaptureClosure(); diff --git a/src/kOS.Safe/kOS.Safe.csproj b/src/kOS.Safe/kOS.Safe.csproj index d11d7a323..709cd89fc 100644 --- a/src/kOS.Safe/kOS.Safe.csproj +++ b/src/kOS.Safe/kOS.Safe.csproj @@ -95,6 +95,7 @@ + @@ -117,6 +118,7 @@ + diff --git a/src/kOS/Execution/CPU.cs b/src/kOS/Execution/CPU.cs index cb163de57..5dfd2e54c 100644 --- a/src/kOS/Execution/CPU.cs +++ b/src/kOS/Execution/CPU.cs @@ -226,19 +226,21 @@ public List GetCurrentClosure() /// Build a delegate call for the given function entry point, in which it will capture a closure of the current /// runtime scoping state to be used when that function gets called later by OpcodeCall: /// + /// Integer location in memory to jump to to start the call + /// Should the closure be captured for this delegate or ignored /// The delegate object you can store in a variable. - public IUserDelegate MakeUserDelegate(int entryPoint) + public IUserDelegate MakeUserDelegate(int entryPoint, bool withClosure) { - return new UserDelegate(this, entryPoint, true); + return new UserDelegate(this, currentContext, entryPoint, withClosure); } // only two contexts exist now, one for the interpreter and one for the programs - public ProgramContext GetInterpreterContext() + public IProgramContext GetInterpreterContext() { return contexts[0]; } - public ProgramContext SwitchToProgramContext() + public IProgramContext SwitchToProgramContext() { if (contexts.Count == 1) { @@ -376,6 +378,19 @@ public void MoveStackPointer(int delta) stack.MoveStackPointer(delta); } + /// Throw exception if the user delegate is not one the CPU can call right now. + /// The userdelegate being checked + /// thrown if the cpu is in a state where it can't call this delegate. + public void AssertValidDelegateCall(IUserDelegate userDelegate) + { + if (userDelegate.ProgContext != currentContext) { + throw new KOSInvalidDelegateContext( + (currentContext == contexts[0] ? "the interpreter" : "a program" ), + (currentContext == contexts[0] ? "a program" : "the interpreter" ) + ); + } + } + /// /// Gets the dictionary N levels of nesting down the dictionary stack, /// where zero is the current localmost level. @@ -995,7 +1010,7 @@ private void ContinueExecution() SafeHouse.Logger.Log(executeLog.ToString()); } - private bool ExecuteInstruction(ProgramContext context) + private bool ExecuteInstruction(IProgramContext context) { bool DEBUG_EACH_OPCODE = false; diff --git a/src/kOS/Execution/ProgramContext.cs b/src/kOS/Execution/ProgramContext.cs index 821f97250..40f5081c7 100644 --- a/src/kOS/Execution/ProgramContext.cs +++ b/src/kOS/Execution/ProgramContext.cs @@ -2,10 +2,11 @@ using System.Collections.Generic; using kOS.Binding; using kOS.Safe.Compilation; +using kOS.Safe.Execution; namespace kOS.Execution { - public class ProgramContext + public class ProgramContext : IProgramContext { private readonly Dictionary flyByWire; private readonly ProgramBuilder builder; @@ -13,8 +14,8 @@ public class ProgramContext public List Program { get; set; } public int InstructionPointer { get; set; } public List Triggers { get; set; } - public bool Silent { get; set; } - + public bool Silent { get; set; } + public ProgramContext(bool interpreterContext) { Program = new List(); @@ -24,8 +25,7 @@ public ProgramContext(bool interpreterContext) flyByWire = new Dictionary(); } - public ProgramContext(bool interpreterContext, List program) - : this(interpreterContext) + public ProgramContext(bool interpreterContext, List program) : this(interpreterContext) { Program = program; } @@ -45,38 +45,31 @@ public int AddObjectParts(IEnumerable parts) UpdateProgram(newProgram); return entryPointAddress; } - + private void UpdateProgram(List newProgram) { - if (Program != null) - { + if (Program != null) { List oldProgram = Program; Program = newProgram; UpdateInstructionPointer(oldProgram); - } - else - { + } else { Program = newProgram; } } private void UpdateInstructionPointer(List oldProgram) { - if (oldProgram.Count > 1) - { + if (oldProgram.Count > 1) { int delta = 0; - if (InstructionPointer == (oldProgram.Count - 1)) - { + if (InstructionPointer == (oldProgram.Count - 1)) { delta = 1; } int currentInstructionId = oldProgram[InstructionPointer - delta].Id; - for (int index = 0; index < Program.Count; index++) - { - if (Program[index].Id == currentInstructionId) - { + for (int index = 0; index < Program.Count; index++) { + if (Program[index].Id == currentInstructionId) { InstructionPointer = index + delta; break; } @@ -86,22 +79,17 @@ private void UpdateInstructionPointer(List oldProgram) public void ToggleFlyByWire(string paramName, bool enabled) { - if (!flyByWire.ContainsKey(paramName)) - { + if (!flyByWire.ContainsKey(paramName)) { flyByWire.Add(paramName, enabled); - } - else - { + } else { flyByWire[paramName] = enabled; } } public void DisableActiveFlyByWire(BindingManager manager) { - foreach (KeyValuePair kvp in flyByWire) - { - if (kvp.Value) - { + foreach (KeyValuePair kvp in flyByWire) { + if (kvp.Value) { manager.ToggleFlyByWire(kvp.Key, false); } } @@ -109,36 +97,27 @@ public void DisableActiveFlyByWire(BindingManager manager) public void EnableActiveFlyByWire(BindingManager manager) { - foreach (KeyValuePair kvp in flyByWire) - { + foreach (KeyValuePair kvp in flyByWire) { manager.ToggleFlyByWire(kvp.Key, kvp.Value); } } - + public List GetCodeFragment(int contextLines) { - return GetCodeFragment( InstructionPointer - contextLines, InstructionPointer + contextLines ); + return GetCodeFragment(InstructionPointer - contextLines, InstructionPointer + contextLines); } - + public List GetCodeFragment(int start, int stop) { var codeFragment = new List(); - + const string FORMAT_STR = "{0,-20} {1,4}:{2,-3} {3:0000} {4} {5}"; - codeFragment.Add(string.Format(FORMAT_STR, "File", "Line", "Col", "IP ", "opcode", "operand" )); - codeFragment.Add(string.Format(FORMAT_STR, "----", "----", "---", "----", "---------------------", "" )); - - for (int index = start; index <= stop; index++) - { - if (index >= 0 && index < Program.Count) - { - codeFragment.Add(string.Format(FORMAT_STR, - Program[index].SourceName, - Program[index].SourceLine, - Program[index].SourceColumn, - index, - Program[index], - (index == InstructionPointer ? "<<--INSTRUCTION POINTER--" : ""))); + codeFragment.Add(string.Format(FORMAT_STR, "File", "Line", "Col", "IP ", "opcode", "operand")); + codeFragment.Add(string.Format(FORMAT_STR, "----", "----", "---", "----", "---------------------", "")); + + for (int index = start; index <= stop; index++) { + if (index >= 0 && index < Program.Count) { + codeFragment.Add(string.Format(FORMAT_STR, Program[index].SourceName, Program[index].SourceLine, Program[index].SourceColumn, index, Program[index], (index == InstructionPointer ? "<<--INSTRUCTION POINTER--" : ""))); } } From 9723fbc150d46111bef16cc80c773984b5ee0086 Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Sat, 25 Apr 2015 00:59:27 -0500 Subject: [PATCH 434/446] Edited functest7 for its out of date syntax. --- kerboscript_tests/user_functions/functest7.ks | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/kerboscript_tests/user_functions/functest7.ks b/kerboscript_tests/user_functions/functest7.ks index 9ec6c1810..01ed9f03f 100644 --- a/kerboscript_tests/user_functions/functest7.ks +++ b/kerboscript_tests/user_functions/functest7.ks @@ -1,9 +1,8 @@ // One test of the nolazyglobal keyword. -// This should work correctly. @lazyglobal off. // at the top - should be okay. -declare x to 1. // this should be fine. +local x is 1. // this should be fine. set x to 2. // this should be fine because x exists now. print "Should bomb out with error because there was no 'declare y' statement and lazyglobals disabled.". set y to 1. From d0b5c018538075baa4f5a5cdfc99e1f7edbd9029 Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Sun, 26 Apr 2015 21:56:03 -0500 Subject: [PATCH 435/446] lex fix caused weird errors - checking it to compare to develop. --- src/kOS.Safe/Compilation/KS/Scanner.cs | 108 ++++++++++++------------- src/kOS.Safe/Compilation/KS/kRISC.tpg | 108 ++++++++++++------------- 2 files changed, 108 insertions(+), 108 deletions(-) diff --git a/src/kOS.Safe/Compilation/KS/Scanner.cs b/src/kOS.Safe/Compilation/KS/Scanner.cs index cd84de946..80216f274 100644 --- a/src/kOS.Safe/Compilation/KS/Scanner.cs +++ b/src/kOS.Safe/Compilation/KS/Scanner.cs @@ -54,23 +54,23 @@ public Scanner() Patterns.Add(TokenType.POWER, regex); Tokens.Add(TokenType.POWER); - regex = new Regex(@"e"); + regex = new Regex(@"\be\b"); Patterns.Add(TokenType.E, regex); Tokens.Add(TokenType.E); - regex = new Regex(@"not"); + regex = new Regex(@"\bnot\b"); Patterns.Add(TokenType.NOT, regex); Tokens.Add(TokenType.NOT); - regex = new Regex(@"and"); + regex = new Regex(@"\band\b"); Patterns.Add(TokenType.AND, regex); Tokens.Add(TokenType.AND); - regex = new Regex(@"or"); + regex = new Regex(@"\bor\b"); Patterns.Add(TokenType.OR, regex); Tokens.Add(TokenType.OR); - regex = new Regex(@"true|false"); + regex = new Regex(@"\btrue\b|\bfalse\b"); Patterns.Add(TokenType.TRUEFALSE, regex); Tokens.Add(TokenType.TRUEFALSE); @@ -78,187 +78,187 @@ public Scanner() Patterns.Add(TokenType.COMPARATOR, regex); Tokens.Add(TokenType.COMPARATOR); - regex = new Regex(@"set"); + regex = new Regex(@"\bset\b"); Patterns.Add(TokenType.SET, regex); Tokens.Add(TokenType.SET); - regex = new Regex(@"to"); + regex = new Regex(@"\bto\b"); Patterns.Add(TokenType.TO, regex); Tokens.Add(TokenType.TO); - regex = new Regex(@"is"); + regex = new Regex(@"\bis\b"); Patterns.Add(TokenType.IS, regex); Tokens.Add(TokenType.IS); - regex = new Regex(@"if"); + regex = new Regex(@"\bif\b"); Patterns.Add(TokenType.IF, regex); Tokens.Add(TokenType.IF); - regex = new Regex(@"else"); + regex = new Regex(@"\belse\b"); Patterns.Add(TokenType.ELSE, regex); Tokens.Add(TokenType.ELSE); - regex = new Regex(@"until"); + regex = new Regex(@"\buntil\b"); Patterns.Add(TokenType.UNTIL, regex); Tokens.Add(TokenType.UNTIL); - regex = new Regex(@"lock"); + regex = new Regex(@"\block\b"); Patterns.Add(TokenType.LOCK, regex); Tokens.Add(TokenType.LOCK); - regex = new Regex(@"unlock"); + regex = new Regex(@"\bunlock\b"); Patterns.Add(TokenType.UNLOCK, regex); Tokens.Add(TokenType.UNLOCK); - regex = new Regex(@"print"); + regex = new Regex(@"\bprint\b"); Patterns.Add(TokenType.PRINT, regex); Tokens.Add(TokenType.PRINT); - regex = new Regex(@"at"); + regex = new Regex(@"\bat\b"); Patterns.Add(TokenType.AT, regex); Tokens.Add(TokenType.AT); - regex = new Regex(@"on"); + regex = new Regex(@"\bon\b"); Patterns.Add(TokenType.ON, regex); Tokens.Add(TokenType.ON); - regex = new Regex(@"toggle"); + regex = new Regex(@"\btoggle\b"); Patterns.Add(TokenType.TOGGLE, regex); Tokens.Add(TokenType.TOGGLE); - regex = new Regex(@"wait"); + regex = new Regex(@"\bwait\b"); Patterns.Add(TokenType.WAIT, regex); Tokens.Add(TokenType.WAIT); - regex = new Regex(@"when"); + regex = new Regex(@"\bwhen\b"); Patterns.Add(TokenType.WHEN, regex); Tokens.Add(TokenType.WHEN); - regex = new Regex(@"then"); + regex = new Regex(@"\bthen\b"); Patterns.Add(TokenType.THEN, regex); Tokens.Add(TokenType.THEN); - regex = new Regex(@"off"); + regex = new Regex(@"\boff\b"); Patterns.Add(TokenType.OFF, regex); Tokens.Add(TokenType.OFF); - regex = new Regex(@"stage"); + regex = new Regex(@"\bstage\b"); Patterns.Add(TokenType.STAGE, regex); Tokens.Add(TokenType.STAGE); - regex = new Regex(@"clearscreen"); + regex = new Regex(@"\bclearscreen\b"); Patterns.Add(TokenType.CLEARSCREEN, regex); Tokens.Add(TokenType.CLEARSCREEN); - regex = new Regex(@"add"); + regex = new Regex(@"\badd\b"); Patterns.Add(TokenType.ADD, regex); Tokens.Add(TokenType.ADD); - regex = new Regex(@"remove"); + regex = new Regex(@"\bremove\b"); Patterns.Add(TokenType.REMOVE, regex); Tokens.Add(TokenType.REMOVE); - regex = new Regex(@"log"); + regex = new Regex(@"\blog\b"); Patterns.Add(TokenType.LOG, regex); Tokens.Add(TokenType.LOG); - regex = new Regex(@"break"); + regex = new Regex(@"\bbreak\b"); Patterns.Add(TokenType.BREAK, regex); Tokens.Add(TokenType.BREAK); - regex = new Regex(@"preserve"); + regex = new Regex(@"\bpreserve\b"); Patterns.Add(TokenType.PRESERVE, regex); Tokens.Add(TokenType.PRESERVE); - regex = new Regex(@"declare"); + regex = new Regex(@"\bdeclare\b"); Patterns.Add(TokenType.DECLARE, regex); Tokens.Add(TokenType.DECLARE); - regex = new Regex(@"local"); + regex = new Regex(@"\blocal\b"); Patterns.Add(TokenType.LOCAL, regex); Tokens.Add(TokenType.LOCAL); - regex = new Regex(@"global"); + regex = new Regex(@"\bglobal\b"); Patterns.Add(TokenType.GLOBAL, regex); Tokens.Add(TokenType.GLOBAL); - regex = new Regex(@"parameter"); + regex = new Regex(@"\bparameter\b"); Patterns.Add(TokenType.PARAMETER, regex); Tokens.Add(TokenType.PARAMETER); - regex = new Regex(@"function"); + regex = new Regex(@"\bfunction\b"); Patterns.Add(TokenType.FUNCTION, regex); Tokens.Add(TokenType.FUNCTION); - regex = new Regex(@"return"); + regex = new Regex(@"\breturn\b"); Patterns.Add(TokenType.RETURN, regex); Tokens.Add(TokenType.RETURN); - regex = new Regex(@"switch"); + regex = new Regex(@"\bswitch\b"); Patterns.Add(TokenType.SWITCH, regex); Tokens.Add(TokenType.SWITCH); - regex = new Regex(@"copy"); + regex = new Regex(@"\bcopy\b"); Patterns.Add(TokenType.COPY, regex); Tokens.Add(TokenType.COPY); - regex = new Regex(@"from"); + regex = new Regex(@"\bfrom\b"); Patterns.Add(TokenType.FROM, regex); Tokens.Add(TokenType.FROM); - regex = new Regex(@"rename"); + regex = new Regex(@"\brename\b"); Patterns.Add(TokenType.RENAME, regex); Tokens.Add(TokenType.RENAME); - regex = new Regex(@"volume"); + regex = new Regex(@"\bvolume\b"); Patterns.Add(TokenType.VOLUME, regex); Tokens.Add(TokenType.VOLUME); - regex = new Regex(@"file"); + regex = new Regex(@"\bfile\b"); Patterns.Add(TokenType.FILE, regex); Tokens.Add(TokenType.FILE); - regex = new Regex(@"delete"); + regex = new Regex(@"\bdelete\b"); Patterns.Add(TokenType.DELETE, regex); Tokens.Add(TokenType.DELETE); - regex = new Regex(@"edit"); + regex = new Regex(@"\bedit\b"); Patterns.Add(TokenType.EDIT, regex); Tokens.Add(TokenType.EDIT); - regex = new Regex(@"run"); + regex = new Regex(@"\brun\b"); Patterns.Add(TokenType.RUN, regex); Tokens.Add(TokenType.RUN); - regex = new Regex(@"compile"); + regex = new Regex(@"\bcompile\b"); Patterns.Add(TokenType.COMPILE, regex); Tokens.Add(TokenType.COMPILE); - regex = new Regex(@"list"); + regex = new Regex(@"\blist\b"); Patterns.Add(TokenType.LIST, regex); Tokens.Add(TokenType.LIST); - regex = new Regex(@"reboot"); + regex = new Regex(@"\breboot\b"); Patterns.Add(TokenType.REBOOT, regex); Tokens.Add(TokenType.REBOOT); - regex = new Regex(@"shutdown"); + regex = new Regex(@"\bshutdown\b"); Patterns.Add(TokenType.SHUTDOWN, regex); Tokens.Add(TokenType.SHUTDOWN); - regex = new Regex(@"for"); + regex = new Regex(@"\bfor\b"); Patterns.Add(TokenType.FOR, regex); Tokens.Add(TokenType.FOR); - regex = new Regex(@"unset"); + regex = new Regex(@"\bunset\b"); Patterns.Add(TokenType.UNSET, regex); Tokens.Add(TokenType.UNSET); - regex = new Regex(@"batch"); + regex = new Regex(@"\bbatch\b"); Patterns.Add(TokenType.BATCH, regex); Tokens.Add(TokenType.BATCH); - regex = new Regex(@"deploy"); + regex = new Regex(@"\bdeploy\b"); Patterns.Add(TokenType.DEPLOY, regex); Tokens.Add(TokenType.DEPLOY); @@ -294,7 +294,7 @@ public Scanner() Patterns.Add(TokenType.COLON, regex); Tokens.Add(TokenType.COLON); - regex = new Regex(@"in"); + regex = new Regex(@"\bin\b"); Patterns.Add(TokenType.IN, regex); Tokens.Add(TokenType.IN); @@ -302,7 +302,7 @@ public Scanner() Patterns.Add(TokenType.ARRAYINDEX, regex); Tokens.Add(TokenType.ARRAYINDEX); - regex = new Regex(@"all"); + regex = new Regex(@"\ball\b"); Patterns.Add(TokenType.ALL, regex); Tokens.Add(TokenType.ALL); @@ -334,7 +334,7 @@ public Scanner() Patterns.Add(TokenType.ATSIGN, regex); Tokens.Add(TokenType.ATSIGN); - regex = new Regex(@"lazyglobal"); + regex = new Regex(@"\blazyglobal\b"); Patterns.Add(TokenType.LAZYGLOBAL, regex); Tokens.Add(TokenType.LAZYGLOBAL); diff --git a/src/kOS.Safe/Compilation/KS/kRISC.tpg b/src/kOS.Safe/Compilation/KS/kRISC.tpg index 88b9f262e..154027f4d 100644 --- a/src/kOS.Safe/Compilation/KS/kRISC.tpg +++ b/src/kOS.Safe/Compilation/KS/kRISC.tpg @@ -7,60 +7,60 @@ PLUSMINUS -> @"(\+|-)"; MULT -> @"\*"; DIV -> @"/"; POWER -> @"\^"; -E -> @"e"; +E -> @"\be\b"; //Logic -NOT -> @"not"; -AND -> @"and"; -OR -> @"or"; -TRUEFALSE -> @"true|false"; +NOT -> @"\bnot\b"; +AND -> @"\band\b"; +OR -> @"\bor\b"; +TRUEFALSE -> @"\btrue\b|\bfalse\b"; COMPARATOR -> @"<>|>=|<=|=|>|<"; //Instructions tokens -SET -> @"set"; -TO -> @"to"; -IS -> @"is"; -IF -> @"if"; -ELSE -> @"else"; -UNTIL -> @"until"; -LOCK -> @"lock"; -UNLOCK -> @"unlock"; -PRINT -> @"print"; -AT -> @"at"; -ON -> @"on"; -TOGGLE -> @"toggle"; -WAIT -> @"wait"; -WHEN -> @"when"; -THEN -> @"then"; -OFF -> @"off"; -STAGE -> @"stage"; -CLEARSCREEN -> @"clearscreen"; -ADD -> @"add"; -REMOVE -> @"remove"; -LOG -> @"log"; -BREAK -> @"break"; -PRESERVE -> @"preserve"; -DECLARE -> @"declare"; -LOCAL -> @"local"; -GLOBAL -> @"global"; -PARAMETER -> @"parameter"; -FUNCTION -> @"function"; -RETURN -> @"return"; -SWITCH -> @"switch"; -COPY -> @"copy"; -FROM -> @"from"; -RENAME -> @"rename"; -VOLUME -> @"volume"; -FILE -> @"file"; -DELETE -> @"delete"; -EDIT -> @"edit"; -RUN -> @"run"; -COMPILE -> @"compile"; -LIST -> @"list"; -REBOOT -> @"reboot"; -SHUTDOWN -> @"shutdown"; -FOR -> @"for"; -UNSET -> @"unset"; -BATCH -> @"batch"; -DEPLOY -> @"deploy"; +SET -> @"\bset\b"; +TO -> @"\bto\b"; +IS -> @"\bis\b"; +IF -> @"\bif\b"; +ELSE -> @"\belse\b"; +UNTIL -> @"\buntil\b"; +LOCK -> @"\block\b"; +UNLOCK -> @"\bunlock\b"; +PRINT -> @"\bprint\b"; +AT -> @"\bat\b"; +ON -> @"\bon\b"; +TOGGLE -> @"\btoggle\b"; +WAIT -> @"\bwait\b"; +WHEN -> @"\bwhen\b"; +THEN -> @"\bthen\b"; +OFF -> @"\boff\b"; +STAGE -> @"\bstage\b"; +CLEARSCREEN -> @"\bclearscreen\b"; +ADD -> @"\badd\b"; +REMOVE -> @"\bremove\b"; +LOG -> @"\blog\b"; +BREAK -> @"\bbreak\b"; +PRESERVE -> @"\bpreserve\b"; +DECLARE -> @"\bdeclare\b"; +LOCAL -> @"\blocal\b"; +GLOBAL -> @"\bglobal\b"; +PARAMETER -> @"\bparameter\b"; +FUNCTION -> @"\bfunction\b"; +RETURN -> @"\breturn\b"; +SWITCH -> @"\bswitch\b"; +COPY -> @"\bcopy\b"; +FROM -> @"\bfrom\b"; +RENAME -> @"\brename\b"; +VOLUME -> @"\bvolume\b"; +FILE -> @"\bfile\b"; +DELETE -> @"\bdelete\b"; +EDIT -> @"\bedit\b"; +RUN -> @"\brun\b"; +COMPILE -> @"\bcompile\b"; +LIST -> @"\blist\b"; +REBOOT -> @"\breboot\b"; +SHUTDOWN -> @"\bshutdown\b"; +FOR -> @"\bfor\b"; +UNSET -> @"\bunset\b"; +BATCH -> @"\bbatch\b"; +DEPLOY -> @"\bdeploy\b"; //Generic BRACKETOPEN -> @"\("; BRACKETCLOSE -> @"\)"; @@ -70,9 +70,9 @@ SQUAREOPEN -> @"\["; SQUARECLOSE -> @"\]"; COMMA -> @","; COLON -> @":"; -IN -> @"in"; +IN -> @"\bin\b"; ARRAYINDEX -> @"#"; -ALL -> @"all"; +ALL -> @"\ball\b"; IDENTIFIER -> @"[a-z_][a-z0-9_]*"; FILEIDENT -> @"[a-z_][a-z0-9_]*(\.[a-z0-9_][a-z0-9_]*)*"; INTEGER -> @"[0-9]+"; @@ -81,7 +81,7 @@ STRING -> @"@?\""(\""\""|[^\""])*\"""; EOI -> @"\."; //Compiler Directives ATSIGN -> @"@"; -LAZYGLOBAL -> @"lazyglobal"; +LAZYGLOBAL -> @"\blazyglobal\b"; //Special EOF -> @"^$"; [Skip] From bd63a8f6b4e621aa38176f00ef9ce78ad58f46a0 Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Sun, 26 Apr 2015 22:33:40 -0500 Subject: [PATCH 436/446] fixed minor warning about virtual/override. --- src/kOS.Safe/Exceptions/KOSInvalidDelegateContext.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/kOS.Safe/Exceptions/KOSInvalidDelegateContext.cs b/src/kOS.Safe/Exceptions/KOSInvalidDelegateContext.cs index 457ff1e93..63d5fc426 100644 --- a/src/kOS.Safe/Exceptions/KOSInvalidDelegateContext.cs +++ b/src/kOS.Safe/Exceptions/KOSInvalidDelegateContext.cs @@ -16,12 +16,12 @@ public KOSInvalidDelegateContext(string currentContextName, string intendedConte { } - public virtual string VerboseMessage + public override string VerboseMessage { get { return base.Message; } } - public virtual string HelpURL + public override string HelpURL { get { return HELP_URL; } } From 2006d16125bc4b0e121dc542948c44577a36db53 Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Sun, 26 Apr 2015 23:09:47 -0500 Subject: [PATCH 437/446] Resolves #893 - removed Batch and Deploy keywords --- src/kOS.Safe/Compilation/KS/Compiler.cs | 18 -- src/kOS.Safe/Compilation/KS/ParseTree.cs | 20 --- src/kOS.Safe/Compilation/KS/Parser.cs | 82 +-------- src/kOS.Safe/Compilation/KS/Scanner.cs | 204 +++++++++++------------ src/kOS.Safe/Compilation/KS/kRISC.tpg | 6 - 5 files changed, 101 insertions(+), 229 deletions(-) diff --git a/src/kOS.Safe/Compilation/KS/Compiler.cs b/src/kOS.Safe/Compilation/KS/Compiler.cs index b16a87c9f..6fa8e53b4 100644 --- a/src/kOS.Safe/Compilation/KS/Compiler.cs +++ b/src/kOS.Safe/Compilation/KS/Compiler.cs @@ -983,12 +983,6 @@ private void VisitNode(ParseNode node) case TokenType.unset_stmt: VisitUnsetStatement(node); break; - case TokenType.batch_stmt: - VisitBatchStatement(node); - break; - case TokenType.deploy_stmt: - VisitDeployStatement(node); - break; case TokenType.arglist: VisitArgList(node); break; @@ -2654,18 +2648,6 @@ private void VisitUnsetStatement(ParseNode node) AddOpcode(new OpcodeUnset()); } - private void VisitBatchStatement(ParseNode node) - { - NodeStartHousekeeping(node); - throw new Exception("Batch mode can only be used when in immediate mode."); - } - - private void VisitDeployStatement(ParseNode node) - { - NodeStartHousekeeping(node); - throw new Exception("Batch mode can only be used when in immediate mode."); - } - private void VisitIdentifierLedStatement(ParseNode node) { NodeStartHousekeeping(node); diff --git a/src/kOS.Safe/Compilation/KS/ParseTree.cs b/src/kOS.Safe/Compilation/KS/ParseTree.cs index 68eee8f0f..d0de9e327 100644 --- a/src/kOS.Safe/Compilation/KS/ParseTree.cs +++ b/src/kOS.Safe/Compilation/KS/ParseTree.cs @@ -301,12 +301,6 @@ internal object Eval(ParseTree tree, params object[] paramlist) case TokenType.unset_stmt: Value = Evalunset_stmt(tree, paramlist); break; - case TokenType.batch_stmt: - Value = Evalbatch_stmt(tree, paramlist); - break; - case TokenType.deploy_stmt: - Value = Evaldeploy_stmt(tree, paramlist); - break; case TokenType.arglist: Value = Evalarglist(tree, paramlist); break; @@ -660,20 +654,6 @@ protected virtual object Evalunset_stmt(ParseTree tree, params object[] paramlis return null; } - protected virtual object Evalbatch_stmt(ParseTree tree, params object[] paramlist) - { - foreach (var node in Nodes) - node.Eval(tree, paramlist); - return null; - } - - protected virtual object Evaldeploy_stmt(ParseTree tree, params object[] paramlist) - { - foreach (var node in Nodes) - node.Eval(tree, paramlist); - return null; - } - protected virtual object Evalarglist(ParseTree tree, params object[] paramlist) { foreach (var node in Nodes) diff --git a/src/kOS.Safe/Compilation/KS/Parser.cs b/src/kOS.Safe/Compilation/KS/Parser.cs index a813113f9..84d245e64 100644 --- a/src/kOS.Safe/Compilation/KS/Parser.cs +++ b/src/kOS.Safe/Compilation/KS/Parser.cs @@ -47,7 +47,7 @@ private void ParseStart(ParseNode parent) - tok = scanner.LookAhead(TokenType.SET, TokenType.IF, TokenType.UNTIL, TokenType.UNLOCK, TokenType.PRINT, TokenType.ON, TokenType.TOGGLE, TokenType.WAIT, TokenType.WHEN, TokenType.STAGE, TokenType.CLEARSCREEN, TokenType.ADD, TokenType.REMOVE, TokenType.LOG, TokenType.BREAK, TokenType.PRESERVE, TokenType.PARAMETER, TokenType.FUNCTION, TokenType.LOCK, TokenType.DECLARE, TokenType.LOCAL, TokenType.GLOBAL, TokenType.RETURN, TokenType.SWITCH, TokenType.COPY, TokenType.RENAME, TokenType.DELETE, TokenType.EDIT, TokenType.RUN, TokenType.COMPILE, TokenType.LIST, TokenType.REBOOT, TokenType.SHUTDOWN, TokenType.FOR, TokenType.UNSET, TokenType.BATCH, TokenType.DEPLOY, TokenType.CURLYOPEN, TokenType.INTEGER, TokenType.DOUBLE, TokenType.TRUEFALSE, TokenType.IDENTIFIER, TokenType.FILEIDENT, TokenType.BRACKETOPEN, TokenType.STRING, TokenType.ATSIGN); + tok = scanner.LookAhead(TokenType.SET, TokenType.IF, TokenType.UNTIL, TokenType.UNLOCK, TokenType.PRINT, TokenType.ON, TokenType.TOGGLE, TokenType.WAIT, TokenType.WHEN, TokenType.STAGE, TokenType.CLEARSCREEN, TokenType.ADD, TokenType.REMOVE, TokenType.LOG, TokenType.BREAK, TokenType.PRESERVE, TokenType.PARAMETER, TokenType.FUNCTION, TokenType.LOCK, TokenType.DECLARE, TokenType.LOCAL, TokenType.GLOBAL, TokenType.RETURN, TokenType.SWITCH, TokenType.COPY, TokenType.RENAME, TokenType.DELETE, TokenType.EDIT, TokenType.RUN, TokenType.COMPILE, TokenType.LIST, TokenType.REBOOT, TokenType.SHUTDOWN, TokenType.FOR, TokenType.UNSET, TokenType.CURLYOPEN, TokenType.INTEGER, TokenType.DOUBLE, TokenType.TRUEFALSE, TokenType.IDENTIFIER, TokenType.FILEIDENT, TokenType.BRACKETOPEN, TokenType.STRING, TokenType.ATSIGN); while (tok.Type == TokenType.SET || tok.Type == TokenType.IF || tok.Type == TokenType.UNTIL @@ -83,8 +83,6 @@ private void ParseStart(ParseNode parent) || tok.Type == TokenType.SHUTDOWN || tok.Type == TokenType.FOR || tok.Type == TokenType.UNSET - || tok.Type == TokenType.BATCH - || tok.Type == TokenType.DEPLOY || tok.Type == TokenType.CURLYOPEN || tok.Type == TokenType.INTEGER || tok.Type == TokenType.DOUBLE @@ -96,7 +94,7 @@ private void ParseStart(ParseNode parent) || tok.Type == TokenType.ATSIGN) { Parseinstruction(node); - tok = scanner.LookAhead(TokenType.SET, TokenType.IF, TokenType.UNTIL, TokenType.UNLOCK, TokenType.PRINT, TokenType.ON, TokenType.TOGGLE, TokenType.WAIT, TokenType.WHEN, TokenType.STAGE, TokenType.CLEARSCREEN, TokenType.ADD, TokenType.REMOVE, TokenType.LOG, TokenType.BREAK, TokenType.PRESERVE, TokenType.PARAMETER, TokenType.FUNCTION, TokenType.LOCK, TokenType.DECLARE, TokenType.LOCAL, TokenType.GLOBAL, TokenType.RETURN, TokenType.SWITCH, TokenType.COPY, TokenType.RENAME, TokenType.DELETE, TokenType.EDIT, TokenType.RUN, TokenType.COMPILE, TokenType.LIST, TokenType.REBOOT, TokenType.SHUTDOWN, TokenType.FOR, TokenType.UNSET, TokenType.BATCH, TokenType.DEPLOY, TokenType.CURLYOPEN, TokenType.INTEGER, TokenType.DOUBLE, TokenType.TRUEFALSE, TokenType.IDENTIFIER, TokenType.FILEIDENT, TokenType.BRACKETOPEN, TokenType.STRING, TokenType.ATSIGN); + tok = scanner.LookAhead(TokenType.SET, TokenType.IF, TokenType.UNTIL, TokenType.UNLOCK, TokenType.PRINT, TokenType.ON, TokenType.TOGGLE, TokenType.WAIT, TokenType.WHEN, TokenType.STAGE, TokenType.CLEARSCREEN, TokenType.ADD, TokenType.REMOVE, TokenType.LOG, TokenType.BREAK, TokenType.PRESERVE, TokenType.PARAMETER, TokenType.FUNCTION, TokenType.LOCK, TokenType.DECLARE, TokenType.LOCAL, TokenType.GLOBAL, TokenType.RETURN, TokenType.SWITCH, TokenType.COPY, TokenType.RENAME, TokenType.DELETE, TokenType.EDIT, TokenType.RUN, TokenType.COMPILE, TokenType.LIST, TokenType.REBOOT, TokenType.SHUTDOWN, TokenType.FOR, TokenType.UNSET, TokenType.CURLYOPEN, TokenType.INTEGER, TokenType.DOUBLE, TokenType.TRUEFALSE, TokenType.IDENTIFIER, TokenType.FILEIDENT, TokenType.BRACKETOPEN, TokenType.STRING, TokenType.ATSIGN); } @@ -131,7 +129,7 @@ private void Parseinstruction_block(ParseNode parent) } - tok = scanner.LookAhead(TokenType.SET, TokenType.IF, TokenType.UNTIL, TokenType.UNLOCK, TokenType.PRINT, TokenType.ON, TokenType.TOGGLE, TokenType.WAIT, TokenType.WHEN, TokenType.STAGE, TokenType.CLEARSCREEN, TokenType.ADD, TokenType.REMOVE, TokenType.LOG, TokenType.BREAK, TokenType.PRESERVE, TokenType.PARAMETER, TokenType.FUNCTION, TokenType.LOCK, TokenType.DECLARE, TokenType.LOCAL, TokenType.GLOBAL, TokenType.RETURN, TokenType.SWITCH, TokenType.COPY, TokenType.RENAME, TokenType.DELETE, TokenType.EDIT, TokenType.RUN, TokenType.COMPILE, TokenType.LIST, TokenType.REBOOT, TokenType.SHUTDOWN, TokenType.FOR, TokenType.UNSET, TokenType.BATCH, TokenType.DEPLOY, TokenType.CURLYOPEN, TokenType.INTEGER, TokenType.DOUBLE, TokenType.TRUEFALSE, TokenType.IDENTIFIER, TokenType.FILEIDENT, TokenType.BRACKETOPEN, TokenType.STRING, TokenType.ATSIGN); + tok = scanner.LookAhead(TokenType.SET, TokenType.IF, TokenType.UNTIL, TokenType.UNLOCK, TokenType.PRINT, TokenType.ON, TokenType.TOGGLE, TokenType.WAIT, TokenType.WHEN, TokenType.STAGE, TokenType.CLEARSCREEN, TokenType.ADD, TokenType.REMOVE, TokenType.LOG, TokenType.BREAK, TokenType.PRESERVE, TokenType.PARAMETER, TokenType.FUNCTION, TokenType.LOCK, TokenType.DECLARE, TokenType.LOCAL, TokenType.GLOBAL, TokenType.RETURN, TokenType.SWITCH, TokenType.COPY, TokenType.RENAME, TokenType.DELETE, TokenType.EDIT, TokenType.RUN, TokenType.COMPILE, TokenType.LIST, TokenType.REBOOT, TokenType.SHUTDOWN, TokenType.FOR, TokenType.UNSET, TokenType.CURLYOPEN, TokenType.INTEGER, TokenType.DOUBLE, TokenType.TRUEFALSE, TokenType.IDENTIFIER, TokenType.FILEIDENT, TokenType.BRACKETOPEN, TokenType.STRING, TokenType.ATSIGN); while (tok.Type == TokenType.SET || tok.Type == TokenType.IF || tok.Type == TokenType.UNTIL @@ -167,8 +165,6 @@ private void Parseinstruction_block(ParseNode parent) || tok.Type == TokenType.SHUTDOWN || tok.Type == TokenType.FOR || tok.Type == TokenType.UNSET - || tok.Type == TokenType.BATCH - || tok.Type == TokenType.DEPLOY || tok.Type == TokenType.CURLYOPEN || tok.Type == TokenType.INTEGER || tok.Type == TokenType.DOUBLE @@ -180,7 +176,7 @@ private void Parseinstruction_block(ParseNode parent) || tok.Type == TokenType.ATSIGN) { Parseinstruction(node); - tok = scanner.LookAhead(TokenType.SET, TokenType.IF, TokenType.UNTIL, TokenType.UNLOCK, TokenType.PRINT, TokenType.ON, TokenType.TOGGLE, TokenType.WAIT, TokenType.WHEN, TokenType.STAGE, TokenType.CLEARSCREEN, TokenType.ADD, TokenType.REMOVE, TokenType.LOG, TokenType.BREAK, TokenType.PRESERVE, TokenType.PARAMETER, TokenType.FUNCTION, TokenType.LOCK, TokenType.DECLARE, TokenType.LOCAL, TokenType.GLOBAL, TokenType.RETURN, TokenType.SWITCH, TokenType.COPY, TokenType.RENAME, TokenType.DELETE, TokenType.EDIT, TokenType.RUN, TokenType.COMPILE, TokenType.LIST, TokenType.REBOOT, TokenType.SHUTDOWN, TokenType.FOR, TokenType.UNSET, TokenType.BATCH, TokenType.DEPLOY, TokenType.CURLYOPEN, TokenType.INTEGER, TokenType.DOUBLE, TokenType.TRUEFALSE, TokenType.IDENTIFIER, TokenType.FILEIDENT, TokenType.BRACKETOPEN, TokenType.STRING, TokenType.ATSIGN); + tok = scanner.LookAhead(TokenType.SET, TokenType.IF, TokenType.UNTIL, TokenType.UNLOCK, TokenType.PRINT, TokenType.ON, TokenType.TOGGLE, TokenType.WAIT, TokenType.WHEN, TokenType.STAGE, TokenType.CLEARSCREEN, TokenType.ADD, TokenType.REMOVE, TokenType.LOG, TokenType.BREAK, TokenType.PRESERVE, TokenType.PARAMETER, TokenType.FUNCTION, TokenType.LOCK, TokenType.DECLARE, TokenType.LOCAL, TokenType.GLOBAL, TokenType.RETURN, TokenType.SWITCH, TokenType.COPY, TokenType.RENAME, TokenType.DELETE, TokenType.EDIT, TokenType.RUN, TokenType.COMPILE, TokenType.LIST, TokenType.REBOOT, TokenType.SHUTDOWN, TokenType.FOR, TokenType.UNSET, TokenType.CURLYOPEN, TokenType.INTEGER, TokenType.DOUBLE, TokenType.TRUEFALSE, TokenType.IDENTIFIER, TokenType.FILEIDENT, TokenType.BRACKETOPEN, TokenType.STRING, TokenType.ATSIGN); } @@ -217,7 +213,7 @@ private void Parseinstruction(ParseNode parent) ParseNode node = parent.CreateNode(scanner.GetToken(TokenType.instruction), "instruction"); parent.Nodes.Add(node); - tok = scanner.LookAhead(TokenType.SET, TokenType.IF, TokenType.UNTIL, TokenType.UNLOCK, TokenType.PRINT, TokenType.ON, TokenType.TOGGLE, TokenType.WAIT, TokenType.WHEN, TokenType.STAGE, TokenType.CLEARSCREEN, TokenType.ADD, TokenType.REMOVE, TokenType.LOG, TokenType.BREAK, TokenType.PRESERVE, TokenType.PARAMETER, TokenType.FUNCTION, TokenType.LOCK, TokenType.DECLARE, TokenType.LOCAL, TokenType.GLOBAL, TokenType.RETURN, TokenType.SWITCH, TokenType.COPY, TokenType.RENAME, TokenType.DELETE, TokenType.EDIT, TokenType.RUN, TokenType.COMPILE, TokenType.LIST, TokenType.REBOOT, TokenType.SHUTDOWN, TokenType.FOR, TokenType.UNSET, TokenType.BATCH, TokenType.DEPLOY, TokenType.CURLYOPEN, TokenType.INTEGER, TokenType.DOUBLE, TokenType.TRUEFALSE, TokenType.IDENTIFIER, TokenType.FILEIDENT, TokenType.BRACKETOPEN, TokenType.STRING, TokenType.ATSIGN); + tok = scanner.LookAhead(TokenType.SET, TokenType.IF, TokenType.UNTIL, TokenType.UNLOCK, TokenType.PRINT, TokenType.ON, TokenType.TOGGLE, TokenType.WAIT, TokenType.WHEN, TokenType.STAGE, TokenType.CLEARSCREEN, TokenType.ADD, TokenType.REMOVE, TokenType.LOG, TokenType.BREAK, TokenType.PRESERVE, TokenType.PARAMETER, TokenType.FUNCTION, TokenType.LOCK, TokenType.DECLARE, TokenType.LOCAL, TokenType.GLOBAL, TokenType.RETURN, TokenType.SWITCH, TokenType.COPY, TokenType.RENAME, TokenType.DELETE, TokenType.EDIT, TokenType.RUN, TokenType.COMPILE, TokenType.LIST, TokenType.REBOOT, TokenType.SHUTDOWN, TokenType.FOR, TokenType.UNSET, TokenType.CURLYOPEN, TokenType.INTEGER, TokenType.DOUBLE, TokenType.TRUEFALSE, TokenType.IDENTIFIER, TokenType.FILEIDENT, TokenType.BRACKETOPEN, TokenType.STRING, TokenType.ATSIGN); switch (tok.Type) { case TokenType.SET: @@ -315,12 +311,6 @@ private void Parseinstruction(ParseNode parent) case TokenType.UNSET: Parseunset_stmt(node); break; - case TokenType.BATCH: - Parsebatch_stmt(node); - break; - case TokenType.DEPLOY: - Parsedeploy_stmt(node); - break; case TokenType.CURLYOPEN: Parseinstruction_block(node); break; @@ -2264,68 +2254,6 @@ private void Parseunset_stmt(ParseNode parent) parent.Token.UpdateRange(node.Token); } - private void Parsebatch_stmt(ParseNode parent) - { - Token tok; - ParseNode n; - ParseNode node = parent.CreateNode(scanner.GetToken(TokenType.batch_stmt), "batch_stmt"); - parent.Nodes.Add(node); - - - - tok = scanner.Scan(TokenType.BATCH); - n = node.CreateNode(tok, tok.ToString() ); - node.Token.UpdateRange(tok); - node.Nodes.Add(n); - if (tok.Type != TokenType.BATCH) { - tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.BATCH.ToString(), 0x1001, tok)); - return; - } - - - tok = scanner.Scan(TokenType.EOI); - n = node.CreateNode(tok, tok.ToString() ); - node.Token.UpdateRange(tok); - node.Nodes.Add(n); - if (tok.Type != TokenType.EOI) { - tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.EOI.ToString(), 0x1001, tok)); - return; - } - - parent.Token.UpdateRange(node.Token); - } - - private void Parsedeploy_stmt(ParseNode parent) - { - Token tok; - ParseNode n; - ParseNode node = parent.CreateNode(scanner.GetToken(TokenType.deploy_stmt), "deploy_stmt"); - parent.Nodes.Add(node); - - - - tok = scanner.Scan(TokenType.DEPLOY); - n = node.CreateNode(tok, tok.ToString() ); - node.Token.UpdateRange(tok); - node.Nodes.Add(n); - if (tok.Type != TokenType.DEPLOY) { - tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.DEPLOY.ToString(), 0x1001, tok)); - return; - } - - - tok = scanner.Scan(TokenType.EOI); - n = node.CreateNode(tok, tok.ToString() ); - node.Token.UpdateRange(tok); - node.Nodes.Add(n); - if (tok.Type != TokenType.EOI) { - tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.EOI.ToString(), 0x1001, tok)); - return; - } - - parent.Token.UpdateRange(node.Token); - } - private void Parsearglist(ParseNode parent) { Token tok; diff --git a/src/kOS.Safe/Compilation/KS/Scanner.cs b/src/kOS.Safe/Compilation/KS/Scanner.cs index 80216f274..5f8204488 100644 --- a/src/kOS.Safe/Compilation/KS/Scanner.cs +++ b/src/kOS.Safe/Compilation/KS/Scanner.cs @@ -254,14 +254,6 @@ public Scanner() Patterns.Add(TokenType.UNSET, regex); Tokens.Add(TokenType.UNSET); - regex = new Regex(@"\bbatch\b"); - Patterns.Add(TokenType.BATCH, regex); - Tokens.Add(TokenType.BATCH); - - regex = new Regex(@"\bdeploy\b"); - Patterns.Add(TokenType.DEPLOY, regex); - Tokens.Add(TokenType.DEPLOY); - regex = new Regex(@"\("); Patterns.Add(TokenType.BRACKETOPEN, regex); Tokens.Add(TokenType.BRACKETOPEN); @@ -551,108 +543,104 @@ public enum TokenType shutdown_stmt= 40, for_stmt= 41, unset_stmt= 42, - batch_stmt= 43, - deploy_stmt= 44, - arglist = 45, - expr = 46, - and_expr= 47, - compare_expr= 48, - arith_expr= 49, - multdiv_expr= 50, - unary_expr= 51, - factor = 52, - suffix = 53, - suffix_trailer= 54, - suffixterm= 55, - suffixterm_trailer= 56, - function_trailer= 57, - array_trailer= 58, - atom = 59, - sci_number= 60, - number = 61, - varidentifier= 62, - identifier_led_stmt= 63, - identifier_led_expr= 64, + arglist = 43, + expr = 44, + and_expr= 45, + compare_expr= 46, + arith_expr= 47, + multdiv_expr= 48, + unary_expr= 49, + factor = 50, + suffix = 51, + suffix_trailer= 52, + suffixterm= 53, + suffixterm_trailer= 54, + function_trailer= 55, + array_trailer= 56, + atom = 57, + sci_number= 58, + number = 59, + varidentifier= 60, + identifier_led_stmt= 61, + identifier_led_expr= 62, //Terminal tokens: - PLUSMINUS= 65, - MULT = 66, - DIV = 67, - POWER = 68, - E = 69, - NOT = 70, - AND = 71, - OR = 72, - TRUEFALSE= 73, - COMPARATOR= 74, - SET = 75, - TO = 76, - IS = 77, - IF = 78, - ELSE = 79, - UNTIL = 80, - LOCK = 81, - UNLOCK = 82, - PRINT = 83, - AT = 84, - ON = 85, - TOGGLE = 86, - WAIT = 87, - WHEN = 88, - THEN = 89, - OFF = 90, - STAGE = 91, - CLEARSCREEN= 92, - ADD = 93, - REMOVE = 94, - LOG = 95, - BREAK = 96, - PRESERVE= 97, - DECLARE = 98, - LOCAL = 99, - GLOBAL = 100, - PARAMETER= 101, - FUNCTION= 102, - RETURN = 103, - SWITCH = 104, - COPY = 105, - FROM = 106, - RENAME = 107, - VOLUME = 108, - FILE = 109, - DELETE = 110, - EDIT = 111, - RUN = 112, - COMPILE = 113, - LIST = 114, - REBOOT = 115, - SHUTDOWN= 116, - FOR = 117, - UNSET = 118, - BATCH = 119, - DEPLOY = 120, - BRACKETOPEN= 121, - BRACKETCLOSE= 122, - CURLYOPEN= 123, - CURLYCLOSE= 124, - SQUAREOPEN= 125, - SQUARECLOSE= 126, - COMMA = 127, - COLON = 128, - IN = 129, - ARRAYINDEX= 130, - ALL = 131, - IDENTIFIER= 132, - FILEIDENT= 133, - INTEGER = 134, - DOUBLE = 135, - STRING = 136, - EOI = 137, - ATSIGN = 138, - LAZYGLOBAL= 139, - EOF = 140, - WHITESPACE= 141, - COMMENTLINE= 142 + PLUSMINUS= 63, + MULT = 64, + DIV = 65, + POWER = 66, + E = 67, + NOT = 68, + AND = 69, + OR = 70, + TRUEFALSE= 71, + COMPARATOR= 72, + SET = 73, + TO = 74, + IS = 75, + IF = 76, + ELSE = 77, + UNTIL = 78, + LOCK = 79, + UNLOCK = 80, + PRINT = 81, + AT = 82, + ON = 83, + TOGGLE = 84, + WAIT = 85, + WHEN = 86, + THEN = 87, + OFF = 88, + STAGE = 89, + CLEARSCREEN= 90, + ADD = 91, + REMOVE = 92, + LOG = 93, + BREAK = 94, + PRESERVE= 95, + DECLARE = 96, + LOCAL = 97, + GLOBAL = 98, + PARAMETER= 99, + FUNCTION= 100, + RETURN = 101, + SWITCH = 102, + COPY = 103, + FROM = 104, + RENAME = 105, + VOLUME = 106, + FILE = 107, + DELETE = 108, + EDIT = 109, + RUN = 110, + COMPILE = 111, + LIST = 112, + REBOOT = 113, + SHUTDOWN= 114, + FOR = 115, + UNSET = 116, + BRACKETOPEN= 117, + BRACKETCLOSE= 118, + CURLYOPEN= 119, + CURLYCLOSE= 120, + SQUAREOPEN= 121, + SQUARECLOSE= 122, + COMMA = 123, + COLON = 124, + IN = 125, + ARRAYINDEX= 126, + ALL = 127, + IDENTIFIER= 128, + FILEIDENT= 129, + INTEGER = 130, + DOUBLE = 131, + STRING = 132, + EOI = 133, + ATSIGN = 134, + LAZYGLOBAL= 135, + EOF = 136, + WHITESPACE= 137, + COMMENTLINE= 138 } public class Token diff --git a/src/kOS.Safe/Compilation/KS/kRISC.tpg b/src/kOS.Safe/Compilation/KS/kRISC.tpg index 154027f4d..e7d6dcb7f 100644 --- a/src/kOS.Safe/Compilation/KS/kRISC.tpg +++ b/src/kOS.Safe/Compilation/KS/kRISC.tpg @@ -59,8 +59,6 @@ REBOOT -> @"\breboot\b"; SHUTDOWN -> @"\bshutdown\b"; FOR -> @"\bfor\b"; UNSET -> @"\bunset\b"; -BATCH -> @"\bbatch\b"; -DEPLOY -> @"\bdeploy\b"; //Generic BRACKETOPEN -> @"\("; BRACKETCLOSE -> @"\)"; @@ -123,8 +121,6 @@ instruction -> set_stmt | shutdown_stmt | for_stmt | unset_stmt | - batch_stmt | - deploy_stmt | instruction_block | identifier_led_stmt | // any statement that starts with an identifier. directive; // allow directives anywhere for now, let the compiler decide if it's in the wrong place, not the parser. @@ -191,8 +187,6 @@ reboot_stmt -> REBOOT EOI; shutdown_stmt -> SHUTDOWN EOI; for_stmt -> FOR IDENTIFIER IN varidentifier instruction EOI?; unset_stmt -> UNSET (IDENTIFIER | ALL) EOI; -batch_stmt -> BATCH EOI; -deploy_stmt -> DEPLOY EOI; // ---------- expressions --------------------------- From 28835ef1231658c3c4aef525216f0ed52a0c3cb9 Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Sun, 26 Apr 2015 23:45:02 -0500 Subject: [PATCH 438/446] Resolves #876 better err msg on missing file. Actually, the check to see if the file handle was null did exist in the code, but was being made too late, after the file object had already been attempted to be used. Just moved the check higher up. --- src/kOS/Function/Misc.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/kOS/Function/Misc.cs b/src/kOS/Function/Misc.cs index e4eced3c3..4185eb9ca 100644 --- a/src/kOS/Function/Misc.cs +++ b/src/kOS/Function/Misc.cs @@ -249,6 +249,7 @@ public override void Execute(SharedObjects shared) throw new KOSFileException("No filename to load was given."); ProgramFile file = shared.VolumeMgr.CurrentVolume.GetByName(fileName, (! justCompiling)); // if running, look for KSM first. If compiling look for KS first. + if (file == null) throw new KOSFileException(string.Format("Can't find file '{0}'.", fileName)); fileName = file.Filename; // just in case GetByName picked an extension that changed it. // filename is now guaranteed to have an extension. To make default output name, replace the extension with KSM: @@ -261,8 +262,6 @@ public override void Execute(SharedObjects shared) if (shared.VolumeMgr == null) return; if (shared.VolumeMgr.CurrentVolume == null) throw new KOSFileException("Volume not found"); - if (file == null) throw new KOSFileException(string.Format("File '{0}' not found", fileName)); - if (shared.ScriptHandler != null) { var options = new CompilerOptions { LoadProgramsInSameAddressSpace = true, FuncManager = shared.FunctionManager }; From f8dfcc0dc2f8b2404feaf14b1423ac943b605a6b Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Mon, 27 Apr 2015 00:21:09 -0500 Subject: [PATCH 439/446] Resolves #857. The math for calculating num args passed in in one of the places it was being checked was not taking into account the way it iterates over the expected parameter list backward (so that 'i' is larger the fewer arguments there were before hitting the arg bottom marker). --- src/kOS.Safe/Compilation/Opcode.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kOS.Safe/Compilation/Opcode.cs b/src/kOS.Safe/Compilation/Opcode.cs index 5c81b630d..31db676c9 100644 --- a/src/kOS.Safe/Compilation/Opcode.cs +++ b/src/kOS.Safe/Compilation/Opcode.cs @@ -1289,7 +1289,7 @@ public static object ExecuteDelegate(ICpu cpu, Delegate dlg) { object arg = cpu.PopValue(); if (arg is string && ((string)arg) == ARG_MARKER_STRING) - throw new KOSArgumentMismatchException(paramArray.Length, i-1); + throw new KOSArgumentMismatchException(paramArray.Length, paramArray.Length - (i+1)); Type argType = arg.GetType(); ParameterInfo paramInfo = paramArray[i]; Type paramType = paramInfo.ParameterType; From 3d650155ae088d09938211c7ac068dfcbc4f220e Mon Sep 17 00:00:00 2001 From: Chris Woerz Date: Mon, 13 Apr 2015 21:15:28 -0600 Subject: [PATCH 440/446] a bunch of 1.0 compatibility issues --- src/kOS/Binding/BindingsUniverse.cs | 23 ++++++++++++++--- src/kOS/Suffixed/BodyAtmosphere.cs | 6 ++--- src/kOS/Suffixed/Part/GimbalValue.cs | 9 +------ .../Suffixed/PartModuleField/GimbalFields.cs | 9 +------ src/kOS/Suffixed/VesselSensors.cs | 2 +- src/kOS/Suffixed/VesselTarget.cs | 13 ++++++++-- src/kOS/Utilities/VesselUtils.cs | 25 ++++++++++--------- 7 files changed, 49 insertions(+), 38 deletions(-) diff --git a/src/kOS/Binding/BindingsUniverse.cs b/src/kOS/Binding/BindingsUniverse.cs index 6a066694e..7acbb9051 100644 --- a/src/kOS/Binding/BindingsUniverse.cs +++ b/src/kOS/Binding/BindingsUniverse.cs @@ -56,13 +56,28 @@ public override void AddTo(SharedObjects shared) FlightDriver.StartAndFocusVessel(game, game.flightState.activeVesselIdx); }); - shared.BindingMgr.AddGetter("LOADDISTANCE", () => Vessel.loadDistance); + shared.BindingMgr.AddGetter("LOADDISTANCE", () => PhysicsGlobals.Instance.VesselRangesDefault.orbit.load); shared.BindingMgr.AddSetter("LOADDISTANCE", val => { var distance = Convert.ToSingle(val); - Vessel.loadDistance = distance; - Vessel.unloadDistance = distance - 250; + PhysicsGlobals.Instance.VesselRangesDefault.landed.load = distance; + PhysicsGlobals.Instance.VesselRangesDefault.splashed.load = distance; + PhysicsGlobals.Instance.VesselRangesDefault.prelaunch.load = distance; + PhysicsGlobals.Instance.VesselRangesDefault.flying.load = distance; + PhysicsGlobals.Instance.VesselRangesDefault.orbit.load = distance; + PhysicsGlobals.Instance.VesselRangesDefault.subOrbital.load = distance; + PhysicsGlobals.Instance.VesselRangesDefault.escaping.load = distance; + + var unloadDistance = distance - 250; + PhysicsGlobals.Instance.VesselRangesDefault.landed.unload = unloadDistance; + PhysicsGlobals.Instance.VesselRangesDefault.splashed.unload = unloadDistance; + PhysicsGlobals.Instance.VesselRangesDefault.prelaunch.unload = unloadDistance; + PhysicsGlobals.Instance.VesselRangesDefault.flying.unload = unloadDistance; + PhysicsGlobals.Instance.VesselRangesDefault.orbit.unload = unloadDistance; + PhysicsGlobals.Instance.VesselRangesDefault.subOrbital.unload = unloadDistance; + PhysicsGlobals.Instance.VesselRangesDefault.escaping.unload = unloadDistance; }); + shared.BindingMgr.AddGetter("WARPMODE", () => { switch (TimeWarp.WarpMode) @@ -81,7 +96,7 @@ public override void AddTo(SharedObjects shared) { TimeWarp.Modes toSet; - switch (val.ToString()) + switch (val.ToString().ToUpper()) { case "PHYSICS": toSet = TimeWarp.Modes.LOW; diff --git a/src/kOS/Suffixed/BodyAtmosphere.cs b/src/kOS/Suffixed/BodyAtmosphere.cs index 361ccb838..38d329efa 100644 --- a/src/kOS/Suffixed/BodyAtmosphere.cs +++ b/src/kOS/Suffixed/BodyAtmosphere.cs @@ -14,9 +14,9 @@ public BodyAtmosphere(CelestialBody celestialBody) AddSuffix("BODY", new Suffix(()=> celestialBody.bodyName)); AddSuffix("EXISTS", new Suffix(()=> celestialBody.atmosphere)); AddSuffix("OXYGEN", new Suffix(()=> celestialBody.atmosphere && celestialBody.atmosphereContainsOxygen)); - AddSuffix("SCALE", new Suffix(()=> celestialBody.atmosphere ? celestialBody.atmosphereScaleHeight : 0)); - AddSuffix("SEALEVELPRESSURE", new Suffix(()=> celestialBody.atmosphere ? celestialBody.staticPressureASL : 0)); - AddSuffix("HEIGHT", new Suffix(()=> celestialBody.atmosphere ? celestialBody.maxAtmosphereAltitude : 0)); + AddSuffix("SCALE", new Suffix(()=> celestialBody.atmosphere ? celestialBody.atmospherePressureCurve.maxTime : 0)); + AddSuffix("SEALEVELPRESSURE", new Suffix(()=> celestialBody.atmosphere ? celestialBody.atmospherePressureSeaLevel : 0)); + AddSuffix("HEIGHT", new Suffix(()=> celestialBody.atmosphere ? celestialBody.atmosphereDepth : 0)); } public override string ToString() diff --git a/src/kOS/Suffixed/Part/GimbalValue.cs b/src/kOS/Suffixed/Part/GimbalValue.cs index 1116c1175..28bc8f1c2 100644 --- a/src/kOS/Suffixed/Part/GimbalValue.cs +++ b/src/kOS/Suffixed/Part/GimbalValue.cs @@ -16,14 +16,7 @@ private void InitializeGimbalSuffixes() { AddSuffix("LOCK", new SetSuffix(() => gimbal.gimbalLock, value => { - if (value) - { - gimbal.LockGimbal(); - } - else - { - gimbal.FreeGimbal(); - } + gimbal.gimbalLock = value; }, "Is the Gimbal free to travel?")); AddSuffix("RANGE", new Suffix(() => gimbal.gimbalRange ,"The Gimbal's Possible Range of movement")); AddSuffix("RESPONSESPEED", new Suffix(() => gimbal.gimbalResponseSpeed, "The Gimbal's Possible Rate of travel")); diff --git a/src/kOS/Suffixed/PartModuleField/GimbalFields.cs b/src/kOS/Suffixed/PartModuleField/GimbalFields.cs index 39e522095..10a325cef 100644 --- a/src/kOS/Suffixed/PartModuleField/GimbalFields.cs +++ b/src/kOS/Suffixed/PartModuleField/GimbalFields.cs @@ -16,14 +16,7 @@ private void InitializeGimbalSuffixes() { AddSuffix("LOCK", new SetSuffix(() => gimbal.gimbalLock, value => { - if (value) - { - gimbal.LockGimbal(); - } - else - { - gimbal.FreeGimbal(); - } + gimbal.gimbalLock = value; }, "Is the Gimbal free to travel?")); AddSuffix("RANGE", new Suffix(() => gimbal.gimbalRange ,"The Gimbal's Possible Range of movement")); AddSuffix("RESPONSESPEED", new Suffix(() => gimbal.gimbalResponseSpeed, "The Gimbal's Possible Rate of travel")); diff --git a/src/kOS/Suffixed/VesselSensors.cs b/src/kOS/Suffixed/VesselSensors.cs index f03634adc..fc57a03c2 100644 --- a/src/kOS/Suffixed/VesselSensors.cs +++ b/src/kOS/Suffixed/VesselSensors.cs @@ -42,7 +42,7 @@ private void FindSensors(Vessel target) acceleration = new Vector(target.acceleration); break; case "PRES": - pressure = target.staticPressure; + pressure = target.staticPressurekPa; break; case "TEMP": temperature = part.temperature; diff --git a/src/kOS/Suffixed/VesselTarget.cs b/src/kOS/Suffixed/VesselTarget.cs index 4013900b9..f955aa764 100644 --- a/src/kOS/Suffixed/VesselTarget.cs +++ b/src/kOS/Suffixed/VesselTarget.cs @@ -419,8 +419,16 @@ private void InitializeSuffixes() AddSuffix("WETMASS", new Suffix(Vessel.GetWetMass, "The Ship's mass when full")); AddSuffix("RESOURCES", new Suffix>(() => AggregateResourceValue.FromVessel(Vessel, Shared), "The Aggregate resources from every part on the craft")); AddSuffix("PACKDISTANCE", new SetSuffix( - () => System.Math.Min(Vessel.distanceLandedPackThreshold, Vessel.distancePackThreshold), - value => { Vessel.distanceLandedPackThreshold = Vessel.distancePackThreshold = value; })); + () => + { + return System.Math.Min(Vessel.vesselRanges.landed.pack, Vessel.vesselRanges.prelaunch.pack); + }, + value => + { + Vessel.vesselRanges.landed.pack = value; + Vessel.vesselRanges.splashed.pack = value; + Vessel.vesselRanges.prelaunch.pack = value; + })); AddSuffix("ISDEAD", new NoArgsSuffix(() => (Vessel.state == Vessel.State.DEAD) )); AddSuffix("STATUS", new Suffix(() => Vessel.situation.ToString())); @@ -430,6 +438,7 @@ private void InitializeSuffixes() AddSuffix("LATITUDE", new Suffix(() => VesselUtils.GetVesselLatitude(Vessel))); AddSuffix("LONGITUDE", new Suffix(() => VesselUtils.GetVesselLongitude(Vessel))); AddSuffix("ALTITUDE", new Suffix(() => Vessel.altitude)); + } diff --git a/src/kOS/Utilities/VesselUtils.cs b/src/kOS/Utilities/VesselUtils.cs index 81b9acb53..f4d07e8f3 100644 --- a/src/kOS/Utilities/VesselUtils.cs +++ b/src/kOS/Utilities/VesselUtils.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Linq; +using kOS.Safe.Compilation; using UnityEngine; namespace kOS.Utilities @@ -347,22 +348,22 @@ public static float GetWetMass(this Vessel vessel) private static double RealMaxAtmosphereAltitude(CelestialBody body) { - // This comes from MechJeb CelestialBodyExtensions.cs - if (!body.atmosphere) return 0; - //Atmosphere actually cuts out when exp(-altitude / scale height) = 1e-6 - return -body.atmosphereScaleHeight * 1000 * Math.Log(1e-6); + return body.atmosphere ? body.atmosphereDepth : 0; } public static double GetTerminalVelocity(Vessel vessel) { - if (vessel.mainBody.GetAltitude(vessel.findWorldCenterOfMass()) > RealMaxAtmosphereAltitude(vessel.mainBody)) - return double.PositiveInfinity; - double densityOfAir = - FlightGlobals.getAtmDensity(FlightGlobals.getStaticPressure(vessel.findWorldCenterOfMass(), - vessel.mainBody)); - return - Math.Sqrt(2 * FlightGlobals.getGeeForceAtPosition(vessel.findWorldCenterOfMass()).magnitude * - vessel.GetTotalMass() / (GetMassDrag(vessel) * FlightGlobals.DragMultiplier * densityOfAir)); + //if (vessel.mainBody.GetAltitude(vessel.findWorldCenterOfMass()) > RealMaxAtmosphereAltitude(vessel.mainBody)) + // return double.PositiveInfinity; + //var staticPressure = FlightGlobals.getStaticPressure(vessel.findWorldCenterOfMass(), vessel.mainBody); + //var exteriorTemperature = FlightGlobals.getExternalTemperature(vessel.findWorldCenterOfMass(), vessel.mainBody); + //double densityOfAir = FlightGlobals.getAtmDensity(staticPressure, exteriorTemperature); + //return + // Math.Sqrt(2 * FlightGlobals.getGeeForceAtPosition(vessel.findWorldCenterOfMass()).magnitude * + // vessel.GetTotalMass() / (GetMassDrag(vessel) * FlightGlobals.DragMultiplier * densityOfAir)); + + #warning Version 1.0 TODO + return default(Double); } public static float GetVesselLatitude(Vessel vessel) From d24b9245703a4a19bce7f6f6c7f36bc3efe8f474 Mon Sep 17 00:00:00 2001 From: Chris Woerz Date: Mon, 13 Apr 2015 21:44:39 -0600 Subject: [PATCH 441/446] mostly spelling --- src/kOS/Suffixed/ResourceTransferValue.cs | 2 +- src/kOS/UserIO/TelnetSingletonServer.cs | 20 +++++++------------- src/kOS/Utilities/Utils.cs | 1 - 3 files changed, 8 insertions(+), 15 deletions(-) diff --git a/src/kOS/Suffixed/ResourceTransferValue.cs b/src/kOS/Suffixed/ResourceTransferValue.cs index 1b2fed993..5781e02b7 100644 --- a/src/kOS/Suffixed/ResourceTransferValue.cs +++ b/src/kOS/Suffixed/ResourceTransferValue.cs @@ -87,7 +87,7 @@ public override string ToString() private void InitializeSuffixes() { - AddSuffix("GOAL", new Suffix(() => amount.HasValue ? amount.Value : -1)); + AddSuffix("GOAL", new Suffix(() => amount ?? -1)); AddSuffix("TRANSFERRED", new Suffix(() => transferredAmount)); AddSuffix("STATUS", new Suffix(() => Status.ToString())); AddSuffix("MESSAGE", new Suffix(() => StatusMessage)); diff --git a/src/kOS/UserIO/TelnetSingletonServer.cs b/src/kOS/UserIO/TelnetSingletonServer.cs index af60708ec..b22fd0204 100644 --- a/src/kOS/UserIO/TelnetSingletonServer.cs +++ b/src/kOS/UserIO/TelnetSingletonServer.cs @@ -44,7 +44,7 @@ public class TelnetSingletonServer private readonly object inQueueAccess = new object(); // To make all access of the inQueue atomic between threads. /// - /// The queue that other parts of kOS can use to write characters to the telent client. + /// The queue that other parts of kOS can use to write characters to the telnet client. /// private volatile Queue outQueue; private readonly object outQueueAccess = new object(); // To make all access of the outQueue atomic between threads. @@ -221,7 +221,7 @@ public char ReadChar() } /// - /// Get a string of all available charactesr from the client. + /// Get a string of all available characters from the client. /// If no such chars are available it will not throw an exception. Instead it just returns a zero length string. /// /// All currently available input characters returned in one string. @@ -254,7 +254,7 @@ public bool InputWaiting() /// /// Write a character out to the telnet client. You can pretend the telnet client is a - /// psuedo-terminal that understands the command codes in UnicodeCommand. + /// pseudo-terminal that understands the command codes in UnicodeCommand. ///
    /// This TelnetSingletonServer will run what you give it through a command code /// mapper for whichever terminal type is actually attached to the telnet client. @@ -274,7 +274,7 @@ public void Write(char ch) /// /// Write a string out to the telnet client. You can pretend the telnet client is a - /// psuedo-terminal that understands the command codes in UnicodeCommand. + /// pseudo-terminal that understands the command codes in UnicodeCommand. ///
    /// This TelnetSingletonServer will run what you give it through a command code /// mapper for whichever terminal type is actually attached to the telnet client. @@ -339,12 +339,6 @@ private void SendTextRaw(byte[] buff) // Not using SuperVerbose because it's flagged by verboseDebugSend and maybe we want to ask users // to be able to send us logs when they issue bug reports: logMessage.Append("Send buff["+i+"] = (int)"+ (int)buff[i] + " = '" + (char)buff[i] + "'\n"); - - // ---- Note to Erendrake: ----- - // Can we at some point change the naming convention in such a way that we stop getting the following - // error messages from the compiler? - // 'Debug' is an ambiguous reference between 'kOS.Safe.Utilities.Debug' and 'UnityEngine.Debug'. - // That message is the reason I have the long fully qualified name for the Log() method above. } SafeHouse.Logger.Log(logMessage.ToString()); } @@ -432,8 +426,8 @@ public void AllowTerminalTypeInfo(bool modeOn) /// /// Detect if the client is stuck, using some dummy sends. /// The low level TCP keepalive would be another way to do this, but .NET did a little bit TOO much abstraction - /// of network sockets, and hid the abilty to change that setting. It's stuck at its default value of 2 hours. - /// To change it from 2 hours would requre dropping into the Windows OS-specific libraries and we're trying to + /// of network sockets, and hid the ability to change that setting. It's stuck at its default value of 2 hours. + /// To change it from 2 hours would require dropping into the Windows OS-specific libraries and we're trying to /// avoid that so KOS can run on Mac and Linux. (Rant: The ability to choose the TCP/IP keepalive interval /// is old bog-standard Internet stuff and in no way is it Windows-specific so there's no reason to restrict /// it to the windows-specific part of the API, dammit! It should be part of .NET because every OS can do it!!) @@ -659,7 +653,7 @@ private byte[] TelnetProtocolScrape(byte[] inRawBuff, int rawLength) rawIndex += TelnetConsumeWont(inRawBuff, rawIndex); break; case RFC854_IAC: - break; // pass through to normal behaviour when two IAC's are back to back - that's how a real IAC char is encoded. + break; // pass through to normal behavior when two IAC's are back to back - that's how a real IAC char is encoded. case RFC854_BREAK: case RFC854_IP: lock (inQueueAccess) { inQueue.Enqueue((char)UnicodeCommand.BREAK); } // async send it out of order, right now diff --git a/src/kOS/Utilities/Utils.cs b/src/kOS/Utilities/Utils.cs index 5cfa84912..780f0c249 100644 --- a/src/kOS/Utilities/Utils.cs +++ b/src/kOS/Utilities/Utils.cs @@ -6,7 +6,6 @@ using System.Linq; using UnityEngine; using System.Reflection; -using Debug = UnityEngine.Debug; namespace kOS.Utilities { From 59c44d8d28d2ed9530c527d4370c734702fe3861 Mon Sep 17 00:00:00 2001 From: Chris Woerz Date: Sat, 25 Apr 2015 08:21:59 -0600 Subject: [PATCH 442/446] fill in scale message --- src/kOS/Suffixed/BodyAtmosphere.cs | 4 +++- src/kOS/Utilities/VesselUtils.cs | 1 - 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/kOS/Suffixed/BodyAtmosphere.cs b/src/kOS/Suffixed/BodyAtmosphere.cs index 38d329efa..b02f9aaf3 100644 --- a/src/kOS/Suffixed/BodyAtmosphere.cs +++ b/src/kOS/Suffixed/BodyAtmosphere.cs @@ -1,5 +1,6 @@ using kOS.Safe.Encapsulation; using kOS.Safe.Encapsulation.Suffixes; +using kOS.Safe.Exceptions; namespace kOS.Suffixed { @@ -14,9 +15,10 @@ public BodyAtmosphere(CelestialBody celestialBody) AddSuffix("BODY", new Suffix(()=> celestialBody.bodyName)); AddSuffix("EXISTS", new Suffix(()=> celestialBody.atmosphere)); AddSuffix("OXYGEN", new Suffix(()=> celestialBody.atmosphere && celestialBody.atmosphereContainsOxygen)); - AddSuffix("SCALE", new Suffix(()=> celestialBody.atmosphere ? celestialBody.atmospherePressureCurve.maxTime : 0)); AddSuffix("SEALEVELPRESSURE", new Suffix(()=> celestialBody.atmosphere ? celestialBody.atmospherePressureSeaLevel : 0)); AddSuffix("HEIGHT", new Suffix(()=> celestialBody.atmosphere ? celestialBody.atmosphereDepth : 0)); + + AddSuffix("SCALE", new Suffix(() => { throw new KOSDeprecationException("0.17.2","SCALE","TODO: build alternatives","TODO: Fill in before 1.0 goes out"); })); } public override string ToString() diff --git a/src/kOS/Utilities/VesselUtils.cs b/src/kOS/Utilities/VesselUtils.cs index f4d07e8f3..feb38a846 100644 --- a/src/kOS/Utilities/VesselUtils.cs +++ b/src/kOS/Utilities/VesselUtils.cs @@ -4,7 +4,6 @@ using System; using System.Collections.Generic; using System.Linq; -using kOS.Safe.Compilation; using UnityEngine; namespace kOS.Utilities From 78d774441c02308bb7c743a633a6155417eaf29d Mon Sep 17 00:00:00 2001 From: Chris Woerz Date: Mon, 27 Apr 2015 11:24:58 -0600 Subject: [PATCH 443/446] deprecation --- src/kOS.Safe/Exceptions/KOSDeprecationException.cs | 6 +++--- src/kOS.Safe/kOS.Safe.csproj | 1 + src/kOS/Suffixed/BodyAtmosphere.cs | 2 +- src/kOS/Suffixed/VesselTarget.cs | 2 +- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/kOS.Safe/Exceptions/KOSDeprecationException.cs b/src/kOS.Safe/Exceptions/KOSDeprecationException.cs index 6b05b9fa4..5a55ebba2 100644 --- a/src/kOS.Safe/Exceptions/KOSDeprecationException.cs +++ b/src/kOS.Safe/Exceptions/KOSDeprecationException.cs @@ -4,10 +4,10 @@ namespace kOS.Safe.Exceptions { public class KOSDeprecationException : KOSException { - protected static string terseMessageFmt = "As of kOS {0}, {1} is obsolete and has been replaced with {2}"; + protected static string TerseMessageFmt = "As of kOS {0}, {1} is obsolete and has been replaced with {2}"; - public KOSDeprecationException(string version, string oldUsage,string newUsage, string Url) : - base( String.Format(terseMessageFmt, version, oldUsage, newUsage) ) + public KOSDeprecationException(string version, string oldUsage,string newUsage, string url) : + base( String.Format(TerseMessageFmt, version, oldUsage, newUsage) ) { } } diff --git a/src/kOS.Safe/kOS.Safe.csproj b/src/kOS.Safe/kOS.Safe.csproj index 709cd89fc..a59d26705 100644 --- a/src/kOS.Safe/kOS.Safe.csproj +++ b/src/kOS.Safe/kOS.Safe.csproj @@ -92,6 +92,7 @@ + diff --git a/src/kOS/Suffixed/BodyAtmosphere.cs b/src/kOS/Suffixed/BodyAtmosphere.cs index b02f9aaf3..966628a82 100644 --- a/src/kOS/Suffixed/BodyAtmosphere.cs +++ b/src/kOS/Suffixed/BodyAtmosphere.cs @@ -18,7 +18,7 @@ public BodyAtmosphere(CelestialBody celestialBody) AddSuffix("SEALEVELPRESSURE", new Suffix(()=> celestialBody.atmosphere ? celestialBody.atmospherePressureSeaLevel : 0)); AddSuffix("HEIGHT", new Suffix(()=> celestialBody.atmosphere ? celestialBody.atmosphereDepth : 0)); - AddSuffix("SCALE", new Suffix(() => { throw new KOSDeprecationException("0.17.2","SCALE","TODO: build alternatives","TODO: Fill in before 1.0 goes out"); })); + AddSuffix("SCALE", new Suffix(() => { throw new KOSAtmosphereDeprecationException("0.17.2","SCALE","",string.Empty); })); } public override string ToString() diff --git a/src/kOS/Suffixed/VesselTarget.cs b/src/kOS/Suffixed/VesselTarget.cs index f955aa764..31a36d698 100644 --- a/src/kOS/Suffixed/VesselTarget.cs +++ b/src/kOS/Suffixed/VesselTarget.cs @@ -412,7 +412,7 @@ private void InitializeSuffixes() AddSuffix(new[] {"SHIPNAME", "NAME"}, new SetSuffix(() => Vessel.vesselName, RenameVessel, "The KSP name for a craft, cannot be empty")); AddSuffix("TYPE", new SetSuffix(() => Vessel.vesselType.ToString(), RetypeVessel, "The Ship's KSP type (e.g. rover, base, probe)")); AddSuffix("SENSORS", new Suffix(() => new VesselSensors(Vessel))); - AddSuffix("TERMVELOCITY", new Suffix(() => VesselUtils.GetTerminalVelocity(Vessel))); + AddSuffix("TERMVELOCITY", new Suffix(() => { throw new KOSAtmosphereDeprecationException("17.2", "TERMVELOCITY", "", string.Empty);})); AddSuffix("LOADED", new Suffix(() => Vessel.loaded)); AddSuffix("ROOTPART", new Suffix(() => PartValueFactory.Construct(Vessel.rootPart, Shared))); AddSuffix("DRYMASS", new Suffix(() => Vessel.GetDryMass(), "The Ship's mass when empty")); From 99ebfd31c3cce1b418d0285d3ef7adf8c76a3a26 Mon Sep 17 00:00:00 2001 From: Chris Woerz Date: Mon, 27 Apr 2015 12:31:18 -0600 Subject: [PATCH 444/446] added missing file --- .../KOSAtmosphereDeprecationException.cs | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 src/kOS.Safe/Exceptions/KOSAtmosphereDeprecationException.cs diff --git a/src/kOS.Safe/Exceptions/KOSAtmosphereDeprecationException.cs b/src/kOS.Safe/Exceptions/KOSAtmosphereDeprecationException.cs new file mode 100644 index 000000000..247834d9a --- /dev/null +++ b/src/kOS.Safe/Exceptions/KOSAtmosphereDeprecationException.cs @@ -0,0 +1,24 @@ +namespace kOS.Safe.Exceptions +{ + public class KOSAtmosphereDeprecationException : KOSDeprecationException + { + public KOSAtmosphereDeprecationException(string version, string oldUsage, string newUsage, string url) : base(version, oldUsage, newUsage, url) + { + } + + public override string VerboseMessage + { + get + { + return string.Format( + "{0}\n" + + "In KSP 1.0 there have been many changes to\n" + + "how planetary atmospheres work.\n" + + "\n" + + "Because the basic concepts of much of that system\n" + + "have changed. We have removed TERMVELOCITY and SCALE\n" + , base.Message); + } + } + } +} \ No newline at end of file From f3d4ce390948405471171f61859273568ffccbe3 Mon Sep 17 00:00:00 2001 From: ZiwKerman Date: Mon, 27 Apr 2015 21:10:13 +0100 Subject: [PATCH 445/446] Fixing Toolbar in 1.0 --- src/kOS/Screen/KOSToolBarWindow.cs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/kOS/Screen/KOSToolBarWindow.cs b/src/kOS/Screen/KOSToolBarWindow.cs index 1eb1fa8f4..c12ea71a5 100644 --- a/src/kOS/Screen/KOSToolBarWindow.cs +++ b/src/kOS/Screen/KOSToolBarWindow.cs @@ -123,9 +123,15 @@ public void Start() FirstTimeSetup(); + //in 1.0 these Events are never fired (it seems), so we need to maka a workaround GameEvents.onGUIApplicationLauncherReady.Add(RunWhenReady); GameEvents.onGUIApplicationLauncherDestroyed.Add(GoAway); + if (ApplicationLauncher.Ready && launcherButton == null) + { + RunWhenReady(); + } + SafeHouse.Logger.SuperVerbose("[kOSToolBarWindow] Start succesful"); } @@ -157,7 +163,8 @@ public void RunWhenReady() launcher.EnableMutuallyExclusive(launcherButton); } - AddBlizzyButton(); + if (BlizzyButton == null) + AddBlizzyButton(); SetupBackingConfigInts(); SafeHouse.Logger.SuperVerbose("[kOSToolBarWindow] Launcher Icon init successful"); From 88992c05fbfdcd1ff0ea5f5b242447e1ec4a2331 Mon Sep 17 00:00:00 2001 From: Chris Woerz Date: Mon, 27 Apr 2015 20:10:20 -0600 Subject: [PATCH 446/446] rev version for release --- CHANGELOG.md | 16 +++++++++++++- Resources/GameData/ModuleManager.2.5.13.dll | Bin 53760 -> 0 bytes .../GameData/kOS/Plugins/KSPAPIExtensions.dll | Bin 117248 -> 0 bytes Resources/GameData/kOS/kOS.version | 2 +- doc/source/conf.py | 4 ++-- src/kOS.Safe/Properties/AssemblyInfo.cs | 4 ++-- src/kOS/Core.cs | 2 +- src/kOS/Properties/AssemblyInfo.cs | 4 ++-- src/kOS/Utilities/VesselUtils.cs | 20 ------------------ 9 files changed, 23 insertions(+), 29 deletions(-) delete mode 100644 Resources/GameData/ModuleManager.2.5.13.dll delete mode 100644 Resources/GameData/kOS/Plugins/KSPAPIExtensions.dll diff --git a/CHANGELOG.md b/CHANGELOG.md index 7f6c64a69..53d83b5dc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,11 +1,25 @@ kOS Mod Changelog ================= +# v0.17.1 + +1.0 Release +----------- + +### New Hotness + +* New infernal robotics integration +* Better error reporting + + +### Old and busted + +* fixes keyword lexxing # v0.17.1 Corrections and omissions ------------------------ +------------------------- ### "New" features diff --git a/Resources/GameData/ModuleManager.2.5.13.dll b/Resources/GameData/ModuleManager.2.5.13.dll deleted file mode 100644 index 797ffa71a434d52d19edbe00634c3e14f282c98d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 53760 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 f**04_JF=#~{o8*bi<)?odf?3kCW9B diff --git a/Resources/GameData/kOS/Plugins/KSPAPIExtensions.dll b/Resources/GameData/kOS/Plugins/KSPAPIExtensions.dll deleted file mode 100644 index 32987a41952163ad5c6a13667fce5ebfaae6fa68..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 117248 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 diff --git a/Resources/GameData/kOS/kOS.version b/Resources/GameData/kOS/kOS.version index 4ecb31d59..ead55c775 100644 --- a/Resources/GameData/kOS/kOS.version +++ b/Resources/GameData/kOS/kOS.version @@ -11,7 +11,7 @@ "VERSION": { "MAJOR": 0, "MINOR": 17, - "PATCH": 1 + "PATCH": 2 }, "KSP_VERSION": { "MAJOR": 0, diff --git a/doc/source/conf.py b/doc/source/conf.py index 462136ef1..2f199b621 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -57,9 +57,9 @@ # built documents. # # The short X.Y version. -version = '0.17.1 ' +version = '0.17.2 ' # The full version, including alpha/beta/rc tags. -release = '0.17.1' +release = '0.17.2' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/src/kOS.Safe/Properties/AssemblyInfo.cs b/src/kOS.Safe/Properties/AssemblyInfo.cs index 75f496678..ef1aee829 100644 --- a/src/kOS.Safe/Properties/AssemblyInfo.cs +++ b/src/kOS.Safe/Properties/AssemblyInfo.cs @@ -31,5 +31,5 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.17.1.0")] -[assembly: AssemblyFileVersion("1.17.1.0")] +[assembly: AssemblyVersion("1.17.2.0")] +[assembly: AssemblyFileVersion("1.17.2.0")] diff --git a/src/kOS/Core.cs b/src/kOS/Core.cs index 3f50ef58b..45edb7fdd 100644 --- a/src/kOS/Core.cs +++ b/src/kOS/Core.cs @@ -5,7 +5,7 @@ namespace kOS { public class Core : MonoBehaviour { - public static VersionInfo VersionInfo = new VersionInfo(0, 17, 1); + public static VersionInfo VersionInfo = new VersionInfo(0, 17, 2); public static Core Fetch; diff --git a/src/kOS/Properties/AssemblyInfo.cs b/src/kOS/Properties/AssemblyInfo.cs index 36bcd0ee9..1a5e79ba2 100644 --- a/src/kOS/Properties/AssemblyInfo.cs +++ b/src/kOS/Properties/AssemblyInfo.cs @@ -31,6 +31,6 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyFileVersion("0.17.1.0")] -[assembly: AssemblyVersion("0.17.1.0")] +[assembly: AssemblyFileVersion("0.17.2.0")] +[assembly: AssemblyVersion("0.17.2.0")] [assembly: KSPAssembly("kOS", 0, 17)] diff --git a/src/kOS/Utilities/VesselUtils.cs b/src/kOS/Utilities/VesselUtils.cs index feb38a846..214b3ced2 100644 --- a/src/kOS/Utilities/VesselUtils.cs +++ b/src/kOS/Utilities/VesselUtils.cs @@ -345,26 +345,6 @@ public static float GetWetMass(this Vessel vessel) return vessel.parts.Sum(part => part.GetWetMass()); } - private static double RealMaxAtmosphereAltitude(CelestialBody body) - { - return body.atmosphere ? body.atmosphereDepth : 0; - } - - public static double GetTerminalVelocity(Vessel vessel) - { - //if (vessel.mainBody.GetAltitude(vessel.findWorldCenterOfMass()) > RealMaxAtmosphereAltitude(vessel.mainBody)) - // return double.PositiveInfinity; - //var staticPressure = FlightGlobals.getStaticPressure(vessel.findWorldCenterOfMass(), vessel.mainBody); - //var exteriorTemperature = FlightGlobals.getExternalTemperature(vessel.findWorldCenterOfMass(), vessel.mainBody); - //double densityOfAir = FlightGlobals.getAtmDensity(staticPressure, exteriorTemperature); - //return - // Math.Sqrt(2 * FlightGlobals.getGeeForceAtPosition(vessel.findWorldCenterOfMass()).magnitude * - // vessel.GetTotalMass() / (GetMassDrag(vessel) * FlightGlobals.DragMultiplier * densityOfAir)); - - #warning Version 1.0 TODO - return default(Double); - } - public static float GetVesselLatitude(Vessel vessel) { var retVal = (float)vessel.latitude;

    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ℜ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