Misc code quality improvements, fixes

This commit is contained in:
Lohikar 2017-11-17 12:30:44 -06:00
parent 91d580e21f
commit 25fc65cdd8
5 changed files with 125 additions and 201 deletions

View file

@ -1,11 +1,11 @@
using System; using MahApps.Metro.Controls.Dialogs;
using System;
using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.IO; using System.IO;
using System.Linq;
using System.Windows; using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
using MahApps.Metro.Controls.Dialogs;
using System.Collections.Generic;
using System.Linq;
namespace AuroraRecordGenerator namespace AuroraRecordGenerator
{ {
@ -21,6 +21,7 @@ namespace AuroraRecordGenerator
DataContext = Data; DataContext = Data;
ProtoBuf.Serializer.PrepareSerializer<GenderType>(); ProtoBuf.Serializer.PrepareSerializer<GenderType>();
ProtoBuf.Serializer.PrepareSerializer<SpeciesType>(); ProtoBuf.Serializer.PrepareSerializer<SpeciesType>();
ProtoBuf.Serializer.PrepareSerializer<SpeciesSubType>();
ProtoBuf.Serializer.PrepareSerializer<Record>(); ProtoBuf.Serializer.PrepareSerializer<Record>();
InitializeComponent(); InitializeComponent();
SubSpeciesCombo.ItemsSource = GetSpeciesOptions(); SubSpeciesCombo.ItemsSource = GetSpeciesOptions();
@ -29,7 +30,6 @@ namespace AuroraRecordGenerator
private Record Data { get; set; } private Record Data { get; set; }
private string _currentFilePath; private string _currentFilePath;
private void SpeciesSelectChanged(object sender, SelectionChangedEventArgs e) private void SpeciesSelectChanged(object sender, SelectionChangedEventArgs e)
{ {
if (SpeciesCombo.SelectionBoxItem == null) if (SpeciesCombo.SelectionBoxItem == null)
@ -55,13 +55,19 @@ namespace AuroraRecordGenerator
Debug.WriteLine("Enabled GenderCombo, type is " + type); Debug.WriteLine("Enabled GenderCombo, type is " + type);
GenderCombo.IsEnabled = true; GenderCombo.IsEnabled = true;
break; break;
case SpeciesType.None: case SpeciesType.None:
break; break;
default: default:
throw new ArgumentOutOfRangeException(); throw new ArgumentOutOfRangeException();
} }
SubSpeciesCombo.ItemsSource = GetSpeciesOptions(type); Debug.WriteLine("Updating subspecies types.");
var types = GetSpeciesOptions(type);
var itemsSource = types as IList<string> ?? types.ToList();
SubSpeciesCombo.ItemsSource = itemsSource;
Debug.WriteLine($"New types: {string.Join(",", itemsSource)}");
} }
private void WindowLoaded(object sender, RoutedEventArgs e) private void WindowLoaded(object sender, RoutedEventArgs e)
@ -88,15 +94,17 @@ namespace AuroraRecordGenerator
switch ( switch (
await await
this.ShowMessageAsync("File Error", this.ShowMessageAsync("File Error",
"Current file missing, renamed or deleted. Do you want to save as another name?", "Current file missing, renamed, or deleted. Do you want to save as another name?",
MessageDialogStyle.AffirmativeAndNegative)) MessageDialogStyle.AffirmativeAndNegative))
{ {
case MessageDialogResult.Negative: case MessageDialogResult.Negative:
_currentFilePath = null; _currentFilePath = null;
return; return;
case MessageDialogResult.Affirmative: case MessageDialogResult.Affirmative:
SaveContentAs(null, null); SaveContentAs(null, null);
return; return;
default: default:
throw new ArgumentOutOfRangeException(); throw new ArgumentOutOfRangeException();
} }
@ -130,7 +138,9 @@ namespace AuroraRecordGenerator
{ {
var dialog = new Microsoft.Win32.SaveFileDialog var dialog = new Microsoft.Win32.SaveFileDialog
{ {
AddExtension = true, CheckPathExists = true, Filter = "Character Profiles (*.ss13prof)|*.ss13prof|All Files (*.*)|*.*" AddExtension = true,
CheckPathExists = true,
Filter = "Character Profiles (*.ss13prof)|*.ss13prof|All Files (*.*)|*.*"
}; };
if (!(dialog.ShowDialog() ?? false)) return; if (!(dialog.ShowDialog() ?? false)) return;
var fs = File.Open(dialog.FileName, FileMode.Create); var fs = File.Open(dialog.FileName, FileMode.Create);
@ -138,14 +148,17 @@ namespace AuroraRecordGenerator
_currentFilePath = dialog.FileName; _currentFilePath = dialog.FileName;
} }
public static IList<string> GetSpeciesOptions() private static IEnumerable<string> GetSpeciesOptions() => Enum.GetValues(typeof(SpeciesSubType)).Cast<SpeciesSubType>().Select(Utility.SubspeciesNiceName);
{
return Enum.GetValues(typeof(SpeciesSubType)).Cast<SpeciesSubType>().Select(item => Utility.SubspeciesNiceName(item)).ToList();
}
public static IList<string> GetSpeciesOptions(SpeciesType limitTo) private static IEnumerable<string> GetSpeciesOptions(SpeciesType limitTo)
{ {
return Enum.GetValues(typeof(SpeciesSubType)).Cast<SpeciesSubType>().Select(item => Utility.SubspeciesNiceName(item)).ToList(); var targetAttr = limitTo.GetAttributeOfType<SubspeciesMetaAttribute>()?.AssociatedSpecies;
if (targetAttr == null)
return GetSpeciesOptions();
return from item in Enum.GetValues(typeof(SpeciesSubType)).Cast<SpeciesSubType>()
let attr = item.GetAttributeOfType<SubspeciesMetaAttribute>()
where attr != null && attr.AssociatedSpecies == targetAttr
select Utility.SubspeciesNiceName(item);
} }
} }
} }

View file

@ -6,30 +6,15 @@ namespace AuroraRecordGenerator
{ {
internal partial class RecordFormatter internal partial class RecordFormatter
{ {
public Record TargetRecord private Record _targetRecord;
{
get { return _targetRecord; }
set
{
UpdateSplitRecords();
MakeCommonRecords();
_lastRecordHash = value.GetHashCode();
_targetRecord = value;
}
}
public RecordFormatter(Record r) public RecordFormatter(Record r)
{ {
_targetRecord = r; _targetRecord = r;
UpdateSplitRecords(); UpdateSplitRecords();
MakeCommonRecords(); MakeCommonRecords();
_lastRecordHash = r.GetHashCode();
} }
private Record _targetRecord;
private int? _lastRecordHash;
private IList<string> _medicalPublicRecord; private IList<string> _medicalPublicRecord;
private IList<string> _medicalHistory; private IList<string> _medicalHistory;
private IList<string> _medicalNotes; private IList<string> _medicalNotes;
@ -48,7 +33,6 @@ namespace AuroraRecordGenerator
private IList<string> _employmentNtEmployment; private IList<string> _employmentNtEmployment;
private IList<string> _employmentSkills; private IList<string> _employmentSkills;
private void UpdateSplitRecords() private void UpdateSplitRecords()
{ {
if (_targetRecord == null) if (_targetRecord == null)
@ -79,50 +63,14 @@ namespace AuroraRecordGenerator
// flush the record cache so they're regenerated // flush the record cache so they're regenerated
_commonRecords = null; _commonRecords = null;
_medicalRecordGenerated = null;
_securityRecordGenerated = null;
_employmentRecordGenerated = null;
} }
public string EmploymentRecords public string EmploymentRecords => MakeEmploymentRecords();
{ public string MedicalRecords => MakeMedicalRecords();
get public string SecurityRecords => MakeSecurityRecords();
{
//if (_employmentRecordGenerated.IsEmpty())
MakeEmploymentRecords();
return _employmentRecordGenerated;
}
}
private string _employmentRecordGenerated;
public string MedicalRecords
{
get
{
//if (_medicalRecordGenerated.IsEmpty())
MakeMedicalRecords();
return _medicalRecordGenerated;
}
}
private string _medicalRecordGenerated;
public string SecurityRecords
{
get
{
//if (_securityRecordGenerated.IsEmpty())
MakeSecurityRecords();
return _securityRecordGenerated;
}
}
private string _securityRecordGenerated;
private string _commonRecords; private string _commonRecords;
/// <summary> /// <summary>
/// Writes the <see cref="string"/> form of a record section to the specified <see cref="StringBuilder"/>, as long as there's entries to write. /// Writes the <see cref="string"/> form of a record section to the specified <see cref="StringBuilder"/>, as long as there's entries to write.
/// </summary> /// </summary>
@ -137,19 +85,6 @@ namespace AuroraRecordGenerator
builder.AppendLine(entries.FormatAsList()); builder.AppendLine(entries.FormatAsList());
} }
/// <summary>
/// Writes the <see cref="string"/> form of a record section to the specified <see cref="StringBuilder"/>, as long as there's entries to write.
/// Inserts a newline before the section.
/// </summary>
/// <param name="builder">The <see cref="StringBuilder"/> to write to.</param>
/// <param name="header">The title for the section.</param>
/// <param name="entries">The entries of this section.</param>
private static void WritePrefixedSectionifAny(ref StringBuilder builder, string header, IList<string> entries)
{
builder.AppendLine();
WriteSectionIfAny(ref builder, header, entries);
}
private string MakeNameLine() private string MakeNameLine()
{ {
var builder = new StringBuilder("Name: "); var builder = new StringBuilder("Name: ");

View file

@ -1,6 +1,6 @@
using System.Linq; using Humanizer;
using System.Linq;
using System.Text; using System.Text;
using Humanizer;
namespace AuroraRecordGenerator namespace AuroraRecordGenerator
{ {
@ -20,15 +20,17 @@ namespace AuroraRecordGenerator
record.AppendLine($"Clearance Level: {_targetRecord.Clearance.IfEmpty("Not Specified")}"); record.AppendLine($"Clearance Level: {_targetRecord.Clearance.IfEmpty("Not Specified")}");
record.AppendLine($"Employed As: {_targetRecord.EmployedAs.IfEmpty("Assistant")}"); record.AppendLine($"Employed As: {_targetRecord.EmployedAs.IfEmpty("Assistant")}");
if (_targetRecord.CharHeight != null) if (_targetRecord.CharHeight != null)
record.AppendLine($"Height: {_targetRecord.CharHeight} cm ({Utility.CmToFeet(_targetRecord.CharHeight.Value)})"); record.AppendLine($"Height: {_targetRecord.CharHeight} cm");// ({Utility.CmToFeet(_targetRecord.CharHeight.Value)})
if (_targetRecord.Weight != null) if (_targetRecord.Weight != null)
record.AppendLine($"Weight: {_targetRecord.Weight} kg ({Utility.KgToLb(_targetRecord.Weight ?? 0)})"); record.AppendLine($"Weight: {_targetRecord.Weight} kg ({Utility.KgToLb(_targetRecord.Weight ?? 0)} lb)");
record.AppendLine();
// identifying features // identifying features
// TODO: identifying features var trimmedFeatures = _targetRecord.DistinguishingFeatures.Trim();
if (trimmedFeatures.Length > 0)
record.AppendLine($"Distinguishing Features: {trimmedFeatures}");
record.AppendLine();
// general notes // general notes
WriteSectionIfAny(ref record, WriteSectionIfAny(ref record,
@ -46,7 +48,7 @@ namespace AuroraRecordGenerator
_commonRecords = record.ToString(); _commonRecords = record.ToString();
} }
private void MakeEmploymentRecords() private string MakeEmploymentRecords()
{ {
var recordText = new StringBuilder(); var recordText = new StringBuilder();
if (_commonRecords.IsEmpty()) if (_commonRecords.IsEmpty())
@ -89,10 +91,10 @@ namespace AuroraRecordGenerator
_employmentSkills); _employmentSkills);
} }
_employmentRecordGenerated = recordText.ToString(); return recordText.ToString();
} }
private void MakeMedicalRecords() private string MakeMedicalRecords()
{ {
var recordText = new StringBuilder(); var recordText = new StringBuilder();
if (_commonRecords.IsEmpty()) if (_commonRecords.IsEmpty())
@ -106,10 +108,10 @@ namespace AuroraRecordGenerator
!_medicalPsychHistory.Any() && !_medicalPsychHistory.Any() &&
!_medicalPsychNotes.Any() && !_medicalPsychNotes.Any() &&
!_medicalPrescriptions.Any() && !_medicalPrescriptions.Any() &&
!TargetRecord.NoBorg && !_targetRecord.NoBorg &&
!TargetRecord.NoClone && !_targetRecord.NoClone &&
!TargetRecord.NoProsthetic && !_targetRecord.NoProsthetic &&
!TargetRecord.NoRevive) !_targetRecord.NoRevive)
{ {
recordText.AppendLine("/// NO MEDICAL RECORD FOUND ///"); recordText.AppendLine("/// NO MEDICAL RECORD FOUND ///");
} }
@ -121,20 +123,20 @@ namespace AuroraRecordGenerator
recordText.AppendLine( recordText.AppendLine(
" The following information is protected by doctor-patient confidentiality laws. Do not release without patient's consent.\n"); " The following information is protected by doctor-patient confidentiality laws. Do not release without patient's consent.\n");
if (TargetRecord.NoBorg || TargetRecord.NoClone || TargetRecord.NoProsthetic || TargetRecord.NoRevive) if (_targetRecord.NoBorg || _targetRecord.NoClone || _targetRecord.NoProsthetic || _targetRecord.NoRevive)
{ {
recordText.AppendLine("IMPORTANT NOTES:"); recordText.AppendLine("IMPORTANT NOTES:");
if (TargetRecord.NoBorg) if (_targetRecord.NoBorg)
MakeMedicalNote(ref recordText, "DO NOT BORGIFY"); MakeMedicalNote(ref recordText, "DO NOT BORGIFY");
if (TargetRecord.NoClone) if (_targetRecord.NoClone)
MakeMedicalNote(ref recordText, "DO NOT CLONE"); MakeMedicalNote(ref recordText, "DO NOT CLONE");
if (TargetRecord.NoProsthetic) if (_targetRecord.NoProsthetic)
MakeMedicalNote(ref recordText, "DO NOT INSTALL PROSTHETICS"); MakeMedicalNote(ref recordText, "DO NOT INSTALL PROSTHETICS");
if (TargetRecord.NoRevive) if (_targetRecord.NoRevive)
MakeMedicalNote(ref recordText, "DO NOT REVIVE"); MakeMedicalNote(ref recordText, "DO NOT REVIVE");
recordText.AppendLine(); recordText.AppendLine();
@ -161,10 +163,10 @@ namespace AuroraRecordGenerator
_medicalPrescriptions); _medicalPrescriptions);
} }
_medicalRecordGenerated = recordText.ToString(); return recordText.ToString();
} }
private void MakeSecurityRecords() private string MakeSecurityRecords()
{ {
var recordText = new StringBuilder(); var recordText = new StringBuilder();
if (_commonRecords.IsEmpty()) if (_commonRecords.IsEmpty())
@ -190,7 +192,7 @@ namespace AuroraRecordGenerator
_securityRecords); _securityRecords);
} }
_securityRecordGenerated = recordText.ToString(); return recordText.ToString();
} }
} }
} }

View file

@ -1,5 +1,5 @@
using System; using ProtoBuf;
using ProtoBuf; using System;
namespace AuroraRecordGenerator namespace AuroraRecordGenerator
{ {
@ -8,18 +8,25 @@ namespace AuroraRecordGenerator
{ {
[ProtoEnum] [ProtoEnum]
None = 0, None = 0,
[ProtoEnum] [ProtoEnum]
Human, Human,
[ProtoEnum] [ProtoEnum]
Skrell, Skrell,
[ProtoEnum] [ProtoEnum]
Tajara, Tajara,
[ProtoEnum] [ProtoEnum]
Unathi, Unathi,
[ProtoEnum] [ProtoEnum]
Vaurca, Vaurca,
[ProtoEnum] [ProtoEnum]
Diona, Diona,
[ProtoEnum] [ProtoEnum]
IPC IPC
} }
@ -29,17 +36,23 @@ namespace AuroraRecordGenerator
{ {
[ProtoEnum] [ProtoEnum]
None = 0, None = 0,
[ProtoEnum]
[ProtoEnum, SubspeciesMeta(SpeciesType.Tajara, "M'sai")]
MsaiTajara, MsaiTajara,
[ProtoEnum]
[ProtoEnum, SubspeciesMeta(SpeciesType.Tajara, "Zhan-Khazan")]
ZhanTajara, ZhanTajara,
[ProtoEnum]
[ProtoEnum, SubspeciesMeta(SpeciesType.Vaurca, "Type A (Worker)")]
VaurcaWorker, VaurcaWorker,
[ProtoEnum]
[ProtoEnum, SubspeciesMeta(SpeciesType.Vaurca, "Type B (Warrior)")]
VaurcaWarrior, VaurcaWarrior,
[ProtoEnum]
[ProtoEnum, SubspeciesMeta(SpeciesType.IPC, "Shell Frame")]
IpcShell, IpcShell,
[ProtoEnum]
[ProtoEnum, SubspeciesMeta(SpeciesType.IPC, "Industrial Frame")]
IpcG1Industrial IpcG1Industrial
} }
@ -48,8 +61,10 @@ namespace AuroraRecordGenerator
{ {
[ProtoEnum] [ProtoEnum]
NotApplicable = 0, NotApplicable = 0,
[ProtoEnum] [ProtoEnum]
Male, Male,
[ProtoEnum] [ProtoEnum]
Female Female
} }
@ -59,8 +74,20 @@ namespace AuroraRecordGenerator
/// <summary> /// <summary>
/// The current in-character date. /// The current in-character date.
/// </summary> /// </summary>
public static DateTime IcDate => new DateTime(2458, public static DateTime IcDate => new DateTime(DateTime.Now.Year + 442,
DateTime.Now.Month, DateTime.Now.Month,
DateTime.Now.Day); DateTime.Now.Day);
} }
[AttributeUsage(AttributeTargets.Field)]
public class SubspeciesMetaAttribute : Attribute
{
public SpeciesType AssociatedSpecies {get; private set;}
public string NiceName { get; private set; }
public SubspeciesMetaAttribute(SpeciesType associatedType, string nicename)
{
AssociatedSpecies = associatedType;
NiceName = nicename;
}
}
} }

View file

@ -7,77 +7,20 @@ namespace AuroraRecordGenerator
{ {
public static class Utility public static class Utility
{ {
/// <summary>
/// Splits a string into an array of strings.
/// </summary>
/// <param name="source">The string to split.</param>
/// <param name="predictedSplitLen">How large each string probably will be. Specify to theoretically improve performance.</param>
/// <param name="splitValues">Array of chars to split on.</param>
/// <returns></returns>
public static IEnumerable<string> LazySplit(this string source, int predictedSplitLen, params char[] splitValues)
{
var builder = predictedSplitLen <= 0
? new StringBuilder()
: new StringBuilder(predictedSplitLen);
foreach (var c in source)
{
if (splitValues.Contains(c))
{
// split off string
var result = builder.ToString();
builder.Clear();
yield return result;
}
builder.Append(c);
}
}
/// <summary>
/// Splits a string into an array of strings.
/// </summary>
/// <param name="source">The string to split.</param>
/// <param name="splitValues">Array of chars to split on.</param>
/// <returns></returns>
public static IEnumerable<string> LazySplit(this string source, params char[] splitValues) =>
source.LazySplit(-1, splitValues);
/// <summary>
/// Splits a string into an array of strings.
/// </summary>
/// <param name="source">The string to split.</param>
/// <param name="predictedSplitLen">How large each string probably will be. Specify to theoretically improve performance.</param>
/// <param name="splitValue">Char to split on.</param>
/// <returns></returns>
public static IEnumerable<string> LazySplit(this string source, int predictedSplitLen, char splitValue)
{
var builder = predictedSplitLen <= 0
? new StringBuilder()
: new StringBuilder(predictedSplitLen);
foreach (var c in source)
{
if (c == splitValue)
{
// split off string
var result = builder.ToString();
builder.Clear();
yield return result;
}
builder.Append(c);
}
}
public static IList<string> LineSplit(this string source) => public static IList<string> LineSplit(this string source) =>
source.Split('\n').Where(item => item.Trim().Length != 0).ToList(); source.Split('\n').Where(item => item.Trim().Length != 0).ToList();
public static string CmToFeet(double cm) public static string CmToFeet(double cm)
{ {
return "0'0\""; return "0'0\"";
} }
public static string KgToLb(double kg) => $"{Math.Round(kg * 2.2046, 2)} lb"; /// <summary>
/// Converts a weight in Kilograms to Pounds.
/// </summary>
/// <param name="kg">The weight in kilograms.</param>
/// <returns>The weight converted to pounds.</returns>
public static double KgToLb(double kg) => Math.Round(kg * 2.2046, 2);
/// <summary> /// <summary>
/// Returns <paramref name="val"/> and a trailing space if val is not whitespace, <see cref="string.Empty"/> otherwise. /// Returns <paramref name="val"/> and a trailing space if val is not whitespace, <see cref="string.Empty"/> otherwise.
@ -113,23 +56,27 @@ namespace AuroraRecordGenerator
public static string SubspeciesNiceName(SpeciesSubType species) public static string SubspeciesNiceName(SpeciesSubType species)
{ {
switch (species) var attr = species.GetAttributeOfType<SubspeciesMetaAttribute>();
return attr?.NiceName ?? Enum.GetName(typeof(SpeciesSubType), species);
}
}
// From https://stackoverflow.com/questions/1799370/getting-attributes-of-enums-value
public static class EnumHelper
{ {
case SpeciesSubType.MsaiTajara: /// <summary>
return "M'sai"; /// Gets an attribute on an enum field value
case SpeciesSubType.ZhanTajara: /// </summary>
return "Zhan-Khazan"; /// <typeparam name="T">The type of the attribute you want to retrieve</typeparam>
case SpeciesSubType.VaurcaWorker: /// <param name="enumVal">The enum value</param>
return "Worker (Type A)"; /// <returns>The attribute of type T that exists on the enum value</returns>
case SpeciesSubType.VaurcaBreeder: /// <example>string desc = myEnumVariable.GetAttributeOfType<DescriptionAttribute>().Description;</example>
return "Warrior (Type B)"; public static T GetAttributeOfType<T>(this Enum enumVal) where T : Attribute
case SpeciesSubType.IpcShell: {
return "Shell Frame"; var type = enumVal.GetType();
case SpeciesSubType.IpcG1Industrial: var memInfo = type.GetMember(enumVal.ToString());
return "Industrial Frame"; var attributes = memInfo[0].GetCustomAttributes(typeof(T), false);
default: return attributes.Length > 0 ? (T)attributes[0] : null;
return Enum.GetName(typeof(SpeciesSubType), species);
}
} }
} }
} }