// events, OnRegistered, OnUnregistered /// <summary> /// Registers a group under the given name. /// </summary> /// <param name="name">The name this group is registered under.</param> /// <returns></returns> public BehaviorGroup Register(string name) { BehaviorGroup group = new BehaviorGroup(name); group.Coordinator = this; Register(group); return(group); }
// with this method we wish to unregiser a specific instance // it is very likely that this method should be removed /// <summary> /// Unregisters a specific group. /// </summary> /// <param name="group">The reference to the group instance to unregister.</param> public void Unregister(BehaviorGroup group) { List <BehaviorGroup> groups = registrants[group.Name]; if (groups.Contains(group)) { groups.Remove(group); // nullify the reference to the coordinator, as it is no longer registered group.Coordinator = null; } }
/// <summary> /// Initializes behavior specific variables that are affected by data from outside the group, and injects non-local dependencies. /// </summary> public virtual void Start() { FieldInfo[] fields = GetType().GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (FieldInfo field in fields) { object[] attributes = field.GetCustomAttributes(typeof(BehaviorDependency), false); foreach (BehaviorDependency attribute in attributes) { string groupName = attribute.Group; if (groupName == null || !(groupName.Length > 0)) { break; } if (!field.FieldType.IsSubclassOf(typeof(Behavior))) { // get outta here, as the field is not a behavior throw new ArgumentException("This field can not be marked as a dependency.", field.Name); } BehaviorGroup externalGroup = group.Coordinator.Select(groupName)[attribute.Index]; if (externalGroup.IsAssociated(field.FieldType)) { field.SetValue(this, externalGroup.Get(field.FieldType)); break; } Behavior behavior = null; try { behavior = Activator.CreateInstance(field.FieldType) as Behavior; } catch (MissingMethodException) { throw new MissingMethodException("The behavior dependency does not implement an empty constructor."); } externalGroup.Associate(behavior); // inject newly created reference field.SetValue(this, behavior); } } }
// because of this overload, it is possible to register a group under multiple names // possibly an un-wanted feature // update: for now, keep it private /// <summary> /// Registers a specific group under the given name. /// </summary> /// <param name="name"></param> /// <param name="group"></param> // experiment: made internal so that a group can register itself if instantiated with a constructor that takes a coordinator internal void Register(BehaviorGroup group) { // exceptions are not thrown before the group has actually been instanciated // this means garbage can potentially be made constantly. best solution // would be to check before creating the new instance if (registrants.ContainsKey(group.Name)) { registrants[group.Name].Add( group); } else { registrants.Add( group.Name, new List <BehaviorGroup>( new BehaviorGroup[] { group })); } }