diff --git a/.gitignore b/.gitignore
index 9cc5d472..fc56f1b6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -113,7 +113,7 @@ _UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
Plugins/MiniAVC.xml
-KAS_v*.zip
+KAS_*.zip
*.zip
*.pyc
diff --git a/docs/APIv1/SearchHelp.aspx b/docs/APIv1/SearchHelp.aspx
new file mode 100644
index 00000000..6e2a17b6
--- /dev/null
+++ b/docs/APIv1/SearchHelp.aspx
@@ -0,0 +1,233 @@
+<%@ Page Language="C#" EnableViewState="False" %>
+
+
diff --git a/docs/APIv1/SearchHelp.inc.php b/docs/APIv1/SearchHelp.inc.php
new file mode 100644
index 00000000..b905e130
--- /dev/null
+++ b/docs/APIv1/SearchHelp.inc.php
@@ -0,0 +1,173 @@
+
+// Contributed to the Sandcastle Help File Builder project by Thomas Levesque
+
+class Ranking
+{
+ public $filename;
+ public $pageTitle;
+ public $rank;
+
+ function __construct($file, $title, $rank)
+ {
+ $this->filename = $file;
+ $this->pageTitle = $title;
+ $this->rank = $rank;
+ }
+}
+
+
+///
KASAPIAttachNodesUtils Field |
+ Namespace: + KASAPIv1
public static IAttachNodesUtils AttachNodesUtils
KASAPICommonConfig Field |
+ Namespace: + KASAPIv1
public static ICommonConfig CommonConfig
KASAPIJointUtils Field |
+ Namespace: + KASAPIv1
KASAPIKasEvents Field |
+ Namespace: + KASAPIv1
KASAPILinkUtils Field |
+ Namespace: + KASAPIv1
KASAPIPhysicsUtils Field |
+ Namespace: + KASAPIv1
public static IPhysicsUtils PhysicsUtils
KASAPIisLoaded Field |
+ Namespace: + KASAPIv1
KASAPI Fields |
The KASAPI type exposes the following members.
+ + | Name | Description |
---|---|---|
AttachNodesUtils | KAS attach nodes utils. | |
CommonConfig | KAS common config settings. | |
isLoaded | Tells if API V1 was loaded and ready to use. | |
JointUtils | KAS joints untils. | |
KasEvents | KAS global events. | |
LinkUtils | KAS link utils. | |
PhysicsUtils | KAS physics utils. |
Please try to load the page again. If the error persists, please contact the site administrator.
+IAttachNodesUtilsAddNode Method |
+ Namespace: + KASAPIv1
void AddNode( + Part part, + AttachNode attachNode +)
IAttachNodesUtilsCreateNode Method |
+ Namespace: + KASAPIv1
AttachNode CreateNode( + Part part, + string nodeName, + Transform nodeTransform +)
+ The node will have the following properties: +
IAttachNodesUtilsDropNode Method |
+ Namespace: + KASAPIv1
void DropNode( + Part part, + AttachNode attachNode +)
IAttachNodesUtilsGetTransformForNode Method |
+ Namespace: + KASAPIv1
Transform GetTransformForNode( + Part ownerPart, + AttachNode an +)
IAttachNodesUtilsNodeId Method |
+ Namespace: + KASAPIv1
string NodeId( + AttachNode an +)
IAttachNodesUtilsParseNodeFromString Method |
+ Namespace: + KASAPIv1
AttachNode ParseNodeFromString( + Part ownerPart, + string def, + string nodeId +)
+ The string format is exactly the same as for the part's attach node definition. It consists of + 10 parts, separated by a comma. Only the first 6 parts are mandatory, the others are optional. + The format is the following: + Position(X,Y,Z), Orientation(X,Y,Z), Size, AttachMethod, CrossFeedAllowed, IsRigid
IJointUtilsDumpJoint Method |
+ Namespace: + KASAPIv1
string DumpJoint( + ConfigurableJoint joint +)
IJointUtilsDumpSpringJoint Method |
+ Namespace: + KASAPIv1
string DumpSpringJoint( + SpringJoint joint +)
IJointUtilsResetJoint Method |
+ Namespace: + KASAPIv1
void ResetJoint( + ConfigurableJoint joint +)
+ It's not the same as creating a default joint. The state is consistent but different from the + default: +
+ Use this method before setting up a new or existing joint. By resetting the joint, you ensure + it's in a consistent state, and the further adjustments will always give the same result + regardless to how the joint was created and what components were affecting it. +
IJointUtilsSetupDistanceJoint Method |
+ Namespace: + KASAPIv1
void SetupDistanceJoint( + ConfigurableJoint joint, + float springForce = 0f, + float springDamper = 0f, + float maxDistance = ∞f +)
IJointUtilsSetupFixedJoint Method |
+ Namespace: + KASAPIv1
void SetupFixedJoint( + ConfigurableJoint joint +)
IJointUtilsSetupPrismaticJoint Method |
+ Namespace: + KASAPIv1
void SetupPrismaticJoint( + ConfigurableJoint joint, + float springForce = 0f, + float springDamperRatio = 0.1f, + float maxSpringForce = ∞f, + float distanceLimit = ∞f, + float distanceLimitForce = 0f, + float distanceLimitDamperRatio = 0.1f +)
+ It's a standard PhysX configuration. Main axis is set to Z. Moving along it is allowed but can + be constrained by a spring and limit. Drive mode is set to + Position. +
+ Only main axis linear settings are changed. Consider using ResetJoint(ConfigurableJoint) to + eliminate side effects from the previous settings of the joint. +
+ Pure prismatic joint assumes 5 out of the 6 degrees of freedom to be locked (everything, + except the main axis linear motion). Consider setting enablePreprocessing + to true since it may improve PhysXperformance. +
+ For performance reasons some parameters combindations may result in different motion modes: +
+ Regardless to the modes set all the other parameters are also applied. I.e. you don't need to + re-apply them when changing mode. +
IJointUtilsSetupSphericalJoint Method |
+ Namespace: + KASAPIv1
void SetupSphericalJoint( + ConfigurableJoint joint, + float springForce = 0f, + float springDamperRatio = 0.1f, + float maxSpringForce = ∞f, + float angleLimit = ∞f, + float angleLimitForce = 0f, + float angleLimitDamperRatio = 0.1f +)
+ It's a standard PhysiX configuration. Main axis is set to Z, and angular rotation around it is + completely unrestricted. Secondary axes are X&Y can be restricted by applying spring force + and/or limits. Drive mode is set to Position. +
+ Only angular settings are set. If joint had linear constraints defined they will stay + unchanged. Consider using ResetJoint(ConfigurableJoint) to eliminate side effects from the previous + settings of the joint. +
+ Pure spherical joint assumes 3 out of the 6 degrees of freedom to be locked (all the three + axes linear motions). Consider setting enablePreprocessing to true + since it may improve PhysX performance. +
+ For performance reasons some parameters combindations may result in different angular modes: +
+ Regardless to the modes set all the other parameters are also applied. I.e. you don't need to + re-apply them when changing mode. +
IKasJointEventsListenerOnKASJointBreak Method |
+ Namespace: + KASAPIv1
void OnKASJointBreak( + GameObject hostObj, + float breakForce +)
ILinkCableJointSetCableLength Method |
+ Namespace: + KASAPIv1
void SetCableLength( + float length +)
+ Setting the new length may trigger the physical effects if the value is less than the real + cable length, since it will force the engine to pull the objects together. Don't reduce the + length too rapidly to avoid the strong forces applied. +
+ Calling for this method doesn't have any effect if the PhysX joint is not created. When a + brand new joint is created, it always has the distance limit set to the actual distance + between the physical objects. I.e. this method must be called after the physical joint + is created. +
ILinkCableJointStartPhysicalHead Method |
+ Namespace: + KASAPIv1
void StartPhysicalHead( + ILinkSource source, + Transform headObjAnchor +)
ILinkCableJointStopPhysicalHead Method |
+ Namespace: + KASAPIv1
ILinkJointAdjustJoint Method |
+ Namespace: + KASAPIv1
void AdjustJoint( + bool isUnbreakable = false +)
ILinkJointCheckConstraints Method |
+ Namespace: + KASAPIv1
string[] CheckConstraints( + ILinkSource source, + ILinkTarget target +)
ILinkJointCreateJoint Method |
+ Namespace: + KASAPIv1
bool CreateJoint( + ILinkSource source, + ILinkTarget target +)
+ This method can be called either to establish a new joint or to restore an existing link on + load. +
+ This method will call the CheckConstraints(ILinkSource, ILinkTarget) method to ensure there are no errors. + If there are some, then the link is not created and the errors are reported to the logs. +
ILinkJointDropJoint Method |
+ Namespace: + KASAPIv1
ILinkJointSetCoupleOnLinkMode Method |
+ Namespace: + KASAPIv1
bool SetCoupleOnLinkMode( + bool isCoupleOnLink +)
+ When both the source and the target peers support coupling, this mode can be arbitrary set or + reset via the joint module. If the new mode is "coupling", and the source and the target + vessels are different, then a coupling action will trigger. If the new mode is "don't couple", + and the source and the target parts are coupled, then a decoupling event is triggered. In all + the other cases it's just a boolean property change. +
+ The modules must support the cycles and be ready to pick up the coupling role when the former + part has gave up. +
ILinkRendererCheckColliderHits Method |
+ Namespace: + KASAPIv1
string[] CheckColliderHits( + Transform source, + Transform target +)
ILinkRendererStartRenderer Method |
+ Namespace: + KASAPIv1
void StartRenderer( + Transform source, + Transform target +)
+ This method only indicates that the link is to be drawn between the specified points. The + renderer is allowed to draw meshes even when not started. E.g. if there are constant parts of + the link like the joint pivots. +
+ The ends of the link are not required to be located at the surface of the owning parts. It's + up to the renderer to decide how to draw the link. +
+ It's OK to call this method multiple times with different or the same source/target arguments: + the renderer must accept the values and update accordingly. However, this operation is rated + as performance expensive, so the callers are discouraged to invoke this method too frequently + (e.g. on every frame update). +
ILinkRendererStopRenderer Method |
+ Namespace: + KASAPIv1
+ It's OK to call this method multiple time. If the renderer is already stopped the call must be + treated as NO-OP with a little or no performance cost. +
ILinkRendererUpdateLink Method |
+ Namespace: + KASAPIv1
+ A specific renderer implementation may introduce own optimization algorithm when the call + becomes too heavy and slow. +
ILinkSourceBreakCurrentLink Method |
+ Namespace: + KASAPIv1
void BreakCurrentLink( + LinkActorType actorType +)
// Disconnects the source part from its target. Only once source can be connected on the part. +// And it can be connected to the exactly one target. +public static void DisconnectParts(Part srcPart) { + var source = srcPart.FindModulesImplementing<ILinkSource>() + .FirstOrDefault(s => s.linkTarget != null); + if (source == null) { + Debug.LogWarningFormat("Part is not connected to anything"); + return; + } + // LinkActorType.API tells the implementation to not execute any user facing effects on the + // link. See LinkActorType for more details. + source.BreakCurrentLink(LinkActorType.API); +}
public class ILinkSourceExample_BreakFromPhysyicalMethod : MonoBehaviour { + public ILinkSource linkSource; + + // This method is called by Unity core during the physics update. + IEnumerable OnJointBreak(float force) { + Debug.LogWarningFormat("Link is broken with force: {0}", force); + // Don't break the link from the physics methods! + yield return new WaitForEndOfFrame(); + // Now it's safe to change the physical objects. + if (linkSource != null && linkSource.linkTarget != null) { + linkSource.BreakCurrentLink(LinkActorType.Physics); + } + } +}
ILinkSourceCancelLinking Method |
+ Namespace: + KASAPIv1
// Connects two parts assuming the source and the target parts own exactly one link module. +public static bool ConnectParts(Part srcPart, Part tgtPart) { + var source = srcPart.FindModuleImplementing<ILinkSource>(); + var target = tgtPart.FindModuleImplementing<ILinkTarget>(); + if (source == null || target == null || source.cfgLinkType != target.cfgLinkType) { + Debug.LogError("Source and target cannot link"); + return false; + } + // GUILinkMode.API mode tells the implementation to not execute any user facing effects on the + // link. See GUILinkMode for more details. + if (!source.StartLinking(GUILinkMode.API, LinkActorType.API) || !source.LinkToTarget(target)) { + // Here we can only fail due to the constraints. E.g. the link mode is not supported, or the + // joint module doesn't give the green light. + Debug.LogError("Linking failed"); + source.CancelLinking(); + return false; + } + Debug.LogFormat("Established link with part: id={0}", source.linkPartId); + return true; +}
ILinkSourceCheckCanLinkTo Method |
+ Namespace: + KASAPIv1
bool CheckCanLinkTo( + ILinkTarget target, + bool checkStates = true, + bool reportToGUI = false, + bool reportToLog = true +)
// Connects two parts assuming the source and the target parts own exactly one link module. +// Does not attempt the link if it's obstructed to avoid a GUI error message. +public static bool ConnectPartsWithCheck(Part srcPart, Part tgtPart) { + var source = srcPart.FindModuleImplementing<ILinkSource>(); + var target = tgtPart.FindModuleImplementing<ILinkTarget>(); + if (source == null || target == null || source.cfgLinkType != target.cfgLinkType) { + Debug.LogError("Source and target cannot link"); + return false; + } + if (!source.CheckCanLinkTo(target, reportToLog: false)) { + Debug.Log("Link is obstructed. Silently cancel the action"); + return false; + } + if (!source.StartLinking(GUILinkMode.API, LinkActorType.API) || !source.LinkToTarget(target)) { + Debug.LogError("Linking failed"); + source.CancelLinking(); + return false; + } + return true; +}
ILinkSourceLinkToTarget Method (ILinkTarget) |
+ Namespace: + KASAPIv1
bool LinkToTarget( + ILinkTarget target +)
+ The linking mode must be started via the StartLinking(GUILinkMode, LinkActorType) call for this method to + succeed. +
+ If the link has been established successfully, the source and the target parts become + associated with each other. +
+ The link conditions will be checked via CheckCanLinkTo(ILinkTarget, Boolean, Boolean, Boolean) before creating the link. + If the were errors, they will be reported to GUI if the linking mode was started with actor + Player. The linking mode won't be cancelled in case of the link + failure. +
// Connects two parts assuming the source and the target parts own exactly one link module. +public static bool ConnectParts(Part srcPart, Part tgtPart) { + var source = srcPart.FindModuleImplementing<ILinkSource>(); + var target = tgtPart.FindModuleImplementing<ILinkTarget>(); + if (source == null || target == null || source.cfgLinkType != target.cfgLinkType) { + Debug.LogError("Source and target cannot link"); + return false; + } + // GUILinkMode.API mode tells the implementation to not execute any user facing effects on the + // link. See GUILinkMode for more details. + if (!source.StartLinking(GUILinkMode.API, LinkActorType.API) || !source.LinkToTarget(target)) { + // Here we can only fail due to the constraints. E.g. the link mode is not supported, or the + // joint module doesn't give the green light. + Debug.LogError("Linking failed"); + source.CancelLinking(); + return false; + } + Debug.LogFormat("Established link with part: id={0}", source.linkPartId); + return true; +}
ILinkSourceLinkToTarget Method (LinkActorType, ILinkTarget) |
+ Namespace: + KASAPIv1
bool LinkToTarget( + LinkActorType actor, + ILinkTarget target +)
ILinkSourceStartLinking Method |
+ Namespace: + KASAPIv1
bool StartLinking( + GUILinkMode mode, + LinkActorType actor +)
+ Only one source at the time can be linking. If the part has more sources or targets, they are + expected to become Locked. +
A module can refuse the mode by returning false.
// Connects two parts assuming the source and the target parts own exactly one link module. +public static bool ConnectParts(Part srcPart, Part tgtPart) { + var source = srcPart.FindModuleImplementing<ILinkSource>(); + var target = tgtPart.FindModuleImplementing<ILinkTarget>(); + if (source == null || target == null || source.cfgLinkType != target.cfgLinkType) { + Debug.LogError("Source and target cannot link"); + return false; + } + // GUILinkMode.API mode tells the implementation to not execute any user facing effects on the + // link. See GUILinkMode for more details. + if (!source.StartLinking(GUILinkMode.API, LinkActorType.API) || !source.LinkToTarget(target)) { + // Here we can only fail due to the constraints. E.g. the link mode is not supported, or the + // joint module doesn't give the green light. + Debug.LogError("Linking failed"); + source.CancelLinking(); + return false; + } + Debug.LogFormat("Established link with part: id={0}", source.linkPartId); + return true; +}
ILinkStateEventListenerOnKASLinkedState Method |
+ Namespace: + KASAPIv1
void OnKASLinkedState( + IKasLinkEvent info, + bool isLinked +)
ILinkStateEventListenerOnKASNodeBlockedState Method |
+ Namespace: + KASAPIv1
void OnKASNodeBlockedState( + ILinkPeer ownerPeer, + bool isBlocked +)
ILinkUtilsCoupleParts Method |
+ Namespace: + KASAPIv1
Part CoupleParts( + AttachNode sourceNode, + AttachNode targetNode, + bool toDominantVessel = false +)
+ Once the coupling is done, one of the vessels will be destroyed. It will become a part of the + other vessel. The new merged vessel will become active. Which vessel will be destroyed is + determined by the toDominantVessel parameter. +
+ This coupling requires the both attach nodes to be provided, and creates a "stack" nodes + coupling. +
ILinkUtilsDecoupleParts Method |
+ Namespace: + KASAPIv1
Part DecoupleParts( + Part part1, + Part part2, + DockedVesselInfo vesselInfo1 = null, + DockedVesselInfo vesselInfo2 = null +)
ILinkUtilsFindLinkPeer Method |
+ Namespace: + KASAPIv1
ILinkPeer FindLinkPeer( + ILinkPeer srcPeer +)
IPhysicsUtilsApplyGravity Method |
+ Namespace: + KASAPIv1
void ApplyGravity( + Rigidbody rb, + Vessel vessel, + double rbAirDragMult = 1 +)
IWinchControlReleaseCable Method |
+ Namespace: + KASAPIv1
IWinchControlSetMotor Method |
+ Namespace: + KASAPIv1
void SetMotor( + float targetSpeed +)
+ The motor is responsible for the deployed cable length changing. It can extend the cable, + retract the cable, or do nothing (idle). The winch and its head cannot get separated at a + greater distance than the current deployed cable length. That said, the motor is controlling + the distance. +
+ The motor speed is not required to change immediately. The motor may need some time to get to + the target speed. It depends on the part implementation and configuration. The rule of thumb + is to not expect the motorCurrentSpeed to match the + targetSpeed right after the method call. There may be some time needed + before the values will match. However, the motorTargetSpeed value will change + immediately, and will match the parameter. +
+ Setting the motor speed may affect the connector state. E.g. if the connector was locked, + and the motor speed is set to a positive value (extending), then the connector is get + deployed. +
+ The motor will automatically stop when the cable length reaches zero or the maximum allowed + value. In case of the zero length, the connector will be attempted to lock into the winch. + This attempt may fail due to the bad align of the connector. To retry the attempt, just call + this method again with a negative value. +
IWinchControlStretchCable Method |
+ Namespace: + KASAPIv1
IAttachNodesUtils Methods |
The IAttachNodesUtils type exposes the following members.
+ + | Name | Description |
---|---|---|
AddNode | Adds an existing attach node into the part. | |
CreateNode | Creates a new attach node on the part. | |
DropNode | Drops the attach node on the part. | |
GetTransformForNode | Gets or creates a transform object for the attach node. | |
NodeId | Returns a user friendly attach node representation. | |
ParseNodeFromString | Creates an attach node form the part's config definition string. |
IJointUtils Methods |
The IJointUtils type exposes the following members.
+ + | Name | Description |
---|---|---|
DumpJoint | Outputs all properties of the joint to the string. | |
DumpSpringJoint | Outputs all properties of the joint to the string. | |
ResetJoint | Initializes joint to a consistent state. | |
SetupDistanceJoint | Sets up a cannonical distance joint. | |
SetupFixedJoint | Sets up a cannonical fixed joint. | |
SetupPrismaticJoint | Sets up joint so what it becomes a prismatic joint. | |
SetupSphericalJoint | Sets up joint so what it becomes a spherical hinge joint. |
IKasJointEventsListener Methods |
The IKasJointEventsListener type exposes the following members.
+ + | Name | Description |
---|---|---|
OnKASJointBreak |
+ Triggers when a connection on the object is broken due to too strong force applied.
+ |
ILinkCableJoint Methods |
The ILinkCableJoint type exposes the following members.
+ + | Name | Description |
---|---|---|
SetCableLength |
+ Sets the maximum possible distance between the source and the head/target physical anchors.
+ | |
StartPhysicalHead |
+ Attaches the specified object to the source and starts the environmental forces on it.
+ | |
StopPhysicalHead | Stops handling the physical head. |
ILinkJoint Methods |
The ILinkJoint type exposes the following members.
+ + | Name | Description |
---|---|---|
AdjustJoint | Requests the joint to become unbreakable or normal. | |
CheckConstraints | Checks if the joint constraints allow the link to be established. | |
CreateJoint | Sets up a physical joint between the source and target. | |
DropJoint | Destroys a physical link between the source and the target. | |
SetCoupleOnLinkMode | Changes the current parts couple mode. |
ILinkRenderer Methods |
The ILinkRenderer type exposes the following members.
+ + | Name | Description |
---|---|---|
CheckColliderHits | Verifies that there are no obstacles beween the points. | |
StartRenderer | Starts rendering a link between the objects. | |
StopRenderer | Cancels rendering the link. | |
UpdateLink | Called when a link representation update is required. |
ILinkSource Methods |
The ILinkSource type exposes the following members.
+ + | Name | Description |
---|---|---|
BreakCurrentLink | Breaks the link between the source and the target. | |
CancelLinking | Cancels the linking mode without creating a link. | |
CheckCanLinkTo | Verifies if a link between the parts can be successful. | |
LinkToTarget(ILinkTarget) | Establishes a link between two parts. | |
LinkToTarget(LinkActorType, ILinkTarget) | Establishes a link between two parts. | |
StartLinking | Starts the linking mode of this source. |
ILinkStateEventListener Methods |
The ILinkStateEventListener type exposes the following members.
+ + | Name | Description |
---|---|---|
OnKASLinkedState | Triggers when any module on the part has created a link. | |
OnKASNodeBlockedState |
+ Triggers when a peer locks itself due to its attach node is blocked by an incompatible part.
+ |
ILinkUtils Methods |
The ILinkUtils type exposes the following members.
+ + | Name | Description |
---|---|---|
CoupleParts | Couples two parts together given they belong to the different vessels. | |
DecoupleParts | Decouples the connected parts and breaks down one vessel into two. | |
FindLinkPeer | Finds the other peer of the link. |
IPhysicsUtils Methods |
The IPhysicsUtils type exposes the following members.
+ + | Name | Description |
---|---|---|
ApplyGravity | Applies the forces that affect a rigidbody on a selectial body. |
IWinchControl Methods |
The IWinchControl type exposes the following members.
+ + | Name | Description |
---|---|---|
ReleaseCable | Sets the deployed cable length to the maximum value allowed by the part. | |
SetMotor | Sets the winch motor to the desired speed. | |
StretchCable |
+ Sets the deployed cable length to the actual distance between the winch and the connector.
+ |
KASAPIv1 Namespace |
KAS API namespace. The third-party code must use the types and interfaces from this namespace instead of depending on the mod modules.
Each API release has a version. Once the API is released to the public, its methods cannot be changed. In case of a new functionality is relased, a new version (and the namespace) will be created. The old namespace will not be removed, so the mods that were built with the old version will continue to work.
If API is needed, the depedent mod should only include a reference to KAS-API-v1.dll (version number may vary). This assembly version never changes, so the dependency will never break. It's OK to provide an API assembly with the mod since multliple API assemblies will not conflict with each other. Moreover, having "own" copy of the API ensures the mod will load even if KAS is not installed in the game. There is an ability to check if KAS is installed in the run-time (see example below).
using KASAPIv1; + +public class MyModule : PartModule { + public void RightSample() { + var source = part.FindModuleImplementing<ILinkSource>(); + if (KASAPI.isLoaded) { + var model = KASAPI.LinkUtils.DecoupleParts(part, part.parent); + } else { + Debug.LogWarning("KAS is not installed"); + } + } +}
+ + | Class | Description |
---|---|---|
KASAPI | KAS API, version 1. |
+ + | Interface | Description |
---|---|---|
IAttachNodesUtils | Various methods to deal with part's attach nodes. | |
ICommonConfig | Container for the various global settings of the mod. | |
IJointUtils | Various tools to deal with KSP part joints. | |
IKasEvents | Defines global events that are triggered by KAS. | |
IKasJointEventsListener | Interface that notifies listeners about joints breaking. | |
IKasLinkEvent | A holder for simple source-to-target event. | |
ILinkCableJoint |
+ Interface for a physical cable link. Such links keep the dsitance between the object below the
+ maximum but don't restict any other movements of the objects relative to each other.
+ | |
ILinkJoint | Base interface for a KAS joint. | |
ILinkPeer | Base interface for an end of the link. | |
ILinkRenderer |
+ Interface for a module that takes care of rendering a link and, optionally, manages its
+ colliders.
+ | |
ILinkSource | A generic source of a KAS link between two parts. | |
ILinkStateEventListener | Part module interface that defines the events for a link state changes. | |
ILinkTarget | A generic target of a KAS link between two parts. | |
ILinkUtils | Various tools to deal with KAS links. | |
ILinkVesselInfo | A generic interface to deal with the vessels info. | |
IPhysicsUtils | Various tools to deal with the gme's physics. | |
IWinchControl | Interface that allows operating the winch parts. |
+ + | Enumeration | Description |
---|---|---|
GUILinkMode | Specifies how the linking mode is displayed in GUI. | |
LinkActorType | Defines an actor that changes KAS link. | |
LinkState | Defines currect state of the link. |
ILinkSourceLinkToTarget Method |
+ + | Name | Description |
---|---|---|
LinkToTarget(ILinkTarget) | Establishes a link between two parts. | |
LinkToTarget(LinkActorType, ILinkTarget) | Establishes a link between two parts. |
ICommonConfigkeyDropConnector Property |
+ Namespace: + KASAPIv1
string keyDropConnector { get; }
public void ShortcutsDemo() { + var simpleY = Event.KeyboardEvent("Y"); + var alt_Y = Event.KeyboardEvent("&Y"); + var shift_Y = Event.KeyboardEvent("#Y"); + var ctrl_Y = Event.KeyboardEvent("$Y"); + var ctrl2_Y = Event.KeyboardEvent("^Y"); // Yup! It's CTRL too. + var numpad0 = Event.KeyboardEvent("[0]"); + var just0 = Event.KeyboardEvent("0"); + + // And here is how it's checked in the OnGUI() method. + if (Event.current.Equals(numpad0)) { + DebugEx.Info("You've pressed the numpad 0 key"); + } +}
ICommonConfigkeyPickupConnector Property |
+ Namespace: + KASAPIv1
string keyPickupConnector { get; }
public void ShortcutsDemo() { + var simpleY = Event.KeyboardEvent("Y"); + var alt_Y = Event.KeyboardEvent("&Y"); + var shift_Y = Event.KeyboardEvent("#Y"); + var ctrl_Y = Event.KeyboardEvent("$Y"); + var ctrl2_Y = Event.KeyboardEvent("^Y"); // Yup! It's CTRL too. + var numpad0 = Event.KeyboardEvent("[0]"); + var just0 = Event.KeyboardEvent("0"); + + // And here is how it's checked in the OnGUI() method. + if (Event.current.Equals(numpad0)) { + DebugEx.Info("You've pressed the numpad 0 key"); + } +}
ICommonConfigsndPathBipWrong Property |
+ Namespace: + KASAPIv1
string sndPathBipWrong { get; }
IKasEventsOnLinkBroken Property |
+ Namespace: + KASAPIv1
EventData<IKasLinkEvent> OnLinkBroken { get; }
The argument of the callback is a KAS event object that describes the link.
+ Consider using OnKASLinkedState(IKasLinkEvent, Boolean) when this state change + is needed in scope of just one part. +
public class KasEventsExample1: PartModule { + public override void OnAwake() { + base.OnAwake(); + KASAPI.KasEvents.OnStartLinking.Add(LinkStarted); + KASAPI.KasEvents.OnStopLinking.Add(LinkStopped); + KASAPI.KasEvents.OnLinkCreated.Add(LinkCreated); + KASAPI.KasEvents.OnLinkBroken.Add(LinkBroken); + } + + void OnDestroy() { + KASAPI.KasEvents.OnStartLinking.Remove(LinkStarted); + KASAPI.KasEvents.OnStopLinking.Remove(LinkStopped); + KASAPI.KasEvents.OnLinkCreated.Remove(LinkCreated); + KASAPI.KasEvents.OnLinkBroken.Remove(LinkBroken); + } + + void LinkStarted(ILinkSource source) { + DebugEx.Info("Link started by: {0}", source); + } + + void LinkStopped(ILinkSource source) { + DebugEx.Info("Link stopepd by: {0}", source); + } + + void LinkCreated(IKasLinkEvent ev) { + DebugEx.Info("Link created: {0} <=> {1}", ev.source, ev.target); + } + + void LinkBroken(IKasLinkEvent ev) { + DebugEx.Info("Link broken: {0} <=> {1}", ev.source, ev.target); + } +}
IKasEventsOnLinkCreated Property |
+ Namespace: + KASAPIv1
EventData<IKasLinkEvent> OnLinkCreated { get; }
The argument of the callback is a KAS event object that describes the link.
+ Consider using OnKASLinkedState(IKasLinkEvent, Boolean) when this state change + is needed in scope of just one part. +
public class KasEventsExample1: PartModule { + public override void OnAwake() { + base.OnAwake(); + KASAPI.KasEvents.OnStartLinking.Add(LinkStarted); + KASAPI.KasEvents.OnStopLinking.Add(LinkStopped); + KASAPI.KasEvents.OnLinkCreated.Add(LinkCreated); + KASAPI.KasEvents.OnLinkBroken.Add(LinkBroken); + } + + void OnDestroy() { + KASAPI.KasEvents.OnStartLinking.Remove(LinkStarted); + KASAPI.KasEvents.OnStopLinking.Remove(LinkStopped); + KASAPI.KasEvents.OnLinkCreated.Remove(LinkCreated); + KASAPI.KasEvents.OnLinkBroken.Remove(LinkBroken); + } + + void LinkStarted(ILinkSource source) { + DebugEx.Info("Link started by: {0}", source); + } + + void LinkStopped(ILinkSource source) { + DebugEx.Info("Link stopepd by: {0}", source); + } + + void LinkCreated(IKasLinkEvent ev) { + DebugEx.Info("Link created: {0} <=> {1}", ev.source, ev.target); + } + + void LinkBroken(IKasLinkEvent ev) { + DebugEx.Info("Link broken: {0} <=> {1}", ev.source, ev.target); + } +}
IKasEventsOnStartLinking Property |
+ Namespace: + KASAPIv1
EventData<ILinkSource> OnStartLinking { get; }
public class KasEventsExample1: PartModule { + public override void OnAwake() { + base.OnAwake(); + KASAPI.KasEvents.OnStartLinking.Add(LinkStarted); + KASAPI.KasEvents.OnStopLinking.Add(LinkStopped); + KASAPI.KasEvents.OnLinkCreated.Add(LinkCreated); + KASAPI.KasEvents.OnLinkBroken.Add(LinkBroken); + } + + void OnDestroy() { + KASAPI.KasEvents.OnStartLinking.Remove(LinkStarted); + KASAPI.KasEvents.OnStopLinking.Remove(LinkStopped); + KASAPI.KasEvents.OnLinkCreated.Remove(LinkCreated); + KASAPI.KasEvents.OnLinkBroken.Remove(LinkBroken); + } + + void LinkStarted(ILinkSource source) { + DebugEx.Info("Link started by: {0}", source); + } + + void LinkStopped(ILinkSource source) { + DebugEx.Info("Link stopepd by: {0}", source); + } + + void LinkCreated(IKasLinkEvent ev) { + DebugEx.Info("Link created: {0} <=> {1}", ev.source, ev.target); + } + + void LinkBroken(IKasLinkEvent ev) { + DebugEx.Info("Link broken: {0} <=> {1}", ev.source, ev.target); + } +}
IKasEventsOnStopLinking Property |
+ Namespace: + KASAPIv1
EventData<ILinkSource> OnStopLinking { get; }
public class KasEventsExample1: PartModule { + public override void OnAwake() { + base.OnAwake(); + KASAPI.KasEvents.OnStartLinking.Add(LinkStarted); + KASAPI.KasEvents.OnStopLinking.Add(LinkStopped); + KASAPI.KasEvents.OnLinkCreated.Add(LinkCreated); + KASAPI.KasEvents.OnLinkBroken.Add(LinkBroken); + } + + void OnDestroy() { + KASAPI.KasEvents.OnStartLinking.Remove(LinkStarted); + KASAPI.KasEvents.OnStopLinking.Remove(LinkStopped); + KASAPI.KasEvents.OnLinkCreated.Remove(LinkCreated); + KASAPI.KasEvents.OnLinkBroken.Remove(LinkBroken); + } + + void LinkStarted(ILinkSource source) { + DebugEx.Info("Link started by: {0}", source); + } + + void LinkStopped(ILinkSource source) { + DebugEx.Info("Link stopepd by: {0}", source); + } + + void LinkCreated(IKasLinkEvent ev) { + DebugEx.Info("Link created: {0} <=> {1}", ev.source, ev.target); + } + + void LinkBroken(IKasLinkEvent ev) { + DebugEx.Info("Link broken: {0} <=> {1}", ev.source, ev.target); + } +}
IKasLinkEventactor Property |
+ Namespace: + KASAPIv1
LinkActorType actor { get; }
IKasLinkEventsource Property |
+ Namespace: + KASAPIv1
ILinkSource source { get; }
IKasLinkEventtarget Property |
+ Namespace: + KASAPIv1
ILinkTarget target { get; }
ILinkCableJointcfgMaxCableLength Property |
+ Namespace: + KASAPIv1
float cfgMaxCableLength { get; }
ILinkCableJointdeployedCableLength Property |
+ Namespace: + KASAPIv1
float deployedCableLength { get; }
ILinkCableJointheadRb Property |
+ Namespace: + KASAPIv1
Rigidbody headRb { get; }
ILinkCableJointrealCableLength Property |
+ Namespace: + KASAPIv1
float realCableLength { get; }
ILinkJointcfgJointName Property |
+ Namespace: + KASAPIv1
string cfgJointName { get; }
ILinkJointcoupleOnLinkMode Property |
+ Namespace: + KASAPIv1
bool coupleOnLinkMode { get; }
ILinkJointisLinked Property |
+ Namespace: + KASAPIv1
bool isLinked { get; }
ILinkJointlinkSource Property |
+ Namespace: + KASAPIv1
ILinkSource linkSource { get; }
ILinkJointlinkTarget Property |
+ Namespace: + KASAPIv1
ILinkTarget linkTarget { get; }
ILinkPeerattachNode Property |
+ Namespace: + KASAPIv1
AttachNode attachNode { get; }
ILinkPeercfgAttachNodeName Property |
+ Namespace: + KASAPIv1
string cfgAttachNodeName { get; }
ILinkPeercfgDependentNodeNames Property |
+ Namespace: + KASAPIv1
string[] cfgDependentNodeNames { get; }
+ The module will track the nodes and will adjust its state as those nodes were owned by the + module. However, this module will never change the mode of those nodes. This can be used to + lock or block the peer modules that control the different primary nodes, but need to cooperate + with the other similar modules on the part. This setting allows defining a group of peer + modules which only allow linking of a single module at the time. +
+ Note, that the part's cfgAttachNodeName is not present in this list by + default. The implementation should explicitly check for the primary node, or the config must + take care of it. +
ILinkPeercfgLinkType Property |
+ Namespace: + KASAPIv1
string cfgLinkType { get; }
ILinkPeercoupleNode Property |
+ Namespace: + KASAPIv1
AttachNode coupleNode { get; }
ILinkPeerisLinked Property |
+ Namespace: + KASAPIv1
bool isLinked { get; }
ILinkPeerisLocked Property |
+ Namespace: + KASAPIv1
ILinkPeerisNodeBlocked Property |
+ Namespace: + KASAPIv1
bool isNodeBlocked { get; }
ILinkPeerlinkModuleIndex Property |
+ Namespace: + KASAPIv1
int linkModuleIndex { get; }
ILinkPeerlinkPartId Property |
+ Namespace: + KASAPIv1
uint linkPartId { get; }
ILinkPeerlinkState Property |
+ Namespace: + KASAPIv1
LinkState linkState { get; }
ILinkPeernodeTransform Property |
+ Namespace: + KASAPIv1
Transform nodeTransform { get; }
ILinkPeerotherPeer Property |
+ Namespace: + KASAPIv1
ILinkPeer otherPeer { get; }
ILinkPeerpart Property |
+ Namespace: + KASAPIv1
ILinkRenderercfgRendererName Property |
+ Namespace: + KASAPIv1
string cfgRendererName { get; }
ILinkRenderercolorOverride Property |
+ Namespace: + KASAPIv1
Nullable<Color> colorOverride { get; set; }
ILinkRendererisPhysicalCollider Property |
+ Namespace: + KASAPIv1
bool isPhysicalCollider { get; set; }
ILinkRendererisStarted Property |
+ Namespace: + KASAPIv1
ILinkRenderershaderNameOverride Property |
+ Namespace: + KASAPIv1
string shaderNameOverride { get; set; }
ILinkRenderersourceTransform Property |
+ Namespace: + KASAPIv1
Transform sourceTransform { get; }
ILinkRendererstretchRatio Property |
+ Namespace: + KASAPIv1
float stretchRatio { get; set; }
+ This ratio only affects the visual representation. For the renderers that don't care about + stretching it's ok to always return 1.0 from the getter and ignore calls to the setter. +
ILinkRenderertargetTransform Property |
+ Namespace: + KASAPIv1
Transform targetTransform { get; }
ILinkSourcelinkJoint Property |
+ Namespace: + KASAPIv1
ILinkJoint linkJoint { get; }
ILinkSourcelinkRenderer Property |
+ Namespace: + KASAPIv1
ILinkRenderer linkRenderer { get; }
public ILinkRenderer linkRenderer { get; private set; } + +[KSPField] +public string rendererName = ""; + +void InitRenderer() { + linkRenderer = part.FindModulesImplementing<ILinkRenderer>() + .FirstOrDefault(r => r.cfgRendererName == rendererName); +}
ILinkSourcelinkTarget Property |
+ Namespace: + KASAPIv1
ILinkTarget linkTarget { get; }
// Returns the linked part of the source, if any. It assumes there is exactly one source module +// on the source part. +public static Part FindTargetFromSource(Part srcPart) { + var source = srcPart.FindModulesImplementing<ILinkSource>() + .FirstOrDefault(s => s.linkTarget != null); + if (source == null) { + Debug.Log("Source is not connected"); + return null; + } + return source.linkTarget.part; +}
ILinkTargetlinkSource Property |
+ Namespace: + KASAPIv1
ILinkSource linkSource { get; set; }
+ Setting of this property changes the target state: +
Assigning the same value to this property doesn't trigger a state change event.
+ Note, that not any state transition is possible. If the transition is invalid then an + exception is thrown. +
+ It's descouraged to assign this property from a code other than an implementation of + ILinkSource. +
// Returns the linked part of the target, if any. It assumes there is exactly one target module +// on the part. +public static Part FindSourceFromTarget(Part tgtPart) { + var source = tgtPart.FindModulesImplementing<ILinkTarget>() + .FirstOrDefault(s => s.linkSource != null); + if (source == null) { + Debug.Log("Target is not connected"); + return null; + } + return source.linkSource.part; +}
ILinkVesselInfopart Property |
+ Namespace: + KASAPIv1
ILinkVesselInfovesselInfo Property |
+ Namespace: + KASAPIv1
DockedVesselInfo vesselInfo { get; set; }
IWinchControlcfgMaxCableLength Property |
+ Namespace: + KASAPIv1
float cfgMaxCableLength { get; }
IWinchControlcfgMotorMaxSpeed Property |
+ Namespace: + KASAPIv1
float cfgMotorMaxSpeed { get; }
IWinchControlcurrentCableLength Property |
+ Namespace: + KASAPIv1
float currentCableLength { get; }
IWinchControlisConnectorLocked Property |
+ Namespace: + KASAPIv1
bool isConnectorLocked { get; }
IWinchControlmotorCurrentSpeed Property |
+ Namespace: + KASAPIv1
float motorCurrentSpeed { get; }
+ This is the speed at which the cable is being extended or retracted at the current moment. + The actual speed of the motor can differ from what was set via the control methods (e.g. + SetMotor(Single)) due to there is some inetria momentum. Negative speed means the cable + is being retracted, and the positive speed means the cable is being extened. +
+ The motor speed is always trying to match the motorTargetSpeed. Depending on the + part's implementation and settings, some time may be needed to actually have the match. +
IWinchControlmotorTargetSpeed Property |
+ Namespace: + KASAPIv1
float motorTargetSpeed { get; }
The URL might be misspelled or the page you are looking for is no longer available. If you entered +the web address, check that it doesn't contain a typo. You can use the search box at the top of the page to +try and locate the page.
+ICommonConfig Properties |
The ICommonConfig type exposes the following members.
+ + | Name | Description |
---|---|---|
keyDropConnector | Keyboard key to trigger the drop connector event. | |
keyPickupConnector | Keyboard key to trigger the pickup connector event. | |
sndPathBipWrong | URL of the sound for the impossible action. |
IKasEvents Properties |
The IKasEvents type exposes the following members.
+ + | Name | Description |
---|---|---|
OnLinkBroken | Triggers when a link between two parts has been broken. | |
OnLinkCreated | Triggers when a link between two parts has been successfully established. | |
OnStartLinking | Triggers when a source has initiated linking mode. | |
OnStopLinking | Triggers when a source has stopped linking mode. |
ILinkCableJoint Properties |
The ILinkCableJoint type exposes the following members.
+ + | Name | Description |
---|---|---|
cfgMaxCableLength | Maximum allowed distance between the parts to establish a link. | |
deployedCableLength |
+ Maximum possible distance between the source and head/target physical anchors.
+ | |
headRb | Rigidbody of the physical cable head. | |
realCableLength |
+ Returns the actual distance between the source and target/head physical anchors.
+ |
ILinkJoint Properties |
The ILinkJoint type exposes the following members.
+ + | Name | Description |
---|---|---|
cfgJointName | Identifier of the joint on the part. | |
coupleOnLinkMode | Tells the current coupling mode. | |
isLinked | Tells if there is a physical joint created. | |
linkSource | Tells the current link source. | |
linkTarget | Tells the current link target. |
ILinkPeer Properties |
The ILinkPeer type exposes the following members.
+ + | Name | Description |
---|---|---|
attachNode | Parsed attach node definition of the peer. | |
cfgAttachNodeName | Name of the attach node on the part. | |
cfgDependentNodeNames |
+ List of the attach node names, which this module doesn't own, but wants to align the state
+ with.
+ | |
cfgLinkType | Source link type identifier. | |
coupleNode |
+ Attach node to use when the peers need to couple into a single parts hierarchy.
+ | |
isLinked | Tells if this peer is currectly linked to another peer. | |
isLocked |
+ Tells if the peer's link ability is disabled due to it's attach node is taken by another peer
+ on the same part.
+ | |
isNodeBlocked | Tells if the peer's attach node is occupied by an incompatible part. | |
linkModuleIndex | The persisted index of the module on the part of the other peer. | |
linkPartId | The persisted ID of the linked part of the other peer. | |
linkState | Current state of the peer. | |
nodeTransform |
+ Transform that defines the position and orientation of the base node to which all the
+ renderers and physical anchors are aligned.
+ | |
otherPeer | Other end of the link. | |
part | Part that owns the source. |
ILinkRenderer Properties |
The ILinkRenderer type exposes the following members.
+ + | Name | Description |
---|---|---|
cfgRendererName |
+ Unique name of the randerer that is used by the other modules to find this renderer.
+ | |
colorOverride | Temporally sets another color to the link meshes. | |
isPhysicalCollider | Tells if the link interacts with the rigid bodies. | |
isStarted | Tells if the renderer is started and active. | |
shaderNameOverride | Temporally sets another shader to the link meshes. | |
sourceTransform |
+ Base position/direction of the connection point at the beginning of the link. The source
+ joint models will be aligned against this transform.
+ | |
stretchRatio |
+ Defines how significantly the link has stretched or shrinked comparing to it's "normal" state.
+ | |
targetTransform |
+ Base position/direction of the connection point at the end of the link. The target
+ joint models will be aligned against this transform.
+ |
ILinkSource Properties |
The ILinkSource type exposes the following members.
+ + | Name | Description |
---|---|---|
linkJoint | Joint module that manages a physical link. | |
linkRenderer | Renderer of the link meshes. | |
linkTarget | Target of the link. |
ILinkTarget Properties |
The ILinkTarget type exposes the following members.
+ + | Name | Description |
---|---|---|
linkSource | Source that maintains the link. |
ILinkVesselInfo Properties |
The ILinkVesselInfo type exposes the following members.
+ + | Name | Description |
---|---|---|
part | Part that owns the info. | |
vesselInfo | The persisted vessel's info. |
IWinchControl Properties |
The IWinchControl type exposes the following members.
+ + | Name | Description |
---|---|---|
cfgMaxCableLength | Maximum reserve of the cable in the winch. | |
cfgMotorMaxSpeed | Maximum speed of retracting or extending the cable. | |
currentCableLength | Amount of the cable that was extended till the moment. | |
isConnectorLocked | Tells if the cable connector head is locked into the winch. | |
motorCurrentSpeed | Current speed of the motor spindel. | |
motorTargetSpeed | Desired speed of the motor spindel. |
GUILinkMode Enumeration |
+ Namespace: + KASAPIv1
+ + | Member name | Value | Description |
---|---|---|---|
None | 0 | Uninitialized value. Must never be used in the real calls. | |
Interactive | 1 | + The ending part of the link will expect the player's input to complete or cancel the link. + | |
API | 2 | No GUI interaction is expected to complete the link. |
IAttachNodesUtils Interface |
+ Namespace: + KASAPIv1
The IAttachNodesUtils type exposes the following members.
+ + | Name | Description |
---|---|---|
AddNode | Adds an existing attach node into the part. | |
CreateNode | Creates a new attach node on the part. | |
DropNode | Drops the attach node on the part. | |
GetTransformForNode | Gets or creates a transform object for the attach node. | |
NodeId | Returns a user friendly attach node representation. | |
ParseNodeFromString | Creates an attach node form the part's config definition string. |
ICommonConfig Interface |
+ Namespace: + KASAPIv1
The ICommonConfig type exposes the following members.
+ + | Name | Description |
---|---|---|
keyDropConnector | Keyboard key to trigger the drop connector event. | |
keyPickupConnector | Keyboard key to trigger the pickup connector event. | |
sndPathBipWrong | URL of the sound for the impossible action. |
IJointUtils Interface |
+ Namespace: + KASAPIv1
The IJointUtils type exposes the following members.
+ + | Name | Description |
---|---|---|
DumpJoint | Outputs all properties of the joint to the string. | |
DumpSpringJoint | Outputs all properties of the joint to the string. | |
ResetJoint | Initializes joint to a consistent state. | |
SetupDistanceJoint | Sets up a cannonical distance joint. | |
SetupFixedJoint | Sets up a cannonical fixed joint. | |
SetupPrismaticJoint | Sets up joint so what it becomes a prismatic joint. | |
SetupSphericalJoint | Sets up joint so what it becomes a spherical hinge joint. |
IKasEvents Interface |
+ Namespace: + KASAPIv1
The IKasEvents type exposes the following members.
+ + | Name | Description |
---|---|---|
OnLinkBroken | Triggers when a link between two parts has been broken. | |
OnLinkCreated | Triggers when a link between two parts has been successfully established. | |
OnStartLinking | Triggers when a source has initiated linking mode. | |
OnStopLinking | Triggers when a source has stopped linking mode. |
public class KasEventsExample1: PartModule { + public override void OnAwake() { + base.OnAwake(); + KASAPI.KasEvents.OnStartLinking.Add(LinkStarted); + KASAPI.KasEvents.OnStopLinking.Add(LinkStopped); + KASAPI.KasEvents.OnLinkCreated.Add(LinkCreated); + KASAPI.KasEvents.OnLinkBroken.Add(LinkBroken); + } + + void OnDestroy() { + KASAPI.KasEvents.OnStartLinking.Remove(LinkStarted); + KASAPI.KasEvents.OnStopLinking.Remove(LinkStopped); + KASAPI.KasEvents.OnLinkCreated.Remove(LinkCreated); + KASAPI.KasEvents.OnLinkBroken.Remove(LinkBroken); + } + + void LinkStarted(ILinkSource source) { + DebugEx.Info("Link started by: {0}", source); + } + + void LinkStopped(ILinkSource source) { + DebugEx.Info("Link stopepd by: {0}", source); + } + + void LinkCreated(IKasLinkEvent ev) { + DebugEx.Info("Link created: {0} <=> {1}", ev.source, ev.target); + } + + void LinkBroken(IKasLinkEvent ev) { + DebugEx.Info("Link broken: {0} <=> {1}", ev.source, ev.target); + } +}
IKasJointEventsListener Interface |
+ Namespace: + KASAPIv1
The IKasJointEventsListener type exposes the following members.
+ + | Name | Description |
---|---|---|
OnKASJointBreak |
+ Triggers when a connection on the object is broken due to too strong force applied.
+ |
class BrokenJointListenerExample : PartModule, IKasJointEventsListener { + /// <inheritdoc/> + public virtual void OnKASJointBreak(GameObject hostObj, float breakForce) { + if (hostObj.name == "MyFakeRB") { + DebugEx.Warning("Joint on MyFakeRB is broken with force {0}", breakForce); + Destroy(hostObj); + } + } +}
IKasLinkEvent Interface |
+ Namespace: + KASAPIv1
The IKasLinkEvent type exposes the following members.
ILinkCableJoint Interface |
+ Namespace: + KASAPIv1
The ILinkCableJoint type exposes the following members.
+ + | Name | Description |
---|---|---|
cfgMaxCableLength | Maximum allowed distance between the parts to establish a link. | |
deployedCableLength |
+ Maximum possible distance between the source and head/target physical anchors.
+ | |
headRb | Rigidbody of the physical cable head. | |
realCableLength |
+ Returns the actual distance between the source and target/head physical anchors.
+ |
+ + | Name | Description |
---|---|---|
SetCableLength |
+ Sets the maximum possible distance between the source and the head/target physical anchors.
+ | |
StartPhysicalHead |
+ Attaches the specified object to the source and starts the environmental forces on it.
+ | |
StopPhysicalHead | Stops handling the physical head. |
+ The specifics of this module is that the distance between the linked parts becomes variable. + Once the link is created, the distance limit is set to the actual distance between the source + and target. This limit won't allow the objects to separate too far from each other, but the + objects will be allowed to come closer. The code can adjust the limit once the joint is + created. +
+ Due to the specifics of handling this kind of joints in PhysX, the real distance between the + objects can become greater than the distance limit. In fact, if there are forces that try + to separate the objects, then the actual distance will always be a bit more than the limit. Do + not expect this difference to have any meaning, it depends on the PhysX engine and can be + anything. +
ILinkJoint Interface |
+ Namespace: + KASAPIv1
The ILinkJoint type exposes the following members.
+ + | Name | Description |
---|---|---|
cfgJointName | Identifier of the joint on the part. | |
coupleOnLinkMode | Tells the current coupling mode. | |
isLinked | Tells if there is a physical joint created. | |
linkSource | Tells the current link source. | |
linkTarget | Tells the current link target. |
+ + | Name | Description |
---|---|---|
AdjustJoint | Requests the joint to become unbreakable or normal. | |
CheckConstraints | Checks if the joint constraints allow the link to be established. | |
CreateJoint | Sets up a physical joint between the source and target. | |
DropJoint | Destroys a physical link between the source and the target. | |
SetCoupleOnLinkMode | Changes the current parts couple mode. |
+ Every KAS part must have a joint module that controls how the KAS joints are maintained. +
+ This interface is primarily designed for use form the ILinkSource implementations. + A third-party code must not interact with it directly. +
ILinkPeer Interface |
+ Namespace: + KASAPIv1
The ILinkPeer type exposes the following members.
+ + | Name | Description |
---|---|---|
attachNode | Parsed attach node definition of the peer. | |
cfgAttachNodeName | Name of the attach node on the part. | |
cfgDependentNodeNames |
+ List of the attach node names, which this module doesn't own, but wants to align the state
+ with.
+ | |
cfgLinkType | Source link type identifier. | |
coupleNode |
+ Attach node to use when the peers need to couple into a single parts hierarchy.
+ | |
isLinked | Tells if this peer is currectly linked to another peer. | |
isLocked |
+ Tells if the peer's link ability is disabled due to it's attach node is taken by another peer
+ on the same part.
+ | |
isNodeBlocked | Tells if the peer's attach node is occupied by an incompatible part. | |
linkModuleIndex | The persisted index of the module on the part of the other peer. | |
linkPartId | The persisted ID of the linked part of the other peer. | |
linkState | Current state of the peer. | |
nodeTransform |
+ Transform that defines the position and orientation of the base node to which all the
+ renderers and physical anchors are aligned.
+ | |
otherPeer | Other end of the link. | |
part | Part that owns the source. |
ILinkRenderer Interface |
+ Namespace: + KASAPIv1
The ILinkRenderer type exposes the following members.
+ + | Name | Description |
---|---|---|
cfgRendererName |
+ Unique name of the randerer that is used by the other modules to find this renderer.
+ | |
colorOverride | Temporally sets another color to the link meshes. | |
isPhysicalCollider | Tells if the link interacts with the rigid bodies. | |
isStarted | Tells if the renderer is started and active. | |
shaderNameOverride | Temporally sets another shader to the link meshes. | |
sourceTransform |
+ Base position/direction of the connection point at the beginning of the link. The source
+ joint models will be aligned against this transform.
+ | |
stretchRatio |
+ Defines how significantly the link has stretched or shrinked comparing to it's "normal" state.
+ | |
targetTransform |
+ Base position/direction of the connection point at the end of the link. The target
+ joint models will be aligned against this transform.
+ |
+ + | Name | Description |
---|---|---|
CheckColliderHits | Verifies that there are no obstacles beween the points. | |
StartRenderer | Starts rendering a link between the objects. | |
StopRenderer | Cancels rendering the link. | |
UpdateLink | Called when a link representation update is required. |
ILinkSource Interface |
+ Namespace: + KASAPIv1
The ILinkSource type exposes the following members.
+ + | Name | Description |
---|---|---|
linkJoint | Joint module that manages a physical link. | |
linkRenderer | Renderer of the link meshes. | |
linkTarget | Target of the link. |
+ + | Name | Description |
---|---|---|
BreakCurrentLink | Breaks the link between the source and the target. | |
CancelLinking | Cancels the linking mode without creating a link. | |
CheckCanLinkTo | Verifies if a link between the parts can be successful. | |
LinkToTarget(ILinkTarget) | Establishes a link between two parts. | |
LinkToTarget(LinkActorType, ILinkTarget) | Establishes a link between two parts. | |
StartLinking | Starts the linking mode of this source. |
+ Source is the initiator of the link to the another part. It holds all the logic on making and + maintaining the actual connection between the two parts. The other end of the connection must be + ILinkTarget which implements its own piece of the logic. +
+ The link source have a state that defines what it can do (linkState). + Not all actions are allowed in any state. The following state diagram tells what the source + can do and when: +
Transition | Action |
---|---|
Available => Linking | + This module has initiated a link via the StartLinking(GUILinkMode, LinkActorType) method call. + |
Available => RejectingLinks | + Some other source module in the world has initiated a link. + |
Linking => Available | + This module has cancelled the linking mode via the CancelLinking method call. + |
Linking => Linked | This module has established a link. |
RejectingLinks => Available | + Some other module, which initiated a link, has cancelled or completed the linking mode. + |
RejectingLinks => Locked | + Some other module on the same part, which initiated a link, has established a link. I.e. this + part cannot have more links. + |
Linked => Available | + This module has broke its link via the BreakCurrentLink(LinkActorType) method call. + |
Locked => Available | + Some other module on the same part, which was linked, has broke its link via the + BreakCurrentLink(LinkActorType) method call. + |
// Connects two parts assuming the source and the target parts own exactly one link module. +public static bool ConnectParts(Part srcPart, Part tgtPart) { + var source = srcPart.FindModuleImplementing<ILinkSource>(); + var target = tgtPart.FindModuleImplementing<ILinkTarget>(); + if (source == null || target == null || source.cfgLinkType != target.cfgLinkType) { + Debug.LogError("Source and target cannot link"); + return false; + } + // GUILinkMode.API mode tells the implementation to not execute any user facing effects on the + // link. See GUILinkMode for more details. + if (!source.StartLinking(GUILinkMode.API, LinkActorType.API) || !source.LinkToTarget(target)) { + // Here we can only fail due to the constraints. E.g. the link mode is not supported, or the + // joint module doesn't give the green light. + Debug.LogError("Linking failed"); + source.CancelLinking(); + return false; + } + Debug.LogFormat("Established link with part: id={0}", source.linkPartId); + return true; +}
// Disconnects the source part from its target. Only once source can be connected on the part. +// And it can be connected to the exactly one target. +public static void DisconnectParts(Part srcPart) { + var source = srcPart.FindModulesImplementing<ILinkSource>() + .FirstOrDefault(s => s.linkTarget != null); + if (source == null) { + Debug.LogWarningFormat("Part is not connected to anything"); + return; + } + // LinkActorType.API tells the implementation to not execute any user facing effects on the + // link. See LinkActorType for more details. + source.BreakCurrentLink(LinkActorType.API); +}
// Returns the linked part of the source, if any. It assumes there is exactly one source module +// on the source part. +public static Part FindTargetFromSource(Part srcPart) { + var source = srcPart.FindModulesImplementing<ILinkSource>() + .FirstOrDefault(s => s.linkTarget != null); + if (source == null) { + Debug.Log("Source is not connected"); + return null; + } + return source.linkTarget.part; +}
// Checks if the two parts are connected via a KAS link. +public static bool CheckIfConnected(Part srcPart, Part tgtPart) { + return srcPart.FindModulesImplementing<ILinkSource>() + .Any(s => s.linkTarget != null && s.linkTarget.part == tgtPart); +}
// Sets up a sample state machine for the source states. +public static void SetupSourceStateModel() { + var linkStateMachine = new SimpleStateMachine<LinkState>(true /* strict */); + linkStateMachine.SetTransitionConstraint( + LinkState.Available, + new[] {LinkState.Linking, LinkState.RejectingLinks}); + linkStateMachine.SetTransitionConstraint( + LinkState.Linking, + new[] {LinkState.Available, LinkState.Linked}); + linkStateMachine.SetTransitionConstraint( + LinkState.Linked, + new[] {LinkState.Available}); + linkStateMachine.SetTransitionConstraint( + LinkState.Locked, + new[] {LinkState.Available}); + linkStateMachine.SetTransitionConstraint( + LinkState.RejectingLinks, + new[] {LinkState.Available, LinkState.Locked}); + + linkStateMachine.AddStateHandlers( + LinkState.Available, + enterHandler: x => Debug.Log("Source is available"), + leaveHandler: x => Debug.Log("Source is NOT available")); +}
ILinkStateEventListener Interface |
+ Namespace: + KASAPIv1
The ILinkStateEventListener type exposes the following members.
+ + | Name | Description |
---|---|---|
OnKASLinkedState | Triggers when any module on the part has created a link. | |
OnKASNodeBlockedState |
+ Triggers when a peer locks itself due to its attach node is blocked by an incompatible part.
+ |
ILinkTarget Interface |
+ Namespace: + KASAPIv1
The ILinkTarget type exposes the following members.
+ + | Name | Description |
---|---|---|
linkSource | Source that maintains the link. |
+ The target is a sink for a link initiated by the another part's ILinkSource. +
+ The link target have a state that defines what it can do (linkState). + Not all actions are allowed in any state. The following state diagram tells what the target + can do and when: +
Transition | Action |
---|---|
Available => AcceptingLinks | + This target is able to connect to a source that has just initiated a link. + |
Available => RejectingLinks | + This target cannot connect to a source that has just initiated a link. + |
AcceptingLinks => Available | + The source module has ended its linking mode without linking to this target. + |
AcceptingLinks => Linked | A source from the world has linked to this target. |
AcceptingLinks => Locked | + A source from the world has linked to another target on the part that owns this target. + |
Linked => Available | The link to this target has been broken by the source. |
Locked => Available | + A source from the world has broke a link to another target on the part that owns this + target. + |
RejectingLinks => Available | + A source from the world has ended the linking mode, and the target's part hasn't linked. + |
RejectingLinks => Locked | + A source from the world has linked to the owner of this target but thru another target. + |
ILinkUtils Interface |
+ Namespace: + KASAPIv1
The ILinkUtils type exposes the following members.
+ + | Name | Description |
---|---|---|
CoupleParts | Couples two parts together given they belong to the different vessels. | |
DecoupleParts | Decouples the connected parts and breaks down one vessel into two. | |
FindLinkPeer | Finds the other peer of the link. |
ILinkVesselInfo Interface |
+ Namespace: + KASAPIv1
The ILinkVesselInfo type exposes the following members.
+ + | Name | Description |
---|---|---|
part | Part that owns the info. | |
vesselInfo | The persisted vessel's info. |
IPhysicsUtils Interface |
+ Namespace: + KASAPIv1
The IPhysicsUtils type exposes the following members.
+ + | Name | Description |
---|---|---|
ApplyGravity | Applies the forces that affect a rigidbody on a selectial body. |
IWinchControl Interface |
+ Namespace: + KASAPIv1
The IWinchControl type exposes the following members.
+ + | Name | Description |
---|---|---|
cfgMaxCableLength | Maximum reserve of the cable in the winch. | |
cfgMotorMaxSpeed | Maximum speed of retracting or extending the cable. | |
currentCableLength | Amount of the cable that was extended till the moment. | |
isConnectorLocked | Tells if the cable connector head is locked into the winch. | |
motorCurrentSpeed | Current speed of the motor spindel. | |
motorTargetSpeed | Desired speed of the motor spindel. |
+ + | Name | Description |
---|---|---|
ReleaseCable | Sets the deployed cable length to the maximum value allowed by the part. | |
SetMotor | Sets the winch motor to the desired speed. | |
StretchCable |
+ Sets the deployed cable length to the actual distance between the winch and the connector.
+ |
KASAPI Class |
+ Namespace: + KASAPIv1
The KASAPI type exposes the following members.
+ + | Name | Description |
---|---|---|
AttachNodesUtils | KAS attach nodes utils. | |
CommonConfig | KAS common config settings. | |
isLoaded | Tells if API V1 was loaded and ready to use. | |
JointUtils | KAS joints untils. | |
KasEvents | KAS global events. | |
LinkUtils | KAS link utils. | |
PhysicsUtils | KAS physics utils. |
LinkActorType Enumeration |
+ Namespace: + KASAPIv1
+ + | Member name | Value | Description |
---|---|---|---|
None | 0 | Actor is unspecified. | |
API | 1 | Thrid-party code has affected the link during its normal workflow. | |
Physics | 2 | Link has changed as a result of physics effect. | |
Player | 3 | Player input has affected the link state. |
// Disconnects the source part from its target. Only once source can be connected on the part. +// And it can be connected to the exactly one target. +public static void DisconnectParts(Part srcPart) { + var source = srcPart.FindModulesImplementing<ILinkSource>() + .FirstOrDefault(s => s.linkTarget != null); + if (source == null) { + Debug.LogWarningFormat("Part is not connected to anything"); + return; + } + // LinkActorType.API tells the implementation to not execute any user facing effects on the + // link. See LinkActorType for more details. + source.BreakCurrentLink(LinkActorType.API); +}
LinkState Enumeration |
+ Namespace: + KASAPIv1
+ + | Member name | Value | Description |
---|---|---|---|
None | 0 | Initial and an invalid state. It must never be normally used. | |
Available | 1 | Module is avalable for the links. | |
Locked | 2 | + Module is unavailable for the link because of another module on the part has established one. + | |
Linking | 3 | + Module has initated an outgoing link request and expecting for it to be accepted. + | |
Linked | 4 | Module is linked to another module. | |
AcceptingLinks | 5 | Module is ready to accept a link and may accept the request. | |
RejectingLinks | 6 | Module doesn't accept link and will reject any request. | |
NodeIsBlocked | 7 | + The attach node, allocated to the module, is occupied by another part, which doesn't support + linking. + |
If you are not redirected automatically, follow this link to the default topic.
+ + diff --git a/docs/APIv1/scripts/branding-Website.js b/docs/APIv1/scripts/branding-Website.js new file mode 100644 index 00000000..dc31b27a --- /dev/null +++ b/docs/APIv1/scripts/branding-Website.js @@ -0,0 +1,624 @@ +//=============================================================================================================== +// System : Sandcastle Help File Builder +// File : branding-Website.js +// Author : Eric Woodruff (Eric@EWoodruff.us) +// Updated : 03/04/2015 +// Note : Copyright 2014-2015, Eric Woodruff, All rights reserved +// Portions Copyright 2014 Sam Harwell, All rights reserved +// +// This file contains the methods necessary to implement the lightweight TOC and search functionality. +// +// This code is published under the Microsoft Public License (Ms-PL). A copy of the license should be +// distributed with the code. It can also be found at the project website: https://GitHub.com/EWSoftware/SHFB. This +// notice, the author's name, and all copyright notices must remain intact in all applications, documentation, +// and source files. +// +// Date Who Comments +// ============================================================================================================== +// 05/04/2014 EFW Created the code based on a combination of the lightweight TOC code from Sam Harwell and +// the existing search code from SHFB. +//=============================================================================================================== + +// Width of the TOC +var tocWidth; + +// Search method (0 = To be determined, 1 = ASPX, 2 = PHP, anything else = client-side script +var searchMethod = 0; + +// Table of contents script + +// Initialize the TOC by restoring its width from the cookie if present +function InitializeToc() +{ + tocWidth = parseInt(GetCookie("TocWidth", "280")); + ResizeToc(); + $(window).resize(SetNavHeight) +} + +function SetNavHeight() +{ + $leftNav = $("#leftNav") + $topicContent = $("#TopicContent") + leftNavPadding = $leftNav.outerHeight() - $leftNav.height() + contentPadding = $topicContent.outerHeight() - $topicContent.height() + // want outer height of left navigation div to match outer height of content + leftNavHeight = $topicContent.outerHeight() - leftNavPadding + $leftNav.css("min-height", leftNavHeight + "px") +} + +// Increase the TOC width +function OnIncreaseToc() +{ + if(tocWidth < 1) + tocWidth = 280; + else + tocWidth += 100; + + if(tocWidth > 680) + tocWidth = 0; + + ResizeToc(); + SetCookie("TocWidth", tocWidth); +} + +// Reset the TOC to its default width +function OnResetToc() +{ + tocWidth = 0; + + ResizeToc(); + SetCookie("TocWidth", tocWidth); +} + +// Resize the TOC width +function ResizeToc() +{ + var toc = document.getElementById("leftNav"); + + if(toc) + { + // Set TOC width + toc.style.width = tocWidth + "px"; + + var leftNavPadding = 10; + + document.getElementById("TopicContent").style.marginLeft = (tocWidth + leftNavPadding) + "px"; + + // Position images + document.getElementById("TocResize").style.left = (tocWidth + leftNavPadding) + "px"; + + // Hide/show increase TOC width image + document.getElementById("ResizeImageIncrease").style.display = (tocWidth >= 680) ? "none" : ""; + + // Hide/show reset TOC width image + document.getElementById("ResizeImageReset").style.display = (tocWidth < 680) ? "none" : ""; + } + + SetNavHeight() +} + +// Toggle a TOC entry between its collapsed and expanded state +function Toggle(item) +{ + var isExpanded = $(item).hasClass("tocExpanded"); + + $(item).toggleClass("tocExpanded tocCollapsed"); + + if(isExpanded) + { + Collapse($(item).parent()); + } + else + { + var childrenLoaded = $(item).parent().attr("data-childrenloaded"); + + if(childrenLoaded) + { + Expand($(item).parent()); + } + else + { + var tocid = $(item).next().attr("tocid"); + + $.ajax({ + url: "../toc/" + tocid + ".xml", + async: true, + dataType: "xml", + success: function(data) + { + BuildChildren($(item).parent(), data); + } + }); + } + } +} + +// HTML encode a value for use on the page +function HtmlEncode(value) +{ + // Create an in-memory div, set it's inner text (which jQuery automatically encodes) then grab the encoded + // contents back out. The div never exists on the page. + return $('').text(value).html(); +} + +// Build the child entries of a TOC entry +function BuildChildren(tocDiv, data) +{ + var childLevel = +tocDiv.attr("data-toclevel") + 1; + var childTocLevel = childLevel >= 10 ? 10 : childLevel; + var elements = data.getElementsByTagName("HelpTOCNode"); + + var isRoot = true; + + if(data.getElementsByTagName("HelpTOC").length == 0) + { + // The first node is the root node of this group, don't show it again + isRoot = false; + } + + for(var i = elements.length - 1; i > 0 || (isRoot && i == 0); i--) + { + var childHRef, childId = elements[i].getAttribute("Url"); + + if(childId != null && childId.length > 5) + { + // The Url attribute has the form "html/{childId}.htm" + childHRef = "../" + childId; + childId = childId.substring(childId.lastIndexOf("/") + 1, childId.lastIndexOf(".")); + } + else + { + // The Id attribute is in raw form. There is no URL (empty container node). In this case, we'll + // just ignore it and go nowhere. It's a rare case that isn't worth trying to get the first child. + // Instead, we'll just expand the node (see below). + childHRef = "#"; + childId = elements[i].getAttribute("Id"); + } + + var existingItem = null; + + tocDiv.nextAll().each(function() + { + if(!existingItem && $(this).children().last("a").attr("tocid") == childId) + { + existingItem = $(this); + } + }); + + if(existingItem != null) + { + // First move the children of the existing item + var existingChildLevel = +existingItem.attr("data-toclevel"); + var doneMoving = false; + var inserter = tocDiv; + + existingItem.nextAll().each(function() + { + if(!doneMoving && +$(this).attr("data-toclevel") > existingChildLevel) + { + inserter.after($(this)); + inserter = $(this); + $(this).attr("data-toclevel", +$(this).attr("data-toclevel") + childLevel - existingChildLevel); + + if($(this).hasClass("current")) + $(this).attr("class", "toclevel" + (+$(this).attr("data-toclevel") + " current")); + else + $(this).attr("class", "toclevel" + (+$(this).attr("data-toclevel"))); + } + else + { + doneMoving = true; + } + }); + + // Now move the existing item itself + tocDiv.after(existingItem); + existingItem.attr("data-toclevel", childLevel); + existingItem.attr("class", "toclevel" + childLevel); + } + else + { + var hasChildren = elements[i].getAttribute("HasChildren"); + var childTitle = HtmlEncode(elements[i].getAttribute("Title")); + var expander = ""; + + if(hasChildren) + expander = ""; + + var text = "Omitted " + (matchingFileIndices.length - rankings.length) + " more results
"; + + return content; +} diff --git a/docs/APIv1/scripts/branding.js b/docs/APIv1/scripts/branding.js new file mode 100644 index 00000000..2acdea51 --- /dev/null +++ b/docs/APIv1/scripts/branding.js @@ -0,0 +1,562 @@ +//=============================================================================================================== +// System : Sandcastle Help File Builder +// File : branding.js +// Author : Eric Woodruff (Eric@EWoodruff.us) +// Updated : 10/08/2015 +// Note : Copyright 2014-2015, Eric Woodruff, All rights reserved +// Portions Copyright 2010-2014 Microsoft, All rights reserved +// +// This file contains the methods necessary to implement the language filtering, collapsible section, and +// copy to clipboard options. +// +// This code is published under the Microsoft Public License (Ms-PL). A copy of the license should be +// distributed with the code and can be found at the project website: https://GitHub.com/EWSoftware/SHFB. This +// notice, the author's name, and all copyright notices must remain intact in all applications, documentation, +// and source files. +// +// Date Who Comments +// ============================================================================================================== +// 05/04/2014 EFW Created the code based on the MS Help Viewer script +//=============================================================================================================== + +// The IDs of all code snippet sets on the same page are stored so that we can keep them in synch when a tab is +// selected. +var allTabSetIds = new Array(); + +// The IDs of language-specific text (LST) spans are used as dictionary keys so that we can get access to the +// spans and update them when the user changes to a different language tab. The values of the dictionary +// objects are pipe separated language-specific attributes (lang1=value|lang2=value|lang3=value). The language +// ID can be specific (cs, vb, cpp, etc.) or may be a neutral entry (nu) which specifies text common to multiple +// languages. If a language is not present and there is no neutral entry, the span is hidden for all languages +// to which it does not apply. +var allLSTSetIds = new Object(); + +// Help 1 persistence support. This code must appear inline. +var isHelp1; + +var curLoc = document.location + "."; + +if(curLoc.indexOf("mk:@MSITStore") == 0) +{ + isHelp1 = true; + curLoc = "ms-its:" + curLoc.substring(14, curLoc.length - 1); + document.location.replace(curLoc); +} +else + if(curLoc.indexOf("ms-its:") == 0) + isHelp1 = true; + else + isHelp1 = false; + +// The OnLoad method +function OnLoad(defaultLanguage) +{ + var defLang; + + if(typeof (defaultLanguage) == "undefined" || defaultLanguage == null || defaultLanguage == "") + defLang = "vb"; + else + defLang = defaultLanguage; + + // In MS Help Viewer, the transform the topic is ran through can move the footer. Move it back where it + // belongs if necessary. + try + { + var footer = document.getElementById("pageFooter") + + if(footer) + { + var footerParent = document.body; + + if(footer.parentElement != footerParent) + { + footer.parentElement.removeChild(footer); + footerParent.appendChild(footer); + } + } + } + catch(e) + { + } + + var language = GetCookie("CodeSnippetContainerLanguage", defLang); + + // If LST exists on the page, set the LST to show the user selected programming language + UpdateLST(language); + + // If code snippet groups exist, set the current language for them + if(allTabSetIds.length > 0) + { + var i = 0; + + while(i < allTabSetIds.length) + { + var tabCount = 1; + + // The tab count may vary so find the last one in this set + while(document.getElementById(allTabSetIds[i] + "_tab" + tabCount) != null) + tabCount++; + + tabCount--; + + // If not grouped, skip it + if(tabCount > 1) + SetCurrentLanguage(allTabSetIds[i], language, tabCount); + + i++; + } + } + + InitializeToc(); +} + +// This is just a place holder. The website script implements this function to initialize it's in-page TOC pane +function InitializeToc() +{ +} + +// This function executes in the OnLoad event and ChangeTab action on code snippets. The function parameter +// is the user chosen programming language. This function iterates through the "allLSTSetIds" dictionary object +// to update the node value of the LST span tag per the user's chosen programming language. +function UpdateLST(language) +{ + for(var lstMember in allLSTSetIds) + { + var devLangSpan = document.getElementById(lstMember); + + if(devLangSpan != null) + { + // There may be a carriage return before the LST span in the content so the replace function below + // is used to trim the whitespace at the end of the previous node of the current LST node. + if(devLangSpan.previousSibling != null && devLangSpan.previousSibling.nodeValue != null) + devLangSpan.previousSibling.nodeValue = devLangSpan.previousSibling.nodeValue.replace(/\s+$/, ""); + + var langs = allLSTSetIds[lstMember].split("|"); + var k = 0; + var keyValue; + + while(k < langs.length) + { + keyValue = langs[k].split("="); + + if(keyValue[0] == language) + { + devLangSpan.innerHTML = keyValue[1]; + + // Help 1 and MS Help Viewer workaround. Add a space if the following text element starts + // with a space to prevent things running together. + if(devLangSpan.parentNode != null && devLangSpan.parentNode.nextSibling != null) + { + if(devLangSpan.parentNode.nextSibling.nodeValue != null && + !devLangSpan.parentNode.nextSibling.nodeValue.substring(0, 1).match(/[.,);:!/?]/) && + (isHelp1 || devLangSpan.innerHTML == '>' || devLangSpan.innerHTML == ')')) + { + devLangSpan.innerHTML = keyValue[1] + " "; + } + } + break; + } + + k++; + } + + // If not found, default to the neutral language. If there is no neutral language entry, clear the + // content to hide it. + if(k >= langs.length) + { + if(language != "nu") + { + k = 0; + + while(k < langs.length) + { + keyValue = langs[k].split("="); + + if(keyValue[0] == "nu") + { + devLangSpan.innerHTML = keyValue[1]; + + // Help 1 and MS Help Viewer workaround. Add a space if the following text element + // starts with a space to prevent things running together. + if(devLangSpan.parentNode != null && devLangSpan.parentNode.nextSibling != null) + { + if(devLangSpan.parentNode.nextSibling.nodeValue != null && + !devLangSpan.parentNode.nextSibling.nodeValue.substring(0, 1).match(/[.,);:!/?]/) && + (isHelp1 || devLangSpan.innerHTML == '>' || devLangSpan.innerHTML == ')')) + { + devLangSpan.innerHTML = keyValue[1] + " "; + } + } + break; + } + + k++; + } + } + + if(k >= langs.length) + devLangSpan.innerHTML = ""; + } + } + } +} + +// Get the specified cookie. If not found, return the specified default value. +function GetCookie(cookieName, defaultValue) +{ + if(isHelp1) + { + try + { + var globals = Help1Globals; + + var value = globals.Load(cookieName); + + if(value == null) + value = defaultValue; + + return value; + } + catch(e) + { + return defaultValue; + } + } + + var cookie = document.cookie.split("; "); + + for(var i = 0; i < cookie.length; i++) + { + var crumb = cookie[i].split("="); + + if(cookieName == crumb[0]) + return unescape(crumb[1]) + } + + return defaultValue; +} + +// Set the specified cookie to the specified value +function SetCookie(name, value) +{ + if(isHelp1) + { + try + { + var globals = Help1Globals; + + globals.Save(name, value); + } + catch(e) + { + } + + return; + } + + var today = new Date(); + + today.setTime(today.getTime()); + + // Set the expiration time to be 60 days from now (in milliseconds) + var expires_date = new Date(today.getTime() + (60 * 1000 * 60 * 60 * 24)); + + document.cookie = name + "=" + escape(value) + ";expires=" + expires_date.toGMTString() + ";path=/"; +} + +// Add a language-specific text ID +function AddLanguageSpecificTextSet(lstId) +{ + var keyValue = lstId.split("?") + + allLSTSetIds[keyValue[0]] = keyValue[1]; +} + +var clipboardHandler; + +// Add a language tab set ID +function AddLanguageTabSet(tabSetId) +{ + allTabSetIds.push(tabSetId); + + // Create the clipboard handler on first use + if(clipboardHandler == null && typeof (Clipboard) == "function") + { + clipboardHandler = new Clipboard('.copyCodeSnippet', + { + text: function (trigger) + { + // Get the code to copy to the clipboard from the active tab of the given tab set + var i = 1, tabSetId = trigger.id; + var pos = tabSetId.indexOf('_'); + + if(pos == -1) + return ""; + + tabSetId = tabSetId.substring(0, pos); + + do + { + contentId = tabSetId + "_code_Div" + i; + tabTemp = document.getElementById(contentId); + + if(tabTemp != null && tabTemp.style.display != "none") + break; + + i++; + + } while(tabTemp != null); + + if(tabTemp == null) + return ""; + + return document.getElementById(contentId).innerText; + } + }); + } +} + +// Switch the active tab for all of other code snippets +function ChangeTab(tabSetId, language, snippetIdx, snippetCount) +{ + SetCookie("CodeSnippetContainerLanguage", language); + + SetActiveTab(tabSetId, snippetIdx, snippetCount); + + // If LST exists on the page, set the LST to show the user selected programming language + UpdateLST(language); + + var i = 0; + + while(i < allTabSetIds.length) + { + // We just care about other snippets + if(allTabSetIds[i] != tabSetId) + { + // Other tab sets may not have the same number of tabs + var tabCount = 1; + + while(document.getElementById(allTabSetIds[i] + "_tab" + tabCount) != null) + tabCount++; + + tabCount--; + + // If not grouped, skip it + if(tabCount > 1) + SetCurrentLanguage(allTabSetIds[i], language, tabCount); + } + + i++; + } +} + +// Sets the current language in the specified tab set +function SetCurrentLanguage(tabSetId, language, tabCount) +{ + var tabIndex = 1; + + while(tabIndex <= tabCount) + { + var tabTemp = document.getElementById(tabSetId + "_tab" + tabIndex); + + if(tabTemp != null && tabTemp.innerHTML.indexOf("'" + language + "'") != -1) + break; + + tabIndex++; + } + + if(tabIndex > tabCount) + { + // Select the first non-disabled tab + tabIndex = 1; + + if(document.getElementById(tabSetId + "_tab1").className == "codeSnippetContainerTabPhantom") + { + tabIndex++; + + while(tabIndex <= tabCount) + { + var tab = document.getElementById(tabSetId + "_tab" + tabIndex); + + if(tab.className != "codeSnippetContainerTabPhantom") + { + tab.className = "codeSnippetContainerTabActive"; + document.getElementById(tabSetId + "_code_Div" + j).style.display = "block"; + break; + } + + tabIndex++; + } + } + } + + SetActiveTab(tabSetId, tabIndex, tabCount); +} + +// Set the active tab within a tab set +function SetActiveTab(tabSetId, tabIndex, tabCount) +{ + var i = 1; + + while(i <= tabCount) + { + var tabTemp = document.getElementById(tabSetId + "_tab" + i); + + if (tabTemp != null) + { + if(tabTemp.className == "codeSnippetContainerTabActive") + tabTemp.className = "codeSnippetContainerTab"; + else + if(tabTemp.className == "codeSnippetContainerTabPhantom") + tabTemp.style.display = "none"; + + var codeTemp = document.getElementById(tabSetId + "_code_Div" + i); + + if(codeTemp.style.display != "none") + codeTemp.style.display = "none"; + } + + i++; + } + + // Phantom tabs are shown or hidden as needed + if(document.getElementById(tabSetId + "_tab" + tabIndex).className != "codeSnippetContainerTabPhantom") + document.getElementById(tabSetId + "_tab" + tabIndex).className = "codeSnippetContainerTabActive"; + else + document.getElementById(tabSetId + "_tab" + tabIndex).style.display = "block"; + + document.getElementById(tabSetId + "_code_Div" + tabIndex).style.display = "block"; +} + +// Copy the code from the active tab of the given tab set to the clipboard +function CopyToClipboard(tabSetId) +{ + var tabTemp, contentId; + var i = 1; + + if(typeof (Clipboard) == "function") + return; + + do + { + contentId = tabSetId + "_code_Div" + i; + tabTemp = document.getElementById(contentId); + + if(tabTemp != null && tabTemp.style.display != "none") + break; + + i++; + + } while(tabTemp != null); + + if(tabTemp == null) + return; + + if(window.clipboardData) + { + try + { + window.clipboardData.setData("Text", document.getElementById(contentId).innerText); + } + catch(e) + { + alert("Permission denied. Enable copying to the clipboard."); + } + } + else if(window.netscape) + { + try + { + netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); + + var clip = Components.classes["@mozilla.org/widget/clipboard;1"].createInstance( + Components.interfaces.nsIClipboard); + + if(!clip) + return; + + var trans = Components.classes["@mozilla.org/widget/transferable;1"].createInstance( + Components.interfaces.nsITransferable); + + if(!trans) + return; + + trans.addDataFlavor("text/unicode"); + + var str = new Object(); + var len = new Object(); + var str = Components.classes["@mozilla.org/supports-string;1"].createInstance( + Components.interfaces.nsISupportsString); + + var copytext = document.getElementById(contentId).textContent; + + str.data = copytext; + trans.setTransferData("text/unicode", str, copytext.length * 2); + + var clipid = Components.interfaces.nsIClipboard; + + clip.setData(trans, null, clipid.kGlobalClipboard); + } + catch(e) + { + alert("Permission denied. Enter \"about:config\" in the address bar and double-click the \"signed.applets.codebase_principal_support\" setting to enable copying to the clipboard."); + } + } +} + +// Expand or collapse a section +function SectionExpandCollapse(togglePrefix) +{ + var image = document.getElementById(togglePrefix + "Toggle"); + var section = document.getElementById(togglePrefix + "Section"); + + if(image != null && section != null) + if(section.style.display == "") + { + image.src = image.src.replace("SectionExpanded.png", "SectionCollapsed.png"); + section.style.display = "none"; + } + else + { + image.src = image.src.replace("SectionCollapsed.png", "SectionExpanded.png"); + section.style.display = ""; + } +} + +// Expand or collapse a section when it has the focus and Enter is hit +function SectionExpandCollapse_CheckKey(togglePrefix, eventArgs) +{ + if(eventArgs.keyCode == 13) + SectionExpandCollapse(togglePrefix); +} + +// Help 1 persistence object. This requires a hidden input element on the page with a class of "userDataStyle" +// defined in the style sheet that implements the user data binary behavior: +// +var Help1Globals = +{ + UserDataCache: function() + { + var userData = document.getElementById("userDataCache"); + + return userData; + }, + + Load: function(key) + { + var userData = this.UserDataCache(); + + userData.load("userDataSettings"); + + var value = userData.getAttribute(key); + + return value; + }, + + Save: function(key, value) + { + var userData = this.UserDataCache(); + userData.setAttribute(key, value); + userData.save("userDataSettings"); + } +}; diff --git a/docs/APIv1/scripts/clipboard.min.js b/docs/APIv1/scripts/clipboard.min.js new file mode 100644 index 00000000..580433f1 --- /dev/null +++ b/docs/APIv1/scripts/clipboard.min.js @@ -0,0 +1,7 @@ +/*! + * clipboard.js v1.5.12 + * https://zenorocha.github.io/clipboard.js + * + * Licensed MIT © Zeno Rocha + */ +!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var e;e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,e.Clipboard=t()}}(function(){var t,e,n;return function t(e,n,o){function i(a,c){if(!n[a]){if(!e[a]){var s="function"==typeof require&&require;if(!c&&s)return s(a,!0);if(r)return r(a,!0);var l=new Error("Cannot find module '"+a+"'");throw l.code="MODULE_NOT_FOUND",l}var u=n[a]={exports:{}};e[a][0].call(u.exports,function(t){var n=e[a][1][t];return i(n?n:t)},u,u.exports,t,e,n,o)}return n[a].exports}for(var r="function"==typeof require&&require,a=0;at |