/// <summary>Recompose the GameSystemController with the latest components available.</summary> public void Recompose() { // Recompose the private Imported properties, then prepare a new usable list of each game element, // and replace the public list with a new one. NOTE: we do not modify the existing public lists // at any time because they may be actively being iterated by other threads. DefaultComposer.Container.ComposeParts(this); this.GameAttributes = DefaultComposer.GetLatestDistinctTypeInstances(this.ImportedGameAttributes); this.GameGenders = DefaultComposer.GetLatestDistinctTypeInstances(this.ImportedGameGenders); this.GameModifiers = DefaultComposer.GetLatestDistinctTypeInstances(this.ImportedGameModifiers); this.GameRaces = DefaultComposer.GetLatestDistinctTypeInstances(this.ImportedGameRaces); this.GameRules = DefaultComposer.GetLatestDistinctTypeInstances(this.ImportedGameRules); this.GameSkills = DefaultComposer.GetLatestDistinctTypeInstances(this.ImportedGameSkills); this.GameStats = DefaultComposer.GetLatestDistinctTypeInstances(this.ImportedGameStats); }
/// <summary>Recompose the subcomponents of this Renderer.</summary> public void Recompose() { DefaultComposer.Container.ComposeParts(this); // Search each of the renderers for the one which has the highest priority. this.currentCommandsCategoriesRenderer = DefaultComposer.GetInstance(this.CommandsCategoriesRenderers); this.currentCommandsListRenderer = DefaultComposer.GetInstance(this.CommandsListRenderers); this.currentHelpCommandRenderer = DefaultComposer.GetInstance(this.HelpCommandRenderers); this.currentHelpTopicRenderer = DefaultComposer.GetInstance(this.HelpTopicRenderers); this.currentHelpTopicsRenderer = DefaultComposer.GetInstance(this.HelpTopicsRenderers); this.currentInventoryRenderer = DefaultComposer.GetInstance(this.InventoryRenderers); this.currentPerceivedRoomRenderer = DefaultComposer.GetInstance(this.PerceivedRoomRenderers); this.currentPerceivedThingRenderer = DefaultComposer.GetInstance(this.PerceivedThingRenderers); this.currentScoreRenderer = DefaultComposer.GetInstance(this.ScoreRenderers); this.currentSplashScreenRenderer = DefaultComposer.GetInstance(this.SplashScreenRenderers); this.currentWhoRenderer = DefaultComposer.GetInstance(this.WhoRenderers); }
/// <summary>Recompose the <see cref="CommandManager"/> system.</summary> public void Recompose() { DefaultComposer.Container.ComposeParts(this); // During non-reboot updates (recomposition): To minimize impact to the running application and players, the // existing command lists will remain intact until preparing the new commands list is complete. Then all the // commands will switch over by replacing the command list references. Thus, the old code will continue to // be used until all new commands are ready, at which point all processed commands start using the new code. // Old MasterCommandList references and old command objects themselves should garbage collect eventually, so // long as nothing is holding references to them incorrectly. var newPrimaryCommandList = new Dictionary <string, Command>(); var newMasterCommandList = new Dictionary <string, Command>(); var actionTypes = DefaultComposer.GetTypes(this.GameActions); foreach (Type type in actionTypes) { // Find the description of this command. object[] descripts = type.GetCustomAttributes(typeof(ActionDescriptionAttribute), false); object[] examples = type.GetCustomAttributes(typeof(ActionExampleAttribute), false); string descript = (from d in descripts select(d as ActionDescriptionAttribute).Description).FirstOrDefault(); string example = (from e in examples select(e as ActionExampleAttribute).Example).FirstOrDefault(); // All alias variations are going to reference the same, single command. // The command defaults to let nobody run it, unless we find an attribute for it. var command = new Command(type, descript, example, SecurityRole.none); // Find out what security roles are associated with that action. // By default, the securityRole will be 'none' so if no security attribute // was specified, then nobody will be able to execute it. object[] roles = type.GetCustomAttributes(typeof(ActionSecurityAttribute), false); command.SecurityRole = (from r in roles select(r as ActionSecurityAttribute).Role).FirstOrDefault(); foreach (object obj in type.GetCustomAttributes(typeof(ActionPrimaryAliasAttribute), false)) { var attr = obj as ActionPrimaryAliasAttribute; var alias = attr.Alias; command.Category = attr.Category; command.PrimaryAlias = true; newPrimaryCommandList.Add(alias, command); newMasterCommandList.Add(alias, command); } // For every alias associated with that action, store a reference to the Command // that represents the action and allows the user to invoke an instance. // If using ActionAliasAttribute that means this is not considered a PrimaryAlias...find the primary // and add it to this. While we're at it, add this to the primary. foreach (object obj in type.GetCustomAttributes(typeof(ActionAliasAttribute), false)) { var attr = obj as ActionAliasAttribute; var alias = attr.Alias; var secondaryCommand = new Command(type, command.SecurityRole) { Category = attr.Category, PrimaryAlias = false }; newMasterCommandList.Add(alias, secondaryCommand); } } // Avoid replacing our lists while another thread is iterating them. // TODO: Exposing MasterCommandList this way is very likely NOT thread-safe. Change to a lock-protected getter? lock (this) { this.primaryCommandList = newPrimaryCommandList; this.MasterCommandList = newMasterCommandList; } }