public void CanAddAndRemoveItems() { var set = new UniqueSetValue(); Assert.IsNotNull(set); var length = InvokeDelegate(set, "LENGTH"); Assert.AreEqual(ScalarIntValue.Zero, length); InvokeDelegate(set, "ADD", new StringValue("value1")); InvokeDelegate(set, "ADD", new StringValue("value1")); InvokeDelegate(set, "ADD", new StringValue("value2")); length = InvokeDelegate(set, "LENGTH"); Assert.AreEqual(ScalarIntValue.Two, length); object result = InvokeDelegate(set, "REMOVE", new StringValue("value1")); Assert.AreEqual(BooleanValue.True, result); length = InvokeDelegate(set, "LENGTH"); Assert.AreEqual(ScalarIntValue.One, length); result = InvokeDelegate(set, "REMOVE", new StringValue("value1")); Assert.AreEqual(BooleanValue.False, result); result = InvokeDelegate(set, "REMOVE", new StringValue("value2")); Assert.AreEqual(BooleanValue.True, result); length = InvokeDelegate(set, "LENGTH"); Assert.AreEqual(ScalarIntValue.Zero, length); }
public void SendToPartUndockNotifyees(Part p) { // Notify any hooks attached to the part on the "from" side of the event: UniqueSetValue <UserDelegate> notifyees = GetPartUndockNotifyees(p); foreach (UserDelegate del in notifyees) { if (UserDelgateIsAcceptable(del)) { Shared.Cpu.AddTrigger(del, InterruptPriority.CallbackOnce, Shared.Cpu.NextTriggerInstanceId, false); } } // Notify any hooks attached to the part on the "to" side of the event: ModuleDockingNode dockModule = (ModuleDockingNode)p.Modules["ModuleDockingNode"]; notifyees = GetPartUndockNotifyees(dockModule.otherNode.part); foreach (UserDelegate del in notifyees) { if (UserDelgateIsAcceptable(del)) { Shared.Cpu.AddTrigger(del, InterruptPriority.CallbackOnce, Shared.Cpu.NextTriggerInstanceId, false); } } // The event has no data available on which other part it had been attached to, apparently. }
public void SendToPartCouplingNotifyees(GameEvents.FromToAction <Part, Part> evt) { // Notify any hooks attached to the part on the "from" side of the event: UniqueSetValue <UserDelegate> notifyees = GetPartCoupleNotifyees(evt.@from); // Use GetFooNotifyees to activate the lazy-build logic if need be. foreach (UserDelegate del in notifyees) { if (UserDelgateIsAcceptable(del)) { Shared.Cpu.AddTrigger(del, InterruptPriority.CallbackOnce, Shared.Cpu.NextTriggerInstanceId, false, PartValueFactory.Construct(evt.to, Shared)); } } // Also notify any hooks attached to the part on the "to" side of the event. Let's not // confuse users with KSP's strange notion of the "from" and the "to" of a docking, and just // treat both ports as equal peers that both get the same notification: notifyees = GetPartCoupleNotifyees(evt.to); foreach (UserDelegate del in notifyees) { if (UserDelgateIsAcceptable(del)) { Shared.Cpu.AddTrigger(del, InterruptPriority.CallbackOnce, Shared.Cpu.NextTriggerInstanceId, false, PartValueFactory.Construct(evt.@from, Shared)); } } }
public void SendToSOIChangeNotifyees(GameEvents.HostedFromToAction <Vessel, CelestialBody> evt) { UniqueSetValue <UserDelegate> notifyees = GetSOIChangeNotifyees(evt.host); foreach (UserDelegate del in notifyees) { if (UserDelgateIsAcceptable(del)) { Shared.Cpu.AddTrigger(del, InterruptPriority.CallbackOnce, Shared.Cpu.NextTriggerInstanceId, false, BodyTarget.CreateOrGetExisting(evt.@from, Shared), BodyTarget.CreateOrGetExisting(evt.to, Shared)); } } }
public override void Execute(SharedObjects shared) { Structure[] argArray = new Structure[CountRemainingArgs(shared)]; for (int i = argArray.Length - 1; i >= 0; --i) { argArray[i] = PopStructureAssertEncapsulated(shared); // fill array in reverse order because .. stack args. } AssertArgBottomAndConsume(shared); var setValue = new UniqueSetValue(argArray.ToList()); ReturnValue = setValue; }
public void SendToSwitchVesselNotifyees(Vessel fromVes, Vessel toVes) { UniqueSetValue <UserDelegate> notifyees = GetSwitchVesselNotifyees(); foreach (UserDelegate del in notifyees) { if (UserDelgateIsAcceptable(del)) { Shared.Cpu.AddTrigger(del, VesselTarget.CreateOrGetExisting(fromVes, Shared), VesselTarget.CreateOrGetExisting(toVes, Shared)); } } }
public void SendToSwitchVesselNotifyees(Vessel fromVes, Vessel toVes) { UniqueSetValue <UserDelegate> notifyees = GetSwitchVesselNotifyees(); foreach (UserDelegate del in notifyees) { if (UserDelgateIsAcceptable(del)) { Shared.Cpu.AddTrigger(del, InterruptPriority.CallbackOnce, Shared.Cpu.NextTriggerInstanceId, false, VesselTarget.CreateOrGetExisting(fromVes, Shared), VesselTarget.CreateOrGetExisting(toVes, Shared)); } } }
public void CanClear() { var set = new UniqueSetValue(); InvokeDelegate(set, "ADD", new ScalarIntValue(1)); InvokeDelegate(set, "ADD", new ScalarIntValue(2)); var length = InvokeDelegate(set, "LENGTH"); Assert.AreEqual(ScalarIntValue.Two,length); InvokeDelegate(set, "CLEAR"); length = InvokeDelegate(set, "LENGTH"); Assert.AreEqual(ScalarIntValue.Zero,length); }
public void CanClear() { var set = new UniqueSetValue(); InvokeDelegate(set, "ADD", new ScalarIntValue(1)); InvokeDelegate(set, "ADD", new ScalarIntValue(2)); var length = InvokeDelegate(set, "LENGTH"); Assert.AreEqual(ScalarIntValue.Two, length); InvokeDelegate(set, "CLEAR"); length = InvokeDelegate(set, "LENGTH"); Assert.AreEqual(ScalarIntValue.Zero, length); }
// WHEN IMPLEMENTING A NEW EVENT TYPE: // Add a GetFooNotifyees() and a SendToFooNotifyees() method for whatever new "Foo" event you're // trying to support. Use the examples below as guides. // // The general algorithm of such methods should be: // // GetFooNotifyees(SomeKSPType thingy): // Some cases might not need the thingy arg. // .................................................................................. // - Given which "thingy" is being watched for, return the list of UserDelegates registered for this event on that thingy. // This List should be a UniqueSetValue and it should be passed directly back to the user script in a GetSuffix call. // (There is no explicit "add a userdelegate to the list" call in this class. Instead it expects the user to add // hooks by adding them to the UniqueSetValue<> this returns.). // - We may as well not clutter up KSP's callback events system with pointless callbacks that don't do anything. // So only when there is evidence the system is being used by the script because GetFooNotifyees() is getting // called, do we then register our SendToFooNotiyees() that goes with it. That registration is a bit like a // "lazy-load" logic. // // SendToFooNotifyees() : The dispatcher for this event. // ..................................................... // - This must be a callback delegate that we register as our hook for whatever GameEvent Foo is. // - When we receive GameEvent foo, this method must check our list of UserDelegates, and if the list isn't // empty, then for each acceptable UserDelegate in the list, we schedule a call // to that user delegate with an AddTrigger() call. // - Note: There isn't a good way to know when the users script is done using the callbacks system, so once // registered, the callback hook we make here will remain alive for the duration of this object, until // Dispose() makes it go away. It shouldn't waste too much execution time, though. If the user is done // using the system, all we'll be doing is noticing the UniqueSetValue<UserDelegate> is empty, and returning // early with nothing to do. // SwitchActiveVessel: // ------------------- public UniqueSetValue <UserDelegate> GetSwitchVesselNotifyees() { UniqueSetValue <UserDelegate> theList = switchVesselNotifyees; if (theList == null) { // This is where we lazy-build it if it's not there yet. switchVesselNotifyees = new UniqueSetValue <UserDelegate>(); theList = switchVesselNotifyees; // Now that we know it's likely getting used, activate our own callback hook: GameEvents.onVesselSwitching.Add(SendToSwitchVesselNotifyees); } return(theList); }
// PartUndock: // ----------- public UniqueSetValue <UserDelegate> GetPartUndockNotifyees(Part p) { if (partUndockNotifyees == null) { partUndockNotifyees = new Dictionary <Part, UniqueSetValue <UserDelegate> >(); } UniqueSetValue <UserDelegate> theList; if (!partUndockNotifyees.TryGetValue(p, out theList)) { // This is where we lazy-build it if it's not there yet. theList = new UniqueSetValue <UserDelegate>(); partUndockNotifyees[p] = theList; // Now that we know it's likely getting used, activate our own callback hook: GameEvents.onPartUndock.Add(SendToPartUndockNotifyees); } return(theList); }
// SOIChange: // ---------- public UniqueSetValue <UserDelegate> GetSOIChangeNotifyees(Vessel ves) { UniqueSetValue <UserDelegate> theList; if (soiChangeNotifyees == null) { soiChangeNotifyees = new Dictionary <Vessel, UniqueSetValue <UserDelegate> >(); } if (!soiChangeNotifyees.TryGetValue(ves, out theList)) { // This is where we lazy-build it if it's not there yet. theList = new UniqueSetValue <UserDelegate>(); soiChangeNotifyees[ves] = theList; // Now that we know it's likely getting used, activate our own callback hook: GameEvents.onVesselSOIChanged.Add(SendToSOIChangeNotifyees); } return(theList); }
public void CanTestContains() { var set = new UniqueSetValue(); var zedObject = new StringValue("abc"); InvokeDelegate(set, "ADD", zedObject); var firstObject = ScalarIntValue.One; InvokeDelegate(set, "ADD", firstObject); var secondObject = ScalarIntValue.Two; var thirdObject = new ScalarIntValue(4); var length = InvokeDelegate(set, "LENGTH"); Assert.AreEqual(ScalarIntValue.Two, length); Assert.IsTrue((BooleanValue)InvokeDelegate(set, "CONTAINS", zedObject)); Assert.IsTrue((BooleanValue)InvokeDelegate(set, "CONTAINS", firstObject)); Assert.IsFalse((BooleanValue)InvokeDelegate(set, "CONTAINS", secondObject)); Assert.IsFalse((BooleanValue)InvokeDelegate(set, "CONTAINS", thirdObject)); }
public void CopyIsACopy() { var set = new UniqueSetValue(); var zedObject = ScalarIntValue.Zero; InvokeDelegate(set, "ADD", zedObject); var firstObject = ScalarIntValue.One; InvokeDelegate(set, "ADD", firstObject); var secondObject = ScalarIntValue.Two; InvokeDelegate(set, "ADD", secondObject); var thirdObject = new StringValue("third"); InvokeDelegate(set, "ADD", thirdObject); var length = InvokeDelegate(set, "LENGTH"); Assert.AreEqual(new ScalarIntValue(4), length); var copy = InvokeDelegate(set, "COPY") as UniqueSetValue; Assert.AreNotSame(set, copy); var copyLength = InvokeDelegate(copy, "LENGTH"); Assert.AreEqual(new ScalarIntValue(4), copyLength); InvokeDelegate(copy, "CLEAR"); copyLength = InvokeDelegate(copy, "LENGTH"); Assert.AreEqual(ScalarIntValue.Zero, copyLength); length = InvokeDelegate(set, "LENGTH"); Assert.AreEqual(new ScalarIntValue(4), length); }
public void CopyIsACopy() { var set = new UniqueSetValue(); var zedObject = ScalarIntValue.Zero; InvokeDelegate(set, "ADD", zedObject); var firstObject = ScalarIntValue.One; InvokeDelegate(set, "ADD", firstObject); var secondObject = ScalarIntValue.Two; InvokeDelegate(set, "ADD", secondObject); var thirdObject = new StringValue("third"); InvokeDelegate(set, "ADD", thirdObject); var length = InvokeDelegate(set, "LENGTH"); Assert.AreEqual(new ScalarIntValue(4), length); var copy = InvokeDelegate(set, "COPY") as UniqueSetValue; Assert.AreNotSame(set, copy); var copyLength = InvokeDelegate(copy, "LENGTH"); Assert.AreEqual(new ScalarIntValue(4),copyLength); InvokeDelegate(copy, "CLEAR"); copyLength = InvokeDelegate(copy, "LENGTH"); Assert.AreEqual(ScalarIntValue.Zero, copyLength); length = InvokeDelegate(set, "LENGTH"); Assert.AreEqual(new ScalarIntValue(4), length); }
public void CanCreate() { var set = new UniqueSetValue(); Assert.IsNotNull(set); }
public override void Execute(SharedObjects shared) { Structure[] argArray = new Structure[CountRemainingArgs(shared)]; for (int i = argArray.Length - 1 ; i >= 0 ; --i) argArray[i] = PopStructureAssertEncapsulated(shared); // fill array in reverse order because .. stack args. AssertArgBottomAndConsume(shared); var setValue = new UniqueSetValue(argArray.ToList()); ReturnValue = setValue; }