Complete legacy operator UI and playout migration
This commit is contained in:
@@ -14,7 +14,10 @@ internal static class LegacySceneRuntimeFactory
|
||||
public static LegacyPlayoutWorkflow Create(
|
||||
IPlayoutEngine engine,
|
||||
IDataQueryExecutor executor,
|
||||
LegacySceneCueCompositionOptions? compositionOptions = null)
|
||||
LegacySceneCueCompositionOptions? compositionOptions = null,
|
||||
ILegacySceneCueCompositionOptionsSource? compositionOptionsSource = null,
|
||||
IS5025TrustedManualDataSource? trustedManualSource = null,
|
||||
ITrustedViStockNameSnapshotSource? trustedViSource = null)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(engine);
|
||||
ArgumentNullException.ThrowIfNull(executor);
|
||||
@@ -50,12 +53,14 @@ internal static class LegacySceneRuntimeFactory
|
||||
var salesLoader = new S5080SceneDataLoader(executor);
|
||||
var participantTrendLoader = new S5083SceneDataLoader(executor);
|
||||
var indexTrendLoader = new S5084SceneDataLoader(executor);
|
||||
var manualDataDirectory = Environment.GetEnvironmentVariable(
|
||||
S5025TrustedManualFileDataSource.DirectoryEnvironmentVariable);
|
||||
IS5025TrustedManualDataSource? trustedManualSource =
|
||||
string.IsNullOrWhiteSpace(manualDataDirectory)
|
||||
if (trustedManualSource is null)
|
||||
{
|
||||
var manualDataDirectory = Environment.GetEnvironmentVariable(
|
||||
S5025TrustedManualFileDataSource.DirectoryEnvironmentVariable);
|
||||
trustedManualSource = string.IsNullOrWhiteSpace(manualDataDirectory)
|
||||
? null
|
||||
: new S5025TrustedManualFileDataSource(manualDataDirectory);
|
||||
}
|
||||
var gridMarketRequestResolver = new LegacyGridMarketSceneRequestResolver(
|
||||
executor,
|
||||
trustedManualSource);
|
||||
@@ -334,6 +339,10 @@ internal static class LegacySceneRuntimeFactory
|
||||
RequireFirstPage(page);
|
||||
var selection = RequireSelection(entry);
|
||||
var target = ParseCandleMarket(selection.GroupCode);
|
||||
var foreignIdentity = target is
|
||||
CandleMarketTarget.OverseasIndex or CandleMarketTarget.OverseasStock
|
||||
? ParseForeignCandleIdentity(selection.DataCode, target)
|
||||
: default;
|
||||
var request = new S8010SceneDataRequest(
|
||||
ParseCandleAlias(entry.CutCode),
|
||||
target,
|
||||
@@ -342,7 +351,9 @@ internal static class LegacySceneRuntimeFactory
|
||||
? RequireLookupValue(selection.Subject, "instrument")
|
||||
: null,
|
||||
HasClosedFlag(selection.GraphicType, "MA5"),
|
||||
HasClosedFlag(selection.GraphicType, "MA20"));
|
||||
HasClosedFlag(selection.GraphicType, "MA20"),
|
||||
foreignIdentity.Symbol,
|
||||
foreignIdentity.NationCode);
|
||||
var data = await candleLoader.LoadAsync(
|
||||
request,
|
||||
cancellationToken).ConfigureAwait(false);
|
||||
@@ -350,10 +361,30 @@ internal static class LegacySceneRuntimeFactory
|
||||
}),
|
||||
new LegacySceneDataSourceRoute(["5074"], async (entry, page, cancellationToken) =>
|
||||
{
|
||||
var request = CreatePagedQuoteRequest(RequireSelection(entry), page);
|
||||
var selection = RequireSelection(entry);
|
||||
var request = selection.GroupCode == "PAGED_VI"
|
||||
? await TrustedViManualReference.ResolveAsync(
|
||||
selection,
|
||||
page,
|
||||
trustedViSource,
|
||||
cancellationToken).ConfigureAwait(false)
|
||||
: CreatePagedQuoteRequest(selection, page);
|
||||
var data = await fiveRowLoader.LoadAsync(request, cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
return new LegacySceneDataPage("s5074", data, data.Rows.Count);
|
||||
}, async (entry, cancellationToken) =>
|
||||
{
|
||||
var selection = RequireSelection(entry);
|
||||
var request = selection.GroupCode == "PAGED_VI"
|
||||
? await TrustedViManualReference.ResolveAsync(
|
||||
selection,
|
||||
pageIndexZeroBased: 0,
|
||||
trustedSource: trustedViSource,
|
||||
cancellationToken: cancellationToken).ConfigureAwait(false)
|
||||
: CreatePagedQuoteRequest(selection, 0);
|
||||
var data = await fiveRowLoader.LoadPagePlanAsync(request, cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
return new LegacySceneDataPage("s5074", data, data.Rows.Count);
|
||||
}),
|
||||
new LegacySceneDataSourceRoute(["5077"], async (entry, page, cancellationToken) =>
|
||||
{
|
||||
@@ -361,6 +392,12 @@ internal static class LegacySceneRuntimeFactory
|
||||
var data = await sixRowLoader.LoadAsync(request, cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
return new LegacySceneDataPage("s5077", data, data.Rows.Count);
|
||||
}, async (entry, cancellationToken) =>
|
||||
{
|
||||
var request = CreatePagedQuoteRequest(RequireSelection(entry), 0);
|
||||
var data = await sixRowLoader.LoadPagePlanAsync(request, cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
return new LegacySceneDataPage("s5077", data, data.Rows.Count);
|
||||
}),
|
||||
new LegacySceneDataSourceRoute(["5088"], async (entry, page, cancellationToken) =>
|
||||
{
|
||||
@@ -368,13 +405,25 @@ internal static class LegacySceneRuntimeFactory
|
||||
var data = await twelveRowLoader.LoadAsync(request, cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
return new LegacySceneDataPage("s5088", data, data.Rows.Count);
|
||||
}, async (entry, cancellationToken) =>
|
||||
{
|
||||
var request = CreatePagedQuoteRequest(RequireSelection(entry), 0);
|
||||
var data = await twelveRowLoader.LoadPagePlanAsync(request, cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
return new LegacySceneDataPage("s5088", data, data.Rows.Count);
|
||||
})
|
||||
]);
|
||||
|
||||
LegacySceneRuntimeCoverage.Validate(dataSource);
|
||||
var cueProvider = new RegisteredLegacySceneCueProvider(
|
||||
dataSource,
|
||||
options: compositionOptions);
|
||||
if (compositionOptions is not null && compositionOptionsSource is not null)
|
||||
{
|
||||
throw new ArgumentException(
|
||||
"Specify either fixed or mutable scene composition options, not both.");
|
||||
}
|
||||
|
||||
var cueProvider = compositionOptionsSource is null
|
||||
? new RegisteredLegacySceneCueProvider(dataSource, options: compositionOptions)
|
||||
: new RegisteredLegacySceneCueProvider(dataSource, compositionOptionsSource);
|
||||
return new LegacyPlayoutWorkflow(engine, cueProvider);
|
||||
}
|
||||
|
||||
@@ -448,6 +497,34 @@ internal static class LegacySceneRuntimeFactory
|
||||
CandleMarketTarget.KospiStock or
|
||||
CandleMarketTarget.KosdaqStock;
|
||||
|
||||
private static (string? Symbol, string? NationCode) ParseForeignCandleIdentity(
|
||||
string value,
|
||||
CandleMarketTarget target)
|
||||
{
|
||||
var parts = value.Split('|', StringSplitOptions.None);
|
||||
var expectedType = target switch
|
||||
{
|
||||
CandleMarketTarget.OverseasIndex => "0",
|
||||
CandleMarketTarget.OverseasStock => "1",
|
||||
_ => throw new LegacySceneDataException(
|
||||
"The foreign candle target is invalid.")
|
||||
};
|
||||
if (parts.Length != 3 ||
|
||||
parts[0].Length is < 1 or > 64 ||
|
||||
parts[0].Any(character => char.IsControl(character) || char.IsSurrogate(character)) ||
|
||||
parts[1].Length != 2 ||
|
||||
parts[1].Any(character => character is < 'A' or > 'Z') ||
|
||||
!string.Equals(parts[2], expectedType, StringComparison.Ordinal) ||
|
||||
target == CandleMarketTarget.OverseasStock &&
|
||||
parts[1] is not ("US" or "TW"))
|
||||
{
|
||||
throw new LegacySceneDataException(
|
||||
"The foreign candle identity is invalid.");
|
||||
}
|
||||
|
||||
return (parts[0], parts[1]);
|
||||
}
|
||||
|
||||
private static string RequireLookupValue(string value, string label)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(value))
|
||||
@@ -500,6 +577,7 @@ internal static class LegacySceneRuntimeFactory
|
||||
ParseNxtSession(selection.GraphicType),
|
||||
page),
|
||||
"PAGED_EXPERT" => new ExpertPagedQuoteLoadRequest(
|
||||
RequireLookupValue(selection.DataCode, "expert code"),
|
||||
RequireLookupValue(selection.Subject, "expert"),
|
||||
page),
|
||||
"PAGED_VI" => new ViPagedQuoteLoadRequest(
|
||||
|
||||
Reference in New Issue
Block a user