2
0
mirror of https://github.com/9ParsonsB/Pulsar.git synced 2025-04-05 17:39:39 -04:00

Update Flag handling

Status now shows readable flag names
Updated Power display
Added more missing Journal events
This commit is contained in:
Ben Parsons 2024-05-16 23:39:16 +10:00
parent 2ac1a927ca
commit d4f3476ad3
5 changed files with 116 additions and 33 deletions

View File

@ -12,7 +12,6 @@ namespace Pulsar.Utils;
using Observatory.Framework.Files.Journal;
[Flags]
public enum JournalReaderState
{
@ -20,14 +19,17 @@ public enum JournalReaderState
/// Have read the first character of the object
/// </summary>
Start,
/// <summary>
/// Have read the timestamp. Generally the first property in a journal entry.
/// </summary>
Timestamp,
/// <summary>
/// have read the event name. Generally the second property in a journal entry.
/// </summary>
Event,
/// <summary>
/// Have read the last character of the object, the next character should be a newline, whitespace, EOF, or another object.
/// </summary>
@ -40,9 +42,10 @@ public enum JournalReaderState
/// all Journals can be deserialized into a JournalBase object for identification
/// and then deserialized into their respective types.
/// </summary>
public class JournalConverter(ILogger logger) : JsonConverter<JournalBase>
public class JournalConverter(ILogger<JournalConverter> logger) : JsonConverter<JournalBase>
{
private JournalReaderState state = JournalReaderState.Start;
public override JournalBase? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
Utf8JsonReader clone = reader;
@ -92,6 +95,7 @@ public class JournalConverter(ILogger logger) : JsonConverter<JournalBase>
// create destination type
return GetDestinationType(ref reader, eventName!);
}
break;
case JsonTokenType.Comment:
continue;
@ -108,7 +112,6 @@ public class JournalConverter(ILogger logger) : JsonConverter<JournalBase>
default:
throw new ArgumentOutOfRangeException();
}
} while (clone.Read());
return new() { Timestamp = timestamp!.Value, Event = eventName! };
@ -340,7 +343,20 @@ public class JournalConverter(ILogger logger) : JsonConverter<JournalBase>
return JsonSerializer.Deserialize<CommitCrime>(ref reader)!;
case "modulestore":
return JsonSerializer.Deserialize<ModuleStore>(ref reader)!;
case "factionkillbond":
return JsonSerializer.Deserialize<FactionKillBond>(ref reader)!;
case "rebootrepair":
return JsonSerializer.Deserialize<RebootRepair>(ref reader)!;
case "launchdrone":
return JsonSerializer.Deserialize<LaunchDrone>(ref reader)!;
case "sellmicroresources":
return JsonSerializer.Deserialize<SellMicroResources>(ref reader)!;
case "navbeaconscan":
return JsonSerializer.Deserialize<NavBeaconScan>(ref reader)!;
case "searchandrescue":
return JsonSerializer.Deserialize<SearchAndRescue>(ref reader)!;
case "marketsell":
return JsonSerializer.Deserialize<MarketSell>(ref reader)!;
default:
logger.LogWarning("Unknown Journal event type {EventName}", eventName);
return JsonSerializer.Deserialize<JournalBase>(ref reader)!;

View File

@ -2,9 +2,12 @@
import { onMount } from "svelte";
import { statusStore } from "./stores/Status.store";
import connection from "./stores/Connection.store";
import { StatusFlags, StatusFlags2 } from "../types/api/enums";
import { FocusStatus, StatusFlags, StatusFlags2 } from "../types/api/enums";
import type JournalBase from "../types/api/JournalBase";
import { slide } from "svelte/transition";
import { fly, scale, slide } from "svelte/transition";
import { getEnumFlags, getEnumNameFromValue, getEnumNamesFromFlag, getEnumPairsFromValue } from "../types/flags";
import type Status from "../types/api/Status";
import { HubConnectionState } from "@microsoft/signalr";
const x: string | null = $state(null);
@ -16,7 +19,11 @@
let alert: JournalBase[] = $state([]);
onMount(async () => {
if ($connection.state === HubConnectionState.Disconnected)
{
await $connection.start();
}
loading = false;
@ -36,9 +43,9 @@
change.push(last[i] - last[i - 1]);
}
const avg = change.reduce((a, b) => a + b, 0) / change.length;
const avg = change.length ? change.reduce((a, b) => a + b, 0) / change.length : 0;
const max = 32;
if ($statusStore.fuel?.fuelMain) {
if ($statusStore.fuel?.fuelMain && avg) {
timeToMax = (max - $statusStore.fuel?.fuelMain) / avg;
}
@ -57,9 +64,15 @@
});
if (!$statusStore.pips) {
statusStore.set(
await (await fetch("http://localhost:5000/api/status")).json()
);
const value = (await (
await fetch("http://localhost:5000/api/status")
).json()) as Status;
console.log(value);
statusStore.set({
...value,
});
}
});
</script>
@ -88,33 +101,33 @@
>
<div class="power">
<div class="sys">
{#each [...Array($statusStore?.pips?.sys ?? 0)] as sys}
<div class="pip" transition:slide></div>
{/each}
<div>{$statusStore?.pips?.sys ?? "?"}</div>
<div>Sys</div>
{#each [...Array($statusStore?.pips?.sys ?? 0)].map((_,i) => i) as sys (sys)}
<div class="pip" transition:scale|global ></div>
{/each}
</div>
<div class="eng">
{#each [...Array($statusStore?.pips?.eng ?? 0)] as eng}
<div class="pip" transition:slide></div>
{/each}
<div>{$statusStore?.pips?.eng ?? "?"}</div>
<div>Eng</div>
{#each [...Array($statusStore?.pips?.eng ?? 0)].map((_,i) => i) as eng (eng)}
<div class="pip" transition:scale|global></div>
{/each}
</div>
<div class="wep">
{#each [...Array($statusStore?.pips?.wep ?? 0)] as wep}
<div class="pip" transition:slide></div>
{/each}
<div>{$statusStore?.pips?.wep ?? "?"}</div>
<div>Wep</div>
{#each [...Array($statusStore?.pips?.wep ?? 0)].map((_,i) => i) as wep (wep)}
<div class="pip" transition:scale|global></div>
{/each}
</div>
</div>
<span>dest?: {$statusStore?.destination?.name}</span>
<span>gui focus: {$statusStore.guiFocus}</span>
<span>gui focus: {getEnumNameFromValue(FocusStatus, $statusStore.guiFocus!)}</span>
<span>cargo: {$statusStore.cargo}</span>
<span>flag1: {$statusStore.flags}</span>
<span>flag2: {$statusStore.flags2}</span>
<span>flag1: {getEnumNamesFromFlag(StatusFlags, $statusStore.flags!)}</span>
<span>flag2: {getEnumNamesFromFlag(StatusFlags2, $statusStore.flags2!)}</span>
{:else}
<span>No data :(</span>
{/if}
@ -133,7 +146,7 @@
div {
display: flex;
height: 100%;
flex-direction: column;
flex-direction: column-reverse;
align-items: center;
div.pip {
min-width: 2vw;

View File

@ -1,5 +1,6 @@
export enum StatusFlags {
Docked = 1,
None = 0,
Docked = 1 << 0,
Landed = 1 << 1,
LandingGear = 1 << 2,
Shields = 1 << 3,
@ -34,7 +35,8 @@ export enum StatusFlags {
}
export enum StatusFlags2 {
OnFoot = 1,
None = 0,
OnFoot = 1 << 0,
InTaxi = 1 << 1,
InMulticrew = 1 << 2,
OnFootInStation = 1 << 3,

View File

@ -0,0 +1,52 @@
const isPowerOfTwo = (x: number): boolean => {
return x !== 0 && (x & (x - 1)) === 0;
};
/***
* returns all possible flags for an enum
* @param obj the Enum type
*/
export function getEnumFlags<
O extends object,
F extends O[keyof O] = O[keyof O],
>(obj: O): [number, string][] {
const isFlag = (arg: string | number | F): arg is F => {
const nArg = Number(arg);
const isNumber = !Number.isNaN(nArg);
return isNumber && isPowerOfTwo(nArg);
};
if (!obj) return [];
return Object.entries(obj)
.filter((k) => Number.parseInt(k[0]))
.map((k) => [Number(k[0]), k[1]]);
}
export function getEnumPairsFromValue<E extends object>(e: E, flag: number) {
const flags = getEnumFlags(e);
const active = [];
for (const f of flags) {
if (f[0] & flag) active.push(f[1]);
}
return active;
}
export function getEnumNamesFromFlag<E extends Record<number, string>>(
e: E,
flag: number,
) {
const flags = getEnumFlags(e);
const active = [];
for (const f of flags) {
if (f[0] & flag) active.push(e[f[0]]);
}
return active;
}
export function getEnumNameFromValue<E extends Record<number, string>>(
e: E,
value: number,
) {
return e[value];
}