/// <summary> /// Creates a new <see cref="Machine"/> of the specified <see cref="Type"/>. /// </summary> /// <param name="mid">Unbound machine id</param> /// <param name="type">Type of the machine</param> /// <param name="friendlyName">Friendly machine name used for logging</param> /// <returns>Machine</returns> private Machine CreateMachine(MachineId mid, Type type, string friendlyName) { this.Assert(type.IsSubclassOf(typeof(Machine)), "Type '{0}' is not a machine.", type.Name); if (mid == null) { mid = new MachineId(type, friendlyName, this); } else { this.Assert(mid.Runtime == null || mid.Runtime == this, "Unbound machine id '{0}' was created by another runtime.", mid.Value); this.Assert(mid.Type == type.FullName, "Cannot bind machine id '{0}' of type '{1}' to a machine of type '{2}'.", mid.Value, mid.Type, type.FullName); mid.Bind(this); } Machine machine = MachineFactory.Create(type); machine.Initialize(this, mid, new MachineInfo(mid)); machine.InitializeStateInformation(); bool result = this.MachineMap.TryAdd(mid, machine); this.Assert(result, "Machine with id '{0}' was already created in generation '{1}'. This typically occurs " + "either if the machine id was created by another runtime instance, or if a machine id from a previous " + "runtime generation was deserialized, but the current runtime has not increased its generation value.", mid.Value, mid.Generation); return(machine); }
/// <summary> /// Tries to create a new machine of the specified type. /// </summary> /// <param name="creator">Creator machine</param> /// <param name="type">Type of the machine</param> /// <param name="friendlyName">Friendly machine name used for logging</param> /// <param name="e">Event</param> /// <returns>MachineId</returns> internal virtual MachineId TryCreateMachine(Machine creator, Type type, string friendlyName, Event e) { this.Assert(type.IsSubclassOf(typeof(Machine)), $"Type '{type.Name}' is not a machine."); MachineId mid = new MachineId(type, friendlyName, this); if (!MachineConstructorMap.ContainsKey(type)) { Func <Machine> constructor = Expression.Lambda <Func <Machine> >( Expression.New(type.GetConstructor(Type.EmptyTypes))).Compile(); MachineConstructorMap[type] = constructor; } Machine machine = MachineConstructorMap[type](); machine.SetMachineId(mid); machine.InitializeStateInformation(); bool result = this.MachineMap.TryAdd(mid.Value, machine); this.Assert(result, $"Machine '{mid}' was already created."); Task task = new Task(() => { try { machine.GotoStartState(e); machine.RunEventHandler(); } catch (Exception) { if (this.Configuration.ThrowInternalExceptions) { throw; } } finally { this.TaskMap.TryRemove(Task.CurrentId.Value, out machine); } }); this.MachineTasks.Add(task); this.TaskMap.TryAdd(task.Id, machine); task.Start(); return(mid); }
/// <summary> /// Creates a new <see cref="Machine"/> of the specified <see cref="Type"/>. /// </summary> /// <param name="type">Type of the machine</param> /// <param name="friendlyName">Friendly machine name used for logging</param> /// <returns>Machine</returns> private Machine CreateMachine(Type type, string friendlyName) { base.Assert(type.IsSubclassOf(typeof(Machine)), $"Type '{type.Name}' is not a machine."); MachineId mid = new MachineId(type, friendlyName, this); Machine machine = MachineFactory.Create(type); machine.Initialize(this, mid, new MachineInfo(mid)); machine.InitializeStateInformation(); bool result = this.MachineMap.TryAdd(mid.Value, machine); base.Assert(result, $"Machine '{mid}' was already created."); base.Log($"<CreateLog> Machine '{mid}' is created."); return(machine); }