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.IO;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using MahApps.Metro.Controls.Dialogs;
using System.Collections.Generic;
using System.Linq;
namespace AuroraRecordGenerator
{
@ -21,6 +21,7 @@ namespace AuroraRecordGenerator
DataContext = Data;
ProtoBuf.Serializer.PrepareSerializer<GenderType>();
ProtoBuf.Serializer.PrepareSerializer<SpeciesType>();
ProtoBuf.Serializer.PrepareSerializer<SpeciesSubType>();
ProtoBuf.Serializer.PrepareSerializer<Record>();
InitializeComponent();
SubSpeciesCombo.ItemsSource = GetSpeciesOptions();
@ -29,13 +30,12 @@ namespace AuroraRecordGenerator
private Record Data { get; set; }
private string _currentFilePath;
private void SpeciesSelectChanged(object sender, SelectionChangedEventArgs e)
{
if (SpeciesCombo.SelectionBoxItem == null)
return;
var type = (SpeciesType) SpeciesCombo.SelectedValue;
var type = (SpeciesType)SpeciesCombo.SelectedValue;
switch (type)
{
@ -55,13 +55,19 @@ namespace AuroraRecordGenerator
Debug.WriteLine("Enabled GenderCombo, type is " + type);
GenderCombo.IsEnabled = true;
break;
case SpeciesType.None:
break;
default:
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)
@ -88,15 +94,17 @@ namespace AuroraRecordGenerator
switch (
await
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))
{
case MessageDialogResult.Negative:
_currentFilePath = null;
return;
case MessageDialogResult.Affirmative:
SaveContentAs(null, null);
return;
default:
throw new ArgumentOutOfRangeException();
}
@ -130,7 +138,9 @@ namespace AuroraRecordGenerator
{
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;
var fs = File.Open(dialog.FileName, FileMode.Create);
@ -138,14 +148,17 @@ namespace AuroraRecordGenerator
_currentFilePath = dialog.FileName;
}
public static IList<string> GetSpeciesOptions()
{
return Enum.GetValues(typeof(SpeciesSubType)).Cast<SpeciesSubType>().Select(item => Utility.SubspeciesNiceName(item)).ToList();
}
private static IEnumerable<string> GetSpeciesOptions() => Enum.GetValues(typeof(SpeciesSubType)).Cast<SpeciesSubType>().Select(Utility.SubspeciesNiceName);
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
{
public Record TargetRecord
{
get { return _targetRecord; }
set
{
UpdateSplitRecords();
MakeCommonRecords();
_lastRecordHash = value.GetHashCode();
_targetRecord = value;
}
}
private Record _targetRecord;
public RecordFormatter(Record r)
{
_targetRecord = r;
UpdateSplitRecords();
MakeCommonRecords();
_lastRecordHash = r.GetHashCode();
}
private Record _targetRecord;
private int? _lastRecordHash;
private IList<string> _medicalPublicRecord;
private IList<string> _medicalHistory;
private IList<string> _medicalNotes;
@ -48,7 +33,6 @@ namespace AuroraRecordGenerator
private IList<string> _employmentNtEmployment;
private IList<string> _employmentSkills;
private void UpdateSplitRecords()
{
if (_targetRecord == null)
@ -79,50 +63,14 @@ namespace AuroraRecordGenerator
// flush the record cache so they're regenerated
_commonRecords = null;
_medicalRecordGenerated = null;
_securityRecordGenerated = null;
_employmentRecordGenerated = null;
}
public string EmploymentRecords
{
get
{
//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;
public string EmploymentRecords => MakeEmploymentRecords();
public string MedicalRecords => MakeMedicalRecords();
public string SecurityRecords => MakeSecurityRecords();
private string _commonRecords;
/// <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.
/// </summary>
@ -137,19 +85,6 @@ namespace AuroraRecordGenerator
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()
{
var builder = new StringBuilder("Name: ");

View file

@ -1,6 +1,6 @@
using System.Linq;
using Humanizer;
using System.Linq;
using System.Text;
using Humanizer;
namespace AuroraRecordGenerator
{
@ -20,15 +20,17 @@ namespace AuroraRecordGenerator
record.AppendLine($"Clearance Level: {_targetRecord.Clearance.IfEmpty("Not Specified")}");
record.AppendLine($"Employed As: {_targetRecord.EmployedAs.IfEmpty("Assistant")}");
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)
record.AppendLine($"Weight: {_targetRecord.Weight} kg ({Utility.KgToLb(_targetRecord.Weight ?? 0)})");
record.AppendLine();
record.AppendLine($"Weight: {_targetRecord.Weight} kg ({Utility.KgToLb(_targetRecord.Weight ?? 0)} lb)");
// identifying features
// TODO: identifying features
var trimmedFeatures = _targetRecord.DistinguishingFeatures.Trim();
if (trimmedFeatures.Length > 0)
record.AppendLine($"Distinguishing Features: {trimmedFeatures}");
record.AppendLine();
// general notes
WriteSectionIfAny(ref record,
@ -46,7 +48,7 @@ namespace AuroraRecordGenerator
_commonRecords = record.ToString();
}
private void MakeEmploymentRecords()
private string MakeEmploymentRecords()
{
var recordText = new StringBuilder();
if (_commonRecords.IsEmpty())
@ -89,10 +91,10 @@ namespace AuroraRecordGenerator
_employmentSkills);
}
_employmentRecordGenerated = recordText.ToString();
return recordText.ToString();
}
private void MakeMedicalRecords()
private string MakeMedicalRecords()
{
var recordText = new StringBuilder();
if (_commonRecords.IsEmpty())
@ -106,10 +108,10 @@ namespace AuroraRecordGenerator
!_medicalPsychHistory.Any() &&
!_medicalPsychNotes.Any() &&
!_medicalPrescriptions.Any() &&
!TargetRecord.NoBorg &&
!TargetRecord.NoClone &&
!TargetRecord.NoProsthetic &&
!TargetRecord.NoRevive)
!_targetRecord.NoBorg &&
!_targetRecord.NoClone &&
!_targetRecord.NoProsthetic &&
!_targetRecord.NoRevive)
{
recordText.AppendLine("/// NO MEDICAL RECORD FOUND ///");
}
@ -121,20 +123,20 @@ namespace AuroraRecordGenerator
recordText.AppendLine(
" 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:");
if (TargetRecord.NoBorg)
if (_targetRecord.NoBorg)
MakeMedicalNote(ref recordText, "DO NOT BORGIFY");
if (TargetRecord.NoClone)
if (_targetRecord.NoClone)
MakeMedicalNote(ref recordText, "DO NOT CLONE");
if (TargetRecord.NoProsthetic)
if (_targetRecord.NoProsthetic)
MakeMedicalNote(ref recordText, "DO NOT INSTALL PROSTHETICS");
if (TargetRecord.NoRevive)
if (_targetRecord.NoRevive)
MakeMedicalNote(ref recordText, "DO NOT REVIVE");
recordText.AppendLine();
@ -161,10 +163,10 @@ namespace AuroraRecordGenerator
_medicalPrescriptions);
}
_medicalRecordGenerated = recordText.ToString();
return recordText.ToString();
}
private void MakeSecurityRecords()
private string MakeSecurityRecords()
{
var recordText = new StringBuilder();
if (_commonRecords.IsEmpty())
@ -190,7 +192,7 @@ namespace AuroraRecordGenerator
_securityRecords);
}
_securityRecordGenerated = recordText.ToString();
return recordText.ToString();
}
}
}

View file

@ -1,5 +1,5 @@
using System;
using ProtoBuf;
using ProtoBuf;
using System;
namespace AuroraRecordGenerator
{
@ -8,18 +8,25 @@ namespace AuroraRecordGenerator
{
[ProtoEnum]
None = 0,
[ProtoEnum]
Human,
[ProtoEnum]
Skrell,
[ProtoEnum]
Tajara,
[ProtoEnum]
Unathi,
[ProtoEnum]
Vaurca,
[ProtoEnum]
Diona,
[ProtoEnum]
IPC
}
@ -29,17 +36,23 @@ namespace AuroraRecordGenerator
{
[ProtoEnum]
None = 0,
[ProtoEnum]
[ProtoEnum, SubspeciesMeta(SpeciesType.Tajara, "M'sai")]
MsaiTajara,
[ProtoEnum]
[ProtoEnum, SubspeciesMeta(SpeciesType.Tajara, "Zhan-Khazan")]
ZhanTajara,
[ProtoEnum]
[ProtoEnum, SubspeciesMeta(SpeciesType.Vaurca, "Type A (Worker)")]
VaurcaWorker,
[ProtoEnum]
[ProtoEnum, SubspeciesMeta(SpeciesType.Vaurca, "Type B (Warrior)")]
VaurcaWarrior,
[ProtoEnum]
[ProtoEnum, SubspeciesMeta(SpeciesType.IPC, "Shell Frame")]
IpcShell,
[ProtoEnum]
[ProtoEnum, SubspeciesMeta(SpeciesType.IPC, "Industrial Frame")]
IpcG1Industrial
}
@ -48,8 +61,10 @@ namespace AuroraRecordGenerator
{
[ProtoEnum]
NotApplicable = 0,
[ProtoEnum]
Male,
[ProtoEnum]
Female
}
@ -59,8 +74,20 @@ namespace AuroraRecordGenerator
/// <summary>
/// The current in-character date.
/// </summary>
public static DateTime IcDate => new DateTime(2458,
public static DateTime IcDate => new DateTime(DateTime.Now.Year + 442,
DateTime.Now.Month,
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
{
/// <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) =>
source.Split('\n').Where(item => item.Trim().Length != 0).ToList();
public static string CmToFeet(double cm)
{
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>
/// Returns <paramref name="val"/> and a trailing space if val is not whitespace, <see cref="string.Empty"/> otherwise.
@ -96,7 +39,7 @@ namespace AuroraRecordGenerator
public static string Repeat(this string target, int repeatNum)
{
var builder = new StringBuilder(target.Length*repeatNum);
var builder = new StringBuilder(target.Length * repeatNum);
for (var i = 0; i < repeatNum; i++)
builder.Append(target);
@ -113,23 +56,27 @@ namespace AuroraRecordGenerator
public static string SubspeciesNiceName(SpeciesSubType species)
{
switch (species)
{
case SpeciesSubType.MsaiTajara:
return "M'sai";
case SpeciesSubType.ZhanTajara:
return "Zhan-Khazan";
case SpeciesSubType.VaurcaWorker:
return "Worker (Type A)";
case SpeciesSubType.VaurcaBreeder:
return "Warrior (Type B)";
case SpeciesSubType.IpcShell:
return "Shell Frame";
case SpeciesSubType.IpcG1Industrial:
return "Industrial Frame";
default:
return Enum.GetName(typeof(SpeciesSubType), 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
{
/// <summary>
/// Gets an attribute on an enum field value
/// </summary>
/// <typeparam name="T">The type of the attribute you want to retrieve</typeparam>
/// <param name="enumVal">The enum value</param>
/// <returns>The attribute of type T that exists on the enum value</returns>
/// <example>string desc = myEnumVariable.GetAttributeOfType<DescriptionAttribute>().Description;</example>
public static T GetAttributeOfType<T>(this Enum enumVal) where T : Attribute
{
var type = enumVal.GetType();
var memInfo = type.GetMember(enumVal.ToString());
var attributes = memInfo[0].GetCustomAttributes(typeof(T), false);
return attributes.Length > 0 ? (T)attributes[0] : null;
}
}
}