/// <summary> /// Creates the root nest node from the given TypeBuilder. /// </summary> /// <param name="tb">The type builder to create for.</param> /// <param name="gen">The ILGenerator for the global function.</param> /// <param name="captures">The captures for the global function.</param> /// <param name="createType"> /// Whether to create a type for the global function. /// </param> /// <returns>The new root nest node.</returns> public static NestInfo Create(TypeBuilder tb, ILGenerator gen, NameItem[] captures, bool createType) { NestInfo temp = new NestInfo(tb); return(new NestInfo(temp, gen, captures, createType, false)); }
private void UpdateNestList() { var nestInfo = new NestInfo(); nestInfo.hubNest = gameNests[0, 0]; nestInfo.plainsNest1 = gameNests[1, 0]; nestInfo.plainsNest2 = gameNests[1, 1]; nestInfo.plainsNest3 = gameNests[1, 2]; nestInfo.desertNest1 = gameNests[2, 0]; nestInfo.desertNest2 = gameNests[2, 1]; nestInfo.desertNest3 = gameNests[2, 2]; nestInfo.underwaterNest1 = gameNests[3, 0]; nestInfo.underwaterNest2 = gameNests[3, 1]; nestInfo.underwaterNest3 = gameNests[3, 2]; nestInfo.jungleNest1 = gameNests[4, 0]; nestInfo.jungleNest2 = gameNests[4, 1]; nestInfo.jungleNest3 = gameNests[4, 2]; nestInfo.skylandNest1 = gameNests[5, 0]; nestInfo.skylandNest2 = gameNests[5, 1]; nestInfo.skylandNest3 = gameNests[5, 2]; nestInfo.castleNest1 = gameNests[6, 0]; nestInfo.castleNest2 = gameNests[6, 1]; nestInfo.castleNest3 = gameNests[6, 2]; GameManager.instance.gameFile.gameProgression.nestInfo = nestInfo; }
/// <summary> /// Creates a new nest with the given parent. /// </summary> /// <param name="parent">The parent nest.</param> /// <param name="gen">The generator used to generate code for this function.</param> /// <param name="storeParent"> /// True to create a field that stores the parent instance; otherwise false. /// </param> /// <param name="captures"> /// The local variables that have been captured by nested functions. /// </param> /// <param name="createType">True to create a nested type, otherwise false.</param> public NestInfo(NestInfo parent, ILGenerator gen, NameItem[] captures, bool createType, bool storeParent) { FreeLocals = new Dictionary <Type, Stack <LocalBuilder> >(); Members = new HashSet <string>(); _captures = new HashSet <NameItem>(captures); Parent = parent; Generator = gen; Locals = new Stack <Dictionary <string, IVarDefinition> >(); Locals.Push(new Dictionary <string, IVarDefinition>()); if (createType) { // create the type and constructor. TypeDef = parent.TypeDef.DefineNestedType( "<>c__DisplayClass" + (_id++), TypeAttributes.NestedPublic | TypeAttributes.Sealed | TypeAttributes.BeforeFieldInit); var ctor = TypeDef.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, new Type[0]); var cgen = ctor.GetILGenerator(); // base(); cgen.Emit(OpCodes.Ldarg_0); cgen.Emit(OpCodes.Call, typeof(object).GetConstructor(new Type[0])); cgen.Emit(OpCodes.Ret); if (storeParent) { ParentInst = TypeDef.DefineField("CS$<>__locals", parent.TypeDef, FieldAttributes.Public); } else { ParentInst = null; } // create the local definition // ThisInst = new TypeDef(); ThisInst = gen.DeclareLocal(TypeDef); gen.Emit(OpCodes.Newobj, ctor); gen.Emit(OpCodes.Stloc, ThisInst); if (storeParent) { // ThisInst.ParentInst = this; gen.Emit(OpCodes.Ldloc, ThisInst); gen.Emit(OpCodes.Ldarg_0); gen.Emit(OpCodes.Stfld, ParentInst); } } else { TypeDef = null; ThisInst = null; ParentInst = null; } }
/// <summary> /// Creates a new ChunkBuilder and initializes the state. /// </summary> /// <param name="tb">The root type of this chunk.</param> /// <param name="captures">An array of the global captures.</param> /// <param name="createType"> /// True to create a nested type for the global function, this means that there are nested /// functions. /// </param> public ChunkBuilder(TypeBuilder tb, NameItem[] captures, bool createType) { //// ILuaEnviormnent $Env; var field = tb.DefineField("$Env", typeof(ILuaEnvironment), FieldAttributes.Private); //// ILuaMultiValue Invoke(ILuaEnvironment E, ILuaMultiValue args); var method = tb.DefineMethod( nameof(ILuaValue.Invoke), MethodAttributes.Public | MethodAttributes.HideBySig, typeof(ILuaMultiValue), new[] { typeof(ILuaEnvironment), typeof(ILuaMultiValue) }); _curNest = NestInfo.Create(tb, method.GetILGenerator(), captures, createType); _addInvoke(tb, method, field); _addConstructor(tb, field); _addAbstracts(tb); }
public void SimulationStarted() { passivesInNewNests = new Dictionary <int, int>(); // Find and keep a reference to the best nest option foreach (NestInfo nest in simulation.NestInfo) { if (bestNest == null || nest.Nest.quality > bestNest.Nest.quality) { bestNest = nest; } if (nest.IsStartingNest != true) { passivesInNewNests.Add(nest.NestId, 0); } } updateNestNumbers(); }
/// <summary> /// Creates a new nest with the given parrent. /// </summary> /// <param name="parrent">The parrent nest.</param> /// <param name="gen">The generator used to generate code for this /// function.</param> /// <param name="storeParrent">True to create a field that stores /// the parrent instance; otherwise false.</param> /// <param name="captures">The local variables that have been /// captured by nested functions.</param> /// <param name="createType">True to create a nested type, otherwise /// false.</param> public NestInfo(NestInfo parrent, ILGenerator gen, NameItem[] captures, bool createType, bool storeParrent) { this.FreeLocals = new Dictionary<Type, Stack<LocalBuilder>>(); this.members = new HashSet<string>(); this.captures = new HashSet<NameItem>(captures); this.Parrent = parrent; this.Generator = gen; this.Locals = new Stack<Dictionary<string, VarDefinition>>(); this.Locals.Push(new Dictionary<string, VarDefinition>()); if (createType) { // create the type and constructor. this.TypeDef = parrent.TypeDef.DefineNestedType("<>c__DisplayClass" + (ID++), TypeAttributes.NestedPublic | TypeAttributes.Sealed | TypeAttributes.BeforeFieldInit); var ctor = this.TypeDef.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, new Type[0]); var cgen = ctor.GetILGenerator(); // base(); cgen.Emit(OpCodes.Ldarg_0); cgen.Emit(OpCodes.Call, typeof(object).GetConstructor(new Type[0])); cgen.Emit(OpCodes.Ret); if (storeParrent) this.ParrentInst = this.TypeDef.DefineField("CS$<>__locals", parrent.TypeDef, FieldAttributes.Public); else this.ParrentInst = null; // create the local definition // ThisInst = new TypeDef(); this.ThisInst = gen.DeclareLocal(this.TypeDef); gen.Emit(OpCodes.Newobj, ctor); gen.Emit(OpCodes.Stloc, this.ThisInst); if (storeParrent) { // ThisInst.ParrentInst = this; gen.Emit(OpCodes.Ldloc, this.ThisInst); gen.Emit(OpCodes.Ldarg_0); gen.Emit(OpCodes.Stfld, this.ParrentInst); } } else { this.TypeDef = null; this.ThisInst = null; this.ParrentInst = null; } }
/// <summary> /// Implements a function definition based on a given function definition. /// </summary> /// <param name="funcName">The simple name of the function, can be null.</param> /// <param name="visitor">The current visitor object.</param> /// <param name="function">The function to generate for.</param> public void ImplementFunction(IParseItemVisitor visitor, FuncDefItem function, string funcName) { NameItem[] args = function.Arguments.ToArray(); if (function.InstanceName != null) args = new[] { new NameItem("self") }.Union(args).ToArray(); // ILuaMultiValue function(ILuaEnvironment E, ILuaMultiValue args, ILuaValue target, bool memberCall); funcName = funcName ?? "<>__" + (_mid++); string name = curNest.members.Contains(funcName) ? funcName + "_" + (_mid++) : funcName; MethodBuilder mb = curNest.TypeDef.DefineMethod(name, MethodAttributes.Public, typeof(ILuaMultiValue), new Type[] { typeof(ILuaEnvironment), typeof(ILuaMultiValue), typeof(ILuaValue), typeof(bool) }); var gen = mb.GetILGenerator(); curNest = new NestInfo(curNest, gen, function.FunctionInformation.CapturedLocals, function.FunctionInformation.HasNested, function.FunctionInformation.CapturesParrent); // if this is an instance method, create a BaseAccessor object to help types. if (function.InstanceName != null) { // TODO: Add base accessor back. //var field = curNest.DefineLocal(new NameItem("base")); } // If this was an instance call, the first Lua argument is the 'target'; // otherwise the it is the zero'th index in args. // int c = 0; var c = gen.DeclareLocal(typeof(int)); if (args.Length > 0) { var field = curNest.DefineLocal(args[0]); var end = gen.DefineLabel(); var else_ = gen.DefineLabel(); // if (!memberCall) c = 1; // {field_0} = (memberCall ? target : args[0]); field.StartSet(); gen.Emit(OpCodes.Ldarg, 4); gen.Emit(OpCodes.Brfalse, else_); gen.Emit(OpCodes.Ldarg_3); gen.Emit(OpCodes.Br, end); gen.MarkLabel(else_); gen.Emit(OpCodes.Ldc_I4_1); gen.Emit(OpCodes.Stloc, c); gen.Emit(OpCodes.Ldarg_2); if (args[0].Name != "...") { gen.Emit(OpCodes.Ldc_I4_0); gen.Emit(OpCodes.Callvirt, typeof(ILuaMultiValue).GetMethod("get_Item")); } else { if (args.Length != 1) throw new InvalidOperationException("Variable arguments (...) only valid at end of argument list."); } gen.MarkLabel(end); field.EndSet(); } for (int i = 1; i < args.Length; i++) { var field = curNest.DefineLocal(args[i]); if (args[i].Name == "...") { if (i != args.Length - 1) throw new InvalidOperationException("Variable arguments (...) only valid at end of argument list."); // {field} = E.Runtime.CreateMultiValue(args.Skip({args.Length - 1}); field.StartSet(); gen.Emit(OpCodes.Ldarg_1); gen.Emit(OpCodes.Callvirt, typeof(ILuaEnvironment).GetMethod("get_Runtime")); gen.Emit(OpCodes.Ldarg_2); gen.Emit(OpCodes.Ldc_I4, args.Length - 1); gen.Emit(OpCodes.Call, typeof(Enumerable).GetMethod("Skip").MakeGenericMethod(typeof(object))); gen.Emit(OpCodes.Callvirt, typeof(ILuaRuntime).GetMethod("CreateMultiValue")); field.EndSet(); } else { // {field} = args[{i - 1} + c]; field.StartSet(); gen.Emit(OpCodes.Ldarg_2); gen.Emit(OpCodes.Ldc_I4, i-1); gen.Emit(OpCodes.Ldloc, c); gen.Emit(OpCodes.Add); gen.Emit(OpCodes.Callvirt, typeof(ILuaMultiValue).GetMethod("get_Item")); field.EndSet(); } } function.Block.Accept(visitor); if (curNest.TypeDef != null) curNest.TypeDef.CreateType(); curNest = curNest.Parrent; // push a pointer to the new method onto the stack of the previous nest method // the above line restores the nest to the previous state and this code will // push the new method. //! push E.Runtime.CreateFunctionValue({name}, {nest.TypeDef}.GetMethod({name}), {nest.ThisInst != null ? nest.NestInst : this} ); curNest.Generator.Emit(OpCodes.Ldarg_1); curNest.Generator.Emit(OpCodes.Callvirt, typeof(ILuaEnvironment).GetMethod("get_Runtime")); curNest.Generator.Emit(OpCodes.Ldstr, name); curNest.Generator.Emit(OpCodes.Ldtoken, curNest.TypeDef); curNest.Generator.Emit(OpCodes.Call, typeof(Type).GetMethod("GetTypeFromHandle", new Type[] { typeof(RuntimeTypeHandle) })); curNest.Generator.Emit(OpCodes.Ldstr, name); curNest.Generator.Emit(OpCodes.Callvirt, typeof(Type).GetMethod("GetMethod", new[] { typeof(string) })); if (curNest.ThisInst != null) curNest.Generator.Emit(OpCodes.Ldloc, curNest.ThisInst); else curNest.Generator.Emit(OpCodes.Ldarg_0); curNest.Generator.Emit(OpCodes.Callvirt, typeof(ILuaRuntime).GetMethod("CreateImplementationFunction")); }
/// <summary> /// Creates a new ChunkBuilder and initializes the state. /// </summary> /// <param name="tb">The root type of this chunk.</param> /// <param name="captures">An array of the global captures.</param> /// <param name="createType">True to create a nested type for the global /// function, this means that there are nested functions.</param> public ChunkBuilder(TypeBuilder tb, NameItem[] captures, bool createType) { //// ILuaEnviormnent $Env; var field = tb.DefineField("$Env", typeof(ILuaEnvironment), FieldAttributes.Private); //// ILuaMultiValue Invoke(ILuaEnvironment E, ILuaMultiValue args); var method = tb.DefineMethod("Invoke", MethodAttributes.Public | MethodAttributes.HideBySig, typeof(ILuaMultiValue), new[] { typeof(ILuaEnvironment), typeof(ILuaMultiValue) }); curNest = NestInfo.Create(tb, method.GetILGenerator(), captures, createType); AddInvoke(tb, method, field); AddConstructor(tb, field); AddAbstracts(tb); }
/// <summary> /// Creates the root nest node from the given TypeBuilder. /// </summary> /// <param name="tb">The type builder to create for.</param> /// <param name="gen">The ILGenerator for the global function.</param> /// <param name="captures">The captures for the global function.</param> /// <param name="createType">Whether to create a type for the global /// function.</param> /// <returns>The new root nest node.</returns> public static NestInfo Create(TypeBuilder tb, ILGenerator gen, NameItem[] captures, bool createType) { NestInfo temp = new NestInfo(tb); return new NestInfo(temp, gen, captures, createType, false); }
/// <summary> /// Implements a function definition based on a given function definition. /// </summary> /// <param name="funcName">The simple name of the function, can be null.</param> /// <param name="visitor">The current visitor object.</param> /// <param name="function">The function to generate for.</param> public void ImplementFunction(IParseItemVisitor visitor, FuncDefItem function, string funcName) { NameItem[] args = function.Arguments.ToArray(); if (function.InstanceName != null) { args = new[] { new NameItem("self") }.Concat(args).ToArray(); } // ILuaMultiValue function(ILuaEnvironment E, ILuaMultiValue args, ILuaValue target, // bool memberCall); funcName ??= "<>__" + (_mid++); string name = _curNest.Members.Contains(funcName) ? funcName + "_" + (_mid++) : funcName; MethodBuilder mb = _curNest.TypeDef.DefineMethod( name, MethodAttributes.Public, typeof(ILuaMultiValue), new Type[] { typeof(ILuaEnvironment), typeof(ILuaMultiValue), typeof(ILuaValue), typeof(bool) }); var gen = mb.GetILGenerator(); _curNest = new NestInfo( _curNest, gen, function.FunctionInformation.CapturedLocals, function.FunctionInformation.HasNested, function.FunctionInformation.CapturesParent); // if this is an instance method, create a BaseAccessor object to help types. if (function.InstanceName != null) { // TODO: Add base accessor back. //var field = curNest.DefineLocal(new NameItem("base")); } // If this was an instance call, the first Lua argument is the 'target'; // otherwise the it is the zero'th index in args. // int c = 0; var c = gen.DeclareLocal(typeof(int)); if (args.Length > 0) { var field = _curNest.DefineLocal(args[0]); var end = gen.DefineLabel(); var else_ = gen.DefineLabel(); // if (!memberCall) c = 1; // {field_0} = (memberCall ? target : args[0]); field.StartSet(); gen.Emit(OpCodes.Ldarg, 4); gen.Emit(OpCodes.Brfalse, else_); gen.Emit(OpCodes.Ldarg_3); gen.Emit(OpCodes.Br, end); gen.MarkLabel(else_); gen.Emit(OpCodes.Ldc_I4_1); gen.Emit(OpCodes.Stloc, c); gen.Emit(OpCodes.Ldarg_2); if (args[0].Name != "...") { gen.Emit(OpCodes.Ldc_I4_0); gen.Emit(OpCodes.Callvirt, typeof(ILuaMultiValue).GetMethod("get_Item")); } else { if (args.Length != 1) { throw new InvalidOperationException( "Variable arguments (...) only valid at end of argument list."); } } gen.MarkLabel(end); field.EndSet(); } for (int i = 1; i < args.Length; i++) { var field = _curNest.DefineLocal(args[i]); if (args[i].Name == "...") { if (i != args.Length - 1) { throw new InvalidOperationException( "Variable arguments (...) only valid at end of argument list."); } // {field} = E.Runtime.CreateMultiValue(args.Skip({args.Length - 1}); field.StartSet(); gen.Emit(OpCodes.Ldarg_1); gen.Emit( OpCodes.Callvirt, typeof(ILuaEnvironment).GetProperty(nameof(ILuaEnvironment.Runtime)).GetGetMethod()); gen.Emit(OpCodes.Ldarg_2); gen.Emit(OpCodes.Ldc_I4, args.Length - 1); gen.Emit(OpCodes.Call, typeof(Enumerable).GetMethod(nameof(Enumerable.Skip)) .MakeGenericMethod(typeof(object))); gen.Emit(OpCodes.Callvirt, typeof(ILuaRuntime).GetMethod(nameof(ILuaRuntime.CreateMultiValue))); field.EndSet(); } else { // {field} = args[{i - 1} + c]; field.StartSet(); gen.Emit(OpCodes.Ldarg_2); gen.Emit(OpCodes.Ldc_I4, i - 1); gen.Emit(OpCodes.Ldloc, c); gen.Emit(OpCodes.Add); gen.Emit(OpCodes.Callvirt, typeof(ILuaMultiValue).GetMethod("get_Item")); field.EndSet(); } } function.Block.Accept(visitor); if (_curNest.TypeDef != null) { _curNest.TypeDef.CreateType(); } _curNest = _curNest.Parent; // push a pointer to the new method onto the stack of the previous nest method // the above line restores the nest to the previous state and this code will // push the new method. //! push E.Runtime.CreateFunctionValue({name}, {nest.TypeDef}.GetMethod({name}), // {nest.ThisInst != null ? nest.NestInst : this} ); _curNest.Generator.Emit(OpCodes.Ldarg_1); _curNest.Generator.Emit( OpCodes.Callvirt, typeof(ILuaEnvironment).GetProperty(nameof(ILuaEnvironment.Runtime)).GetGetMethod()); _curNest.Generator.Emit(OpCodes.Ldstr, name); _curNest.Generator.Emit(OpCodes.Ldtoken, _curNest.TypeDef); _curNest.Generator.Emit( OpCodes.Call, typeof(Type).GetMethod(nameof(Type.GetTypeFromHandle), new Type[] { typeof(RuntimeTypeHandle) })); _curNest.Generator.Emit(OpCodes.Ldstr, name); _curNest.Generator.Emit( OpCodes.Callvirt, typeof(Type).GetMethod(nameof(Type.GetMethod), new[] { typeof(string) })); if (_curNest.ThisInst != null) { _curNest.Generator.Emit(OpCodes.Ldloc, _curNest.ThisInst); } else { _curNest.Generator.Emit(OpCodes.Ldarg_0); } _curNest.Generator.Emit( OpCodes.Callvirt, typeof(ILuaRuntime).GetMethod(nameof(ILuaRuntime.CreateImplementationFunction))); }
private void SpawnColony(Transform ants) { var antPrefab = Resources.Load(Naming.Resources.AntPrefab) as GameObject; Transform passive = MakeObject("P0", ants).transform; NestInfo.Add(new NestInfo(initialNest.NestManager(), 0, true, MakeObject(Naming.Ants.BehavourState.Assessing + "0", ants), MakeObject(Naming.Ants.BehavourState.Recruiting + "0", ants), passive.gameObject, MakeObject(Naming.Ants.BehavourState.Reversing + "0", ants) )); // Local variables for ant setup //find size of square to spawn ants into float sqrt = Mathf.Ceil(Mathf.Sqrt(Settings.ColonySize.Value)); //? int spawnedAnts = 0; int spawnedAntScouts = 0; //just spawns ants in square around wherever this is placed while (spawnedAnts < Settings.ColonySize.Value) { int column = 0; while ((column == 0 || spawnedAnts % sqrt != 0) && spawnedAnts < Settings.ColonySize.Value) { float row = Mathf.Floor(spawnedAnts / sqrt); Vector3 pos = initialNest.transform.position; //? pos.x -= 1; pos.z -= 1; GameObject newAnt = Instantiate(antPrefab, pos + (new Vector3(row, 0, column) * Length.v[Length.Spawning]), Quaternion.identity); newAnt.transform.position += new Vector3(0, newAnt.GetComponent <CapsuleCollider>().radius * 2, 0); newAnt.name = CreateAntId(Settings.ColonySize.Value, spawnedAnts); newAnt.AntMovement().simulation = this; AntManager newAM = newAnt.AntManager(); Ants.Add(newAM); newAM.AntId = spawnedAnts; newAM.myNest = initialNest.NestManager(); // why is there 2 of this here? is it meant to be old nest or something // newAM.myNest = initialNest; newAM.simulation = this; newAM.inNest = true; newAM.quorumThreshold = Settings.QuorumThreshold.Value; newAnt.transform.parent = passive; if (spawnedAnts < Settings.ColonySize.Value * Settings.ProportionActive.Value || Settings.ColonySize.Value <= 1 || _spawnOnlyScouts) { newAM.state = BehaviourState.Inactive; newAM.passive = false; newAnt.GetComponentInChildren <Renderer>().material.color = AntColours.States.Inactive; Transform senses = newAnt.transform.Find(Naming.Ants.SensesArea); (senses.GetComponent <SphereCollider>()).enabled = true; (senses.GetComponent <SphereCollider>()).radius = Length.v[Length.SensesCollider]; (senses.GetComponent <AntSenses>()).enabled = true; if (spawnedAntScouts < InitialScouts || Settings.ColonySize.Value <= 1 || _spawnOnlyScouts) { newAM.nextAssessment = TotalElapsedSimulatedTime("s") + RandomGenerator.Instance.Range(0.5f, 1f) * Times.v[Times.MaxAssessmentWait]; spawnedAntScouts++; } else { newAM.nextAssessment = 0; } } else { // Passive ant newAM.passive = true; newAnt.GetComponentInChildren <Renderer>().material.color = AntColours.States.InactivePassive; } column++; spawnedAnts++; } } }