1070 lines
44 KiB
C#
1070 lines
44 KiB
C#
using Simulator.Data;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using Unity.VisualScripting;
|
|
using UnityEngine;
|
|
using UnityEngine.Windows;
|
|
using UVC.UI.Window.PropertyWindow;
|
|
using static Unity.VisualScripting.Member;
|
|
|
|
public class ProcessorProperty : MonoBehaviour
|
|
{
|
|
[SerializeField]
|
|
private PropertyWindow propertyWindow;
|
|
|
|
ProcessorDataClass processor;
|
|
private void Awake()
|
|
{
|
|
propertyWindow.PropertyValueChanged += OnPropertyValueChanged;
|
|
}
|
|
|
|
public void SetProertyWindow(ComponentType type, ComponentDataBase data)
|
|
{
|
|
Debug.Log(data);
|
|
switch (type)
|
|
{
|
|
case ComponentType.Processor:
|
|
processor = data as ProcessorDataClass;
|
|
InitProcessorProperty(data as ProcessorDataClass);
|
|
break;
|
|
}
|
|
}
|
|
|
|
void SaveChange(object source, object value, string name)
|
|
{
|
|
var path = PathIndexer.GetNodePath(source);
|
|
Patch updateData = new Patch();
|
|
updateData.value = value;
|
|
UpdateValueStack.AddPatch($"{path}.{name}", value);
|
|
}
|
|
|
|
public void InitProcessorProperty(ProcessorDataClass processor)
|
|
{
|
|
var entries = new List<IPropertyEntry>();
|
|
|
|
entries.Add(new StringProperty("name", "이름", processor.name) { IsReadOnly = true });
|
|
|
|
entries.Add(
|
|
new StringProperty("label", "라벨", processor.label) { IsReadOnly = false }
|
|
.Bind(setter: v => { processor.label = v; SaveChange(processor, v, "label"); })
|
|
);
|
|
|
|
entries.Add(CreatePositionGroup(processor));
|
|
|
|
entries.Add(
|
|
new ListProperty("processing_type", "처리 유형",
|
|
new List<string>() { "combine", "seperate", "transform" }, processor.processor_type)
|
|
{ IsReadOnly = false }
|
|
.Bind(setter: v => { processor.processor_type = v; SaveChange(processor, v, "processing_type"); })
|
|
);
|
|
|
|
entries.Add(
|
|
new ListProperty("input_selection_policy", "투입 정책",
|
|
new List<string>() { "round_robin", "random" }, processor.input_selection_policy)
|
|
{ IsReadOnly = false }
|
|
.Bind(setter: v => { processor.input_selection_policy = v; SaveChange(processor, v, "input_selection_policy"); })
|
|
);
|
|
entries.Add(CreateInputPrefabToggleGroup(processor));
|
|
|
|
foreach (var prefab in PrefabManager.Instance.prefabDict.Keys)
|
|
entries.Add(CreateInputPrefabDetailGroup(processor, prefab));
|
|
|
|
entries.Add(
|
|
new ListProperty("output_selection_policy", "출고 정책",
|
|
new List<string>() { "round_robin", "random" }, processor.output_selection_policy)
|
|
{ IsReadOnly = false }
|
|
.Bind(setter: v => { processor.output_selection_policy = v; SaveChange(processor, v, "output_selection_policy"); })
|
|
);
|
|
|
|
entries.Add(CreateOutputPrefabToggleGroup(processor));
|
|
|
|
foreach (var prefab in PrefabManager.Instance.prefabDict.Keys)
|
|
entries.Add(CreateOutputPrefabDetailGroup(processor, prefab));
|
|
|
|
entries.Add(new EnumProperty("display_mode_ProcessingTimePolicy", "처리 시간 정책", processor.processing_time_policy.policy).Bind(
|
|
setter: v =>
|
|
{
|
|
processor.processing_time_policy = PolicyFactory.Create(v.ToString()); SaveChange(processor, v.ToString(), "processing_time_policy.type");
|
|
}));
|
|
entries.Add(CreateProcessingTimePolicy_Constant(processor));
|
|
entries.Add(CreateProcessingTimePolicy_Normal(processor));
|
|
entries.Add(CreateProcessingTimePolicy_Uniform(processor));
|
|
entries.Add(CreateProcessingTimePolicy_Exponential(processor));
|
|
entries.Add(CreateProcessingTimePolicy_Triangular(processor));
|
|
|
|
entries.Add(BuildOutputTagChanges());
|
|
entries.Add(new ListProperty("outputTagType_string", "", new List<string> { "set" }, "set"));
|
|
entries.Add(new StringProperty("outputTagValue_string", "", ""));
|
|
entries.Add(new ListProperty("outputTagType_number", "", new List<string> { "set", "increment", "decrement" }, "값 설정"));
|
|
entries.Add(new IntProperty("outputTagValue_number", "", 0));
|
|
entries.Add(new ButtonProperty("AddTagChangeButton", "태그 변경 추가", "").BindClick(SaveOutputTag));
|
|
entries.Add(CreateOutputTags(processor));
|
|
|
|
|
|
entries.Add(new EnumProperty("display_mode_ReadyTimePolicy", "준비 시간 정책", processor.ready_time_policy.policy).Bind(
|
|
setter: v =>
|
|
{
|
|
processor.ready_time_policy = PolicyFactory.Create(v.ToString()); SaveChange(processor, v.ToString(), "ready_time_policy.type");
|
|
}));
|
|
entries.Add(CreateReadyTimePolicy_Constant(processor));
|
|
entries.Add(CreateReadyTimePolicy_Normal(processor));
|
|
entries.Add(CreateReadyTimePolicy_Uniform(processor));
|
|
entries.Add(CreateReadyTimePolicy_Exponential(processor));
|
|
entries.Add(CreateReadyTimePolicy_Triangular(processor));
|
|
|
|
entries.Add(new EnumProperty("display_mode_DefectTimePolicy", "불량률 정책", processor.defect_rate_policy.policy).Bind(
|
|
setter: v =>
|
|
{
|
|
processor.defect_rate_policy = PolicyFactory.Create(v.ToString()); SaveChange(processor, v.ToString(), "defect_rate_policy.type");
|
|
}));
|
|
entries.Add(CreateDefectRatePolicy_Constant(processor));
|
|
entries.Add(CreateDefectRatePolicy_Normal(processor));
|
|
entries.Add(CreateDefectRatePolicy_Uniform(processor));
|
|
entries.Add(CreateDefectRatePolicy_Exponential(processor));
|
|
entries.Add(CreateDefectRatePolicy_Triangular(processor));
|
|
|
|
entries.Add(CreateRequireResourceGroup(processor));
|
|
|
|
entries.Add(new BoolProperty("fms_input_enabled", "입력에 FMS 사용", processor.fms_input_enabled) { IsReadOnly = true });
|
|
entries.Add(new BoolProperty("fms_output_enabled", "출력에 FMS 사용", processor.fms_output_enabled) { IsReadOnly = true });
|
|
|
|
propertyWindow.LoadMixedProperties(entries);
|
|
|
|
HandleDisplayModeChanged_ProcessingTimePolicy(processor.processing_time_policy.policy.ToString());
|
|
HandleDisplayModeChanged_ReadyTimePolicy(processor.ready_time_policy.policy.ToString());
|
|
HandleDisplayModeChanged_DefectRatePolicy(processor.defect_rate_policy.policy.ToString());
|
|
SyncInputPrefabDetailVisibility(processor);
|
|
SyncOutputPrefabDetailVisibility(processor);
|
|
SyncOutputTagType(ComponentsManager.webconfigData.tags[0].type);
|
|
}
|
|
|
|
private void OnPropertyValueChanged(object sender, PropertyValueChangedEventArgs e)
|
|
{
|
|
// 동적 그룹 표시/비표시 테스트
|
|
if (e.PropertyId == "display_mode_ProcessingTimePolicy")
|
|
{
|
|
string selectedMode = e.NewValue.ToString();
|
|
HandleDisplayModeChanged_ProcessingTimePolicy(selectedMode);
|
|
}
|
|
if (e.PropertyId == "display_mode_ReadyTimePolicy")
|
|
{
|
|
string selectedMode = e.NewValue.ToString();
|
|
HandleDisplayModeChanged_ReadyTimePolicy(selectedMode);
|
|
}
|
|
if (e.PropertyId == "display_mode_DefectPolicy")
|
|
{
|
|
string selectedMode = e.NewValue.ToString();
|
|
HandleDisplayModeChanged_DefectRatePolicy(selectedMode);
|
|
}
|
|
if (e.PropertyId == "input_selection_policy")
|
|
{
|
|
SyncInputPrefabDetailVisibility(processor);
|
|
}
|
|
if (e.PropertyId == "output_selection_policy")
|
|
{
|
|
SyncOutputPrefabDetailVisibility(processor);
|
|
}
|
|
}
|
|
|
|
private PropertyGroup CreatePositionGroup(ProcessorDataClass processor)
|
|
{
|
|
var group = new PropertyGroup("processor_position", "위치 및 회전", isExpanded: true);
|
|
group.AddItems(new IPropertyItem[]
|
|
{
|
|
new FloatProperty("x_position", "X 좌표(m)", processor.physical.position.x)
|
|
{
|
|
}.Bind(
|
|
setter: v => {processor.physical.position.x = v;SaveChange(processor,v,"physical.position.x"); }
|
|
),
|
|
new FloatProperty("y_position", "y 좌표(m)", processor.physical.position.y)
|
|
{
|
|
}.Bind(
|
|
setter: v => {processor.physical.position.y = v;SaveChange(processor,v,"physical.position.y"); }
|
|
),
|
|
new FloatProperty("orientation", "회전(°)", processor.physical.orientation)
|
|
{
|
|
}.Bind(
|
|
setter: v => {processor.physical.orientation = v;SaveChange(processor,v,"physical.orientation");propertyWindow.ApplyExternalValue("orientation",RotationSnap.snaporientaion(v),false); }
|
|
),
|
|
});
|
|
return group;
|
|
}
|
|
|
|
#region
|
|
|
|
public ListProperty BuildOutputTagChanges()
|
|
{
|
|
List<string> tagKeyList = new List<string>();
|
|
foreach (var tag in ComponentsManager.webconfigData.tags)
|
|
{
|
|
tagKeyList.Add(tag.key);
|
|
}
|
|
var property = new ListProperty("output_tag_keys", "처리 완료 태그 설정", tagKeyList, tagKeyList[0]);
|
|
property.Bind(setter: v => { SyncOutputTagType(ComponentsManager.webconfigData.tags.Find(tag => tag.key == v).type); });
|
|
return property;
|
|
}
|
|
|
|
public PropertyGroup CreateOutputTags(ProcessorDataClass processor)
|
|
{
|
|
var group = new PropertyGroup("output_tags", "", isExpanded: true);
|
|
foreach (var tag in processor.output_tag_changes)
|
|
{
|
|
var property = new ChangeTagProperty($"tag{tag.key}", tag.key, tag.operation, tag.value.ToString());
|
|
property.BindClick(() => { processor.output_tag_changes.Remove(tag); SaveChange(processor, processor.output_tag_changes, "output_tag_changes"); InitProcessorProperty(processor); });
|
|
property.Bind(setter: v => { tag.value = v; SaveChange(tag, v, "value"); });
|
|
group.AddItem(property);
|
|
}
|
|
return group;
|
|
}
|
|
|
|
public void SyncOutputTagType(string tagType)
|
|
{
|
|
propertyWindow.SetPropertyVisibility("outputTagType_string", false);
|
|
propertyWindow.SetPropertyVisibility("outputTagValue_string", false);
|
|
propertyWindow.SetPropertyVisibility("outputTagType_number", false);
|
|
propertyWindow.SetPropertyVisibility("outputTagValue_number", false);
|
|
propertyWindow.SetPropertyVisibility("AddTagChangeButton", false);
|
|
switch (tagType)
|
|
{
|
|
case "string":
|
|
propertyWindow.SetPropertyVisibility("outputTagType_string", true);
|
|
propertyWindow.SetPropertyVisibility("outputTagValue_string", true);
|
|
propertyWindow.SetPropertyVisibility("outputTagType_number", false);
|
|
propertyWindow.SetPropertyVisibility("outputTagValue_number", false);
|
|
propertyWindow.SetPropertyVisibility("AddTagChangeButton", true);
|
|
break;
|
|
case "number":
|
|
propertyWindow.SetPropertyVisibility("outputTagType_string", false);
|
|
propertyWindow.SetPropertyVisibility("outputTagValue_string", false);
|
|
propertyWindow.SetPropertyVisibility("outputTagType_number", true);
|
|
propertyWindow.SetPropertyVisibility("outputTagValue_number", true);
|
|
propertyWindow.SetPropertyVisibility("AddTagChangeButton", true);
|
|
break;
|
|
}
|
|
}
|
|
|
|
public void SaveOutputTag()
|
|
{
|
|
string key = propertyWindow.GetProperty("output_tag_keys").GetValue() as string;
|
|
string operation = "";
|
|
object value = null;
|
|
if (processor.output_tag_changes.Exists(x => x != null && x.key == key))
|
|
{
|
|
Debug.LogWarning($"이미 '{key}' 태그가 존재합니다.");
|
|
return;
|
|
}
|
|
var tagtype = ComponentsManager.webconfigData.tags?.Find(t => t.key == key);
|
|
|
|
switch (tagtype.type)
|
|
{
|
|
case "string":
|
|
operation = propertyWindow.GetProperty("outputTagType_string").GetValue() as string;
|
|
value = propertyWindow.GetProperty("outputTagValue_string").GetValue();
|
|
break;
|
|
case "number":
|
|
operation = propertyWindow.GetProperty("outputTagValue_number").GetValue() as string;
|
|
value = propertyWindow.GetProperty("outputTagValue_number").GetValue();
|
|
break;
|
|
}
|
|
processor.output_tag_changes.Add(new output_tag_changes_base
|
|
{
|
|
key = key,
|
|
operation = operation,
|
|
value = value,
|
|
});
|
|
SaveChange(processor, processor.output_tag_changes, "output_tag_changes");
|
|
InitProcessorProperty(processor);
|
|
}
|
|
#endregion
|
|
|
|
#region 투입개체
|
|
private PropertyGroup CreateInputPrefabToggleGroup(ProcessorDataClass processor)
|
|
{
|
|
var group = new PropertyGroup("InputPrefab", "투입 개체", isExpanded: true);
|
|
|
|
foreach (var prefab in PrefabManager.Instance.prefabDict.Keys)
|
|
{
|
|
bool enabled = processor.inputs != null && processor.inputs.Exists(x => x.prefab == prefab);
|
|
|
|
string itemId = $"input_prefab.toggle.{prefab}";
|
|
string detailGroupId = GetInputPrefabDetailGroupId(prefab);
|
|
|
|
var toggle = new BoolProperty($"input_{itemId}", prefab, enabled)
|
|
.Bind(setter: v =>
|
|
{
|
|
if (v) EnsureInputPrefab(processor, prefab);
|
|
else RemoveInputPrefab(processor, prefab);
|
|
|
|
SaveChange(processor, processor.inputs, "inputs");
|
|
InitProcessorProperty(processor);
|
|
});
|
|
|
|
group.AddItem(toggle);
|
|
}
|
|
|
|
return group;
|
|
}
|
|
|
|
private static string GetInputPrefabDetailGroupId(string prefabKey)
|
|
=> $"InputPrefabDetail.{prefabKey}";
|
|
|
|
private PropertyGroup CreateInputPrefabDetailGroup(ProcessorDataClass processor, string prefabKey)
|
|
{
|
|
string groupId = GetInputPrefabDetailGroupId(prefabKey);
|
|
var group = new PropertyGroup(groupId, $"{prefabKey} 연결", isExpanded: true);
|
|
|
|
var entry = GetInputEntry(processor, prefabKey);
|
|
|
|
if (entry == null)
|
|
{
|
|
group.AddItem(new StringProperty($"{groupId}.empty", "연결", "투입 개체가 선택되지 않았습니다.")
|
|
{
|
|
IsReadOnly = true
|
|
});
|
|
return group;
|
|
}
|
|
|
|
entry.locations ??= new List<Prefab_location>();
|
|
|
|
string totalId = $"{groupId}.total_count";
|
|
var totalProp = new IntProperty(
|
|
totalId,
|
|
"총 개수",
|
|
entry.total_count
|
|
)
|
|
.Bind(setter: v =>
|
|
{
|
|
entry.total_count = v;
|
|
SaveChange(processor, entry.total_count, $"inputs[{prefabKey}].total_count");
|
|
});
|
|
|
|
group.AddItem(totalProp);
|
|
|
|
if (entry.locations.Count == 0)
|
|
{
|
|
group.AddItem(new StringProperty($"{groupId}.no_locs", "연결", "연결된 항목이 없습니다.")
|
|
{
|
|
IsReadOnly = true
|
|
});
|
|
return group;
|
|
}
|
|
|
|
foreach (var loc in entry.locations)
|
|
{
|
|
string locId = $"{groupId}.count.{loc.target}";
|
|
|
|
var countProp = new IntProperty(
|
|
locId,
|
|
loc.target,
|
|
Mathf.Max(0, loc.count),
|
|
isSlider: false,
|
|
minValue: 0,
|
|
maxValue: 9999
|
|
)
|
|
.Bind(setter: v =>
|
|
{
|
|
loc.count = Mathf.Max(0, v);
|
|
SaveChange(processor, loc.count, $"inputs[{prefabKey}].locations[target={loc.target}].count");
|
|
});
|
|
|
|
group.AddItem(countProp);
|
|
}
|
|
|
|
return group;
|
|
}
|
|
|
|
private void EnsureInputPrefab(ProcessorDataClass processor, string prefabKey)
|
|
{
|
|
processor.inputs ??= new List<Prefab_Data>();
|
|
|
|
if (processor.inputs.Exists(x => x.prefab == prefabKey))
|
|
return;
|
|
|
|
var locations = new List<Prefab_location>();
|
|
var workbench = ComponentsManager.webconfigData.property.Processor.workbench.Find(x => x.name == processor.name);
|
|
var input = workbench.input_items.Find(x => x.prefab == prefabKey);
|
|
if (input != null)
|
|
{
|
|
foreach (var location in input.locationCounts)
|
|
{
|
|
var prefablocation = new Prefab_location();
|
|
prefablocation.type = location.type;
|
|
prefablocation.count = location.count;
|
|
prefablocation.target = location.location;
|
|
locations.Add(prefablocation);
|
|
}
|
|
}
|
|
processor.inputs.Add(new Prefab_Data
|
|
{
|
|
prefab = prefabKey,
|
|
locations = locations,
|
|
total_count = 0
|
|
});
|
|
}
|
|
|
|
private void RemoveInputPrefab(ProcessorDataClass processor, string prefabKey)
|
|
{
|
|
if (processor.inputs == null) return;
|
|
|
|
int idx = processor.inputs.FindIndex(x => x.prefab == prefabKey);
|
|
if (idx >= 0) processor.inputs.RemoveAt(idx);
|
|
}
|
|
|
|
private Prefab_Data GetInputEntry(ProcessorDataClass processor, string prefabKey)
|
|
{
|
|
if (processor.inputs == null) return null;
|
|
return processor.inputs.Find(x => x.prefab == prefabKey);
|
|
}
|
|
|
|
private void SyncInputPrefabDetailVisibility(ProcessorDataClass processor)
|
|
{
|
|
bool isRandom = string.Equals(processor.input_selection_policy, "random", StringComparison.OrdinalIgnoreCase);
|
|
|
|
foreach (var prefabKey in PrefabManager.Instance.prefabDict.Keys)
|
|
{
|
|
bool enabled = processor.inputs != null && processor.inputs.Exists(x => x != null && x.prefab == prefabKey);
|
|
|
|
string groupId = GetInputPrefabDetailGroupId(prefabKey);
|
|
|
|
propertyWindow.SetGroupVisibility(groupId, enabled);
|
|
|
|
if (!enabled)
|
|
continue;
|
|
|
|
var entry = GetInputEntry(processor, prefabKey);
|
|
|
|
string totalId = $"{groupId}.total_count";
|
|
if (propertyWindow.GetProperty(totalId) != null)
|
|
propertyWindow.SetPropertyVisibility(totalId, isRandom);
|
|
|
|
if (entry?.locations != null)
|
|
{
|
|
foreach (var loc in entry.locations)
|
|
{
|
|
string locId = $"{groupId}.count.{loc.target}";
|
|
if (propertyWindow.GetProperty(locId) != null)
|
|
propertyWindow.SetPropertyVisibility(locId, !isRandom);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region 출고개체
|
|
private PropertyGroup CreateOutputPrefabToggleGroup(ProcessorDataClass processor)
|
|
{
|
|
var group = new PropertyGroup("OutputPrefab", "출고 개체", isExpanded: true);
|
|
|
|
foreach (var prefab in PrefabManager.Instance.prefabDict.Keys)
|
|
{
|
|
bool enabled = processor.outputs != null && processor.outputs.Exists(x => x.prefab == prefab);
|
|
|
|
string itemId = $"output_prefab.toggle.{prefab}";
|
|
string detailGroupId = GetOutputPrefabDetailGroupId(prefab);
|
|
|
|
var toggle = new BoolProperty($"output_{itemId}", prefab, enabled)
|
|
.Bind(setter: v =>
|
|
{
|
|
if (v) EnsureOutputPrefab(processor, prefab);
|
|
else RemoveOutputPrefab(processor, prefab);
|
|
|
|
SaveChange(processor, processor.outputs, "outputs");
|
|
InitProcessorProperty(processor);
|
|
});
|
|
|
|
group.AddItem(toggle);
|
|
}
|
|
|
|
return group;
|
|
}
|
|
|
|
private static string GetOutputPrefabDetailGroupId(string prefabKey)
|
|
=> $"OutputPrefabDetail.{prefabKey}";
|
|
|
|
private PropertyGroup CreateOutputPrefabDetailGroup(ProcessorDataClass processor, string prefabKey)
|
|
{
|
|
string groupId = GetOutputPrefabDetailGroupId(prefabKey);
|
|
var group = new PropertyGroup(groupId, $"{prefabKey} 연결", isExpanded: true);
|
|
|
|
var entry = GetOutputEntry(processor, prefabKey);
|
|
|
|
if (entry == null)
|
|
{
|
|
group.AddItem(new StringProperty($"{groupId}.empty", "연결", "투입 개체가 선택되지 않았습니다.")
|
|
{
|
|
IsReadOnly = true
|
|
});
|
|
return group;
|
|
}
|
|
|
|
entry.locations ??= new List<Prefab_location>();
|
|
|
|
string totalId = $"{groupId}.total_count";
|
|
var totalProp = new IntProperty(
|
|
totalId,
|
|
"총 개수",
|
|
Mathf.Max(0, entry.total_count),
|
|
isSlider: false,
|
|
minValue: 0,
|
|
maxValue: 9999
|
|
)
|
|
.Bind(setter: v =>
|
|
{
|
|
entry.total_count = Mathf.Max(0, v);
|
|
SaveChange(processor, entry.total_count, $"outputs[{prefabKey}].total_count");
|
|
});
|
|
|
|
group.AddItem(totalProp);
|
|
|
|
if (entry.locations.Count == 0)
|
|
{
|
|
group.AddItem(new StringProperty($"{groupId}.no_locs", "연결", "연결된 항목이 없습니다.")
|
|
{
|
|
IsReadOnly = true
|
|
});
|
|
return group;
|
|
}
|
|
|
|
foreach (var loc in entry.locations)
|
|
{
|
|
string locId = $"{groupId}.count.{loc.target}";
|
|
|
|
var countProp = new IntProperty(
|
|
locId,
|
|
loc.target,
|
|
loc.count
|
|
)
|
|
.Bind(setter: v =>
|
|
{
|
|
loc.count = v;
|
|
SaveChange(processor, loc.count, $"outputs[{prefabKey}].locations[target={loc.target}].count");
|
|
});
|
|
|
|
group.AddItem(countProp);
|
|
}
|
|
|
|
return group;
|
|
}
|
|
|
|
private void EnsureOutputPrefab(ProcessorDataClass processor, string prefabKey)
|
|
{
|
|
processor.outputs ??= new List<Prefab_Data>();
|
|
|
|
if (processor.outputs.Exists(x => x.prefab == prefabKey))
|
|
return;
|
|
|
|
var locations = new List<Prefab_location>();
|
|
var workbench = ComponentsManager.webconfigData.property.Processor.workbench.Find(x => x.name == processor.name);
|
|
var output = workbench.output_items.Find(x => x.prefab == prefabKey);
|
|
if (output != null)
|
|
{
|
|
foreach (var location in output.locationCounts)
|
|
{
|
|
var prefablocation = new Prefab_location();
|
|
prefablocation.type = location.type;
|
|
prefablocation.count = location.count;
|
|
prefablocation.target = location.location;
|
|
locations.Add(prefablocation);
|
|
}
|
|
}
|
|
processor.outputs.Add(new Prefab_Data
|
|
{
|
|
prefab = prefabKey,
|
|
locations = locations,
|
|
total_count = 0
|
|
});
|
|
}
|
|
|
|
private void RemoveOutputPrefab(ProcessorDataClass processor, string prefabKey)
|
|
{
|
|
if (processor.outputs == null) return;
|
|
|
|
int idx = processor.outputs.FindIndex(x => x.prefab == prefabKey);
|
|
if (idx >= 0) processor.outputs.RemoveAt(idx);
|
|
}
|
|
|
|
private Prefab_Data GetOutputEntry(ProcessorDataClass processor, string prefabKey)
|
|
{
|
|
if (processor.outputs == null) return null;
|
|
return processor.outputs.Find(x => x.prefab == prefabKey);
|
|
}
|
|
|
|
private void SyncOutputPrefabDetailVisibility(ProcessorDataClass processor)
|
|
{
|
|
bool isRandom = string.Equals(processor.output_selection_policy, "random", StringComparison.OrdinalIgnoreCase);
|
|
|
|
foreach (var prefabKey in PrefabManager.Instance.prefabDict.Keys)
|
|
{
|
|
bool enabled = processor.outputs != null && processor.outputs.Exists(x => x != null && x.prefab == prefabKey);
|
|
|
|
string groupId = GetOutputPrefabDetailGroupId(prefabKey);
|
|
|
|
propertyWindow.SetGroupVisibility(groupId, enabled);
|
|
|
|
if (!enabled)
|
|
continue;
|
|
|
|
var entry = GetOutputEntry(processor, prefabKey);
|
|
|
|
string totalId = $"{groupId}.total_count";
|
|
if (propertyWindow.GetProperty(totalId) != null)
|
|
propertyWindow.SetPropertyVisibility(totalId, isRandom);
|
|
|
|
if (entry?.locations != null)
|
|
{
|
|
foreach (var loc in entry.locations)
|
|
{
|
|
string locId = $"{groupId}.count.{loc.target}";
|
|
if (propertyWindow.GetProperty(locId) != null)
|
|
propertyWindow.SetPropertyVisibility(locId, !isRandom);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
private PropertyGroup CreateRequireResourceGroup(ProcessorDataClass processor)
|
|
{
|
|
var group = new PropertyGroup("RequireResource", "자원 할당", isExpanded: true);
|
|
|
|
// 1) required_resources 인덱스화
|
|
var requiredIndex = BuildRequiredIndex(processor);
|
|
|
|
int count = 0;
|
|
foreach (var resource in ComponentsManager.logicDetailData.infrastructure.resources)
|
|
{
|
|
if (!string.Equals(resource.type, "worker"))
|
|
continue;
|
|
|
|
// 2) 매칭 키 결정: 여기서는 resource.name을 키로 쓴다고 가정
|
|
var key = resource.name; // ★ label 말고 name/id 권장
|
|
bool isRequired = key != null && requiredIndex.ContainsKey(key);
|
|
|
|
// 3) 초기값을 isRequired로
|
|
var property = new BoolProperty($"required_resource[{count++}]", resource.label, isRequired);
|
|
|
|
// 4) (선택) 변경 시 processor.required_resources 업데이트 + Patch 저장까지 Bind로 연결
|
|
property.Bind(setter: v =>
|
|
{
|
|
SetRequiredResource(processor, key, v);
|
|
// SaveChange(processor or sourceRoot, processorRequiredPath...) 형태로 패치 기록
|
|
});
|
|
|
|
group.AddItem(property);
|
|
}
|
|
|
|
return group;
|
|
}
|
|
|
|
private void SetRequiredResource(ProcessorDataClass processor, string resourceName, bool required)
|
|
{
|
|
if (string.IsNullOrEmpty(resourceName)) return;
|
|
|
|
processor.required_resources ??= new List<Required_Resources>();
|
|
|
|
int idx = processor.required_resources.FindIndex(x => x != null && x.name == resourceName);
|
|
|
|
if (required)
|
|
{
|
|
if (idx < 0)
|
|
{
|
|
processor.required_resources.Add(new Required_Resources
|
|
{
|
|
name = resourceName,
|
|
count = 1,
|
|
selection_policy = "random" // 기본값 정책은 규칙에 맞춰 결정
|
|
});
|
|
}
|
|
else
|
|
{
|
|
// 이미 있으면 유지 (필요 시 count/policy 기본 보정)
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (idx >= 0)
|
|
processor.required_resources.RemoveAt(idx);
|
|
}
|
|
}
|
|
|
|
#region 처리 시간 정책
|
|
private PropertyGroup CreateProcessingTimePolicy_Constant(ProcessorDataClass processor)
|
|
{
|
|
var group = new PropertyGroup("ProcessingTimePolicy_Constant", "", isExpanded: true);
|
|
group.AddItems(new IPropertyItem[]
|
|
{
|
|
new FloatProperty("ProcessingTimePolicy_Constant_Value", "상수 값", (processor.processing_time_policy as Policy_Constant) ?.value ?? 0f)
|
|
{
|
|
}.Bind(
|
|
setter: v => {(processor.processing_time_policy as Policy_Constant).value = v;SaveChange(processor,v,"processing_time_policy.value"); }
|
|
),
|
|
});
|
|
return group;
|
|
}
|
|
|
|
private PropertyGroup CreateProcessingTimePolicy_Normal(ProcessorDataClass processor)
|
|
{
|
|
var group = new PropertyGroup("ProcessingTimePolicy_Normal", "", isExpanded: true);
|
|
group.AddItems(new IPropertyItem[]
|
|
{
|
|
new FloatProperty("ProcessingTimePolicy_Normal_Mean", "정규 분포 표준치", (processor.processing_time_policy as Policy_Normal) ?.mean ?? 0f)
|
|
{
|
|
}.Bind(
|
|
setter: v => {(processor.processing_time_policy as Policy_Normal).mean = v;SaveChange(processor,v,"processing_time_policy.mean"); }
|
|
),
|
|
new FloatProperty("ProcessingTimePolicy_Normal_Gap", "정규 분포 표준 편차", (processor.processing_time_policy as Policy_Normal) ?.stddev ?? 0f)
|
|
{
|
|
}.Bind(
|
|
setter: v => {(processor.processing_time_policy as Policy_Normal).stddev = v;SaveChange(processor,v,"processing_time_policy.stddev"); }
|
|
),
|
|
});
|
|
return group;
|
|
}
|
|
|
|
private PropertyGroup CreateProcessingTimePolicy_Uniform(ProcessorDataClass processor)
|
|
{
|
|
var group = new PropertyGroup("ProcessingTimePolicy_Uniform", "", isExpanded: true);
|
|
group.AddItems(new IPropertyItem[]
|
|
{
|
|
new FloatProperty("ProcessingTimePolicy_Uniform_Min", "균등 분포 최소값", (processor.processing_time_policy as Policy_Uniform) ?.min_val ?? 0f)
|
|
{
|
|
}.Bind(
|
|
setter: v => {(processor.processing_time_policy as Policy_Uniform).min_val = v;SaveChange(processor,v,"processing_time_policy.min_val"); }
|
|
),
|
|
new FloatProperty("ProcessingTimePolicy_Uniform_Max", "균등 분포 최대값", (processor.processing_time_policy as Policy_Uniform) ?.max_val ?? 0f)
|
|
{
|
|
}.Bind(
|
|
setter: v => {(processor.processing_time_policy as Policy_Uniform).max_val = v;SaveChange(processor,v,"processing_time_policy.max_val"); }
|
|
),
|
|
});
|
|
return group;
|
|
}
|
|
|
|
private PropertyGroup CreateProcessingTimePolicy_Exponential(ProcessorDataClass processor)
|
|
{
|
|
var group = new PropertyGroup("ProcessingTimePolicy_Exponential", "", isExpanded: true);
|
|
group.AddItems(new IPropertyItem[]
|
|
{
|
|
new FloatProperty("ProcessingTimePolicy_Exponential_Mean", "지수 분포 평균치", (processor.processing_time_policy as Policy_Exponential) ?.mean ?? 0f)
|
|
{
|
|
}.Bind(
|
|
setter: v => {(processor.processing_time_policy as Policy_Exponential).mean = v;SaveChange(processor,v,"processing_time_policy.mean"); }
|
|
),
|
|
});
|
|
return group;
|
|
}
|
|
|
|
private PropertyGroup CreateProcessingTimePolicy_Triangular(ProcessorDataClass processor)
|
|
{
|
|
var group = new PropertyGroup("ProcessingTimePolicy_Triangular", "", isExpanded: true);
|
|
group.AddItems(new IPropertyItem[]
|
|
{
|
|
new FloatProperty("ProcessingTimePolicy_Triangular_Min", "지수 분포 최소값", (processor.processing_time_policy as Policy_Triangular) ?.min_val ?? 0f)
|
|
{
|
|
}.Bind(
|
|
setter: v => {(processor.processing_time_policy as Policy_Triangular).min_val = v;SaveChange(processor,v,"processing_time_policy.min_val"); }
|
|
),
|
|
new FloatProperty("ProcessingTimePolicy_Triangular_Mean", "지수 분포 최빈값", (processor.processing_time_policy as Policy_Triangular) ?.mode ?? 0f)
|
|
{
|
|
}.Bind(
|
|
setter: v => {(processor.processing_time_policy as Policy_Triangular).mode = v;SaveChange(processor,v,"processing_time_policy.mode"); }
|
|
),
|
|
new FloatProperty("ProcessingTimePolicy_Triangular_Max", "지수 분포 최대값", (processor.processing_time_policy as Policy_Triangular) ?.max_val ?? 0f)
|
|
{
|
|
}.Bind(
|
|
setter: v => {(processor.processing_time_policy as Policy_Triangular).max_val = v;SaveChange(processor,v,"processing_time_policy.max_val"); }
|
|
),
|
|
});
|
|
return group;
|
|
}
|
|
|
|
private void HandleDisplayModeChanged_ProcessingTimePolicy(string mode)
|
|
{
|
|
// 모든 조건부 그룹 숨김
|
|
propertyWindow.SetGroupVisibility("ProcessingTimePolicy_Constant", false);
|
|
propertyWindow.SetGroupVisibility("ProcessingTimePolicy_Normal", false);
|
|
propertyWindow.SetGroupVisibility("ProcessingTimePolicy_Uniform", false);
|
|
propertyWindow.SetGroupVisibility("ProcessingTimePolicy_Exponential", false);
|
|
propertyWindow.SetGroupVisibility("ProcessingTimePolicy_Triangular", false);
|
|
|
|
// 선택된 모드에 따라 해당 그룹만 표시
|
|
switch (mode)
|
|
{
|
|
case "Constant":
|
|
propertyWindow.SetGroupVisibility("ProcessingTimePolicy_Constant", true);
|
|
break;
|
|
case "Normal":
|
|
propertyWindow.SetGroupVisibility("ProcessingTimePolicy_Normal", true);
|
|
break;
|
|
case "Uniform":
|
|
propertyWindow.SetGroupVisibility("ProcessingTimePolicy_Uniform", true);
|
|
break;
|
|
case "Exponential":
|
|
propertyWindow.SetGroupVisibility("ProcessingTimePolicy_Exponential", true);
|
|
break;
|
|
case "Triangular":
|
|
propertyWindow.SetGroupVisibility("ProcessingTimePolicy_Triangular", true);
|
|
break;
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
#region 준비 시간 정책
|
|
private PropertyGroup CreateReadyTimePolicy_Constant(ProcessorDataClass processor)
|
|
{
|
|
var group = new PropertyGroup("ReadyTimePolicy_Constant", "", isExpanded: true);
|
|
group.AddItems(new IPropertyItem[]
|
|
{
|
|
new FloatProperty("ReadyTimePolicy_Constant_Value", "상수 값", (processor.ready_time_policy as Policy_Constant) ?.value ?? 0f)
|
|
{
|
|
}.Bind(
|
|
setter: v => {(processor.ready_time_policy as Policy_Constant).value = v;SaveChange(processor,v,"ready_time_policy.value"); }
|
|
),
|
|
});
|
|
return group;
|
|
}
|
|
|
|
private PropertyGroup CreateReadyTimePolicy_Normal(ProcessorDataClass processor)
|
|
{
|
|
var group = new PropertyGroup("ReadyTimePolicy_Normal", "", isExpanded: true);
|
|
group.AddItems(new IPropertyItem[]
|
|
{
|
|
new FloatProperty("ReadyTimePolicy_Normal_Mean", "정규 분포 표준치", (processor.ready_time_policy as Policy_Normal) ?.mean ?? 0f)
|
|
{
|
|
}.Bind(
|
|
setter: v => {(processor.ready_time_policy as Policy_Normal).mean = v;SaveChange(processor,v,"ready_time_policy.mean"); }
|
|
),
|
|
new FloatProperty("ReadyTimePolicy_Normal_Gap", "정규 분포 표준 편차", (processor.ready_time_policy as Policy_Normal) ?.stddev ?? 0f)
|
|
{
|
|
}.Bind(
|
|
setter: v => {(processor.ready_time_policy as Policy_Normal).stddev = v;SaveChange(processor,v,"ready_time_policy.stddev"); }
|
|
),
|
|
});
|
|
return group;
|
|
}
|
|
|
|
private PropertyGroup CreateReadyTimePolicy_Uniform(ProcessorDataClass processor)
|
|
{
|
|
var group = new PropertyGroup("ReadyTimePolicy_Uniform", "", isExpanded: true);
|
|
group.AddItems(new IPropertyItem[]
|
|
{
|
|
new FloatProperty("ReadyTimePolicy_Uniform_Min", "균등 분포 최소값", (processor.ready_time_policy as Policy_Uniform) ?.min_val ?? 0f)
|
|
{
|
|
}.Bind(
|
|
setter: v => {(processor.ready_time_policy as Policy_Uniform).min_val = v;SaveChange(processor,v,"ready_time_policy.min_val"); }
|
|
),
|
|
new FloatProperty("ReadyTimePolicy_Uniform_Max", "균등 분포 최대값", (processor.ready_time_policy as Policy_Uniform) ?.max_val ?? 0f)
|
|
{
|
|
}.Bind(
|
|
setter: v => {(processor.ready_time_policy as Policy_Uniform).max_val = v;SaveChange(processor,v,"ready_time_policy.max_val"); }
|
|
),
|
|
});
|
|
return group;
|
|
}
|
|
|
|
private PropertyGroup CreateReadyTimePolicy_Exponential(ProcessorDataClass processor)
|
|
{
|
|
var group = new PropertyGroup("ReadyTimePolicy_Exponential", "", isExpanded: true);
|
|
group.AddItems(new IPropertyItem[]
|
|
{
|
|
new FloatProperty("ReadyTimePolicy_Exponential_Mean", "지수 분포 평균치", (processor.ready_time_policy as Policy_Exponential) ?.mean ?? 0f)
|
|
{
|
|
}.Bind(
|
|
setter: v => {(processor.ready_time_policy as Policy_Exponential).mean = v;SaveChange(processor,v,"ready_time_policy.mean"); }
|
|
),
|
|
});
|
|
return group;
|
|
}
|
|
|
|
private PropertyGroup CreateReadyTimePolicy_Triangular(ProcessorDataClass processor)
|
|
{
|
|
var group = new PropertyGroup("ReadyTimePolicy_Triangular", "", isExpanded: true);
|
|
group.AddItems(new IPropertyItem[]
|
|
{
|
|
new FloatProperty("ReadyTimePolicy_Triangular_Min", "지수 분포 최소값", (processor.ready_time_policy as Policy_Triangular) ?.min_val ?? 0f)
|
|
{
|
|
}.Bind(
|
|
setter: v => {(processor.ready_time_policy as Policy_Triangular).min_val = v;SaveChange(processor,v,"ready_time_policy.min_val"); }
|
|
),
|
|
new FloatProperty("ReadyTimePolicy_Triangular_Mean", "지수 분포 최빈값", (processor.ready_time_policy as Policy_Triangular) ?.mode ?? 0f)
|
|
{
|
|
}.Bind(
|
|
setter: v => {(processor.ready_time_policy as Policy_Triangular).mode = v;SaveChange(processor,v,"ready_time_policy.mode"); }
|
|
),
|
|
new FloatProperty("ReadyTimePolicy_Triangular_Max", "지수 분포 최대값", (processor.ready_time_policy as Policy_Triangular) ?.max_val ?? 0f)
|
|
{
|
|
}.Bind(
|
|
setter: v => {(processor.ready_time_policy as Policy_Triangular).max_val = v;SaveChange(processor,v,"ready_time_policy.max_val"); }
|
|
),
|
|
});
|
|
return group;
|
|
}
|
|
|
|
private void HandleDisplayModeChanged_ReadyTimePolicy(string mode)
|
|
{
|
|
// 모든 조건부 그룹 숨김
|
|
propertyWindow.SetGroupVisibility("ReadyTimePolicy_Constant", false);
|
|
propertyWindow.SetGroupVisibility("ReadyTimePolicy_Normal", false);
|
|
propertyWindow.SetGroupVisibility("ReadyTimePolicy_Uniform", false);
|
|
propertyWindow.SetGroupVisibility("ReadyTimePolicy_Exponential", false);
|
|
propertyWindow.SetGroupVisibility("ReadyTimePolicy_Triangular", false);
|
|
|
|
// 선택된 모드에 따라 해당 그룹만 표시
|
|
switch (mode)
|
|
{
|
|
case "Constant":
|
|
propertyWindow.SetGroupVisibility("ReadyTimePolicy_Constant", true);
|
|
break;
|
|
case "Normal":
|
|
propertyWindow.SetGroupVisibility("ReadyTimePolicy_Normal", true);
|
|
break;
|
|
case "Uniform":
|
|
propertyWindow.SetGroupVisibility("ReadyTimePolicy_Uniform", true);
|
|
break;
|
|
case "Exponential":
|
|
propertyWindow.SetGroupVisibility("ReadyTimePolicy_Exponential", true);
|
|
break;
|
|
case "Triangular":
|
|
propertyWindow.SetGroupVisibility("ReadyTimePolicy_Triangular", true);
|
|
break;
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
#region 불량률 정책
|
|
private PropertyGroup CreateDefectRatePolicy_Constant(ProcessorDataClass processor)
|
|
{
|
|
var group = new PropertyGroup("DefectRatePolicy_Constant", "", isExpanded: true);
|
|
group.AddItems(new IPropertyItem[]
|
|
{
|
|
new FloatProperty("DefectRatePolicy_Constant_Value", "상수 값", (processor.defect_rate_policy as Policy_Constant) ?.value ?? 0f)
|
|
{
|
|
}.Bind(
|
|
setter: v => {(processor.defect_rate_policy as Policy_Constant).value = v;SaveChange(processor,v,"defect_rate_policy.value"); }
|
|
),
|
|
});
|
|
return group;
|
|
}
|
|
|
|
private PropertyGroup CreateDefectRatePolicy_Normal(ProcessorDataClass processor)
|
|
{
|
|
var group = new PropertyGroup("DefectRatePolicy_Normal", "", isExpanded: true);
|
|
group.AddItems(new IPropertyItem[]
|
|
{
|
|
new FloatProperty("DefectRatePolicy_Normal_Mean", "정규 분포 표준치", (processor.defect_rate_policy as Policy_Normal) ?.mean ?? 0f)
|
|
{
|
|
}.Bind(
|
|
setter: v => {(processor.defect_rate_policy as Policy_Normal).mean = v;SaveChange(processor,v,"defect_rate_policy.mean"); }
|
|
),
|
|
new FloatProperty("DefectRatePolicy_Normal_Gap", "정규 분포 표준 편차", (processor.defect_rate_policy as Policy_Normal) ?.stddev ?? 0f)
|
|
{
|
|
}.Bind(
|
|
setter: v => {(processor.defect_rate_policy as Policy_Normal).stddev = v;SaveChange(processor,v,"defect_rate_policy.stddev"); }
|
|
),
|
|
});
|
|
return group;
|
|
}
|
|
|
|
private PropertyGroup CreateDefectRatePolicy_Uniform(ProcessorDataClass processor)
|
|
{
|
|
var group = new PropertyGroup("DefectRatePolicy_Uniform", "", isExpanded: true);
|
|
group.AddItems(new IPropertyItem[]
|
|
{
|
|
new FloatProperty("DefectRatePolicy_Uniform_Min", "균등 분포 최소값", (processor.defect_rate_policy as Policy_Uniform) ?.min_val ?? 0f)
|
|
{
|
|
}.Bind(
|
|
setter: v => {(processor.defect_rate_policy as Policy_Uniform).min_val = v;SaveChange(processor,v,"defect_rate_policy.min_val"); }
|
|
),
|
|
new FloatProperty("DefectRatePolicy_Uniform_Max", "균등 분포 최대값", (processor.defect_rate_policy as Policy_Uniform) ?.max_val ?? 0f)
|
|
{
|
|
}.Bind(
|
|
setter: v => {(processor.defect_rate_policy as Policy_Uniform).max_val = v;SaveChange(processor,v,"defect_rate_policy.max_val"); }
|
|
),
|
|
});
|
|
return group;
|
|
}
|
|
|
|
private PropertyGroup CreateDefectRatePolicy_Exponential(ProcessorDataClass processor)
|
|
{
|
|
var group = new PropertyGroup("DefectRatePolicy_Exponential", "", isExpanded: true);
|
|
group.AddItems(new IPropertyItem[]
|
|
{
|
|
new FloatProperty("DefectRatePolicy_Exponential_Mean", "지수 분포 평균치", (processor.defect_rate_policy as Policy_Exponential) ?.mean ?? 0f)
|
|
{
|
|
}.Bind(
|
|
setter: v => {(processor.defect_rate_policy as Policy_Exponential).mean = v;SaveChange(processor,v,"defect_rate_policy.mean"); }
|
|
),
|
|
});
|
|
return group;
|
|
}
|
|
|
|
private PropertyGroup CreateDefectRatePolicy_Triangular(ProcessorDataClass processor)
|
|
{
|
|
var group = new PropertyGroup("DefectRatePolicy_Triangular", "", isExpanded: true);
|
|
group.AddItems(new IPropertyItem[]
|
|
{
|
|
new FloatProperty("DefectRatePolicy_Triangular_Min", "지수 분포 최소값", (processor.defect_rate_policy as Policy_Triangular) ?.min_val ?? 0f)
|
|
{
|
|
}.Bind(
|
|
setter: v => {(processor.defect_rate_policy as Policy_Triangular).min_val = v;SaveChange(processor,v,"defect_rate_policy.min_val"); }
|
|
),
|
|
new FloatProperty("DefectRatePolicy_Triangular_Mean", "지수 분포 최빈값", (processor.defect_rate_policy as Policy_Triangular) ?.mode ?? 0f)
|
|
{
|
|
}.Bind(
|
|
setter: v => {(processor.defect_rate_policy as Policy_Triangular).mode = v;SaveChange(processor,v,"defect_rate_policy.mode"); }
|
|
),
|
|
new FloatProperty("DefectRatePolicy_Triangular_Max", "지수 분포 최대값", (processor.defect_rate_policy as Policy_Triangular) ?.max_val ?? 0f)
|
|
{
|
|
}.Bind(
|
|
setter: v => {(processor.defect_rate_policy as Policy_Triangular).max_val = v;SaveChange(processor,v,"defect_rate_policy.max_val"); }
|
|
),
|
|
});
|
|
return group;
|
|
}
|
|
|
|
private void HandleDisplayModeChanged_DefectRatePolicy(string mode)
|
|
{
|
|
// 모든 조건부 그룹 숨김
|
|
propertyWindow.SetGroupVisibility("DefectRatePolicy_Constant", false);
|
|
propertyWindow.SetGroupVisibility("DefectRatePolicy_Normal", false);
|
|
propertyWindow.SetGroupVisibility("DefectRatePolicy_Uniform", false);
|
|
propertyWindow.SetGroupVisibility("DefectRatePolicy_Exponential", false);
|
|
propertyWindow.SetGroupVisibility("DefectRatePolicy_Triangular", false);
|
|
|
|
// 선택된 모드에 따라 해당 그룹만 표시
|
|
switch (mode)
|
|
{
|
|
case "Constant":
|
|
propertyWindow.SetGroupVisibility("DefectRatePolicy_Constant", true);
|
|
break;
|
|
case "Normal":
|
|
propertyWindow.SetGroupVisibility("DefectRatePolicy_Normal", true);
|
|
break;
|
|
case "Uniform":
|
|
propertyWindow.SetGroupVisibility("DefectRatePolicy_Uniform", true);
|
|
break;
|
|
case "Exponential":
|
|
propertyWindow.SetGroupVisibility("DefectRatePolicy_Exponential", true);
|
|
break;
|
|
case "Triangular":
|
|
propertyWindow.SetGroupVisibility("DefectRatePolicy_Triangular", true);
|
|
break;
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
private Dictionary<string, Required_Resources> BuildRequiredIndex(ProcessorDataClass processor)
|
|
{
|
|
var dict = new Dictionary<string, Required_Resources>(StringComparer.Ordinal);
|
|
|
|
if (processor.required_resources == null) return dict;
|
|
|
|
foreach (var rr in processor.required_resources)
|
|
{
|
|
if (rr?.name == null) continue;
|
|
dict[rr.name] = rr;
|
|
}
|
|
return dict;
|
|
}
|
|
} |