Compare commits
81 Commits
830d014bf0
...
0.0.10
Author | SHA1 | Date | |
---|---|---|---|
a131ed10f9 | |||
ad0797585b | |||
304ab10491 | |||
130f880d5d | |||
cf6d76d4c0 | |||
4628db1d49 | |||
1eeaa4f728 | |||
309ee12b93 | |||
59335c9102 | |||
e182ebd53f | |||
65b158f387 | |||
9f844f2744 | |||
ae917a8e51 | |||
44a72d1a8f | |||
4758b65159 | |||
de3196d38a | |||
c2311fb7a4 | |||
7562be2c09 | |||
a8f46113d4 | |||
99736f114d | |||
4d1a008106 | |||
9318cbca4e | |||
a162f345c4 | |||
1af4afc7c6 | |||
a3efe939e8 | |||
5daee1a01a | |||
2d5d305528 | |||
8da46c0511 | |||
75b5d7708c | |||
5b2177a795 | |||
8cb33dca5f | |||
ae2e0af18a | |||
2ac5a3d4f0 | |||
5f78a1afde | |||
ef5cf78a03 | |||
b60e62af70 | |||
3e59fe1462 | |||
4b4bf5ed65 | |||
a4f78b3a95 | |||
074a58dabd | |||
a2ef175a81 | |||
915ba55c2e | |||
f154a2a468 | |||
c52d438d40 | |||
8d3f53ba13 | |||
1db25e62e7 | |||
18312176d9 | |||
5be6e32b03 | |||
b33e5ca223 | |||
fe4430b1bf | |||
5a48073152 | |||
41c1e6f9fd | |||
0743fa45eb | |||
7f2c0d2e23 | |||
14202714cc | |||
ce0c23805a | |||
75124a4f62 | |||
9193eb9c8c | |||
c0b3449cc8 | |||
d986418927 | |||
0adea1a325 | |||
399fb577f3 | |||
c3cd512611 | |||
f783d45e23 | |||
04ba735ea6 | |||
7bfe335c13 | |||
4c812db03a | |||
6ee7a4720c | |||
302dc36eba | |||
3ca96c1a68 | |||
fbf35c923b | |||
b749cf0221 | |||
5b3a51150c | |||
02fc481993 | |||
1d619391c9 | |||
dad7e703e6 | |||
a1f6c4ef94 | |||
a0ded872b3 | |||
35b77b044c | |||
70f4d0ffc3 | |||
6ead7aa5ce |
@@ -2,7 +2,7 @@
|
|||||||
"name": "Cryville.Common",
|
"name": "Cryville.Common",
|
||||||
"rootNamespace": "",
|
"rootNamespace": "",
|
||||||
"references": [
|
"references": [
|
||||||
"GUID:da293eebbcb9a4947a212534c52d1a32"
|
"GUID:6055be8ebefd69e48b49212b09b47b2f"
|
||||||
],
|
],
|
||||||
"includePlatforms": [],
|
"includePlatforms": [],
|
||||||
"excludePlatforms": [],
|
"excludePlatforms": [],
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace Utils {
|
namespace Cryville.Common.Unity {
|
||||||
public class PropertyTweener<T> {
|
public class PropertyTweener<T> {
|
||||||
readonly Func<T> _getter;
|
readonly Func<T> _getter;
|
||||||
readonly Action<T> _setter;
|
readonly Action<T> _setter;
|
||||||
|
160
Assets/Cryville.Common/Unity/UI/RecyclerView.cs
Normal file
160
Assets/Cryville.Common/Unity/UI/RecyclerView.cs
Normal file
@@ -0,0 +1,160 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.EventSystems;
|
||||||
|
using UnityEngine.UI;
|
||||||
|
|
||||||
|
namespace Cryville.Common.Unity.UI {
|
||||||
|
public delegate void LoadItemHandler(int index, GameObject gameObject);
|
||||||
|
[RequireComponent(typeof(RectTransform))]
|
||||||
|
public class RecyclerView : UIBehaviour {
|
||||||
|
[SerializeField]
|
||||||
|
private GameObject m_itemTemplate;
|
||||||
|
public GameObject ItemTemplate {
|
||||||
|
get { return m_itemTemplate; }
|
||||||
|
set { m_itemTemplate = value; /*OnTemplateUpdate();*/ }
|
||||||
|
}
|
||||||
|
public LoadItemHandler LoadItem { private get; set; }
|
||||||
|
|
||||||
|
public enum Axis {
|
||||||
|
Horizontal = 0,
|
||||||
|
Vertical = 1,
|
||||||
|
}
|
||||||
|
[SerializeField]
|
||||||
|
private Axis m_direction;
|
||||||
|
public Axis Direction {
|
||||||
|
get { return m_direction; }
|
||||||
|
set { m_direction = value; /*OnFrameUpdate();*/ }
|
||||||
|
}
|
||||||
|
|
||||||
|
[SerializeField]
|
||||||
|
RectOffset m_padding;
|
||||||
|
public RectOffset Padding {
|
||||||
|
get => m_padding;
|
||||||
|
set => m_padding = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
[SerializeField]
|
||||||
|
float m_spacing;
|
||||||
|
public float Spacing {
|
||||||
|
get => m_spacing;
|
||||||
|
set => m_spacing = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
[SerializeField]
|
||||||
|
private int m_itemCount = 3;
|
||||||
|
public int ItemCount {
|
||||||
|
get { return m_itemCount; }
|
||||||
|
set { m_itemCount = value; /*OnRefresh();*/ }
|
||||||
|
}
|
||||||
|
|
||||||
|
RectTransform _rectTransform;
|
||||||
|
protected override void Awake() {
|
||||||
|
_rectTransform = GetComponent<RectTransform>();
|
||||||
|
}
|
||||||
|
|
||||||
|
const float _placeholderLength = 100;
|
||||||
|
int _firstIndex, _lastIndex;
|
||||||
|
readonly Stack<GameObject> _pool = new();
|
||||||
|
void LateUpdate() {
|
||||||
|
int axis = (int)m_direction;
|
||||||
|
int sign = m_direction == 0 ? 1 : -1;
|
||||||
|
float padding = axis == 0 ? m_padding.left : m_padding.top;
|
||||||
|
if (_rectTransform.parent is not RectTransform parentTransform)
|
||||||
|
throw new InvalidOperationException("Parent transform is not RectTransform");
|
||||||
|
|
||||||
|
Vector2 apos = _rectTransform.anchoredPosition;
|
||||||
|
float pos = apos[axis] + padding;
|
||||||
|
float childPos = _firstIndex * _placeholderLength + padding;
|
||||||
|
float visibleLength = parentTransform.rect.size[axis];
|
||||||
|
|
||||||
|
//// Add preceding
|
||||||
|
//while (_firstIndex > 0 && childPos > pos) {
|
||||||
|
// var child = Rent();
|
||||||
|
// child.transform.SetAsFirstSibling();
|
||||||
|
// LoadItem(--_firstIndex, child);
|
||||||
|
// pos += GetLength(axis, child.transform) - _placeholderLength;
|
||||||
|
// childPos -= _placeholderLength;
|
||||||
|
//}
|
||||||
|
|
||||||
|
//// Remove preceding
|
||||||
|
//while (_firstIndex < _lastIndex) {
|
||||||
|
// var child = transform.GetChild(0);
|
||||||
|
// float len = GetLength(axis, child.transform);
|
||||||
|
// if (childPos + len > pos) break;
|
||||||
|
// Return(child.gameObject);
|
||||||
|
// _firstIndex++;
|
||||||
|
// pos += _placeholderLength - len;
|
||||||
|
// childPos += _placeholderLength;
|
||||||
|
//}
|
||||||
|
|
||||||
|
//apos[axis] = pos;
|
||||||
|
//_rectTransform.anchoredPosition = apos;
|
||||||
|
|
||||||
|
// Layout existing
|
||||||
|
int index = _firstIndex;
|
||||||
|
float layoutToPos = pos + visibleLength;
|
||||||
|
for (; index < _lastIndex && childPos < layoutToPos; index++) {
|
||||||
|
var child = (RectTransform)transform.GetChild(index - _firstIndex);
|
||||||
|
LayoutChild(axis, sign, ref childPos, child);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove following
|
||||||
|
for (; _lastIndex > index; --_lastIndex) {
|
||||||
|
var child = (RectTransform)transform.GetChild(index - _firstIndex);
|
||||||
|
Return(child.gameObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add following (and layout)
|
||||||
|
while (_lastIndex < m_itemCount && childPos < layoutToPos) {
|
||||||
|
var child = Rent();
|
||||||
|
if (child.transform is not RectTransform childTransform)
|
||||||
|
throw new InvalidOperationException("Child transform is not RectTransform");
|
||||||
|
childTransform.SetSiblingIndex(_lastIndex - _firstIndex);
|
||||||
|
LoadItem(_lastIndex++, child);
|
||||||
|
LayoutChild(axis, sign, ref childPos, childTransform);
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector2 gsize = _rectTransform.sizeDelta;
|
||||||
|
gsize[axis] = childPos + (m_itemCount - _lastIndex) * _placeholderLength + (axis == 0 ? m_padding.horizontal : m_padding.vertical);
|
||||||
|
_rectTransform.sizeDelta = gsize;
|
||||||
|
}
|
||||||
|
static float GetLength(int axis, Transform child) {
|
||||||
|
if (child is not RectTransform childTransform)
|
||||||
|
throw new InvalidOperationException("Child transform is not RectTransform");
|
||||||
|
return LayoutUtility.GetPreferredSize(childTransform, axis);
|
||||||
|
}
|
||||||
|
void LayoutChild(int axis, int sign, ref float childPos, RectTransform childTransform) {
|
||||||
|
Vector2 cpos = childTransform.anchoredPosition;
|
||||||
|
cpos[axis] = childPos * sign;
|
||||||
|
cpos[axis ^ 1] = axis == 1 ? m_padding.left : m_padding.top;
|
||||||
|
childTransform.anchoredPosition = cpos;
|
||||||
|
|
||||||
|
Vector2 size = childTransform.sizeDelta;
|
||||||
|
size[axis ^ 1] = _rectTransform.rect.size[axis ^ 1] - (axis == 1 ? m_padding.horizontal : m_padding.vertical);
|
||||||
|
childTransform.sizeDelta = size;
|
||||||
|
|
||||||
|
childPos += GetLength(axis, childTransform) + m_spacing;
|
||||||
|
}
|
||||||
|
|
||||||
|
GameObject Rent() {
|
||||||
|
if (_pool.TryPop(out var ret)) {
|
||||||
|
ret.SetActive(true);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
return Instantiate(m_itemTemplate, transform, false);
|
||||||
|
}
|
||||||
|
void Return(GameObject child) {
|
||||||
|
child.transform.SetAsLastSibling();
|
||||||
|
child.SetActive(false);
|
||||||
|
_pool.Push(child);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void InvalidateAll() {
|
||||||
|
for (; _lastIndex > _firstIndex; --_lastIndex) {
|
||||||
|
var child = (RectTransform)transform.GetChild(0);
|
||||||
|
Return(child.gameObject);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -1,5 +1,5 @@
|
|||||||
fileFormatVersion: 2
|
fileFormatVersion: 2
|
||||||
guid: 9e8aa96a139a7414cb4d2031a22588db
|
guid: 1257c1f4490f1d64bb8fc52a9abed1ae
|
||||||
MonoImporter:
|
MonoImporter:
|
||||||
externalObjects: {}
|
externalObjects: {}
|
||||||
serializedVersion: 2
|
serializedVersion: 2
|
@@ -23,6 +23,12 @@ namespace Cryville.Common.Unity.UI {
|
|||||||
[SerializeField]
|
[SerializeField]
|
||||||
protected bool m_ChildScaleHeight;
|
protected bool m_ChildScaleHeight;
|
||||||
|
|
||||||
|
[SerializeField]
|
||||||
|
protected bool m_ChildOverflowWidth;
|
||||||
|
|
||||||
|
[SerializeField]
|
||||||
|
protected bool m_ChildOverflowHeight;
|
||||||
|
|
||||||
public override void CalculateLayoutInputHorizontal() {
|
public override void CalculateLayoutInputHorizontal() {
|
||||||
base.CalculateLayoutInputHorizontal();
|
base.CalculateLayoutInputHorizontal();
|
||||||
CalcAlongAxis(0);
|
CalcAlongAxis(0);
|
||||||
@@ -60,9 +66,10 @@ namespace Cryville.Common.Unity.UI {
|
|||||||
float size = rectTransform.rect.size[axis];
|
float size = rectTransform.rect.size[axis];
|
||||||
bool controlSize = (axis == 0) ? m_ChildControlWidth : m_ChildControlHeight;
|
bool controlSize = (axis == 0) ? m_ChildControlWidth : m_ChildControlHeight;
|
||||||
bool useScale = (axis == 0) ? m_ChildScaleWidth : m_ChildScaleHeight;
|
bool useScale = (axis == 0) ? m_ChildScaleWidth : m_ChildScaleHeight;
|
||||||
|
bool overflow = (axis == 0) ? m_ChildOverflowWidth : m_ChildOverflowHeight;
|
||||||
bool childForceExpandSize = (axis == 0) ? m_ChildForceExpandWidth : m_ChildForceExpandHeight;
|
bool childForceExpandSize = (axis == 0) ? m_ChildForceExpandWidth : m_ChildForceExpandHeight;
|
||||||
float alignmentOnAxis = GetAlignmentOnAxis(axis);
|
float alignmentOnAxis = GetAlignmentOnAxis(axis);
|
||||||
float innerSize = size - ((axis == 0) ? padding.horizontal : padding.vertical);
|
float innerSize = overflow ? float.PositiveInfinity : (size - ((axis == 0) ? padding.horizontal : padding.vertical));
|
||||||
RectTransform child = rectChildren[0];
|
RectTransform child = rectChildren[0];
|
||||||
GetChildSizes(child, axis, controlSize, childForceExpandSize, out var min2, out var preferred2, out var flexible2);
|
GetChildSizes(child, axis, controlSize, childForceExpandSize, out var min2, out var preferred2, out var flexible2);
|
||||||
float scaleFactor2 = useScale ? child.localScale[axis] : 1f;
|
float scaleFactor2 = useScale ? child.localScale[axis] : 1f;
|
||||||
|
@@ -6,8 +6,9 @@ using System.Globalization;
|
|||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using TMPro;
|
using TMPro;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
using UnityEngine.TextCore;
|
||||||
using UnityEngine.TextCore.LowLevel;
|
using UnityEngine.TextCore.LowLevel;
|
||||||
using UnityEngine.TextCore.Text;
|
using AtlasPopulationMode = TMPro.AtlasPopulationMode;
|
||||||
|
|
||||||
namespace Cryville.Common.Unity.UI {
|
namespace Cryville.Common.Unity.UI {
|
||||||
[RequireComponent(typeof(TMP_Text))]
|
[RequireComponent(typeof(TMP_Text))]
|
||||||
@@ -16,7 +17,7 @@ namespace Cryville.Common.Unity.UI {
|
|||||||
public static FontMatcher FontMatcher;
|
public static FontMatcher FontMatcher;
|
||||||
public static int MaxFallbackCount = 4;
|
public static int MaxFallbackCount = 4;
|
||||||
|
|
||||||
static readonly Dictionary<CultureInfo, FontAsset> _cachedFonts = new();
|
static readonly Dictionary<CultureInfo, TMP_FontAsset> _cachedFonts = new();
|
||||||
|
|
||||||
[SerializeField]
|
[SerializeField]
|
||||||
Shader m_shader;
|
Shader m_shader;
|
||||||
@@ -46,7 +47,7 @@ namespace Cryville.Common.Unity.UI {
|
|||||||
if (MaxFallbackCount <= 0) break;
|
if (MaxFallbackCount <= 0) break;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
font.fallbackFontAssetTable ??= new List<FontAsset>();
|
font.fallbackFontAssetTable ??= new List<TMP_FontAsset>();
|
||||||
font.fallbackFontAssetTable.Add(ifont);
|
font.fallbackFontAssetTable.Add(ifont);
|
||||||
if (font.fallbackFontAssetTable.Count >= MaxFallbackCount) break;
|
if (font.fallbackFontAssetTable.Count >= MaxFallbackCount) break;
|
||||||
}
|
}
|
||||||
@@ -58,23 +59,93 @@ namespace Cryville.Common.Unity.UI {
|
|||||||
Text.font = font;
|
Text.font = font;
|
||||||
}
|
}
|
||||||
|
|
||||||
static MethodInfo _methodCreateFontAsset;
|
static TMP_FontAsset CreateFontAsset(string path, int index) => CreateFontAsset(path, index, 90, 9, GlyphRenderMode.SDFAA, 1024, 1024, AtlasPopulationMode.Dynamic);
|
||||||
static readonly object[] _paramsCreateFontAsset = new object[] { null, null, 90, 9, GlyphRenderMode.SDFAA, 1024, 1024, Type.Missing, Type.Missing };
|
|
||||||
static FontAsset CreateFontAsset(string path, int index) {
|
static readonly Lazy<FieldInfo> _f_m_Version = new(() => typeof(TMP_FontAsset).GetField("m_Version", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic));
|
||||||
if (_methodCreateFontAsset == null) {
|
static readonly Lazy<PropertyInfo> _p_atlasWidth = new(() => typeof(TMP_FontAsset).GetProperty("atlasWidth", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic));
|
||||||
_methodCreateFontAsset = typeof(FontAsset).GetMethod(
|
static readonly Lazy<PropertyInfo> _p_atlasHeight = new(() => typeof(TMP_FontAsset).GetProperty("atlasHeight", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic));
|
||||||
"CreateFontAsset", BindingFlags.Static | BindingFlags.NonPublic, null,
|
static readonly Lazy<PropertyInfo> _p_atlasPadding = new(() => typeof(TMP_FontAsset).GetProperty("atlasPadding", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic));
|
||||||
new Type[] {
|
static readonly Lazy<PropertyInfo> _p_atlasRenderMode = new(() => typeof(TMP_FontAsset).GetProperty("atlasRenderMode", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic));
|
||||||
typeof(string), typeof(int), typeof(int), typeof(int),
|
static readonly Lazy<PropertyInfo> _p_freeGlyphRects = new(() => typeof(TMP_FontAsset).GetProperty("freeGlyphRects", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic));
|
||||||
typeof(GlyphRenderMode), typeof(int), typeof(int),
|
static readonly Lazy<PropertyInfo> _p_usedGlyphRects = new(() => typeof(TMP_FontAsset).GetProperty("usedGlyphRects", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic));
|
||||||
typeof(AtlasPopulationMode), typeof(bool)
|
|
||||||
},
|
static readonly Lazy<PropertyInfo> _p_ShaderRef_MobileBitmap = new(() => typeof(ShaderUtilities).GetProperty("ShaderRef_MobileBitmap", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic));
|
||||||
null
|
static readonly Lazy<PropertyInfo> _p_ShaderRef_MobileSDF = new(() => typeof(ShaderUtilities).GetProperty("ShaderRef_MobileSDF", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic));
|
||||||
);
|
|
||||||
|
public static TMP_FontAsset CreateFontAsset(string path, int faceIndex, int samplingPointSize, int atlasPadding, GlyphRenderMode renderMode, int atlasWidth, int atlasHeight, AtlasPopulationMode atlasPopulationMode = AtlasPopulationMode.Dynamic, bool enableMultiAtlasSupport = true) {
|
||||||
|
// Initialize FontEngine
|
||||||
|
FontEngine.InitializeFontEngine();
|
||||||
|
|
||||||
|
// Load Font Face
|
||||||
|
if (FontEngine.LoadFontFace(path, samplingPointSize, faceIndex) != FontEngineError.Success) {
|
||||||
|
Debug.LogWarning("Unable to load font face at path " + path);
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
_paramsCreateFontAsset[0] = path;
|
|
||||||
_paramsCreateFontAsset[1] = index;
|
// Create new font asset
|
||||||
return (FontAsset)_methodCreateFontAsset.Invoke(null, _paramsCreateFontAsset);
|
TMP_FontAsset fontAsset = ScriptableObject.CreateInstance<TMP_FontAsset>();
|
||||||
|
|
||||||
|
_f_m_Version.Value.SetValue(fontAsset, "1.1.0");
|
||||||
|
fontAsset.faceInfo = FontEngine.GetFaceInfo();
|
||||||
|
|
||||||
|
fontAsset.atlasPopulationMode = atlasPopulationMode;
|
||||||
|
|
||||||
|
_p_atlasWidth.Value.SetValue(fontAsset, atlasWidth);
|
||||||
|
_p_atlasHeight.Value.SetValue(fontAsset, atlasHeight);
|
||||||
|
_p_atlasPadding.Value.SetValue(fontAsset, atlasPadding);
|
||||||
|
_p_atlasRenderMode.Value.SetValue(fontAsset, renderMode);
|
||||||
|
|
||||||
|
// Initialize array for the font atlas textures.
|
||||||
|
fontAsset.atlasTextures = new Texture2D[1];
|
||||||
|
|
||||||
|
// Create and add font atlas texture.
|
||||||
|
var texture = new Texture2D(0, 0, TextureFormat.Alpha8, false);
|
||||||
|
fontAsset.atlasTextures[0] = texture;
|
||||||
|
|
||||||
|
fontAsset.isMultiAtlasTexturesEnabled = enableMultiAtlasSupport;
|
||||||
|
|
||||||
|
// Add free rectangle of the size of the texture.
|
||||||
|
int packingModifier;
|
||||||
|
if (((int)renderMode & 0x10) != 0) {
|
||||||
|
packingModifier = 0;
|
||||||
|
|
||||||
|
// Optimize by adding static ref to shader.
|
||||||
|
var tmp_material = new Material((Shader)_p_ShaderRef_MobileBitmap.Value.GetValue(null));
|
||||||
|
|
||||||
|
//tmp_material.name = texture.name + " Material";
|
||||||
|
tmp_material.SetTexture(ShaderUtilities.ID_MainTex, texture);
|
||||||
|
tmp_material.SetFloat(ShaderUtilities.ID_TextureWidth, atlasWidth);
|
||||||
|
tmp_material.SetFloat(ShaderUtilities.ID_TextureHeight, atlasHeight);
|
||||||
|
|
||||||
|
fontAsset.material = tmp_material;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
packingModifier = 1;
|
||||||
|
|
||||||
|
// Optimize by adding static ref to shader.
|
||||||
|
var tmp_material = new Material((Shader)_p_ShaderRef_MobileSDF.Value.GetValue(null));
|
||||||
|
|
||||||
|
//tmp_material.name = texture.name + " Material";
|
||||||
|
tmp_material.SetTexture(ShaderUtilities.ID_MainTex, texture);
|
||||||
|
tmp_material.SetFloat(ShaderUtilities.ID_TextureWidth, atlasWidth);
|
||||||
|
tmp_material.SetFloat(ShaderUtilities.ID_TextureHeight, atlasHeight);
|
||||||
|
|
||||||
|
tmp_material.SetFloat(ShaderUtilities.ID_GradientScale, atlasPadding + packingModifier);
|
||||||
|
|
||||||
|
tmp_material.SetFloat(ShaderUtilities.ID_WeightNormal, fontAsset.normalStyle);
|
||||||
|
tmp_material.SetFloat(ShaderUtilities.ID_WeightBold, fontAsset.boldStyle);
|
||||||
|
|
||||||
|
fontAsset.material = tmp_material;
|
||||||
|
}
|
||||||
|
|
||||||
|
_p_freeGlyphRects.Value.SetValue(fontAsset, new List<GlyphRect>(8) { new(0, 0, atlasWidth - packingModifier, atlasHeight - packingModifier) });
|
||||||
|
_p_usedGlyphRects.Value.SetValue(fontAsset, new List<GlyphRect>(8));
|
||||||
|
|
||||||
|
// TODO: Consider adding support for extracting glyph positioning data
|
||||||
|
|
||||||
|
fontAsset.ReadFontAssetDefinition();
|
||||||
|
|
||||||
|
return fontAsset;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -4,7 +4,7 @@ MonoImporter:
|
|||||||
externalObjects: {}
|
externalObjects: {}
|
||||||
serializedVersion: 2
|
serializedVersion: 2
|
||||||
defaultReferences: []
|
defaultReferences: []
|
||||||
executionOrder: 0
|
executionOrder: -95
|
||||||
icon: {instanceID: 0}
|
icon: {instanceID: 0}
|
||||||
userData:
|
userData:
|
||||||
assetBundleName:
|
assetBundleName:
|
||||||
|
@@ -1,20 +1,60 @@
|
|||||||
using Cryville.Common.Font;
|
using Cryville.Common.Font;
|
||||||
|
using Cryville.Common.Logging;
|
||||||
using Cryville.Common.Unity.UI;
|
using Cryville.Common.Unity.UI;
|
||||||
using Cryville.Crtr;
|
|
||||||
using Cryville.Culture;
|
using Cryville.Culture;
|
||||||
|
using System;
|
||||||
|
using System.Globalization;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Xml.Linq;
|
|
||||||
using System.Xml;
|
using System.Xml;
|
||||||
|
using System.Xml.Linq;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
using Logger = Cryville.Common.Logging.Logger;
|
||||||
|
|
||||||
namespace Cryville.EEW.Unity {
|
namespace Cryville.EEW.Unity {
|
||||||
class App {
|
class App {
|
||||||
|
public static string AppDataPath { get; private set; }
|
||||||
|
|
||||||
|
public static Logger MainLogger { get; private set; }
|
||||||
|
static FileStream _logFileStream;
|
||||||
|
static StreamLoggerListener _logWriter;
|
||||||
|
|
||||||
static bool _init;
|
static bool _init;
|
||||||
public static void Init() {
|
public static void Init() {
|
||||||
if (_init) return;
|
if (_init) return;
|
||||||
_init = true;
|
_init = true;
|
||||||
|
|
||||||
|
AppDataPath = Application.persistentDataPath;
|
||||||
|
|
||||||
|
var logPath = Directory.CreateDirectory(Path.Combine(AppDataPath, "logs"));
|
||||||
|
_logFileStream = new FileStream(
|
||||||
|
Path.Combine(
|
||||||
|
logPath.FullName,
|
||||||
|
string.Format(
|
||||||
|
CultureInfo.InvariantCulture,
|
||||||
|
"{0}.log",
|
||||||
|
DateTimeOffset.UtcNow.ToString("yyyyMMddHHmmssfff", CultureInfo.InvariantCulture)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
FileMode.Create, FileAccess.Write, FileShare.Read
|
||||||
|
);
|
||||||
|
_logWriter = new StreamLoggerListener(_logFileStream) { AutoFlush = true };
|
||||||
|
MainLogger = new Logger();
|
||||||
|
var listener = new InstantLoggerListener();
|
||||||
|
listener.Log += MainLogger.Log;
|
||||||
|
MainLogger.AddListener(_logWriter);
|
||||||
|
Application.logMessageReceivedThreaded += OnInternalLog;
|
||||||
|
|
||||||
|
MainLogger.Log(1, "App", null, "App Version: {0}", Application.version);
|
||||||
|
MainLogger.Log(1, "App", null, "Unity Version: {0}", Application.unityVersion);
|
||||||
|
MainLogger.Log(1, "App", null, "Operating System: {0}, Unity = {1}, Family = {2}", Environment.OSVersion, SystemInfo.operatingSystem, SystemInfo.operatingSystemFamily);
|
||||||
|
MainLogger.Log(1, "App", null, "Platform: Build = {0}, Unity = {1}", PlatformConfig.Name, Application.platform);
|
||||||
|
MainLogger.Log(1, "App", null, "Culture: {0}, UI = {1}, Unity = {2}", SharedCultures.CurrentCulture, SharedCultures.CurrentUICulture, Application.systemLanguage);
|
||||||
|
MainLogger.Log(1, "App", null, "Device: Model = {0}, Type = {1}", SystemInfo.deviceModel, SystemInfo.deviceType);
|
||||||
|
MainLogger.Log(1, "App", null, "Graphics: Name = {0}, Type = {1}, Vendor = {2}, Version = {3}", SystemInfo.graphicsDeviceName, SystemInfo.graphicsDeviceType, SystemInfo.graphicsDeviceVendor, SystemInfo.graphicsDeviceVersion);
|
||||||
|
MainLogger.Log(1, "App", null, "Processor: Count = {0}, Frequency = {1}MHz, Type = {2}", SystemInfo.processorCount, SystemInfo.processorFrequency, SystemInfo.processorType);
|
||||||
|
|
||||||
|
MainLogger.Log(1, "App", null, "Initializing font manager");
|
||||||
foreach (var res in Resources.LoadAll<TextAsset>("cldr/common/validity")) {
|
foreach (var res in Resources.LoadAll<TextAsset>("cldr/common/validity")) {
|
||||||
IdValidity.Load(LoadXmlDocument(res));
|
IdValidity.Load(LoadXmlDocument(res));
|
||||||
}
|
}
|
||||||
@@ -26,7 +66,10 @@ namespace Cryville.EEW.Unity {
|
|||||||
};
|
};
|
||||||
TMPLocalizedText.DefaultShader = Resources.Load<Shader>(PlatformConfig.TextShader);
|
TMPLocalizedText.DefaultShader = Resources.Load<Shader>(PlatformConfig.TextShader);
|
||||||
|
|
||||||
|
MainLogger.Log(1, "App", null, "Loading config");
|
||||||
SharedSettings.Instance.Init();
|
SharedSettings.Instance.Init();
|
||||||
|
|
||||||
|
MainLogger.Log(1, "App", null, "Initialized");
|
||||||
}
|
}
|
||||||
|
|
||||||
static readonly Encoding _encoding = new UTF8Encoding(false, true);
|
static readonly Encoding _encoding = new UTF8Encoding(false, true);
|
||||||
@@ -41,5 +84,16 @@ namespace Cryville.EEW.Unity {
|
|||||||
using var reader = XmlReader.Create(stream, _xmlSettings);
|
using var reader = XmlReader.Create(stream, _xmlSettings);
|
||||||
return XDocument.Load(reader);
|
return XDocument.Load(reader);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void OnInternalLog(string condition, string stackTrace, LogType type) {
|
||||||
|
var l = type switch {
|
||||||
|
LogType.Log => 1,
|
||||||
|
LogType.Assert => 2,
|
||||||
|
LogType.Warning => 3,
|
||||||
|
LogType.Error or LogType.Exception => 4,
|
||||||
|
_ => 1,
|
||||||
|
};
|
||||||
|
MainLogger.Log(l, "Internal", null, "{0}\n{1}", condition, stackTrace);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
3
Assets/Cryville.EEW.Unity/AssemblyInfo.cs
Normal file
3
Assets/Cryville.EEW.Unity/AssemblyInfo.cs
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
using System.Reflection;
|
||||||
|
|
||||||
|
[assembly: AssemblyVersion("0.0.10")]
|
@@ -1,5 +1,5 @@
|
|||||||
fileFormatVersion: 2
|
fileFormatVersion: 2
|
||||||
guid: cc4155a9f4c4a61478dced5053f1bd07
|
guid: c468580e7742d414e96822c2dfe6e4b4
|
||||||
MonoImporter:
|
MonoImporter:
|
||||||
externalObjects: {}
|
externalObjects: {}
|
||||||
serializedVersion: 2
|
serializedVersion: 2
|
100
Assets/Cryville.EEW.Unity/Config.cs
Normal file
100
Assets/Cryville.EEW.Unity/Config.cs
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
using Cryville.EEW.Core;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Text.Json;
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
|
namespace Cryville.EEW.Unity {
|
||||||
|
record Config(
|
||||||
|
string SeverityScheme,
|
||||||
|
float SeverityColorMappingLuminanceMultiplier,
|
||||||
|
bool UseContinuousColor,
|
||||||
|
string ColorScheme,
|
||||||
|
float HillshadeLayerOpacity,
|
||||||
|
string LocationNamer,
|
||||||
|
|
||||||
|
string OverrideTimeZone,
|
||||||
|
bool DoDisplayTimeZone,
|
||||||
|
bool DoSwitchBackToHistory,
|
||||||
|
|
||||||
|
string NowcastWarningDelayTolerance,
|
||||||
|
|
||||||
|
string OverrideDisplayCulture,
|
||||||
|
IReadOnlyCollection<TTSCultureConfig> TTSCultures,
|
||||||
|
bool DoIgnoreLanguageVariant,
|
||||||
|
|
||||||
|
IReadOnlyCollection<EventSourceConfig> EventSources
|
||||||
|
) {
|
||||||
|
public static Config Default => new(
|
||||||
|
"Default",
|
||||||
|
1f,
|
||||||
|
false,
|
||||||
|
"Default",
|
||||||
|
1,
|
||||||
|
"FERegionLong",
|
||||||
|
|
||||||
|
null,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
|
||||||
|
"1:00:00",
|
||||||
|
|
||||||
|
"",
|
||||||
|
new List<TTSCultureConfig> { new(SharedCultures.CurrentUICulture) },
|
||||||
|
true,
|
||||||
|
|
||||||
|
new List<EventSourceConfig> {
|
||||||
|
new JMAAtomEventSourceConfig(Array.Empty<string>()),
|
||||||
|
new UpdateCheckerEventSourceConfig(),
|
||||||
|
new WolfxEventSourceConfig(Array.Empty<string>()),
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
[JsonPolymorphic(TypeDiscriminatorPropertyName = "Type", UnknownDerivedTypeHandling = JsonUnknownDerivedTypeHandling.FallBackToBaseType)]
|
||||||
|
[JsonDerivedType(typeof(BMKGOpenDataEventSourceConfig), "BMKGOpenData")]
|
||||||
|
[JsonDerivedType(typeof(CWAOpenDataEventSourceConfig), "CWAOpenData")]
|
||||||
|
[JsonDerivedType(typeof(EMSCRealTimeEventSourceConfig), "EMSCRealTime")]
|
||||||
|
[JsonDerivedType(typeof(FANStudioEventSourceConfig), "FANStudio")]
|
||||||
|
[JsonDerivedType(typeof(GeoNetEventSourceConfig), "GeoNet")]
|
||||||
|
[JsonDerivedType(typeof(GlobalQuakeServerEventSourceConfig), "GlobalQuakeServer")]
|
||||||
|
[JsonDerivedType(typeof(GlobalQuakeServer15EventSourceConfig), "GlobalQuakeServer15")]
|
||||||
|
[JsonDerivedType(typeof(JMAAtomEventSourceConfig), "JMAAtom")]
|
||||||
|
[JsonDerivedType(typeof(NOAAEventSourceConfig), "NOAA")]
|
||||||
|
[JsonDerivedType(typeof(UpdateCheckerEventSourceConfig), "UpdateChecker")]
|
||||||
|
[JsonDerivedType(typeof(USGSEventSourceConfig), "USGSQuakeML")]
|
||||||
|
[JsonDerivedType(typeof(WolfxEventSourceConfig), "Wolfx")]
|
||||||
|
abstract record EventSourceConfig();
|
||||||
|
record BMKGOpenDataEventSourceConfig([property: JsonRequired] string[] Subtypes) : EventSourceConfig;
|
||||||
|
record CWAOpenDataEventSourceConfig([property: JsonRequired] string Subtype, [property: JsonRequired] string Token) : EventSourceConfig;
|
||||||
|
record EMSCRealTimeEventSourceConfig() : EventSourceConfig;
|
||||||
|
record FANStudioEventSourceConfig([property: JsonRequired] string Subtype) : EventSourceConfig;
|
||||||
|
record GeoNetEventSourceConfig(int MinimumMMI = 3, bool DoGetFullHistory = false, bool DoGetStrongMotionInfo = true) : EventSourceConfig;
|
||||||
|
record GlobalQuakeServerEventSourceConfig([property: JsonRequired] string Host, int Port = 38000) : EventSourceConfig;
|
||||||
|
record GlobalQuakeServer15EventSourceConfig(string Host, int Port = 38000) : GlobalQuakeServerEventSourceConfig(Host, Port);
|
||||||
|
record JMAAtomEventSourceConfig(IReadOnlyCollection<string> Filter = null, bool IsFilterWhitelist = false) : EventSourceConfig;
|
||||||
|
record NOAAEventSourceConfig([property: JsonRequired] string Subtype) : EventSourceConfig;
|
||||||
|
record UpdateCheckerEventSourceConfig : EventSourceConfig;
|
||||||
|
record USGSEventSourceConfig([property: JsonRequired] string Subtype, bool UseGeoJSONFeeds, string[] Products) : EventSourceConfig;
|
||||||
|
record WolfxEventSourceConfig(IReadOnlyCollection<string> Filter = null, bool IsFilterWhitelist = false, bool UseRawCENCLocationName = false) : EventSourceConfig;
|
||||||
|
|
||||||
|
[JsonSerializable(typeof(Config))]
|
||||||
|
[JsonSourceGenerationOptions(Converters = new Type[] { typeof(CultureInfoConverter) }, WriteIndented = true)]
|
||||||
|
sealed partial class ConfigSerializationContext : JsonSerializerContext { }
|
||||||
|
|
||||||
|
sealed class CultureInfoConverter : JsonConverter<CultureInfo> {
|
||||||
|
public override CultureInfo Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) {
|
||||||
|
Debug.Assert(typeToConvert == typeof(CultureInfo));
|
||||||
|
var value = reader.GetString();
|
||||||
|
if (value == null) return CultureInfo.InvariantCulture;
|
||||||
|
if (value == "") return SharedCultures.CurrentUICulture;
|
||||||
|
return SharedCultures.Get(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Write(Utf8JsonWriter writer, CultureInfo value, JsonSerializerOptions options) {
|
||||||
|
writer.WriteStringValue(value.Name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -1,5 +1,5 @@
|
|||||||
fileFormatVersion: 2
|
fileFormatVersion: 2
|
||||||
guid: 4f85302336d038c4da80ea264d185657
|
guid: b478a322f8c49a247b6761de7b5c0e0a
|
||||||
MonoImporter:
|
MonoImporter:
|
||||||
externalObjects: {}
|
externalObjects: {}
|
||||||
serializedVersion: 2
|
serializedVersion: 2
|
@@ -3,8 +3,9 @@
|
|||||||
"rootNamespace": "",
|
"rootNamespace": "",
|
||||||
"references": [
|
"references": [
|
||||||
"GUID:b92f9c7ac10b1c04e86fc48210f62ab1",
|
"GUID:b92f9c7ac10b1c04e86fc48210f62ab1",
|
||||||
|
"GUID:1e0937e40dadba24a97b7342c4559580",
|
||||||
"GUID:e5b7e7f40a80a814ba706299d68f9213",
|
"GUID:e5b7e7f40a80a814ba706299d68f9213",
|
||||||
"GUID:da293eebbcb9a4947a212534c52d1a32"
|
"GUID:6055be8ebefd69e48b49212b09b47b2f"
|
||||||
],
|
],
|
||||||
"includePlatforms": [],
|
"includePlatforms": [],
|
||||||
"excludePlatforms": [],
|
"excludePlatforms": [],
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
using Cryville.EEW.Core.Map;
|
||||||
using System;
|
using System;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
@@ -10,26 +11,51 @@ namespace Cryville.EEW.Unity.Map {
|
|||||||
[SerializeField]
|
[SerializeField]
|
||||||
Transform m_layerTile;
|
Transform m_layerTile;
|
||||||
[SerializeField]
|
[SerializeField]
|
||||||
|
Transform m_layerTileHillshade;
|
||||||
|
[SerializeField]
|
||||||
MapElementManager m_layerElement;
|
MapElementManager m_layerElement;
|
||||||
[SerializeField]
|
[SerializeField]
|
||||||
MapElementManager m_layerElementSub;
|
MapElementManager m_layerElementSub;
|
||||||
[SerializeField]
|
[SerializeField]
|
||||||
GameObject m_prefabTile;
|
GameObject m_prefabTile;
|
||||||
|
[SerializeField]
|
||||||
|
GameObject m_prefabTileHillshade;
|
||||||
|
[SerializeField]
|
||||||
|
GameObject m_prefabBitmapHolder;
|
||||||
|
[SerializeField]
|
||||||
|
int m_maxMapTileZoom = 10;
|
||||||
|
[SerializeField]
|
||||||
|
bool m_isEditor;
|
||||||
|
|
||||||
readonly MapTileCacheManager _tiles = new();
|
MapTileCacheManager _tiles;
|
||||||
|
MapTileCacheManager _tilesHillshade;
|
||||||
float _elementLayerZ;
|
float _elementLayerZ;
|
||||||
|
|
||||||
void Start() {
|
void Start() {
|
||||||
_camera = GetComponent<Camera>();
|
_camera = GetComponent<Camera>();
|
||||||
|
_tiles = m_isEditor ? new EditorMapTileCacheManager() : new MapTileCacheManager();
|
||||||
|
_tiles.ExtraCachedZoomLevel = 20;
|
||||||
_tiles.Parent = m_layerTile;
|
_tiles.Parent = m_layerTile;
|
||||||
_tiles.PrefabTile = m_prefabTile;
|
_tiles.PrefabTile = m_prefabTile;
|
||||||
|
_tiles.PrefabBitmapHolder = m_prefabBitmapHolder;
|
||||||
_tiles.CacheDir = Application.temporaryCachePath;
|
_tiles.CacheDir = Application.temporaryCachePath;
|
||||||
|
if (m_layerTileHillshade) {
|
||||||
|
m_prefabTileHillshade.GetComponent<SpriteRenderer>().sharedMaterial.color = new UnityEngine.Color(1, 1, 1, SharedSettings.Instance.HillshadeLayerOpacity);
|
||||||
|
_tilesHillshade = new HillshadeMapTileCacheManager {
|
||||||
|
ExtraCachedZoomLevel = 20,
|
||||||
|
Parent = m_layerTileHillshade,
|
||||||
|
PrefabTile = m_prefabTileHillshade,
|
||||||
|
PrefabBitmapHolder = m_prefabBitmapHolder,
|
||||||
|
CacheDir = Application.temporaryCachePath,
|
||||||
|
};
|
||||||
|
}
|
||||||
_camera.orthographicSize = 0.5f / MathF.Max(1, (float)_camera.pixelWidth / _camera.pixelHeight);
|
_camera.orthographicSize = 0.5f / MathF.Max(1, (float)_camera.pixelWidth / _camera.pixelHeight);
|
||||||
_elementLayerZ = m_layerElement.transform.position.z;
|
if (m_layerElement != null) _elementLayerZ = m_layerElement.transform.position.z;
|
||||||
UpdateTransform();
|
_mapElementUpdated = true;
|
||||||
}
|
}
|
||||||
void OnDestroy() {
|
void OnDestroy() {
|
||||||
_tiles.Dispose();
|
_tiles.Dispose();
|
||||||
|
_tilesHillshade?.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
float Scale {
|
float Scale {
|
||||||
@@ -39,7 +65,9 @@ namespace Cryville.EEW.Unity.Map {
|
|||||||
|
|
||||||
static readonly Rect _viewportRect = new(0, 0, 1, 1);
|
static readonly Rect _viewportRect = new(0, 0, 1, 1);
|
||||||
Vector3? ppos;
|
Vector3? ppos;
|
||||||
|
bool _mapElementUpdated;
|
||||||
void Update() {
|
void Update() {
|
||||||
|
bool flag = false;
|
||||||
var cpos = Input.mousePosition;
|
var cpos = Input.mousePosition;
|
||||||
bool isMouseInViewport = _viewportRect.Contains(_camera.ScreenToViewportPoint(Input.mousePosition));
|
bool isMouseInViewport = _viewportRect.Contains(_camera.ScreenToViewportPoint(Input.mousePosition));
|
||||||
if (Input.GetMouseButtonDown(0) && isMouseInViewport) {
|
if (Input.GetMouseButtonDown(0) && isMouseInViewport) {
|
||||||
@@ -49,19 +77,26 @@ namespace Cryville.EEW.Unity.Map {
|
|||||||
var delta = _camera.ScreenToWorldPoint(pos0) - _camera.ScreenToWorldPoint(cpos);
|
var delta = _camera.ScreenToWorldPoint(pos0) - _camera.ScreenToWorldPoint(cpos);
|
||||||
transform.position += delta;
|
transform.position += delta;
|
||||||
ppos = cpos;
|
ppos = cpos;
|
||||||
UpdateTransform();
|
flag = true;
|
||||||
}
|
}
|
||||||
if (Input.GetMouseButtonUp(0)) {
|
if (Input.GetMouseButtonUp(0)) {
|
||||||
ppos = null;
|
ppos = null;
|
||||||
}
|
}
|
||||||
if (Input.mouseScrollDelta.y != 0 && isMouseInViewport) {
|
if (Input.mouseScrollDelta.y != 0 && isMouseInViewport) {
|
||||||
Scale *= Mathf.Pow(2, -Input.mouseScrollDelta.y / 8);
|
Scale *= Mathf.Pow(2, -Input.mouseScrollDelta.y / 8);
|
||||||
UpdateTransform();
|
flag = true;
|
||||||
|
}
|
||||||
|
if (_mapElementUpdated) {
|
||||||
|
_mapElementUpdated = false;
|
||||||
|
ZoomToMapElement();
|
||||||
|
flag = true;
|
||||||
|
}
|
||||||
|
if (flag) {
|
||||||
|
UpdateTransform(); // Ensure UpdateTransform is called at most once per frame for tiles to unload correctly
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
void ZoomToMapElement() {
|
||||||
public void OnMapElementUpdated() {
|
var aabb = m_layerElement != null ? m_layerElement.AABB : null;
|
||||||
var aabb = m_layerElement.AABB;
|
|
||||||
if (aabb is not RectangleF b) return;
|
if (aabb is not RectangleF b) return;
|
||||||
if (b.Width * _camera.pixelHeight < _camera.pixelWidth * b.Height)
|
if (b.Width * _camera.pixelHeight < _camera.pixelWidth * b.Height)
|
||||||
Scale = b.Height;
|
Scale = b.Height;
|
||||||
@@ -70,7 +105,9 @@ namespace Cryville.EEW.Unity.Map {
|
|||||||
Scale *= 0.6f;
|
Scale *= 0.6f;
|
||||||
if (Scale < 0.01f) Scale = 0.01f;
|
if (Scale < 0.01f) Scale = 0.01f;
|
||||||
transform.localPosition = new PointF(b.X + b.Width / 2, b.Y + b.Height / 2).ToVector2();
|
transform.localPosition = new PointF(b.X + b.Width / 2, b.Y + b.Height / 2).ToVector2();
|
||||||
UpdateTransform();
|
}
|
||||||
|
public void OnMapElementUpdated() {
|
||||||
|
_mapElementUpdated = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void UpdateTransform() {
|
void UpdateTransform() {
|
||||||
@@ -82,14 +119,17 @@ namespace Cryville.EEW.Unity.Map {
|
|||||||
transform.localPosition = new(nx, Math.Clamp(transform.position.y, h / 2 - 1, -h / 2), -20);
|
transform.localPosition = new(nx, Math.Clamp(transform.position.y, h / 2 - 1, -h / 2), -20);
|
||||||
|
|
||||||
var bounds = new Bounds((Vector2)transform.position, new Vector2(w, h));
|
var bounds = new Bounds((Vector2)transform.position, new Vector2(w, h));
|
||||||
int zoom = Math.Clamp((int)Math.Log(vz / 256, 2) + 1, 0, 10);
|
int zoom = Math.Clamp((int)Math.Log(vz / 256, 2) + 1, 0, m_maxMapTileZoom);
|
||||||
int zoomScale = 1 << zoom;
|
int zoomScale = 1 << zoom;
|
||||||
_tiles.MoveTo(
|
var a = new MapTileIndex(Mathf.FloorToInt(bounds.min.x * zoomScale), Mathf.FloorToInt(-bounds.max.y * zoomScale), zoom);
|
||||||
new(Mathf.FloorToInt(bounds.min.x * zoomScale), Mathf.FloorToInt(-bounds.max.y * zoomScale), zoom),
|
var b = new MapTileIndex(Mathf.CeilToInt(bounds.max.x * zoomScale), Mathf.CeilToInt(-bounds.min.y * zoomScale), zoom);
|
||||||
new(Mathf.CeilToInt(bounds.max.x * zoomScale), Mathf.CeilToInt(-bounds.min.y * zoomScale), zoom)
|
_tiles.MoveTo(a, b);
|
||||||
);
|
_tilesHillshade?.MoveTo(a, b);
|
||||||
|
|
||||||
|
if (m_layerElement != null) {
|
||||||
m_layerElement.Scale = h;
|
m_layerElement.Scale = h;
|
||||||
|
}
|
||||||
|
if (m_layerElementSub != null) {
|
||||||
m_layerElementSub.Scale = h;
|
m_layerElementSub.Scale = h;
|
||||||
|
|
||||||
if (nx - w / 2 < 0) {
|
if (nx - w / 2 < 0) {
|
||||||
@@ -106,3 +146,4 @@ namespace Cryville.EEW.Unity.Map {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
@@ -4,7 +4,7 @@ MonoImporter:
|
|||||||
externalObjects: {}
|
externalObjects: {}
|
||||||
serializedVersion: 2
|
serializedVersion: 2
|
||||||
defaultReferences: []
|
defaultReferences: []
|
||||||
executionOrder: 0
|
executionOrder: 5
|
||||||
icon: {instanceID: 0}
|
icon: {instanceID: 0}
|
||||||
userData:
|
userData:
|
||||||
assetBundleName:
|
assetBundleName:
|
||||||
|
15
Assets/Cryville.EEW.Unity/Map/EditorMapTileCacheManager.cs
Normal file
15
Assets/Cryville.EEW.Unity/Map/EditorMapTileCacheManager.cs
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
using Cryville.EEW.Core.Map;
|
||||||
|
using System.IO;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace Cryville.EEW.Unity.Map {
|
||||||
|
sealed class EditorMapTileCacheManager : MapTileCacheManager {
|
||||||
|
protected override MapTileBitmapHolder CreateBitmapHolder(MapTileIndex index) => new(
|
||||||
|
index,
|
||||||
|
GameObject.Instantiate(PrefabBitmapHolder, Parent, false),
|
||||||
|
new($"https://tile.openstreetmap.org/{index.Z}/{index.NX}/{index.NY}.png")
|
||||||
|
);
|
||||||
|
|
||||||
|
protected override string GetCacheFilePath(MapTileIndex index) => Path.Combine(CacheDir, $"map_editor/{index.Z}/{index.NX}/{index.NY}");
|
||||||
|
}
|
||||||
|
}
|
@@ -1,5 +1,5 @@
|
|||||||
fileFormatVersion: 2
|
fileFormatVersion: 2
|
||||||
guid: 225b67dcce9247b4c806e435b34695d2
|
guid: 478198b8ecc0082449fa3f68795174a9
|
||||||
MonoImporter:
|
MonoImporter:
|
||||||
externalObjects: {}
|
externalObjects: {}
|
||||||
serializedVersion: 2
|
serializedVersion: 2
|
@@ -98,24 +98,25 @@ namespace Cryville.EEW.Unity.Map.Element {
|
|||||||
for (int d = 0; d < 360; d++) {
|
for (int d = 0; d < 360; d++) {
|
||||||
Quaternion q = Quaternion.AngleAxis(d, axis);
|
Quaternion q = Quaternion.AngleAxis(d, axis);
|
||||||
Vector3 p = q * rp;
|
Vector3 p = q * rp;
|
||||||
Vector2 p2 = ToTilePos(p).ToVector2();
|
AddVertex(renderer, ref lp2, ref segmentIndex, d, p);
|
||||||
if (lp2 != null) {
|
|
||||||
float dx = p2.x - lp2.Value.x;
|
|
||||||
if (MathF.Abs(dx) >= 0.5) {
|
|
||||||
_vertexBuffer[d] = p2.x < 0.5 ? p2 + new Vector2(1, 0) : p2 - new Vector2(1, 0);
|
|
||||||
renderer.AddSegment(_vertexBuffer, segmentIndex, d - segmentIndex + 1);
|
|
||||||
segmentIndex = d;
|
|
||||||
}
|
}
|
||||||
}
|
AddVertex(renderer, ref lp2, ref segmentIndex, 360, rp);
|
||||||
_vertexBuffer[d] = p2;
|
|
||||||
lp2 = p2;
|
|
||||||
}
|
|
||||||
Vector2 rp2 = ToTilePos(rp).ToVector2();
|
|
||||||
_vertexBuffer[360] = rp2;
|
|
||||||
renderer.AddSegment(_vertexBuffer, segmentIndex, 361 - segmentIndex);
|
renderer.AddSegment(_vertexBuffer, segmentIndex, 361 - segmentIndex);
|
||||||
}
|
}
|
||||||
renderer.SetMaterial(isHistory ? m_historyMaterial : m_ongoingMaterial);
|
renderer.SetMaterial(isHistory ? m_historyMaterial : m_ongoingMaterial);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AddVertex(MultiLineRenderer renderer, ref Vector2? lp2, ref int segmentIndex, int d, Vector3 p) {
|
||||||
|
Vector2 p2 = ToTilePos(p).ToVector2();
|
||||||
|
if (lp2 != null && MathF.Abs(p2.x - lp2.Value.x) >= 0.5) {
|
||||||
|
_vertexBuffer[d] = p2.x < 0.5 ? p2 + new Vector2(1, 0) : p2 - new Vector2(1, 0);
|
||||||
|
renderer.AddSegment(_vertexBuffer, segmentIndex, d - segmentIndex + 1);
|
||||||
|
segmentIndex = d;
|
||||||
|
}
|
||||||
|
_vertexBuffer[d] = p2;
|
||||||
|
lp2 = p2;
|
||||||
|
}
|
||||||
|
|
||||||
static PointF ToTilePos(Vector3 p) => MapTileUtils.WorldToTilePos(new(MathF.Atan2(p.z, p.x) / MathF.PI * 180f, MathF.Asin(p.y) / MathF.PI * 180f));
|
static PointF ToTilePos(Vector3 p) => MapTileUtils.WorldToTilePos(new(MathF.Atan2(p.z, p.x) / MathF.PI * 180f, MathF.Asin(p.y) / MathF.PI * 180f));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,15 @@
|
|||||||
|
using Cryville.EEW.Core.Map;
|
||||||
|
using System.IO;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace Cryville.EEW.Unity.Map {
|
||||||
|
sealed class HillshadeMapTileCacheManager : MapTileCacheManager {
|
||||||
|
protected override MapTileBitmapHolder CreateBitmapHolder(MapTileIndex index) => new(
|
||||||
|
index,
|
||||||
|
GameObject.Instantiate(PrefabBitmapHolder, Parent, false),
|
||||||
|
new($"https://services.arcgisonline.com/arcgis/rest/services/Elevation/World_Hillshade/MapServer/tile/{index.Z}/{index.NY}/{index.NX}.png")
|
||||||
|
);
|
||||||
|
|
||||||
|
protected override string GetCacheFilePath(MapTileIndex index) => Path.Combine(CacheDir, $"map_hillshade/{index.Z}/{index.NX}/{index.NY}");
|
||||||
|
}
|
||||||
|
}
|
@@ -1,5 +1,5 @@
|
|||||||
fileFormatVersion: 2
|
fileFormatVersion: 2
|
||||||
guid: f0dddddc28f728c42a1fed80ba8f95cc
|
guid: d5fed9b884a4ff54f837aa0f2265ad36
|
||||||
MonoImporter:
|
MonoImporter:
|
||||||
externalObjects: {}
|
externalObjects: {}
|
||||||
serializedVersion: 2
|
serializedVersion: 2
|
@@ -13,11 +13,16 @@ namespace Cryville.EEW.Unity.Map {
|
|||||||
[RequireComponent(typeof(MeshFilter))]
|
[RequireComponent(typeof(MeshFilter))]
|
||||||
[RequireComponent(typeof(MeshRenderer))]
|
[RequireComponent(typeof(MeshRenderer))]
|
||||||
class LineRenderer : MonoBehaviour {
|
class LineRenderer : MonoBehaviour {
|
||||||
|
Material _sharedMaterial;
|
||||||
public Material Material {
|
public Material Material {
|
||||||
get => _meshRenderer.material;
|
get => _meshRenderer.sharedMaterial;
|
||||||
set {
|
set {
|
||||||
_meshRenderer.material = value;
|
if (value == _sharedMaterial) return;
|
||||||
_meshRenderer.material.color = m_color;
|
if (_sharedMaterial != null) Destroy(_meshRenderer.sharedMaterial);
|
||||||
|
_sharedMaterial = value;
|
||||||
|
if (_sharedMaterial == null) return;
|
||||||
|
_meshRenderer.sharedMaterial = Instantiate(_sharedMaterial);
|
||||||
|
_meshRenderer.sharedMaterial.color = m_color;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -28,7 +33,7 @@ namespace Cryville.EEW.Unity.Map {
|
|||||||
set {
|
set {
|
||||||
if (m_color == value) return;
|
if (m_color == value) return;
|
||||||
m_color = value;
|
m_color = value;
|
||||||
_meshRenderer.material.color = value;
|
_meshRenderer.sharedMaterial.color = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -126,12 +131,17 @@ namespace Cryville.EEW.Unity.Map {
|
|||||||
_meshFilter.mesh = new();
|
_meshFilter.mesh = new();
|
||||||
}
|
}
|
||||||
_mesh = _meshFilter.mesh;
|
_mesh = _meshFilter.mesh;
|
||||||
_meshRenderer.material.color = m_color;
|
if (_sharedMaterial == null && _meshRenderer.sharedMaterial != null) {
|
||||||
|
_sharedMaterial = _meshRenderer.sharedMaterial;
|
||||||
|
_meshRenderer.sharedMaterial = Instantiate(_sharedMaterial);
|
||||||
|
_meshRenderer.sharedMaterial.color = m_color;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
void OnDestroy() {
|
void OnDestroy() {
|
||||||
if (_positions is not null)
|
if (_positions is not null)
|
||||||
ArrayPool<Vector2>.Shared.Return(_positions);
|
ArrayPool<Vector2>.Shared.Return(_positions);
|
||||||
Destroy(_mesh);
|
Destroy(_mesh);
|
||||||
|
Destroy(Material);
|
||||||
}
|
}
|
||||||
void LateUpdate() {
|
void LateUpdate() {
|
||||||
if (_valid) return;
|
if (_valid) return;
|
||||||
@@ -140,12 +150,8 @@ namespace Cryville.EEW.Unity.Map {
|
|||||||
_mesh.Clear();
|
_mesh.Clear();
|
||||||
if (_positions == null) return;
|
if (_positions == null) return;
|
||||||
if (_positionCount <= 1) return;
|
if (_positionCount <= 1) return;
|
||||||
float hw = m_width / 2;
|
|
||||||
int maxVertexCount = 4 * (_positionCount - 1);
|
|
||||||
var vbuf = ArrayPool<Vector3>.Shared.Rent(maxVertexCount);
|
|
||||||
var ubuf = ArrayPool<Vector2>.Shared.Rent(maxVertexCount);
|
|
||||||
var ibuf = ArrayPool<int>.Shared.Rent(3 * (2 + 4 * (_positionCount - 2)));
|
|
||||||
|
|
||||||
|
float hw = m_width / 2;
|
||||||
int i, vi = 0, ii = 0, li = 0, ri = 1;
|
int i, vi = 0, ii = 0, li = 0, ri = 1;
|
||||||
float uvScale = 1 / (m_tilingScale * m_width);
|
float uvScale = 1 / (m_tilingScale * m_width);
|
||||||
Vector2 p0 = _positions[0], p1 = default;
|
Vector2 p0 = _positions[0], p1 = default;
|
||||||
@@ -153,6 +159,12 @@ namespace Cryville.EEW.Unity.Map {
|
|||||||
if ((p1 = _positions[i]) != p0) break;
|
if ((p1 = _positions[i]) != p0) break;
|
||||||
}
|
}
|
||||||
if (i >= _positionCount) return;
|
if (i >= _positionCount) return;
|
||||||
|
|
||||||
|
int maxVertexCount = 4 * (_positionCount - 1);
|
||||||
|
var vbuf = ArrayPool<Vector3>.Shared.Rent(maxVertexCount);
|
||||||
|
var ubuf = ArrayPool<Vector2>.Shared.Rent(maxVertexCount);
|
||||||
|
var ibuf = ArrayPool<int>.Shared.Rent(3 * (2 + 4 * (_positionCount - 2)));
|
||||||
|
|
||||||
Vector2 dp0 = NormalizeSmallVector(p1 - p0), np0 = GetNormal(dp0 * hw);
|
Vector2 dp0 = NormalizeSmallVector(p1 - p0), np0 = GetNormal(dp0 * hw);
|
||||||
vbuf[vi] = p0 - np0; ubuf[vi++] = new(0, 0);
|
vbuf[vi] = p0 - np0; ubuf[vi++] = new(0, 0);
|
||||||
vbuf[vi] = p0 + np0; ubuf[vi++] = new(0, 1);
|
vbuf[vi] = p0 + np0; ubuf[vi++] = new(0, 1);
|
||||||
|
@@ -1,10 +1,16 @@
|
|||||||
|
using Cryville.EEW.BMKGOpenData.Map;
|
||||||
using Cryville.EEW.Core;
|
using Cryville.EEW.Core;
|
||||||
using Cryville.EEW.CWAOpenData.Map;
|
using Cryville.EEW.CWAOpenData.Map;
|
||||||
|
using Cryville.EEW.EMSC.Map;
|
||||||
|
using Cryville.EEW.FANStudio.Map;
|
||||||
|
using Cryville.EEW.GeoNet.Map;
|
||||||
using Cryville.EEW.GlobalQuake.Map;
|
using Cryville.EEW.GlobalQuake.Map;
|
||||||
using Cryville.EEW.JMAAtom.Map;
|
using Cryville.EEW.JMAAtom.Map;
|
||||||
using Cryville.EEW.Map;
|
using Cryville.EEW.Map;
|
||||||
using Cryville.EEW.NOAA.Map;
|
using Cryville.EEW.NOAA.Map;
|
||||||
|
using Cryville.EEW.QuakeML.Map;
|
||||||
using Cryville.EEW.Report;
|
using Cryville.EEW.Report;
|
||||||
|
using Cryville.EEW.USGS.Map;
|
||||||
using Cryville.EEW.Wolfx.Map;
|
using Cryville.EEW.Wolfx.Map;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
@@ -22,6 +28,9 @@ namespace Cryville.EEW.Unity.Map {
|
|||||||
readonly List<ReportViewModel> _displayingReports = new();
|
readonly List<ReportViewModel> _displayingReports = new();
|
||||||
readonly List<int> _displayingOrder = new();
|
readonly List<int> _displayingOrder = new();
|
||||||
|
|
||||||
|
public int Count => _displayingReports.Count;
|
||||||
|
public int OngoingCount => _displayingReports.Count - (_selected != null ? 1 : 0);
|
||||||
|
|
||||||
[SerializeField] MapElementManager m_subManager;
|
[SerializeField] MapElementManager m_subManager;
|
||||||
|
|
||||||
public RectangleF? AABB {
|
public RectangleF? AABB {
|
||||||
@@ -37,25 +46,44 @@ namespace Cryville.EEW.Unity.Map {
|
|||||||
return _displayingElements[index].AABB;
|
return _displayingElements[index].AABB;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddOngoing(ReportViewModel e) => Add(e);
|
public void SetSelected(ReportViewModel e, bool forced = false) {
|
||||||
public void RemoveOngoing(ReportViewModel e) => Remove(e);
|
if (e == null) {
|
||||||
public void SetSelected(ReportViewModel e) {
|
|
||||||
if (_selected is not null)
|
|
||||||
Remove(_selected);
|
Remove(_selected);
|
||||||
if (e == null || _displayingReports.Contains(e)) {
|
|
||||||
_selected = null;
|
_selected = null;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Add(e);
|
if (_displayingReports.Contains(e)) {
|
||||||
|
if (forced) return;
|
||||||
|
Remove(_selected);
|
||||||
|
_selected = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (e.IsExcludedFromHistory)
|
||||||
|
return;
|
||||||
|
if (!Add(e))
|
||||||
|
return;
|
||||||
|
if (_selected is not null)
|
||||||
|
Remove(_selected);
|
||||||
_selected = e;
|
_selected = e;
|
||||||
}
|
}
|
||||||
public void SetCurrent(ReportViewModel e) {
|
public bool SetCurrent(ReportViewModel e) {
|
||||||
|
if (e == null) {
|
||||||
|
_current = null;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (!_displayingReports.Contains(e)) {
|
||||||
|
_current = null;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (_current == e)
|
||||||
|
return false;
|
||||||
_current = e;
|
_current = e;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Add(ReportViewModel e) {
|
public bool Add(ReportViewModel e) {
|
||||||
var element = Build(e.Model, out _, out int order);
|
var element = Build(e.Model, out _, out int order);
|
||||||
if (element == null) return;
|
if (element == null) return false;
|
||||||
var pos = element.transform.localPosition;
|
var pos = element.transform.localPosition;
|
||||||
pos.z = OrderToZ(_displayingOrder.Sum());
|
pos.z = OrderToZ(_displayingOrder.Sum());
|
||||||
element.transform.localPosition = pos;
|
element.transform.localPosition = pos;
|
||||||
@@ -64,8 +92,10 @@ namespace Cryville.EEW.Unity.Map {
|
|||||||
_displayingOrder.Add(order);
|
_displayingOrder.Add(order);
|
||||||
element.transform.SetParent(transform, false);
|
element.transform.SetParent(transform, false);
|
||||||
if (m_subManager != null) m_subManager.Add(e);
|
if (m_subManager != null) m_subManager.Add(e);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
void Remove(ReportViewModel e) {
|
public void Remove(ReportViewModel e) {
|
||||||
|
if (_current == e) _current = null;
|
||||||
int index = _displayingReports.IndexOf(e);
|
int index = _displayingReports.IndexOf(e);
|
||||||
if (index == -1) return;
|
if (index == -1) return;
|
||||||
_displayingElements.RemoveAt(index);
|
_displayingElements.RemoveAt(index);
|
||||||
@@ -100,17 +130,28 @@ namespace Cryville.EEW.Unity.Map {
|
|||||||
}
|
}
|
||||||
|
|
||||||
readonly ContextedGeneratorManager<IMapGeneratorContext, MapElement> _gen = new(new IContextedGenerator<IMapGeneratorContext, MapElement>[] {
|
readonly ContextedGeneratorManager<IMapGeneratorContext, MapElement> _gen = new(new IContextedGenerator<IMapGeneratorContext, MapElement>[] {
|
||||||
|
new BMKGEarthquakeMapGenerator(),
|
||||||
|
new CEAEEWMapGenerator(),
|
||||||
new CENCEarthquakeMapGenerator(),
|
new CENCEarthquakeMapGenerator(),
|
||||||
new CENCEEWMapGenerator(),
|
new CENCEEWMapGenerator(),
|
||||||
new CWAEarthquakeMapGenerator(),
|
new CWAEarthquakeMapGenerator(),
|
||||||
new CWAEEWMapGenerator(),
|
new CWAEEWMapGenerator(),
|
||||||
new CWATsunamiMapGenerator(),
|
new CWATsunamiMapGenerator(),
|
||||||
new FujianEEWMapGenerator(),
|
new EMSCRealTimeEventMapGenerator(),
|
||||||
|
new FANStudio.Map.FujianEEWMapGenerator(),
|
||||||
|
new Wolfx.Map.FujianEEWMapGenerator(),
|
||||||
|
new GeoNetQuakeHistoryMapGenerator(),
|
||||||
|
new GeoNetQuakeMapGenerator(),
|
||||||
|
new GeoNetStrongMapGenerator(),
|
||||||
new GlobalQuakeMapViewGenerator(),
|
new GlobalQuakeMapViewGenerator(),
|
||||||
|
new ICLEEWMapGenerator(),
|
||||||
new JMAAtomMapGenerator(),
|
new JMAAtomMapGenerator(),
|
||||||
new JMAEEWMapGenerator(),
|
new JMAEEWMapGenerator(),
|
||||||
new NOAAMapGenerator(),
|
new NOAAMapGenerator(),
|
||||||
new SichuanEEWMapGenerator(),
|
new FANStudio.Map.SichuanEEWMapGenerator(),
|
||||||
|
new Wolfx.Map.SichuanEEWMapGenerator(),
|
||||||
|
new QuakeMLEventMapGenerator(),
|
||||||
|
new USGSContoursMapGenerator(),
|
||||||
});
|
});
|
||||||
public UnityMapElement Build(object e, out CultureInfo culture, out int order) {
|
public UnityMapElement Build(object e, out CultureInfo culture, out int order) {
|
||||||
culture = CultureInfo.InvariantCulture;
|
culture = CultureInfo.InvariantCulture;
|
||||||
|
@@ -1,115 +1,50 @@
|
|||||||
using Cryville.EEW.Core.Map;
|
using Cryville.EEW.Core.Map;
|
||||||
using System;
|
|
||||||
using System.Diagnostics.CodeAnalysis;
|
|
||||||
using System.IO;
|
|
||||||
using System.Net.Http;
|
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.Networking;
|
|
||||||
|
|
||||||
namespace Cryville.EEW.Unity.Map {
|
namespace Cryville.EEW.Unity.Map {
|
||||||
[RequireComponent(typeof(SpriteRenderer))]
|
[RequireComponent(typeof(SpriteRenderer))]
|
||||||
sealed class MapTile : MonoBehaviour {
|
sealed class MapTile : MonoBehaviour {
|
||||||
static readonly SemaphoreSlim _semaphore = new(2);
|
|
||||||
|
|
||||||
static readonly HttpClient _httpClient = new() { Timeout = TimeSpan.FromSeconds(10) };
|
|
||||||
|
|
||||||
[SerializeField] Transform _idView;
|
[SerializeField] Transform _idView;
|
||||||
|
|
||||||
public MapTileIndex Index { get; set; }
|
public MapTileIndex Index { get; set; }
|
||||||
public bool IsEmpty { get; private set; }
|
|
||||||
|
|
||||||
Action<MapTile> _callback;
|
|
||||||
|
|
||||||
SpriteRenderer _renderer;
|
SpriteRenderer _renderer;
|
||||||
|
|
||||||
UnityWebRequest _req;
|
|
||||||
DownloadHandlerTexture _texHandler;
|
|
||||||
Texture2D _tex;
|
|
||||||
Sprite _sprite;
|
|
||||||
|
|
||||||
void Awake() {
|
void Awake() {
|
||||||
_renderer = GetComponent<SpriteRenderer>();
|
_renderer = GetComponent<SpriteRenderer>();
|
||||||
}
|
}
|
||||||
|
|
||||||
FileInfo _localFile;
|
public void Init(MapTileIndex index) {
|
||||||
bool _downloadDone;
|
|
||||||
public void Load(MapTileIndex index, string cacheDir, Action<MapTile> onUpdated) {
|
|
||||||
Index = index;
|
Index = index;
|
||||||
_callback = onUpdated;
|
|
||||||
_localFile = new(Path.Combine(cacheDir, $"map/{Index.Z}/{Index.NX}/{Index.NY}"));
|
|
||||||
float z = 1 << index.Z;
|
float z = 1 << index.Z;
|
||||||
transform.localPosition = new(index.X / z, -(index.Y + 1) / z, -index.Z / 100f);
|
transform.localPosition = new(index.X / z, -(index.Y + 1) / z, -index.Z / 100f);
|
||||||
transform.localScale = new Vector3(1 / z, 1 / z, 1);
|
transform.localScale = new Vector3(1 / z, 1 / z, 1);
|
||||||
|
if (_idView) {
|
||||||
_idView.gameObject.SetActive(true);
|
_idView.gameObject.SetActive(true);
|
||||||
byte e = SharedSettings.Instance.IdBytes[((index.X << 2) + index.Y) & 0x1f];
|
byte e = SharedSettings.Instance.IdBytes[((index.X << 2) + index.Y) & 0x1f];
|
||||||
int ex = e >> 4, ey = e & 0xf;
|
int ex = e >> 4, ey = e & 0xf;
|
||||||
_idView.localPosition = new(ex / 16f, 1 - ey / 16f, -1 / 200f);
|
_idView.localPosition = new(ex / 16f, 1 - ey / 16f, -1 / 200f);
|
||||||
if (_localFile.Exists) {
|
|
||||||
_downloadDone = true;
|
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
Task.Run(() => RunAsync($"https://server.arcgisonline.com/ArcGIS/rest/services/Ocean/World_Ocean_Base/MapServer/tile/{Index.Z}/{Index.NY}/{Index.NX}"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
async Task RunAsync(string url) {
|
|
||||||
await _semaphore.WaitAsync().ConfigureAwait(true);
|
|
||||||
try {
|
|
||||||
Directory.CreateDirectory(_localFile.DirectoryName);
|
|
||||||
using var webStream = await _httpClient.GetStreamAsync(new Uri(url)).ConfigureAwait(true);
|
|
||||||
using var fileStream = new FileStream(_localFile.FullName, FileMode.Create, FileAccess.Write);
|
|
||||||
await webStream.CopyToAsync(fileStream).ConfigureAwait(true);
|
|
||||||
}
|
|
||||||
finally {
|
|
||||||
_semaphore.Release();
|
|
||||||
}
|
|
||||||
_downloadDone = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[SuppressMessage("CodeQuality", "IDE0051", Justification = "Unity message")]
|
public void Set(Sprite sprite) {
|
||||||
|
if (_renderer) {
|
||||||
|
_renderer.sprite = sprite;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool _isDestroyed;
|
||||||
|
public void Destroy() {
|
||||||
|
_isDestroyed = true;
|
||||||
|
}
|
||||||
void Update() {
|
void Update() {
|
||||||
if (_downloadDone) {
|
if (_isDestroyed) {
|
||||||
try {
|
Destroy(gameObject);
|
||||||
_texHandler = new DownloadHandlerTexture();
|
|
||||||
_req = new UnityWebRequest($"file:///{_localFile}") {
|
|
||||||
downloadHandler = _texHandler,
|
|
||||||
disposeDownloadHandlerOnDispose = true,
|
|
||||||
};
|
|
||||||
_req.SendWebRequest();
|
|
||||||
}
|
}
|
||||||
catch (Exception ex) {
|
|
||||||
Debug.LogException(ex);
|
|
||||||
}
|
|
||||||
_downloadDone = false;
|
|
||||||
}
|
|
||||||
if (_req == null || !_req.isDone) return;
|
|
||||||
if (_texHandler.isDone) {
|
|
||||||
_tex = _texHandler.texture;
|
|
||||||
_tex.wrapMode = TextureWrapMode.Clamp;
|
|
||||||
_sprite = Sprite.Create(_tex, new Rect(0, 0, _tex.width, _tex.height), Vector2.zero, _tex.height);
|
|
||||||
_renderer.sprite = _sprite;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Debug.LogError(_req.error);
|
|
||||||
_localFile.Delete();
|
|
||||||
IsEmpty = true;
|
|
||||||
}
|
|
||||||
_req.Dispose();
|
|
||||||
_req = null;
|
|
||||||
_callback?.Invoke(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[SuppressMessage("CodeQuality", "IDE0051", Justification = "Unity message")]
|
public void SetVisible(bool v) {
|
||||||
void OnDestroy() {
|
_renderer.enabled = v;
|
||||||
if (_req != null) {
|
|
||||||
_req.Abort();
|
|
||||||
_req.Dispose();
|
|
||||||
}
|
|
||||||
if (_sprite) Destroy(_sprite);
|
|
||||||
if (_tex) Destroy(_tex);
|
|
||||||
IsEmpty = true;
|
|
||||||
_callback?.Invoke(this);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
49
Assets/Cryville.EEW.Unity/Map/MapTileBitmapHolder.cs
Normal file
49
Assets/Cryville.EEW.Unity/Map/MapTileBitmapHolder.cs
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
using Cryville.EEW.Core.Map;
|
||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace Cryville.EEW.Unity.Map {
|
||||||
|
sealed class MapTileBitmapHolder : Core.Map.MapTileBitmapHolder {
|
||||||
|
readonly MapTileBitmapHolderBehaviour _behaviour;
|
||||||
|
readonly Uri _uri;
|
||||||
|
|
||||||
|
public MapTileBitmapHolder(MapTileIndex index, GameObject gameObject, Uri uri) : base(index) {
|
||||||
|
_behaviour = gameObject.GetComponent<MapTileBitmapHolderBehaviour>();
|
||||||
|
_behaviour.Index = index;
|
||||||
|
_uri = uri;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Dispose(bool disposing) {
|
||||||
|
base.Dispose(disposing);
|
||||||
|
if (disposing) {
|
||||||
|
if (_behaviour) _behaviour.Destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override Uri GetUri() => _uri;
|
||||||
|
|
||||||
|
protected override Task LoadBitmap(FileInfo file, CancellationToken cancellationToken) {
|
||||||
|
_behaviour.Load(file);
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Bind(MapTile tile) {
|
||||||
|
_behaviour.Bind(tile);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Unbind(MapTile tile) {
|
||||||
|
_behaviour.Unbind(tile);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddChild(MapTileBitmapHolder bitmapHolder) {
|
||||||
|
_behaviour.AddChild(bitmapHolder._behaviour);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RemoveChild(MapTileBitmapHolder bitmapHolder) {
|
||||||
|
_behaviour.RemoveChild(bitmapHolder._behaviour);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
11
Assets/Cryville.EEW.Unity/Map/MapTileBitmapHolder.cs.meta
Normal file
11
Assets/Cryville.EEW.Unity/Map/MapTileBitmapHolder.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: f7ad3a3ac7d829249ba21987d585b07f
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
127
Assets/Cryville.EEW.Unity/Map/MapTileBitmapHolderBehaviour.cs
Normal file
127
Assets/Cryville.EEW.Unity/Map/MapTileBitmapHolderBehaviour.cs
Normal file
@@ -0,0 +1,127 @@
|
|||||||
|
using Cryville.EEW.Core.Map;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.Networking;
|
||||||
|
|
||||||
|
namespace Cryville.EEW.Unity.Map {
|
||||||
|
sealed class MapTileBitmapHolderBehaviour : MonoBehaviour {
|
||||||
|
public MapTileIndex Index { get; set; }
|
||||||
|
|
||||||
|
readonly List<MapTile> _tiles = new();
|
||||||
|
public void Bind(MapTile tile) {
|
||||||
|
_tiles.Add(tile);
|
||||||
|
if (_sprite) {
|
||||||
|
tile.Set(_sprite);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public void Unbind(MapTile tile) {
|
||||||
|
_tiles.Remove(tile);
|
||||||
|
}
|
||||||
|
|
||||||
|
readonly List<MapTileBitmapHolderBehaviour> _children = new();
|
||||||
|
public void AddChild(MapTileBitmapHolderBehaviour behaviour) {
|
||||||
|
_children.Add(behaviour);
|
||||||
|
foreach (var tile in _tiles) {
|
||||||
|
tile.SetVisible(false);
|
||||||
|
}
|
||||||
|
SetChildSprite(behaviour);
|
||||||
|
}
|
||||||
|
public void RemoveChild(MapTileBitmapHolderBehaviour behaviour) {
|
||||||
|
_children.Remove(behaviour);
|
||||||
|
bool isActive = _children.Count == 0;
|
||||||
|
foreach (var tile in _tiles) {
|
||||||
|
tile.SetVisible(isActive);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
UnityWebRequest _req;
|
||||||
|
DownloadHandlerTexture _texHandler;
|
||||||
|
Texture2D _tex;
|
||||||
|
Sprite _sprite;
|
||||||
|
|
||||||
|
FileInfo _localFile;
|
||||||
|
bool _isReady;
|
||||||
|
public void Load(FileInfo file) {
|
||||||
|
_localFile = file;
|
||||||
|
_isReady = true;
|
||||||
|
}
|
||||||
|
void Update() {
|
||||||
|
if (_isDestroyed) {
|
||||||
|
Destroy(gameObject);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (_isReady) {
|
||||||
|
try {
|
||||||
|
_texHandler = new DownloadHandlerTexture();
|
||||||
|
_req = new UnityWebRequest($"file:///{_localFile}") {
|
||||||
|
downloadHandler = _texHandler,
|
||||||
|
disposeDownloadHandlerOnDispose = true,
|
||||||
|
};
|
||||||
|
_req.SendWebRequest();
|
||||||
|
}
|
||||||
|
catch (Exception ex) {
|
||||||
|
App.MainLogger.Log(4, "Map", null, "An error occurred when loading map tile {0}: {1}", _localFile, ex);
|
||||||
|
}
|
||||||
|
_isReady = false;
|
||||||
|
}
|
||||||
|
if (_req == null || !_req.isDone) return;
|
||||||
|
if (_texHandler.isDone && _texHandler.texture != null) {
|
||||||
|
_tex = _texHandler.texture;
|
||||||
|
_tex.wrapMode = TextureWrapMode.Clamp;
|
||||||
|
SetSprite(_tex, 0, 0, 0);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
App.MainLogger.Log(4, "Map", null, "An error occurred when loading map tile {0}: {1}", _localFile, _texHandler.error);
|
||||||
|
_localFile.Delete();
|
||||||
|
}
|
||||||
|
_req.Dispose();
|
||||||
|
_texHandler.Dispose();
|
||||||
|
_req = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
int _minDz = int.MaxValue;
|
||||||
|
int _x, _y;
|
||||||
|
void SetSprite(Texture2D tex, int dz, int x, int y) {
|
||||||
|
if (dz >= 8) return;
|
||||||
|
if (dz > _minDz) return;
|
||||||
|
_tex = tex;
|
||||||
|
_x = x; _y = y;
|
||||||
|
_minDz = dz;
|
||||||
|
if (_sprite) Destroy(_sprite);
|
||||||
|
int sx = x << (8 - dz), sy = 256 - ((y + 1) << (8 - dz));
|
||||||
|
_sprite = Sprite.Create(tex, new Rect(sx, sy, 1 << (8 - dz), 1 << (8 - dz)), Vector2.zero, 1 << (8 - dz), 0, SpriteMeshType.FullRect, Vector4.zero, false);
|
||||||
|
foreach (var tile in _tiles)
|
||||||
|
tile.Set(_sprite);
|
||||||
|
foreach (var child in _children) {
|
||||||
|
SetChildSprite(child);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetChildSprite(MapTileBitmapHolderBehaviour child) {
|
||||||
|
if (!_tex) return;
|
||||||
|
int cdz = child.Index.Z - Index.Z;
|
||||||
|
int cx = child.Index.X % (1 << cdz) | (_x << cdz), cy = child.Index.Y % (1 << cdz) | (_y << cdz);
|
||||||
|
child.SetSprite(_tex, cdz + _minDz, cx, cy);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool _isDestroyed;
|
||||||
|
public void Destroy() {
|
||||||
|
_isDestroyed = true;
|
||||||
|
}
|
||||||
|
void OnDestroy() {
|
||||||
|
if (_req != null) {
|
||||||
|
_req.Abort();
|
||||||
|
if (_texHandler != null) {
|
||||||
|
var tex = _texHandler.texture;
|
||||||
|
if (tex) Destroy(tex);
|
||||||
|
_texHandler.Dispose();
|
||||||
|
}
|
||||||
|
_req.Dispose();
|
||||||
|
}
|
||||||
|
if (_sprite) Destroy(_sprite);
|
||||||
|
if (_tex && _minDz == 0) Destroy(_tex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: c17f6b26e9a6bd74e8b2d071c6951c41
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@@ -1,166 +1,56 @@
|
|||||||
using Cryville.EEW.Core.Map;
|
using Cryville.EEW.Core.Map;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace Cryville.EEW.Unity.Map {
|
namespace Cryville.EEW.Unity.Map {
|
||||||
sealed class TileZOrderComparer : IComparer<MapTileIndex>, IComparer<MapTile> {
|
class MapTileCacheManager : MapTileCacheManager<MapTileBitmapHolder> {
|
||||||
public static readonly TileZOrderComparer Instance = new();
|
public GameObject PrefabTile { get; set; }
|
||||||
public int Compare(MapTileIndex a, MapTileIndex b) {
|
public GameObject PrefabBitmapHolder { get; set; }
|
||||||
var c = a.Z.CompareTo(b.Z);
|
|
||||||
if (c != 0) return c;
|
|
||||||
c = a.Y.CompareTo(b.Y);
|
|
||||||
if (c != 0) return c;
|
|
||||||
return a.X.CompareTo(b.X);
|
|
||||||
}
|
|
||||||
public int Compare(MapTile a, MapTile b) {
|
|
||||||
if (a == null) return b == null ? 0 : -1;
|
|
||||||
if (b == null) return 1;
|
|
||||||
return Compare(a.Index, b.Index);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sealed class MapTileCacheManager : IDisposable {
|
|
||||||
public int ExtraCachedZoomLevel { get; set; } = 2;
|
|
||||||
|
|
||||||
GameObject m_prefabTile;
|
|
||||||
public GameObject PrefabTile {
|
|
||||||
get => m_prefabTile;
|
|
||||||
set {
|
|
||||||
m_prefabTile = value;
|
|
||||||
if (_dummyTask) GameObject.Destroy(_dummyTask.gameObject);
|
|
||||||
_dummyTask = GameObject.Instantiate(m_prefabTile, Parent, false).GetComponent<MapTile>();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Transform Parent { get; set; }
|
public Transform Parent { get; set; }
|
||||||
|
|
||||||
public string CacheDir { get; set; }
|
public string CacheDir { get; set; }
|
||||||
|
|
||||||
public event Action Updated;
|
protected override MapTileBitmapHolder CreateBitmapHolder(MapTileIndex index) => new(
|
||||||
void OnUpdated(MapTile tile) {
|
index,
|
||||||
if (tile.IsEmpty) {
|
GameObject.Instantiate(PrefabBitmapHolder, Parent, false),
|
||||||
lock (ActiveTiles) {
|
new($"https://services.arcgisonline.com/arcgis/rest/services/Ocean/World_Ocean_Base/MapServer/tile/{index.Z}/{index.NY}/{index.NX}")
|
||||||
if (_cache.Remove(tile.Index)) {
|
);
|
||||||
ActiveTiles.RemoveAt(ActiveTiles.BinarySearch(tile, TileZOrderComparer.Instance));
|
|
||||||
}
|
protected override string GetCacheFilePath(MapTileIndex index) => Path.Combine(CacheDir, $"map/{index.Z}/{index.NX}/{index.NY}");
|
||||||
}
|
|
||||||
}
|
readonly Dictionary<MapTile<MapTileBitmapHolder>, MapTile> _map = new();
|
||||||
Updated?.Invoke();
|
protected override void OnTileCreated(MapTile<MapTileBitmapHolder> tile) {
|
||||||
|
base.OnTileCreated(tile);
|
||||||
|
var gameObject = GameObject.Instantiate(PrefabTile, Parent, false);
|
||||||
|
var uTile = gameObject.GetComponent<MapTile>();
|
||||||
|
_map.Add(tile, uTile);
|
||||||
|
var index = tile.Index;
|
||||||
|
uTile.Init(index);
|
||||||
|
var bitmapHolder = tile.BitmapHolder;
|
||||||
|
bitmapHolder.Bind(uTile);
|
||||||
|
|
||||||
|
if (index.Z <= 0) return;
|
||||||
|
var maybeTile = FindTile(index.ZoomToLevel(index.Z - 1, Math.Floor), false);
|
||||||
|
if (maybeTile is not MapTile<MapTileBitmapHolder> parentTile) return;
|
||||||
|
parentTile.BitmapHolder.AddChild(bitmapHolder);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose() {
|
protected override void OnTileDestroyed(MapTile<MapTileBitmapHolder> tile) {
|
||||||
MonoBehaviour.Destroy(_dummyTask);
|
base.OnTileDestroyed(tile);
|
||||||
|
var bitmapHolder = tile.BitmapHolder;
|
||||||
lock (ActiveTiles) {
|
if (_map.TryGetValue(tile, out var uTile)) {
|
||||||
foreach (var task in ActiveTiles)
|
uTile.Destroy();
|
||||||
GameObject.Destroy(task.gameObject);
|
bitmapHolder.Unbind(uTile);
|
||||||
ActiveTiles.Clear();
|
_map.Remove(tile);
|
||||||
_cache.Clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
readonly Dictionary<MapTileIndex, MapTile> _cache = new();
|
|
||||||
public List<MapTile> ActiveTiles { get; } = new();
|
|
||||||
|
|
||||||
MapTileIndex _a, _b;
|
|
||||||
|
|
||||||
public void MoveTo(MapTileIndex a, MapTileIndex b) {
|
|
||||||
if (a.Z != b.Z) throw new ArgumentException("Mismatched Z index.");
|
|
||||||
if (a.X >= b.X || a.Y >= b.Y) throw new ArgumentException("Incorrect relative X/Y index.");
|
|
||||||
|
|
||||||
lock (ActiveTiles) {
|
|
||||||
UnloadTiles(a, b);
|
|
||||||
_a = a; _b = b;
|
|
||||||
LoadTiles(a, b);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void LoadTiles(MapTileIndex a, MapTileIndex b) {
|
|
||||||
for (int z = Math.Max(0, a.Z - ExtraCachedZoomLevel); z <= Math.Max(0, a.Z); z++) {
|
|
||||||
var ia = a.ZoomToLevel(z, Math.Floor);
|
|
||||||
var ib = b.ZoomToLevel(z, Math.Ceiling);
|
|
||||||
for (int x = ia.X; x < ib.X; x++) {
|
|
||||||
for (int y = ia.Y; y < ib.Y; y++) {
|
|
||||||
var index = new MapTileIndex(x, y, z);
|
|
||||||
if (_cache.ContainsKey(index)) continue;
|
|
||||||
var task = GameObject.Instantiate(PrefabTile, Parent, false).GetComponent<MapTile>();
|
|
||||||
task.Load(index, CacheDir, OnUpdated);
|
|
||||||
_cache.Add(index, task);
|
|
||||||
var i = ~ActiveTiles.BinarySearch(task, TileZOrderComparer.Instance);
|
|
||||||
ActiveTiles.Insert(i, task);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void UnloadTiles(MapTileIndex a, MapTileIndex b) {
|
|
||||||
if (a.Z != _a.Z) {
|
|
||||||
for (int z = _a.Z - ExtraCachedZoomLevel; z < a.Z - ExtraCachedZoomLevel; z++) UnloadTilesAtZoomLevel(z);
|
|
||||||
for (int z = a.Z + 1; z <= _a.Z; z++) UnloadTilesAtZoomLevel(z);
|
|
||||||
}
|
|
||||||
if (a.X > _a.X) {
|
|
||||||
for (int z = Math.Max(0, a.Z); z >= Math.Max(0, a.Z - ExtraCachedZoomLevel); --z) {
|
|
||||||
var ia0 = _a.ZoomToLevel(z, Math.Floor);
|
|
||||||
var ib0 = _b.ZoomToLevel(z, Math.Ceiling);
|
|
||||||
var ia1 = a.ZoomToLevel(z, Math.Floor);
|
|
||||||
if (ia0.X == ia1.X) break;
|
|
||||||
UnloadTilesInRegion(ia0.X, ia0.Y, ia1.X, ib0.Y, z);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (b.X < _b.X) {
|
|
||||||
for (int z = Math.Max(0, a.Z); z >= Math.Max(0, a.Z - ExtraCachedZoomLevel); --z) {
|
|
||||||
var ia0 = _a.ZoomToLevel(z, Math.Floor);
|
|
||||||
var ib0 = _b.ZoomToLevel(z, Math.Ceiling);
|
|
||||||
var ib1 = b.ZoomToLevel(z, Math.Ceiling);
|
|
||||||
if (ib0.X == ib1.X) break;
|
|
||||||
UnloadTilesInRegion(ib1.X, ia0.Y, ib0.X, ib0.Y, z);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (a.Y > _a.Y) {
|
|
||||||
for (int z = Math.Max(0, a.Z); z >= Math.Max(0, a.Z - ExtraCachedZoomLevel); --z) {
|
|
||||||
var ia0 = _a.ZoomToLevel(z, Math.Floor);
|
|
||||||
var ib0 = _b.ZoomToLevel(z, Math.Ceiling);
|
|
||||||
var ia1 = a.ZoomToLevel(z, Math.Floor);
|
|
||||||
if (ia0.Y == ia1.Y) break;
|
|
||||||
UnloadTilesInRegion(ia0.X, ia0.Y, ib0.X, ia1.Y, z);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (b.Y < _b.Y) {
|
|
||||||
for (int z = Math.Max(0, a.Z); z >= Math.Max(0, a.Z - ExtraCachedZoomLevel); --z) {
|
|
||||||
var ia0 = _a.ZoomToLevel(z, Math.Floor);
|
|
||||||
var ib0 = _b.ZoomToLevel(z, Math.Ceiling);
|
|
||||||
var ib1 = b.ZoomToLevel(z, Math.Ceiling);
|
|
||||||
if (ib0.Y == ib1.Y) break;
|
|
||||||
UnloadTilesInRegion(ia0.X, ib1.Y, ib0.X, ib0.Y, z);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void UnloadTilesInRegion(int x1, int y1, int x2, int y2, int z) {
|
|
||||||
for (int x = x1; x < x2; x++) {
|
|
||||||
for (int y = y1; y < y2; y++) {
|
|
||||||
var index = new MapTileIndex(x, y, z);
|
|
||||||
if (!_cache.TryGetValue(index, out var task)) continue;
|
|
||||||
GameObject.Destroy(task.gameObject);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MapTile _dummyTask;
|
|
||||||
void UnloadTilesAtZoomLevel(int z) {
|
|
||||||
if (z < 0) return;
|
|
||||||
|
|
||||||
_dummyTask.Index = new(int.MinValue, int.MinValue, z);
|
|
||||||
var i0 = ActiveTiles.BinarySearch(_dummyTask, TileZOrderComparer.Instance);
|
|
||||||
if (i0 < 0) i0 = ~i0;
|
|
||||||
|
|
||||||
_dummyTask.Index = new(int.MinValue, int.MinValue, z + 1);
|
|
||||||
var i1 = ActiveTiles.BinarySearch(_dummyTask, TileZOrderComparer.Instance);
|
|
||||||
if (i1 < 0) i1 = ~i1;
|
|
||||||
|
|
||||||
for (var i = i1 - 1; i >= i0; --i) {
|
|
||||||
var index = ActiveTiles[i].Index;
|
|
||||||
if (!_cache.TryGetValue(index, out var task)) continue;
|
|
||||||
GameObject.Destroy(task.gameObject);
|
|
||||||
}
|
}
|
||||||
|
var index = tile.Index;
|
||||||
|
if (index.Z <= 0) return;
|
||||||
|
var maybeTile = FindTile(index.ZoomToLevel(index.Z - 1, Math.Floor), false);
|
||||||
|
if (maybeTile is not MapTile<MapTileBitmapHolder> parentTile) return;
|
||||||
|
parentTile.BitmapHolder.RemoveChild(bitmapHolder);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -48,11 +48,13 @@ namespace Cryville.EEW.Unity.Map {
|
|||||||
_segments.Add(segment = Instantiate(m_lineRendererPrefab, transform, false).GetComponent<LineRenderer>());
|
_segments.Add(segment = Instantiate(m_lineRendererPrefab, transform, false).GetComponent<LineRenderer>());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
segment = _segments[_segmentIndex++];
|
segment = _segments[_segmentIndex];
|
||||||
segment.gameObject.SetActive(true);
|
segment.gameObject.SetActive(true);
|
||||||
}
|
}
|
||||||
|
_segmentIndex++;
|
||||||
segment.SetPositions(positions, index, length);
|
segment.SetPositions(positions, index, length);
|
||||||
segment.Width = m_width;
|
segment.Width = m_width;
|
||||||
|
segment.TilingScale = m_tilingScale;
|
||||||
}
|
}
|
||||||
public void Clear() {
|
public void Clear() {
|
||||||
for (int i = 0; i < _segmentIndex; i++) {
|
for (int i = 0; i < _segmentIndex; i++) {
|
||||||
|
@@ -11,11 +11,16 @@ namespace Cryville.EEW.Unity.Map {
|
|||||||
[RequireComponent(typeof(MeshFilter))]
|
[RequireComponent(typeof(MeshFilter))]
|
||||||
[RequireComponent(typeof(MeshRenderer))]
|
[RequireComponent(typeof(MeshRenderer))]
|
||||||
class PolygonRenderer : MonoBehaviour {
|
class PolygonRenderer : MonoBehaviour {
|
||||||
|
Material _sharedMaterial;
|
||||||
public Material Material {
|
public Material Material {
|
||||||
get => _meshRenderer.material;
|
get => _meshRenderer.sharedMaterial;
|
||||||
set {
|
set {
|
||||||
_meshRenderer.material = value;
|
if (value == _sharedMaterial) return;
|
||||||
_meshRenderer.material.color = m_color;
|
if (_sharedMaterial != null) Destroy(_meshRenderer.sharedMaterial);
|
||||||
|
_sharedMaterial = value;
|
||||||
|
if (_sharedMaterial == null) return;
|
||||||
|
_meshRenderer.sharedMaterial = Instantiate(_sharedMaterial);
|
||||||
|
_meshRenderer.sharedMaterial.color = m_color;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -40,10 +45,15 @@ namespace Cryville.EEW.Unity.Map {
|
|||||||
_meshFilter.mesh = new();
|
_meshFilter.mesh = new();
|
||||||
}
|
}
|
||||||
_mesh = _meshFilter.mesh;
|
_mesh = _meshFilter.mesh;
|
||||||
_meshRenderer.material.color = m_color;
|
if (_sharedMaterial == null && _meshRenderer.sharedMaterial != null) {
|
||||||
|
_sharedMaterial = _meshRenderer.sharedMaterial;
|
||||||
|
_meshRenderer.sharedMaterial = Instantiate(_sharedMaterial);
|
||||||
|
_meshRenderer.sharedMaterial.color = m_color;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
void OnDestroy() {
|
void OnDestroy() {
|
||||||
Destroy(_mesh);
|
Destroy(_mesh);
|
||||||
|
Destroy(Material);
|
||||||
}
|
}
|
||||||
public void SetPolygon(IEnumerable<IEnumerable<PointF>> polygon) {
|
public void SetPolygon(IEnumerable<IEnumerable<PointF>> polygon) {
|
||||||
_mesh.Clear();
|
_mesh.Clear();
|
||||||
@@ -67,7 +77,13 @@ namespace Cryville.EEW.Unity.Map {
|
|||||||
DTSweep.Triangulate(tcx);
|
DTSweep.Triangulate(tcx);
|
||||||
|
|
||||||
var codeToIndex = new Dictionary<uint, int>();
|
var codeToIndex = new Dictionary<uint, int>();
|
||||||
var vertices = ArrayPool<Vector3>.Shared.Rent(convertedPolygon.Points.Count);
|
int vertexCount = convertedPolygon.Points.Count;
|
||||||
|
if (convertedPolygon.Holes != null) {
|
||||||
|
foreach (var hole in convertedPolygon.Holes) {
|
||||||
|
vertexCount += hole.Points.Count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var vertices = ArrayPool<Vector3>.Shared.Rent(vertexCount);
|
||||||
var triangles = ArrayPool<int>.Shared.Rent(convertedPolygon.Triangles.Count * 3);
|
var triangles = ArrayPool<int>.Shared.Rent(convertedPolygon.Triangles.Count * 3);
|
||||||
int vi = 0, ii = 0;
|
int vi = 0, ii = 0;
|
||||||
foreach (var tri in convertedPolygon.Triangles) {
|
foreach (var tri in convertedPolygon.Triangles) {
|
||||||
|
219
Assets/Cryville.EEW.Unity/Map/RegionEditor.cs
Normal file
219
Assets/Cryville.EEW.Unity/Map/RegionEditor.cs
Normal file
@@ -0,0 +1,219 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.IO;
|
||||||
|
using System.Text.Json;
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
|
using TMPro;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace Cryville.EEW.Unity.Map {
|
||||||
|
sealed class RegionEditor : MonoBehaviour {
|
||||||
|
QuadTreeNode _root;
|
||||||
|
|
||||||
|
[SerializeField] CameraController m_cameraController;
|
||||||
|
[SerializeField] GameObject m_regionViewPrefab;
|
||||||
|
|
||||||
|
[SerializeField] TMP_Text m_textSelectedInfo;
|
||||||
|
[SerializeField] TMP_Text m_textHoveredInfo;
|
||||||
|
[SerializeField] TMP_InputField m_inputId;
|
||||||
|
|
||||||
|
readonly Dictionary<QuadTreeNode, RegionView> _map = new();
|
||||||
|
|
||||||
|
void Start() {
|
||||||
|
var file = new FileInfo(Path.Combine(Application.persistentDataPath, "regions.json"));
|
||||||
|
if (file.Exists) {
|
||||||
|
using var stream = file.OpenRead();
|
||||||
|
_root = JsonSerializer.Deserialize<QuadTreeNode>(stream);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
_root = NewNode();
|
||||||
|
}
|
||||||
|
BuildView(_root);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Save() {
|
||||||
|
var file = new FileInfo(Path.Combine(Application.persistentDataPath, "regions.json"));
|
||||||
|
using var stream = file.Open(FileMode.Create);
|
||||||
|
JsonSerializer.Serialize(stream, _root);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BuildView(QuadTreeNode node) {
|
||||||
|
var view = Instantiate(m_regionViewPrefab, transform, false).GetComponent<RegionView>();
|
||||||
|
view.Init(node.X, node.Y, node.Z);
|
||||||
|
view.Id = node.Data.Id;
|
||||||
|
view.IsLeaf = node.Children == null;
|
||||||
|
_map.Add(node, view);
|
||||||
|
BuildChildViews(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BuildChildViews(QuadTreeNode node) {
|
||||||
|
if (node.Children == null) return;
|
||||||
|
foreach (var child in node.Children) {
|
||||||
|
BuildView(child);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DestroyChildViews(QuadTreeNode node) {
|
||||||
|
if (node.Children == null) return;
|
||||||
|
foreach (var child in node.Children) {
|
||||||
|
Destroy(_map[child].gameObject);
|
||||||
|
_map.Remove(child);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QuadTreeNode _hoveredNode;
|
||||||
|
QuadTreeNode _selectedNode;
|
||||||
|
Vector3? _ppos;
|
||||||
|
void Update() {
|
||||||
|
var pos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
|
||||||
|
pos.y += 1;
|
||||||
|
var hoveredNode = _root.Get(pos);
|
||||||
|
if (hoveredNode != _hoveredNode) {
|
||||||
|
HoverNode(hoveredNode);
|
||||||
|
}
|
||||||
|
if (Input.GetMouseButtonDown(0)) {
|
||||||
|
_ppos = Input.mousePosition;
|
||||||
|
}
|
||||||
|
if (Input.GetMouseButton(0) && _ppos is Vector3 pos0) {
|
||||||
|
if (Input.mousePosition != pos0) {
|
||||||
|
_ppos = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (hoveredNode == null) return;
|
||||||
|
if (Input.GetMouseButtonUp(0) && _ppos != null) {
|
||||||
|
SelectNode(hoveredNode);
|
||||||
|
_ppos = null;
|
||||||
|
}
|
||||||
|
if (m_inputId.isFocused)
|
||||||
|
return;
|
||||||
|
if (Input.GetKeyUp(KeyCode.A)) {
|
||||||
|
MergeNode(hoveredNode);
|
||||||
|
}
|
||||||
|
if (Input.GetKeyUp(KeyCode.S)) {
|
||||||
|
SplitNode(hoveredNode);
|
||||||
|
}
|
||||||
|
if (Input.GetKeyUp(KeyCode.C)) {
|
||||||
|
m_inputId.text = hoveredNode.Data.Id;
|
||||||
|
}
|
||||||
|
if (Input.GetKeyUp(KeyCode.V)) {
|
||||||
|
hoveredNode.Data.Id = m_inputId.text;
|
||||||
|
_map[hoveredNode].Id = hoveredNode.Data.Id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void HoverNode(QuadTreeNode node) {
|
||||||
|
if (_hoveredNode != null) {
|
||||||
|
_map[_hoveredNode].IsHovered = false;
|
||||||
|
}
|
||||||
|
_hoveredNode = node;
|
||||||
|
if (_hoveredNode != null) {
|
||||||
|
_map[_hoveredNode].IsHovered = true;
|
||||||
|
m_textHoveredInfo.text = string.Format(CultureInfo.InvariantCulture, "<Hovered>\nZ: {2}, XY: ({0}, {1})\nD: {3}", node.X, node.Y, node.Z, node.Data.Id);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
m_textHoveredInfo.text = "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void SelectNode(QuadTreeNode node) {
|
||||||
|
if (_selectedNode != null) {
|
||||||
|
_map[_selectedNode].IsSelected = false;
|
||||||
|
}
|
||||||
|
_selectedNode = node;
|
||||||
|
if (_selectedNode != null) {
|
||||||
|
_map[_selectedNode].IsSelected = true;
|
||||||
|
m_textSelectedInfo.text = string.Format(CultureInfo.InvariantCulture, "<Selected>\nZ: {2}, XY: ({0}, {1})\nD: {3}", node.X, node.Y, node.Z, node.Data.Id);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
m_textSelectedInfo.text = "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void MergeNode(QuadTreeNode node) {
|
||||||
|
var parent = node.Parent;
|
||||||
|
if (parent == null)
|
||||||
|
return;
|
||||||
|
DestroyChildViews(parent);
|
||||||
|
_map[parent].IsLeaf = true;
|
||||||
|
parent.Merge();
|
||||||
|
_hoveredNode = null;
|
||||||
|
if (_selectedNode != null && !_map.ContainsKey(_selectedNode)) {
|
||||||
|
_selectedNode = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void SplitNode(QuadTreeNode node) {
|
||||||
|
node.Split();
|
||||||
|
_map[node].IsLeaf = false;
|
||||||
|
BuildChildViews(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
static QuadTreeNode NewNode() => new() { Data = new("") };
|
||||||
|
|
||||||
|
sealed class QuadTreeNode {
|
||||||
|
QuadTreeNode[] m_children;
|
||||||
|
public QuadTreeNode[] Children {
|
||||||
|
get => m_children;
|
||||||
|
set {
|
||||||
|
if (m_children != null) {
|
||||||
|
foreach (var child in m_children) {
|
||||||
|
child.DetachFromParent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_children = value;
|
||||||
|
UpdateChildren();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
QuadTreeNode m_parent;
|
||||||
|
[JsonIgnore] public QuadTreeNode Parent => m_parent;
|
||||||
|
void AttachToParent(QuadTreeNode parent, int index) {
|
||||||
|
if (m_parent != null && m_parent != parent)
|
||||||
|
throw new InvalidOperationException("Node already in a tree.");
|
||||||
|
m_parent = parent;
|
||||||
|
X = (parent.X << 1) | (index is 0 or 3 ? 1 : 0);
|
||||||
|
Y = (parent.Y << 1) | (index is 0 or 1 ? 1 : 0);
|
||||||
|
Z = parent.Z + 1;
|
||||||
|
UpdateChildren();
|
||||||
|
}
|
||||||
|
void DetachFromParent() => m_parent = null;
|
||||||
|
void UpdateChildren() {
|
||||||
|
if (m_children != null) {
|
||||||
|
for (int i = 0; i < m_children.Length; i++) {
|
||||||
|
m_children[i].AttachToParent(this, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
[JsonIgnore] public int X { get; private set; }
|
||||||
|
[JsonIgnore] public int Y { get; private set; }
|
||||||
|
[JsonIgnore] public int Z { get; private set; }
|
||||||
|
public RegionData Data { get; set; }
|
||||||
|
|
||||||
|
public QuadTreeNode Get(Vector2 pos) {
|
||||||
|
if ((pos.x is < 0 or >= 1) || (pos.y is < 0 or >= 1))
|
||||||
|
return null;
|
||||||
|
if (m_children == null)
|
||||||
|
return this;
|
||||||
|
Vector2 subPos = pos * 2;
|
||||||
|
subPos.x %= 1;
|
||||||
|
subPos.y %= 1;
|
||||||
|
return pos.x >= 0.5f
|
||||||
|
? (pos.y >= 0.5f ? m_children[0] : m_children[3]).Get(subPos)
|
||||||
|
: (pos.y >= 0.5f ? m_children[1] : m_children[2]).Get(subPos);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Merge() {
|
||||||
|
Children = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Split() {
|
||||||
|
Children = new QuadTreeNode[] {
|
||||||
|
new() { Data = Data.Copy() },
|
||||||
|
new() { Data = Data.Copy() },
|
||||||
|
new() { Data = Data.Copy() },
|
||||||
|
new() { Data = Data.Copy() },
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sealed record RegionData(string Id) {
|
||||||
|
public string Id { get; set; } = Id;
|
||||||
|
public RegionData Copy() => (RegionData)MemberwiseClone();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
11
Assets/Cryville.EEW.Unity/Map/RegionEditor.cs.meta
Normal file
11
Assets/Cryville.EEW.Unity/Map/RegionEditor.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: fd7b70d11ebfe324e830806e394cc334
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
68
Assets/Cryville.EEW.Unity/Map/RegionView.cs
Normal file
68
Assets/Cryville.EEW.Unity/Map/RegionView.cs
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace Cryville.EEW.Unity.Map {
|
||||||
|
sealed class RegionView : MonoBehaviour {
|
||||||
|
[SerializeField]
|
||||||
|
SpriteRenderer m_spriteRenderer;
|
||||||
|
|
||||||
|
Color _color;
|
||||||
|
|
||||||
|
bool m_isHovered;
|
||||||
|
public bool IsHovered {
|
||||||
|
get => m_isHovered;
|
||||||
|
set {
|
||||||
|
m_isHovered = value;
|
||||||
|
UpdateColor();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool m_isSelected;
|
||||||
|
public bool IsSelected {
|
||||||
|
get => m_isSelected;
|
||||||
|
set {
|
||||||
|
m_isSelected = value;
|
||||||
|
UpdateColor();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool m_isLeaf = true;
|
||||||
|
public bool IsLeaf {
|
||||||
|
get => m_isLeaf;
|
||||||
|
set {
|
||||||
|
m_isLeaf = value;
|
||||||
|
UpdateColor();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
string m_id;
|
||||||
|
public string Id {
|
||||||
|
get => m_id;
|
||||||
|
set {
|
||||||
|
m_id = value;
|
||||||
|
unchecked {
|
||||||
|
uint hash = (uint)value.GetHashCode();
|
||||||
|
_color = Color.HSVToRGB(((hash >> 24) ^ ((hash >> 16) & 0xff) ^ ((hash >> 8) & 0xff) ^ (hash & 0xff)) / (float)0xff, 1, 1);
|
||||||
|
}
|
||||||
|
UpdateColor();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Init(int x, int y, int z) {
|
||||||
|
float scale = 1f / (1 << z);
|
||||||
|
transform.localScale = new Vector3(scale, scale, 1);
|
||||||
|
transform.localPosition = new Vector3(x * scale, y * scale - 1, -1 - z / 100f);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UpdateColor() {
|
||||||
|
if (!m_isLeaf)
|
||||||
|
_color.a = 0.0f;
|
||||||
|
else if (m_isSelected)
|
||||||
|
_color.a = 0.6f;
|
||||||
|
else if (m_isHovered)
|
||||||
|
_color.a = 0.4f;
|
||||||
|
else
|
||||||
|
_color.a = 0.2f;
|
||||||
|
m_spriteRenderer.color = _color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
11
Assets/Cryville.EEW.Unity/Map/RegionView.cs.meta
Normal file
11
Assets/Cryville.EEW.Unity/Map/RegionView.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: c57a0e86eb63b6048ba265e9d98e84f6
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@@ -1,7 +1,8 @@
|
|||||||
using Cryville.Common.Font;
|
using Cryville.Common.Font;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
namespace Cryville.Crtr {
|
namespace Cryville.EEW.Unity {
|
||||||
internal static class PlatformConfig {
|
internal static class PlatformConfig {
|
||||||
#if UNITY_STANDALONE_WIN
|
#if UNITY_STANDALONE_WIN
|
||||||
public static readonly string Name = "windows";
|
public static readonly string Name = "windows";
|
||||||
@@ -11,11 +12,17 @@ namespace Cryville.Crtr {
|
|||||||
#error Unknown platform.
|
#error Unknown platform.
|
||||||
#endif
|
#endif
|
||||||
#if UNITY_STANDALONE_WIN || UNITY_EDITOR_WIN
|
#if UNITY_STANDALONE_WIN || UNITY_EDITOR_WIN
|
||||||
|
#if UNITY_EDITOR_WIN
|
||||||
|
public static readonly string ConfigPath = Application.persistentDataPath;
|
||||||
|
#else
|
||||||
|
public static readonly string ConfigPath = Application.dataPath;
|
||||||
|
#endif
|
||||||
public static readonly string FileProtocolPrefix = "file:///";
|
public static readonly string FileProtocolPrefix = "file:///";
|
||||||
public static readonly FontManager FontManager = new FontManagerWindows();
|
public static readonly FontManager FontManager = new FontManagerWindows();
|
||||||
public static Dictionary<string, List<string>> ScriptFontMap => FallbackListFontMatcher.GetDefaultWindowsFallbackMap();
|
public static Dictionary<string, List<string>> ScriptFontMap => FallbackListFontMatcher.GetDefaultWindowsFallbackMap();
|
||||||
public static readonly string TextShader = "TextMesh Pro/Shaders/TMP_SDF SSD";
|
public static readonly string TextShader = "TextMesh Pro/Shaders/TMP_SDF SSD";
|
||||||
#elif UNITY_ANDROID
|
#elif UNITY_ANDROID
|
||||||
|
public static readonly string ConfigPath = Application.persistentDataPath;
|
||||||
public static readonly string FileProtocolPrefix = "file://";
|
public static readonly string FileProtocolPrefix = "file://";
|
||||||
public static readonly FontManager FontManager = new FontManagerAndroid();
|
public static readonly FontManager FontManager = new FontManagerAndroid();
|
||||||
public static Dictionary<string, List<string>> ScriptFontMap => FallbackListFontMatcher.GetDefaultAndroidFallbackMap();
|
public static Dictionary<string, List<string>> ScriptFontMap => FallbackListFontMatcher.GetDefaultAndroidFallbackMap();
|
||||||
|
@@ -1,11 +1,17 @@
|
|||||||
using Cryville.EEW.Colors;
|
using Cryville.EEW.Colors;
|
||||||
|
using Cryville.EEW.Core;
|
||||||
using Cryville.EEW.Core.Colors;
|
using Cryville.EEW.Core.Colors;
|
||||||
using Cryville.EEW.FERegion;
|
using Cryville.EEW.FERegion;
|
||||||
using Cryville.EEW.Map;
|
using Cryville.EEW.Map;
|
||||||
using Cryville.EEW.Report;
|
using Cryville.EEW.Report;
|
||||||
using Cryville.EEW.TTS;
|
using Cryville.EEW.TTS;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.IO;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
|
using System.Text.Json;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using Color = System.Drawing.Color;
|
using Color = System.Drawing.Color;
|
||||||
|
|
||||||
@@ -14,19 +20,126 @@ namespace Cryville.EEW.Unity {
|
|||||||
static SharedSettings s_instance;
|
static SharedSettings s_instance;
|
||||||
public static SharedSettings Instance => s_instance ??= new();
|
public static SharedSettings Instance => s_instance ??= new();
|
||||||
|
|
||||||
public ISeverityScheme SeverityScheme => DefaultSeverityScheme.Instance;
|
public ISeverityScheme SeverityScheme { get; private set; } = DefaultSeverityScheme.Instance;
|
||||||
public ISeverityColorMapping SeverityColorMapping => DefaultSeverityColorMapping.Instance;
|
public ISeverityColorMapping SeverityColorMapping { get; private set; } = DefaultSeverityColorMapping.Instance;
|
||||||
public bool UseContinuousColor => true;
|
public bool UseContinuousColor { get; private set; } = true;
|
||||||
public IColorScheme ColorScheme => new SeverityBasedColorScheme(SeverityScheme, DefaultSeverityColorMapping.Instance);
|
public IColorScheme ColorScheme { get; private set; } = new SeverityBasedColorScheme(DefaultSeverityScheme.Instance, DefaultSeverityColorMapping.Instance);
|
||||||
public ISubColorScheme BorderColorScheme => new WrappedColorScheme(new SeverityBasedColorScheme(SeverityScheme, DefaultSeverityColorMapping.SecondaryInstance));
|
public ISubColorScheme BorderColorScheme { get; private set; } = new WrappedColorScheme(new SeverityBasedColorScheme(DefaultSeverityScheme.Instance, DefaultSeverityColorMapping.SecondaryInstance));
|
||||||
public ISubColorScheme TextColorScheme => new DefaultTextColorScheme(Color.White, Color.Black);
|
public ISubColorScheme TextColorScheme { get; private set; } = new DefaultTextColorScheme(Color.White, Color.Black);
|
||||||
public ILocationConverter LocationConverter => new FERegionLongConverter();
|
public float HillshadeLayerOpacity { get; private set; } = 1;
|
||||||
public TimeSpan NowcastWarningDelayTolerance => TimeSpan.MaxValue;
|
public TimeSpan NowcastWarningDelayTolerance { get; private set; } = TimeSpan.FromMinutes(60);
|
||||||
|
|
||||||
|
public CultureInfo RVMCulture { get; private set; } = SharedCultures.CurrentUICulture;
|
||||||
|
readonly int _infoLocationSpecificity = 3;
|
||||||
|
readonly int _ttsLocationSpecificity = 3;
|
||||||
|
readonly LocationNamer _locationNamer = new() { Namer = new FERegionLongNamer() };
|
||||||
|
public bool NameLocation(double lat, double lon, CultureInfo localCulture, ref CultureInfo targetCulture, out string name, out int specificity) {
|
||||||
|
specificity = _ttsLocationSpecificity;
|
||||||
|
return _locationNamer.Name(lat, lon, localCulture, ref targetCulture, out name, ref specificity);
|
||||||
|
}
|
||||||
|
public bool NameLocation(double lat, double lon, CultureInfo localCulture, ref CultureInfo targetCulture, out string name) {
|
||||||
|
int specificity = _infoLocationSpecificity;
|
||||||
|
return _locationNamer.Name(lat, lon, localCulture, ref targetCulture, out name, ref specificity);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IReadOnlyCollection<TTSCultureConfig> TTSCultures { get; private set; }
|
||||||
|
public bool DoIgnoreLanguageVariant { get; private set; }
|
||||||
|
|
||||||
|
public TimeZoneInfo OverrideTimeZone { get; private set; }
|
||||||
|
public bool DoDisplayTimeZone { get; private set; } = true;
|
||||||
|
public bool DoSwitchBackToHistory { get; private set; } = true;
|
||||||
|
|
||||||
|
public IReadOnlyCollection<EventSourceConfig> EventSources { get; private set; }
|
||||||
|
|
||||||
|
public string Id { get; private set; }
|
||||||
public byte[] IdBytes { get; } = new byte[32];
|
public byte[] IdBytes { get; } = new byte[32];
|
||||||
|
public string UnityUserAgent { get; private set; }
|
||||||
|
|
||||||
public void Init() {
|
public void Init() {
|
||||||
|
Id = SystemInfo.deviceUniqueIdentifier;
|
||||||
using var hash = SHA256.Create();
|
using var hash = SHA256.Create();
|
||||||
hash.ComputeHash(EEW.SharedSettings.Encoding.GetBytes(SystemInfo.deviceUniqueIdentifier)).CopyTo(IdBytes, 0);
|
hash.ComputeHash(EEW.SharedSettings.Encoding.GetBytes(Id)).CopyTo(IdBytes, 0);
|
||||||
|
#if UNITY_STANDALONE_WIN
|
||||||
|
UnityUserAgent = string.Format(
|
||||||
|
CultureInfo.InvariantCulture,
|
||||||
|
"{0} CysTerraUnity/{1} (Windows NT {2}; {3})",
|
||||||
|
EEW.SharedSettings.UserAgent,
|
||||||
|
Application.version,
|
||||||
|
Environment.OSVersion.Version,
|
||||||
|
RuntimeInformation.OSArchitecture.ToString().ToLowerInvariant()
|
||||||
|
);
|
||||||
|
#else
|
||||||
|
#error No Unity User Agent
|
||||||
|
#endif
|
||||||
|
|
||||||
|
var file = new FileInfo(Path.Combine(PlatformConfig.ConfigPath, "config.json"));
|
||||||
|
if (!file.Exists) {
|
||||||
|
using var stream1 = file.OpenWrite();
|
||||||
|
using var writer = new StreamWriter(stream1, EEW.SharedSettings.Encoding);
|
||||||
|
writer.Write(JsonSerializer.Serialize(Config.Default, ConfigSerializationContext.Default.Config));
|
||||||
|
}
|
||||||
|
using var stream = file.OpenRead();
|
||||||
|
var config = JsonSerializer.Deserialize(stream, ConfigSerializationContext.Default.Config) ?? throw new InvalidOperationException("Null config.");
|
||||||
|
|
||||||
|
SeverityScheme = config.SeverityScheme switch {
|
||||||
|
"Default" => new DefaultSeverityScheme(),
|
||||||
|
"Legacy" => new LegacySeverityScheme(),
|
||||||
|
_ => throw new InvalidOperationException("Unknown severity scheme."),
|
||||||
|
};
|
||||||
|
SeverityColorMapping = config.ColorScheme switch {
|
||||||
|
"Default" => new DefaultSeverityColorMapping(config.SeverityColorMappingLuminanceMultiplier),
|
||||||
|
"SREV" => new SREVSeverityColorMapping(config.SeverityColorMappingLuminanceMultiplier),
|
||||||
|
"DichromaticYB" => new DichromaticSeverityColorMapping(0.62f, 0.20f, 90, config.SeverityColorMappingLuminanceMultiplier),
|
||||||
|
"DichromaticRC" => new DichromaticSeverityColorMapping(0.62f, 0.25f, 30, config.SeverityColorMappingLuminanceMultiplier),
|
||||||
|
"DichromaticPG" => new DichromaticSeverityColorMapping(0.62f, 0.30f, -30, config.SeverityColorMappingLuminanceMultiplier),
|
||||||
|
"Monochromatic" => new MonochromaticSeverityColorMapping(config.SeverityColorMappingLuminanceMultiplier),
|
||||||
|
_ => throw new InvalidOperationException("Unknown color scheme."),
|
||||||
|
};
|
||||||
|
UseContinuousColor = config.UseContinuousColor;
|
||||||
|
ColorScheme = config.ColorScheme switch {
|
||||||
|
"Default" => new SeverityBasedColorScheme(SeverityScheme, DefaultSeverityColorMapping.Instance),
|
||||||
|
"SREV" => new SREVColorScheme(),
|
||||||
|
"DichromaticYB" => new SeverityBasedColorScheme(SeverityScheme, new DichromaticSeverityColorMapping(0.62f, 0.20f, 90)),
|
||||||
|
"DichromaticRC" => new SeverityBasedColorScheme(SeverityScheme, new DichromaticSeverityColorMapping(0.62f, 0.25f, 30)),
|
||||||
|
"DichromaticPG" => new SeverityBasedColorScheme(SeverityScheme, new DichromaticSeverityColorMapping(0.62f, 0.30f, -30)),
|
||||||
|
"Monochromatic" => new SeverityBasedColorScheme(SeverityScheme, new MonochromaticSeverityColorMapping()),
|
||||||
|
_ => throw new InvalidOperationException("Unknown color scheme."),
|
||||||
|
};
|
||||||
|
BorderColorScheme = config.ColorScheme switch {
|
||||||
|
"Default" => new WrappedColorScheme(new SeverityBasedColorScheme(SeverityScheme, DefaultSeverityColorMapping.SecondaryInstance)),
|
||||||
|
"SREV" => new WrappedColorScheme(new SREVBorderColorScheme()),
|
||||||
|
"DichromaticYB" => new WrappedColorScheme(new SeverityBasedColorScheme(SeverityScheme, new DichromaticSeverityColorMapping(0.62f, 0.20f, 90, 0.75f))),
|
||||||
|
"DichromaticRC" => new WrappedColorScheme(new SeverityBasedColorScheme(SeverityScheme, new DichromaticSeverityColorMapping(0.62f, 0.25f, 30, 0.75f))),
|
||||||
|
"DichromaticPG" => new WrappedColorScheme(new SeverityBasedColorScheme(SeverityScheme, new DichromaticSeverityColorMapping(0.62f, 0.30f, -30, 0.75f))),
|
||||||
|
"Monochromatic" => new WrappedColorScheme(new SeverityBasedColorScheme(SeverityScheme, new MonochromaticSeverityColorMapping(0.75f))),
|
||||||
|
_ => throw new InvalidOperationException("Unknown color scheme."),
|
||||||
|
};
|
||||||
|
TextColorScheme = config.ColorScheme switch {
|
||||||
|
"SREV" => new DefaultTextColorScheme(Color.White, Color.FromArgb(28, 28, 28), 0.555f),
|
||||||
|
_ => new DefaultTextColorScheme(Color.White, Color.Black),
|
||||||
|
};
|
||||||
|
HillshadeLayerOpacity = config.HillshadeLayerOpacity;
|
||||||
|
_locationNamer.Namer = config.LocationNamer switch {
|
||||||
|
"FERegionShort" => new FERegionShortNamer(),
|
||||||
|
_ => new FERegionLongNamer(),
|
||||||
|
};
|
||||||
|
if (config.NowcastWarningDelayTolerance is string nowcastWarningDelayTolerance)
|
||||||
|
NowcastWarningDelayTolerance = TimeSpan.Parse(nowcastWarningDelayTolerance, CultureInfo.InvariantCulture);
|
||||||
|
OverrideTimeZone = ParseTimeZone(config.OverrideTimeZone);
|
||||||
|
DoDisplayTimeZone = config.DoDisplayTimeZone;
|
||||||
|
DoSwitchBackToHistory = config.DoSwitchBackToHistory;
|
||||||
|
RVMCulture = config.OverrideDisplayCulture is string rvmCulture
|
||||||
|
? (string.IsNullOrEmpty(rvmCulture) ? SharedCultures.CurrentUICulture : SharedCultures.Get(rvmCulture))
|
||||||
|
: CultureInfo.InvariantCulture;
|
||||||
|
TTSCultures = config.TTSCultures ?? new List<TTSCultureConfig> { new(CultureInfo.InvariantCulture) };
|
||||||
|
DoIgnoreLanguageVariant = config.DoIgnoreLanguageVariant;
|
||||||
|
EventSources = config.EventSources;
|
||||||
|
}
|
||||||
|
|
||||||
|
TimeZoneInfo ParseTimeZone(string timeZone) {
|
||||||
|
if (timeZone == null) return null;
|
||||||
|
if (timeZone == "") return TimeZoneInfo.Local;
|
||||||
|
return TimeZoneInfo.CreateCustomTimeZone("Custom", TimeSpan.Parse(timeZone, CultureInfo.InvariantCulture), null, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -5,7 +5,7 @@ using System.IO;
|
|||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace Cryville.EEW.Unity {
|
namespace Cryville.EEW.Unity {
|
||||||
class SoundPlayer : Core.SoundPlayer {
|
class SoundPlayer : Core.Audio.SoundPlayer {
|
||||||
public SoundPlayer() : base(GetEngineList(), AudioUsage.NotificationEvent) { }
|
public SoundPlayer() : base(GetEngineList(), AudioUsage.NotificationEvent) { }
|
||||||
static List<Type> GetEngineList() => new() {
|
static List<Type> GetEngineList() => new() {
|
||||||
typeof(Audio.Wasapi.MMDeviceEnumeratorWrapper),
|
typeof(Audio.Wasapi.MMDeviceEnumeratorWrapper),
|
||||||
@@ -13,6 +13,7 @@ namespace Cryville.EEW.Unity {
|
|||||||
};
|
};
|
||||||
|
|
||||||
protected override Stream Open(string path) {
|
protected override Stream Open(string path) {
|
||||||
|
App.MainLogger.Log(0, "Audio", null, "Opening audio file {0}", path);
|
||||||
path = Path.Combine(Application.streamingAssetsPath, "Sounds", path + ".ogg");
|
path = Path.Combine(Application.streamingAssetsPath, "Sounds", path + ".ogg");
|
||||||
if (!File.Exists(path)) return null;
|
if (!File.Exists(path)) return null;
|
||||||
return new FileStream(path, FileMode.Open, FileAccess.Read);
|
return new FileStream(path, FileMode.Open, FileAccess.Read);
|
||||||
|
@@ -1,25 +1,53 @@
|
|||||||
|
using SpeechLib;
|
||||||
using System;
|
using System;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Cryville.EEW.Unity {
|
namespace Cryville.EEW.Unity {
|
||||||
class TTSWorker : Core.TTSWorker {
|
class TTSWorker : Core.Audio.TTSWorker {
|
||||||
public TTSWorker() : base(CreateSoundPlayer()) { }
|
readonly ISpVoice _voice;
|
||||||
|
|
||||||
|
public TTSWorker() : base(CreateSoundPlayer()) {
|
||||||
|
App.MainLogger.Log(1, "Audio", null, "Initializing TTS worker");
|
||||||
|
try {
|
||||||
|
_voice = new SpVoiceClass();
|
||||||
|
}
|
||||||
|
catch { }
|
||||||
|
}
|
||||||
|
|
||||||
static SoundPlayer CreateSoundPlayer() {
|
static SoundPlayer CreateSoundPlayer() {
|
||||||
|
App.MainLogger.Log(1, "Audio", null, "Creating sound player");
|
||||||
try {
|
try {
|
||||||
return new SoundPlayer();
|
return new SoundPlayer();
|
||||||
}
|
}
|
||||||
catch (InvalidOperationException) {
|
catch (InvalidOperationException ex) {
|
||||||
|
App.MainLogger.Log(3, "Audio", null, "An error occurred when creating sound player: {0}", ex);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override bool IsSpeaking() => false;
|
protected override bool IsSpeaking() {
|
||||||
|
if (_voice == null) return false;
|
||||||
|
_voice.GetStatus(out var status, out _);
|
||||||
|
return (status.dwRunningState & (uint)SpeechRunState.SRSEIsSpeaking) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
protected override Task Speak(CultureInfo culture, string content, CancellationToken cancellationToken) => Task.CompletedTask;
|
protected override Task Speak(CultureInfo culture, string content, CancellationToken cancellationToken) {
|
||||||
|
if (_voice == null) return Task.CompletedTask;
|
||||||
|
_voice.Speak(
|
||||||
|
string.Format(CultureInfo.InvariantCulture, "<LANG LANGID=\"{0:x}\">{1}</LANG>", culture.LCID, content),
|
||||||
|
(uint)(SpeechVoiceSpeakFlags.SVSFlagsAsync | SpeechVoiceSpeakFlags.SVSFPurgeBeforeSpeak),
|
||||||
|
out _
|
||||||
|
);
|
||||||
|
App.MainLogger.Log(0, "Audio", null, "TTS ({0}): {1}", culture, content);
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
|
||||||
protected override void StopCurrent() { }
|
protected override void StopCurrent() {
|
||||||
|
if (_voice == null) return;
|
||||||
|
App.MainLogger.Log(0, "Audio", null, "TTS stopping current");
|
||||||
|
_voice.Skip("SENTENCE", int.MaxValue, out _);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
37
Assets/Cryville.EEW.Unity/UI/Dialog.cs
Normal file
37
Assets/Cryville.EEW.Unity/UI/Dialog.cs
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
using Cryville.Common.Unity;
|
||||||
|
using Cryville.Common.Unity.UI;
|
||||||
|
using System.Globalization;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace Cryville.EEW.Unity.UI {
|
||||||
|
public class Dialog : MonoBehaviour {
|
||||||
|
public static Dialog Instance { get; private set; }
|
||||||
|
|
||||||
|
[SerializeField] CanvasGroup m_mask;
|
||||||
|
PropertyTweener<float> _groupAlphaTweener;
|
||||||
|
|
||||||
|
[SerializeField] TMPLocalizedText m_title;
|
||||||
|
[SerializeField] TMPLocalizedText m_message;
|
||||||
|
|
||||||
|
void Awake() {
|
||||||
|
Instance = this;
|
||||||
|
|
||||||
|
m_mask.gameObject.SetActive(false);
|
||||||
|
_groupAlphaTweener = new(() => m_mask.alpha, v => m_mask.alpha = v, Tweeners.Single);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Show(string title, string message) {
|
||||||
|
Show(SharedCultures.CurrentUICulture, title, message);
|
||||||
|
}
|
||||||
|
public void Show(CultureInfo culture, string title, string message) {
|
||||||
|
m_title.SetText(title, culture);
|
||||||
|
m_message.SetText(message, culture);
|
||||||
|
m_mask.gameObject.SetActive(true);
|
||||||
|
_groupAlphaTweener.Start(1, 0.2f);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Update() {
|
||||||
|
_groupAlphaTweener.Advance(Time.deltaTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
11
Assets/Cryville.EEW.Unity/UI/Dialog.cs.meta
Normal file
11
Assets/Cryville.EEW.Unity/UI/Dialog.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: f1b4f209f34bc6e4c8e13aeb4dd5789d
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: -5
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@@ -39,18 +39,15 @@ namespace Cryville.EEW.Unity.UI {
|
|||||||
SetText(m_locationView, location.Value, location.Culture);
|
SetText(m_locationView, location.Value, location.Culture);
|
||||||
SetText(m_predicateView, predicate.Value, predicate.Culture);
|
SetText(m_predicateView, predicate.Value, predicate.Culture);
|
||||||
if (time.Value is DateTime ttime) {
|
if (time.Value is DateTime ttime) {
|
||||||
// TODO
|
if (SharedSettings.Instance.OverrideTimeZone is TimeZoneInfo tTimeZone)
|
||||||
//if (SharedSettings.Instance.OverrideTimeZone is TimeZoneInfo tTimeZone)
|
ttime = TimeZoneInfo.ConvertTime(ttime, timeZone, tTimeZone);
|
||||||
// ttime = TimeZoneInfo.ConvertTime(ttime, timeZone, tTimeZone);
|
else
|
||||||
//else
|
tTimeZone = timeZone;
|
||||||
// tTimeZone = timeZone;
|
|
||||||
TimeZoneInfo tTimeZone = timeZone;
|
|
||||||
if (UseShortTimeFormat) {
|
if (UseShortTimeFormat) {
|
||||||
SetText(m_timeView, ttime.ToString("G", time.Culture), time.Culture);
|
SetText(m_timeView, ttime.ToString("G", time.Culture), time.Culture);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// TODO SetText(m_timeView, SharedSettings.Instance.DoDisplayTimeZone ? string.Format(time.Culture, "{0:G} ({1})", ttime, tTimeZone.ToTimeZoneString()) : ttime.ToString(time.Culture), time.Culture);
|
SetText(m_timeView, SharedSettings.Instance.DoDisplayTimeZone ? string.Format(time.Culture, "{0:G} ({1})", ttime, tTimeZone.ToTimeZoneString()) : ttime.ToString(time.Culture), time.Culture);
|
||||||
SetText(m_timeView, string.Format(time.Culture, "{0:G} ({1})", ttime, tTimeZone.ToTimeZoneString()), time.Culture);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@@ -1,11 +1,19 @@
|
|||||||
|
using Cryville.Common.Unity.UI;
|
||||||
using Cryville.EEW.Core;
|
using Cryville.EEW.Core;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace Cryville.EEW.Unity.UI {
|
namespace Cryville.EEW.Unity.UI {
|
||||||
|
[RequireComponent(typeof(RecyclerView))]
|
||||||
class EventGroupListView : MonoBehaviour {
|
class EventGroupListView : MonoBehaviour {
|
||||||
[SerializeField]
|
RecyclerView _recyclerView;
|
||||||
EventGroupView m_prefabEventGroupView;
|
void Awake() {
|
||||||
|
_recyclerView = GetComponent<RecyclerView>();
|
||||||
|
_recyclerView.LoadItem = LoadItem;
|
||||||
|
}
|
||||||
|
void LoadItem(int index, GameObject gameObject) {
|
||||||
|
gameObject.GetComponent<EventGroupView>().Set(_groups[^(index + 1)]);
|
||||||
|
}
|
||||||
|
|
||||||
readonly List<ReportGroup> _groups = new();
|
readonly List<ReportGroup> _groups = new();
|
||||||
public void UpdateGroup(ReportGroup e) {
|
public void UpdateGroup(ReportGroup e) {
|
||||||
@@ -17,19 +25,16 @@ namespace Cryville.EEW.Unity.UI {
|
|||||||
}
|
}
|
||||||
void Add(ReportGroup group) {
|
void Add(ReportGroup group) {
|
||||||
_groups.Add(group);
|
_groups.Add(group);
|
||||||
var child = Instantiate(m_prefabEventGroupView);
|
_recyclerView.ItemCount++;
|
||||||
child.Set(group);
|
_recyclerView.InvalidateAll();
|
||||||
child.transform.SetParent(transform, false);
|
|
||||||
child.transform.SetSiblingIndex(0);
|
|
||||||
}
|
}
|
||||||
void Remove(ReportGroup group) {
|
void Remove(ReportGroup group) {
|
||||||
int index = _groups.LastIndexOf(group);
|
int index = _groups.LastIndexOf(group);
|
||||||
if (index == -1) return;
|
if (index == -1) return;
|
||||||
_groups.RemoveAt(index);
|
_groups.RemoveAt(index);
|
||||||
|
|
||||||
var child = transform.GetChild(_groups.Count - index);
|
--_recyclerView.ItemCount;
|
||||||
child.SetParent(null, false);
|
_recyclerView.InvalidateAll();
|
||||||
Destroy(child.gameObject);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -14,9 +14,12 @@ namespace Cryville.EEW.Unity.UI {
|
|||||||
[SerializeField] GameObject m_listViewRail;
|
[SerializeField] GameObject m_listViewRail;
|
||||||
[SerializeField] GameObject m_expander;
|
[SerializeField] GameObject m_expander;
|
||||||
|
|
||||||
void Start() {
|
void OnEnable() {
|
||||||
m_groupHeader.onClick.AddListener(OnGroupHeaderClicked);
|
m_groupHeader.onClick.AddListener(OnGroupHeaderClicked);
|
||||||
}
|
}
|
||||||
|
void OnDisable() {
|
||||||
|
m_groupHeader.onClick.RemoveListener(OnGroupHeaderClicked);
|
||||||
|
}
|
||||||
void OnGroupHeaderClicked() {
|
void OnGroupHeaderClicked() {
|
||||||
SetExpanded(!m_listViewContainer.activeSelf);
|
SetExpanded(!m_listViewContainer.activeSelf);
|
||||||
}
|
}
|
||||||
|
@@ -23,6 +23,7 @@ namespace Cryville.EEW.Unity.UI {
|
|||||||
child.SetViewModel(e);
|
child.SetViewModel(e);
|
||||||
child.transform.SetParent(m_listView, false);
|
child.transform.SetParent(m_listView, false);
|
||||||
_displayingViews.Add(child);
|
_displayingViews.Add(child);
|
||||||
|
OnDisplayingViewsChanged();
|
||||||
|
|
||||||
SwitchTo(_displayingReports.Count - 1);
|
SwitchTo(_displayingReports.Count - 1);
|
||||||
|
|
||||||
@@ -37,6 +38,7 @@ namespace Cryville.EEW.Unity.UI {
|
|||||||
child.SetParent(null, false);
|
child.SetParent(null, false);
|
||||||
Destroy(child.gameObject);
|
Destroy(child.gameObject);
|
||||||
_displayingViews.RemoveAt(index);
|
_displayingViews.RemoveAt(index);
|
||||||
|
OnDisplayingViewsChanged();
|
||||||
|
|
||||||
if (_displayingReports.Count == 0) {
|
if (_displayingReports.Count == 0) {
|
||||||
m_currentView.gameObject.SetActive(false);
|
m_currentView.gameObject.SetActive(false);
|
||||||
@@ -49,6 +51,14 @@ namespace Cryville.EEW.Unity.UI {
|
|||||||
|
|
||||||
if (_displayingReports.Count <= 1) m_listView.gameObject.SetActive(false);
|
if (_displayingReports.Count <= 1) m_listView.gameObject.SetActive(false);
|
||||||
}
|
}
|
||||||
|
void OnDisplayingViewsChanged() {
|
||||||
|
_maxBaseDuration = 1;
|
||||||
|
foreach (var e in _displayingReports) {
|
||||||
|
float duration = GetBaseDuration(e);
|
||||||
|
if (duration > _maxBaseDuration)
|
||||||
|
_maxBaseDuration = duration;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Awake() {
|
void Awake() {
|
||||||
if (Instance != null) {
|
if (Instance != null) {
|
||||||
@@ -63,6 +73,7 @@ namespace Cryville.EEW.Unity.UI {
|
|||||||
|
|
||||||
int _index = -1;
|
int _index = -1;
|
||||||
float _tickDown;
|
float _tickDown;
|
||||||
|
float _maxBaseDuration;
|
||||||
void Update() {
|
void Update() {
|
||||||
if (_displayingReports.Count == 0) return;
|
if (_displayingReports.Count == 0) return;
|
||||||
_tickDown -= Time.deltaTime;
|
_tickDown -= Time.deltaTime;
|
||||||
@@ -77,16 +88,20 @@ namespace Cryville.EEW.Unity.UI {
|
|||||||
_index = index;
|
_index = index;
|
||||||
var e = _displayingReports[index];
|
var e = _displayingReports[index];
|
||||||
m_currentView.SetViewModel(e, true);
|
m_currentView.SetViewModel(e, true);
|
||||||
var keyProp = e.Properties.FirstOrDefault();
|
|
||||||
_displayingViews[_index].SetCurrent(true);
|
_displayingViews[_index].SetCurrent(true);
|
||||||
_tickDown = Math.Max(0, keyProp?.Severity ?? 0) * 4 + 4;
|
_tickDown = GetBaseDuration(e) / Math.Min(_maxBaseDuration, 4) * 4;
|
||||||
m_currentView.gameObject.SetActive(true);
|
m_currentView.gameObject.SetActive(true);
|
||||||
Worker.Instance.SetCurrent(e);
|
Worker.Instance.SetCurrent(e);
|
||||||
}
|
}
|
||||||
public void SetCurrent(ReportViewModel viewModel) {
|
static float GetBaseDuration(ReportViewModel e) {
|
||||||
|
return MathF.Exp(Math.Max(-1f, e.Properties.FirstOrDefault()?.Severity ?? -1f) + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnItemClicked(ReportViewModel viewModel) {
|
||||||
int index = _displayingReports.IndexOf(viewModel);
|
int index = _displayingReports.IndexOf(viewModel);
|
||||||
if (index == -1) return;
|
if (index == -1) return;
|
||||||
SwitchTo(index);
|
SwitchTo(index);
|
||||||
|
Worker.Instance.SetSelected(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,10 +1,10 @@
|
|||||||
|
using Cryville.Common.Unity;
|
||||||
using Cryville.Common.Unity.UI;
|
using Cryville.Common.Unity.UI;
|
||||||
using Cryville.EEW.Report;
|
using Cryville.EEW.Report;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.UI;
|
using UnityEngine.UI;
|
||||||
using Utils;
|
|
||||||
|
|
||||||
namespace Cryville.EEW.Unity.UI {
|
namespace Cryville.EEW.Unity.UI {
|
||||||
class EventOngoingView : MonoBehaviour {
|
class EventOngoingView : MonoBehaviour {
|
||||||
@@ -27,7 +27,7 @@ namespace Cryville.EEW.Unity.UI {
|
|||||||
}
|
}
|
||||||
void SetView(float mainSeverity, string title, string location, CultureInfo culture) {
|
void SetView(float mainSeverity, string title, string location, CultureInfo culture) {
|
||||||
SetSeverity(mainSeverity);
|
SetSeverity(mainSeverity);
|
||||||
SetText(m_textView, string.Format("{0} {1}", title, location), culture);
|
SetText(m_textView, string.Format(culture, "{0} {1}", title, location), culture);
|
||||||
}
|
}
|
||||||
static void SetText(TMPLocalizedText view, string text, CultureInfo culture) {
|
static void SetText(TMPLocalizedText view, string text, CultureInfo culture) {
|
||||||
if (string.IsNullOrWhiteSpace(text)) {
|
if (string.IsNullOrWhiteSpace(text)) {
|
||||||
@@ -47,11 +47,14 @@ namespace Cryville.EEW.Unity.UI {
|
|||||||
void Awake() {
|
void Awake() {
|
||||||
_dockRatioTweener = new(() => m_dockLayoutGroup.DockOccupiedRatio, v => m_dockLayoutGroup.DockOccupiedRatio = v, Tweeners.Single);
|
_dockRatioTweener = new(() => m_dockLayoutGroup.DockOccupiedRatio, v => m_dockLayoutGroup.DockOccupiedRatio = v, Tweeners.Single);
|
||||||
}
|
}
|
||||||
void Start() {
|
void OnEnable() {
|
||||||
m_button.onClick.AddListener(OnViewClicked);
|
m_button.onClick.AddListener(OnViewClicked);
|
||||||
}
|
}
|
||||||
|
void OnDisable() {
|
||||||
|
m_button.onClick.RemoveListener(OnViewClicked);
|
||||||
|
}
|
||||||
void OnViewClicked() {
|
void OnViewClicked() {
|
||||||
EventOngoingListView.Instance.SetCurrent(_viewModel);
|
EventOngoingListView.Instance.OnItemClicked(_viewModel);
|
||||||
}
|
}
|
||||||
void Update() {
|
void Update() {
|
||||||
_dockRatioTweener.Advance(Time.deltaTime);
|
_dockRatioTweener.Advance(Time.deltaTime);
|
||||||
|
@@ -14,9 +14,12 @@ namespace Cryville.EEW.Unity.UI {
|
|||||||
[SerializeField] TMPLocalizedText m_revisionView;
|
[SerializeField] TMPLocalizedText m_revisionView;
|
||||||
ReportViewModel _viewModel;
|
ReportViewModel _viewModel;
|
||||||
|
|
||||||
protected virtual void Start() {
|
protected virtual void OnEnable() {
|
||||||
if (m_reportViewButton != null) m_reportViewButton.onClick.AddListener(OnViewClicked);
|
if (m_reportViewButton != null) m_reportViewButton.onClick.AddListener(OnViewClicked);
|
||||||
}
|
}
|
||||||
|
protected virtual void OnDisable() {
|
||||||
|
if (m_reportViewButton != null) m_reportViewButton.onClick.RemoveListener(OnViewClicked);
|
||||||
|
}
|
||||||
void OnViewClicked() {
|
void OnViewClicked() {
|
||||||
Worker.Instance.SetSelected(_viewModel);
|
Worker.Instance.SetSelected(_viewModel);
|
||||||
}
|
}
|
||||||
|
@@ -8,7 +8,6 @@ namespace Cryville.EEW.Unity.UI {
|
|||||||
|
|
||||||
public void Set(ReportGroup group) {
|
public void Set(ReportGroup group) {
|
||||||
foreach (Transform child in transform) {
|
foreach (Transform child in transform) {
|
||||||
child.SetParent(null, false);
|
|
||||||
Destroy(child.gameObject);
|
Destroy(child.gameObject);
|
||||||
}
|
}
|
||||||
foreach (var unit in group) {
|
foreach (var unit in group) {
|
||||||
|
@@ -8,10 +8,14 @@ namespace Cryville.EEW.Unity.UI {
|
|||||||
|
|
||||||
[SerializeField] Button m_revisionViewContainerButton;
|
[SerializeField] Button m_revisionViewContainerButton;
|
||||||
|
|
||||||
protected override void Start() {
|
protected override void OnEnable() {
|
||||||
base.Start();
|
base.OnEnable();
|
||||||
m_revisionViewContainerButton.onClick.AddListener(OnRevisionViewClicked);
|
m_revisionViewContainerButton.onClick.AddListener(OnRevisionViewClicked);
|
||||||
}
|
}
|
||||||
|
protected override void OnDisable() {
|
||||||
|
base.OnDisable();
|
||||||
|
m_revisionViewContainerButton.onClick.RemoveListener(OnRevisionViewClicked);
|
||||||
|
}
|
||||||
void OnRevisionViewClicked() {
|
void OnRevisionViewClicked() {
|
||||||
m_listView.gameObject.SetActive(!m_listView.gameObject.activeSelf);
|
m_listView.gameObject.SetActive(!m_listView.gameObject.activeSelf);
|
||||||
}
|
}
|
||||||
|
41
Assets/Cryville.EEW.Unity/UI/StatusView.cs
Normal file
41
Assets/Cryville.EEW.Unity/UI/StatusView.cs
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
using System.Globalization;
|
||||||
|
using System.Text;
|
||||||
|
using TMPro;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace Cryville.EEW.Unity.UI {
|
||||||
|
[RequireComponent(typeof(TMP_Text))]
|
||||||
|
class StatusView : MonoBehaviour {
|
||||||
|
TMP_Text _textView;
|
||||||
|
|
||||||
|
void Awake() {
|
||||||
|
_textView = GetComponent<TMP_Text>();
|
||||||
|
}
|
||||||
|
|
||||||
|
readonly StringBuilder _sb = new();
|
||||||
|
readonly char[] _buffer = new char[256];
|
||||||
|
void Update() {
|
||||||
|
_sb.Clear();
|
||||||
|
_sb.AppendFormat(
|
||||||
|
CultureInfo.InvariantCulture,
|
||||||
|
"FPS: i{0:0} / s{1:0}\n",
|
||||||
|
1 / Time.deltaTime,
|
||||||
|
1 / Time.smoothDeltaTime
|
||||||
|
);
|
||||||
|
_sb.AppendFormat(
|
||||||
|
CultureInfo.InvariantCulture,
|
||||||
|
"SMem: {0:N0} / {1:N0}\n",
|
||||||
|
UnityEngine.Profiling.Profiler.GetMonoUsedSizeLong(),
|
||||||
|
UnityEngine.Profiling.Profiler.GetMonoHeapSizeLong()
|
||||||
|
);
|
||||||
|
_sb.AppendFormat(
|
||||||
|
CultureInfo.InvariantCulture,
|
||||||
|
"IMem: {0:N0} / {1:N0}",
|
||||||
|
UnityEngine.Profiling.Profiler.GetTotalAllocatedMemoryLong(),
|
||||||
|
UnityEngine.Profiling.Profiler.GetTotalReservedMemoryLong()
|
||||||
|
);
|
||||||
|
_sb.CopyTo(0, _buffer, _sb.Length);
|
||||||
|
_textView.SetText(_buffer, 0, _sb.Length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
11
Assets/Cryville.EEW.Unity/UI/StatusView.cs.meta
Normal file
11
Assets/Cryville.EEW.Unity/UI/StatusView.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 4e142baf0f0bd70439133e17e7185611
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@@ -1,5 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Globalization;
|
|
||||||
using TMPro;
|
using TMPro;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
@@ -13,7 +12,13 @@ namespace Cryville.EEW.Unity.UI {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Update() {
|
void Update() {
|
||||||
_textView.text = string.Format(CultureInfo.CurrentCulture, "{0:G} ({1})", DateTime.Now, TimeZoneInfo.Local.ToTimeZoneString());
|
var time = DateTime.Now;
|
||||||
|
var timeZone = TimeZoneInfo.Local;
|
||||||
|
if (SharedSettings.Instance.OverrideTimeZone is TimeZoneInfo tTimeZone)
|
||||||
|
time = TimeZoneInfo.ConvertTime(time, timeZone, tTimeZone);
|
||||||
|
else
|
||||||
|
tTimeZone = timeZone;
|
||||||
|
_textView.text = SharedSettings.Instance.DoDisplayTimeZone ? string.Format(SharedCultures.CurrentCulture, "{0:G} ({1})", time, tTimeZone.ToTimeZoneString()) : time.ToString(SharedCultures.CurrentCulture);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,20 +1,33 @@
|
|||||||
|
using Cryville.EEW.BMKGOpenData;
|
||||||
|
using Cryville.EEW.BMKGOpenData.TTS;
|
||||||
using Cryville.EEW.Core;
|
using Cryville.EEW.Core;
|
||||||
using Cryville.EEW.CWAOpenData;
|
using Cryville.EEW.CWAOpenData;
|
||||||
using Cryville.EEW.CWAOpenData.Model;
|
using Cryville.EEW.CWAOpenData.Model;
|
||||||
using Cryville.EEW.CWAOpenData.TTS;
|
using Cryville.EEW.CWAOpenData.TTS;
|
||||||
|
using Cryville.EEW.EMSC;
|
||||||
|
using Cryville.EEW.FANStudio;
|
||||||
|
using Cryville.EEW.FANStudio.TTS;
|
||||||
|
using Cryville.EEW.GeoNet;
|
||||||
|
using Cryville.EEW.GeoNet.TTS;
|
||||||
using Cryville.EEW.GlobalQuake;
|
using Cryville.EEW.GlobalQuake;
|
||||||
using Cryville.EEW.JMAAtom;
|
using Cryville.EEW.JMAAtom;
|
||||||
using Cryville.EEW.JMAAtom.TTS;
|
using Cryville.EEW.JMAAtom.TTS;
|
||||||
using Cryville.EEW.NOAA;
|
using Cryville.EEW.NOAA;
|
||||||
using Cryville.EEW.NOAA.TTS;
|
using Cryville.EEW.NOAA.TTS;
|
||||||
|
using Cryville.EEW.QuakeML;
|
||||||
using Cryville.EEW.Report;
|
using Cryville.EEW.Report;
|
||||||
using Cryville.EEW.Unity.Map;
|
using Cryville.EEW.Unity.Map;
|
||||||
using Cryville.EEW.Unity.UI;
|
using Cryville.EEW.Unity.UI;
|
||||||
using Cryville.EEW.UpdateChecker;
|
using Cryville.EEW.UpdateChecker;
|
||||||
|
using Cryville.EEW.USGS;
|
||||||
using Cryville.EEW.Wolfx;
|
using Cryville.EEW.Wolfx;
|
||||||
using Cryville.EEW.Wolfx.TTS;
|
using Cryville.EEW.Wolfx.TTS;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net;
|
||||||
|
using System.Net.Http;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
@@ -27,8 +40,10 @@ namespace Cryville.EEW.Unity {
|
|||||||
[SerializeField] MapElementManager m_mapElementManager;
|
[SerializeField] MapElementManager m_mapElementManager;
|
||||||
[SerializeField] EventOngoingListView m_ongoingEventList;
|
[SerializeField] EventOngoingListView m_ongoingEventList;
|
||||||
[SerializeField] EventGroupListView m_historyEventGroupList;
|
[SerializeField] EventGroupListView m_historyEventGroupList;
|
||||||
|
[SerializeField] GameObject m_connectingHint;
|
||||||
|
|
||||||
GroupingCoreWorker _worker;
|
CoreWorker _worker;
|
||||||
|
ReportGrouper _grouper;
|
||||||
CancellationTokenSource _cancellationTokenSource;
|
CancellationTokenSource _cancellationTokenSource;
|
||||||
|
|
||||||
void Awake() {
|
void Awake() {
|
||||||
@@ -38,25 +53,52 @@ namespace Cryville.EEW.Unity {
|
|||||||
}
|
}
|
||||||
Instance = this;
|
Instance = this;
|
||||||
|
|
||||||
|
try {
|
||||||
App.Init();
|
App.Init();
|
||||||
|
|
||||||
_worker = new(new TTSWorker());
|
_worker = new(new TTSWorker());
|
||||||
|
_grouper = new ReportGrouper();
|
||||||
_cancellationTokenSource = new();
|
_cancellationTokenSource = new();
|
||||||
}
|
}
|
||||||
|
catch (Exception ex) {
|
||||||
|
Dialog.Instance.Show("FATAL ERROR", ex.ToString());
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Start() {
|
void Start() {
|
||||||
|
try {
|
||||||
|
App.MainLogger.Log(1, "App", null, "Initializing localized resources manager");
|
||||||
LocalizedResources.Init(new LocalizedResourcesManager());
|
LocalizedResources.Init(new LocalizedResourcesManager());
|
||||||
RegisterViewModelGenerators(_worker);
|
RegisterViewModelGenerators(_worker);
|
||||||
RegisterTTSMessageGenerators(_worker);
|
RegisterTTSMessageGenerators(_worker);
|
||||||
BuildWorkers();
|
BuildWorkers();
|
||||||
_worker.RVMGeneratorContext = SharedSettings.Instance;
|
_worker.RVMGeneratorContext = SharedSettings.Instance;
|
||||||
_worker.TTSMessageGeneratorContext = SharedSettings.Instance;
|
_worker.TTSMessageGeneratorContext = SharedSettings.Instance;
|
||||||
|
_worker.RVMCulture = SharedSettings.Instance.RVMCulture;
|
||||||
|
_worker.SetTTSCultures(SharedSettings.Instance.TTSCultures ?? new TTSCultureConfig[0]);
|
||||||
|
_worker.IgnoreLanguageVariant = SharedSettings.Instance.DoIgnoreLanguageVariant;
|
||||||
_ongoingReportManager.Changed += OnOngoingReported;
|
_ongoingReportManager.Changed += OnOngoingReported;
|
||||||
_worker.Reported += OnReported;
|
_worker.Reported += OnReported;
|
||||||
_worker.GroupUpdated += OnGroupUpdated;
|
_grouper.GroupUpdated += OnGroupUpdated;
|
||||||
_worker.GroupRemoved += OnGroupRemoved;
|
_grouper.GroupRemoved += OnGroupRemoved;
|
||||||
|
App.MainLogger.Log(1, "App", null, "Worker ready");
|
||||||
|
Task.Run(() => GatewayVerify(_cancellationTokenSource.Token)).ContinueWith(task => {
|
||||||
|
if (task.IsFaulted) {
|
||||||
|
OnReported(this, new() { Title = task.Exception.Message });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_verified = true;
|
||||||
|
_uiActionQueue.Enqueue(() => m_connectingHint.SetActive(false));
|
||||||
|
Task.Run(() => ScheduledGatewayVerify(_cancellationTokenSource, _cancellationTokenSource.Token));
|
||||||
Task.Run(() => _worker.RunAsync(_cancellationTokenSource.Token));
|
Task.Run(() => _worker.RunAsync(_cancellationTokenSource.Token));
|
||||||
Task.Run(() => _ongoingReportManager.RunAsync(_cancellationTokenSource.Token));
|
Task.Run(() => _ongoingReportManager.RunAsync(_cancellationTokenSource.Token));
|
||||||
|
}, TaskScheduler.Current);
|
||||||
|
}
|
||||||
|
catch (Exception ex) {
|
||||||
|
Dialog.Instance.Show("FATAL ERROR", ex.ToString());
|
||||||
|
throw;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnDestroy() {
|
void OnDestroy() {
|
||||||
@@ -65,74 +107,187 @@ namespace Cryville.EEW.Unity {
|
|||||||
_ongoingReportManager.Dispose();
|
_ongoingReportManager.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void RegisterViewModelGenerators(CoreWorker worker) {
|
CENCEarthquakeRVMGenerator _cencEarthquakeRVMGenerator;
|
||||||
worker.RegisterViewModelGenerator(new CENCEarthquakeRVMGenerator());
|
void RegisterViewModelGenerators(CoreWorker worker) {
|
||||||
|
worker.RegisterViewModelGenerator(new BMKGEarthquakeRVMGenerator());
|
||||||
|
worker.RegisterViewModelGenerator(new CEAEEWRVMGenerator());
|
||||||
|
worker.RegisterViewModelGenerator(_cencEarthquakeRVMGenerator = new CENCEarthquakeRVMGenerator());
|
||||||
worker.RegisterViewModelGenerator(new CENCEEWRVMGenerator());
|
worker.RegisterViewModelGenerator(new CENCEEWRVMGenerator());
|
||||||
worker.RegisterViewModelGenerator(new CWAEarthquakeRVMGenerator());
|
worker.RegisterViewModelGenerator(new CWAEarthquakeRVMGenerator());
|
||||||
worker.RegisterViewModelGenerator(new CWAEEWRVMGenerator());
|
worker.RegisterViewModelGenerator(new CWAEEWRVMGenerator());
|
||||||
worker.RegisterViewModelGenerator(new CWATsunamiRVMGenerator());
|
worker.RegisterViewModelGenerator(new CWATsunamiRVMGenerator());
|
||||||
worker.RegisterViewModelGenerator(new FujianEEWRVMGenerator());
|
worker.RegisterViewModelGenerator(new EMSCRealTimeEventRVMGenerator());
|
||||||
|
worker.RegisterViewModelGenerator(new FANStudio.FujianEEWRVMGenerator());
|
||||||
|
worker.RegisterViewModelGenerator(new Wolfx.FujianEEWRVMGenerator());
|
||||||
|
worker.RegisterViewModelGenerator(new GeoNetQuakeHistoryRVMGenerator());
|
||||||
|
worker.RegisterViewModelGenerator(new GeoNetQuakeRVMGenerator());
|
||||||
|
worker.RegisterViewModelGenerator(new GeoNetStrongRVMGenerator());
|
||||||
worker.RegisterViewModelGenerator(new GlobalQuakeRVMGenerator());
|
worker.RegisterViewModelGenerator(new GlobalQuakeRVMGenerator());
|
||||||
|
worker.RegisterViewModelGenerator(new ICLEEWRVMGenerator());
|
||||||
worker.RegisterViewModelGenerator(new JMAAtomRVMGenerator());
|
worker.RegisterViewModelGenerator(new JMAAtomRVMGenerator());
|
||||||
worker.RegisterViewModelGenerator(new JMAEEWRVMGenerator());
|
worker.RegisterViewModelGenerator(new JMAEEWRVMGenerator());
|
||||||
worker.RegisterViewModelGenerator(new NOAAAtomRVMGenerator());
|
worker.RegisterViewModelGenerator(new NOAAAtomRVMGenerator());
|
||||||
worker.RegisterViewModelGenerator(new SichuanEEWRVMGenerator());
|
var quakemlEventRVMGenerator = new QuakeMLEventRVMGenerator();
|
||||||
|
quakemlEventRVMGenerator.AddExtension(new USGSQuakeMLExtension());
|
||||||
|
worker.RegisterViewModelGenerator(quakemlEventRVMGenerator);
|
||||||
|
worker.RegisterViewModelGenerator(new FANStudio.SichuanEEWRVMGenerator());
|
||||||
|
worker.RegisterViewModelGenerator(new Wolfx.SichuanEEWRVMGenerator());
|
||||||
|
worker.RegisterViewModelGenerator(new USGSContoursRVMGenerator());
|
||||||
worker.RegisterViewModelGenerator(new VersionRVMGenerator());
|
worker.RegisterViewModelGenerator(new VersionRVMGenerator());
|
||||||
}
|
}
|
||||||
static void RegisterTTSMessageGenerators(CoreWorker worker) {
|
CENCEarthquakeTTSMessageGenerator _cencEarthquakeTTSMessageGenerator;
|
||||||
worker.RegisterTTSMessageGenerator(new CENCEarthquakeTTSMessageGenerator());
|
void RegisterTTSMessageGenerators(CoreWorker worker) {
|
||||||
|
worker.RegisterTTSMessageGenerator(new BMKGEarthquakeTTSMessageGenerator());
|
||||||
|
worker.RegisterTTSMessageGenerator(new CEAEEWTTSMessageGenerator());
|
||||||
|
worker.RegisterTTSMessageGenerator(_cencEarthquakeTTSMessageGenerator = new CENCEarthquakeTTSMessageGenerator());
|
||||||
worker.RegisterTTSMessageGenerator(new CENCEEWTTSMessageGenerator());
|
worker.RegisterTTSMessageGenerator(new CENCEEWTTSMessageGenerator());
|
||||||
worker.RegisterTTSMessageGenerator(new CWAEarthquakeTTSMessageGenerator());
|
worker.RegisterTTSMessageGenerator(new CWAEarthquakeTTSMessageGenerator());
|
||||||
worker.RegisterTTSMessageGenerator(new CWAEEWTTSMessageGenerator());
|
worker.RegisterTTSMessageGenerator(new CWAEEWTTSMessageGenerator());
|
||||||
worker.RegisterTTSMessageGenerator(new CWATsunamiTTSMessageGenerator());
|
worker.RegisterTTSMessageGenerator(new CWATsunamiTTSMessageGenerator());
|
||||||
worker.RegisterTTSMessageGenerator(new FujianEEWTTSMessageGenerator());
|
worker.RegisterTTSMessageGenerator(new FANStudio.TTS.FujianEEWTTSMessageGenerator());
|
||||||
|
worker.RegisterTTSMessageGenerator(new Wolfx.TTS.FujianEEWTTSMessageGenerator());
|
||||||
|
worker.RegisterTTSMessageGenerator(new GeoNetQuakeHistoryTTSMessageGenerator());
|
||||||
|
worker.RegisterTTSMessageGenerator(new GeoNetQuakeTTSMessageGenerator());
|
||||||
|
worker.RegisterTTSMessageGenerator(new GeoNetStrongTTSMessageGenerator());
|
||||||
|
worker.RegisterTTSMessageGenerator(new ICLEEWTTSMessageGenerator());
|
||||||
worker.RegisterTTSMessageGenerator(new JMAAtomTTSMessageGenerator());
|
worker.RegisterTTSMessageGenerator(new JMAAtomTTSMessageGenerator());
|
||||||
worker.RegisterTTSMessageGenerator(new JMAEEWTTSMessageGenerator());
|
worker.RegisterTTSMessageGenerator(new JMAEEWTTSMessageGenerator());
|
||||||
worker.RegisterTTSMessageGenerator(new NOAATTSMessageGenerator());
|
worker.RegisterTTSMessageGenerator(new NOAATTSMessageGenerator());
|
||||||
worker.RegisterTTSMessageGenerator(new SichuanEEWTTSMessageGenerator());
|
worker.RegisterTTSMessageGenerator(new FANStudio.TTS.SichuanEEWTTSMessageGenerator());
|
||||||
|
worker.RegisterTTSMessageGenerator(new Wolfx.TTS.SichuanEEWTTSMessageGenerator());
|
||||||
}
|
}
|
||||||
|
|
||||||
WolfxWorker _wolfxWorker;
|
bool _verified;
|
||||||
JMAAtomWorker _jmaWorker;
|
|
||||||
CWAReportWorker<Tsunami> _cwa14Worker;
|
|
||||||
CWAReportWorker<Earthquake> _cwa15Worker;
|
|
||||||
CWAReportWorker<Earthquake> _cwa16Worker;
|
|
||||||
GlobalQuakeWorker _gqWorker;
|
|
||||||
NOAAAtomWorker _ntwcWorker;
|
|
||||||
NOAAAtomWorker _ptwcWorker;
|
|
||||||
UpdateCheckerWorker _updateChecker;
|
|
||||||
void BuildWorkers() {
|
void BuildWorkers() {
|
||||||
|
App.MainLogger.Log(1, "App", null, "Building workers");
|
||||||
#if UNITY_EDITOR
|
#if UNITY_EDITOR
|
||||||
_worker.AddWorker(_wolfxWorker = new WolfxWorker(new Uri("ws://localhost:9995/wolfx")));
|
_worker.AddWorker(new WolfxWorker(new Uri("ws://localhost:9995/wolfx")));
|
||||||
_worker.AddWorker(_jmaWorker = new JMAAtomWorker(new Uri("http://localhost:9095/eqvol.xml")));
|
_worker.AddWorker(new JMAAtomWorker(new Uri("http://localhost:9095/eqvol.xml")));
|
||||||
_worker.AddWorker(_cwa14Worker = new CWAReportWorker<Tsunami>(new Uri("http://localhost:9095/E-A0014-001.json"), "1"));
|
_worker.AddWorker(new FANStudioWorker<FANStudio.Model.CEAEEW>(new("ws://localhost:9995/fan/cea")));
|
||||||
_worker.AddWorker(_cwa15Worker = new CWAReportWorker<Earthquake>(new Uri("http://localhost:9095/E-A0015-001.json"), "1"));
|
_worker.AddWorker(new CWAReportWorker<Tsunami>(new Uri("http://localhost:9095/E-A0014-001.json"), "1"));
|
||||||
_worker.AddWorker(_cwa16Worker = new CWAReportWorker<Earthquake>(new Uri("http://localhost:9095/E-A0016-001.json"), "1"));
|
_worker.AddWorker(new CWAReportWorker<Earthquake>(new Uri("http://localhost:9095/E-A0015-001.json"), "1"));
|
||||||
_worker.AddWorker(_ntwcWorker = new NOAAAtomWorker(new("http://localhost:9095/PAAQAtom.xml")));
|
_worker.AddWorker(new CWAReportWorker<Earthquake>(new Uri("http://localhost:9095/E-A0016-001.json"), "1"));
|
||||||
// _worker.AddWorker(_gqWorker = new GlobalQuakeWorker("localhost", 38000));
|
BMKGOpenDataWorker bmkgWorker = new(new Uri("http://localhost:9095/autogempa.json"));
|
||||||
|
bmkgWorker.SetDataUris(new Uri[] { new("http://localhost:9095/gempadirasakan.json") });
|
||||||
|
_worker.AddWorker(bmkgWorker);
|
||||||
|
_worker.AddWorker(new NOAAAtomWorker(new("http://localhost:9095/PAAQAtom.xml"), forceHttps: false));
|
||||||
|
_worker.AddWorker(new UpdateCheckerWorker(typeof(Worker).Assembly.GetName().Version?.ToString(3) ?? "", "unity"));
|
||||||
#else
|
#else
|
||||||
// TODO
|
foreach (var source in SharedSettings.Instance.EventSources) {
|
||||||
|
_worker.AddWorker(source switch {
|
||||||
|
BMKGOpenDataEventSourceConfig bmkgOpenData => BuildBMKGOpenDataWorkerUris(new(new("https://data.bmkg.go.id/DataMKG/TEWS/autogempa.json")), bmkgOpenData),
|
||||||
|
CWAOpenDataEventSourceConfig cwaOpenData => cwaOpenData.Subtype switch {
|
||||||
|
"E-A0014-001" => new CWAReportWorker<Tsunami>(new("https://opendata.cwa.gov.tw/api/v1/rest/datastore/E-A0014-001"), cwaOpenData.Token, 1440, 17280),
|
||||||
|
"E-A0015-001" => new CWAReportWorker<Earthquake>(new("https://opendata.cwa.gov.tw/api/v1/rest/datastore/E-A0015-001"), cwaOpenData.Token),
|
||||||
|
"E-A0016-001" => new CWAReportWorker<Earthquake>(new("https://opendata.cwa.gov.tw/api/v1/rest/datastore/E-A0016-001"), cwaOpenData.Token),
|
||||||
|
_ => throw new InvalidOperationException("Unknown CWA open data sub-type."),
|
||||||
|
},
|
||||||
|
EMSCRealTimeEventSourceConfig => new EMSCRealTimeWorker(new("wss://www.seismicportal.eu/standing_order/websocket")),
|
||||||
|
FANStudioEventSourceConfig fanStudio => fanStudio.Subtype switch {
|
||||||
|
"cea" => new FANStudioWorker<FANStudio.Model.CEAEEW>(new("wss://ws.fanstudio.tech/cea")),
|
||||||
|
"sichuan" => new FANStudioWorker<FANStudio.Model.SichuanEEW>(new("wss://ws.fanstudio.tech/sichuan")),
|
||||||
|
"fujian" => new FANStudioWorker<FANStudio.Model.FujianEEW>(new("wss://ws.fanstudio.tech/fujian")),
|
||||||
|
_ => throw new InvalidOperationException("Unknown FAN Studio sub-type."),
|
||||||
|
},
|
||||||
|
GeoNetEventSourceConfig geoNet => BuildGeoNetWorker(new(new("https://api.geonet.org.nz/quake"), new("https://api.geonet.org.nz/quake/history/index"), new("https://api.geonet.org.nz/intensity/strong/processed/index")), geoNet),
|
||||||
|
GlobalQuakeServer15EventSourceConfig gq => new GlobalQuakeWorker15(gq.Host, gq.Port),
|
||||||
|
GlobalQuakeServerEventSourceConfig gq => new GlobalQuakeWorker(gq.Host, gq.Port),
|
||||||
|
JMAAtomEventSourceConfig jmaAtom => BuildJMAAtomWorkerFilter(new(new("https://www.data.jma.go.jp/developer/xml/feed/eqvol.xml")), jmaAtom),
|
||||||
|
NOAAEventSourceConfig noaaAtom => noaaAtom.Subtype switch {
|
||||||
|
"PAAQ" => new NOAAAtomWorker(new("https://www.tsunami.gov/events/xml/PAAQAtom.xml"), new("https://www.tsunami.gov/"), new("/php/esri.php?e=t", UriKind.Relative), "PAAQ"),
|
||||||
|
"PHEB" => new NOAAAtomWorker(new("https://www.tsunami.gov/events/xml/PHEBAtom.xml"), new("https://www.tsunami.gov/"), new("/php/esri.php?e=t", UriKind.Relative), "PHEB"),
|
||||||
|
_ => throw new InvalidOperationException("Unknown NOAA sub-type."),
|
||||||
|
},
|
||||||
|
UpdateCheckerEventSourceConfig => new UpdateCheckerWorker(typeof(Worker).Assembly.GetName().Version?.ToString(3) ?? "", "unity"),
|
||||||
|
USGSEventSourceConfig usgs => BuildUSGSWorker(usgs.UseGeoJSONFeeds
|
||||||
|
? new USGSGeoJSONWorker(new Uri("https://earthquake.usgs.gov/earthquakes/feed/v1.0/geojson.php"))
|
||||||
|
: new USGSQuakeMLWorker(new Uri("https://earthquake.usgs.gov/earthquakes/feed/v1.0/quakeml.php"))
|
||||||
|
, usgs),
|
||||||
|
WolfxEventSourceConfig wolfx => BuildWolfxWorkerFilter(new WolfxWorker(new("wss://ws-api.wolfx.jp/all_eew")), wolfx),
|
||||||
|
_ => throw new InvalidOperationException("Unknown event source type."),
|
||||||
|
});
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
if (_updateChecker == null) _worker.AddWorker(_updateChecker = new(typeof(Worker).Assembly.GetName().Version?.ToString(3) ?? "", "unity"));
|
}
|
||||||
|
static JMAAtomWorker BuildJMAAtomWorkerFilter(JMAAtomWorker worker, JMAAtomEventSourceConfig config) {
|
||||||
|
if (config.Filter != null) worker.SetFilter(config.Filter);
|
||||||
|
worker.IsFilterWhitelist = config.IsFilterWhitelist;
|
||||||
|
return worker;
|
||||||
|
}
|
||||||
|
WolfxWorker BuildWolfxWorkerFilter(WolfxWorker worker, WolfxEventSourceConfig config) {
|
||||||
|
if (config.Filter != null) worker.SetFilter(config.Filter.Select(i => i switch {
|
||||||
|
"cenc_eew" => typeof(Wolfx.Model.CENCEEW),
|
||||||
|
"cenc_eqlist" => typeof(Wolfx.Model.WolfxEarthquakeList<Wolfx.Model.CENCEarthquake>),
|
||||||
|
"cwa_eew" => typeof(Wolfx.Model.CWAEEW),
|
||||||
|
"fj_eew" => typeof(Wolfx.Model.FujianEEW),
|
||||||
|
"jma_eew" => typeof(Wolfx.Model.JMAEEW),
|
||||||
|
"sc_eew" => typeof(Wolfx.Model.SichuanEEW),
|
||||||
|
_ => throw new InvalidOperationException("Unknown Wolfx event type."),
|
||||||
|
}));
|
||||||
|
worker.IsFilterWhitelist = config.IsFilterWhitelist;
|
||||||
|
|
||||||
|
_cencEarthquakeRVMGenerator.UseRawLocationName
|
||||||
|
= _cencEarthquakeTTSMessageGenerator.UseRawLocationName
|
||||||
|
= config.UseRawCENCLocationName;
|
||||||
|
|
||||||
|
return worker;
|
||||||
|
}
|
||||||
|
static BMKGOpenDataWorker BuildBMKGOpenDataWorkerUris(BMKGOpenDataWorker worker, BMKGOpenDataEventSourceConfig config) {
|
||||||
|
worker.SetDataUris(config.Subtypes.Select(i => new Uri(string.Format(CultureInfo.InvariantCulture, "https://data.bmkg.go.id/DataMKG/TEWS/{0}.json", i))));
|
||||||
|
return worker;
|
||||||
|
}
|
||||||
|
static GeoNetWorker BuildGeoNetWorker(GeoNetWorker worker, GeoNetEventSourceConfig pref) {
|
||||||
|
worker.MinimumMMI = pref.MinimumMMI;
|
||||||
|
worker.DoGetFullHistory = pref.DoGetFullHistory;
|
||||||
|
worker.DoGetStrongMotionInfo = pref.DoGetStrongMotionInfo;
|
||||||
|
return worker;
|
||||||
|
}
|
||||||
|
static USGSWorker BuildUSGSWorker(USGSWorker worker, USGSEventSourceConfig config) {
|
||||||
|
worker.SetFeedRelativeUri(new(string.Format(CultureInfo.InvariantCulture, "/earthquakes/feed/v1.0/summary/{0}{1}", config.Subtype, config.UseGeoJSONFeeds ? ".geojson" : ".quakeml"), UriKind.Relative));
|
||||||
|
if (worker is USGSGeoJSONWorker geojsonWorker) {
|
||||||
|
geojsonWorker.SetFilter(
|
||||||
|
config.Products
|
||||||
|
.Select(i => i.Split('/', 2))
|
||||||
|
.GroupBy(i => i[0])
|
||||||
|
.ToDictionary(g => g.Key, g => g.Select(i => i[1]))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return worker;
|
||||||
}
|
}
|
||||||
|
|
||||||
readonly OngoingReportManager _ongoingReportManager = new();
|
readonly OngoingReportManager _ongoingReportManager = new();
|
||||||
readonly ConcurrentQueue<Action> _uiActionQueue = new();
|
readonly ConcurrentQueue<Action> _uiActionQueue = new();
|
||||||
|
ReportViewModel _latestHistoryReport;
|
||||||
void OnReported(object sender, ReportViewModel e) {
|
void OnReported(object sender, ReportViewModel e) {
|
||||||
Debug.Log(e);
|
if (e.Model is Exception && e.Model is not SourceWorkerNetworkException)
|
||||||
|
App.MainLogger.Log(4, "App", null, "Received an error from {0}: {1}", sender.GetType(), e.Model);
|
||||||
|
_grouper.Report(e);
|
||||||
_ongoingReportManager.Report(e);
|
_ongoingReportManager.Report(e);
|
||||||
_uiActionQueue.Enqueue(() => m_mapElementManager.SetSelected(e));
|
_uiActionQueue.Enqueue(() => {
|
||||||
|
if (m_mapElementManager.OngoingCount == 0) {
|
||||||
|
m_mapElementManager.SetSelected(e);
|
||||||
|
m_cameraController.OnMapElementUpdated();
|
||||||
|
}
|
||||||
|
if (e.InvalidatedTime == null && (!(e.RevisionKey?.IsCancellation ?? false))) {
|
||||||
|
_latestHistoryReport = e;
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
void OnOngoingReported(ReportViewModel item, CollectionChangeAction action) {
|
void OnOngoingReported(ReportViewModel item, CollectionChangeAction action) {
|
||||||
if (action == CollectionChangeAction.Add) {
|
if (action == CollectionChangeAction.Add) {
|
||||||
_uiActionQueue.Enqueue(() => {
|
_uiActionQueue.Enqueue(() => {
|
||||||
m_mapElementManager.AddOngoing(item);
|
if (m_mapElementManager.Add(item)) {
|
||||||
|
m_mapElementManager.SetSelected(null);
|
||||||
|
}
|
||||||
m_ongoingEventList.Add(item);
|
m_ongoingEventList.Add(item);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else if (action == CollectionChangeAction.Remove) {
|
else if (action == CollectionChangeAction.Remove) {
|
||||||
_uiActionQueue.Enqueue(() => {
|
_uiActionQueue.Enqueue(() => {
|
||||||
m_mapElementManager.RemoveOngoing(item);
|
m_mapElementManager.Remove(item);
|
||||||
|
if (m_mapElementManager.Count == 0 && SharedSettings.Instance.DoSwitchBackToHistory && _latestHistoryReport is not null) {
|
||||||
|
m_mapElementManager.SetSelected(_latestHistoryReport, true);
|
||||||
|
}
|
||||||
m_ongoingEventList.Remove(item);
|
m_ongoingEventList.Remove(item);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -148,15 +303,58 @@ namespace Cryville.EEW.Unity {
|
|||||||
m_cameraController.OnMapElementUpdated();
|
m_cameraController.OnMapElementUpdated();
|
||||||
}
|
}
|
||||||
public void SetCurrent(ReportViewModel e) {
|
public void SetCurrent(ReportViewModel e) {
|
||||||
m_mapElementManager.SetCurrent(e);
|
if (m_mapElementManager.SetCurrent(e)) {
|
||||||
m_cameraController.OnMapElementUpdated();
|
m_cameraController.OnMapElementUpdated();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Update() {
|
void Update() {
|
||||||
while (_uiActionQueue.TryDequeue(out var action)) {
|
while (_uiActionQueue.TryDequeue(out var action)) {
|
||||||
action();
|
action();
|
||||||
m_cameraController.OnMapElementUpdated();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async Task ScheduledGatewayVerify(CancellationTokenSource source, CancellationToken cancellationToken) {
|
||||||
|
Exception lastEx = null;
|
||||||
|
for (int i = 0; i < 8; i++) {
|
||||||
|
await Task.Delay(TimeSpan.FromHours(3), cancellationToken).ConfigureAwait(true);
|
||||||
|
try {
|
||||||
|
await GatewayVerify(cancellationToken).ConfigureAwait(true);
|
||||||
|
i = -1;
|
||||||
|
}
|
||||||
|
catch (HttpRequestException ex) {
|
||||||
|
lastEx = ex;
|
||||||
|
}
|
||||||
|
catch (WebException ex) {
|
||||||
|
lastEx = ex;
|
||||||
|
}
|
||||||
|
catch (InvalidOperationException ex) {
|
||||||
|
lastEx = ex;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (lastEx != null) {
|
||||||
|
OnReported(this, new() { Title = lastEx.Message });
|
||||||
|
_verified = false;
|
||||||
|
}
|
||||||
|
source.Cancel();
|
||||||
|
}
|
||||||
|
#if UNITY_EDITOR
|
||||||
|
#pragma warning disable CS1998
|
||||||
|
#endif
|
||||||
|
static async Task GatewayVerify(CancellationToken cancellationToken) {
|
||||||
|
#if !UNITY_EDITOR
|
||||||
|
using var client = new HttpClient();
|
||||||
|
client.DefaultRequestHeaders.UserAgent.ParseAdd(SharedSettings.Instance.UnityUserAgent);
|
||||||
|
using var response = await client.GetAsync(new Uri("https://gateway.cryville.world/?rin=" + SharedSettings.Instance.Id), cancellationToken).ConfigureAwait(true);
|
||||||
|
if (response.StatusCode is >= ((HttpStatusCode)400) and < ((HttpStatusCode)500)) {
|
||||||
|
throw new InvalidOperationException(response.ReasonPhrase);
|
||||||
|
}
|
||||||
|
response.EnsureSuccessStatusCode();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#if UNITY_EDITOR
|
||||||
|
#pragma warning restore CS1998
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
2797
Assets/Main.unity
2797
Assets/Main.unity
File diff suppressed because it is too large
Load Diff
91
Assets/Materials/Multiply.mat
Normal file
91
Assets/Materials/Multiply.mat
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
%YAML 1.1
|
||||||
|
%TAG !u! tag:unity3d.com,2011:
|
||||||
|
--- !u!21 &2100000
|
||||||
|
Material:
|
||||||
|
serializedVersion: 8
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_Name: Multiply
|
||||||
|
m_Shader: {fileID: 4800000, guid: 0637d3d4bac33b34ea1fb084d1aa83c5, type: 3}
|
||||||
|
m_Parent: {fileID: 0}
|
||||||
|
m_ModifiedSerializedProperties: 0
|
||||||
|
m_ValidKeywords: []
|
||||||
|
m_InvalidKeywords: []
|
||||||
|
m_LightmapFlags: 4
|
||||||
|
m_EnableInstancingVariants: 0
|
||||||
|
m_DoubleSidedGI: 0
|
||||||
|
m_CustomRenderQueue: -1
|
||||||
|
stringTagMap: {}
|
||||||
|
disabledShaderPasses: []
|
||||||
|
m_LockedProperties:
|
||||||
|
m_SavedProperties:
|
||||||
|
serializedVersion: 3
|
||||||
|
m_TexEnvs:
|
||||||
|
- _AlphaTex:
|
||||||
|
m_Texture: {fileID: 0}
|
||||||
|
m_Scale: {x: 1, y: 1}
|
||||||
|
m_Offset: {x: 0, y: 0}
|
||||||
|
- _BumpMap:
|
||||||
|
m_Texture: {fileID: 0}
|
||||||
|
m_Scale: {x: 1, y: 1}
|
||||||
|
m_Offset: {x: 0, y: 0}
|
||||||
|
- _DetailAlbedoMap:
|
||||||
|
m_Texture: {fileID: 0}
|
||||||
|
m_Scale: {x: 1, y: 1}
|
||||||
|
m_Offset: {x: 0, y: 0}
|
||||||
|
- _DetailMask:
|
||||||
|
m_Texture: {fileID: 0}
|
||||||
|
m_Scale: {x: 1, y: 1}
|
||||||
|
m_Offset: {x: 0, y: 0}
|
||||||
|
- _DetailNormalMap:
|
||||||
|
m_Texture: {fileID: 0}
|
||||||
|
m_Scale: {x: 1, y: 1}
|
||||||
|
m_Offset: {x: 0, y: 0}
|
||||||
|
- _EmissionMap:
|
||||||
|
m_Texture: {fileID: 0}
|
||||||
|
m_Scale: {x: 1, y: 1}
|
||||||
|
m_Offset: {x: 0, y: 0}
|
||||||
|
- _MainTex:
|
||||||
|
m_Texture: {fileID: 0}
|
||||||
|
m_Scale: {x: 1, y: 1}
|
||||||
|
m_Offset: {x: 0, y: 0}
|
||||||
|
- _MetallicGlossMap:
|
||||||
|
m_Texture: {fileID: 0}
|
||||||
|
m_Scale: {x: 1, y: 1}
|
||||||
|
m_Offset: {x: 0, y: 0}
|
||||||
|
- _OcclusionMap:
|
||||||
|
m_Texture: {fileID: 0}
|
||||||
|
m_Scale: {x: 1, y: 1}
|
||||||
|
m_Offset: {x: 0, y: 0}
|
||||||
|
- _ParallaxMap:
|
||||||
|
m_Texture: {fileID: 0}
|
||||||
|
m_Scale: {x: 1, y: 1}
|
||||||
|
m_Offset: {x: 0, y: 0}
|
||||||
|
m_Ints: []
|
||||||
|
m_Floats:
|
||||||
|
- PixelSnap: 0
|
||||||
|
- _BumpScale: 1
|
||||||
|
- _Cutoff: 0.5
|
||||||
|
- _DetailNormalMapScale: 1
|
||||||
|
- _DstBlend: 0
|
||||||
|
- _EnableExternalAlpha: 0
|
||||||
|
- _GlossMapScale: 1
|
||||||
|
- _Glossiness: 0.5
|
||||||
|
- _GlossyReflections: 1
|
||||||
|
- _Metallic: 0
|
||||||
|
- _Mode: 0
|
||||||
|
- _OcclusionStrength: 1
|
||||||
|
- _Parallax: 0.02
|
||||||
|
- _SmoothnessTextureChannel: 0
|
||||||
|
- _SpecularHighlights: 1
|
||||||
|
- _SrcBlend: 1
|
||||||
|
- _UVSec: 0
|
||||||
|
- _ZWrite: 1
|
||||||
|
m_Colors:
|
||||||
|
- _Color: {r: 1, g: 1, b: 1, a: 1}
|
||||||
|
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
|
||||||
|
- _Flip: {r: 1, g: 1, b: 1, a: 1}
|
||||||
|
- _RendererColor: {r: 1, g: 1, b: 1, a: 1}
|
||||||
|
m_BuildTextureStacks: []
|
@@ -1,8 +1,8 @@
|
|||||||
fileFormatVersion: 2
|
fileFormatVersion: 2
|
||||||
guid: 4972abff193472e4bbef2dd0ec07b55e
|
guid: e2b4779e0934e3b45978a57b79d75597
|
||||||
NativeFormatImporter:
|
NativeFormatImporter:
|
||||||
externalObjects: {}
|
externalObjects: {}
|
||||||
mainObjectFileID: 0
|
mainObjectFileID: 2100000
|
||||||
userData:
|
userData:
|
||||||
assetBundleName:
|
assetBundleName:
|
||||||
assetBundleVariant:
|
assetBundleVariant:
|
@@ -1,5 +1,5 @@
|
|||||||
fileFormatVersion: 2
|
fileFormatVersion: 2
|
||||||
guid: fa01d66f44e9d4a42ae8ca989003a496
|
guid: 6430b56ba6977f04291fbf3b0a464655
|
||||||
folderAsset: yes
|
folderAsset: yes
|
||||||
DefaultImporter:
|
DefaultImporter:
|
||||||
externalObjects: {}
|
externalObjects: {}
|
BIN
Assets/Plugins/Analyzers/Cryville.EEW.Analyzer.dll
Normal file
BIN
Assets/Plugins/Analyzers/Cryville.EEW.Analyzer.dll
Normal file
Binary file not shown.
78
Assets/Plugins/Analyzers/Cryville.EEW.Analyzer.dll.meta
Normal file
78
Assets/Plugins/Analyzers/Cryville.EEW.Analyzer.dll.meta
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 88e8ae9c8ce06934ab7681fb678d7b00
|
||||||
|
labels:
|
||||||
|
- RoslynAnalyzer
|
||||||
|
PluginImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
iconMap: {}
|
||||||
|
executionOrder: {}
|
||||||
|
defineConstraints: []
|
||||||
|
isPreloaded: 0
|
||||||
|
isOverridable: 0
|
||||||
|
isExplicitlyReferenced: 0
|
||||||
|
validateReferences: 1
|
||||||
|
platformData:
|
||||||
|
- first:
|
||||||
|
: Any
|
||||||
|
second:
|
||||||
|
enabled: 0
|
||||||
|
settings:
|
||||||
|
Exclude Android: 1
|
||||||
|
Exclude Editor: 1
|
||||||
|
Exclude Linux64: 1
|
||||||
|
Exclude OSXUniversal: 1
|
||||||
|
Exclude Win: 1
|
||||||
|
Exclude Win64: 1
|
||||||
|
- first:
|
||||||
|
Android: Android
|
||||||
|
second:
|
||||||
|
enabled: 0
|
||||||
|
settings:
|
||||||
|
CPU: ARMv7
|
||||||
|
- first:
|
||||||
|
Any:
|
||||||
|
second:
|
||||||
|
enabled: 0
|
||||||
|
settings: {}
|
||||||
|
- first:
|
||||||
|
Editor: Editor
|
||||||
|
second:
|
||||||
|
enabled: 0
|
||||||
|
settings:
|
||||||
|
CPU: AnyCPU
|
||||||
|
DefaultValueInitialized: true
|
||||||
|
OS: AnyOS
|
||||||
|
- first:
|
||||||
|
Standalone: Linux64
|
||||||
|
second:
|
||||||
|
enabled: 0
|
||||||
|
settings:
|
||||||
|
CPU: None
|
||||||
|
- first:
|
||||||
|
Standalone: OSXUniversal
|
||||||
|
second:
|
||||||
|
enabled: 0
|
||||||
|
settings:
|
||||||
|
CPU: None
|
||||||
|
- first:
|
||||||
|
Standalone: Win
|
||||||
|
second:
|
||||||
|
enabled: 0
|
||||||
|
settings:
|
||||||
|
CPU: None
|
||||||
|
- first:
|
||||||
|
Standalone: Win64
|
||||||
|
second:
|
||||||
|
enabled: 0
|
||||||
|
settings:
|
||||||
|
CPU: None
|
||||||
|
- first:
|
||||||
|
Windows Store Apps: WindowsStoreApps
|
||||||
|
second:
|
||||||
|
enabled: 0
|
||||||
|
settings:
|
||||||
|
CPU: AnyCPU
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
BIN
Assets/Plugins/Analyzers/System.Text.Json.SourceGeneration.dll
Normal file
BIN
Assets/Plugins/Analyzers/System.Text.Json.SourceGeneration.dll
Normal file
Binary file not shown.
@@ -0,0 +1,78 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 15569127b9ff7604198a55092602f59a
|
||||||
|
labels:
|
||||||
|
- RoslynAnalyzer
|
||||||
|
PluginImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
iconMap: {}
|
||||||
|
executionOrder: {}
|
||||||
|
defineConstraints: []
|
||||||
|
isPreloaded: 0
|
||||||
|
isOverridable: 0
|
||||||
|
isExplicitlyReferenced: 0
|
||||||
|
validateReferences: 1
|
||||||
|
platformData:
|
||||||
|
- first:
|
||||||
|
: Any
|
||||||
|
second:
|
||||||
|
enabled: 0
|
||||||
|
settings:
|
||||||
|
Exclude Android: 1
|
||||||
|
Exclude Editor: 1
|
||||||
|
Exclude Linux64: 1
|
||||||
|
Exclude OSXUniversal: 1
|
||||||
|
Exclude Win: 1
|
||||||
|
Exclude Win64: 1
|
||||||
|
- first:
|
||||||
|
Android: Android
|
||||||
|
second:
|
||||||
|
enabled: 0
|
||||||
|
settings:
|
||||||
|
CPU: ARMv7
|
||||||
|
- first:
|
||||||
|
Any:
|
||||||
|
second:
|
||||||
|
enabled: 0
|
||||||
|
settings: {}
|
||||||
|
- first:
|
||||||
|
Editor: Editor
|
||||||
|
second:
|
||||||
|
enabled: 0
|
||||||
|
settings:
|
||||||
|
CPU: AnyCPU
|
||||||
|
DefaultValueInitialized: true
|
||||||
|
OS: AnyOS
|
||||||
|
- first:
|
||||||
|
Standalone: Linux64
|
||||||
|
second:
|
||||||
|
enabled: 0
|
||||||
|
settings:
|
||||||
|
CPU: None
|
||||||
|
- first:
|
||||||
|
Standalone: OSXUniversal
|
||||||
|
second:
|
||||||
|
enabled: 0
|
||||||
|
settings:
|
||||||
|
CPU: None
|
||||||
|
- first:
|
||||||
|
Standalone: Win
|
||||||
|
second:
|
||||||
|
enabled: 0
|
||||||
|
settings:
|
||||||
|
CPU: None
|
||||||
|
- first:
|
||||||
|
Standalone: Win64
|
||||||
|
second:
|
||||||
|
enabled: 0
|
||||||
|
settings:
|
||||||
|
CPU: None
|
||||||
|
- first:
|
||||||
|
Windows Store Apps: WindowsStoreApps
|
||||||
|
second:
|
||||||
|
enabled: 0
|
||||||
|
settings:
|
||||||
|
CPU: AnyCPU
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
Binary file not shown.
1315
Assets/Plugins/Cryville.Audio.xml
Normal file
1315
Assets/Plugins/Cryville.Audio.xml
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
|||||||
fileFormatVersion: 2
|
fileFormatVersion: 2
|
||||||
guid: 2ade62400bece1a4f9093a91ca22b276
|
guid: 0444abb2bb6ae5c44a7f7ee60b312f0d
|
||||||
TextScriptImporter:
|
TextScriptImporter:
|
||||||
externalObjects: {}
|
externalObjects: {}
|
||||||
userData:
|
userData:
|
BIN
Assets/Plugins/Cryville.Common.Logging.dll
Normal file
BIN
Assets/Plugins/Cryville.Common.Logging.dll
Normal file
Binary file not shown.
33
Assets/Plugins/Cryville.Common.Logging.dll.meta
Normal file
33
Assets/Plugins/Cryville.Common.Logging.dll.meta
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 7aa0c56ccfdaf9443b58f26bf40eed01
|
||||||
|
PluginImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
iconMap: {}
|
||||||
|
executionOrder: {}
|
||||||
|
defineConstraints: []
|
||||||
|
isPreloaded: 0
|
||||||
|
isOverridable: 0
|
||||||
|
isExplicitlyReferenced: 0
|
||||||
|
validateReferences: 1
|
||||||
|
platformData:
|
||||||
|
- first:
|
||||||
|
Any:
|
||||||
|
second:
|
||||||
|
enabled: 1
|
||||||
|
settings: {}
|
||||||
|
- first:
|
||||||
|
Editor: Editor
|
||||||
|
second:
|
||||||
|
enabled: 0
|
||||||
|
settings:
|
||||||
|
DefaultValueInitialized: true
|
||||||
|
- first:
|
||||||
|
Windows Store Apps: WindowsStoreApps
|
||||||
|
second:
|
||||||
|
enabled: 0
|
||||||
|
settings:
|
||||||
|
CPU: AnyCPU
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
185
Assets/Plugins/Cryville.Common.Logging.xml
Normal file
185
Assets/Plugins/Cryville.Common.Logging.xml
Normal file
@@ -0,0 +1,185 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<doc>
|
||||||
|
<assembly>
|
||||||
|
<name>Cryville.Common.Logging</name>
|
||||||
|
</assembly>
|
||||||
|
<members>
|
||||||
|
<member name="T:Cryville.Common.Logging.Logger">
|
||||||
|
<summary>
|
||||||
|
A logger.
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:Cryville.Common.Logging.Logger.AddListener(Cryville.Common.Logging.LoggerListener)">
|
||||||
|
<summary>
|
||||||
|
Attaches a listener to the logger.
|
||||||
|
</summary>
|
||||||
|
<param name="listener">The logger listener.</param>
|
||||||
|
</member>
|
||||||
|
<member name="M:Cryville.Common.Logging.Logger.RemoveListener(Cryville.Common.Logging.LoggerListener)">
|
||||||
|
<summary>
|
||||||
|
Detaches a listener from the logger.
|
||||||
|
</summary>
|
||||||
|
<param name="listener">The logger listener.</param>
|
||||||
|
</member>
|
||||||
|
<member name="M:Cryville.Common.Logging.Logger.Log(System.Int32,System.String,System.String,System.Object[])">
|
||||||
|
<summary>
|
||||||
|
Logs to the logger.
|
||||||
|
</summary>
|
||||||
|
<param name="level">The severity level.</param>
|
||||||
|
<param name="category">The category.</param>
|
||||||
|
<param name="format">The format string.</param>
|
||||||
|
<param name="args">The arguments for formatting.</param>
|
||||||
|
</member>
|
||||||
|
<member name="M:Cryville.Common.Logging.Logger.Log(System.Int32,System.String,System.IFormatProvider,System.String,System.Object[])">
|
||||||
|
<summary>
|
||||||
|
Logs to the logger.
|
||||||
|
</summary>
|
||||||
|
<param name="level">The severity level.</param>
|
||||||
|
<param name="category">The category.</param>
|
||||||
|
<param name="provider">The format provider.</param>
|
||||||
|
<param name="format">The format string.</param>
|
||||||
|
<param name="args">The arguments for formatting.</param>
|
||||||
|
</member>
|
||||||
|
<member name="M:Cryville.Common.Logging.Logger.Log(System.Int32,System.String,System.String)">
|
||||||
|
<summary>
|
||||||
|
Logs to the logger.
|
||||||
|
</summary>
|
||||||
|
<param name="level">The severity level.</param>
|
||||||
|
<param name="category">The category.</param>
|
||||||
|
<param name="message">The message.</param>
|
||||||
|
</member>
|
||||||
|
<member name="M:Cryville.Common.Logging.Logger.Log(System.Int32,System.String,System.Char[])">
|
||||||
|
<summary>
|
||||||
|
Logs to the logger.
|
||||||
|
</summary>
|
||||||
|
<param name="level">The severity level.</param>
|
||||||
|
<param name="category">The category.</param>
|
||||||
|
<param name="message">An array of <see cref="T:System.Char" /> containing the message.</param>
|
||||||
|
</member>
|
||||||
|
<member name="M:Cryville.Common.Logging.Logger.Log(System.Int32,System.String,System.Char[],System.Int32,System.Int32)">
|
||||||
|
<summary>
|
||||||
|
Logs to the logger.
|
||||||
|
</summary>
|
||||||
|
<param name="level">The severity level.</param>
|
||||||
|
<param name="category">The category.</param>
|
||||||
|
<param name="message">An array of <see cref="T:System.Char" /> containing the message.</param>
|
||||||
|
<param name="index">A zero-based index of the first character of the message within <paramref name="message" />.</param>
|
||||||
|
<param name="length">The length of the message.</param>
|
||||||
|
</member>
|
||||||
|
<member name="M:Cryville.Common.Logging.Logger.Log(System.Int32,System.String,System.Char*,System.Int32)">
|
||||||
|
<summary>
|
||||||
|
Logs to the logger.
|
||||||
|
</summary>
|
||||||
|
<param name="level">The severity level.</param>
|
||||||
|
<param name="category">The category.</param>
|
||||||
|
<param name="message">A pointer to the first character of the message.</param>
|
||||||
|
<param name="length">The length of the message.</param>
|
||||||
|
</member>
|
||||||
|
<member name="T:Cryville.Common.Logging.LoggerListener">
|
||||||
|
<summary>
|
||||||
|
A logger listener.
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:Cryville.Common.Logging.LoggerListener.Dispose(System.Boolean)">
|
||||||
|
<summary>
|
||||||
|
Closes the logger listener and cleans up all the resources.
|
||||||
|
</summary>
|
||||||
|
<param name="disposing">Whether to clean up managed resources.</param>
|
||||||
|
</member>
|
||||||
|
<member name="M:Cryville.Common.Logging.LoggerListener.Dispose">
|
||||||
|
<summary>
|
||||||
|
Closes the logger listener.
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:Cryville.Common.Logging.LoggerListener.OnLog(System.Int32,System.String,System.String)">
|
||||||
|
<summary>
|
||||||
|
Handles an incoming log.
|
||||||
|
</summary>
|
||||||
|
<param name="level">The severity level.</param>
|
||||||
|
<param name="category">The category.</param>
|
||||||
|
<param name="message">The message.</param>
|
||||||
|
</member>
|
||||||
|
<member name="M:Cryville.Common.Logging.LoggerListener.OnLog(System.Int32,System.String,System.Char[],System.Int32,System.Int32)">
|
||||||
|
<summary>
|
||||||
|
Handles an incoming log.
|
||||||
|
</summary>
|
||||||
|
<param name="level">The severity level.</param>
|
||||||
|
<param name="category">The category.</param>
|
||||||
|
<param name="message">An array of <see cref="T:System.Char" /> containing the message.</param>
|
||||||
|
<param name="index">A zero-based index of the first character of the message within <paramref name="message" />.</param>
|
||||||
|
<param name="length">The length of the message.</param>
|
||||||
|
</member>
|
||||||
|
<member name="M:Cryville.Common.Logging.LoggerListener.OnLog(System.Int32,System.String,System.Char*,System.Int32)">
|
||||||
|
<summary>
|
||||||
|
Handles an incoming log.
|
||||||
|
</summary>
|
||||||
|
<param name="level">The severity level.</param>
|
||||||
|
<param name="category">The category.</param>
|
||||||
|
<param name="message">A pointer to the first character of the message.</param>
|
||||||
|
<param name="length">The length of the message.</param>
|
||||||
|
</member>
|
||||||
|
<member name="T:Cryville.Common.Logging.InstantLoggerListener">
|
||||||
|
<summary>
|
||||||
|
A <see cref="T:Cryville.Common.Logging.LoggerListener" /> that calls a callback function on log.
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="E:Cryville.Common.Logging.InstantLoggerListener.Log">
|
||||||
|
<summary>
|
||||||
|
Occurs when a log is logged to the logger.
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:Cryville.Common.Logging.InstantLoggerListener.OnLog(System.Int32,System.String,System.String)">
|
||||||
|
<inheritdoc />
|
||||||
|
</member>
|
||||||
|
<member name="T:Cryville.Common.Logging.BufferedLoggerListener">
|
||||||
|
<summary>
|
||||||
|
A <see cref="T:Cryville.Common.Logging.LoggerListener" /> that buffers the logs for enumeration.
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:Cryville.Common.Logging.BufferedLoggerListener.OnLog(System.Int32,System.String,System.String)">
|
||||||
|
<inheritdoc />
|
||||||
|
</member>
|
||||||
|
<member name="M:Cryville.Common.Logging.BufferedLoggerListener.Enumerate(Cryville.Common.Logging.LogHandler)">
|
||||||
|
<summary>
|
||||||
|
Enumerates the buffered logs.
|
||||||
|
</summary>
|
||||||
|
<param name="callback">The callback function to receive the logs.</param>
|
||||||
|
</member>
|
||||||
|
<member name="T:Cryville.Common.Logging.StreamLoggerListener">
|
||||||
|
<summary>
|
||||||
|
A <see cref="T:Cryville.Common.Logging.LoggerListener" /> that writes logs into a stream.
|
||||||
|
</summary>
|
||||||
|
<param name="stream">The stream.</param>
|
||||||
|
<param name="encoding">The encoding.</param>
|
||||||
|
</member>
|
||||||
|
<member name="M:Cryville.Common.Logging.StreamLoggerListener.#ctor(System.IO.Stream,System.Text.Encoding)">
|
||||||
|
<summary>
|
||||||
|
A <see cref="T:Cryville.Common.Logging.LoggerListener" /> that writes logs into a stream.
|
||||||
|
</summary>
|
||||||
|
<param name="stream">The stream.</param>
|
||||||
|
<param name="encoding">The encoding.</param>
|
||||||
|
</member>
|
||||||
|
<member name="M:Cryville.Common.Logging.StreamLoggerListener.#ctor(System.IO.Stream)">
|
||||||
|
<summary>
|
||||||
|
Creates an instance of the <see cref="T:Cryville.Common.Logging.StreamLoggerListener" /> class.
|
||||||
|
</summary>
|
||||||
|
<param name="stream">The stream.</param>
|
||||||
|
</member>
|
||||||
|
<member name="P:Cryville.Common.Logging.StreamLoggerListener.AutoFlush">
|
||||||
|
<summary>
|
||||||
|
Whether to flush the stream every time a log is written.
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:Cryville.Common.Logging.StreamLoggerListener.OnLog(System.Int32,System.String,System.String)">
|
||||||
|
<inheritdoc />
|
||||||
|
</member>
|
||||||
|
<member name="T:Cryville.Common.Logging.LogHandler">
|
||||||
|
<summary>
|
||||||
|
Represents the method that will handle a log.
|
||||||
|
</summary>
|
||||||
|
<param name="level">The severity level.</param>
|
||||||
|
<param name="category">The category.</param>
|
||||||
|
<param name="message">The message.</param>
|
||||||
|
</member>
|
||||||
|
</members>
|
||||||
|
</doc>
|
7
Assets/Plugins/Cryville.Common.Logging.xml.meta
Normal file
7
Assets/Plugins/Cryville.Common.Logging.xml.meta
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 72ded0675457e0348809193a9c1092b5
|
||||||
|
TextScriptImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
BIN
Assets/Plugins/Cryville.EEW.BMKGOpenData.Map.dll
Normal file
BIN
Assets/Plugins/Cryville.EEW.BMKGOpenData.Map.dll
Normal file
Binary file not shown.
33
Assets/Plugins/Cryville.EEW.BMKGOpenData.Map.dll.meta
Normal file
33
Assets/Plugins/Cryville.EEW.BMKGOpenData.Map.dll.meta
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 9c2c20067e0adc54c813350fd61f9a3a
|
||||||
|
PluginImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
iconMap: {}
|
||||||
|
executionOrder: {}
|
||||||
|
defineConstraints: []
|
||||||
|
isPreloaded: 0
|
||||||
|
isOverridable: 0
|
||||||
|
isExplicitlyReferenced: 0
|
||||||
|
validateReferences: 1
|
||||||
|
platformData:
|
||||||
|
- first:
|
||||||
|
Any:
|
||||||
|
second:
|
||||||
|
enabled: 1
|
||||||
|
settings: {}
|
||||||
|
- first:
|
||||||
|
Editor: Editor
|
||||||
|
second:
|
||||||
|
enabled: 0
|
||||||
|
settings:
|
||||||
|
DefaultValueInitialized: true
|
||||||
|
- first:
|
||||||
|
Windows Store Apps: WindowsStoreApps
|
||||||
|
second:
|
||||||
|
enabled: 0
|
||||||
|
settings:
|
||||||
|
CPU: AnyCPU
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
BIN
Assets/Plugins/Cryville.EEW.BMKGOpenData.TTS.dll
Normal file
BIN
Assets/Plugins/Cryville.EEW.BMKGOpenData.TTS.dll
Normal file
Binary file not shown.
33
Assets/Plugins/Cryville.EEW.BMKGOpenData.TTS.dll.meta
Normal file
33
Assets/Plugins/Cryville.EEW.BMKGOpenData.TTS.dll.meta
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: e9164d2df3d1c03499419935666416ae
|
||||||
|
PluginImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
iconMap: {}
|
||||||
|
executionOrder: {}
|
||||||
|
defineConstraints: []
|
||||||
|
isPreloaded: 0
|
||||||
|
isOverridable: 0
|
||||||
|
isExplicitlyReferenced: 0
|
||||||
|
validateReferences: 1
|
||||||
|
platformData:
|
||||||
|
- first:
|
||||||
|
Any:
|
||||||
|
second:
|
||||||
|
enabled: 1
|
||||||
|
settings: {}
|
||||||
|
- first:
|
||||||
|
Editor: Editor
|
||||||
|
second:
|
||||||
|
enabled: 0
|
||||||
|
settings:
|
||||||
|
DefaultValueInitialized: true
|
||||||
|
- first:
|
||||||
|
Windows Store Apps: WindowsStoreApps
|
||||||
|
second:
|
||||||
|
enabled: 0
|
||||||
|
settings:
|
||||||
|
CPU: AnyCPU
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
BIN
Assets/Plugins/Cryville.EEW.BMKGOpenData.dll
Normal file
BIN
Assets/Plugins/Cryville.EEW.BMKGOpenData.dll
Normal file
Binary file not shown.
33
Assets/Plugins/Cryville.EEW.BMKGOpenData.dll.meta
Normal file
33
Assets/Plugins/Cryville.EEW.BMKGOpenData.dll.meta
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 152cea136489ac044b7c12c66ba72b53
|
||||||
|
PluginImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
iconMap: {}
|
||||||
|
executionOrder: {}
|
||||||
|
defineConstraints: []
|
||||||
|
isPreloaded: 0
|
||||||
|
isOverridable: 0
|
||||||
|
isExplicitlyReferenced: 0
|
||||||
|
validateReferences: 1
|
||||||
|
platformData:
|
||||||
|
- first:
|
||||||
|
Any:
|
||||||
|
second:
|
||||||
|
enabled: 1
|
||||||
|
settings: {}
|
||||||
|
- first:
|
||||||
|
Editor: Editor
|
||||||
|
second:
|
||||||
|
enabled: 0
|
||||||
|
settings:
|
||||||
|
DefaultValueInitialized: true
|
||||||
|
- first:
|
||||||
|
Windows Store Apps: WindowsStoreApps
|
||||||
|
second:
|
||||||
|
enabled: 0
|
||||||
|
settings:
|
||||||
|
CPU: AnyCPU
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
BIN
Assets/Plugins/Cryville.EEW.CENCStrongGroundMotion.Map.dll
Normal file
BIN
Assets/Plugins/Cryville.EEW.CENCStrongGroundMotion.Map.dll
Normal file
Binary file not shown.
@@ -0,0 +1,33 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 550171b48a648b34e9ce5f1aba6244f1
|
||||||
|
PluginImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
iconMap: {}
|
||||||
|
executionOrder: {}
|
||||||
|
defineConstraints: []
|
||||||
|
isPreloaded: 0
|
||||||
|
isOverridable: 0
|
||||||
|
isExplicitlyReferenced: 0
|
||||||
|
validateReferences: 1
|
||||||
|
platformData:
|
||||||
|
- first:
|
||||||
|
Any:
|
||||||
|
second:
|
||||||
|
enabled: 1
|
||||||
|
settings: {}
|
||||||
|
- first:
|
||||||
|
Editor: Editor
|
||||||
|
second:
|
||||||
|
enabled: 0
|
||||||
|
settings:
|
||||||
|
DefaultValueInitialized: true
|
||||||
|
- first:
|
||||||
|
Windows Store Apps: WindowsStoreApps
|
||||||
|
second:
|
||||||
|
enabled: 0
|
||||||
|
settings:
|
||||||
|
CPU: AnyCPU
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
BIN
Assets/Plugins/Cryville.EEW.CENCStrongGroundMotion.dll
Normal file
BIN
Assets/Plugins/Cryville.EEW.CENCStrongGroundMotion.dll
Normal file
Binary file not shown.
33
Assets/Plugins/Cryville.EEW.CENCStrongGroundMotion.dll.meta
Normal file
33
Assets/Plugins/Cryville.EEW.CENCStrongGroundMotion.dll.meta
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 0f848a4ea2f35e7449e584beee48c659
|
||||||
|
PluginImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
iconMap: {}
|
||||||
|
executionOrder: {}
|
||||||
|
defineConstraints: []
|
||||||
|
isPreloaded: 0
|
||||||
|
isOverridable: 0
|
||||||
|
isExplicitlyReferenced: 0
|
||||||
|
validateReferences: 1
|
||||||
|
platformData:
|
||||||
|
- first:
|
||||||
|
Any:
|
||||||
|
second:
|
||||||
|
enabled: 1
|
||||||
|
settings: {}
|
||||||
|
- first:
|
||||||
|
Editor: Editor
|
||||||
|
second:
|
||||||
|
enabled: 0
|
||||||
|
settings:
|
||||||
|
DefaultValueInitialized: true
|
||||||
|
- first:
|
||||||
|
Windows Store Apps: WindowsStoreApps
|
||||||
|
second:
|
||||||
|
enabled: 0
|
||||||
|
settings:
|
||||||
|
CPU: AnyCPU
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Assets/Plugins/Cryville.EEW.EMSC.Map.dll
Normal file
BIN
Assets/Plugins/Cryville.EEW.EMSC.Map.dll
Normal file
Binary file not shown.
33
Assets/Plugins/Cryville.EEW.EMSC.Map.dll.meta
Normal file
33
Assets/Plugins/Cryville.EEW.EMSC.Map.dll.meta
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: e1ef9470a2a1d7b4da9ddd106620b665
|
||||||
|
PluginImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
iconMap: {}
|
||||||
|
executionOrder: {}
|
||||||
|
defineConstraints: []
|
||||||
|
isPreloaded: 0
|
||||||
|
isOverridable: 0
|
||||||
|
isExplicitlyReferenced: 0
|
||||||
|
validateReferences: 1
|
||||||
|
platformData:
|
||||||
|
- first:
|
||||||
|
Any:
|
||||||
|
second:
|
||||||
|
enabled: 1
|
||||||
|
settings: {}
|
||||||
|
- first:
|
||||||
|
Editor: Editor
|
||||||
|
second:
|
||||||
|
enabled: 0
|
||||||
|
settings:
|
||||||
|
DefaultValueInitialized: true
|
||||||
|
- first:
|
||||||
|
Windows Store Apps: WindowsStoreApps
|
||||||
|
second:
|
||||||
|
enabled: 0
|
||||||
|
settings:
|
||||||
|
CPU: AnyCPU
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
BIN
Assets/Plugins/Cryville.EEW.EMSC.dll
Normal file
BIN
Assets/Plugins/Cryville.EEW.EMSC.dll
Normal file
Binary file not shown.
33
Assets/Plugins/Cryville.EEW.EMSC.dll.meta
Normal file
33
Assets/Plugins/Cryville.EEW.EMSC.dll.meta
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 48f0c884a8a1e4043948f765ed18e4bc
|
||||||
|
PluginImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
iconMap: {}
|
||||||
|
executionOrder: {}
|
||||||
|
defineConstraints: []
|
||||||
|
isPreloaded: 0
|
||||||
|
isOverridable: 0
|
||||||
|
isExplicitlyReferenced: 0
|
||||||
|
validateReferences: 1
|
||||||
|
platformData:
|
||||||
|
- first:
|
||||||
|
Any:
|
||||||
|
second:
|
||||||
|
enabled: 1
|
||||||
|
settings: {}
|
||||||
|
- first:
|
||||||
|
Editor: Editor
|
||||||
|
second:
|
||||||
|
enabled: 0
|
||||||
|
settings:
|
||||||
|
DefaultValueInitialized: true
|
||||||
|
- first:
|
||||||
|
Windows Store Apps: WindowsStoreApps
|
||||||
|
second:
|
||||||
|
enabled: 0
|
||||||
|
settings:
|
||||||
|
CPU: AnyCPU
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
BIN
Assets/Plugins/Cryville.EEW.FANStudio.Map.dll
Normal file
BIN
Assets/Plugins/Cryville.EEW.FANStudio.Map.dll
Normal file
Binary file not shown.
33
Assets/Plugins/Cryville.EEW.FANStudio.Map.dll.meta
Normal file
33
Assets/Plugins/Cryville.EEW.FANStudio.Map.dll.meta
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: decba95f87869fa4699fd22f50528285
|
||||||
|
PluginImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
iconMap: {}
|
||||||
|
executionOrder: {}
|
||||||
|
defineConstraints: []
|
||||||
|
isPreloaded: 0
|
||||||
|
isOverridable: 0
|
||||||
|
isExplicitlyReferenced: 0
|
||||||
|
validateReferences: 1
|
||||||
|
platformData:
|
||||||
|
- first:
|
||||||
|
Any:
|
||||||
|
second:
|
||||||
|
enabled: 1
|
||||||
|
settings: {}
|
||||||
|
- first:
|
||||||
|
Editor: Editor
|
||||||
|
second:
|
||||||
|
enabled: 0
|
||||||
|
settings:
|
||||||
|
DefaultValueInitialized: true
|
||||||
|
- first:
|
||||||
|
Windows Store Apps: WindowsStoreApps
|
||||||
|
second:
|
||||||
|
enabled: 0
|
||||||
|
settings:
|
||||||
|
CPU: AnyCPU
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
BIN
Assets/Plugins/Cryville.EEW.FANStudio.TTS.dll
Normal file
BIN
Assets/Plugins/Cryville.EEW.FANStudio.TTS.dll
Normal file
Binary file not shown.
33
Assets/Plugins/Cryville.EEW.FANStudio.TTS.dll.meta
Normal file
33
Assets/Plugins/Cryville.EEW.FANStudio.TTS.dll.meta
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 50ac3fa1c3c1c7244820383f3c6f2617
|
||||||
|
PluginImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
iconMap: {}
|
||||||
|
executionOrder: {}
|
||||||
|
defineConstraints: []
|
||||||
|
isPreloaded: 0
|
||||||
|
isOverridable: 0
|
||||||
|
isExplicitlyReferenced: 0
|
||||||
|
validateReferences: 1
|
||||||
|
platformData:
|
||||||
|
- first:
|
||||||
|
Any:
|
||||||
|
second:
|
||||||
|
enabled: 1
|
||||||
|
settings: {}
|
||||||
|
- first:
|
||||||
|
Editor: Editor
|
||||||
|
second:
|
||||||
|
enabled: 0
|
||||||
|
settings:
|
||||||
|
DefaultValueInitialized: true
|
||||||
|
- first:
|
||||||
|
Windows Store Apps: WindowsStoreApps
|
||||||
|
second:
|
||||||
|
enabled: 0
|
||||||
|
settings:
|
||||||
|
CPU: AnyCPU
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
BIN
Assets/Plugins/Cryville.EEW.FANStudio.dll
Normal file
BIN
Assets/Plugins/Cryville.EEW.FANStudio.dll
Normal file
Binary file not shown.
33
Assets/Plugins/Cryville.EEW.FANStudio.dll.meta
Normal file
33
Assets/Plugins/Cryville.EEW.FANStudio.dll.meta
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 2c4be81d04cc2a345933d001819f2d96
|
||||||
|
PluginImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
iconMap: {}
|
||||||
|
executionOrder: {}
|
||||||
|
defineConstraints: []
|
||||||
|
isPreloaded: 0
|
||||||
|
isOverridable: 0
|
||||||
|
isExplicitlyReferenced: 0
|
||||||
|
validateReferences: 1
|
||||||
|
platformData:
|
||||||
|
- first:
|
||||||
|
Any:
|
||||||
|
second:
|
||||||
|
enabled: 1
|
||||||
|
settings: {}
|
||||||
|
- first:
|
||||||
|
Editor: Editor
|
||||||
|
second:
|
||||||
|
enabled: 0
|
||||||
|
settings:
|
||||||
|
DefaultValueInitialized: true
|
||||||
|
- first:
|
||||||
|
Windows Store Apps: WindowsStoreApps
|
||||||
|
second:
|
||||||
|
enabled: 0
|
||||||
|
settings:
|
||||||
|
CPU: AnyCPU
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
Binary file not shown.
BIN
Assets/Plugins/Cryville.EEW.GeoNet.Map.dll
Normal file
BIN
Assets/Plugins/Cryville.EEW.GeoNet.Map.dll
Normal file
Binary file not shown.
33
Assets/Plugins/Cryville.EEW.GeoNet.Map.dll.meta
Normal file
33
Assets/Plugins/Cryville.EEW.GeoNet.Map.dll.meta
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 9add703a85e306e41a5f1f424b9e5980
|
||||||
|
PluginImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
iconMap: {}
|
||||||
|
executionOrder: {}
|
||||||
|
defineConstraints: []
|
||||||
|
isPreloaded: 0
|
||||||
|
isOverridable: 0
|
||||||
|
isExplicitlyReferenced: 0
|
||||||
|
validateReferences: 1
|
||||||
|
platformData:
|
||||||
|
- first:
|
||||||
|
Any:
|
||||||
|
second:
|
||||||
|
enabled: 1
|
||||||
|
settings: {}
|
||||||
|
- first:
|
||||||
|
Editor: Editor
|
||||||
|
second:
|
||||||
|
enabled: 0
|
||||||
|
settings:
|
||||||
|
DefaultValueInitialized: true
|
||||||
|
- first:
|
||||||
|
Windows Store Apps: WindowsStoreApps
|
||||||
|
second:
|
||||||
|
enabled: 0
|
||||||
|
settings:
|
||||||
|
CPU: AnyCPU
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
BIN
Assets/Plugins/Cryville.EEW.GeoNet.TTS.dll
Normal file
BIN
Assets/Plugins/Cryville.EEW.GeoNet.TTS.dll
Normal file
Binary file not shown.
33
Assets/Plugins/Cryville.EEW.GeoNet.TTS.dll.meta
Normal file
33
Assets/Plugins/Cryville.EEW.GeoNet.TTS.dll.meta
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 1fa7d6d104052f447b49fc53f65d55cd
|
||||||
|
PluginImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
iconMap: {}
|
||||||
|
executionOrder: {}
|
||||||
|
defineConstraints: []
|
||||||
|
isPreloaded: 0
|
||||||
|
isOverridable: 0
|
||||||
|
isExplicitlyReferenced: 0
|
||||||
|
validateReferences: 1
|
||||||
|
platformData:
|
||||||
|
- first:
|
||||||
|
Any:
|
||||||
|
second:
|
||||||
|
enabled: 1
|
||||||
|
settings: {}
|
||||||
|
- first:
|
||||||
|
Editor: Editor
|
||||||
|
second:
|
||||||
|
enabled: 0
|
||||||
|
settings:
|
||||||
|
DefaultValueInitialized: true
|
||||||
|
- first:
|
||||||
|
Windows Store Apps: WindowsStoreApps
|
||||||
|
second:
|
||||||
|
enabled: 0
|
||||||
|
settings:
|
||||||
|
CPU: AnyCPU
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
BIN
Assets/Plugins/Cryville.EEW.GeoNet.dll
Normal file
BIN
Assets/Plugins/Cryville.EEW.GeoNet.dll
Normal file
Binary file not shown.
33
Assets/Plugins/Cryville.EEW.GeoNet.dll.meta
Normal file
33
Assets/Plugins/Cryville.EEW.GeoNet.dll.meta
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 590f9955e3e1e36458e2f7b807a05188
|
||||||
|
PluginImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
iconMap: {}
|
||||||
|
executionOrder: {}
|
||||||
|
defineConstraints: []
|
||||||
|
isPreloaded: 0
|
||||||
|
isOverridable: 0
|
||||||
|
isExplicitlyReferenced: 0
|
||||||
|
validateReferences: 1
|
||||||
|
platformData:
|
||||||
|
- first:
|
||||||
|
Any:
|
||||||
|
second:
|
||||||
|
enabled: 1
|
||||||
|
settings: {}
|
||||||
|
- first:
|
||||||
|
Editor: Editor
|
||||||
|
second:
|
||||||
|
enabled: 0
|
||||||
|
settings:
|
||||||
|
DefaultValueInitialized: true
|
||||||
|
- first:
|
||||||
|
Windows Store Apps: WindowsStoreApps
|
||||||
|
second:
|
||||||
|
enabled: 0
|
||||||
|
settings:
|
||||||
|
CPU: AnyCPU
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user