public InvokeWorkItem(ActivationData activation, Message message, ISchedulingContext context) { this.activation = activation; this.message = message; SchedulingContext = context; if (activation == null || activation.GrainInstance==null) { var str = String.Format("Creating InvokeWorkItem with bad activation: {0}. Message: {1}", activation, message); logger.Warn(ErrorCode.SchedulerNullActivation, str); throw new ArgumentException(str); } activation.IncrementInFlightCount(); }
private void EnqueueReceiveMessage(Message msg, ActivationData targetActivation, ISchedulingContext context) { MessagingProcessingStatisticsGroup.OnImaMessageEnqueued(context); if (targetActivation != null) targetActivation.IncrementEnqueuedOnDispatcherCount(); scheduler.QueueWorkItem(new ClosureWorkItem(() => { try { dispatcher.ReceiveMessage(msg); } finally { if (targetActivation != null) targetActivation.DecrementEnqueuedOnDispatcherCount(); } }, () => "Dispatcher.ReceiveMessage"), context); }
public SchedulingContext(ActivationData activation) { Activation = activation; ContextType = SchedulingContextType.Activation; isLowPrioritySystemTarget = false; }
private void ReceiveMessage(Message msg) { MessagingProcessingStatisticsGroup.OnImaMessageReceived(msg); ISchedulingContext context; // Find the activation it targets; first check for a system activation, then an app activation if (msg.TargetGrain.IsSystemTarget) { SystemTarget target = directory.FindSystemTarget(msg.TargetActivation); if (target == null) { MessagingStatisticsGroup.OnRejectedMessage(msg); Message response = this.messageFactory.CreateRejectionResponse(msg, Message.RejectionTypes.Unrecoverable, String.Format("SystemTarget {0} not active on this silo. Msg={1}", msg.TargetGrain, msg)); messageCenter.SendMessage(response); Log.Warn(ErrorCode.MessagingMessageFromUnknownActivation, "Received a message {0} for an unknown SystemTarget: {1}", msg, msg.TargetAddress); return; } context = target.SchedulingContext; switch (msg.Direction) { case Message.Directions.Request: MessagingProcessingStatisticsGroup.OnImaMessageEnqueued(context); scheduler.QueueWorkItem(new RequestWorkItem(target, msg), context); break; case Message.Directions.Response: MessagingProcessingStatisticsGroup.OnImaMessageEnqueued(context); scheduler.QueueWorkItem(new ResponseWorkItem(target, msg), context); break; default: Log.Error(ErrorCode.Runtime_Error_100097, "Invalid message: " + msg); break; } } else { // Run this code on the target activation's context, if it already exists ActivationData targetActivation = directory.FindTarget(msg.TargetActivation); if (targetActivation != null) { lock (targetActivation) { var target = targetActivation; // to avoid a warning about nulling targetActivation under a lock on it if (target.State == ActivationState.Valid) { // Response messages are not subject to overload checks. if (msg.Direction != Message.Directions.Response) { var overloadException = target.CheckOverloaded(Log); if (overloadException != null) { // Send rejection as soon as we can, to avoid creating additional work for runtime dispatcher.RejectMessage(msg, Message.RejectionTypes.Overloaded, overloadException, "Target activation is overloaded " + target); return; } } // Run ReceiveMessage in context of target activation context = target.SchedulingContext; } else { // Can't use this activation - will queue for another activation target = null; context = null; } EnqueueReceiveMessage(msg, target, context); } } else { // No usable target activation currently, so run ReceiveMessage in system context EnqueueReceiveMessage(msg, null, null); } } }
// Add a section of an ini file to game content // name is from the ini file and must start with the type // path is relative and is used for images or other paths in the content void AddContent(string name, Dictionary <string, string> content, string path, string packID) { // Is this a "PackType" entry? if (name.IndexOf(PackTypeData.type) == 0) { PackTypeData d = new PackTypeData(name, content, path); // Ignore invalid entry if (d.name.Equals("")) { return; } // If we don't already have one then add this if (!packTypes.ContainsKey(name)) { packTypes.Add(name, d); d.sets.Add(packID); } // If we do replace if this has higher priority else if (packTypes[name].priority < d.priority) { packTypes.Remove(name); packTypes.Add(name, d); } // items of the same priority belong to multiple packs else if (packTypes[name].priority == d.priority) { packTypes[name].sets.Add(packID); } } // Is this a "TileSide" entry? if (name.IndexOf(TileSideData.type) == 0) { TileSideData d = new TileSideData(name, content, path); // Ignore invalid entry if (d.name.Equals("")) { return; } // If we don't already have one then add this if (!tileSides.ContainsKey(name)) { tileSides.Add(name, d); d.sets.Add(packID); } // If we do replace if this has higher priority else if (tileSides[name].priority < d.priority) { tileSides.Remove(name); tileSides.Add(name, d); } // items of the same priority belong to multiple packs else if (tileSides[name].priority == d.priority) { tileSides[name].sets.Add(packID); } } // Is this a "Hero" entry? if (name.IndexOf(HeroData.type) == 0) { HeroData d = new HeroData(name, content, path); // Ignore invalid entry if (d.name.Equals("")) { return; } // If we don't already have one then add this if (!heroes.ContainsKey(name)) { heroes.Add(name, d); d.sets.Add(packID); } // If we do replace if this has higher priority else if (heroes[name].priority < d.priority) { heroes.Remove(name); heroes.Add(name, d); } // items of the same priority belong to multiple packs else if (heroes[name].priority == d.priority) { heroes[name].sets.Add(packID); } } // Is this a "Class" entry? if (name.IndexOf(ClassData.type) == 0) { ClassData d = new ClassData(name, content, path); // Ignore invalid entry if (d.name.Equals("")) { return; } // If we don't already have one then add this if (!classes.ContainsKey(name)) { classes.Add(name, d); d.sets.Add(packID); } // If we do replace if this has higher priority else if (classes[name].priority < d.priority) { classes.Remove(name); classes.Add(name, d); } // items of the same priority belong to multiple packs else if (classes[name].priority == d.priority) { classes[name].sets.Add(packID); } } // Is this a "Skill" entry? if (name.IndexOf(SkillData.type) == 0) { SkillData d = new SkillData(name, content, path); // Ignore invalid entry if (d.name.Equals("")) { return; } // If we don't already have one then add this if (!skills.ContainsKey(name)) { skills.Add(name, d); d.sets.Add(packID); } // If we do replace if this has higher priority else if (skills[name].priority < d.priority) { skills.Remove(name); skills.Add(name, d); } // items of the same priority belong to multiple packs else if (skills[name].priority == d.priority) { skills[name].sets.Add(packID); } } // Is this a "Item" entry? if (name.IndexOf(ItemData.type) == 0) { ItemData d = new ItemData(name, content, path); // Ignore invalid entry if (d.name.Equals("")) { return; } // If we don't already have one then add this if (!items.ContainsKey(name)) { items.Add(name, d); d.sets.Add(packID); } // If we do replace if this has higher priority else if (items[name].priority < d.priority) { items.Remove(name); items.Add(name, d); } // items of the same priority belong to multiple packs else if (items[name].priority == d.priority) { items[name].sets.Add(packID); } } // Is this a "Monster" entry? if (name.IndexOf(MonsterData.type) == 0) { MonsterData d = new MonsterData(name, content, path); // Ignore invalid entry if (d.name.Equals("")) { return; } // Ignore monster activations if (name.IndexOf(ActivationData.type) != 0) { // If we don't already have one then add this if (!monsters.ContainsKey(name)) { monsters.Add(name, d); d.sets.Add(packID); } // If we do replace if this has higher priority else if (monsters[name].priority < d.priority) { monsters.Remove(name); monsters.Add(name, d); } // items of the same priority belong to multiple packs else if (monsters[name].priority == d.priority) { monsters[name].sets.Add(packID); } } } // Is this a "Activation" entry? if (name.IndexOf(ActivationData.type) == 0) { ActivationData d = new ActivationData(name, content, path); // Ignore invalid entry if (d.name.Equals("")) { return; } // If we don't already have one then add this if (!activations.ContainsKey(name)) { activations.Add(name, d); d.sets.Add(packID); } // If we do replace if this has higher priority else if (activations[name].priority < d.priority) { activations.Remove(name); activations.Add(name, d); } // items of the same priority belong to multiple packs else if (activations[name].priority == d.priority) { activations[name].sets.Add(packID); } } // Is this a "Attack" entry? if (name.IndexOf(AttackData.type) == 0) { AttackData d = new AttackData(name, content, path); // Ignore invalid entry if (d.name.Equals("")) { return; } // If we don't already have one then add this if (!investigatorAttacks.ContainsKey(name)) { investigatorAttacks.Add(name, d); d.sets.Add(packID); } // If we do replace if this has higher priority else if (investigatorAttacks[name].priority < d.priority) { investigatorAttacks.Remove(name); investigatorAttacks.Add(name, d); } // items of the same priority belong to multiple packs else if (investigatorAttacks[name].priority == d.priority) { investigatorAttacks[name].sets.Add(packID); } } // Is this a "Evade" entry? if (name.IndexOf(EvadeData.type) == 0) { EvadeData d = new EvadeData(name, content, path); // Ignore invalid entry if (d.name.Equals("")) { return; } // If we don't already have one then add this if (!investigatorEvades.ContainsKey(name)) { investigatorEvades.Add(name, d); d.sets.Add(packID); } // If we do replace if this has higher priority else if (investigatorEvades[name].priority < d.priority) { investigatorEvades.Remove(name); investigatorEvades.Add(name, d); } // items of the same priority belong to multiple packs else if (investigatorEvades[name].priority == d.priority) { investigatorEvades[name].sets.Add(packID); } } // Is this a "Horror" entry? if (name.IndexOf(HorrorData.type) == 0) { HorrorData d = new HorrorData(name, content, path); // Ignore invalid entry if (d.name.Equals("")) { return; } // If we don't already have one then add this if (!horrorChecks.ContainsKey(name)) { horrorChecks.Add(name, d); d.sets.Add(packID); } // If we do replace if this has higher priority else if (horrorChecks[name].priority < d.priority) { horrorChecks.Remove(name); horrorChecks.Add(name, d); } // items of the same priority belong to multiple packs else if (horrorChecks[name].priority == d.priority) { horrorChecks[name].sets.Add(packID); } } // Is this a "Token" entry? if (name.IndexOf(TokenData.type) == 0) { TokenData d = new TokenData(name, content, path); // Ignore invalid entry if (d.name.Equals("")) { return; } // If we don't already have one then add this if (!tokens.ContainsKey(name)) { tokens.Add(name, d); d.sets.Add(packID); } // If we do replace if this has higher priority else if (tokens[name].priority < d.priority) { tokens.Remove(name); tokens.Add(name, d); } // items of the same priority belong to multiple packs else if (tokens[name].priority == d.priority) { tokens[name].sets.Add(packID); } } // Is this a "Peril" entry? if (name.IndexOf(PerilData.type) == 0) { PerilData d = new PerilData(name, content); // Ignore invalid entry if (d.sectionName.Equals("")) { return; } // If we don't already have one then add this if (!perils.ContainsKey(name)) { perils.Add(name, d); } // If we do replace if this has higher priority else if (perils[name].priority < d.priority) { perils.Remove(name); perils.Add(name, d); } } // Is this a "Puzzle" entry? if (name.IndexOf(PuzzleData.type) == 0) { PuzzleData d = new PuzzleData(name, content, path); // Ignore invalid entry if (d.name.Equals("")) { return; } // If we don't already have one then add this if (!puzzles.ContainsKey(name)) { puzzles.Add(name, d); d.sets.Add(packID); } // If we do replace if this has higher priority else if (puzzles[name].priority < d.priority) { puzzles.Remove(name); puzzles.Add(name, d); } // items of the same priority belong to multiple packs else if (puzzles[name].priority == d.priority) { puzzles[name].sets.Add(packID); } } // Is this a "Image" entry? if (name.IndexOf(ImageData.type) == 0) { ImageData d = new ImageData(name, content, path); // Ignore invalid entry if (d.name.Equals("")) { return; } // If we don't already have one then add this if (!images.ContainsKey(name)) { images.Add(name, d); d.sets.Add(packID); } // If we do replace if this has higher priority else if (images[name].priority < d.priority) { images.Remove(name); images.Add(name, d); } // items of the same priority belong to multiple packs else if (images[name].priority == d.priority) { images[name].sets.Add(packID); } } // Is this a "Audio" entry? if (name.IndexOf(AudioData.type) == 0) { AudioData d = new AudioData(name, content, path); // Ignore invalid entry if (d.name.Equals("")) { return; } // If we don't already have one then add this if (!audio.ContainsKey(name)) { audio.Add(name, d); } // If we do replace if this has higher priority else if (audio[name].priority < d.priority) { audio.Remove(name); audio.Add(name, d); } } }
// Create new activation public void NewActivation(ActivationData contentActivation) { currentActivation = new ActivationInstance(contentActivation, monsterData.name.Translate()); }
// Activate a monster virtual public bool ActivateMonster(Quest.Monster m) { List <ActivationData> adList = new List <ActivationData>(); Game game = Game.Get(); bool customActivations = false; MonsterData md = m.monsterData; // Find out of this monster is quest specific QuestMonster qm = md as QuestMonster; if (qm != null) { // Get the base monster type if (game.cd.ContainsKey <MonsterData>(qm.derivedType)) { md = game.cd.Get <MonsterData>(qm.derivedType); } // Determine if the monster has quest specific activations customActivations = !qm.useMonsterTypeActivations; } // A monster with quest specific activations if (customActivations) { if (!qm.useMonsterTypeActivations) { adList = new List <ActivationData>(); // Get all custom activations foreach (string s in qm.activations) { // Find the activation in quest data if (game.quest.qd.components.ContainsKey("Activation" + s) && game.quest.vars.Test((game.quest.qd.components["Activation" + s] as QuestData.Activation).tests) ) { adList.Add(new QuestActivation(game.quest.qd.components["Activation" + s] as QuestData.Activation)); } // Otherwise look for the activation in content data else if (game.cd.TryGet("MonsterActivation" + s, out ActivationData activationData)) { adList.Add(activationData); } else // Invalid activation { game.quest.log.Add(new Quest.LogEntry("Warning: Unable to find activation: " + s + " for monster type: " + m.monsterData.sectionName, true)); } } } } else // Content Data activations only { // Find all possible activations foreach (KeyValuePair <string, ActivationData> kv in game.cd.GetAll <ActivationData>()) { // Is this activation for this monster type? (replace "Monster" with "MonsterActivation", ignore specific variety) if (kv.Key.IndexOf("MonsterActivation" + md.sectionName.Substring("Monster".Length)) == 0) { adList.Add(kv.Value); } } // Search for additional common activations foreach (string s in md.activations) { if (game.cd.TryGet("MonsterActivation" + s, out ActivationData activationData)) { adList.Add(activationData); } else { ValkyrieDebug.Log("Warning: Unable to find activation: " + s + " for monster type: " + md.sectionName); } } } // Check for no activations if (adList.Count == 0) { ValkyrieDebug.Log("Error: Unable to find any activation data for monster type: " + md.name); Application.Quit(); } // No current activation if (m.currentActivation == null) { // Pick a random activation ActivationData activation = adList[Random.Range(0, adList.Count)]; m.NewActivation(activation); } // MoM has a special activation if (game.gameType is MoMGameType) { m.masterStarted = true; new ActivateDialogMoM(m); return(false); } // If no minion activation just do master if (m.currentActivation.ad.minionActions.fullKey.Length == 0) { m.minionStarted = true; m.masterStarted = true; new ActivateDialog(m, true, true); return(false); } // If no master activation just do minion if (m.currentActivation.ad.masterActions.fullKey.Length == 0) { m.minionStarted = true; m.masterStarted = true; new ActivateDialog(m, false, true); return(false); } // Random pick Minion or master (both available) m.minionStarted = Random.Range(0, 2) == 0; // If order specificed then use that instead if (m.currentActivation.ad.masterFirst) { m.minionStarted = false; } if (m.currentActivation.ad.minionFirst) { m.minionStarted = true; } // Master is opposite of minion as this is the first activation m.masterStarted = !m.minionStarted; // Create activation window new ActivateDialog(m, m.masterStarted); // More groups unactivated return(false); }