This commit is contained in:
DESKTOP-5RP3AKU\Jisol
2024-10-17 03:20:22 +08:00
parent dd2e0e8a46
commit 0d600a2786
1490 changed files with 12905 additions and 7825 deletions

View File

@@ -1,141 +0,0 @@
using System;
using System.Collections.Generic;
using JNGame.Runtime.Util;
using UnityEngine;
namespace JNGame.Util
{
/// <summary>
/// 静态事件分发器
/// </summary>
public class EventDispatcher
{
public static readonly EventDispatcher Event = new EventDispatcher();
public Dictionary<string, List<Delegate>> EventHandlers { get; private set; } = new();
/// <summary>
/// 添加事件监听器
/// </summary>
/// <param name="eventId">事件标识符</param>
/// <param name="listener">事件监听器</param>
public void AddListener(string eventId, Action listener)
{
if (!EventHandlers.ContainsKey(eventId))
{
EventHandlers[eventId] = new List<Delegate>();
}
EventHandlers[eventId].Add(listener);
Debug.Log(eventId+ "AddListener" + EventHandlers[eventId].Count);
}
/// <summary>
/// 添加事件监听器
/// </summary>
/// <typeparam name="T">事件参数类型</typeparam>
/// <param name="eventId">事件标识符</param>
/// <param name="listener">事件监听器</param>
public void AddListener<T>(string eventId, Action<T> listener)
{
if (!EventHandlers.ContainsKey(eventId))
{
EventHandlers[eventId] = new List<Delegate>();
}
EventHandlers[eventId].Add(listener);
Debug.Log(eventId+ "AddListener" + EventHandlers[eventId].Count);
}
/// <summary>
/// 移除事件监听器
/// </summary>
/// <typeparam name="T">事件参数类型</typeparam>
/// <param name="eventId">事件标识符</param>
/// <param name="listener">事件监听器</param>
public void RemoveListener(string eventId, Action listener)
{
if (EventHandlers.ContainsKey(eventId))
{
//eventHandlers[eventId] = (Action<T>)eventHandlers[eventId] - listener;
EventHandlers[eventId].Remove(listener);
Debug.Log(eventId + "RemoveListener" + EventHandlers[eventId].Count);
}
}
public void RemoveListener<T>(string eventId, Action<T> listener)
{
if (EventHandlers.ContainsKey(eventId))
{
//eventHandlers[eventId] = (Action<T>)eventHandlers[eventId] - listener;
EventHandlers[eventId].Remove(listener);
Debug.Log(eventId + "RemoveListener" + EventHandlers[eventId].Count);
}
}
/// <summary>
/// 分发事件
/// </summary>
/// <typeparam name="T">事件参数类型</typeparam>
/// <param name="eventId">事件标识符</param>
/// <param name="args">事件参数</param>
public void Dispatch<T>(string eventId, T args)
{
if (EventHandlers.ContainsKey(eventId) && EventHandlers[eventId] != null)
{
foreach(Delegate fun in EventHandlers[eventId])
{
// 确保 fun 实际上是指向一个 Action<T> 类型的函数
if (fun.Method.GetParameters().Length == 1 && fun.Method.GetParameters()[0].ParameterType == typeof(T))
{
((Action<T>)fun)(args);
}
}
}
}
public void Dispatch(string eventId)
{
if (EventHandlers.ContainsKey(eventId) && EventHandlers[eventId] != null)
{
foreach(Delegate fun in EventHandlers[eventId])
{
// 确保 fun 实际上是指向一个 Action<T> 类型的函数
if (fun.Method.GetParameters().Length == 0)
{
((Action)fun)();
}
}
}
}
/// <summary>
/// 主线程分发事件 [禁止帧同步中使用主线分发事件]
/// </summary>
public void TryMainDispatch<T>(string eventId, T args)
{
UnityMainThreadDispatcher.Instance.Enqueue(() =>
{
try
{
Dispatch<T>(eventId,args);
}catch(Exception e){Debug.LogError(e.Message);}
});
}
public void TryMainDispatch(string eventId)
{
UnityMainThreadDispatcher.Instance.Enqueue(() =>
{
try
{
Dispatch(eventId);
}catch(Exception e){Debug.LogError(e.Message);}
});
}
public void Reset()
{
EventHandlers = new();
}
}
}

View File

@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 311db7dc834c409b81610b20f5510988
timeCreated: 1706065209

View File

@@ -1,78 +0,0 @@
using System;
using System.Collections.Generic;
using Cysharp.Threading.Tasks;
using Newtonsoft.Json;
using UnityEngine.Networking;
namespace JNGame.Runtime.Util
{
public class JAPIConfig{
public string BaseURL = "http://localhost:8080"; //baseURL 默认HTTP头
public int Timeout = 5000; //超时时间
}
public class JAPIData<T>{
public T Data;
}
public class NewsContext<T>
{
public int state;
public String msg;
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public T data;
}
/**
* JNGame 的 网络请求类
*/
public class JAPI {
private JAPIConfig _config;
public JAPI(JAPIConfig config = null)
{
if (config == null) config = new JAPIConfig();
this._config = config;
}
public async UniTask<NewsContext<T>> GetNews<T>(string url)
{
var request = UnityWebRequest.Get($"{this._config.BaseURL}/{url}");
var text = (await request.SendWebRequest()).downloadHandler.text;
return JsonConvert.DeserializeObject<NewsContext<T>>(text);
}
public async UniTask<T> Get<T>(string url)
{
var request = UnityWebRequest.Get($"{this._config.BaseURL}/{url}");
return JsonConvert.DeserializeObject<T>((await request.SendWebRequest()).downloadHandler.text);
}
public async UniTask<T> Post<T>(string url,Dictionary<string,string> data)
{
var request = UnityWebRequest.Post($"{this._config.BaseURL}/{url}",data);
return JsonConvert.DeserializeObject<T>((await request.SendWebRequest()).downloadHandler.text);
}
public async UniTask<T> Post<T,TA>(string url,TA data)
{
var request = UnityWebRequest.PostWwwForm($"{this._config.BaseURL}/{url}",JsonConvert.SerializeObject(data));
return JsonConvert.DeserializeObject<T>((await request.SendWebRequest()).downloadHandler.text);
}
public async UniTask<byte[]> GetByte(string url)
{
var request = UnityWebRequest.Get($"{this._config.BaseURL}/{url}");
return (await request.SendWebRequest()).downloadHandler.data;
}
public async UniTask<byte[]> PostByte(string url,Dictionary<string,string> data)
{
var request = UnityWebRequest.Post($"{this._config.BaseURL}/{url}",data);
return (await request.SendWebRequest()).downloadHandler.data;
}
}
}

View File

@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: fc72d9190d1241f680950baaaf2ec27e
timeCreated: 1706373831

View File

@@ -1,13 +0,0 @@
using Newtonsoft.Json;
namespace JNGame.Runtime.Util {
public static class JsonUtil {
public static string ToJson(object obj){
return JsonConvert.SerializeObject(obj);
}
public static T ToObject<T>(string txt){
return JsonConvert.DeserializeObject<T>(txt);
}
}
}

View File

@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 73b025deb8654b7dbc511312822630ab
timeCreated: 1715152907

View File

@@ -1,33 +0,0 @@
using System;
using System.Net.Sockets;
using System.Threading.Tasks;
namespace JNGame.Runtime.Util
{
public class NetTool
{
public static async Task SendAsync(Socket socket, byte[] buffer)
{
// 注意这里我们实际上并没有直接使用async/await因为BeginSend是回调模式
// 但我们可以使用TaskCompletionSource来桥接回调和async/await
var tcs = new TaskCompletionSource<int>();
// 异步发送数据
socket.BeginSend(buffer, 0, buffer.Length, SocketFlags.None, (ar) =>
{
try
{
int bytesSent = socket.EndSend(ar);
tcs.SetResult(bytesSent);
}
catch (Exception ex)
{
tcs.SetException(ex);
}
}, null);
// 等待发送完成
await tcs.Task;
}
}
}

View File

@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 43383731dd334efaad1a886ec16ac729
timeCreated: 1723713652

View File

@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 08fe2a0eeed74d1db5fa680814c1a9b3
timeCreated: 1720682585

View File

@@ -1,66 +0,0 @@
namespace JNGame.Runtime.Util.NoThread
{
public class Interlocked
{
public static long Read(ref long location)
{
return location;
}
public static int Increment(ref int location)
{
return location += 1;
}
public static long Increment(ref long location)
{
return location += 1;
}
public static int Decrement(ref int location)
{
return location -= 1;
}
public static long Decrement(ref long location)
{
return location -= 1;
}
public static int Exchange(ref int location, int value)
{
int temp = location;
return location = value;
}
public static long Exchange(ref long location, long value)
{
long temp = location;
return location = value;
}
public static int Add(ref int location, int value)
{
return location += value;
}
public static long Add(ref long location, long value)
{
return location += value;
}
public static int CompareExchange(ref int location, int value, int comparand)
{
if (location == comparand)
{
return location = value;
}
else
{
return location;
}
}
public static long CompareExchange(ref long location, long value, long comparand)
{
if (location == comparand)
{
return location = value;
}
else
{
return location;
}
}
}
}

View File

@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: a13340b679274363b976467f30806a56
timeCreated: 1720682597

View File

@@ -1,49 +0,0 @@
using System;
using UnityEngine;
namespace JNGame.Runtime.Util
{
public class Profiler
{
// [System.Diagnostics.Conditional("ENABLE_TEST_SROPTIONS")]
public static void BeginSample(string tag)
{
#if UNITY_5_3_OR_NEWER
UnityEngine.Profiling.Profiler.BeginSample(tag);
#endif
}
// [System.Diagnostics.Conditional("ENABLE_TEST_SROPTIONS")]
public static void EndSample()
{
#if UNITY_5_3_OR_NEWER
UnityEngine.Profiling.Profiler.EndSample();
#endif
}
/// <summary>
/// 统计标记时间
/// </summary>
private static DateTime s_MarkStart;
/// <summary>
/// 重置当前时间
/// </summary>
public static void ResetElapseTime()
{
s_MarkStart = DateTime.Now;
}
/// <summary>
/// 统计时间间隔,单位:毫秒
/// </summary>
/// <param name="tag"></param>
public static void LogElapseTime(string tag = "")
{
var ms = (DateTime.Now - s_MarkStart).TotalMilliseconds;
Debug.LogWarning($"{tag} use time:{ms} ms");
s_MarkStart = DateTime.Now;
}
}
}

View File

@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 75ef2062d79a44248c98964373827d74
timeCreated: 1715153593

View File

@@ -1,61 +0,0 @@
using System;
using JNGame.Math;
namespace JNGame.Runtime.Util
{
public static class RandomUtil
{
public static Func<LFloat> SyncRandom(int seed = 1000000,int start = 10)
{
// 线性同余生成器的参数
// const int a = 1103515245;
// const int increment = 16807;
for (var i = 0; i < start; i++)
{
seed = (110351* seed + 16807) % 214748;
}
return () =>
{
seed = (110351 * seed + 16807) % 214748;
// 返回随机浮点数
return LMath.Abs((LFloat)seed / 214748);
};
}
public static Func<LFloat,LFloat,LFloat> SyncRandomFloat(int seed = 1000000,int start = 10)
{
var nRandom = SyncRandom(seed, start);
return (LFloat min,LFloat max) =>
{
var random = nRandom();
return random * (max - min) + min;
};
}
public static Func<int,int,int> SyncRandomInt(int seed = 2000000,int start = 10)
{
var nRandom = SyncRandom(seed, start);
return (min, max) =>
{
var random = nRandom();
return LMath.Round(random * (max - min) + min);
};
}
public static Func<int> Next(int start)
{
return () => start++;
}
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 04c0ca6d0b7f4dfab57c8dca2a3a7b94
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,53 +0,0 @@
namespace JNGame.Runtime.Util
{
public abstract class SingletonUtil<T> where T : Singleton<T>,new() {
public static T Instance{
get{
if (Singleton<T>.ins == null)
{
Singleton<T>.ins = new T();
Singleton<T>.ins.Init();
}
return Singleton<T>.ins;
}
}
public static void Clean()
{
if(Singleton<T>.ins != null)
Singleton<T>.ins.Clean();
Singleton<T>.ins = null;
}
}
public class Singleton<T> {
public static T ins;
public virtual void Init(){}
public virtual void Clean(){}
}
/// <summary>
/// 通用单例。
/// </summary>
/// <typeparam name="T">泛型T。</typeparam>
public class TSingleton<T> where T : new()
{
private static T _instance;
public static T Instance
{
get
{
if (null == _instance)
{
_instance = new T();
}
return _instance;
}
}
}
}

View File

@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 80ef0477d1c9478a8d73b1e6ac21a8b9
timeCreated: 1706167436

View File

@@ -1,97 +0,0 @@
using System;
using UnityEngine;
namespace JNGame.Runtime.Util
{
/// <summary>
/// Be aware this will not prevent a non singleton constructor
/// such as `T myT = new T();`
/// To prevent that, add `protected T () {}` to your singleton class.
///
/// As a note, this is made as MonoBehaviour because we need Coroutines.
/// </summary>
public class SingletonScene<T> : MonoBehaviour where T : MonoBehaviour
{
private static T _instance;
private static object _lock = new object();
public static T Instance
{
get
{
if (applicationIsQuitting)
{
Debug.LogWarning("[Singleton] Instance '" + typeof(T) +
"' already destroyed on application quit." +
" Won't create again - returning null.");
return null;
}
lock (_lock)
{
if (_instance == null)
{
try
{
_instance = (T)FindObjectOfType(typeof(T));
if (FindObjectsOfType(typeof(T)).Length > 1)
{
Debug.LogError("[Singleton] Something went really wrong " +
" - there should never be more than 1 singleton!" +
" Reopening the scene might fix it.");
return _instance;
}
if (_instance == null)
{
GameObject singleton = new GameObject();
_instance = singleton.AddComponent<T>();
singleton.name = "(singleton) " + typeof(T).ToString();
DontDestroyOnLoad(singleton);
Debug.Log("[Singleton] An instance of " + typeof(T) +
" is needed in the scene, so '" + singleton +
"' was created with DontDestroyOnLoad.");
}
else
{
Debug.Log("[Singleton] Using instance already created: " +
_instance.gameObject.name);
}
}
catch (Exception e)
{
Debug.LogError(e.Message);
}
}
return _instance;
}
}
}
private static bool applicationIsQuitting = false;
/// <summary>
/// When Unity quits, it destroys objects in a random order.
/// In principle, a Singleton is only destroyed when application quits.
/// If any script calls Instance after it have been destroyed,
/// it will create a buggy ghost object that will stay on the Editor scene
/// even after stopping playing the Application. Really bad!
/// So, this was made to be sure we're not creating that buggy ghost object.
/// </summary>
public void OnDestroy()
{
applicationIsQuitting = true;
OnDispose();
}
protected virtual void OnDispose()
{
}
}
}

View File

@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: c9277ee16036443695be9ff1ff09df12
timeCreated: 1706168129

View File

@@ -1,80 +0,0 @@
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
namespace JNGame.Runtime.Util
{
public delegate void TimerCallback();
public class TimerInfo
{
public TimerCallback Callback { get; set; }
public float Interval { get; set; }
public int Repeat { get; set; }
public float RunTime = 0;
public bool IsRunSuccess { get; private set; } = false;
public void Update(float dt)
{
if (IsRunSuccess) return;
RunTime += dt;
if (RunTime >= Interval)
{
RunTime = 0;
Callback?.Invoke();
if (Repeat > 0)
{
Repeat -= 1;
}
if (Repeat == 0) IsRunSuccess = true;
}
}
}
public class Timers : SingletonScene<Timers>
{
private List<TimerInfo> timers = new List<TimerInfo>();
public TimerInfo SetInterval(float interval,TimerCallback callback)
{
return SetTimeout(interval,callback,-1);
}
public TimerInfo SetTimeout(float interval,TimerCallback callback,int repeat = 1)
{
TimerInfo timerInfo = new TimerInfo()
{
Callback = callback,
Interval = interval,
Repeat = repeat,
};
timers.Add(timerInfo);
return timerInfo;
}
public void ClearTimeout(TimerCallback callback)
{
var removes = timers.Where(time => callback == time.Callback).ToList();
removes.ForEach(time=> timers.Remove(time));
}
private void Update()
{
timers.ForEach(time =>
{
time.Update(Time.deltaTime);
});
var removes = timers.Where(time => time.IsRunSuccess).ToList();
removes.ForEach(time=> timers.Remove(time));
}
}
}

View File

@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 0e985380c33944c08d0f350d088ae1fd
timeCreated: 1723616461

View File

@@ -1,41 +0,0 @@
using System;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
namespace JNGame.Runtime.Util
{
public class ToUtil
{
public static int Byte4ToInt(byte[] data)
{
return BitConverter.ToInt32(data, 0);
}
public static byte[] IntToByte4(int value)
{
byte[] result = new byte[4];
BitConverter.GetBytes(value).CopyTo(result, 0);
return result;
}
public static byte[] ObjectToBytes<T>(T data)
{
var formatter = new BinaryFormatter();
using var mStream = new MemoryStream();
formatter.Serialize(mStream, data);
mStream.Flush();
return mStream.GetBuffer();
}
public static T BytesToObject<T>(byte[] data)
{
var formatter = new BinaryFormatter();
using var mStream = new MemoryStream();
mStream.Write(data, 0, data.Length);
mStream.Flush();
mStream.Seek(0, SeekOrigin.Begin);
return (T)formatter.Deserialize(mStream);
}
}
}

View File

@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 22d4030ad259466884c3fefc632770f9
timeCreated: 1706004960

View File

@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 15722a570d164d64a9fcd76b3b0f48ba
timeCreated: 1720751749

View File

@@ -1,72 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace JNGame.Runtime.Util.Types
{
public class KeyValue<TKey, TValue>
{
private Dictionary<TKey, TValue> keyToValue = new Dictionary<TKey, TValue>();
private Dictionary<TValue, TKey> valueToKey = new Dictionary<TValue, TKey>();
public TKey[] Keys => keyToValue.Keys.ToArray();
public TValue[] Values => keyToValue.Values.ToArray();
public void Add(TKey key, TValue value)
{
if (keyToValue.ContainsKey(key) || valueToKey.ContainsKey(value))
{
throw new ArgumentException("Key or value already exists.");
}
keyToValue[key] = value;
valueToKey[value] = key;
}
public TValue Key2Value(TKey key)
{
keyToValue.TryGetValue(key, out var value);
return value;
}
public TKey Value2Key(TValue value)
{
valueToKey.TryGetValue(value, out var key);
return key;
}
public bool TryGetValueByKey(TKey key, out TValue value)
{
return keyToValue.TryGetValue(key, out value);
}
public bool TryGetValueByValue(TValue value, out TKey key)
{
return valueToKey.TryGetValue(value, out key);
}
public bool RemoveByKey(TKey key)
{
if (keyToValue.TryGetValue(key, out var value))
{
keyToValue.Remove(key);
valueToKey.Remove(value);
return true;
}
return false;
}
public bool RemoveByValue(TValue value)
{
if (valueToKey.TryGetValue(value, out var key))
{
keyToValue.Remove(key);
valueToKey.Remove(value);
return true;
}
return false;
}
}
}

View File

@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: bcb961f69f3a41428001d0f5c4841bf5
timeCreated: 1720751753

View File

@@ -1,78 +0,0 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace JNGame.Runtime.Util
{
/// Author: Pim de Witte (pimdewitte.com) and contributors, https://github.com/PimDeWitte/UnityMainThreadDispatcher
/// <summary>
/// A thread-safe class which holds a queue with actions to execute on the next Update() method. It can be used to make calls to the main thread for
/// things such as UI Manipulation in Unity. It was developed for use in combination with the Firebase Unity plugin, which uses separate threads for event handling
/// </summary>
public class UnityMainThreadDispatcher : SingletonScene<UnityMainThreadDispatcher> {
private readonly Queue<Action> _executionQueue = new Queue<Action>();
public void Update() {
lock(_executionQueue) {
while (_executionQueue.Count > 0) {
_executionQueue.Dequeue().Invoke();
}
}
}
/// <summary>
/// Locks the queue and adds the IEnumerator to the queue
/// </summary>
/// <param name="action">IEnumerator function that will be executed from the main thread.</param>
public void Enqueue(IEnumerator action) {
lock (_executionQueue) {
_executionQueue.Enqueue (() => {
StartCoroutine(action);
});
}
}
/// <summary>
/// Locks the queue and adds the Action to the queue
/// </summary>
/// <param name="action">function that will be executed from the main thread.</param>
public void Enqueue(Action action)
{
Enqueue(ActionWrapper(action));
}
/// <summary>
/// Locks the queue and adds the Action to the queue, returning a Task which is completed when the action completes
/// </summary>
/// <param name="action">function that will be executed from the main thread.</param>
/// <returns>A Task that can be awaited until the action completes</returns>
public Task EnqueueAsync(Action action)
{
var tcs = new TaskCompletionSource<bool>();
void WrappedAction() {
try
{
action();
tcs.TrySetResult(true);
} catch (Exception ex)
{
tcs.TrySetException(ex);
}
}
Enqueue(ActionWrapper(WrappedAction));
return tcs.Task;
}
IEnumerator ActionWrapper(Action a)
{
a();
yield return null;
}
}
}

View File

@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 4d1e1ab4d41f4a618dcf3ba40014cf20
timeCreated: 1724926741

View File

@@ -1,19 +0,0 @@
using System;
namespace JNGame.Runtime.Util
{
public class UseUtil
{
public static bool ContainsType(object[] array, Type typeToFind)
{
foreach (var item in array)
{
if (item.GetType() == typeToFind)
{
return true;
}
}
return false;
}
}
}

View File

@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 500748b025884f42ade05338e47bff56
timeCreated: 1708237347