Example #1
0
        public void makeTraits(int item)
        {
            Pawn        pawn         = this.parent.pawn;
            float       recordCounts = traitsOverTimes[item].recordCount;
            TraitDef    traitDef     = traitsOverTimes[item].traitDef;
            SimpleCurve ageOverTime  = traitsOverTimes[item].ageFractionCurve;
            RecordDef   records      = traitsOverTimes[item].recordDef;
            int         degree       = traitsOverTimes[item].degree;
            bool        changeDegree = traitsOverTimes[item].changeDegree;

            traitIfStatsMatch(traitDef, records, recordCounts, degree, pawn.ageTracker.AgeBiologicalYears, ageOverTime, changeDegree);
        }
        public override int GetMinHeaderHeight(PawnTable table) => Mathf.CeilToInt(Text.CalcSize(def.LabelCap.WordWrapAt(GetMinWidth(table))).y); //not messy at all.

        public override int Compare(Pawn a, Pawn b)
        {
            RecordDef recordDef = def.Ext().record;

            if (recordDef.type == RecordType.Time)
            {
                return(a.records.GetAsInt(recordDef).CompareTo(b.records.GetAsInt(recordDef)));
            }
            else
            {
                return(a.records.GetValue(recordDef).CompareTo(b.records.GetValue(recordDef)));
            }
        }
Example #3
0
        public IEnumerable <String> ServerCommand(ServerCommandDef c)
        {
            var EventRef = GetSuffixedTypeRef(c.Name, c.Version, "Event");
            var Event    = new RecordDef {
                Name = EventRef.Name, Version = EventRef.Version, GenericParameters = new List <VariableDef> {
                }, Fields = c.OutParameters, Attributes = c.Attributes, Description = c.Description
            };

            foreach (var _Line in Combine(Begin(), Record(Event)))
            {
                yield return(_Line);
            }
        }
 public void GiveTraitIfConditionReached(string traitName, RecordDef record, float recordsCount, int degree)
 {
     if (pawn.story.traits.allTraits.Count >= 3)
     {
         return;
     }
     if (!pawn.story.traits.HasTrait(TraitDef.Named(traitName)))
     {
         if (pawn.records.GetValue(record) > recordsCount)
         {
             pawn.story.traits.GainTrait(new Trait(TraitDef.Named(traitName), degree, false));
         }
     }
 }
Example #5
0
        public IEnumerable <String> GetTypePredefinition(TypeDef t)
        {
            var    Name = t.DefinitionName();
            var    GenericParameterLine = GetGenericParameterLine(t.GenericParameters());
            String MetaType             = "class";

            if (t.OnPrimitive)
            {
                return(new List <String> {
                });
            }
            else if (t.OnAlias || t.OnRecord || t.OnTaggedUnion || t.OnClientCommand || t.OnServerCommand)
            {
                MetaType = "class";
            }
            else if (t.OnEnum)
            {
                return(new List <String> {
                });
            }
            if (t.OnClientCommand)
            {
                var c          = t.ClientCommand;
                var RequestRef = GetSuffixedTypeRef(c.Name, c.Version, "Request");
                var ReplyRef   = GetSuffixedTypeRef(c.Name, c.Version, "Reply");
                var Request    = new RecordDef {
                    Name = RequestRef.Name, Version = RequestRef.Version, GenericParameters = new List <VariableDef> {
                    }, Fields = c.OutParameters, Attributes = c.Attributes, Description = c.Description
                };
                var Reply = new TaggedUnionDef {
                    Name = ReplyRef.Name, Version = ReplyRef.Version, GenericParameters = new List <VariableDef> {
                    }, Alternatives = c.InParameters, Attributes = c.Attributes, Description = c.Description
                };
                return(TypePredefinition(Request.DefinitionName(), MetaType, t.GenericParameters()).Concat(TypePredefinition(Reply.DefinitionName(), MetaType, t.GenericParameters())));
            }
            else if (t.OnServerCommand)
            {
                var c        = t.ServerCommand;
                var EventRef = GetSuffixedTypeRef(c.Name, c.Version, "Event");
                var Event    = new RecordDef {
                    Name = EventRef.Name, Version = EventRef.Version, GenericParameters = new List <VariableDef> {
                    }, Fields = c.OutParameters, Attributes = c.Attributes, Description = c.Description
                };
                return(TypePredefinition(Event.DefinitionName(), MetaType, t.GenericParameters()));
            }
            else
            {
                return(TypePredefinition(Name, MetaType, t.GenericParameters()));
            }
        }
Example #6
0
    private void EmitRecord(RecordDef record)
    {
        WriteTypeAttributesForCoreLib();
        OpenScope($"public partial struct {record.Name}");

        WriteLine("internal MetadataReader _reader;");
        WriteLine($"internal {record.Name}Handle _handle;");

        OpenScope($"public {record.Name}Handle Handle");
        OpenScope("get");
        WriteLine("return _handle;");
        CloseScope();
        CloseScope("Handle");

        foreach (var member in record.Members)
        {
            if ((member.Flags & MemberDefFlags.NotPersisted) != 0)
            {
                continue;
            }

            string memberType = member.GetMemberType();
            string fieldType  = member.GetMemberType(MemberTypeKind.ReaderField);

            string fieldName = member.GetMemberFieldName();

            string description = member.GetMemberDescription();
            if (description != null)
            {
                WriteDocComment(description);
            }
            OpenScope($"public {memberType} {member.Name}");
            OpenScope("get");
            if (fieldType != memberType)
            {
                WriteLine($"return ({memberType}){fieldName};");
            }
            else
            {
                WriteLine($"return {fieldName};");
            }
            CloseScope();
            CloseScope(member.Name);

            WriteLineIfNeeded();
            WriteLine($"internal {fieldType} {fieldName};");
        }

        CloseScope(record.Name);
    }
        protected override string GetTextFor(Pawn pawn)
        {
            RecordDef recordDef = def.Ext().record;
            string    recordValue;

            if (recordDef.type == RecordType.Time)
            {
                recordValue = pawn.records.GetAsInt(recordDef).ToStringTicksToPeriod();
            }
            else
            {
                recordValue = pawn.records.GetValue(recordDef).ToString("0.##");
            }

            return(recordValue);
        }
Example #8
0
    private void EmitEnum(RecordDef record)
    {
        if ((record.Flags & RecordDefFlags.Flags) != 0)
            WriteScopeAttribute("[Flags]");
        OpenScope($"public enum {record.Name} : {record.BaseTypeName}");

        foreach (var member in record.Members)
        {
            if (member.Comment != null)
            {
                WriteLineIfNeeded();
                WriteDocComment(member.Comment);
            }
            WriteLine($"{member.Name} = {member.Value},");
        }

        CloseScope(record.Name);
    }
Example #9
0
 /// <summary>
 /// Increment Event where Records are incremented by 1
 /// </summary>
 /// <param name="def"></param>
 /// <param name="__instance"></param>
 public static void RecordEvent(RecordDef def, Pawn_RecordsTracker __instance)
 {
     foreach (var card in AchievementPointManager.GetCards <RecordEventTracker>())
     {
         try
         {
             if ((card.tracker as RecordEventTracker).Trigger(def, __instance.pawn))
             {
                 card.UnlockCard();
             }
         }
         catch (Exception ex)
         {
             Log.Error($"Unable to trigger event for card validation. To avoid further errors {card.def.LabelCap} has been automatically unlocked.\n\nException={ex.Message}");
             card.UnlockCard();
         }
     }
 }
 /// <summary>
 /// HelperMethod for Time based record event
 /// </summary>
 /// <param name="def"></param>
 /// <param name="pawn"></param>
 /// <param name="interval"></param>
 public static void RecordTimeEvent(RecordDef def, Pawn pawn, int interval)
 {
     foreach (var card in AchievementPointManager.GetCards <RecordTimeTracker>())
     {
         try
         {
             var tracker = card.tracker as RecordTimeTracker;
             if (tracker.def == def && tracker.Trigger(def, pawn, (float)interval))
             {
                 card.UnlockCard();
             }
         }
         catch (Exception ex)
         {
             Log.Error($"Unable to trigger event for card validation. To avoid further errors {card.def.LabelCap} has been automatically unlocked.\n\nException={ex.Message}");
             card.UnlockCard();
         }
     }
 }
Example #11
0
        public static void Postfix(RecordDef def, float value, ref Pawn_RecordsTracker __instance)
        {
            if (def != RecordDefOf.NutritionEaten)
            {
                return;
            }

            if (!PicnicArea.VerifyPicnicSpot(__instance.pawn))
            {
                return;
            }

            if (!PicnicArea.VerifyPicnicConditions(__instance.pawn.Map))
            {
                return;
            }

            __instance.pawn.needs.mood?.thoughts.memories.TryGainMemory(PicnicAreaThoughtDefOf.AteAtPicnicArea);
        }
Example #12
0
        public void AddTypeDef(Type type)
        {
            string name = type.Name;

            if (TypeDefs.ContainsKey(name))
            {
                return;
            }

            ElmAstNode def;

            if (type.IsEnum)
            {
                var t = new AdtDef(name);
                t.Alternatives.AddRange(Array.ConvertAll(type.GetEnumNames(), altName => AdtAlternativeName(type, altName)));
                def = t;
            }
            else
            {
                //Otherwise, a class
                var t = new RecordDef(name);
                def = t;
                foreach (var prop in type.GetProperties(PROP_FLAGS))
                {
                    var jsonAttrs = prop.GetCustomAttributes(typeof(JsonPropertyAttribute));
                    if (jsonAttrs.Any())
                    {
                        t.Fields.Add(ElmRecordFieldName(prop), ElmType(prop.PropertyType));

                        //If the property type is an enum, generate an ADT for it
                        if (prop.PropertyType.IsEnum)
                        {
                            AddTypeDef(prop.PropertyType);
                            AddDecodeFun(prop.PropertyType);
                            AddEncodeFun(prop.PropertyType);
                            AddToStringFun(prop.PropertyType);
                        }
                    }
                }
            }

            TypeDefs.Add(name, def);
        }
Example #13
0
    private void EmitEnum(RecordDef record)
    {
        if ((record.Flags & RecordDefFlags.Flags) != 0)
        {
            WriteScopeAttribute("[Flags]");
        }
        OpenScope($"public enum {record.Name} : {record.BaseTypeName}");

        foreach (var member in record.Members)
        {
            if (member.Comment != null)
            {
                WriteLineIfNeeded();
                WriteDocComment(member.Comment);
            }
            WriteLine($"{member.Name} = {member.Value},");
        }

        CloseScope(record.Name);
    }
Example #14
0
    private void EmitRecord(RecordDef record)
    {
        OpenScope($"public partial struct {record.Name}");

        WriteLine("internal MetadataReader _reader;");
        WriteLine($"internal {record.Name}Handle _handle;");

        OpenScope($"public {record.Name}Handle Handle");
        OpenScope("get");
        WriteLine("return _handle;");
        CloseScope();
        CloseScope("Handle");

        foreach (var member in record.Members)
        {
            if ((member.Flags & MemberDefFlags.NotPersisted) != 0)
                continue;

            string memberType = member.GetMemberType();
            string fieldType = member.GetMemberType(MemberTypeKind.ReaderField);

            string fieldName = member.GetMemberFieldName();

            string description = member.GetMemberDescription();
            if (description != null)
                WriteDocComment(description);
            OpenScope($"public {memberType} {member.Name}");
            OpenScope("get");
            if (fieldType != memberType)
                WriteLine($"return ({memberType}){fieldName};");
            else
                WriteLine($"return {fieldName};");
            CloseScope();
            CloseScope(member.Name);

            WriteLineIfNeeded();
            WriteLine($"internal {fieldType} {fieldName};");
        }

        CloseScope(record.Name);
    }
Example #15
0
        public void ExposeData()
        {
            Scribe_Values.Look <ObjectType>(ref oType, "oType");
            Scribe_Values.Look <float>(ref minWidthDesired, "minWidthDesired");
            Scribe_Values.Look <string>(ref this.label, "label");

            switch (oType)
            {
            case ObjectType.Stat:
                StatDef tempObjectS = (StatDef)displayObject;
                Scribe_Defs.Look(ref tempObjectS, "displayObject");
                displayObject = tempObjectS;
                break;

            case ObjectType.Skill:
                SkillDef tempObjectK = (SkillDef)displayObject;
                Scribe_Defs.Look(ref tempObjectK, "displayObject");
                displayObject = tempObjectK;
                break;

            case ObjectType.Need:
                NeedDef tempObjectN = (NeedDef)displayObject;
                Scribe_Defs.Look(ref tempObjectN, "displayObject");
                displayObject = tempObjectN;
                break;

            case ObjectType.Capacity:
                PawnCapacityDef tempObjectCap = (PawnCapacityDef)displayObject;
                Scribe_Defs.Look(ref tempObjectCap, "displayObject");
                displayObject = tempObjectCap;
                break;

            case ObjectType.Record:
                RecordDef tempObjectRecord = (RecordDef)displayObject;
                Scribe_Defs.Look(ref tempObjectRecord, "displayObject");
                displayObject = tempObjectRecord;
                break;
            }
        }
Example #16
0
        public IEnumerable <String> ClientCommand(ClientCommandDef c)
        {
            var RequestRef = GetSuffixedTypeRef(c.Name, c.Version, "Request");
            var ReplyRef   = GetSuffixedTypeRef(c.Name, c.Version, "Reply");
            var Request    = new RecordDef {
                Name = RequestRef.Name, Version = RequestRef.Version, GenericParameters = new List <VariableDef> {
                }, Fields = c.OutParameters, Attributes = c.Attributes, Description = c.Description
            };
            var Reply = new TaggedUnionDef {
                Name = ReplyRef.Name, Version = ReplyRef.Version, GenericParameters = new List <VariableDef> {
                }, Alternatives = c.InParameters, Attributes = c.Attributes, Description = c.Description
            };

            foreach (var _Line in Combine(Begin(), Record(Request)))
            {
                yield return(_Line);
            }
            foreach (var _Line in Combine(Begin(), TaggedUnion(Reply)))
            {
                yield return(_Line);
            }
        }
Example #17
0
        public void Draw(Rect rect, ThingWithComps ownerPawn)
        {
            Text.Font = GameFont.Small;
            string value = "-";

            switch (oType)
            {
            case ObjectType.Stat:
                Text.Anchor = TextAnchor.MiddleCenter;
                StatDef stat = (StatDef)displayObject;
                stat.neverDisabled = true;
                string statValue = (stat.ValueToString(ownerPawn.GetStatValue((StatDef)displayObject, true)));
                Widgets.Label(rect, statValue);
                if (Mouse.IsOver(rect))
                {
                    GUI.DrawTexture(rect, TexUI.HighlightTex);
                }

                StringBuilder stringBuilder = new StringBuilder();
                stringBuilder.AppendLine(stat.LabelCap);
                stringBuilder.AppendLine();
                stringBuilder.AppendLine(stat.description);
                TooltipHandler.TipRegion(rect, new TipSignal(stringBuilder.ToString(), rect.GetHashCode()));
                break;

            case ObjectType.Skill:
                if ((ownerPawn is Pawn) && (ownerPawn as Pawn).RaceProps.Humanlike)
                {
                    DrawSkill(rect, ownerPawn as Pawn);
                }
                break;

            case ObjectType.Need:
                if (ownerPawn is Pawn)
                {
                    DrawNeed(rect, ownerPawn as Pawn);
                }
                break;

            case ObjectType.Capacity:
                Text.Anchor = TextAnchor.MiddleCenter;
                if (ownerPawn is Pawn p)
                {
                    PawnCapacityDef cap = (PawnCapacityDef)displayObject;

                    Pair <string, Color> effLabel = HealthCardUtility.GetEfficiencyLabel(p, cap);
                    string pawnCapTip             = HealthCardUtility.GetPawnCapacityTip(p, cap);

                    // I stole this one line from Fluffy's Medical Tab. THANKS FLUFFY!
                    string capValue = (p.health.capacities.GetLevel(cap) * 100f).ToString("F0") + "%";
                    GUI.color = effLabel.Second;
                    Widgets.Label(rect, capValue);
                    GUI.color = Color.white;

                    if (Mouse.IsOver(rect))
                    {
                        GUI.DrawTexture(rect, TexUI.HighlightTex);
                    }

                    StringBuilder stringBuilder2 = new StringBuilder();
                    stringBuilder2.AppendLine(cap.LabelCap);
                    stringBuilder2.AppendLine();
                    stringBuilder2.AppendLine(cap.description);
                    TooltipHandler.TipRegion(rect, new TipSignal(stringBuilder2.ToString(), rect.GetHashCode()));
                }
                break;

            case ObjectType.Record:
                Text.Anchor = TextAnchor.MiddleCenter;
                if (ownerPawn is Pawn pawn)
                {
                    RecordDef recordDef = (RecordDef)displayObject;
                    string    recordValue;

                    if (recordDef.type == RecordType.Time)
                    {
                        recordValue = pawn.records.GetAsInt(recordDef).ToStringTicksToPeriod();
                    }
                    else
                    {
                        recordValue = pawn.records.GetValue(recordDef).ToString("0.##");
                    }

                    Widgets.Label(rect, recordValue);

                    if (Mouse.IsOver(rect))
                    {
                        GUI.DrawTexture(rect, TexUI.HighlightTex);
                    }

                    StringBuilder recordDefStringBuilder = new StringBuilder();
                    recordDefStringBuilder.AppendLine(recordDef.LabelCap);
                    recordDefStringBuilder.AppendLine();
                    recordDefStringBuilder.AppendLine(recordDef.description);
                    TooltipHandler.TipRegion(rect, new TipSignal(recordDefStringBuilder.ToString(), rect.GetHashCode()));
                }
                break;

            case ObjectType.MentalState:
                Text.Font   = GameFont.Tiny;
                Text.Anchor = TextAnchor.MiddleCenter;
                if (ownerPawn is Pawn && (ownerPawn as Pawn).MentalState != null)
                {
                    string ms = ((ownerPawn as Pawn).MentalState.InspectLine);
                    Widgets.Label(rect, ms);
                    if (Mouse.IsOver(rect))
                    {
                        GUI.DrawTexture(rect, TexUI.HighlightTex);
                    }
                }
                Text.Font = GameFont.Medium;
                break;

            case ObjectType.Age:
                Text.Anchor = TextAnchor.MiddleCenter;
                string ageValue = ((ownerPawn as Pawn).ageTracker.AgeBiologicalYears.ToString());
                Widgets.Label(rect, ageValue);
                if (Mouse.IsOver(rect))
                {
                    GUI.DrawTexture(rect, TexUI.HighlightTex);
                }
                break;

            case ObjectType.Race:
                Text.Anchor = TextAnchor.MiddleCenter;
                string race = ((ownerPawn as Pawn).kindDef.race.LabelCap) ?? string.Empty;
                Widgets.Label(rect, race);
                if (Mouse.IsOver(rect))
                {
                    GUI.DrawTexture(rect, TexUI.HighlightTex);
                }
                break;

            case ObjectType.Gear:
                DrawGear(rect, ownerPawn);
                break;

            case ObjectType.ControlPrisonerGetsFood:
                if (ownerPawn is Pawn)
                {
                    if (Mouse.IsOver(rect))
                    {
                        GUI.DrawTexture(rect, TexUI.HighlightTex);
                    }
                    bool getsFood = (ownerPawn as Pawn).guest.GetsFood;
                    Widgets.CheckboxLabeled(new Rect(rect.x + 8f, rect.y + 3f, 27f, 27f), "", ref getsFood, false);
                    (ownerPawn as Pawn).guest.GetsFood = getsFood;
                }
                break;

            case ObjectType.ControlPrisonerInteraction:
                if (ownerPawn is Pawn)
                {
                    if (Mouse.IsOver(rect))
                    {
                        GUI.DrawTexture(rect, TexUI.HighlightTex);
                    }
                    float x = 8f;

                    GUI.BeginGroup(rect);
                    foreach (PrisonerInteractionModeDef current in from prisonerinteractionmode in DefDatabase <PrisonerInteractionModeDef> .AllDefs
                             orderby prisonerinteractionmode.listOrder
                             select prisonerinteractionmode)
                    {
                        if (Widgets.RadioButton(new Vector2(x, 3f), (ownerPawn as Pawn).guest.interactionMode == current))
                        {
                            (ownerPawn as Pawn).guest.interactionMode = current;
                        }
                        TooltipHandler.TipRegion(new Rect(x, 0f, 30f, 30f), new TipSignal(current.LabelCap));
                        x += 30f;
                    }
                    GUI.EndGroup();
                }
                break;

            case ObjectType.PrisonerRecruitmentDifficulty:
                Text.Anchor = TextAnchor.MiddleCenter;
                if (ownerPawn is Pawn)
                {
                    value = (ownerPawn as Pawn).RecruitDifficulty(Faction.OfPlayer, false).ToStringPercent();
                }
                Widgets.Label(rect, value);
                break;

            case ObjectType.ControlMedicalCare:
                if (ownerPawn is Pawn)
                {
                    MedicalCareSetter(rect, ref (ownerPawn as Pawn).playerSettings.medCare);
                }
                break;

            case ObjectType.AnimalMilkFullness:
                Text.Anchor = TextAnchor.MiddleCenter;
                if (ownerPawn is Pawn && ((Pawn)ownerPawn).ageTracker.CurLifeStage.milkable)
                {
                    var comp = ((Pawn)ownerPawn).AllComps.Where <ThingComp>(x => x is CompMilkable).FirstOrDefault();
                    if (comp != null)
                    {
                        value = ((CompMilkable)comp).Fullness.ToStringPercent();
                    }
                }

                Widgets.Label(rect, value);
                break;

            case ObjectType.AnimalWoolGrowth:
                Text.Anchor = TextAnchor.MiddleCenter;
                if (ownerPawn is Pawn && ((Pawn)ownerPawn).ageTracker.CurLifeStage.shearable)
                {
                    var comp = ((Pawn)ownerPawn).AllComps.Where <ThingComp>(x => x is CompShearable).FirstOrDefault();
                    if (comp != null)
                    {
                        value = ((CompShearable)comp).Fullness.ToStringPercent();
                    }
                }

                Widgets.Label(rect, value);
                break;

            case ObjectType.AnimalEggProgress:
                Text.Anchor = TextAnchor.MiddleCenter;
                if (ownerPawn is Pawn && ((Pawn)ownerPawn).ageTracker.CurLifeStage.reproductive)
                {
                    var comp = ((Pawn)ownerPawn).AllComps.Where <ThingComp>(x => x is CompEggLayer).FirstOrDefault();
                    if (comp != null)
                    {
                        value = ((CompEggLayer)comp).CompInspectStringExtra();
                    }
                }

                Widgets.Label(rect, value);
                break;

            case ObjectType.CurrentJob:
                if (ownerPawn is Pawn && ((Pawn)ownerPawn).jobs?.curDriver != null)
                {
                    string text = ((Pawn)ownerPawn).jobs.curDriver.GetReport();
                    Text.Anchor = TextAnchor.MiddleLeft;
                    Rect tRect = new Rect(rect.xMin + 2, rect.yMin + 3, rect.width - 2, rect.height);
                    GenText.SetTextSizeToFit(text, tRect);

                    if (Text.Font == GameFont.Tiny)
                    {
                        Widgets.Label(tRect, text);
                    }
                    else
                    {
                        Rect sRect = new Rect(rect.xMin + 2, rect.yMin, rect.width - 2, rect.height);
                        Widgets.Label(sRect, text);
                    }

                    if (Mouse.IsOver(rect))
                    {
                        GUI.DrawTexture(rect, TexUI.HighlightTex);
                    }
                }

                break;

            case ObjectType.QueuedJob:
                if (ownerPawn is Pawn && ((Pawn)ownerPawn).jobs?.jobQueue.Count > 0)
                {
                    string text = ((Pawn)ownerPawn).jobs.jobQueue[0].job.GetReport((Pawn)ownerPawn);
                    Text.Anchor = TextAnchor.MiddleLeft;
                    Rect tRect = new Rect(rect.xMin + 2, rect.yMin + 3, rect.width - 2, rect.height);
                    GenText.SetTextSizeToFit(text, tRect);

                    if (Text.Font == GameFont.Tiny)
                    {
                        Widgets.Label(tRect, text);
                    }
                    else
                    {
                        Rect sRect = new Rect(rect.xMin + 2, rect.yMin, rect.width - 2, rect.height);
                        Widgets.Label(sRect, text);
                    }

                    if (Mouse.IsOver(rect))
                    {
                        GUI.DrawTexture(rect, TexUI.HighlightTex);
                    }
                }
                break;
            }
        }
Example #18
0
        public Dictionary <String, IEnumerable <String> > GetPackageFiles(Schema Schema, String NamespaceName)
        {
            var NamespaceToClasses = new Dictionary <String, List <KeyValuePair <String, List <String> > > >();

            void AddClass(String ClassNamespaceName, String ClassName, IEnumerable <String> ClassContent)
            {
                if (!NamespaceToClasses.ContainsKey(ClassNamespaceName))
                {
                    NamespaceToClasses.Add(ClassNamespaceName, new List <KeyValuePair <String, List <String> > >());
                }
                NamespaceToClasses[ClassNamespaceName].Add(new KeyValuePair <String, List <String> >(ClassName, ClassContent.ToList()));
            }

            AddClass("niveum.lang", "Record", Attribute_Record());
            AddClass("niveum.lang", "Alias", Attribute_Alias());
            AddClass("niveum.lang", "TaggedUnion", Attribute_TaggedUnion());
            AddClass("niveum.lang", "Tag", Attribute_Tag());
            AddClass("niveum.lang", "Tuple", Attribute_Tuple());
            AddClass("niveum.lang", "Unit", Primitive_Unit());

            foreach (var c in Schema.Types)
            {
                if (c.OnPrimitive)
                {
                    continue;
                }
                else if (c.OnAlias)
                {
                    AddClass(c.NamespaceName(), c.DefinitionName(), Alias(c.Alias));
                }
                else if (c.OnRecord)
                {
                    AddClass(c.NamespaceName(), c.DefinitionName(), Record(c.Record));
                }
                else if (c.OnTaggedUnion)
                {
                    var tu      = c.TaggedUnion;
                    var TagName = GetSuffixedTypeName(tu.Name, tu.Version, "Tag", tu.NamespaceName());
                    AddClass(c.NamespaceName(), TagName, TaggedUnionTag(c.TaggedUnion));
                    AddClass(c.NamespaceName(), c.DefinitionName(), TaggedUnion(c.TaggedUnion));
                }
                else if (c.OnEnum)
                {
                    AddClass(c.NamespaceName(), c.DefinitionName(), Enum(c.Enum));
                }
                else if (c.OnClientCommand)
                {
                    var tc         = c.ClientCommand;
                    var RequestRef = GetSuffixedTypeRef(tc.Name, tc.Version, "Request");
                    var Request    = new RecordDef {
                        Name = RequestRef.Name, Version = RequestRef.Version, GenericParameters = new List <VariableDef> {
                        }, Fields = tc.OutParameters, Attributes = tc.Attributes, Description = tc.Description
                    };
                    var ReplyRef = GetSuffixedTypeRef(tc.Name, tc.Version, "Reply");
                    var Reply    = new TaggedUnionDef {
                        Name = ReplyRef.Name, Version = ReplyRef.Version, GenericParameters = new List <VariableDef> {
                        }, Alternatives = tc.InParameters, Attributes = tc.Attributes, Description = tc.Description
                    };
                    var ReplyTagName = GetSuffixedTypeName(Reply.Name, Reply.Version, "Tag", tc.NamespaceName());
                    AddClass(c.NamespaceName(), Request.DefinitionName(), Record(Request));
                    AddClass(c.NamespaceName(), ReplyTagName, TaggedUnionTag(Reply));
                    AddClass(c.NamespaceName(), Reply.DefinitionName(), TaggedUnion(Reply));
                }
                else if (c.OnServerCommand)
                {
                    var tc       = c.ServerCommand;
                    var EventRef = GetSuffixedTypeRef(tc.Name, tc.Version, "Event");
                    var Event    = new RecordDef {
                        Name = EventRef.Name, Version = EventRef.Version, GenericParameters = new List <VariableDef> {
                        }, Fields = tc.OutParameters, Attributes = tc.Attributes, Description = tc.Description
                    };
                    AddClass(c.NamespaceName(), Event.DefinitionName(), Record(Event));
                }
                else
                {
                    throw new InvalidOperationException();
                }
            }

            var scg              = Schema.GetSchemaClosureGenerator();
            var sc               = scg.GetClosure(Schema.TypeRefs.Concat(Schema.Types), new List <TypeSpec> {
            });
            var Tuples           = sc.TypeSpecs.Where(t => t.OnTuple).ToList();
            var GenericTypeSpecs = sc.TypeSpecs.Where(t => t.OnGenericTypeSpec).ToList();

            foreach (var t in Tuples)
            {
                AddClass(NamespaceName, t.SimpleName(NamespaceName), Tuple(t, NamespaceName));
            }

            var GenericOptionalTypes = Schema.TypeRefs.Concat(Schema.Types).Where(t => t.NameMatches("Optional")).ToList();

            if (GenericOptionalTypes.Count > 0)
            {
                var GenericOptionalType = new TaggedUnionDef
                {
                    Name = new List <String> {
                        "Optional"
                    },
                    Version           = "",
                    GenericParameters = new List <VariableDef> {
                        new VariableDef {
                            Name = "T", Type = TypeSpec.CreateTypeRef(new TypeRef {
                                Name = new List <String> {
                                    "Type"
                                }, Version = ""
                            }), Attributes = new List <KeyValuePair <String, List <String> > > {
                            }, Description = ""
                        }
                    },
                    Alternatives = new List <VariableDef>
                    {
                        new VariableDef {
                            Name = "None", Type = TypeSpec.CreateTypeRef(new TypeRef {
                                Name = new List <String> {
                                    "Unit"
                                }, Version = ""
                            }), Attributes = new List <KeyValuePair <String, List <String> > > {
                            }, Description = ""
                        },
                        new VariableDef {
                            Name = "Some", Type = TypeSpec.CreateGenericParameterRef("T"), Attributes = new List <KeyValuePair <String, List <String> > > {
                            }, Description = ""
                        }
                    },
                    Attributes  = new List <KeyValuePair <String, List <String> > > {
                    },
                    Description = ""
                };
                {
                    var TagName = GetSuffixedTypeName(GenericOptionalType.Name, GenericOptionalType.Version, "Tag", GenericOptionalType.NamespaceName());
                    AddClass(NamespaceName, TagName, TaggedUnionTag(GenericOptionalType));
                }
                foreach (var gts in GenericTypeSpecs)
                {
                    if (gts.GenericTypeSpec.TypeSpec.OnTypeRef && gts.GenericTypeSpec.TypeSpec.TypeRef.NameMatches("Optional") && gts.GenericTypeSpec.ParameterValues.Count == 1)
                    {
                        var ElementType  = gts.GenericTypeSpec.ParameterValues.Single();
                        var Name         = "Opt" + ElementType.SimpleName(NamespaceName);
                        var Alternatives = GenericOptionalType.Alternatives.Select(a => new VariableDef {
                            Name = a.Name, Type = a.Type.OnGenericParameterRef ? ElementType : a.Type, Attributes = a.Attributes, Description = a.Description
                        }).ToList();
                        var tu = new TaggedUnionDef {
                            Name = new List <String> {
                                Name
                            }, Version = "", GenericParameters = new List <VariableDef> {
                            }, Alternatives = Alternatives, Attributes = GenericOptionalType.Attributes, Description = GenericOptionalType.Description
                        };
                        AddClass(NamespaceName, Name, TaggedUnion(tu, "OptionalTag"));
                    }
                }
            }

            return(NamespaceToClasses.SelectMany(p => p.Value.Select(v => new KeyValuePair <String, IEnumerable <String> >(String.Join("/", p.Key.Split('.').Where(NamespacePart => NamespacePart != "").Select(NamespacePart => LowercaseCamelize(NamespacePart)).Concat(new String[] { v.Key })), WrapModule(p.Key, Schema.Imports, v.Value)))).ToDictionary(p => p.Key, p => p.Value));
        }
Example #19
0
    private void EmitHandle(RecordDef record)
    {
        string handleName = $"{record.Name}Handle";

        OpenScope($"public partial struct {handleName}");

        OpenScope("public override bool Equals(object obj)");
        WriteLine($"if (obj is {handleName})");
        WriteLine($"    return _value == (({handleName})obj)._value;");
        WriteLine("else if (obj is Handle)");
        WriteLine("    return _value == ((Handle)obj)._value;");
        WriteLine("else");
        WriteLine("    return false;");
        CloseScope("Equals");

        OpenScope($"public bool Equals({handleName} handle)");
        WriteLine("return _value == handle._value;");
        CloseScope("Equals");

        OpenScope("public bool Equals(Handle handle)");
        WriteLine("return _value == handle._value;");
        CloseScope("Equals");

        OpenScope("public override int GetHashCode()");
        WriteLine("return (int)_value;");
        CloseScope("GetHashCode");

        WriteLineIfNeeded();
        WriteLine("internal int _value;");

        OpenScope($"internal {handleName}(Handle handle) : this(handle._value)");
        CloseScope();

        OpenScope($"internal {handleName}(int value)");
        WriteLine("HandleType hType = (HandleType)(value >> 24);");
        WriteLine($"if (!(hType == 0 || hType == HandleType.{record.Name} || hType == HandleType.Null))");
        WriteLine("    throw new ArgumentException();");
        WriteLine($"_value = (value & 0x00FFFFFF) | (((int)HandleType.{record.Name}) << 24);");
        WriteLine("_Validate();");
        CloseScope();

        OpenScope($"public static implicit operator  Handle({handleName} handle)");
        WriteLine("return new Handle(handle._value);");
        CloseScope("Handle");

        OpenScope("internal int Offset");
        OpenScope("get");
        WriteLine("return (this._value & 0x00FFFFFF);");
        CloseScope();
        CloseScope("Offset");

        OpenScope($"public {record.Name} Get{record.Name}(MetadataReader reader)");
        WriteLine($"return reader.Get{record.Name}(this);");
        CloseScope($"Get{record.Name}");

        OpenScope("public bool IsNull(MetadataReader reader)");
        WriteLine("return reader.IsNull(this);");
        CloseScope("IsNull");

        OpenScope("public Handle ToHandle(MetadataReader reader)");
        WriteLine("return reader.ToHandle(this);");
        CloseScope("ToHandle");

        WriteScopeAttribute("[System.Diagnostics.Conditional(\"DEBUG\")]");
        OpenScope("internal void _Validate()");
        WriteLine($"if ((HandleType)((_value & 0xFF000000) >> 24) != HandleType.{record.Name})");
        WriteLine("    throw new ArgumentException();");
        CloseScope("_Validate");

        OpenScope("public override String ToString()");
        WriteLine("return String.Format(\"{0:X8}\", _value);");
        CloseScope("ToString");

        CloseScope(handleName);
    }
Example #20
0
 /// <summary>
 /// Additional Patch to AddTo to catch outside calls to increment the non Time-based RecordDef
 /// </summary>
 /// <param name="def"></param>
 /// <param name="__instance"></param>
 public static void RecordAddToEvent(RecordDef def, Pawn_RecordsTracker __instance)
 {
     RecordEvent(def, __instance);
 }
Example #21
0
    private void EmitRecord(RecordDef record)
    {
        bool isConstantStringValue = record.Name == "ConstantStringValue";

        OpenScope($"public partial class {record.Name} : MetadataRecord");

        if ((record.Flags & RecordDefFlags.ReentrantEquals) != 0)
        {
            OpenScope($"public {record.Name}()");
            WriteLine("_equalsReentrancyGuard = new ThreadLocal<ReentrancyGuardStack>(() => new ReentrancyGuardStack());");
            CloseScope();
        }

        OpenScope("public override HandleType HandleType");
        OpenScope("get");
        WriteLine($"return HandleType.{record.Name};");
        CloseScope();
        CloseScope("HandleType");

        OpenScope("internal override void Visit(IRecordVisitor visitor)");
        foreach (var member in record.Members)
        {
            if ((member.Flags & MemberDefFlags.RecordRef) == 0)
                continue;

            if ((member.Flags & (MemberDefFlags.Map | MemberDefFlags.Sequence)) != 0)
            {
                WriteLine($"{member.Name} = visitor.Visit(this, {member.Name});");
            }
            else
            {
                WriteLine($"{member.Name} = visitor.Visit(this, {member.Name});");
            }
        }
        CloseScope("Visit");

        OpenScope("public override sealed bool Equals(Object obj)");
        WriteLine("if (Object.ReferenceEquals(this, obj)) return true;");
        WriteLine($"var other = obj as {record.Name};");
        WriteLine("if (other == null) return false;");
        if ((record.Flags & RecordDefFlags.ReentrantEquals) != 0)
        {
            WriteLine("if (_equalsReentrancyGuard.Value.Contains(other))");
            WriteLine("    return true;");
            WriteLine("_equalsReentrancyGuard.Value.Push(other);");
            WriteLine("try");
            WriteLine("{");
        }
        foreach (var member in record.Members)
        {
            if ((member.Flags & MemberDefFlags.NotPersisted) != 0)
                continue;

            if ((record.Flags & RecordDefFlags.CustomCompare) != 0 && (member.Flags & MemberDefFlags.Compare) == 0)
                continue;

            if ((member.Flags & MemberDefFlags.Sequence) != 0)
            {
                WriteLine($"if (!{member.Name}.SequenceEqual(other.{member.Name})) return false;");
            }
            else
            if ((member.Flags & (MemberDefFlags.List | MemberDefFlags.Map)) != 0)
            {
                WriteLine($"if (!Object.Equals({member.Name}, other.{member.Name})) return false;");
            }
            else
            if ((member.Flags & MemberDefFlags.RecordRef) != 0)
            {
                WriteLine($"if (!Object.Equals({member.Name}, other.{member.Name})) return false;");
            }
            else
            {
                WriteLine($"if ({member.Name} != other.{member.Name}) return false;");
            }
        }
        if ((record.Flags & RecordDefFlags.ReentrantEquals) != 0)
        {
            WriteLine("}");

            WriteLine("finally");
            WriteLine("{");
            WriteLine("    var popped = _equalsReentrancyGuard.Value.Pop();");
            WriteLine("    Debug.Assert(Object.ReferenceEquals(other, popped));");
            WriteLine("}");
        }
        WriteLine("return true;");
        CloseScope("Equals");
        if ((record.Flags & RecordDefFlags.ReentrantEquals) != 0)
            WriteLine("private ThreadLocal<ReentrancyGuardStack> _equalsReentrancyGuard;");

        OpenScope("public override sealed int GetHashCode()");
        WriteLine("if (_hash != 0)");
        WriteLine("    return _hash;");
        WriteLine("EnterGetHashCode();");

        // Compute hash seed using stable hashcode
        byte[] nameBytes = System.Text.Encoding.UTF8.GetBytes(record.Name);
        byte[] hashBytes = new System.Security.Cryptography.SHA1Managed().ComputeHash(nameBytes);
        int hashSeed = System.BitConverter.ToInt32(hashBytes, 0);
        WriteLine($"int hash = {hashSeed};");

        foreach (var member in record.Members)
        {
            if ((member.Flags & MemberDefFlags.NotPersisted) != 0)
                continue;

            if ((record.Flags & RecordDefFlags.CustomCompare) != 0 && (member.Flags & MemberDefFlags.Compare) == 0)
                continue;

            if (member.TypeName as string == "ConstantStringValue")
            {
                WriteLine($"hash = ((hash << 13) - (hash >> 19)) ^ ({member.Name} == null ? 0 : {member.Name}.GetHashCode());");
            }
            else
            if ((member.Flags & MemberDefFlags.Array) != 0)
            {
                WriteLine($"if ({member.Name} != null)");
                WriteLine("{");
                WriteLine($"    for (int i = 0; i < {member.Name}.Length; i++)");
                WriteLine("    {");
                WriteLine($"        hash = ((hash << 13) - (hash >> 19)) ^ {member.Name}[i].GetHashCode();");
                WriteLine("    }");
                WriteLine("}");
            }
            else
            if ((member.Flags & (MemberDefFlags.List | MemberDefFlags.Map)) != 0)
            {
                if ((member.Flags & MemberDefFlags.EnumerateForHashCode) == 0)
                    continue;

                WriteLine($"if ({member.Name} != null)");
                WriteLine("{");
                WriteLine($"for (int i = 0; i < {member.Name}.Count; i++)");
                WriteLine("    {");
                WriteLine($"        hash = ((hash << 13) - (hash >> 19)) ^ ({member.Name}[i] == null ? 0 : {member.Name}[i].GetHashCode());");
                WriteLine("    }");
                WriteLine("}");
            }
            else
            if ((member.Flags & MemberDefFlags.RecordRef) != 0 || isConstantStringValue)
            {
                WriteLine($"hash = ((hash << 13) - (hash >> 19)) ^ ({member.Name} == null ? 0 : {member.Name}.GetHashCode());");
            }
            else
            {
                WriteLine($"hash = ((hash << 13) - (hash >> 19)) ^ {member.Name}.GetHashCode();");
            }
        }
        WriteLine("LeaveGetHashCode();");
        WriteLine("_hash = hash;");
        WriteLine("return _hash;");
        CloseScope("GetHashCode");

        OpenScope("internal override void Save(NativeWriter writer)");
        if (isConstantStringValue)
        {
            WriteLine("if (Value == null)");
            WriteLine("    return;");
            WriteLine();
        }
        foreach (var member in record.Members)
        {
            if ((member.Flags & MemberDefFlags.NotPersisted) != 0)
                continue;

            var typeSet = member.TypeName as string[];
            if (typeSet != null)
            {
                if ((member.Flags & (MemberDefFlags.List | MemberDefFlags.Map)) != 0)
                {
                    WriteLine($"Debug.Assert({member.Name}.TrueForAll(handle => handle == null ||");
                    for (int i = 0; i < typeSet.Length; i++)
                        WriteLine($"    handle.HandleType == HandleType.{typeSet[i]}"
                            + ((i == typeSet.Length - 1) ? "));" : " ||"));
                }
                else
                {
                    WriteLine($"Debug.Assert({member.Name} == null ||");
                    for (int i = 0; i < typeSet.Length; i++)
                        WriteLine($"    {member.Name}.HandleType == HandleType.{typeSet[i]}"
                            + ((i == typeSet.Length - 1) ? ");" : " ||"));
                }
            }
            WriteLine($"writer.Write({member.Name});");
        }
        CloseScope("Save");

        OpenScope($"internal static {record.Name}Handle AsHandle({record.Name} record)");
        WriteLine("if (record == null)");
        WriteLine("{");
        WriteLine($"    return new {record.Name}Handle(0);");
        WriteLine("}");
        WriteLine("else");
        WriteLine("{");
        WriteLine("    return record.Handle;");
        WriteLine("}");
        CloseScope("AsHandle");

        OpenScope($"internal new {record.Name}Handle Handle");
        OpenScope("get");
        if (isConstantStringValue)
        {
            WriteLine("if (Value == null)");
            WriteLine("    return new ConstantStringValueHandle(0);");
            WriteLine("else");
            WriteLine("    return new ConstantStringValueHandle(HandleOffset);");
        }
        else
        {
            WriteLine($"return new {record.Name}Handle(HandleOffset);");
        }
        CloseScope();
        CloseScope("Handle");

        WriteLineIfNeeded();
        foreach (var member in record.Members)
        {
            if ((member.Flags & MemberDefFlags.NotPersisted) != 0)
                continue;

            string fieldType = member.GetMemberType(MemberTypeKind.WriterField);
            if ((member.Flags & (MemberDefFlags.List | MemberDefFlags.Map)) != 0)
            {
                WriteLine($"public {fieldType} {member.Name} = new {fieldType}();");
            }
            else
            {
                WriteLine($"public {fieldType} {member.Name};");
            }
        }

        CloseScope(record.Name);
    }
Example #22
0
        public Dictionary <String, IEnumerable <String> > GetPackageFiles(Schema Schema, String NamespaceName)
        {
            var NamespaceToClasses = new Dictionary <String, List <KeyValuePair <String, List <String> > > >();

            void AddClass(String ClassNamespaceName, String ClassName, IEnumerable <String> ClassContent)
            {
                if (!NamespaceToClasses.ContainsKey(ClassNamespaceName))
                {
                    NamespaceToClasses.Add(ClassNamespaceName, new List <KeyValuePair <String, List <String> > >());
                }
                NamespaceToClasses[ClassNamespaceName].Add(new KeyValuePair <String, List <String> >(ClassName, ClassContent.ToList()));
            }

            foreach (var c in Schema.Types)
            {
                if (c.OnPrimitive)
                {
                    if (c.VersionedName() == "Unit")
                    {
                        AddClass(c.NamespaceName(), "Unit", Primitive_Unit());
                    }
                    else if (c.VersionedName() == "Set")
                    {
                        AddClass(c.NamespaceName(), "Set", Primitive_Set());
                    }
                    else
                    {
                        var p = c.Primitive;
                        if (PrimitiveMapping.ContainsKey(p.VersionedName()))
                        {
                            var Name         = p.VersionedName();
                            var PlatformName = PrimitiveMapping[Name];
                            if (Name != PlatformName && p.GenericParameters.Count() == 0 && PlatformName != "Error")
                            {
                                AddClass(c.NamespaceName(), Name, Primitive(Name, PlatformName));
                            }
                            else
                            {
                                continue;
                            }
                        }
                    }
                }
                else if (c.OnAlias)
                {
                    AddClass(c.NamespaceName(), c.DefinitionName(), Alias(c.Alias));
                }
                else if (c.OnRecord)
                {
                    AddClass(c.NamespaceName(), c.DefinitionName(), Record(c.Record));
                }
                else if (c.OnTaggedUnion)
                {
                    AddClass(c.NamespaceName(), c.DefinitionName(), TaggedUnion(c.TaggedUnion));
                }
                else if (c.OnEnum)
                {
                    AddClass(c.NamespaceName(), c.DefinitionName(), Enum(c.Enum));
                }
                else if (c.OnClientCommand)
                {
                    var tc         = c.ClientCommand;
                    var RequestRef = GetSuffixedTypeRef(tc.Name, tc.Version, "Request");
                    var Request    = new RecordDef {
                        Name = RequestRef.Name, Version = RequestRef.Version, GenericParameters = new List <VariableDef> {
                        }, Fields = tc.OutParameters, Attributes = tc.Attributes, Description = tc.Description
                    };
                    var ReplyRef = GetSuffixedTypeRef(tc.Name, tc.Version, "Reply");
                    var Reply    = new TaggedUnionDef {
                        Name = ReplyRef.Name, Version = ReplyRef.Version, GenericParameters = new List <VariableDef> {
                        }, Alternatives = tc.InParameters, Attributes = tc.Attributes, Description = tc.Description
                    };
                    AddClass(c.NamespaceName(), Request.DefinitionName(), Record(Request));
                    AddClass(c.NamespaceName(), Reply.DefinitionName(), TaggedUnion(Reply));
                }
                else if (c.OnServerCommand)
                {
                    var tc       = c.ServerCommand;
                    var EventRef = GetSuffixedTypeRef(tc.Name, tc.Version, "Event");
                    var Event    = new RecordDef {
                        Name = EventRef.Name, Version = EventRef.Version, GenericParameters = new List <VariableDef> {
                        }, Fields = tc.OutParameters, Attributes = tc.Attributes, Description = tc.Description
                    };
                    AddClass(c.NamespaceName(), Event.DefinitionName(), Record(Event));
                }
                else
                {
                    throw new InvalidOperationException();
                }
            }

            var scg    = Schema.GetSchemaClosureGenerator();
            var sc     = scg.GetClosure(Schema.TypeRefs.Concat(Schema.Types), new List <TypeSpec> {
            });
            var Tuples = sc.TypeSpecs.Where(t => t.OnTuple).ToList();

            foreach (var t in Tuples)
            {
                AddClass(NamespaceName, t.SimpleName(NamespaceName), Tuple(t, NamespaceName));
            }

            var Commands = Schema.Types.Where(t => t.OnClientCommand || t.OnServerCommand).Where(t => t.Version() == "").ToList();

            if (Commands.Count > 0)
            {
                AddClass(NamespaceName, "IApplicationClient", IApplicationClient(Commands, NamespaceName));
            }

            return(NamespaceToClasses.SelectMany(p => p.Value.Select(v => new KeyValuePair <String, IEnumerable <String> >(String.Join("/", p.Key.Split('.').Where(NamespacePart => NamespacePart != "").Select(NamespacePart => LowercaseCamelize(NamespacePart)).Concat(new String[] { v.Key })), WrapModule(p.Key, Schema.Imports, v.Value)))).ToDictionary(p => p.Key, p => p.Value));
        }
Example #23
0
    private void EmitHandle(RecordDef record)
    {
        string handleName = $"{record.Name}Handle";

        OpenScope($"public partial struct {handleName}");

        OpenScope("public override bool Equals(object obj)");
        WriteLine($"if (obj is {handleName})");
        WriteLine($"    return _value == (({handleName})obj)._value;");
        WriteLine("else if (obj is Handle)");
        WriteLine("    return _value == ((Handle)obj)._value;");
        WriteLine("else");
        WriteLine("    return false;");
        CloseScope("Equals");

        OpenScope($"public bool Equals({handleName} handle)");
        WriteLine("return _value == handle._value;");
        CloseScope("Equals");

        OpenScope("public bool Equals(Handle handle)");
        WriteLine("return _value == handle._value;");
        CloseScope("Equals");

        OpenScope("public override int GetHashCode()");
        WriteLine("return (int)_value;");
        CloseScope("GetHashCode");

        WriteLineIfNeeded();
        WriteLine("internal int _value;");

        OpenScope($"internal {handleName}(Handle handle) : this(handle._value)");
        CloseScope();

        OpenScope($"internal {handleName}(int value)");
        WriteLine("HandleType hType = (HandleType)(value >> 24);");
        WriteLine($"if (!(hType == 0 || hType == HandleType.{record.Name} || hType == HandleType.Null))");
        WriteLine("    throw new ArgumentException();");
        WriteLine($"_value = (value & 0x00FFFFFF) | (((int)HandleType.{record.Name}) << 24);");
        WriteLine("_Validate();");
        CloseScope();

        OpenScope($"public static implicit operator  Handle({handleName} handle)");
        WriteLine("return new Handle(handle._value);");
        CloseScope("Handle");

        OpenScope("internal int Offset");
        OpenScope("get");
        WriteLine("return (this._value & 0x00FFFFFF);");
        CloseScope();
        CloseScope("Offset");

        OpenScope($"public {record.Name} Get{record.Name}(MetadataReader reader)");
        WriteLine($"return reader.Get{record.Name}(this);");
        CloseScope($"Get{record.Name}");

        OpenScope("public bool IsNull(MetadataReader reader)");
        WriteLine("return reader.IsNull(this);");
        CloseScope("IsNull");

        OpenScope("public Handle ToHandle(MetadataReader reader)");
        WriteLine("return reader.ToHandle(this);");
        CloseScope("ToHandle");

        WriteScopeAttribute("[System.Diagnostics.Conditional(\"DEBUG\")]");
        OpenScope("internal void _Validate()");
        WriteLine($"if ((HandleType)((_value & 0xFF000000) >> 24) != HandleType.{record.Name})");
        WriteLine("    throw new ArgumentException();");
        CloseScope("_Validate");

        OpenScope("public override String ToString()");
        WriteLine("return String.Format(\"{0:X8}\", _value);");
        CloseScope("ToString");

        CloseScope(handleName);
    }
Example #24
0
        public void FillTranslatorRecordTo(Dictionary <String, TypeDef> VersionedNameToType, RecordDef r, List <String> l, String NamespaceName)
        {
            var       Name  = r.FullName();
            RecordDef rHead = null;

            if (VersionedNameToType.ContainsKey(Name))
            {
                var tHead = VersionedNameToType[Name];
                if (tHead.OnRecord)
                {
                    rHead = tHead.Record;
                }
            }
            var VersionedSimpleName = r.GetTypeSpec().SimpleName(NamespaceName);
            var TypeString          = GetTypeString(Nonversioned(r.GetTypeSpec()), NamespaceName);
            var VersionedTypeString = GetTypeString(r.GetTypeSpec(), NamespaceName);

            if (rHead == null)
            {
                FillTranslatorRecordTo(VersionedSimpleName, TypeString, VersionedTypeString, r.Fields, new List <VariableDef> {
                }, l, true, NamespaceName);
            }
            else
            {
                FillTranslatorRecordTo(VersionedSimpleName, TypeString, VersionedTypeString, r.Fields, rHead.Fields, l, false, NamespaceName);
            }
        }
Example #25
0
    private void EmitRecord(RecordDef record)
    {
        bool isConstantStringValue = record.Name == "ConstantStringValue";

        OpenScope($"public partial class {record.Name} : MetadataRecord");

        if ((record.Flags & RecordDefFlags.ReentrantEquals) != 0)
        {
            OpenScope($"public {record.Name}()");
            WriteLine("_equalsReentrancyGuard = new ThreadLocal<ReentrancyGuardStack>(() => new ReentrancyGuardStack());");
            CloseScope();
        }

        OpenScope("public override HandleType HandleType");
        OpenScope("get");
        WriteLine($"return HandleType.{record.Name};");
        CloseScope();
        CloseScope("HandleType");

        OpenScope("internal override void Visit(IRecordVisitor visitor)");
        foreach (var member in record.Members)
        {
            if ((member.Flags & MemberDefFlags.RecordRef) == 0)
            {
                continue;
            }

            WriteLine($"{member.Name} = visitor.Visit(this, {member.Name});");
        }
        CloseScope("Visit");

        OpenScope("public override sealed bool Equals(Object obj)");
        WriteLine("if (Object.ReferenceEquals(this, obj)) return true;");
        WriteLine($"var other = obj as {record.Name};");
        WriteLine("if (other == null) return false;");
        if ((record.Flags & RecordDefFlags.ReentrantEquals) != 0)
        {
            WriteLine("if (_equalsReentrancyGuard.Value.Contains(other))");
            WriteLine("    return true;");
            WriteLine("_equalsReentrancyGuard.Value.Push(other);");
            WriteLine("try");
            WriteLine("{");
        }
        foreach (var member in record.Members)
        {
            if ((member.Flags & MemberDefFlags.NotPersisted) != 0)
            {
                continue;
            }

            if ((record.Flags & RecordDefFlags.CustomCompare) != 0 && (member.Flags & MemberDefFlags.Compare) == 0)
            {
                continue;
            }

            if ((member.Flags & MemberDefFlags.Sequence) != 0)
            {
                if ((member.Flags & MemberDefFlags.CustomCompare) != 0)
                {
                    WriteLine($"if (!{member.Name}.SequenceEqual(other.{member.Name}, {member.TypeName}Comparer.Instance)) return false;");
                }
                else
                {
                    WriteLine($"if (!{member.Name}.SequenceEqual(other.{member.Name})) return false;");
                }
            }
            else
            if ((member.Flags & (MemberDefFlags.Map | MemberDefFlags.RecordRef)) != 0)
            {
                WriteLine($"if (!Object.Equals({member.Name}, other.{member.Name})) return false;");
            }
            else
            if ((member.Flags & MemberDefFlags.CustomCompare) != 0)
            {
                WriteLine($"if (!CustomComparer.Equals({member.Name}, other.{member.Name})) return false;");
            }
            else
            {
                WriteLine($"if ({member.Name} != other.{member.Name}) return false;");
            }
        }
        if ((record.Flags & RecordDefFlags.ReentrantEquals) != 0)
        {
            WriteLine("}");

            WriteLine("finally");
            WriteLine("{");
            WriteLine("    var popped = _equalsReentrancyGuard.Value.Pop();");
            WriteLine("    Debug.Assert(Object.ReferenceEquals(other, popped));");
            WriteLine("}");
        }
        WriteLine("return true;");
        CloseScope("Equals");
        if ((record.Flags & RecordDefFlags.ReentrantEquals) != 0)
        {
            WriteLine("private ThreadLocal<ReentrancyGuardStack> _equalsReentrancyGuard;");
        }

        OpenScope("public override sealed int GetHashCode()");
        WriteLine("if (_hash != 0)");
        WriteLine("    return _hash;");
        WriteLine("EnterGetHashCode();");

        // Compute hash seed using stable hashcode
        byte[] nameBytes = System.Text.Encoding.UTF8.GetBytes(record.Name);
        byte[] hashBytes = System.Security.Cryptography.SHA256.Create().ComputeHash(nameBytes);
        int    hashSeed  = System.BitConverter.ToInt32(hashBytes, 0);

        WriteLine($"int hash = {hashSeed};");

        foreach (var member in record.Members)
        {
            if ((member.Flags & MemberDefFlags.NotPersisted) != 0)
            {
                continue;
            }

            if ((record.Flags & RecordDefFlags.CustomCompare) != 0 && (member.Flags & MemberDefFlags.Compare) == 0)
            {
                continue;
            }

            if (member.TypeName as string == "ConstantStringValue")
            {
                WriteLine($"hash = ((hash << 13) - (hash >> 19)) ^ ({member.Name} == null ? 0 : {member.Name}.GetHashCode());");
            }
            else
            if ((member.Flags & MemberDefFlags.Array) != 0)
            {
                WriteLine($"if ({member.Name} != null)");
                WriteLine("{");
                WriteLine($"    for (int i = 0; i < {member.Name}.Length; i++)");
                WriteLine("    {");
                WriteLine($"        hash = ((hash << 13) - (hash >> 19)) ^ {member.Name}[i].GetHashCode();");
                WriteLine("    }");
                WriteLine("}");
            }
            else
            if ((member.Flags & (MemberDefFlags.List | MemberDefFlags.Map)) != 0)
            {
                if ((member.Flags & MemberDefFlags.EnumerateForHashCode) == 0)
                {
                    continue;
                }

                WriteLine($"if ({member.Name} != null)");
                WriteLine("{");
                WriteLine($"for (int i = 0; i < {member.Name}.Count; i++)");
                WriteLine("    {");
                WriteLine($"        hash = ((hash << 13) - (hash >> 19)) ^ ({member.Name}[i] == null ? 0 : {member.Name}[i].GetHashCode());");
                WriteLine("    }");
                WriteLine("}");
            }
            else
            if ((member.Flags & MemberDefFlags.RecordRef) != 0 || isConstantStringValue)
            {
                WriteLine($"hash = ((hash << 13) - (hash >> 19)) ^ ({member.Name} == null ? 0 : {member.Name}.GetHashCode());");
            }
            else
            {
                WriteLine($"hash = ((hash << 13) - (hash >> 19)) ^ {member.Name}.GetHashCode();");
            }
        }
        WriteLine("LeaveGetHashCode();");
        WriteLine("_hash = hash;");
        WriteLine("return _hash;");
        CloseScope("GetHashCode");

        OpenScope("internal override void Save(NativeWriter writer)");
        if (isConstantStringValue)
        {
            WriteLine("if (Value == null)");
            WriteLine("    return;");
            WriteLine();
        }
        foreach (var member in record.Members)
        {
            if ((member.Flags & MemberDefFlags.NotPersisted) != 0)
            {
                continue;
            }

            var typeSet = member.TypeName as string[];
            if (typeSet != null)
            {
                if ((member.Flags & (MemberDefFlags.List | MemberDefFlags.Map)) != 0)
                {
                    WriteLine($"Debug.Assert({member.Name}.TrueForAll(handle => handle == null ||");
                    for (int i = 0; i < typeSet.Length; i++)
                    {
                        WriteLine($"    handle.HandleType == HandleType.{typeSet[i]}"
                                  + ((i == typeSet.Length - 1) ? "));" : " ||"));
                    }
                }
                else
                {
                    WriteLine($"Debug.Assert({member.Name} == null ||");
                    for (int i = 0; i < typeSet.Length; i++)
                    {
                        WriteLine($"    {member.Name}.HandleType == HandleType.{typeSet[i]}"
                                  + ((i == typeSet.Length - 1) ? ");" : " ||"));
                    }
                }
            }
            WriteLine($"writer.Write({member.Name});");
        }
        CloseScope("Save");

        OpenScope($"internal static {record.Name}Handle AsHandle({record.Name} record)");
        WriteLine("if (record == null)");
        WriteLine("{");
        WriteLine($"    return new {record.Name}Handle(0);");
        WriteLine("}");
        WriteLine("else");
        WriteLine("{");
        WriteLine("    return record.Handle;");
        WriteLine("}");
        CloseScope("AsHandle");

        OpenScope($"internal new {record.Name}Handle Handle");
        OpenScope("get");
        if (isConstantStringValue)
        {
            WriteLine("if (Value == null)");
            WriteLine("    return new ConstantStringValueHandle(0);");
            WriteLine("else");
            WriteLine("    return new ConstantStringValueHandle(HandleOffset);");
        }
        else
        {
            WriteLine($"return new {record.Name}Handle(HandleOffset);");
        }
        CloseScope();
        CloseScope("Handle");

        WriteLineIfNeeded();
        foreach (var member in record.Members)
        {
            if ((member.Flags & MemberDefFlags.NotPersisted) != 0)
            {
                continue;
            }

            string fieldType = member.GetMemberType(MemberTypeKind.WriterField);
            if ((member.Flags & (MemberDefFlags.List | MemberDefFlags.Map)) != 0)
            {
                WriteLine($"public {fieldType} {member.Name} = new {fieldType}();");
            }
            else
            {
                WriteLine($"public {fieldType} {member.Name};");
            }
        }

        CloseScope(record.Name);
    }
Example #26
0
 public static float getCuMRecordPoints(Pawn p, RecordDef def)
 {
     return(p.records.GetValue(def) * getCuMRecordFactor(def));
 }