//methods public override List <SignalDispatch <TKey> > Build(EventSettings <TKey> settings, SignalEvent <TKey> signalEvent, List <Subscriber <TKey> > subscribers, List <TemplateData> languageTemplateData) { List <string> texts = FillTemplateProperty(TextProvider, TextTransformer, subscribers, languageTemplateData); return(subscribers .Select((subscriber, i) => AssembleSlackMessage(settings, signalEvent, subscriber, texts[i])) .Cast <SignalDispatch <TKey> >() .ToList()); }
protected virtual StoredNotificationDispatch <TKey> AssembleStoredNotification(EventSettings <TKey> settings , SignalEvent <TKey> signalEvent, Subscriber <TKey> subscriber, string subject, string body) { var dispatch = new StoredNotificationDispatch <TKey>() { MessageSubject = subject, MessageBody = body }; SetBaseProperties(dispatch, settings, signalEvent, subscriber); return(dispatch); }
public static IMapEvent SerdesEvent(IMapEvent e, ISerializer s, AssetId chainSource, TextId textSourceId, AssetMapping mapping) { if (s == null) { throw new ArgumentNullException(nameof(s)); } var initialPosition = s.Offset; s.Begin(); var type = s.EnumU8("Type", e?.EventType ?? MapEventType.UnkFf); e = type switch // Individual parsers handle byte range [1,9] { MapEventType.Action => ActionEvent.Serdes((ActionEvent)e, mapping, s), MapEventType.AskSurrender => AskSurrenderEvent.Serdes((AskSurrenderEvent)e, s), MapEventType.ChangeIcon => ChangeIconEvent.Serdes((ChangeIconEvent)e, mapping, s), MapEventType.ChangeUsedItem => ChangeUsedItemEvent.Serdes((ChangeUsedItemEvent)e, mapping, s), MapEventType.Chest => ChestEvent.Serdes((ChestEvent)e, mapping, s, textSourceId), MapEventType.CloneAutomap => CloneAutomapEvent.Serdes((CloneAutomapEvent)e, mapping, s), MapEventType.CreateTransport => CreateTransportEvent.Serdes((CreateTransportEvent)e, s), MapEventType.DataChange => DataChangeEvent.Serdes((DataChangeEvent)e, mapping, s), MapEventType.Door => DoorEvent.Serdes((DoorEvent)e, mapping, s, textSourceId), MapEventType.Encounter => EncounterEvent.Serdes((EncounterEvent)e, s), MapEventType.EndDialogue => EndDialogueEvent.Serdes((EndDialogueEvent)e, s), MapEventType.Execute => ExecuteEvent.Serdes((ExecuteEvent)e, s), MapEventType.MapExit => TeleportEvent.Serdes((TeleportEvent)e, mapping, s), MapEventType.Modify => ModifyEvent.BaseSerdes((ModifyEvent)e, mapping, chainSource, s), MapEventType.Offset => OffsetEvent.Serdes((OffsetEvent)e, s), MapEventType.Pause => PauseEvent.Serdes((PauseEvent)e, s), MapEventType.PlaceAction => PlaceActionEvent.Serdes((PlaceActionEvent)e, s), MapEventType.PlayAnimation => PlayAnimationEvent.Serdes((PlayAnimationEvent)e, mapping, s), MapEventType.Query => QueryEvent.Serdes((QueryEvent)e, mapping, s, textSourceId), MapEventType.RemovePartyMember => RemovePartyMemberEvent.Serdes((RemovePartyMemberEvent)e, mapping, s), MapEventType.Script => DoScriptEvent.Serdes((DoScriptEvent)e, mapping, s), MapEventType.Signal => SignalEvent.Serdes((SignalEvent)e, s), MapEventType.SimpleChest => SimpleChestEvent.Serdes((SimpleChestEvent)e, mapping, s), MapEventType.Sound => SoundEvent.Serdes((SoundEvent)e, mapping, s), MapEventType.Spinner => SpinnerEvent.Serdes((SpinnerEvent)e, s), MapEventType.StartDialogue => StartDialogueEvent.Serdes((StartDialogueEvent)e, mapping, s), MapEventType.Text => MapTextEvent.Serdes((MapTextEvent)e, mapping, s, textSourceId), MapEventType.Trap => TrapEvent.Serdes((TrapEvent)e, s), MapEventType.Wipe => WipeEvent.Serdes((WipeEvent)e, s), _ => DummyMapEvent.Serdes((DummyMapEvent)e, s, type) }; s.End(); if (e is IBranchingEvent) { s.Assert(s.Offset - initialPosition == 8, "Query events should always be 8 bytes"); } else { s.Assert(s.Offset - initialPosition == 10, "Non-query map events should always be 10 bytes"); } return(e); } /* == Binary Serialisable Event types: == * 1 Teleport (teleport 300 32 75) * 2 Door (open_door ...) * 3 Chest (open_chest ...) * 4 Text (map_text 100) * 5 Spinner (spinner ...) * 6 Trap (trap ...) * 7 ChangeUsedItem (change_used_item ...) * 8 DataChange (further subdivided by operation: min,max,?,set,add,sub,add%,sub%) * 0 Unk0 (TODO) * 2 Health (party[Tom].health += 20%) * 3 Mana (party[Sira].mana -= 5) * 5 Status (party[Rainer].status[Poisoned] = max) * 7 Language (party[Tom].language[Iskai] = max) * 8 Experience (party[Drirr].experience += 2000) * B UnkB (TODO) * C UnkC (TODO) * 13 Item (party[Tom].items[LughsShield] = 1) * 14 Gold (party[Joe].gold += 12) * 15 Food (party[Siobhan].food -= 10%) * 9 ChangeIcon (scope: rel vs abs, temp vs perm) * 0 Underlay (map.tempUnderlay[23,12] = 47) * 1 Overlay (map.permOverlay[+0,-3] = 1231) * 2 Wall (map.tempWall[10, 10] = 7) * 3 Floor (map.permFloor[64, 64] = 1) * 4 Ceiling (map.permCeiling[12, 24] = 7) * 5 NpcMovement (npc[12].permMovement = 3) * 6 NpcSprite (npc[5].tempSprite = 14) * 7 Chain (map.tempChain[10, 10] = 15) * 8 BlockHard (block_hard ...) * 9 BlockSoft (block_soft ...) * A Trigger (map.tempTrigger[96, 7] = Normal) * A Encounter (encounter ...) * B PlaceAction * 0 LearnCloseCombat * 1 Heal * 2 Cure * 3 RemoveCurse * 4 AskOpinion * 5 RestoreItemEnergy * 6 SleepInRoom * 7 Merchant * 8 OrderFood * 9 ScrollMerchant * B LearnSpells * C RepairItem * C Query (further subdivided by operation: NZ, <=, !=, ==, >=, >, <) * 0 Switch (switch[100]), (!switch[203]), (switch[KhunagMentionedSecretPassage]) * 1 Unk1 * 4 Unk4 * 5 HasPartyMember (party[Tom].isPresent) * 6 HasItem (!party.hasItem[Axe]) * 7 UsedItem (context.usedItem == Pick) * 9 PreviousActionResult (context.result) * A ScriptDebugMode (context.isDebug) * C UnkC * E NpcActive (npc[16].isActive) * F Gold (party.gold > 100) * 11 RandomChance (random(50)) * 12 Unk12 * 14 ChosenVerb (context.verb == Examine) * 15 Conscious (party[Tom].isConscious) * 1A Leader (party[Rainer].isLeader) * 1C Ticker (ticker[50] > 12) * 1D Map (context.map == Drinno3) * 1E Unk1E * 1F PromptPlayer (askYesNo(100)) * 19 Unk19 * 20 TriggerType (context.trigger == UseItem) * 21 Unk21 * 22 EventUsed (context.event[108].hasRun) * 23 DemoVersion (context.isDemo) * 29 Unk29 * 2A Unk2A * 2B PromptPlayerNumeric (askNumeric() = 1042) * D Modify * 0 Switch (switch[125] = 1) * 1 DisableEventChain (map[CantosHouse].chain[120] = 0) * 2 Unk2 * 4 NpcActive (set_npc_active ...) * 5 AddPartyMember (add_party_member ...) * 6 InventoryItem (party.item[Knife] += 3) * B Lighting (map.lighting = 5) ?? * F PartyGold (party.gold = min) * 10 PartyRations (party.rations += 12) * 12 Time (context.time += 6) * 1A Leader (party.leader = Tom) * 1C Ticker (ticker[93] = 108) * E Action (action ...) * 0 Word * 1 AskAboutItem * 2 Unk2 // Pay money? See ES156 (Garris, Gratogel sailor) * 4 Unk4 * 5 Unk5 * 6 StartDialogue * 7 FinishDialogue * 8 DialogueLine * 9 Unk9 * E Unk14 * 17 Unk23 * 2D Unk45 * 2E UseItem * 2F EquipItem * 30 UnequipItem * 36 PickupItem * 39 Unk57 * 3D Unk61 * F Signal (signal ...) * 10 CloneAutomap (clone_automap ...) * 11 Sound (sound ...) * 12 StartDialogue (start_dialogue ...) * 13 CreateTransport (???) * 14 Execute (execute) * 15 RemovePartyMember (remove_party_member ...) * 16 EndDialogue (end_dialogue) * 17 Wipe (wipe ...) * 18 PlayAnimation (play_anim ...) * 19 Offset (offset 0 0) * 1A Pause (pause 3) * 1B SimpleChest (simple_chest ...) * 1C AskSurrender (ask_surrender) * 1D Script (script 15) * FF UnkFF */ }
protected virtual List <SignalDispatch <TKey> > BuildTemplate(EventSettings <TKey> settings, SignalEvent <TKey> signalEvent , DispatchTemplate <TKey> template, List <Subscriber <TKey> > subscribers, List <TemplateData> templateData) { return(template.Build(settings, signalEvent, subscribers, templateData)); }
//methods public override List <SignalDispatch <TKey> > Build(EventSettings <TKey> settings, SignalEvent <TKey> signalEvent, List <Subscriber <TKey> > subscribers, List <TemplateData> languageTemplateData) { List <string> subjects = FillTemplateProperty(SubjectProvider, SubjectTransformer, subscribers, languageTemplateData); List <string> bodies = FillTemplateProperty(BodyProvider, BodyTransformer, subscribers, languageTemplateData); return(subscribers .Select((subscriber, i) => AssembleStoredNotification(settings, signalEvent, subscriber, subjects[i], bodies[i])) .Cast <SignalDispatch <TKey> >() .ToList()); }
/// <summary>Вызов события SignalEvent</summary> /// <param name="signal">Значение сигнала</param> public virtual void OnSignalEvent(SignalEnum signal) => SignalEvent?.Invoke(signal);
public void TestWaitingMultipleEvents() { using (var ev = new SignalEvent()) using (var ev2 = new SignalEvent()) using (var ev3 = new SignalEvent()) { int waiterEntered = 0; int waitResult = 0; int waitCondition = 0; int condEvaluated = 0; object waiterRef = null; var task = Task.Run(() => { var factory = SignalWaiterFactory.Create(ev.Factory, ev2.Factory); var factory2 = SignalWaiterFactory.Create(factory, ev3.Factory); using (var waiter = factory2.CreateWaiter()) { Interlocked.Exchange(ref waiterRef, waiter); lock (waiter) { Interlocked.Increment(ref waiterEntered); if (waiter.Wait(s => { Interlocked.Increment(ref condEvaluated); return(Volatile.Read(ref waitCondition) > 0); }, (object)null, 60000)) { Interlocked.Exchange(ref waitResult, 1); } else { Interlocked.Exchange(ref waitResult, 2); } if (waiter.Wait(s => { Interlocked.Increment(ref condEvaluated); return(Volatile.Read(ref waitCondition) > 1); }, (object)null, 60000)) { Interlocked.Exchange(ref waitResult, 3); } else { Interlocked.Exchange(ref waitResult, 4); } if (waiter.Wait(s => { Interlocked.Increment(ref condEvaluated); return(Volatile.Read(ref waitCondition) > 2); }, (object)null, 60000)) { Interlocked.Exchange(ref waitResult, 5); } else { Interlocked.Exchange(ref waitResult, 6); } } } }); TimingAssert.AreEqual(10000, 1, () => Volatile.Read(ref waiterEntered)); lock (waiterRef) { Interlocked.Increment(ref waitCondition); ev.Signal(); } TimingAssert.AreEqual(10000, 1, () => Volatile.Read(ref waitResult)); lock (waiterRef) { Interlocked.Increment(ref waitCondition); ev2.Signal(); } TimingAssert.AreEqual(10000, 3, () => Volatile.Read(ref waitResult)); lock (waiterRef) { Interlocked.Increment(ref waitCondition); ev2.Signal(); } TimingAssert.AreEqual(10000, 5, () => Volatile.Read(ref waitResult)); task.Wait(); } }
//methods public override List <SignalDispatch <long> > Build(EventSettings <long> settings, SignalEvent <long> signalEvent, List <Subscriber <long> > subscribers, List <TemplateData> dataWithCulture) { throw new NotImplementedException(); }
//methods public override List <SignalDispatch <TKey> > Build(EventSettings <TKey> settings, SignalEvent <TKey> signalEvent, List <Subscriber <TKey> > subscribers, List <TemplateData> languageTemplateData) { List <string> bodies = FillTemplateProperty(ContentProvider, ContentTransformer, subscribers, languageTemplateData); return(subscribers .Select((subscriber, i) => AssembleHttpRequest(settings, signalEvent, subscriber, bodies[i])) .Cast <SignalDispatch <TKey> >() .ToList()); }
private static void HandleSellSignals(SimulationDto simulationDto, IList <CompanyPricesDto> allPrices, SignalEvent signalEvent, SimulationResultDto simulationResult) { var prices = ConvertPrices(allPrices, signalEvent.CompaniesToSell, signalEvent.Date); foreach (var price in prices) { if (!simulationResult.CurrentCompanyQuantity.ContainsKey(price.Key)) { continue; } var transaction = new SimulationTransactionDto { Date = signalEvent.Date, CompanyId = price.Key, Price = price.Value, Action = SignalAction.Sell, Quantity = simulationResult.CurrentCompanyQuantity[price.Key], BudgetAfter = simulationDto.Budget + simulationResult.CurrentCompanyQuantity[price.Key] * price.Value }; simulationResult.TransactionsLog.Add(transaction); simulationDto.Budget = transaction.BudgetAfter; simulationResult.CurrentCompanyQuantity.Remove(price.Key); } }
private static void HandleBuySignals(SimulationDto simulationDto, IList <CompanyPricesDto> allPrices, SignalEvent signalEvent, SimulationResultDto simulationResult) { var prices = ConvertPrices(allPrices, signalEvent.CompaniesToBuy, signalEvent.Date); //.OrderByDescending(item => item.Value); foreach (var price in prices) { var value = simulationDto.Budget; if (simulationDto.HasMaximalTransactionLimit) { value = Math.Min(value, simulationDto.MaximalBudgetPerTransaction); } if (simulationDto.HasMinimalTransactionLimit) { if (value < simulationDto.MinimalBudgetPerTransaction) { continue; // not enough money } value = Math.Max(value, simulationDto.MinimalBudgetPerTransaction); } if (value < price.Value) { continue; } int quantity = (int)Math.Floor(value / price.Value); var transaction = new SimulationTransactionDto { Date = signalEvent.Date, CompanyId = price.Key, Price = price.Value, Action = SignalAction.Buy, Quantity = quantity, BudgetAfter = simulationDto.Budget - quantity * price.Value }; simulationResult.TransactionsLog.Add(transaction); if (simulationResult.CurrentCompanyQuantity.ContainsKey(price.Key)) { simulationResult.CurrentCompanyQuantity[price.Key] += quantity; } else { simulationResult.CurrentCompanyQuantity.Add(price.Key, quantity); } simulationDto.Budget = transaction.BudgetAfter; } }
protected void OnSignalEvent(char c) => SignalEvent?.Invoke(this, c);
// Метод для вызова события public void OnSignal(SignalEnum signal) => SignalEvent?.Invoke(signal);
public void Exec(int _tick) { if (!started) { return; } if (complete) { return; } for (; ;) { SignalEvent se = SL.CatchNext(); if (se == null) { break; } switch (step) { case 0: // Ждем начала if (!teOn.Check(se)) { break; } pr(teOn.ToString()); L.Add(new TickPosition(teOn.Tick, teOn.Position)); teStrobe.FirstTick = teOn.Tick; step = 2; break; case 2: // Собираем стробы if (teStrobe.Check(se)) { pr(teStrobe.ToString()); L.Add(new TickPosition(teStrobe.Tick, teStrobe.Position)); } if (!teOff0.Was) { if (teOff0.Check(se)) { // Если снялся контроль - вычисляем длину трубы. pr(teOff0.ToString()); { int curr_position = teStrobe.Position + CalcDelta(teOff0.Tick); // int TubeLength = curr_position - teOff0.Position; int TubeLength = curr_position - teOff0.Position; pr("curr_position=" + curr_position.ToString()); pr("teOn.Position=" + teOn.Position.ToString()); pr("teOff0.Position=" + teOff0.Position.ToString()); pr("TubeLength=" + TubeLength.ToString()); bank.TubeLength = TubeLength; SendTubeLength(TubeLength); L.Add(new TickPosition(teOff0.Tick, teOff0.Position + TubeLength)); } } } break; } //foreach (TickPosition tp in L) //{ // Send(tp); // bank.AddTickPosition(tp); //} //L.Clear(); if (teOff0.Was) { // Если Знаем конец трубы - сбрасываем зоны в банк foreach (TickPosition tp in L) { Send(tp); bank.AddTickPosition(tp); } L.Clear(); } else { // Если НЕ знаем конец трубы - сбрасываем в банк только те стробы, // после которых уже пришли стробы на длину, не менее длины // между первым и последним контролем. // // Иначе говоря зедержим тот строб, которым может оказаться за границей трубы, чтобы не выдать зону из воздуха. if (L.Count != 0) { double last_position = L[L.Count - 1].position; for (; ;) { TickPosition p = L[0]; if (last_position - p.position >= teOff0.Position - teOn.Position) { Send(p); bank.AddTickPosition(p); L.Remove(p); } else { // AnsiString a = ""; // a += last_position; // a += "-"; // a += p->position; // a+=">"; // a+=teOff0->Position(); // a+="-"; // a+=teOn->Position(); // pr(a); break; } if (L.Count == 0) { break; } } } } } }