95 Commits

Author SHA1 Message Date
준학 노
07858a99b3 오브젝트 목록 할당 팝업메세지 추가 2025-07-23 17:27:28 +09:00
준학 노
e6d842c89a 리셋 부분 수정 Long 값 처리 2025-07-23 13:44:18 +09:00
lwj
87cfbba0cb fix window scrollbar remove
fix ui text cannot click
2025-07-23 11:24:24 +09:00
준학 노
9915b30166 소수점처리 2025-07-23 10:45:24 +09:00
lwj
05ae017731 fix conveyor move 2025-07-23 10:28:20 +09:00
lwj
7d3e2c7a5f fix only fisrt 2025-07-22 18:25:07 +09:00
261fbac539 fix 2025-07-22 18:02:00 +09:00
0af1034974 deleteinterval 2025-07-22 16:22:57 +09:00
bde808b592 Merge branch 'main' of http://220.90.135.190:3000/uvcxr/Simulation 2025-07-22 15:57:36 +09:00
4b7a07b5cf bubblecomplete 2025-07-22 15:57:29 +09:00
lwj
2535ce4a1b fix save camera position 2025-07-22 15:56:22 +09:00
04dc2468f7 Merge branch 'main' of http://220.90.135.190:3000/uvcxr/Simulation 2025-07-22 14:36:31 +09:00
2a5e716c91 bubble 2025-07-22 14:36:21 +09:00
준학 노
497c559175 Editor에서 MQTT Manager Destroy 되면서 생기는 오류 제거 2025-07-22 14:29:05 +09:00
d2acc16c78 Merge branch 'main' of http://220.90.135.190:3000/uvcxr/Simulation 2025-07-22 14:03:55 +09:00
95adb69ab0 bubble 2025-07-22 14:03:40 +09:00
준학 노
6858c66450 133번 132번 수정 완료 하이라이트 박스사이즈 1.1배로 확대 2025-07-21 18:11:30 +09:00
b7fa22f11a 집가고싶다 2025-07-21 17:18:32 +09:00
9ac566321e loadingfail 2025-07-21 14:27:35 +09:00
0f38a1d780 summary 2025-07-18 15:50:58 +09:00
a233ea4f91 Merge branch 'main' of http://220.90.135.190:3000/uvcxr/Simulation 2025-07-18 14:42:52 +09:00
65ca5c5f32 20250718_bugfix 2025-07-18 14:42:37 +09:00
lwj
eeb5ba03e2 콜라이더삭제 2025-07-18 14:24:39 +09:00
lwj
36ad26ae2a 불필요한 update 삭제 2025-07-18 13:28:19 +09:00
준학 노
c6ce6d2c18 namespace정리 폴더 위치 이동 2025-07-18 11:35:21 +09:00
e4f2f60388 Merge branch 'main' of http://220.90.135.190:3000/uvcxr/Simulation 2025-07-18 10:37:34 +09:00
c6c0b9186a conveyor fix 2025-07-18 10:37:17 +09:00
lwj
758d80aff8 에러메세지 추가 2025-07-18 10:36:14 +09:00
lwj
058dd69f97 led수정 2025-07-18 10:32:58 +09:00
lwj
81e45788cc fix 2025-07-17 18:28:24 +09:00
4ede5816de asdf 2025-07-17 18:24:43 +09:00
a4f4f98538 push 2025-07-17 16:12:11 +09:00
899f26474a Merge branch 'main' of http://220.90.135.190:3000/uvcxr/Simulation 2025-07-17 15:48:26 +09:00
d7ee0c4b9a middle 2025-07-17 15:47:48 +09:00
286e7f4a59 bubbleUI 2025-07-17 15:39:12 +09:00
a79f80ce1f request 시 try catch 추가 제이슨 파싱 실패시 에러팝업 생성
오브젝트 삭제시 기즈모 삭제
2025-07-17 15:07:36 +09:00
cf5db448ff update 2025-07-17 14:53:40 +09:00
0aac6eeb82 update 2025-07-17 11:41:03 +09:00
f4143f90d2 Merge branch 'rjh/250716_03' 2025-07-16 18:10:46 +09:00
96ce3ba5e4 logicdata item 생성 로직수정 2025-07-16 18:10:29 +09:00
44673137af Merge branch 'main' of http://220.90.135.190:3000/uvcxr/Simulation 2025-07-16 16:45:27 +09:00
b84e0ee488 ui update 2025-07-16 16:44:58 +09:00
lwj
8ab89edc18 add changes 2025-07-16 16:31:18 +09:00
lwj
7bb6891d44 add led action 2025-07-16 16:25:17 +09:00
b274539e1c current 2025-07-16 14:57:38 +09:00
174c81907a Merge branch 'simulator_khm_20250715' 2025-07-16 12:13:22 +09:00
372cf7de6b asdf 2025-07-16 12:13:13 +09:00
d140c86be0 pallet 2025-07-16 12:10:57 +09:00
46770120cc Merge branch 'main' of http://220.90.135.190:3000/uvcxr/Simulation 2025-07-16 11:38:00 +09:00
0fd5e44401 process 2025-07-16 11:37:49 +09:00
e31ad735f3 Merge branch 'main' of http://220.90.135.190:3000/UVCXR/Simulation 2025-07-16 11:37:00 +09:00
bb9bddf34f 카메라위치저장수정 2025-07-16 11:36:48 +09:00
a09cb64ddf 1126 2025-07-16 11:27:00 +09:00
5cdf2b5413 resourceupdate 2025-07-16 11:18:57 +09:00
43dc7b86bb Merge branch '20250716merge' 2025-07-16 11:12:32 +09:00
70fc1f433f backup 2025-07-16 11:12:19 +09:00
025ce1ec68 light 2025-07-16 10:53:49 +09:00
75f387723d merge 2025-07-16 10:46:07 +09:00
d9c3a9f827 카메라디비저장완료 2025-07-16 10:45:35 +09:00
5d21d6e11c Merge branch 'simulator_khm_20250715' into 20250716merge 2025-07-16 10:40:55 +09:00
14b8c75785 sceneupdated 2025-07-16 10:33:09 +09:00
7e7340717e bugfix 2025-07-16 09:40:18 +09:00
27ecc35708 Merge branch 'main' of http://220.90.135.190:3000/uvcxr/Simulation 2025-07-15 18:21:00 +09:00
a7a9ff1c2e UI적용 2025-07-15 18:20:51 +09:00
77944f951a mqtt 2025-07-15 18:10:38 +09:00
14f65da8ff merge 2025-07-15 18:10:34 +09:00
64c94474d2 merge 2025-07-15 18:07:24 +09:00
932f4c9611 Merge branch 'lh/20250715' 2025-07-15 17:59:49 +09:00
ddacb54484 정합성/ui 2025-07-15 17:35:53 +09:00
ec93847c53 Update Simulation_0.0.1.unity 2025-07-15 16:25:17 +09:00
24f1e86b28 박스 큐브 사이즈(1:1)로 제작 2025-07-15 16:23:07 +09:00
83db394a70 카메라 제한 기본디폴트값 추가 2025-07-15 11:17:08 +09:00
755df45cfa 깃이그노에어 에셋셋팅있는거제거후 테스트 2025-07-15 11:12:01 +09:00
39b47928f3 Merge branch 'main' of http://220.90.135.190:3000/UVCXR/Simulation 2025-07-15 11:01:15 +09:00
7d55b3190a MERGE 2025-07-15 11:01:10 +09:00
4c33c97ad1 temp 2025-07-15 11:00:21 +09:00
0be41c12cd 카메라 이동범위 설정 -0.2(노준학)
기즈모 고정 -0.5(노준학) 완료
MQTT 재연결 로직 -0.2(노준학) - 작업중
2025-07-15 11:00:11 +09:00
6aa4a7978b comit 2025-07-14 17:50:13 +09:00
e92778f77b why 2025-07-14 12:10:34 +09:00
a9159cb508 cube 2025-07-14 09:36:53 +09:00
8e97f43011 update 2025-07-14 09:35:27 +09:00
8a5e3b28ba 중간안정화 2025-07-08 13:42:26 +09:00
89364d9f0a commit 2025-07-07 09:57:13 +09:00
f780b0fabb lightingupdate 2025-07-01 09:57:16 +09:00
lwj
664d32c24f merge main devs 2025-06-26 15:56:32 +09:00
lwj
e855f49513 add resources
add worker
fix process logic
2025-06-26 15:55:03 +09:00
506aa54e91 quality 2025-06-26 15:53:13 +09:00
7dadb75ed8 envirment 2025-06-26 11:48:44 +09:00
b899ba6acd bugfix 2025-06-25 14:41:15 +09:00
lwj
0f94e89de7 remove unused corutines in webmanager 2025-06-24 17:10:00 +09:00
lwj
73e8c28990 merge with 2025-06-24 17:07:39 +09:00
lwj
8e0bb1a559 remove all corutine base restAPI call 2025-06-24 17:02:33 +09:00
lwj
b111be2693 change network UnitaskBase 2025-06-23 16:52:46 +09:00
lwj
0a80f3778b remove uselessPackages 2025-06-23 14:00:47 +09:00
lwj
c1de962908 change web manager
intergrate reqeust corutine
2025-06-19 18:11:12 +09:00
1096 changed files with 158213 additions and 25134 deletions

6
.gitignore vendored
View File

@@ -73,4 +73,8 @@ crashlytics-build.properties
/[Aa]ssets/[Ss]treamingAssets/aa.meta
/[Aa]ssets/[Ss]treamingAssets/aa/*
/Assets/Settings
/Assets/Settings/Build Profiles
/Assets/Settings/Build Profiles/New Web Profile.asset
/Assets/Settings/Build Profiles/New Web Profile.asset.meta
/Assets/Settings/Build Profiles.meta

92
.json
View File

@@ -1,92 +0,0 @@
[
{
"prefabName": "ForkLift",
"modelName": "ForkLift_0",
"modelType": "Move",
"modelID": "",
"nodeID": "conveyor_0_59857fd6-573b-4ac1-8ea3-caaafe362d8f",
"position": "(14.64, 0.00, -12.49)",
"rotation": "(0.00000, 0.00000, 0.00000, 1.00000)",
"scale": "(1.00, 1.00, 1.00)"
},
{
"prefabName": "BigShelves01",
"modelName": "BigShelves01_0",
"modelType": "Queue",
"modelID": "",
"nodeID": "queue_0_e38d4154-304b-49bf-b3b3-8efb9eec5bcc",
"position": "(2.33, 0.00, -11.97)",
"rotation": "(0.00000, 0.00000, 0.00000, 1.00000)",
"scale": "(1.00, 1.00, 1.00)"
},
{
"prefabName": "Pallet",
"modelName": "Pallet_0",
"modelType": "Source",
"modelID": "",
"nodeID": "product_generator_0_9752fa8d-edce-4688-ae61-5c230fd9e215",
"position": "(-8.78, 0.00, -11.54)",
"rotation": "(0.00000, 0.00000, 0.00000, 1.00000)",
"scale": "(1.00, 1.00, 1.00)"
},
{
"prefabName": "Pallet",
"modelName": "Pallet_1",
"modelType": "Source",
"modelID": "",
"nodeID": "queue_0_814c82ee-39dd-400c-9431-7a08e53c7cdc",
"position": "(19.00, 0.00, -10.32)",
"rotation": "(0.00000, 0.00000, 0.00000, 1.00000)",
"scale": "(1.00, 1.00, 1.00)"
},
{
"prefabName": "Pallet",
"modelName": "Pallet_2",
"modelType": "Source",
"modelID": "",
"nodeID": "queue_0_5fe5935a-12da-4df8-826a-2866f1ebb39c",
"position": "(44.92, 0.00, -10.08)",
"rotation": "(0.00000, 0.00000, 0.00000, 1.00000)",
"scale": "(1.00, 1.00, 1.00)"
},
{
"prefabName": "Pallet",
"modelName": "Pallet_3",
"modelType": "Source",
"modelID": "",
"nodeID": "queue_0_7d839a7a-8669-4a52-8ee3-9397d9eea97d",
"position": "(54.26, 0.00, -9.26)",
"rotation": "(0.00000, 0.00000, 0.00000, 1.00000)",
"scale": "(1.00, 1.00, 1.00)"
},
{
"prefabName": "Pallet",
"modelName": "Pallet_4",
"modelType": "Source",
"modelID": "",
"nodeID": "shipment_0_6b2177cc-e89c-48c0-8948-918ed6adf8ee",
"position": "(63.43, 0.00, -9.95)",
"rotation": "(0.00000, 0.00000, 0.00000, 1.00000)",
"scale": "(1.00, 1.00, 1.00)"
},
{
"prefabName": "ForkLift",
"modelName": "ForkLift_1",
"modelType": "Move",
"modelID": "",
"nodeID": "conveyor_0_32e374b3-7f80-44ae-ae24-c686fd77d4c1",
"position": "(48.46, 0.00, -9.92)",
"rotation": "(0.00000, 0.00000, 0.00000, 1.00000)",
"scale": "(1.00, 1.00, 1.00)"
},
{
"prefabName": "BigShelves01",
"modelName": "BigShelves01_1",
"modelType": "Queue",
"modelID": "",
"nodeID": "store_0_28fefae0-5091-4e0f-a1ac-a44ae5d272db",
"position": "(31.60, 0.00, -11.43)",
"rotation": "(0.00000, 0.00000, 0.00000, 1.00000)",
"scale": "(1.00, 1.00, 1.00)"
}
]

73
Assets/CAMERACON.cs Normal file
View File

@@ -0,0 +1,73 @@
using UnityEngine;
public class CAMERACON : MonoBehaviour
{
[Header("이동 설정")]
[Tooltip("이동 속도 (단위: 유닛/초)")]
public float moveSpeed = 5f;
[Header("회전 설정")]
[Tooltip("마우스 회전 속도 (단위: 도/픽셀)")]
public float rotationSpeed = 2f;
[Tooltip("Pitch(상하회전) 최대/최소 각도 제한")]
public Vector2 pitchLimits = new Vector2(-80f, 80f);
// 내부 상태
private float yaw; // Y축 회전 (좌우)
private float pitch; // X축 회전 (상하)
void Start()
{
// 초기 회전값 저장
Vector3 angles = transform.eulerAngles;
yaw = angles.y;
pitch = angles.x;
// 마우스 포커스 잠금 (선택)
Cursor.lockState = CursorLockMode.None;
Cursor.visible = true;
}
void Update()
{
HandleMovement();
HandleRotation();
}
/// <summary>
/// WASD 키 입력으로 카메라 이동 처리
/// </summary>
void HandleMovement()
{
// Unity 기본 축("Horizontal"="A/D", "Vertical"="W/S")
float h = Input.GetAxis("Horizontal");
float v = Input.GetAxis("Vertical");
// 로컬 기준으로 이동 벡터 생성
Vector3 move = transform.right * h + transform.forward * v;
transform.position += move * moveSpeed * Time.deltaTime;
}
/// <summary>
/// 우클릭 + 마우스 드래그로 카메라 회전 처리
/// </summary>
void HandleRotation()
{
if (Input.GetMouseButton(1))
{
// 마우스 움직임 감지
float deltaX = Input.GetAxis("Mouse X");
float deltaY = Input.GetAxis("Mouse Y");
// 회전값 갱신
yaw += deltaX * rotationSpeed;
pitch -= deltaY * rotationSpeed; // 아래로 드래그 시 음수 값
// 피치(상하) 각도 제한
pitch = Mathf.Clamp(pitch, pitchLimits.x, pitchLimits.y);
// 적용
transform.rotation = Quaternion.Euler(pitch, yaw, 0f);
}
}
}

2
Assets/CAMERACON.cs.meta Normal file
View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: edf8366fe251e954b9f40ed68fb05764

View File

@@ -1,16 +1,6 @@
using UnityEngine;
using UnityEngine;
public class Canvas_Bottom : MonoBehaviour
{
// Start is called once before the first execution of Update after the MonoBehaviour is created
void Start()
{
}
// Update is called once per frame
void Update()
{
}
}

View File

@@ -1,6 +1,7 @@
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using TMPro;
public class Canvas_Library : MonoBehaviour
{
@@ -31,6 +32,7 @@ public class Canvas_Library : MonoBehaviour
{
var index = i;
libraryTabs[i].onValueChanged.AddListener(isOn => OnActiveTabChange(index, isOn));
libraryTabs[i].onValueChanged.AddListener(isOn => libraryTabs[index].GetComponent<LibraryToggle>().OnToggle(isOn));
}
}

5
Assets/Canvas_Main.cs Normal file
View File

@@ -0,0 +1,5 @@
using UnityEngine;
public class Canvas_Main : MonoBehaviour
{
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: ad17c40cd0dc74549b72315f71c1d058

View File

@@ -1,9 +1,16 @@
fileFormatVersion: 2
guid: 5808e54fc20f649f5a92a16a458427b9
AssetOrigin:
serializedVersion: 1
productId: 176695
packageName: GUI Pro - Casual Game
packageVersion: 4.1.1
assetPath: Assets/Layer Lab/GUI Pro-CasualGame/ResourcesData/Sprites/Components/Frame/ItemFrame07_f_White2.png
uploadId: 754818
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 12
serializedVersion: 13
mipmaps:
mipMapMode: 0
enableMipMap: 0
@@ -20,11 +27,12 @@ TextureImporter:
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
flipGreenChannel: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMasterTextureLimit: 0
ignoreMipmapLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
@@ -48,7 +56,7 @@ TextureImporter:
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 37, y: 37, z: 37, w: 38}
spriteBorder: {x: 24, y: 25, z: 24, w: 25}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
@@ -63,9 +71,10 @@ TextureImporter:
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
swizzle: 50462976
cookieLightType: 1
platformSettings:
- serializedVersion: 3
- serializedVersion: 4
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
@@ -75,9 +84,10 @@ TextureImporter:
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
- serializedVersion: 4
buildTarget: WebGL
maxTextureSize: 2048
resizeAlgorithm: 0
@@ -87,9 +97,10 @@ TextureImporter:
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
- serializedVersion: 4
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
@@ -99,9 +110,10 @@ TextureImporter:
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
- serializedVersion: 4
buildTarget: Server
maxTextureSize: 2048
resizeAlgorithm: 0
@@ -111,32 +123,28 @@ TextureImporter:
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
customData:
physicsShape: []
bones: []
spriteID: 5e97eb03825dee720800000000000000
internalID: 0
internalID: 1537655665
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spriteCustomMetadata:
entries: []
nameFileIdTable: {}
spritePackingTag:
mipmapLimitGroupName:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 176695
packageName: GUI Pro - Casual Game
packageVersion: 4.1.1
assetPath: Assets/Layer Lab/GUI Pro-CasualGame/ResourcesData/Sprites/Components/Frame/ItemFrame07_f_White2.png
uploadId: 754818

View File

@@ -49,7 +49,7 @@ TextureImporter:
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteBorder: {x: 5, y: 5, z: 5, w: 5}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
@@ -69,7 +69,7 @@ TextureImporter:
platformSettings:
- serializedVersion: 4
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
maxTextureSize: 256
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
@@ -114,7 +114,7 @@ TextureImporter:
physicsShape: []
bones: []
spriteID: 5e97eb03825dee720800000000000000
internalID: 0
internalID: 1537655665
vertices: []
indices:
edges: []

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

View File

@@ -0,0 +1,130 @@
fileFormatVersion: 2
guid: 68895733fc0c3b74d8c8ad4e1f6e143e
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 13
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
flipGreenChannel: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMipmapLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
mipBias: 0
wrapU: 1
wrapV: 1
wrapW: 0
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 1
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 83, y: 83, z: 83, w: 83}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 8
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
swizzle: 50462976
cookieLightType: 0
platformSettings:
- serializedVersion: 4
buildTarget: DefaultTexturePlatform
maxTextureSize: 256
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: WebGL
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
customData:
physicsShape: []
bones: []
spriteID: 5e97eb03825dee720800000000000000
internalID: 1537655665
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spriteCustomMetadata:
entries: []
nameFileIdTable: {}
mipmapLimitGroupName:
pSDRemoveMatte: 0
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

After

Width:  |  Height:  |  Size: 288 B

View File

@@ -0,0 +1,130 @@
fileFormatVersion: 2
guid: ebd72748387c5af439273c678778a8da
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 13
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
flipGreenChannel: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMipmapLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
mipBias: 0
wrapU: 1
wrapV: 1
wrapW: 0
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 1
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 8
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
swizzle: 50462976
cookieLightType: 0
platformSettings:
- serializedVersion: 4
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: WebGL
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
customData:
physicsShape: []
bones: []
spriteID: 5e97eb03825dee720800000000000000
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spriteCustomMetadata:
entries: []
nameFileIdTable: {}
mipmapLimitGroupName:
pSDRemoveMatte: 0
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

After

Width:  |  Height:  |  Size: 365 B

View File

@@ -0,0 +1,130 @@
fileFormatVersion: 2
guid: 84cd248598452024c857dcdc595c14c2
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 13
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
flipGreenChannel: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMipmapLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
mipBias: 0
wrapU: 1
wrapV: 1
wrapW: 0
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 1
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 8
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
swizzle: 50462976
cookieLightType: 0
platformSettings:
- serializedVersion: 4
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: WebGL
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
customData:
physicsShape: []
bones: []
spriteID: 5e97eb03825dee720800000000000000
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spriteCustomMetadata:
entries: []
nameFileIdTable: {}
mipmapLimitGroupName:
pSDRemoveMatte: 0
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

After

Width:  |  Height:  |  Size: 832 B

View File

@@ -0,0 +1,130 @@
fileFormatVersion: 2
guid: 0f1a632ef1ed006409a7b5a0d5620f72
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 13
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
flipGreenChannel: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMipmapLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
mipBias: 0
wrapU: 1
wrapV: 1
wrapW: 0
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 1
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 8
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
swizzle: 50462976
cookieLightType: 0
platformSettings:
- serializedVersion: 4
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: WebGL
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
customData:
physicsShape: []
bones: []
spriteID: 5e97eb03825dee720800000000000000
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spriteCustomMetadata:
entries: []
nameFileIdTable: {}
mipmapLimitGroupName:
pSDRemoveMatte: 0
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

After

Width:  |  Height:  |  Size: 699 B

View File

@@ -0,0 +1,130 @@
fileFormatVersion: 2
guid: 97e2c78d5c49d5546946eb184f101cca
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 13
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
flipGreenChannel: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMipmapLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
mipBias: 0
wrapU: 1
wrapV: 1
wrapW: 0
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 1
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 8
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
swizzle: 50462976
cookieLightType: 0
platformSettings:
- serializedVersion: 4
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: WebGL
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
customData:
physicsShape: []
bones: []
spriteID: 5e97eb03825dee720800000000000000
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spriteCustomMetadata:
entries: []
nameFileIdTable: {}
mipmapLimitGroupName:
pSDRemoveMatte: 0
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

After

Width:  |  Height:  |  Size: 654 B

View File

@@ -0,0 +1,130 @@
fileFormatVersion: 2
guid: 907fcdc707a48fb41bb577d02452b669
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 13
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
flipGreenChannel: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMipmapLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
mipBias: 0
wrapU: 1
wrapV: 1
wrapW: 0
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 1
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 8
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
swizzle: 50462976
cookieLightType: 0
platformSettings:
- serializedVersion: 4
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: WebGL
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
customData:
physicsShape: []
bones: []
spriteID: 5e97eb03825dee720800000000000000
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spriteCustomMetadata:
entries: []
nameFileIdTable: {}
mipmapLimitGroupName:
pSDRemoveMatte: 0
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

After

Width:  |  Height:  |  Size: 634 B

View File

@@ -0,0 +1,130 @@
fileFormatVersion: 2
guid: da990a9291945554cbce0a41d69c7991
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 13
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
flipGreenChannel: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMipmapLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
mipBias: 0
wrapU: 1
wrapV: 1
wrapW: 0
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 1
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 8
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
swizzle: 50462976
cookieLightType: 0
platformSettings:
- serializedVersion: 4
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: WebGL
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
customData:
physicsShape: []
bones: []
spriteID: 5e97eb03825dee720800000000000000
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spriteCustomMetadata:
entries: []
nameFileIdTable: {}
mipmapLimitGroupName:
pSDRemoveMatte: 0
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

After

Width:  |  Height:  |  Size: 732 B

View File

@@ -0,0 +1,130 @@
fileFormatVersion: 2
guid: f4e116c80b91ac248a73b8366f646bb5
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 13
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
flipGreenChannel: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMipmapLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
mipBias: 0
wrapU: 1
wrapV: 1
wrapW: 0
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 1
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 8
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
swizzle: 50462976
cookieLightType: 0
platformSettings:
- serializedVersion: 4
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: WebGL
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
customData:
physicsShape: []
bones: []
spriteID: 5e97eb03825dee720800000000000000
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spriteCustomMetadata:
entries: []
nameFileIdTable: {}
mipmapLimitGroupName:
pSDRemoveMatte: 0
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

After

Width:  |  Height:  |  Size: 540 B

View File

@@ -0,0 +1,130 @@
fileFormatVersion: 2
guid: 9a35a4df63e9649499a3ba92cf631ec5
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 13
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
flipGreenChannel: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMipmapLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
mipBias: 0
wrapU: 1
wrapV: 1
wrapW: 0
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 1
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 8
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
swizzle: 50462976
cookieLightType: 0
platformSettings:
- serializedVersion: 4
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: WebGL
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
customData:
physicsShape: []
bones: []
spriteID: 5e97eb03825dee720800000000000000
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spriteCustomMetadata:
entries: []
nameFileIdTable: {}
mipmapLimitGroupName:
pSDRemoveMatte: 0
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

After

Width:  |  Height:  |  Size: 154 B

View File

@@ -0,0 +1,130 @@
fileFormatVersion: 2
guid: d686d86f33c0e574c8dce8db338c207d
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 13
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
flipGreenChannel: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMipmapLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
mipBias: 0
wrapU: 1
wrapV: 1
wrapW: 0
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 1
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 8
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
swizzle: 50462976
cookieLightType: 0
platformSettings:
- serializedVersion: 4
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: WebGL
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
customData:
physicsShape: []
bones: []
spriteID: 5e97eb03825dee720800000000000000
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spriteCustomMetadata:
entries: []
nameFileIdTable: {}
mipmapLimitGroupName:
pSDRemoveMatte: 0
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: b649a29e06d03d042ba6511aeaed0637
guid: 794d299eeafec1046953f6b7a50bf74b
folderAsset: yes
DefaultImporter:
externalObjects: {}

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 6bcf5c4eb0e96f34d8bab46ec5da8a68
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: e5813b55306be104783dea4ec1a84fd6
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,62 @@
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
using System;
using System.Linq;
using System.Reflection;
using UnityEditor;
using UnityEngine;
namespace Cysharp.Threading.Tasks.Editor
{
// reflection call of UnityEditor.SplitterGUILayout
internal static class SplitterGUILayout
{
static BindingFlags flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static;
static Lazy<Type> splitterStateType = new Lazy<Type>(() =>
{
var type = typeof(EditorWindow).Assembly.GetTypes().First(x => x.FullName == "UnityEditor.SplitterState");
return type;
});
static Lazy<ConstructorInfo> splitterStateCtor = new Lazy<ConstructorInfo>(() =>
{
var type = splitterStateType.Value;
return type.GetConstructor(flags, null, new Type[] { typeof(float[]), typeof(int[]), typeof(int[]) }, null);
});
static Lazy<Type> splitterGUILayoutType = new Lazy<Type>(() =>
{
var type = typeof(EditorWindow).Assembly.GetTypes().First(x => x.FullName == "UnityEditor.SplitterGUILayout");
return type;
});
static Lazy<MethodInfo> beginVerticalSplit = new Lazy<MethodInfo>(() =>
{
var type = splitterGUILayoutType.Value;
return type.GetMethod("BeginVerticalSplit", flags, null, new Type[] { splitterStateType.Value, typeof(GUILayoutOption[]) }, null);
});
static Lazy<MethodInfo> endVerticalSplit = new Lazy<MethodInfo>(() =>
{
var type = splitterGUILayoutType.Value;
return type.GetMethod("EndVerticalSplit", flags, null, Type.EmptyTypes, null);
});
public static object CreateSplitterState(float[] relativeSizes, int[] minSizes, int[] maxSizes)
{
return splitterStateCtor.Value.Invoke(new object[] { relativeSizes, minSizes, maxSizes });
}
public static void BeginVerticalSplit(object splitterState, params GUILayoutOption[] options)
{
beginVerticalSplit.Value.Invoke(null, new object[] { splitterState, options });
}
public static void EndVerticalSplit()
{
endVerticalSplit.Value.Invoke(null, Type.EmptyTypes);
}
}
}

View File

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

View File

@@ -0,0 +1,17 @@
{
"name": "UniTask.Editor",
"references": [
"UniTask"
],
"includePlatforms": [
"Editor"
],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": false,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false
}

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 4129704b5a1a13841ba16f230bf24a57
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,182 @@
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
using UnityEngine;
using UnityEditor;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System;
using UnityEditor.IMGUI.Controls;
using Cysharp.Threading.Tasks.Internal;
using System.Text;
using System.Text.RegularExpressions;
namespace Cysharp.Threading.Tasks.Editor
{
public class UniTaskTrackerViewItem : TreeViewItem
{
static Regex removeHref = new Regex("<a href.+>(.+)</a>", RegexOptions.Compiled);
public string TaskType { get; set; }
public string Elapsed { get; set; }
public string Status { get; set; }
string position;
public string Position
{
get { return position; }
set
{
position = value;
PositionFirstLine = GetFirstLine(position);
}
}
public string PositionFirstLine { get; private set; }
static string GetFirstLine(string str)
{
var sb = new StringBuilder();
for (int i = 0; i < str.Length; i++)
{
if (str[i] == '\r' || str[i] == '\n')
{
break;
}
sb.Append(str[i]);
}
return removeHref.Replace(sb.ToString(), "$1");
}
public UniTaskTrackerViewItem(int id) : base(id)
{
}
}
public class UniTaskTrackerTreeView : TreeView
{
const string sortedColumnIndexStateKey = "UniTaskTrackerTreeView_sortedColumnIndex";
public IReadOnlyList<TreeViewItem> CurrentBindingItems;
public UniTaskTrackerTreeView()
: this(new TreeViewState(), new MultiColumnHeader(new MultiColumnHeaderState(new[]
{
new MultiColumnHeaderState.Column() { headerContent = new GUIContent("TaskType"), width = 20},
new MultiColumnHeaderState.Column() { headerContent = new GUIContent("Elapsed"), width = 10},
new MultiColumnHeaderState.Column() { headerContent = new GUIContent("Status"), width = 10},
new MultiColumnHeaderState.Column() { headerContent = new GUIContent("Position")},
})))
{
}
UniTaskTrackerTreeView(TreeViewState state, MultiColumnHeader header)
: base(state, header)
{
rowHeight = 20;
showAlternatingRowBackgrounds = true;
showBorder = true;
header.sortingChanged += Header_sortingChanged;
header.ResizeToFit();
Reload();
header.sortedColumnIndex = SessionState.GetInt(sortedColumnIndexStateKey, 1);
}
public void ReloadAndSort()
{
var currentSelected = this.state.selectedIDs;
Reload();
Header_sortingChanged(this.multiColumnHeader);
this.state.selectedIDs = currentSelected;
}
private void Header_sortingChanged(MultiColumnHeader multiColumnHeader)
{
SessionState.SetInt(sortedColumnIndexStateKey, multiColumnHeader.sortedColumnIndex);
var index = multiColumnHeader.sortedColumnIndex;
var ascending = multiColumnHeader.IsSortedAscending(multiColumnHeader.sortedColumnIndex);
var items = rootItem.children.Cast<UniTaskTrackerViewItem>();
IOrderedEnumerable<UniTaskTrackerViewItem> orderedEnumerable;
switch (index)
{
case 0:
orderedEnumerable = ascending ? items.OrderBy(item => item.TaskType) : items.OrderByDescending(item => item.TaskType);
break;
case 1:
orderedEnumerable = ascending ? items.OrderBy(item => double.Parse(item.Elapsed)) : items.OrderByDescending(item => double.Parse(item.Elapsed));
break;
case 2:
orderedEnumerable = ascending ? items.OrderBy(item => item.Status) : items.OrderByDescending(item => item.Elapsed);
break;
case 3:
orderedEnumerable = ascending ? items.OrderBy(item => item.Position) : items.OrderByDescending(item => item.PositionFirstLine);
break;
default:
throw new ArgumentOutOfRangeException(nameof(index), index, null);
}
CurrentBindingItems = rootItem.children = orderedEnumerable.Cast<TreeViewItem>().ToList();
BuildRows(rootItem);
}
protected override TreeViewItem BuildRoot()
{
var root = new TreeViewItem { depth = -1 };
var children = new List<TreeViewItem>();
TaskTracker.ForEachActiveTask((trackingId, awaiterType, status, created, stackTrace) =>
{
children.Add(new UniTaskTrackerViewItem(trackingId) { TaskType = awaiterType, Status = status.ToString(), Elapsed = (DateTime.UtcNow - created).TotalSeconds.ToString("00.00"), Position = stackTrace });
});
CurrentBindingItems = children;
root.children = CurrentBindingItems as List<TreeViewItem>;
return root;
}
protected override bool CanMultiSelect(TreeViewItem item)
{
return false;
}
protected override void RowGUI(RowGUIArgs args)
{
var item = args.item as UniTaskTrackerViewItem;
for (var visibleColumnIndex = 0; visibleColumnIndex < args.GetNumVisibleColumns(); visibleColumnIndex++)
{
var rect = args.GetCellRect(visibleColumnIndex);
var columnIndex = args.GetColumn(visibleColumnIndex);
var labelStyle = args.selected ? EditorStyles.whiteLabel : EditorStyles.label;
labelStyle.alignment = TextAnchor.MiddleLeft;
switch (columnIndex)
{
case 0:
EditorGUI.LabelField(rect, item.TaskType, labelStyle);
break;
case 1:
EditorGUI.LabelField(rect, item.Elapsed, labelStyle);
break;
case 2:
EditorGUI.LabelField(rect, item.Status, labelStyle);
break;
case 3:
EditorGUI.LabelField(rect, item.PositionFirstLine, labelStyle);
break;
default:
throw new ArgumentOutOfRangeException(nameof(columnIndex), columnIndex, null);
}
}
}
}
}

View File

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

View File

@@ -0,0 +1,209 @@
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
using UnityEngine;
using UnityEditor;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System;
using UnityEditor.IMGUI.Controls;
using Cysharp.Threading.Tasks.Internal;
namespace Cysharp.Threading.Tasks.Editor
{
public class UniTaskTrackerWindow : EditorWindow
{
static int interval;
static UniTaskTrackerWindow window;
[MenuItem("Window/UniTask Tracker")]
public static void OpenWindow()
{
if (window != null)
{
window.Close();
}
// will called OnEnable(singleton instance will be set).
GetWindow<UniTaskTrackerWindow>("UniTask Tracker").Show();
}
static readonly GUILayoutOption[] EmptyLayoutOption = new GUILayoutOption[0];
UniTaskTrackerTreeView treeView;
object splitterState;
void OnEnable()
{
window = this; // set singleton.
splitterState = SplitterGUILayout.CreateSplitterState(new float[] { 75f, 25f }, new int[] { 32, 32 }, null);
treeView = new UniTaskTrackerTreeView();
TaskTracker.EditorEnableState.EnableAutoReload = EditorPrefs.GetBool(TaskTracker.EnableAutoReloadKey, false);
TaskTracker.EditorEnableState.EnableTracking = EditorPrefs.GetBool(TaskTracker.EnableTrackingKey, false);
TaskTracker.EditorEnableState.EnableStackTrace = EditorPrefs.GetBool(TaskTracker.EnableStackTraceKey, false);
}
void OnGUI()
{
// Head
RenderHeadPanel();
// Splittable
SplitterGUILayout.BeginVerticalSplit(this.splitterState, EmptyLayoutOption);
{
// Column Tabble
RenderTable();
// StackTrace details
RenderDetailsPanel();
}
SplitterGUILayout.EndVerticalSplit();
}
#region HeadPanel
public static bool EnableAutoReload => TaskTracker.EditorEnableState.EnableAutoReload;
public static bool EnableTracking => TaskTracker.EditorEnableState.EnableTracking;
public static bool EnableStackTrace => TaskTracker.EditorEnableState.EnableStackTrace;
static readonly GUIContent EnableAutoReloadHeadContent = EditorGUIUtility.TrTextContent("Enable AutoReload", "Reload automatically.", (Texture)null);
static readonly GUIContent ReloadHeadContent = EditorGUIUtility.TrTextContent("Reload", "Reload View.", (Texture)null);
static readonly GUIContent GCHeadContent = EditorGUIUtility.TrTextContent("GC.Collect", "Invoke GC.Collect.", (Texture)null);
static readonly GUIContent EnableTrackingHeadContent = EditorGUIUtility.TrTextContent("Enable Tracking", "Start to track async/await UniTask. Performance impact: low", (Texture)null);
static readonly GUIContent EnableStackTraceHeadContent = EditorGUIUtility.TrTextContent("Enable StackTrace", "Capture StackTrace when task is started. Performance impact: high", (Texture)null);
// [Enable Tracking] | [Enable StackTrace]
void RenderHeadPanel()
{
EditorGUILayout.BeginVertical(EmptyLayoutOption);
EditorGUILayout.BeginHorizontal(EditorStyles.toolbar, EmptyLayoutOption);
if (GUILayout.Toggle(EnableAutoReload, EnableAutoReloadHeadContent, EditorStyles.toolbarButton, EmptyLayoutOption) != EnableAutoReload)
{
TaskTracker.EditorEnableState.EnableAutoReload = !EnableAutoReload;
}
if (GUILayout.Toggle(EnableTracking, EnableTrackingHeadContent, EditorStyles.toolbarButton, EmptyLayoutOption) != EnableTracking)
{
TaskTracker.EditorEnableState.EnableTracking = !EnableTracking;
}
if (GUILayout.Toggle(EnableStackTrace, EnableStackTraceHeadContent, EditorStyles.toolbarButton, EmptyLayoutOption) != EnableStackTrace)
{
TaskTracker.EditorEnableState.EnableStackTrace = !EnableStackTrace;
}
GUILayout.FlexibleSpace();
if (GUILayout.Button(ReloadHeadContent, EditorStyles.toolbarButton, EmptyLayoutOption))
{
TaskTracker.CheckAndResetDirty();
treeView.ReloadAndSort();
Repaint();
}
if (GUILayout.Button(GCHeadContent, EditorStyles.toolbarButton, EmptyLayoutOption))
{
GC.Collect(0);
}
EditorGUILayout.EndHorizontal();
EditorGUILayout.EndVertical();
}
#endregion
#region TableColumn
Vector2 tableScroll;
GUIStyle tableListStyle;
void RenderTable()
{
if (tableListStyle == null)
{
tableListStyle = new GUIStyle("CN Box");
tableListStyle.margin.top = 0;
tableListStyle.padding.left = 3;
}
EditorGUILayout.BeginVertical(tableListStyle, EmptyLayoutOption);
this.tableScroll = EditorGUILayout.BeginScrollView(this.tableScroll, new GUILayoutOption[]
{
GUILayout.ExpandWidth(true),
GUILayout.MaxWidth(2000f)
});
var controlRect = EditorGUILayout.GetControlRect(new GUILayoutOption[]
{
GUILayout.ExpandHeight(true),
GUILayout.ExpandWidth(true)
});
treeView?.OnGUI(controlRect);
EditorGUILayout.EndScrollView();
EditorGUILayout.EndVertical();
}
private void Update()
{
if (EnableAutoReload)
{
if (interval++ % 120 == 0)
{
if (TaskTracker.CheckAndResetDirty())
{
treeView.ReloadAndSort();
Repaint();
}
}
}
}
#endregion
#region Details
static GUIStyle detailsStyle;
Vector2 detailsScroll;
void RenderDetailsPanel()
{
if (detailsStyle == null)
{
detailsStyle = new GUIStyle("CN Message");
detailsStyle.wordWrap = false;
detailsStyle.stretchHeight = true;
detailsStyle.margin.right = 15;
}
string message = "";
var selected = treeView.state.selectedIDs;
if (selected.Count > 0)
{
var first = selected[0];
var item = treeView.CurrentBindingItems.FirstOrDefault(x => x.id == first) as UniTaskTrackerViewItem;
if (item != null)
{
message = item.Position;
}
}
detailsScroll = EditorGUILayout.BeginScrollView(this.detailsScroll, EmptyLayoutOption);
var vector = detailsStyle.CalcSize(new GUIContent(message));
EditorGUILayout.SelectableLabel(message, detailsStyle, new GUILayoutOption[]
{
GUILayout.ExpandHeight(true),
GUILayout.ExpandWidth(true),
GUILayout.MinWidth(vector.x),
GUILayout.MinHeight(vector.y)
});
EditorGUILayout.EndScrollView();
}
#endregion
}
}

View File

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

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 8f5048a1d4677c14b8b0d7c2c1e7c593
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,245 @@
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
using System;
using System.Threading;
namespace Cysharp.Threading.Tasks
{
public class AsyncLazy
{
static Action<object> continuation = SetCompletionSource;
Func<UniTask> taskFactory;
UniTaskCompletionSource completionSource;
UniTask.Awaiter awaiter;
object syncLock;
bool initialized;
public AsyncLazy(Func<UniTask> taskFactory)
{
this.taskFactory = taskFactory;
this.completionSource = new UniTaskCompletionSource();
this.syncLock = new object();
this.initialized = false;
}
internal AsyncLazy(UniTask task)
{
this.taskFactory = null;
this.completionSource = new UniTaskCompletionSource();
this.syncLock = null;
this.initialized = true;
var awaiter = task.GetAwaiter();
if (awaiter.IsCompleted)
{
SetCompletionSource(awaiter);
}
else
{
this.awaiter = awaiter;
awaiter.SourceOnCompleted(continuation, this);
}
}
public UniTask Task
{
get
{
EnsureInitialized();
return completionSource.Task;
}
}
public UniTask.Awaiter GetAwaiter() => Task.GetAwaiter();
void EnsureInitialized()
{
if (Volatile.Read(ref initialized))
{
return;
}
EnsureInitializedCore();
}
void EnsureInitializedCore()
{
lock (syncLock)
{
if (!Volatile.Read(ref initialized))
{
var f = Interlocked.Exchange(ref taskFactory, null);
if (f != null)
{
var task = f();
var awaiter = task.GetAwaiter();
if (awaiter.IsCompleted)
{
SetCompletionSource(awaiter);
}
else
{
this.awaiter = awaiter;
awaiter.SourceOnCompleted(continuation, this);
}
Volatile.Write(ref initialized, true);
}
}
}
}
void SetCompletionSource(in UniTask.Awaiter awaiter)
{
try
{
awaiter.GetResult();
completionSource.TrySetResult();
}
catch (Exception ex)
{
completionSource.TrySetException(ex);
}
}
static void SetCompletionSource(object state)
{
var self = (AsyncLazy)state;
try
{
self.awaiter.GetResult();
self.completionSource.TrySetResult();
}
catch (Exception ex)
{
self.completionSource.TrySetException(ex);
}
finally
{
self.awaiter = default;
}
}
}
public class AsyncLazy<T>
{
static Action<object> continuation = SetCompletionSource;
Func<UniTask<T>> taskFactory;
UniTaskCompletionSource<T> completionSource;
UniTask<T>.Awaiter awaiter;
object syncLock;
bool initialized;
public AsyncLazy(Func<UniTask<T>> taskFactory)
{
this.taskFactory = taskFactory;
this.completionSource = new UniTaskCompletionSource<T>();
this.syncLock = new object();
this.initialized = false;
}
internal AsyncLazy(UniTask<T> task)
{
this.taskFactory = null;
this.completionSource = new UniTaskCompletionSource<T>();
this.syncLock = null;
this.initialized = true;
var awaiter = task.GetAwaiter();
if (awaiter.IsCompleted)
{
SetCompletionSource(awaiter);
}
else
{
this.awaiter = awaiter;
awaiter.SourceOnCompleted(continuation, this);
}
}
public UniTask<T> Task
{
get
{
EnsureInitialized();
return completionSource.Task;
}
}
public UniTask<T>.Awaiter GetAwaiter() => Task.GetAwaiter();
void EnsureInitialized()
{
if (Volatile.Read(ref initialized))
{
return;
}
EnsureInitializedCore();
}
void EnsureInitializedCore()
{
lock (syncLock)
{
if (!Volatile.Read(ref initialized))
{
var f = Interlocked.Exchange(ref taskFactory, null);
if (f != null)
{
var task = f();
var awaiter = task.GetAwaiter();
if (awaiter.IsCompleted)
{
SetCompletionSource(awaiter);
}
else
{
this.awaiter = awaiter;
awaiter.SourceOnCompleted(continuation, this);
}
Volatile.Write(ref initialized, true);
}
}
}
}
void SetCompletionSource(in UniTask<T>.Awaiter awaiter)
{
try
{
var result = awaiter.GetResult();
completionSource.TrySetResult(result);
}
catch (Exception ex)
{
completionSource.TrySetException(ex);
}
}
static void SetCompletionSource(object state)
{
var self = (AsyncLazy<T>)state;
try
{
var result = self.awaiter.GetResult();
self.completionSource.TrySetResult(result);
}
catch (Exception ex)
{
self.completionSource.TrySetException(ex);
}
finally
{
self.awaiter = default;
}
}
}
}

View File

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

View File

@@ -0,0 +1,644 @@
using System;
using System.Threading;
namespace Cysharp.Threading.Tasks
{
public interface IReadOnlyAsyncReactiveProperty<T> : IUniTaskAsyncEnumerable<T>
{
T Value { get; }
IUniTaskAsyncEnumerable<T> WithoutCurrent();
UniTask<T> WaitAsync(CancellationToken cancellationToken = default);
}
public interface IAsyncReactiveProperty<T> : IReadOnlyAsyncReactiveProperty<T>
{
new T Value { get; set; }
}
[Serializable]
public class AsyncReactiveProperty<T> : IAsyncReactiveProperty<T>, IDisposable
{
TriggerEvent<T> triggerEvent;
#if UNITY_2018_3_OR_NEWER
[UnityEngine.SerializeField]
#endif
T latestValue;
public T Value
{
get
{
return latestValue;
}
set
{
this.latestValue = value;
triggerEvent.SetResult(value);
}
}
public AsyncReactiveProperty(T value)
{
this.latestValue = value;
this.triggerEvent = default;
}
public IUniTaskAsyncEnumerable<T> WithoutCurrent()
{
return new WithoutCurrentEnumerable(this);
}
public IUniTaskAsyncEnumerator<T> GetAsyncEnumerator(CancellationToken cancellationToken)
{
return new Enumerator(this, cancellationToken, true);
}
public void Dispose()
{
triggerEvent.SetCompleted();
}
public static implicit operator T(AsyncReactiveProperty<T> value)
{
return value.Value;
}
public override string ToString()
{
if (isValueType) return latestValue.ToString();
return latestValue?.ToString();
}
public UniTask<T> WaitAsync(CancellationToken cancellationToken = default)
{
return new UniTask<T>(WaitAsyncSource.Create(this, cancellationToken, out var token), token);
}
static bool isValueType;
static AsyncReactiveProperty()
{
isValueType = typeof(T).IsValueType;
}
sealed class WaitAsyncSource : IUniTaskSource<T>, ITriggerHandler<T>, ITaskPoolNode<WaitAsyncSource>
{
static Action<object> cancellationCallback = CancellationCallback;
static TaskPool<WaitAsyncSource> pool;
WaitAsyncSource nextNode;
ref WaitAsyncSource ITaskPoolNode<WaitAsyncSource>.NextNode => ref nextNode;
static WaitAsyncSource()
{
TaskPool.RegisterSizeGetter(typeof(WaitAsyncSource), () => pool.Size);
}
AsyncReactiveProperty<T> parent;
CancellationToken cancellationToken;
CancellationTokenRegistration cancellationTokenRegistration;
UniTaskCompletionSourceCore<T> core;
WaitAsyncSource()
{
}
public static IUniTaskSource<T> Create(AsyncReactiveProperty<T> parent, CancellationToken cancellationToken, out short token)
{
if (cancellationToken.IsCancellationRequested)
{
return AutoResetUniTaskCompletionSource<T>.CreateFromCanceled(cancellationToken, out token);
}
if (!pool.TryPop(out var result))
{
result = new WaitAsyncSource();
}
result.parent = parent;
result.cancellationToken = cancellationToken;
if (cancellationToken.CanBeCanceled)
{
result.cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(cancellationCallback, result);
}
result.parent.triggerEvent.Add(result);
TaskTracker.TrackActiveTask(result, 3);
token = result.core.Version;
return result;
}
bool TryReturn()
{
TaskTracker.RemoveTracking(this);
core.Reset();
cancellationTokenRegistration.Dispose();
cancellationTokenRegistration = default;
parent.triggerEvent.Remove(this);
parent = null;
cancellationToken = default;
return pool.TryPush(this);
}
static void CancellationCallback(object state)
{
var self = (WaitAsyncSource)state;
self.OnCanceled(self.cancellationToken);
}
// IUniTaskSource
public T GetResult(short token)
{
try
{
return core.GetResult(token);
}
finally
{
TryReturn();
}
}
void IUniTaskSource.GetResult(short token)
{
GetResult(token);
}
public void OnCompleted(Action<object> continuation, object state, short token)
{
core.OnCompleted(continuation, state, token);
}
public UniTaskStatus GetStatus(short token)
{
return core.GetStatus(token);
}
public UniTaskStatus UnsafeGetStatus()
{
return core.UnsafeGetStatus();
}
// ITriggerHandler
ITriggerHandler<T> ITriggerHandler<T>.Prev { get; set; }
ITriggerHandler<T> ITriggerHandler<T>.Next { get; set; }
public void OnCanceled(CancellationToken cancellationToken)
{
core.TrySetCanceled(cancellationToken);
}
public void OnCompleted()
{
// Complete as Cancel.
core.TrySetCanceled(CancellationToken.None);
}
public void OnError(Exception ex)
{
core.TrySetException(ex);
}
public void OnNext(T value)
{
core.TrySetResult(value);
}
}
sealed class WithoutCurrentEnumerable : IUniTaskAsyncEnumerable<T>
{
readonly AsyncReactiveProperty<T> parent;
public WithoutCurrentEnumerable(AsyncReactiveProperty<T> parent)
{
this.parent = parent;
}
public IUniTaskAsyncEnumerator<T> GetAsyncEnumerator(CancellationToken cancellationToken = default)
{
return new Enumerator(parent, cancellationToken, false);
}
}
sealed class Enumerator : MoveNextSource, IUniTaskAsyncEnumerator<T>, ITriggerHandler<T>
{
static Action<object> cancellationCallback = CancellationCallback;
readonly AsyncReactiveProperty<T> parent;
readonly CancellationToken cancellationToken;
readonly CancellationTokenRegistration cancellationTokenRegistration;
T value;
bool isDisposed;
bool firstCall;
public Enumerator(AsyncReactiveProperty<T> parent, CancellationToken cancellationToken, bool publishCurrentValue)
{
this.parent = parent;
this.cancellationToken = cancellationToken;
this.firstCall = publishCurrentValue;
parent.triggerEvent.Add(this);
TaskTracker.TrackActiveTask(this, 3);
if (cancellationToken.CanBeCanceled)
{
cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(cancellationCallback, this);
}
}
public T Current => value;
ITriggerHandler<T> ITriggerHandler<T>.Prev { get; set; }
ITriggerHandler<T> ITriggerHandler<T>.Next { get; set; }
public UniTask<bool> MoveNextAsync()
{
// raise latest value on first call.
if (firstCall)
{
firstCall = false;
value = parent.Value;
return CompletedTasks.True;
}
completionSource.Reset();
return new UniTask<bool>(this, completionSource.Version);
}
public UniTask DisposeAsync()
{
if (!isDisposed)
{
isDisposed = true;
TaskTracker.RemoveTracking(this);
completionSource.TrySetCanceled(cancellationToken);
parent.triggerEvent.Remove(this);
}
return default;
}
public void OnNext(T value)
{
this.value = value;
completionSource.TrySetResult(true);
}
public void OnCanceled(CancellationToken cancellationToken)
{
DisposeAsync().Forget();
}
public void OnCompleted()
{
completionSource.TrySetResult(false);
}
public void OnError(Exception ex)
{
completionSource.TrySetException(ex);
}
static void CancellationCallback(object state)
{
var self = (Enumerator)state;
self.DisposeAsync().Forget();
}
}
}
public class ReadOnlyAsyncReactiveProperty<T> : IReadOnlyAsyncReactiveProperty<T>, IDisposable
{
TriggerEvent<T> triggerEvent;
T latestValue;
IUniTaskAsyncEnumerator<T> enumerator;
public T Value
{
get
{
return latestValue;
}
}
public ReadOnlyAsyncReactiveProperty(T initialValue, IUniTaskAsyncEnumerable<T> source, CancellationToken cancellationToken)
{
latestValue = initialValue;
ConsumeEnumerator(source, cancellationToken).Forget();
}
public ReadOnlyAsyncReactiveProperty(IUniTaskAsyncEnumerable<T> source, CancellationToken cancellationToken)
{
ConsumeEnumerator(source, cancellationToken).Forget();
}
async UniTaskVoid ConsumeEnumerator(IUniTaskAsyncEnumerable<T> source, CancellationToken cancellationToken)
{
enumerator = source.GetAsyncEnumerator(cancellationToken);
try
{
while (await enumerator.MoveNextAsync())
{
var value = enumerator.Current;
this.latestValue = value;
triggerEvent.SetResult(value);
}
}
finally
{
await enumerator.DisposeAsync();
enumerator = null;
}
}
public IUniTaskAsyncEnumerable<T> WithoutCurrent()
{
return new WithoutCurrentEnumerable(this);
}
public IUniTaskAsyncEnumerator<T> GetAsyncEnumerator(CancellationToken cancellationToken)
{
return new Enumerator(this, cancellationToken, true);
}
public void Dispose()
{
if (enumerator != null)
{
enumerator.DisposeAsync().Forget();
}
triggerEvent.SetCompleted();
}
public static implicit operator T(ReadOnlyAsyncReactiveProperty<T> value)
{
return value.Value;
}
public override string ToString()
{
if (isValueType) return latestValue.ToString();
return latestValue?.ToString();
}
public UniTask<T> WaitAsync(CancellationToken cancellationToken = default)
{
return new UniTask<T>(WaitAsyncSource.Create(this, cancellationToken, out var token), token);
}
static bool isValueType;
static ReadOnlyAsyncReactiveProperty()
{
isValueType = typeof(T).IsValueType;
}
sealed class WaitAsyncSource : IUniTaskSource<T>, ITriggerHandler<T>, ITaskPoolNode<WaitAsyncSource>
{
static Action<object> cancellationCallback = CancellationCallback;
static TaskPool<WaitAsyncSource> pool;
WaitAsyncSource nextNode;
ref WaitAsyncSource ITaskPoolNode<WaitAsyncSource>.NextNode => ref nextNode;
static WaitAsyncSource()
{
TaskPool.RegisterSizeGetter(typeof(WaitAsyncSource), () => pool.Size);
}
ReadOnlyAsyncReactiveProperty<T> parent;
CancellationToken cancellationToken;
CancellationTokenRegistration cancellationTokenRegistration;
UniTaskCompletionSourceCore<T> core;
WaitAsyncSource()
{
}
public static IUniTaskSource<T> Create(ReadOnlyAsyncReactiveProperty<T> parent, CancellationToken cancellationToken, out short token)
{
if (cancellationToken.IsCancellationRequested)
{
return AutoResetUniTaskCompletionSource<T>.CreateFromCanceled(cancellationToken, out token);
}
if (!pool.TryPop(out var result))
{
result = new WaitAsyncSource();
}
result.parent = parent;
result.cancellationToken = cancellationToken;
if (cancellationToken.CanBeCanceled)
{
result.cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(cancellationCallback, result);
}
result.parent.triggerEvent.Add(result);
TaskTracker.TrackActiveTask(result, 3);
token = result.core.Version;
return result;
}
bool TryReturn()
{
TaskTracker.RemoveTracking(this);
core.Reset();
cancellationTokenRegistration.Dispose();
cancellationTokenRegistration = default;
parent.triggerEvent.Remove(this);
parent = null;
cancellationToken = default;
return pool.TryPush(this);
}
static void CancellationCallback(object state)
{
var self = (WaitAsyncSource)state;
self.OnCanceled(self.cancellationToken);
}
// IUniTaskSource
public T GetResult(short token)
{
try
{
return core.GetResult(token);
}
finally
{
TryReturn();
}
}
void IUniTaskSource.GetResult(short token)
{
GetResult(token);
}
public void OnCompleted(Action<object> continuation, object state, short token)
{
core.OnCompleted(continuation, state, token);
}
public UniTaskStatus GetStatus(short token)
{
return core.GetStatus(token);
}
public UniTaskStatus UnsafeGetStatus()
{
return core.UnsafeGetStatus();
}
// ITriggerHandler
ITriggerHandler<T> ITriggerHandler<T>.Prev { get; set; }
ITriggerHandler<T> ITriggerHandler<T>.Next { get; set; }
public void OnCanceled(CancellationToken cancellationToken)
{
core.TrySetCanceled(cancellationToken);
}
public void OnCompleted()
{
// Complete as Cancel.
core.TrySetCanceled(CancellationToken.None);
}
public void OnError(Exception ex)
{
core.TrySetException(ex);
}
public void OnNext(T value)
{
core.TrySetResult(value);
}
}
sealed class WithoutCurrentEnumerable : IUniTaskAsyncEnumerable<T>
{
readonly ReadOnlyAsyncReactiveProperty<T> parent;
public WithoutCurrentEnumerable(ReadOnlyAsyncReactiveProperty<T> parent)
{
this.parent = parent;
}
public IUniTaskAsyncEnumerator<T> GetAsyncEnumerator(CancellationToken cancellationToken = default)
{
return new Enumerator(parent, cancellationToken, false);
}
}
sealed class Enumerator : MoveNextSource, IUniTaskAsyncEnumerator<T>, ITriggerHandler<T>
{
static Action<object> cancellationCallback = CancellationCallback;
readonly ReadOnlyAsyncReactiveProperty<T> parent;
readonly CancellationToken cancellationToken;
readonly CancellationTokenRegistration cancellationTokenRegistration;
T value;
bool isDisposed;
bool firstCall;
public Enumerator(ReadOnlyAsyncReactiveProperty<T> parent, CancellationToken cancellationToken, bool publishCurrentValue)
{
this.parent = parent;
this.cancellationToken = cancellationToken;
this.firstCall = publishCurrentValue;
parent.triggerEvent.Add(this);
TaskTracker.TrackActiveTask(this, 3);
if (cancellationToken.CanBeCanceled)
{
cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(cancellationCallback, this);
}
}
public T Current => value;
ITriggerHandler<T> ITriggerHandler<T>.Prev { get; set; }
ITriggerHandler<T> ITriggerHandler<T>.Next { get; set; }
public UniTask<bool> MoveNextAsync()
{
// raise latest value on first call.
if (firstCall)
{
firstCall = false;
value = parent.Value;
return CompletedTasks.True;
}
completionSource.Reset();
return new UniTask<bool>(this, completionSource.Version);
}
public UniTask DisposeAsync()
{
if (!isDisposed)
{
isDisposed = true;
TaskTracker.RemoveTracking(this);
completionSource.TrySetCanceled(cancellationToken);
parent.triggerEvent.Remove(this);
}
return default;
}
public void OnNext(T value)
{
this.value = value;
completionSource.TrySetResult(true);
}
public void OnCanceled(CancellationToken cancellationToken)
{
DisposeAsync().Forget();
}
public void OnCompleted()
{
completionSource.TrySetResult(false);
}
public void OnError(Exception ex)
{
completionSource.TrySetException(ex);
}
static void CancellationCallback(object state)
{
var self = (Enumerator)state;
self.DisposeAsync().Forget();
}
}
}
public static class StateExtensions
{
public static ReadOnlyAsyncReactiveProperty<T> ToReadOnlyAsyncReactiveProperty<T>(this IUniTaskAsyncEnumerable<T> source, CancellationToken cancellationToken)
{
return new ReadOnlyAsyncReactiveProperty<T>(source, cancellationToken);
}
public static ReadOnlyAsyncReactiveProperty<T> ToReadOnlyAsyncReactiveProperty<T>(this IUniTaskAsyncEnumerable<T> source, T initialValue, CancellationToken cancellationToken)
{
return new ReadOnlyAsyncReactiveProperty<T>(initialValue, source, cancellationToken);
}
}
}

View File

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

View File

@@ -0,0 +1,26 @@
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or
using System;
namespace Cysharp.Threading.Tasks
{
public readonly struct AsyncUnit : IEquatable<AsyncUnit>
{
public static readonly AsyncUnit Default = new AsyncUnit();
public override int GetHashCode()
{
return 0;
}
public bool Equals(AsyncUnit other)
{
return true;
}
public override string ToString()
{
return "()";
}
}
}

View File

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

View File

@@ -0,0 +1,23 @@
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
using System.Collections.Generic;
using System.Threading;
namespace Cysharp.Threading.Tasks
{
public class CancellationTokenEqualityComparer : IEqualityComparer<CancellationToken>
{
public static readonly IEqualityComparer<CancellationToken> Default = new CancellationTokenEqualityComparer();
public bool Equals(CancellationToken x, CancellationToken y)
{
return x.Equals(y);
}
public int GetHashCode(CancellationToken obj)
{
return obj.GetHashCode();
}
}
}

View File

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

View File

@@ -0,0 +1,182 @@
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
using System;
using System.Runtime.CompilerServices;
using System.Threading;
namespace Cysharp.Threading.Tasks
{
public static class CancellationTokenExtensions
{
static readonly Action<object> cancellationTokenCallback = Callback;
static readonly Action<object> disposeCallback = DisposeCallback;
public static CancellationToken ToCancellationToken(this UniTask task)
{
var cts = new CancellationTokenSource();
ToCancellationTokenCore(task, cts).Forget();
return cts.Token;
}
public static CancellationToken ToCancellationToken(this UniTask task, CancellationToken linkToken)
{
if (linkToken.IsCancellationRequested)
{
return linkToken;
}
if (!linkToken.CanBeCanceled)
{
return ToCancellationToken(task);
}
var cts = CancellationTokenSource.CreateLinkedTokenSource(linkToken);
ToCancellationTokenCore(task, cts).Forget();
return cts.Token;
}
public static CancellationToken ToCancellationToken<T>(this UniTask<T> task)
{
return ToCancellationToken(task.AsUniTask());
}
public static CancellationToken ToCancellationToken<T>(this UniTask<T> task, CancellationToken linkToken)
{
return ToCancellationToken(task.AsUniTask(), linkToken);
}
static async UniTaskVoid ToCancellationTokenCore(UniTask task, CancellationTokenSource cts)
{
try
{
await task;
}
catch (Exception ex)
{
UniTaskScheduler.PublishUnobservedTaskException(ex);
}
cts.Cancel();
cts.Dispose();
}
public static (UniTask, CancellationTokenRegistration) ToUniTask(this CancellationToken cancellationToken)
{
if (cancellationToken.IsCancellationRequested)
{
return (UniTask.FromCanceled(cancellationToken), default(CancellationTokenRegistration));
}
var promise = new UniTaskCompletionSource();
return (promise.Task, cancellationToken.RegisterWithoutCaptureExecutionContext(cancellationTokenCallback, promise));
}
static void Callback(object state)
{
var promise = (UniTaskCompletionSource)state;
promise.TrySetResult();
}
public static CancellationTokenAwaitable WaitUntilCanceled(this CancellationToken cancellationToken)
{
return new CancellationTokenAwaitable(cancellationToken);
}
public static CancellationTokenRegistration RegisterWithoutCaptureExecutionContext(this CancellationToken cancellationToken, Action callback)
{
var restoreFlow = false;
if (!ExecutionContext.IsFlowSuppressed())
{
ExecutionContext.SuppressFlow();
restoreFlow = true;
}
try
{
return cancellationToken.Register(callback, false);
}
finally
{
if (restoreFlow)
{
ExecutionContext.RestoreFlow();
}
}
}
public static CancellationTokenRegistration RegisterWithoutCaptureExecutionContext(this CancellationToken cancellationToken, Action<object> callback, object state)
{
var restoreFlow = false;
if (!ExecutionContext.IsFlowSuppressed())
{
ExecutionContext.SuppressFlow();
restoreFlow = true;
}
try
{
return cancellationToken.Register(callback, state, false);
}
finally
{
if (restoreFlow)
{
ExecutionContext.RestoreFlow();
}
}
}
public static CancellationTokenRegistration AddTo(this IDisposable disposable, CancellationToken cancellationToken)
{
return cancellationToken.RegisterWithoutCaptureExecutionContext(disposeCallback, disposable);
}
static void DisposeCallback(object state)
{
var d = (IDisposable)state;
d.Dispose();
}
}
public struct CancellationTokenAwaitable
{
CancellationToken cancellationToken;
public CancellationTokenAwaitable(CancellationToken cancellationToken)
{
this.cancellationToken = cancellationToken;
}
public Awaiter GetAwaiter()
{
return new Awaiter(cancellationToken);
}
public struct Awaiter : ICriticalNotifyCompletion
{
CancellationToken cancellationToken;
public Awaiter(CancellationToken cancellationToken)
{
this.cancellationToken = cancellationToken;
}
public bool IsCompleted => !cancellationToken.CanBeCanceled || cancellationToken.IsCancellationRequested;
public void GetResult()
{
}
public void OnCompleted(Action continuation)
{
UnsafeOnCompleted(continuation);
}
public void UnsafeOnCompleted(Action continuation)
{
cancellationToken.RegisterWithoutCaptureExecutionContext(continuation);
}
}
}
}

View File

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

View File

@@ -0,0 +1,44 @@
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
using System.Threading;
using UnityEngine;
using Cysharp.Threading.Tasks.Triggers;
using System;
using Cysharp.Threading.Tasks.Internal;
namespace Cysharp.Threading.Tasks
{
public static partial class CancellationTokenSourceExtensions
{
readonly static Action<object> CancelCancellationTokenSourceStateDelegate = new Action<object>(CancelCancellationTokenSourceState);
static void CancelCancellationTokenSourceState(object state)
{
var cts = (CancellationTokenSource)state;
cts.Cancel();
}
public static IDisposable CancelAfterSlim(this CancellationTokenSource cts, int millisecondsDelay, DelayType delayType = DelayType.DeltaTime, PlayerLoopTiming delayTiming = PlayerLoopTiming.Update)
{
return CancelAfterSlim(cts, TimeSpan.FromMilliseconds(millisecondsDelay), delayType, delayTiming);
}
public static IDisposable CancelAfterSlim(this CancellationTokenSource cts, TimeSpan delayTimeSpan, DelayType delayType = DelayType.DeltaTime, PlayerLoopTiming delayTiming = PlayerLoopTiming.Update)
{
return PlayerLoopTimer.StartNew(delayTimeSpan, false, delayType, delayTiming, cts.Token, CancelCancellationTokenSourceStateDelegate, cts);
}
public static void RegisterRaiseCancelOnDestroy(this CancellationTokenSource cts, Component component)
{
RegisterRaiseCancelOnDestroy(cts, component.gameObject);
}
public static void RegisterRaiseCancelOnDestroy(this CancellationTokenSource cts, GameObject gameObject)
{
var trigger = gameObject.GetAsyncDestroyTrigger();
trigger.CancellationToken.RegisterWithoutCaptureExecutionContext(CancelCancellationTokenSourceStateDelegate, cts);
}
}
}

View File

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

View File

@@ -0,0 +1,450 @@
using System;
using System.Collections.Generic;
using System.Threading;
namespace Cysharp.Threading.Tasks
{
public static class Channel
{
public static Channel<T> CreateSingleConsumerUnbounded<T>()
{
return new SingleConsumerUnboundedChannel<T>();
}
}
public abstract class Channel<TWrite, TRead>
{
public ChannelReader<TRead> Reader { get; protected set; }
public ChannelWriter<TWrite> Writer { get; protected set; }
public static implicit operator ChannelReader<TRead>(Channel<TWrite, TRead> channel) => channel.Reader;
public static implicit operator ChannelWriter<TWrite>(Channel<TWrite, TRead> channel) => channel.Writer;
}
public abstract class Channel<T> : Channel<T, T>
{
}
public abstract class ChannelReader<T>
{
public abstract bool TryRead(out T item);
public abstract UniTask<bool> WaitToReadAsync(CancellationToken cancellationToken = default(CancellationToken));
public abstract UniTask Completion { get; }
public virtual UniTask<T> ReadAsync(CancellationToken cancellationToken = default(CancellationToken))
{
if (this.TryRead(out var item))
{
return UniTask.FromResult(item);
}
return ReadAsyncCore(cancellationToken);
}
async UniTask<T> ReadAsyncCore(CancellationToken cancellationToken = default(CancellationToken))
{
if (await WaitToReadAsync(cancellationToken))
{
if (TryRead(out var item))
{
return item;
}
}
throw new ChannelClosedException();
}
public abstract IUniTaskAsyncEnumerable<T> ReadAllAsync(CancellationToken cancellationToken = default(CancellationToken));
}
public abstract class ChannelWriter<T>
{
public abstract bool TryWrite(T item);
public abstract bool TryComplete(Exception error = null);
public void Complete(Exception error = null)
{
if (!TryComplete(error))
{
throw new ChannelClosedException();
}
}
}
public partial class ChannelClosedException : InvalidOperationException
{
public ChannelClosedException() :
base("Channel is already closed.")
{ }
public ChannelClosedException(string message) : base(message) { }
public ChannelClosedException(Exception innerException) :
base("Channel is already closed", innerException)
{ }
public ChannelClosedException(string message, Exception innerException) : base(message, innerException) { }
}
internal class SingleConsumerUnboundedChannel<T> : Channel<T>
{
readonly Queue<T> items;
readonly SingleConsumerUnboundedChannelReader readerSource;
UniTaskCompletionSource completedTaskSource;
UniTask completedTask;
Exception completionError;
bool closed;
public SingleConsumerUnboundedChannel()
{
items = new Queue<T>();
Writer = new SingleConsumerUnboundedChannelWriter(this);
readerSource = new SingleConsumerUnboundedChannelReader(this);
Reader = readerSource;
}
sealed class SingleConsumerUnboundedChannelWriter : ChannelWriter<T>
{
readonly SingleConsumerUnboundedChannel<T> parent;
public SingleConsumerUnboundedChannelWriter(SingleConsumerUnboundedChannel<T> parent)
{
this.parent = parent;
}
public override bool TryWrite(T item)
{
bool waiting;
lock (parent.items)
{
if (parent.closed) return false;
parent.items.Enqueue(item);
waiting = parent.readerSource.isWaiting;
}
if (waiting)
{
parent.readerSource.SingalContinuation();
}
return true;
}
public override bool TryComplete(Exception error = null)
{
bool waiting;
lock (parent.items)
{
if (parent.closed) return false;
parent.closed = true;
waiting = parent.readerSource.isWaiting;
if (parent.items.Count == 0)
{
if (error == null)
{
if (parent.completedTaskSource != null)
{
parent.completedTaskSource.TrySetResult();
}
else
{
parent.completedTask = UniTask.CompletedTask;
}
}
else
{
if (parent.completedTaskSource != null)
{
parent.completedTaskSource.TrySetException(error);
}
else
{
parent.completedTask = UniTask.FromException(error);
}
}
if (waiting)
{
parent.readerSource.SingalCompleted(error);
}
}
parent.completionError = error;
}
return true;
}
}
sealed class SingleConsumerUnboundedChannelReader : ChannelReader<T>, IUniTaskSource<bool>
{
readonly Action<object> CancellationCallbackDelegate = CancellationCallback;
readonly SingleConsumerUnboundedChannel<T> parent;
CancellationToken cancellationToken;
CancellationTokenRegistration cancellationTokenRegistration;
UniTaskCompletionSourceCore<bool> core;
internal bool isWaiting;
public SingleConsumerUnboundedChannelReader(SingleConsumerUnboundedChannel<T> parent)
{
this.parent = parent;
TaskTracker.TrackActiveTask(this, 4);
}
public override UniTask Completion
{
get
{
if (parent.completedTaskSource != null) return parent.completedTaskSource.Task;
if (parent.closed)
{
return parent.completedTask;
}
parent.completedTaskSource = new UniTaskCompletionSource();
return parent.completedTaskSource.Task;
}
}
public override bool TryRead(out T item)
{
lock (parent.items)
{
if (parent.items.Count != 0)
{
item = parent.items.Dequeue();
// complete when all value was consumed.
if (parent.closed && parent.items.Count == 0)
{
if (parent.completionError != null)
{
if (parent.completedTaskSource != null)
{
parent.completedTaskSource.TrySetException(parent.completionError);
}
else
{
parent.completedTask = UniTask.FromException(parent.completionError);
}
}
else
{
if (parent.completedTaskSource != null)
{
parent.completedTaskSource.TrySetResult();
}
else
{
parent.completedTask = UniTask.CompletedTask;
}
}
}
}
else
{
item = default;
return false;
}
}
return true;
}
public override UniTask<bool> WaitToReadAsync(CancellationToken cancellationToken)
{
if (cancellationToken.IsCancellationRequested)
{
return UniTask.FromCanceled<bool>(cancellationToken);
}
lock (parent.items)
{
if (parent.items.Count != 0)
{
return CompletedTasks.True;
}
if (parent.closed)
{
if (parent.completionError == null)
{
return CompletedTasks.False;
}
else
{
return UniTask.FromException<bool>(parent.completionError);
}
}
cancellationTokenRegistration.Dispose();
core.Reset();
isWaiting = true;
this.cancellationToken = cancellationToken;
if (this.cancellationToken.CanBeCanceled)
{
cancellationTokenRegistration = this.cancellationToken.RegisterWithoutCaptureExecutionContext(CancellationCallbackDelegate, this);
}
return new UniTask<bool>(this, core.Version);
}
}
public void SingalContinuation()
{
core.TrySetResult(true);
}
public void SingalCancellation(CancellationToken cancellationToken)
{
TaskTracker.RemoveTracking(this);
core.TrySetCanceled(cancellationToken);
}
public void SingalCompleted(Exception error)
{
if (error != null)
{
TaskTracker.RemoveTracking(this);
core.TrySetException(error);
}
else
{
TaskTracker.RemoveTracking(this);
core.TrySetResult(false);
}
}
public override IUniTaskAsyncEnumerable<T> ReadAllAsync(CancellationToken cancellationToken = default)
{
return new ReadAllAsyncEnumerable(this, cancellationToken);
}
bool IUniTaskSource<bool>.GetResult(short token)
{
return core.GetResult(token);
}
void IUniTaskSource.GetResult(short token)
{
core.GetResult(token);
}
UniTaskStatus IUniTaskSource.GetStatus(short token)
{
return core.GetStatus(token);
}
void IUniTaskSource.OnCompleted(Action<object> continuation, object state, short token)
{
core.OnCompleted(continuation, state, token);
}
UniTaskStatus IUniTaskSource.UnsafeGetStatus()
{
return core.UnsafeGetStatus();
}
static void CancellationCallback(object state)
{
var self = (SingleConsumerUnboundedChannelReader)state;
self.SingalCancellation(self.cancellationToken);
}
sealed class ReadAllAsyncEnumerable : IUniTaskAsyncEnumerable<T>, IUniTaskAsyncEnumerator<T>
{
readonly Action<object> CancellationCallback1Delegate = CancellationCallback1;
readonly Action<object> CancellationCallback2Delegate = CancellationCallback2;
readonly SingleConsumerUnboundedChannelReader parent;
CancellationToken cancellationToken1;
CancellationToken cancellationToken2;
CancellationTokenRegistration cancellationTokenRegistration1;
CancellationTokenRegistration cancellationTokenRegistration2;
T current;
bool cacheValue;
bool running;
public ReadAllAsyncEnumerable(SingleConsumerUnboundedChannelReader parent, CancellationToken cancellationToken)
{
this.parent = parent;
this.cancellationToken1 = cancellationToken;
}
public IUniTaskAsyncEnumerator<T> GetAsyncEnumerator(CancellationToken cancellationToken = default)
{
if (running)
{
throw new InvalidOperationException("Enumerator is already running, does not allow call GetAsyncEnumerator twice.");
}
if (this.cancellationToken1 != cancellationToken)
{
this.cancellationToken2 = cancellationToken;
}
if (this.cancellationToken1.CanBeCanceled)
{
this.cancellationTokenRegistration1 = this.cancellationToken1.RegisterWithoutCaptureExecutionContext(CancellationCallback1Delegate, this);
}
if (this.cancellationToken2.CanBeCanceled)
{
this.cancellationTokenRegistration2 = this.cancellationToken2.RegisterWithoutCaptureExecutionContext(CancellationCallback2Delegate, this);
}
running = true;
return this;
}
public T Current
{
get
{
if (cacheValue)
{
return current;
}
parent.TryRead(out current);
return current;
}
}
public UniTask<bool> MoveNextAsync()
{
cacheValue = false;
return parent.WaitToReadAsync(CancellationToken.None); // ok to use None, registered in ctor.
}
public UniTask DisposeAsync()
{
cancellationTokenRegistration1.Dispose();
cancellationTokenRegistration2.Dispose();
return default;
}
static void CancellationCallback1(object state)
{
var self = (ReadAllAsyncEnumerable)state;
self.parent.SingalCancellation(self.cancellationToken1);
}
static void CancellationCallback2(object state)
{
var self = (ReadAllAsyncEnumerable)state;
self.parent.SingalCancellation(self.cancellationToken2);
}
}
}
}
}

View File

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

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 8b156714d4b179940b1f0f5b7d48f5c5
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,17 @@
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
#pragma warning disable CS0436
namespace System.Runtime.CompilerServices
{
internal sealed class AsyncMethodBuilderAttribute : Attribute
{
public Type BuilderType { get; }
public AsyncMethodBuilderAttribute(Type builderType)
{
BuilderType = builderType;
}
}
}

View File

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

View File

@@ -0,0 +1,269 @@
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
using System;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Security;
namespace Cysharp.Threading.Tasks.CompilerServices
{
[StructLayout(LayoutKind.Auto)]
public struct AsyncUniTaskMethodBuilder
{
IStateMachineRunnerPromise runnerPromise;
Exception ex;
// 1. Static Create method.
[DebuggerHidden]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static AsyncUniTaskMethodBuilder Create()
{
return default;
}
// 2. TaskLike Task property.
public UniTask Task
{
[DebuggerHidden]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get
{
if (runnerPromise != null)
{
return runnerPromise.Task;
}
else if (ex != null)
{
return UniTask.FromException(ex);
}
else
{
return UniTask.CompletedTask;
}
}
}
// 3. SetException
[DebuggerHidden]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void SetException(Exception exception)
{
if (runnerPromise == null)
{
ex = exception;
}
else
{
runnerPromise.SetException(exception);
}
}
// 4. SetResult
[DebuggerHidden]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void SetResult()
{
if (runnerPromise != null)
{
runnerPromise.SetResult();
}
}
// 5. AwaitOnCompleted
[DebuggerHidden]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void AwaitOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine)
where TAwaiter : INotifyCompletion
where TStateMachine : IAsyncStateMachine
{
if (runnerPromise == null)
{
AsyncUniTask<TStateMachine>.SetStateMachine(ref stateMachine, ref runnerPromise);
}
awaiter.OnCompleted(runnerPromise.MoveNext);
}
// 6. AwaitUnsafeOnCompleted
[DebuggerHidden]
[SecuritySafeCritical]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine)
where TAwaiter : ICriticalNotifyCompletion
where TStateMachine : IAsyncStateMachine
{
if (runnerPromise == null)
{
AsyncUniTask<TStateMachine>.SetStateMachine(ref stateMachine, ref runnerPromise);
}
awaiter.UnsafeOnCompleted(runnerPromise.MoveNext);
}
// 7. Start
[DebuggerHidden]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Start<TStateMachine>(ref TStateMachine stateMachine)
where TStateMachine : IAsyncStateMachine
{
stateMachine.MoveNext();
}
// 8. SetStateMachine
[DebuggerHidden]
public void SetStateMachine(IAsyncStateMachine stateMachine)
{
// don't use boxed stateMachine.
}
#if DEBUG || !UNITY_2018_3_OR_NEWER
// Important for IDE debugger.
object debuggingId;
private object ObjectIdForDebugger
{
get
{
if (debuggingId == null)
{
debuggingId = new object();
}
return debuggingId;
}
}
#endif
}
[StructLayout(LayoutKind.Auto)]
public struct AsyncUniTaskMethodBuilder<T>
{
IStateMachineRunnerPromise<T> runnerPromise;
Exception ex;
T result;
// 1. Static Create method.
[DebuggerHidden]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static AsyncUniTaskMethodBuilder<T> Create()
{
return default;
}
// 2. TaskLike Task property.
public UniTask<T> Task
{
[DebuggerHidden]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get
{
if (runnerPromise != null)
{
return runnerPromise.Task;
}
else if (ex != null)
{
return UniTask.FromException<T>(ex);
}
else
{
return UniTask.FromResult(result);
}
}
}
// 3. SetException
[DebuggerHidden]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void SetException(Exception exception)
{
if (runnerPromise == null)
{
ex = exception;
}
else
{
runnerPromise.SetException(exception);
}
}
// 4. SetResult
[DebuggerHidden]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void SetResult(T result)
{
if (runnerPromise == null)
{
this.result = result;
}
else
{
runnerPromise.SetResult(result);
}
}
// 5. AwaitOnCompleted
[DebuggerHidden]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void AwaitOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine)
where TAwaiter : INotifyCompletion
where TStateMachine : IAsyncStateMachine
{
if (runnerPromise == null)
{
AsyncUniTask<TStateMachine, T>.SetStateMachine(ref stateMachine, ref runnerPromise);
}
awaiter.OnCompleted(runnerPromise.MoveNext);
}
// 6. AwaitUnsafeOnCompleted
[DebuggerHidden]
[SecuritySafeCritical]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine)
where TAwaiter : ICriticalNotifyCompletion
where TStateMachine : IAsyncStateMachine
{
if (runnerPromise == null)
{
AsyncUniTask<TStateMachine, T>.SetStateMachine(ref stateMachine, ref runnerPromise);
}
awaiter.UnsafeOnCompleted(runnerPromise.MoveNext);
}
// 7. Start
[DebuggerHidden]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Start<TStateMachine>(ref TStateMachine stateMachine)
where TStateMachine : IAsyncStateMachine
{
stateMachine.MoveNext();
}
// 8. SetStateMachine
[DebuggerHidden]
public void SetStateMachine(IAsyncStateMachine stateMachine)
{
// don't use boxed stateMachine.
}
#if DEBUG || !UNITY_2018_3_OR_NEWER
// Important for IDE debugger.
object debuggingId;
private object ObjectIdForDebugger
{
get
{
if (debuggingId == null)
{
debuggingId = new object();
}
return debuggingId;
}
}
#endif
}
}

View File

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

View File

@@ -0,0 +1,137 @@
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
using System;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Security;
namespace Cysharp.Threading.Tasks.CompilerServices
{
[StructLayout(LayoutKind.Auto)]
public struct AsyncUniTaskVoidMethodBuilder
{
IStateMachineRunner runner;
// 1. Static Create method.
[DebuggerHidden]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static AsyncUniTaskVoidMethodBuilder Create()
{
return default;
}
// 2. TaskLike Task property(void)
public UniTaskVoid Task
{
[DebuggerHidden]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get
{
return default;
}
}
// 3. SetException
[DebuggerHidden]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void SetException(Exception exception)
{
// runner is finished, return first.
if (runner != null)
{
#if ENABLE_IL2CPP
// workaround for IL2CPP bug.
PlayerLoopHelper.AddContinuation(PlayerLoopTiming.LastPostLateUpdate, runner.ReturnAction);
#else
runner.Return();
#endif
runner = null;
}
UniTaskScheduler.PublishUnobservedTaskException(exception);
}
// 4. SetResult
[DebuggerHidden]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void SetResult()
{
// runner is finished, return.
if (runner != null)
{
#if ENABLE_IL2CPP
// workaround for IL2CPP bug.
PlayerLoopHelper.AddContinuation(PlayerLoopTiming.LastPostLateUpdate, runner.ReturnAction);
#else
runner.Return();
#endif
runner = null;
}
}
// 5. AwaitOnCompleted
[DebuggerHidden]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void AwaitOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine)
where TAwaiter : INotifyCompletion
where TStateMachine : IAsyncStateMachine
{
if (runner == null)
{
AsyncUniTaskVoid<TStateMachine>.SetStateMachine(ref stateMachine, ref runner);
}
awaiter.OnCompleted(runner.MoveNext);
}
// 6. AwaitUnsafeOnCompleted
[DebuggerHidden]
[SecuritySafeCritical]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine)
where TAwaiter : ICriticalNotifyCompletion
where TStateMachine : IAsyncStateMachine
{
if (runner == null)
{
AsyncUniTaskVoid<TStateMachine>.SetStateMachine(ref stateMachine, ref runner);
}
awaiter.UnsafeOnCompleted(runner.MoveNext);
}
// 7. Start
[DebuggerHidden]
public void Start<TStateMachine>(ref TStateMachine stateMachine)
where TStateMachine : IAsyncStateMachine
{
stateMachine.MoveNext();
}
// 8. SetStateMachine
[DebuggerHidden]
public void SetStateMachine(IAsyncStateMachine stateMachine)
{
// don't use boxed stateMachine.
}
#if DEBUG || !UNITY_2018_3_OR_NEWER
// Important for IDE debugger.
object debuggingId;
private object ObjectIdForDebugger
{
get
{
if (debuggingId == null)
{
debuggingId = new object();
}
return debuggingId;
}
}
#endif
}
}

View File

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

View File

@@ -0,0 +1,380 @@
#pragma warning disable CS1591
using Cysharp.Threading.Tasks.Internal;
using System;
using System.Linq;
using System.Diagnostics;
using System.Runtime.CompilerServices;
namespace Cysharp.Threading.Tasks.CompilerServices
{
// #ENABLE_IL2CPP in this file is to avoid bug of IL2CPP VM.
// Issue is tracked on https://issuetracker.unity3d.com/issues/il2cpp-incorrect-results-when-calling-a-method-from-outside-class-in-a-struct
// but currently it is labeled `Won't Fix`.
internal interface IStateMachineRunner
{
Action MoveNext { get; }
void Return();
#if ENABLE_IL2CPP
Action ReturnAction { get; }
#endif
}
internal interface IStateMachineRunnerPromise : IUniTaskSource
{
Action MoveNext { get; }
UniTask Task { get; }
void SetResult();
void SetException(Exception exception);
}
internal interface IStateMachineRunnerPromise<T> : IUniTaskSource<T>
{
Action MoveNext { get; }
UniTask<T> Task { get; }
void SetResult(T result);
void SetException(Exception exception);
}
internal static class StateMachineUtility
{
// Get AsyncStateMachine internal state to check IL2CPP bug
public static int GetState(IAsyncStateMachine stateMachine)
{
var info = stateMachine.GetType().GetFields(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)
.First(x => x.Name.EndsWith("__state"));
return (int)info.GetValue(stateMachine);
}
}
internal sealed class AsyncUniTaskVoid<TStateMachine> : IStateMachineRunner, ITaskPoolNode<AsyncUniTaskVoid<TStateMachine>>, IUniTaskSource
where TStateMachine : IAsyncStateMachine
{
static TaskPool<AsyncUniTaskVoid<TStateMachine>> pool;
#if ENABLE_IL2CPP
public Action ReturnAction { get; }
#endif
TStateMachine stateMachine;
public Action MoveNext { get; }
public AsyncUniTaskVoid()
{
MoveNext = Run;
#if ENABLE_IL2CPP
ReturnAction = Return;
#endif
}
public static void SetStateMachine(ref TStateMachine stateMachine, ref IStateMachineRunner runnerFieldRef)
{
if (!pool.TryPop(out var result))
{
result = new AsyncUniTaskVoid<TStateMachine>();
}
TaskTracker.TrackActiveTask(result, 3);
runnerFieldRef = result; // set runner before copied.
result.stateMachine = stateMachine; // copy struct StateMachine(in release build).
}
static AsyncUniTaskVoid()
{
TaskPool.RegisterSizeGetter(typeof(AsyncUniTaskVoid<TStateMachine>), () => pool.Size);
}
AsyncUniTaskVoid<TStateMachine> nextNode;
public ref AsyncUniTaskVoid<TStateMachine> NextNode => ref nextNode;
public void Return()
{
TaskTracker.RemoveTracking(this);
stateMachine = default;
pool.TryPush(this);
}
[DebuggerHidden]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
void Run()
{
stateMachine.MoveNext();
}
// dummy interface implementation for TaskTracker.
UniTaskStatus IUniTaskSource.GetStatus(short token)
{
return UniTaskStatus.Pending;
}
UniTaskStatus IUniTaskSource.UnsafeGetStatus()
{
return UniTaskStatus.Pending;
}
void IUniTaskSource.OnCompleted(Action<object> continuation, object state, short token)
{
}
void IUniTaskSource.GetResult(short token)
{
}
}
internal sealed class AsyncUniTask<TStateMachine> : IStateMachineRunnerPromise, IUniTaskSource, ITaskPoolNode<AsyncUniTask<TStateMachine>>
where TStateMachine : IAsyncStateMachine
{
static TaskPool<AsyncUniTask<TStateMachine>> pool;
#if ENABLE_IL2CPP
readonly Action returnDelegate;
#endif
public Action MoveNext { get; }
TStateMachine stateMachine;
UniTaskCompletionSourceCore<AsyncUnit> core;
AsyncUniTask()
{
MoveNext = Run;
#if ENABLE_IL2CPP
returnDelegate = Return;
#endif
}
public static void SetStateMachine(ref TStateMachine stateMachine, ref IStateMachineRunnerPromise runnerPromiseFieldRef)
{
if (!pool.TryPop(out var result))
{
result = new AsyncUniTask<TStateMachine>();
}
TaskTracker.TrackActiveTask(result, 3);
runnerPromiseFieldRef = result; // set runner before copied.
result.stateMachine = stateMachine; // copy struct StateMachine(in release build).
}
AsyncUniTask<TStateMachine> nextNode;
public ref AsyncUniTask<TStateMachine> NextNode => ref nextNode;
static AsyncUniTask()
{
TaskPool.RegisterSizeGetter(typeof(AsyncUniTask<TStateMachine>), () => pool.Size);
}
void Return()
{
TaskTracker.RemoveTracking(this);
core.Reset();
stateMachine = default;
pool.TryPush(this);
}
bool TryReturn()
{
TaskTracker.RemoveTracking(this);
core.Reset();
stateMachine = default;
return pool.TryPush(this);
}
[DebuggerHidden]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
void Run()
{
stateMachine.MoveNext();
}
public UniTask Task
{
[DebuggerHidden]
get
{
return new UniTask(this, core.Version);
}
}
[DebuggerHidden]
public void SetResult()
{
core.TrySetResult(AsyncUnit.Default);
}
[DebuggerHidden]
public void SetException(Exception exception)
{
core.TrySetException(exception);
}
[DebuggerHidden]
public void GetResult(short token)
{
try
{
core.GetResult(token);
}
finally
{
#if ENABLE_IL2CPP
// workaround for IL2CPP bug.
PlayerLoopHelper.AddContinuation(PlayerLoopTiming.LastPostLateUpdate, returnDelegate);
#else
TryReturn();
#endif
}
}
[DebuggerHidden]
public UniTaskStatus GetStatus(short token)
{
return core.GetStatus(token);
}
[DebuggerHidden]
public UniTaskStatus UnsafeGetStatus()
{
return core.UnsafeGetStatus();
}
[DebuggerHidden]
public void OnCompleted(Action<object> continuation, object state, short token)
{
core.OnCompleted(continuation, state, token);
}
}
internal sealed class AsyncUniTask<TStateMachine, T> : IStateMachineRunnerPromise<T>, IUniTaskSource<T>, ITaskPoolNode<AsyncUniTask<TStateMachine, T>>
where TStateMachine : IAsyncStateMachine
{
static TaskPool<AsyncUniTask<TStateMachine, T>> pool;
#if ENABLE_IL2CPP
readonly Action returnDelegate;
#endif
public Action MoveNext { get; }
TStateMachine stateMachine;
UniTaskCompletionSourceCore<T> core;
AsyncUniTask()
{
MoveNext = Run;
#if ENABLE_IL2CPP
returnDelegate = Return;
#endif
}
public static void SetStateMachine(ref TStateMachine stateMachine, ref IStateMachineRunnerPromise<T> runnerPromiseFieldRef)
{
if (!pool.TryPop(out var result))
{
result = new AsyncUniTask<TStateMachine, T>();
}
TaskTracker.TrackActiveTask(result, 3);
runnerPromiseFieldRef = result; // set runner before copied.
result.stateMachine = stateMachine; // copy struct StateMachine(in release build).
}
AsyncUniTask<TStateMachine, T> nextNode;
public ref AsyncUniTask<TStateMachine, T> NextNode => ref nextNode;
static AsyncUniTask()
{
TaskPool.RegisterSizeGetter(typeof(AsyncUniTask<TStateMachine, T>), () => pool.Size);
}
void Return()
{
TaskTracker.RemoveTracking(this);
core.Reset();
stateMachine = default;
pool.TryPush(this);
}
bool TryReturn()
{
TaskTracker.RemoveTracking(this);
core.Reset();
stateMachine = default;
return pool.TryPush(this);
}
[DebuggerHidden]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
void Run()
{
// UnityEngine.Debug.Log($"MoveNext State:" + StateMachineUtility.GetState(stateMachine));
stateMachine.MoveNext();
}
public UniTask<T> Task
{
[DebuggerHidden]
get
{
return new UniTask<T>(this, core.Version);
}
}
[DebuggerHidden]
public void SetResult(T result)
{
core.TrySetResult(result);
}
[DebuggerHidden]
public void SetException(Exception exception)
{
core.TrySetException(exception);
}
[DebuggerHidden]
public T GetResult(short token)
{
try
{
return core.GetResult(token);
}
finally
{
#if ENABLE_IL2CPP
// workaround for IL2CPP bug.
PlayerLoopHelper.AddContinuation(PlayerLoopTiming.LastPostLateUpdate, returnDelegate);
#else
TryReturn();
#endif
}
}
[DebuggerHidden]
void IUniTaskSource.GetResult(short token)
{
GetResult(token);
}
[DebuggerHidden]
public UniTaskStatus GetStatus(short token)
{
return core.GetStatus(token);
}
[DebuggerHidden]
public UniTaskStatus UnsafeGetStatus()
{
return core.UnsafeGetStatus();
}
[DebuggerHidden]
public void OnCompleted(Action<object> continuation, object state, short token)
{
core.OnCompleted(continuation, state, token);
}
}
}

View File

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

View File

@@ -0,0 +1,34 @@
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
using System;
using System.Collections.Generic;
namespace Cysharp.Threading.Tasks
{
public static class EnumerableAsyncExtensions
{
// overload resolver - .Select(async x => { }) : IEnumerable<UniTask<T>>
public static IEnumerable<UniTask> Select<T>(this IEnumerable<T> source, Func<T, UniTask> selector)
{
return System.Linq.Enumerable.Select(source, selector);
}
public static IEnumerable<UniTask<TR>> Select<T, TR>(this IEnumerable<T> source, Func<T, UniTask<TR>> selector)
{
return System.Linq.Enumerable.Select(source, selector);
}
public static IEnumerable<UniTask> Select<T>(this IEnumerable<T> source, Func<T, int, UniTask> selector)
{
return System.Linq.Enumerable.Select(source, selector);
}
public static IEnumerable<UniTask<TR>> Select<T, TR>(this IEnumerable<T> source, Func<T, int, UniTask<TR>> selector)
{
return System.Linq.Enumerable.Select(source, selector);
}
}
}

View File

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

View File

@@ -0,0 +1,287 @@
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
using System;
using System.Collections;
using System.Reflection;
using System.Runtime.ExceptionServices;
using System.Threading;
using Cysharp.Threading.Tasks.Internal;
using UnityEngine;
namespace Cysharp.Threading.Tasks
{
public static class EnumeratorAsyncExtensions
{
public static UniTask.Awaiter GetAwaiter<T>(this T enumerator)
where T : IEnumerator
{
var e = (IEnumerator)enumerator;
Error.ThrowArgumentNullException(e, nameof(enumerator));
return new UniTask(EnumeratorPromise.Create(e, PlayerLoopTiming.Update, CancellationToken.None, out var token), token).GetAwaiter();
}
public static UniTask WithCancellation(this IEnumerator enumerator, CancellationToken cancellationToken)
{
Error.ThrowArgumentNullException(enumerator, nameof(enumerator));
return new UniTask(EnumeratorPromise.Create(enumerator, PlayerLoopTiming.Update, cancellationToken, out var token), token);
}
public static UniTask ToUniTask(this IEnumerator enumerator, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken))
{
Error.ThrowArgumentNullException(enumerator, nameof(enumerator));
return new UniTask(EnumeratorPromise.Create(enumerator, timing, cancellationToken, out var token), token);
}
public static UniTask ToUniTask(this IEnumerator enumerator, MonoBehaviour coroutineRunner)
{
var source = AutoResetUniTaskCompletionSource.Create();
coroutineRunner.StartCoroutine(Core(enumerator, coroutineRunner, source));
return source.Task;
}
static IEnumerator Core(IEnumerator inner, MonoBehaviour coroutineRunner, AutoResetUniTaskCompletionSource source)
{
yield return coroutineRunner.StartCoroutine(inner);
source.TrySetResult();
}
sealed class EnumeratorPromise : IUniTaskSource, IPlayerLoopItem, ITaskPoolNode<EnumeratorPromise>
{
static TaskPool<EnumeratorPromise> pool;
EnumeratorPromise nextNode;
public ref EnumeratorPromise NextNode => ref nextNode;
static EnumeratorPromise()
{
TaskPool.RegisterSizeGetter(typeof(EnumeratorPromise), () => pool.Size);
}
IEnumerator innerEnumerator;
CancellationToken cancellationToken;
int initialFrame;
bool loopRunning;
bool calledGetResult;
UniTaskCompletionSourceCore<object> core;
EnumeratorPromise()
{
}
public static IUniTaskSource Create(IEnumerator innerEnumerator, PlayerLoopTiming timing, CancellationToken cancellationToken, out short token)
{
if (cancellationToken.IsCancellationRequested)
{
return AutoResetUniTaskCompletionSource.CreateFromCanceled(cancellationToken, out token);
}
if (!pool.TryPop(out var result))
{
result = new EnumeratorPromise();
}
TaskTracker.TrackActiveTask(result, 3);
result.innerEnumerator = ConsumeEnumerator(innerEnumerator);
result.cancellationToken = cancellationToken;
result.loopRunning = true;
result.calledGetResult = false;
result.initialFrame = -1;
token = result.core.Version;
// run immediately.
if (result.MoveNext())
{
PlayerLoopHelper.AddAction(timing, result);
}
return result;
}
public void GetResult(short token)
{
try
{
calledGetResult = true;
core.GetResult(token);
}
finally
{
if (!loopRunning)
{
TryReturn();
}
}
}
public UniTaskStatus GetStatus(short token)
{
return core.GetStatus(token);
}
public UniTaskStatus UnsafeGetStatus()
{
return core.UnsafeGetStatus();
}
public void OnCompleted(Action<object> continuation, object state, short token)
{
core.OnCompleted(continuation, state, token);
}
public bool MoveNext()
{
if (calledGetResult)
{
loopRunning = false;
TryReturn();
return false;
}
if (innerEnumerator == null) // invalid status, returned but loop running?
{
return false;
}
if (cancellationToken.IsCancellationRequested)
{
loopRunning = false;
core.TrySetCanceled(cancellationToken);
return false;
}
if (initialFrame == -1)
{
// Time can not touch in threadpool.
if (PlayerLoopHelper.IsMainThread)
{
initialFrame = Time.frameCount;
}
}
else if (initialFrame == Time.frameCount)
{
return true; // already executed in first frame, skip.
}
try
{
if (innerEnumerator.MoveNext())
{
return true;
}
}
catch (Exception ex)
{
loopRunning = false;
core.TrySetException(ex);
return false;
}
loopRunning = false;
core.TrySetResult(null);
return false;
}
bool TryReturn()
{
TaskTracker.RemoveTracking(this);
core.Reset();
innerEnumerator = default;
cancellationToken = default;
return pool.TryPush(this);
}
// Unwrap YieldInstructions
static IEnumerator ConsumeEnumerator(IEnumerator enumerator)
{
while (enumerator.MoveNext())
{
var current = enumerator.Current;
if (current == null)
{
yield return null;
}
else if (current is CustomYieldInstruction cyi)
{
// WWW, WaitForSecondsRealtime
while (cyi.keepWaiting)
{
yield return null;
}
}
else if (current is YieldInstruction)
{
IEnumerator innerCoroutine = null;
switch (current)
{
case AsyncOperation ao:
innerCoroutine = UnwrapWaitAsyncOperation(ao);
break;
case WaitForSeconds wfs:
innerCoroutine = UnwrapWaitForSeconds(wfs);
break;
}
if (innerCoroutine != null)
{
while (innerCoroutine.MoveNext())
{
yield return null;
}
}
else
{
goto WARN;
}
}
else if (current is IEnumerator e3)
{
var e4 = ConsumeEnumerator(e3);
while (e4.MoveNext())
{
yield return null;
}
}
else
{
goto WARN;
}
continue;
WARN:
// WaitForEndOfFrame, WaitForFixedUpdate, others.
UnityEngine.Debug.LogWarning($"yield {current.GetType().Name} is not supported on await IEnumerator or IEnumerator.ToUniTask(), please use ToUniTask(MonoBehaviour coroutineRunner) instead.");
yield return null;
}
}
static readonly FieldInfo waitForSeconds_Seconds = typeof(WaitForSeconds).GetField("m_Seconds", BindingFlags.Instance | BindingFlags.GetField | BindingFlags.NonPublic);
static IEnumerator UnwrapWaitForSeconds(WaitForSeconds waitForSeconds)
{
var second = (float)waitForSeconds_Seconds.GetValue(waitForSeconds);
var elapsed = 0.0f;
while (true)
{
yield return null;
elapsed += Time.deltaTime;
if (elapsed >= second)
{
break;
}
};
}
static IEnumerator UnwrapWaitAsyncOperation(AsyncOperation asyncOperation)
{
while (!asyncOperation.isDone)
{
yield return null;
}
}
}
}
}

View File

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

View File

@@ -0,0 +1,14 @@
using System;
namespace Cysharp.Threading.Tasks
{
public static class ExceptionExtensions
{
public static bool IsOperationCanceledException(this Exception exception)
{
return exception is OperationCanceledException;
}
}
}

View File

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

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 1daf560b608c5834cb5ccee628a81d34
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: d022eea31c1a10643b5b617779daca71
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,483 @@
// asmdef Version Defines, enabled when com.unity.addressables is imported.
#if UNITASK_ADDRESSABLE_SUPPORT
using Cysharp.Threading.Tasks.Internal;
using System;
using System.Runtime.CompilerServices;
using System.Runtime.ExceptionServices;
using System.Threading;
using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.AsyncOperations;
namespace Cysharp.Threading.Tasks
{
public static class AddressablesAsyncExtensions
{
#region AsyncOperationHandle
public static UniTask.Awaiter GetAwaiter(this AsyncOperationHandle handle)
{
return ToUniTask(handle).GetAwaiter();
}
public static UniTask WithCancellation(this AsyncOperationHandle handle, CancellationToken cancellationToken, bool cancelImmediately = false, bool autoReleaseWhenCanceled = false)
{
return ToUniTask(handle, cancellationToken: cancellationToken, cancelImmediately: cancelImmediately, autoReleaseWhenCanceled: autoReleaseWhenCanceled);
}
public static UniTask ToUniTask(this AsyncOperationHandle handle, IProgress<float> progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken), bool cancelImmediately = false, bool autoReleaseWhenCanceled = false)
{
if (cancellationToken.IsCancellationRequested) return UniTask.FromCanceled(cancellationToken);
if (!handle.IsValid())
{
// autoReleaseHandle:true handle is invalid(immediately internal handle == null) so return completed.
return UniTask.CompletedTask;
}
if (handle.IsDone)
{
if (handle.Status == AsyncOperationStatus.Failed)
{
return UniTask.FromException(handle.OperationException);
}
return UniTask.CompletedTask;
}
return new UniTask(AsyncOperationHandleConfiguredSource.Create(handle, timing, progress, cancellationToken, cancelImmediately, autoReleaseWhenCanceled, out var token), token);
}
public struct AsyncOperationHandleAwaiter : ICriticalNotifyCompletion
{
AsyncOperationHandle handle;
Action<AsyncOperationHandle> continuationAction;
public AsyncOperationHandleAwaiter(AsyncOperationHandle handle)
{
this.handle = handle;
this.continuationAction = null;
}
public bool IsCompleted => handle.IsDone;
public void GetResult()
{
if (continuationAction != null)
{
handle.Completed -= continuationAction;
continuationAction = null;
}
if (handle.Status == AsyncOperationStatus.Failed)
{
var e = handle.OperationException;
handle = default;
ExceptionDispatchInfo.Capture(e).Throw();
}
var result = handle.Result;
handle = default;
}
public void OnCompleted(Action continuation)
{
UnsafeOnCompleted(continuation);
}
public void UnsafeOnCompleted(Action continuation)
{
Error.ThrowWhenContinuationIsAlreadyRegistered(continuationAction);
continuationAction = PooledDelegate<AsyncOperationHandle>.Create(continuation);
handle.Completed += continuationAction;
}
}
sealed class AsyncOperationHandleConfiguredSource : IUniTaskSource, IPlayerLoopItem, ITaskPoolNode<AsyncOperationHandleConfiguredSource>
{
static TaskPool<AsyncOperationHandleConfiguredSource> pool;
AsyncOperationHandleConfiguredSource nextNode;
public ref AsyncOperationHandleConfiguredSource NextNode => ref nextNode;
static AsyncOperationHandleConfiguredSource()
{
TaskPool.RegisterSizeGetter(typeof(AsyncOperationHandleConfiguredSource), () => pool.Size);
}
readonly Action<AsyncOperationHandle> completedCallback;
AsyncOperationHandle handle;
CancellationToken cancellationToken;
CancellationTokenRegistration cancellationTokenRegistration;
IProgress<float> progress;
bool autoReleaseWhenCanceled;
bool cancelImmediately;
bool completed;
UniTaskCompletionSourceCore<AsyncUnit> core;
AsyncOperationHandleConfiguredSource()
{
completedCallback = HandleCompleted;
}
public static IUniTaskSource Create(AsyncOperationHandle handle, PlayerLoopTiming timing, IProgress<float> progress, CancellationToken cancellationToken, bool cancelImmediately, bool autoReleaseWhenCanceled, out short token)
{
if (cancellationToken.IsCancellationRequested)
{
return AutoResetUniTaskCompletionSource.CreateFromCanceled(cancellationToken, out token);
}
if (!pool.TryPop(out var result))
{
result = new AsyncOperationHandleConfiguredSource();
}
result.handle = handle;
result.progress = progress;
result.cancellationToken = cancellationToken;
result.cancelImmediately = cancelImmediately;
result.autoReleaseWhenCanceled = autoReleaseWhenCanceled;
result.completed = false;
if (cancelImmediately && cancellationToken.CanBeCanceled)
{
result.cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(state =>
{
var promise = (AsyncOperationHandleConfiguredSource)state;
if (promise.autoReleaseWhenCanceled && promise.handle.IsValid())
{
Addressables.Release(promise.handle);
}
promise.core.TrySetCanceled(promise.cancellationToken);
}, result);
}
TaskTracker.TrackActiveTask(result, 3);
PlayerLoopHelper.AddAction(timing, result);
handle.Completed += result.completedCallback;
token = result.core.Version;
return result;
}
void HandleCompleted(AsyncOperationHandle _)
{
if (handle.IsValid())
{
handle.Completed -= completedCallback;
}
if (completed)
{
return;
}
completed = true;
if (cancellationToken.IsCancellationRequested)
{
if (autoReleaseWhenCanceled && handle.IsValid())
{
Addressables.Release(handle);
}
core.TrySetCanceled(cancellationToken);
}
else if (handle.Status == AsyncOperationStatus.Failed)
{
core.TrySetException(handle.OperationException);
}
else
{
core.TrySetResult(AsyncUnit.Default);
}
}
public void GetResult(short token)
{
try
{
core.GetResult(token);
}
finally
{
if (!(cancelImmediately && cancellationToken.IsCancellationRequested))
{
TryReturn();
}
else
{
TaskTracker.RemoveTracking(this);
}
}
}
public UniTaskStatus GetStatus(short token)
{
return core.GetStatus(token);
}
public UniTaskStatus UnsafeGetStatus()
{
return core.UnsafeGetStatus();
}
public void OnCompleted(Action<object> continuation, object state, short token)
{
core.OnCompleted(continuation, state, token);
}
public bool MoveNext()
{
if (completed)
{
return false;
}
if (cancellationToken.IsCancellationRequested)
{
completed = true;
if (autoReleaseWhenCanceled && handle.IsValid())
{
Addressables.Release(handle);
}
core.TrySetCanceled(cancellationToken);
return false;
}
if (progress != null && handle.IsValid())
{
progress.Report(handle.GetDownloadStatus().Percent);
}
return true;
}
bool TryReturn()
{
TaskTracker.RemoveTracking(this);
core.Reset();
handle = default;
progress = default;
cancellationToken = default;
cancellationTokenRegistration.Dispose();
return pool.TryPush(this);
}
}
#endregion
#region AsyncOperationHandle_T
public static UniTask<T>.Awaiter GetAwaiter<T>(this AsyncOperationHandle<T> handle)
{
return ToUniTask(handle).GetAwaiter();
}
public static UniTask<T> WithCancellation<T>(this AsyncOperationHandle<T> handle, CancellationToken cancellationToken, bool cancelImmediately = false, bool autoReleaseWhenCanceled = false)
{
return ToUniTask(handle, cancellationToken: cancellationToken, cancelImmediately: cancelImmediately, autoReleaseWhenCanceled: autoReleaseWhenCanceled);
}
public static UniTask<T> ToUniTask<T>(this AsyncOperationHandle<T> handle, IProgress<float> progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken), bool cancelImmediately = false, bool autoReleaseWhenCanceled = false)
{
if (cancellationToken.IsCancellationRequested) return UniTask.FromCanceled<T>(cancellationToken);
if (!handle.IsValid())
{
throw new Exception("Attempting to use an invalid operation handle");
}
if (handle.IsDone)
{
if (handle.Status == AsyncOperationStatus.Failed)
{
return UniTask.FromException<T>(handle.OperationException);
}
return UniTask.FromResult(handle.Result);
}
return new UniTask<T>(AsyncOperationHandleConfiguredSource<T>.Create(handle, timing, progress, cancellationToken, cancelImmediately, autoReleaseWhenCanceled, out var token), token);
}
sealed class AsyncOperationHandleConfiguredSource<T> : IUniTaskSource<T>, IPlayerLoopItem, ITaskPoolNode<AsyncOperationHandleConfiguredSource<T>>
{
static TaskPool<AsyncOperationHandleConfiguredSource<T>> pool;
AsyncOperationHandleConfiguredSource<T> nextNode;
public ref AsyncOperationHandleConfiguredSource<T> NextNode => ref nextNode;
static AsyncOperationHandleConfiguredSource()
{
TaskPool.RegisterSizeGetter(typeof(AsyncOperationHandleConfiguredSource<T>), () => pool.Size);
}
readonly Action<AsyncOperationHandle<T>> completedCallback;
AsyncOperationHandle<T> handle;
CancellationToken cancellationToken;
CancellationTokenRegistration cancellationTokenRegistration;
IProgress<float> progress;
bool autoReleaseWhenCanceled;
bool cancelImmediately;
bool completed;
UniTaskCompletionSourceCore<T> core;
AsyncOperationHandleConfiguredSource()
{
completedCallback = HandleCompleted;
}
public static IUniTaskSource<T> Create(AsyncOperationHandle<T> handle, PlayerLoopTiming timing, IProgress<float> progress, CancellationToken cancellationToken, bool cancelImmediately, bool autoReleaseWhenCanceled, out short token)
{
if (cancellationToken.IsCancellationRequested)
{
return AutoResetUniTaskCompletionSource<T>.CreateFromCanceled(cancellationToken, out token);
}
if (!pool.TryPop(out var result))
{
result = new AsyncOperationHandleConfiguredSource<T>();
}
result.handle = handle;
result.cancellationToken = cancellationToken;
result.completed = false;
result.progress = progress;
result.autoReleaseWhenCanceled = autoReleaseWhenCanceled;
result.cancelImmediately = cancelImmediately;
if (cancelImmediately && cancellationToken.CanBeCanceled)
{
result.cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(state =>
{
var promise = (AsyncOperationHandleConfiguredSource<T>)state;
if (promise.autoReleaseWhenCanceled && promise.handle.IsValid())
{
Addressables.Release(promise.handle);
}
promise.core.TrySetCanceled(promise.cancellationToken);
}, result);
}
TaskTracker.TrackActiveTask(result, 3);
PlayerLoopHelper.AddAction(timing, result);
handle.Completed += result.completedCallback;
token = result.core.Version;
return result;
}
void HandleCompleted(AsyncOperationHandle<T> argHandle)
{
if (handle.IsValid())
{
handle.Completed -= completedCallback;
}
if (completed)
{
return;
}
completed = true;
if (cancellationToken.IsCancellationRequested)
{
if (autoReleaseWhenCanceled && handle.IsValid())
{
Addressables.Release(handle);
}
core.TrySetCanceled(cancellationToken);
}
else if (argHandle.Status == AsyncOperationStatus.Failed)
{
core.TrySetException(argHandle.OperationException);
}
else
{
core.TrySetResult(argHandle.Result);
}
}
public T GetResult(short token)
{
try
{
return core.GetResult(token);
}
finally
{
if (!(cancelImmediately && cancellationToken.IsCancellationRequested))
{
TryReturn();
}
else
{
TaskTracker.RemoveTracking(this);
}
}
}
void IUniTaskSource.GetResult(short token)
{
GetResult(token);
}
public UniTaskStatus GetStatus(short token)
{
return core.GetStatus(token);
}
public UniTaskStatus UnsafeGetStatus()
{
return core.UnsafeGetStatus();
}
public void OnCompleted(Action<object> continuation, object state, short token)
{
core.OnCompleted(continuation, state, token);
}
public bool MoveNext()
{
if (completed)
{
return false;
}
if (cancellationToken.IsCancellationRequested)
{
completed = true;
if (autoReleaseWhenCanceled && handle.IsValid())
{
Addressables.Release(handle);
}
core.TrySetCanceled(cancellationToken);
return false;
}
if (progress != null && handle.IsValid())
{
progress.Report(handle.GetDownloadStatus().Percent);
}
return true;
}
bool TryReturn()
{
TaskTracker.RemoveTracking(this);
core.Reset();
handle = default;
progress = default;
cancellationToken = default;
cancellationTokenRegistration.Dispose();
return pool.TryPush(this);
}
}
#endregion
}
}
#endif

View File

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

View File

@@ -0,0 +1,28 @@
{
"name": "UniTask.Addressables",
"references": [
"UniTask",
"Unity.ResourceManager",
"Unity.Addressables"
],
"includePlatforms": [],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [
{
"name": "com.unity.addressables",
"expression": "",
"define": "UNITASK_ADDRESSABLE_SUPPORT"
},
{
"name": "com.unity.addressables.cn",
"expression": "",
"define": "UNITASK_ADDRESSABLE_SUPPORT"
}
],
"noEngineReferences": false
}

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 593a5b492d29ac6448b1ebf7f035ef33
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 50d32ab2d84824748acc812f132b8cc0
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,436 @@
// asmdef Version Defines, enabled when com.demigiant.dotween is imported.
#if UNITASK_DOTWEEN_SUPPORT
using Cysharp.Threading.Tasks.Internal;
using DG.Tweening;
using System;
using System.Collections.Concurrent;
using System.Runtime.CompilerServices;
using System.Threading;
namespace Cysharp.Threading.Tasks
{
public enum TweenCancelBehaviour
{
Kill,
KillWithCompleteCallback,
Complete,
CompleteWithSequenceCallback,
CancelAwait,
// AndCancelAwait
KillAndCancelAwait,
KillWithCompleteCallbackAndCancelAwait,
CompleteAndCancelAwait,
CompleteWithSequenceCallbackAndCancelAwait
}
public static class DOTweenAsyncExtensions
{
enum CallbackType
{
Kill,
Complete,
Pause,
Play,
Rewind,
StepComplete
}
public static TweenAwaiter GetAwaiter(this Tween tween)
{
return new TweenAwaiter(tween);
}
public static UniTask WithCancellation(this Tween tween, CancellationToken cancellationToken)
{
Error.ThrowArgumentNullException(tween, nameof(tween));
if (!tween.IsActive()) return UniTask.CompletedTask;
return new UniTask(TweenConfiguredSource.Create(tween, TweenCancelBehaviour.Kill, cancellationToken, CallbackType.Kill, out var token), token);
}
public static UniTask ToUniTask(this Tween tween, TweenCancelBehaviour tweenCancelBehaviour = TweenCancelBehaviour.Kill, CancellationToken cancellationToken = default)
{
Error.ThrowArgumentNullException(tween, nameof(tween));
if (!tween.IsActive()) return UniTask.CompletedTask;
return new UniTask(TweenConfiguredSource.Create(tween, tweenCancelBehaviour, cancellationToken, CallbackType.Kill, out var token), token);
}
public static UniTask AwaitForComplete(this Tween tween, TweenCancelBehaviour tweenCancelBehaviour = TweenCancelBehaviour.Kill, CancellationToken cancellationToken = default)
{
Error.ThrowArgumentNullException(tween, nameof(tween));
if (!tween.IsActive()) return UniTask.CompletedTask;
return new UniTask(TweenConfiguredSource.Create(tween, tweenCancelBehaviour, cancellationToken, CallbackType.Complete, out var token), token);
}
public static UniTask AwaitForPause(this Tween tween, TweenCancelBehaviour tweenCancelBehaviour = TweenCancelBehaviour.Kill, CancellationToken cancellationToken = default)
{
Error.ThrowArgumentNullException(tween, nameof(tween));
if (!tween.IsActive()) return UniTask.CompletedTask;
return new UniTask(TweenConfiguredSource.Create(tween, tweenCancelBehaviour, cancellationToken, CallbackType.Pause, out var token), token);
}
public static UniTask AwaitForPlay(this Tween tween, TweenCancelBehaviour tweenCancelBehaviour = TweenCancelBehaviour.Kill, CancellationToken cancellationToken = default)
{
Error.ThrowArgumentNullException(tween, nameof(tween));
if (!tween.IsActive()) return UniTask.CompletedTask;
return new UniTask(TweenConfiguredSource.Create(tween, tweenCancelBehaviour, cancellationToken, CallbackType.Play, out var token), token);
}
public static UniTask AwaitForRewind(this Tween tween, TweenCancelBehaviour tweenCancelBehaviour = TweenCancelBehaviour.Kill, CancellationToken cancellationToken = default)
{
Error.ThrowArgumentNullException(tween, nameof(tween));
if (!tween.IsActive()) return UniTask.CompletedTask;
return new UniTask(TweenConfiguredSource.Create(tween, tweenCancelBehaviour, cancellationToken, CallbackType.Rewind, out var token), token);
}
public static UniTask AwaitForStepComplete(this Tween tween, TweenCancelBehaviour tweenCancelBehaviour = TweenCancelBehaviour.Kill, CancellationToken cancellationToken = default)
{
Error.ThrowArgumentNullException(tween, nameof(tween));
if (!tween.IsActive()) return UniTask.CompletedTask;
return new UniTask(TweenConfiguredSource.Create(tween, tweenCancelBehaviour, cancellationToken, CallbackType.StepComplete, out var token), token);
}
public struct TweenAwaiter : ICriticalNotifyCompletion
{
readonly Tween tween;
// killed(non active) as completed.
public bool IsCompleted => !tween.IsActive();
public TweenAwaiter(Tween tween)
{
this.tween = tween;
}
public TweenAwaiter GetAwaiter()
{
return this;
}
public void GetResult()
{
}
public void OnCompleted(System.Action continuation)
{
UnsafeOnCompleted(continuation);
}
public void UnsafeOnCompleted(System.Action continuation)
{
// onKill is called after OnCompleted, both Complete(false/true) and Kill(false/true).
tween.onKill = PooledTweenCallback.Create(continuation);
}
}
sealed class TweenConfiguredSource : IUniTaskSource, ITaskPoolNode<TweenConfiguredSource>
{
static TaskPool<TweenConfiguredSource> pool;
TweenConfiguredSource nextNode;
public ref TweenConfiguredSource NextNode => ref nextNode;
static TweenConfiguredSource()
{
TaskPool.RegisterSizeGetter(typeof(TweenConfiguredSource), () => pool.Size);
}
readonly TweenCallback onCompleteCallbackDelegate;
Tween tween;
TweenCancelBehaviour cancelBehaviour;
CancellationToken cancellationToken;
CancellationTokenRegistration cancellationRegistration;
CallbackType callbackType;
bool canceled;
TweenCallback originalCompleteAction;
UniTaskCompletionSourceCore<AsyncUnit> core;
TweenConfiguredSource()
{
onCompleteCallbackDelegate = OnCompleteCallbackDelegate;
}
public static IUniTaskSource Create(Tween tween, TweenCancelBehaviour cancelBehaviour, CancellationToken cancellationToken, CallbackType callbackType, out short token)
{
if (cancellationToken.IsCancellationRequested)
{
DoCancelBeforeCreate(tween, cancelBehaviour);
return AutoResetUniTaskCompletionSource.CreateFromCanceled(cancellationToken, out token);
}
if (!pool.TryPop(out var result))
{
result = new TweenConfiguredSource();
}
result.tween = tween;
result.cancelBehaviour = cancelBehaviour;
result.cancellationToken = cancellationToken;
result.callbackType = callbackType;
result.canceled = false;
switch (callbackType)
{
case CallbackType.Kill:
result.originalCompleteAction = tween.onKill;
tween.onKill = result.onCompleteCallbackDelegate;
break;
case CallbackType.Complete:
result.originalCompleteAction = tween.onComplete;
tween.onComplete = result.onCompleteCallbackDelegate;
break;
case CallbackType.Pause:
result.originalCompleteAction = tween.onPause;
tween.onPause = result.onCompleteCallbackDelegate;
break;
case CallbackType.Play:
result.originalCompleteAction = tween.onPlay;
tween.onPlay = result.onCompleteCallbackDelegate;
break;
case CallbackType.Rewind:
result.originalCompleteAction = tween.onRewind;
tween.onRewind = result.onCompleteCallbackDelegate;
break;
case CallbackType.StepComplete:
result.originalCompleteAction = tween.onStepComplete;
tween.onStepComplete = result.onCompleteCallbackDelegate;
break;
default:
break;
}
if (result.originalCompleteAction == result.onCompleteCallbackDelegate)
{
result.originalCompleteAction = null;
}
if (cancellationToken.CanBeCanceled)
{
result.cancellationRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(x =>
{
var source = (TweenConfiguredSource)x;
switch (source.cancelBehaviour)
{
case TweenCancelBehaviour.Kill:
default:
source.tween.Kill(false);
break;
case TweenCancelBehaviour.KillAndCancelAwait:
source.canceled = true;
source.tween.Kill(false);
break;
case TweenCancelBehaviour.KillWithCompleteCallback:
source.tween.Kill(true);
break;
case TweenCancelBehaviour.KillWithCompleteCallbackAndCancelAwait:
source.canceled = true;
source.tween.Kill(true);
break;
case TweenCancelBehaviour.Complete:
source.tween.Complete(false);
break;
case TweenCancelBehaviour.CompleteAndCancelAwait:
source.canceled = true;
source.tween.Complete(false);
break;
case TweenCancelBehaviour.CompleteWithSequenceCallback:
source.tween.Complete(true);
break;
case TweenCancelBehaviour.CompleteWithSequenceCallbackAndCancelAwait:
source.canceled = true;
source.tween.Complete(true);
break;
case TweenCancelBehaviour.CancelAwait:
source.RestoreOriginalCallback();
source.core.TrySetCanceled(source.cancellationToken);
break;
}
}, result);
}
TaskTracker.TrackActiveTask(result, 3);
token = result.core.Version;
return result;
}
void OnCompleteCallbackDelegate()
{
if (cancellationToken.IsCancellationRequested)
{
if (this.cancelBehaviour == TweenCancelBehaviour.KillAndCancelAwait
|| this.cancelBehaviour == TweenCancelBehaviour.KillWithCompleteCallbackAndCancelAwait
|| this.cancelBehaviour == TweenCancelBehaviour.CompleteAndCancelAwait
|| this.cancelBehaviour == TweenCancelBehaviour.CompleteWithSequenceCallbackAndCancelAwait
|| this.cancelBehaviour == TweenCancelBehaviour.CancelAwait)
{
canceled = true;
}
}
if (canceled)
{
core.TrySetCanceled(cancellationToken);
}
else
{
originalCompleteAction?.Invoke();
core.TrySetResult(AsyncUnit.Default);
}
}
static void DoCancelBeforeCreate(Tween tween, TweenCancelBehaviour tweenCancelBehaviour)
{
switch (tweenCancelBehaviour)
{
case TweenCancelBehaviour.Kill:
default:
tween.Kill(false);
break;
case TweenCancelBehaviour.KillAndCancelAwait:
tween.Kill(false);
break;
case TweenCancelBehaviour.KillWithCompleteCallback:
tween.Kill(true);
break;
case TweenCancelBehaviour.KillWithCompleteCallbackAndCancelAwait:
tween.Kill(true);
break;
case TweenCancelBehaviour.Complete:
tween.Complete(false);
break;
case TweenCancelBehaviour.CompleteAndCancelAwait:
tween.Complete(false);
break;
case TweenCancelBehaviour.CompleteWithSequenceCallback:
tween.Complete(true);
break;
case TweenCancelBehaviour.CompleteWithSequenceCallbackAndCancelAwait:
tween.Complete(true);
break;
case TweenCancelBehaviour.CancelAwait:
break;
}
}
public void GetResult(short token)
{
try
{
core.GetResult(token);
}
finally
{
TryReturn();
}
}
public UniTaskStatus GetStatus(short token)
{
return core.GetStatus(token);
}
public UniTaskStatus UnsafeGetStatus()
{
return core.UnsafeGetStatus();
}
public void OnCompleted(Action<object> continuation, object state, short token)
{
core.OnCompleted(continuation, state, token);
}
bool TryReturn()
{
TaskTracker.RemoveTracking(this);
core.Reset();
cancellationRegistration.Dispose();
RestoreOriginalCallback();
tween = default;
cancellationToken = default;
originalCompleteAction = default;
return pool.TryPush(this);
}
void RestoreOriginalCallback()
{
switch (callbackType)
{
case CallbackType.Kill:
tween.onKill = originalCompleteAction;
break;
case CallbackType.Complete:
tween.onComplete = originalCompleteAction;
break;
case CallbackType.Pause:
tween.onPause = originalCompleteAction;
break;
case CallbackType.Play:
tween.onPlay = originalCompleteAction;
break;
case CallbackType.Rewind:
tween.onRewind = originalCompleteAction;
break;
case CallbackType.StepComplete:
tween.onStepComplete = originalCompleteAction;
break;
default:
break;
}
}
}
}
sealed class PooledTweenCallback
{
static readonly ConcurrentQueue<PooledTweenCallback> pool = new ConcurrentQueue<PooledTweenCallback>();
readonly TweenCallback runDelegate;
Action continuation;
PooledTweenCallback()
{
runDelegate = Run;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static TweenCallback Create(Action continuation)
{
if (!pool.TryDequeue(out var item))
{
item = new PooledTweenCallback();
}
item.continuation = continuation;
return item.runDelegate;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
void Run()
{
var call = continuation;
continuation = null;
if (call != null)
{
pool.Enqueue(this);
call.Invoke();
}
}
}
}
#endif

View File

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

View File

@@ -0,0 +1,22 @@
{
"name": "UniTask.DOTween",
"references": [
"UniTask",
"DOTween.Modules"
],
"includePlatforms": [],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [
{
"name": "com.demigiant.dotween",
"expression": "",
"define": "UNITASK_DOTWEEN_SUPPORT"
}
],
"noEngineReferences": false
}

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 029c1c1b674aaae47a6841a0b89ad80e
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: fbbc43611642c0347bf936527dddd511
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,224 @@
#if UNITASK_TEXTMESHPRO_SUPPORT
using System;
using System.Threading;
using TMPro;
namespace Cysharp.Threading.Tasks
{
public static partial class TextMeshProAsyncExtensions
{
public static IAsyncValueChangedEventHandler<string> GetAsyncValueChangedEventHandler(this TMP_InputField inputField)
{
return new AsyncUnityEventHandler<string>(inputField.onValueChanged, inputField.GetCancellationTokenOnDestroy(), false);
}
public static IAsyncValueChangedEventHandler<string> GetAsyncValueChangedEventHandler(this TMP_InputField inputField, CancellationToken cancellationToken)
{
return new AsyncUnityEventHandler<string>(inputField.onValueChanged, cancellationToken, false);
}
public static UniTask<string> OnValueChangedAsync(this TMP_InputField inputField)
{
return new AsyncUnityEventHandler<string>(inputField.onValueChanged, inputField.GetCancellationTokenOnDestroy(), true).OnInvokeAsync();
}
public static UniTask<string> OnValueChangedAsync(this TMP_InputField inputField, CancellationToken cancellationToken)
{
return new AsyncUnityEventHandler<string>(inputField.onValueChanged, cancellationToken, true).OnInvokeAsync();
}
public static IUniTaskAsyncEnumerable<string> OnValueChangedAsAsyncEnumerable(this TMP_InputField inputField)
{
return new UnityEventHandlerAsyncEnumerable<string>(inputField.onValueChanged, inputField.GetCancellationTokenOnDestroy());
}
public static IUniTaskAsyncEnumerable<string> OnValueChangedAsAsyncEnumerable(this TMP_InputField inputField, CancellationToken cancellationToken)
{
return new UnityEventHandlerAsyncEnumerable<string>(inputField.onValueChanged, cancellationToken);
}
public static IAsyncEndEditEventHandler<string> GetAsyncEndEditEventHandler(this TMP_InputField inputField)
{
return new AsyncUnityEventHandler<string>(inputField.onEndEdit, inputField.GetCancellationTokenOnDestroy(), false);
}
public static IAsyncEndEditEventHandler<string> GetAsyncEndEditEventHandler(this TMP_InputField inputField, CancellationToken cancellationToken)
{
return new AsyncUnityEventHandler<string>(inputField.onEndEdit, cancellationToken, false);
}
public static UniTask<string> OnEndEditAsync(this TMP_InputField inputField)
{
return new AsyncUnityEventHandler<string>(inputField.onEndEdit, inputField.GetCancellationTokenOnDestroy(), true).OnInvokeAsync();
}
public static UniTask<string> OnEndEditAsync(this TMP_InputField inputField, CancellationToken cancellationToken)
{
return new AsyncUnityEventHandler<string>(inputField.onEndEdit, cancellationToken, true).OnInvokeAsync();
}
public static IUniTaskAsyncEnumerable<string> OnEndEditAsAsyncEnumerable(this TMP_InputField inputField)
{
return new UnityEventHandlerAsyncEnumerable<string>(inputField.onEndEdit, inputField.GetCancellationTokenOnDestroy());
}
public static IUniTaskAsyncEnumerable<string> OnEndEditAsAsyncEnumerable(this TMP_InputField inputField, CancellationToken cancellationToken)
{
return new UnityEventHandlerAsyncEnumerable<string>(inputField.onEndEdit, cancellationToken);
}
public static IAsyncEndTextSelectionEventHandler<(string, int, int)> GetAsyncEndTextSelectionEventHandler(this TMP_InputField inputField)
{
return new AsyncUnityEventHandler<(string, int, int)>(new TextSelectionEventConverter(inputField.onEndTextSelection), inputField.GetCancellationTokenOnDestroy(), false);
}
public static IAsyncEndTextSelectionEventHandler<(string, int, int)> GetAsyncEndTextSelectionEventHandler(this TMP_InputField inputField, CancellationToken cancellationToken)
{
return new AsyncUnityEventHandler<(string, int, int)>(new TextSelectionEventConverter(inputField.onEndTextSelection), cancellationToken, false);
}
public static UniTask<(string, int, int)> OnEndTextSelectionAsync(this TMP_InputField inputField)
{
return new AsyncUnityEventHandler<(string, int, int)>(new TextSelectionEventConverter(inputField.onEndTextSelection), inputField.GetCancellationTokenOnDestroy(), true).OnInvokeAsync();
}
public static UniTask<(string, int, int)> OnEndTextSelectionAsync(this TMP_InputField inputField, CancellationToken cancellationToken)
{
return new AsyncUnityEventHandler<(string, int, int)>(new TextSelectionEventConverter(inputField.onEndTextSelection), cancellationToken, true).OnInvokeAsync();
}
public static IUniTaskAsyncEnumerable<(string, int, int)> OnEndTextSelectionAsAsyncEnumerable(this TMP_InputField inputField)
{
return new UnityEventHandlerAsyncEnumerable<(string, int, int)>(new TextSelectionEventConverter(inputField.onEndTextSelection), inputField.GetCancellationTokenOnDestroy());
}
public static IUniTaskAsyncEnumerable<(string, int, int)> OnEndTextSelectionAsAsyncEnumerable(this TMP_InputField inputField, CancellationToken cancellationToken)
{
return new UnityEventHandlerAsyncEnumerable<(string, int, int)>(new TextSelectionEventConverter(inputField.onEndTextSelection), cancellationToken);
}
public static IAsyncTextSelectionEventHandler<(string, int, int)> GetAsyncTextSelectionEventHandler(this TMP_InputField inputField)
{
return new AsyncUnityEventHandler<(string, int, int)>(new TextSelectionEventConverter(inputField.onTextSelection), inputField.GetCancellationTokenOnDestroy(), false);
}
public static IAsyncTextSelectionEventHandler<(string, int, int)> GetAsyncTextSelectionEventHandler(this TMP_InputField inputField, CancellationToken cancellationToken)
{
return new AsyncUnityEventHandler<(string, int, int)>(new TextSelectionEventConverter(inputField.onTextSelection), cancellationToken, false);
}
public static UniTask<(string, int, int)> OnTextSelectionAsync(this TMP_InputField inputField)
{
return new AsyncUnityEventHandler<(string, int, int)>(new TextSelectionEventConverter(inputField.onTextSelection), inputField.GetCancellationTokenOnDestroy(), true).OnInvokeAsync();
}
public static UniTask<(string, int, int)> OnTextSelectionAsync(this TMP_InputField inputField, CancellationToken cancellationToken)
{
return new AsyncUnityEventHandler<(string, int, int)>(new TextSelectionEventConverter(inputField.onTextSelection), cancellationToken, true).OnInvokeAsync();
}
public static IUniTaskAsyncEnumerable<(string, int, int)> OnTextSelectionAsAsyncEnumerable(this TMP_InputField inputField)
{
return new UnityEventHandlerAsyncEnumerable<(string, int, int)>(new TextSelectionEventConverter(inputField.onTextSelection), inputField.GetCancellationTokenOnDestroy());
}
public static IUniTaskAsyncEnumerable<(string, int, int)> OnTextSelectionAsAsyncEnumerable(this TMP_InputField inputField, CancellationToken cancellationToken)
{
return new UnityEventHandlerAsyncEnumerable<(string, int, int)>(new TextSelectionEventConverter(inputField.onTextSelection), cancellationToken);
}
public static IAsyncDeselectEventHandler<string> GetAsyncDeselectEventHandler(this TMP_InputField inputField)
{
return new AsyncUnityEventHandler<string>(inputField.onDeselect, inputField.GetCancellationTokenOnDestroy(), false);
}
public static IAsyncDeselectEventHandler<string> GetAsyncDeselectEventHandler(this TMP_InputField inputField, CancellationToken cancellationToken)
{
return new AsyncUnityEventHandler<string>(inputField.onDeselect, cancellationToken, false);
}
public static UniTask<string> OnDeselectAsync(this TMP_InputField inputField)
{
return new AsyncUnityEventHandler<string>(inputField.onDeselect, inputField.GetCancellationTokenOnDestroy(), true).OnInvokeAsync();
}
public static UniTask<string> OnDeselectAsync(this TMP_InputField inputField, CancellationToken cancellationToken)
{
return new AsyncUnityEventHandler<string>(inputField.onDeselect, cancellationToken, true).OnInvokeAsync();
}
public static IUniTaskAsyncEnumerable<string> OnDeselectAsAsyncEnumerable(this TMP_InputField inputField)
{
return new UnityEventHandlerAsyncEnumerable<string>(inputField.onDeselect, inputField.GetCancellationTokenOnDestroy());
}
public static IUniTaskAsyncEnumerable<string> OnDeselectAsAsyncEnumerable(this TMP_InputField inputField, CancellationToken cancellationToken)
{
return new UnityEventHandlerAsyncEnumerable<string>(inputField.onDeselect, cancellationToken);
}
public static IAsyncSelectEventHandler<string> GetAsyncSelectEventHandler(this TMP_InputField inputField)
{
return new AsyncUnityEventHandler<string>(inputField.onSelect, inputField.GetCancellationTokenOnDestroy(), false);
}
public static IAsyncSelectEventHandler<string> GetAsyncSelectEventHandler(this TMP_InputField inputField, CancellationToken cancellationToken)
{
return new AsyncUnityEventHandler<string>(inputField.onSelect, cancellationToken, false);
}
public static UniTask<string> OnSelectAsync(this TMP_InputField inputField)
{
return new AsyncUnityEventHandler<string>(inputField.onSelect, inputField.GetCancellationTokenOnDestroy(), true).OnInvokeAsync();
}
public static UniTask<string> OnSelectAsync(this TMP_InputField inputField, CancellationToken cancellationToken)
{
return new AsyncUnityEventHandler<string>(inputField.onSelect, cancellationToken, true).OnInvokeAsync();
}
public static IUniTaskAsyncEnumerable<string> OnSelectAsAsyncEnumerable(this TMP_InputField inputField)
{
return new UnityEventHandlerAsyncEnumerable<string>(inputField.onSelect, inputField.GetCancellationTokenOnDestroy());
}
public static IUniTaskAsyncEnumerable<string> OnSelectAsAsyncEnumerable(this TMP_InputField inputField, CancellationToken cancellationToken)
{
return new UnityEventHandlerAsyncEnumerable<string>(inputField.onSelect, cancellationToken);
}
public static IAsyncSubmitEventHandler<string> GetAsyncSubmitEventHandler(this TMP_InputField inputField)
{
return new AsyncUnityEventHandler<string>(inputField.onSubmit, inputField.GetCancellationTokenOnDestroy(), false);
}
public static IAsyncSubmitEventHandler<string> GetAsyncSubmitEventHandler(this TMP_InputField inputField, CancellationToken cancellationToken)
{
return new AsyncUnityEventHandler<string>(inputField.onSubmit, cancellationToken, false);
}
public static UniTask<string> OnSubmitAsync(this TMP_InputField inputField)
{
return new AsyncUnityEventHandler<string>(inputField.onSubmit, inputField.GetCancellationTokenOnDestroy(), true).OnInvokeAsync();
}
public static UniTask<string> OnSubmitAsync(this TMP_InputField inputField, CancellationToken cancellationToken)
{
return new AsyncUnityEventHandler<string>(inputField.onSubmit, cancellationToken, true).OnInvokeAsync();
}
public static IUniTaskAsyncEnumerable<string> OnSubmitAsAsyncEnumerable(this TMP_InputField inputField)
{
return new UnityEventHandlerAsyncEnumerable<string>(inputField.onSubmit, inputField.GetCancellationTokenOnDestroy());
}
public static IUniTaskAsyncEnumerable<string> OnSubmitAsAsyncEnumerable(this TMP_InputField inputField, CancellationToken cancellationToken)
{
return new UnityEventHandlerAsyncEnumerable<string>(inputField.onSubmit, cancellationToken);
}
}
}
#endif

View File

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

View File

@@ -0,0 +1,130 @@
#if UNITASK_TEXTMESHPRO_SUPPORT
using System;
using System.Threading;
using TMPro;
using UnityEngine.Events;
namespace Cysharp.Threading.Tasks
{
public static partial class TextMeshProAsyncExtensions
{
// <string> -> Text
public static void BindTo(this IUniTaskAsyncEnumerable<string> source, TMP_Text text, bool rebindOnError = true)
{
BindToCore(source, text, text.GetCancellationTokenOnDestroy(), rebindOnError).Forget();
}
public static void BindTo(this IUniTaskAsyncEnumerable<string> source, TMP_Text text, CancellationToken cancellationToken, bool rebindOnError = true)
{
BindToCore(source, text, cancellationToken, rebindOnError).Forget();
}
static async UniTaskVoid BindToCore(IUniTaskAsyncEnumerable<string> source, TMP_Text text, CancellationToken cancellationToken, bool rebindOnError)
{
var repeat = false;
BIND_AGAIN:
var e = source.GetAsyncEnumerator(cancellationToken);
try
{
while (true)
{
bool moveNext;
try
{
moveNext = await e.MoveNextAsync();
repeat = false;
}
catch (Exception ex)
{
if (ex is OperationCanceledException) return;
if (rebindOnError && !repeat)
{
repeat = true;
goto BIND_AGAIN;
}
else
{
throw;
}
}
if (!moveNext) return;
text.text = e.Current;
}
}
finally
{
if (e != null)
{
await e.DisposeAsync();
}
}
}
// <T> -> Text
public static void BindTo<T>(this IUniTaskAsyncEnumerable<T> source, TMP_Text text, bool rebindOnError = true)
{
BindToCore(source, text, text.GetCancellationTokenOnDestroy(), rebindOnError).Forget();
}
public static void BindTo<T>(this IUniTaskAsyncEnumerable<T> source, TMP_Text text, CancellationToken cancellationToken, bool rebindOnError = true)
{
BindToCore(source, text, cancellationToken, rebindOnError).Forget();
}
public static void BindTo<T>(this AsyncReactiveProperty<T> source, TMP_Text text, bool rebindOnError = true)
{
BindToCore(source, text, text.GetCancellationTokenOnDestroy(), rebindOnError).Forget();
}
static async UniTaskVoid BindToCore<T>(IUniTaskAsyncEnumerable<T> source, TMP_Text text, CancellationToken cancellationToken, bool rebindOnError)
{
var repeat = false;
BIND_AGAIN:
var e = source.GetAsyncEnumerator(cancellationToken);
try
{
while (true)
{
bool moveNext;
try
{
moveNext = await e.MoveNextAsync();
repeat = false;
}
catch (Exception ex)
{
if (ex is OperationCanceledException) return;
if (rebindOnError && !repeat)
{
repeat = true;
goto BIND_AGAIN;
}
else
{
throw;
}
}
if (!moveNext) return;
text.text = e.Current.ToString();
}
}
finally
{
if (e != null)
{
await e.DisposeAsync();
}
}
}
}
}
#endif

View File

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

View File

@@ -0,0 +1,27 @@
{
"name": "UniTask.TextMeshPro",
"references": [
"UniTask",
"Unity.TextMeshPro"
],
"includePlatforms": [],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [
{
"name": "com.unity.textmeshpro",
"expression": "",
"define": "UNITASK_TEXTMESHPRO_SUPPORT"
},
{
"name": "com.unity.ugui",
"expression": "2.0.0",
"define": "UNITASK_TEXTMESHPRO_SUPPORT"
}
],
"noEngineReferences": false
}

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: dc47925d1a5fa2946bdd37746b2b5d48
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,91 @@
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Threading;
namespace Cysharp.Threading.Tasks
{
public interface IUniTaskAsyncEnumerable<out T>
{
IUniTaskAsyncEnumerator<T> GetAsyncEnumerator(CancellationToken cancellationToken = default);
}
public interface IUniTaskAsyncEnumerator<out T> : IUniTaskAsyncDisposable
{
T Current { get; }
UniTask<bool> MoveNextAsync();
}
public interface IUniTaskAsyncDisposable
{
UniTask DisposeAsync();
}
public interface IUniTaskOrderedAsyncEnumerable<TElement> : IUniTaskAsyncEnumerable<TElement>
{
IUniTaskOrderedAsyncEnumerable<TElement> CreateOrderedEnumerable<TKey>(Func<TElement, TKey> keySelector, IComparer<TKey> comparer, bool descending);
IUniTaskOrderedAsyncEnumerable<TElement> CreateOrderedEnumerable<TKey>(Func<TElement, UniTask<TKey>> keySelector, IComparer<TKey> comparer, bool descending);
IUniTaskOrderedAsyncEnumerable<TElement> CreateOrderedEnumerable<TKey>(Func<TElement, CancellationToken, UniTask<TKey>> keySelector, IComparer<TKey> comparer, bool descending);
}
public interface IConnectableUniTaskAsyncEnumerable<out T> : IUniTaskAsyncEnumerable<T>
{
IDisposable Connect();
}
// don't use AsyncGrouping.
//public interface IUniTaskAsyncGrouping<out TKey, out TElement> : IUniTaskAsyncEnumerable<TElement>
//{
// TKey Key { get; }
//}
public static class UniTaskAsyncEnumerableExtensions
{
public static UniTaskCancelableAsyncEnumerable<T> WithCancellation<T>(this IUniTaskAsyncEnumerable<T> source, CancellationToken cancellationToken)
{
return new UniTaskCancelableAsyncEnumerable<T>(source, cancellationToken);
}
}
[StructLayout(LayoutKind.Auto)]
public readonly struct UniTaskCancelableAsyncEnumerable<T>
{
private readonly IUniTaskAsyncEnumerable<T> enumerable;
private readonly CancellationToken cancellationToken;
internal UniTaskCancelableAsyncEnumerable(IUniTaskAsyncEnumerable<T> enumerable, CancellationToken cancellationToken)
{
this.enumerable = enumerable;
this.cancellationToken = cancellationToken;
}
public Enumerator GetAsyncEnumerator()
{
return new Enumerator(enumerable.GetAsyncEnumerator(cancellationToken));
}
[StructLayout(LayoutKind.Auto)]
public readonly struct Enumerator
{
private readonly IUniTaskAsyncEnumerator<T> enumerator;
internal Enumerator(IUniTaskAsyncEnumerator<T> enumerator)
{
this.enumerator = enumerator;
}
public T Current => enumerator.Current;
public UniTask<bool> MoveNextAsync()
{
return enumerator.MoveNextAsync();
}
public UniTask DisposeAsync()
{
return enumerator.DisposeAsync();
}
}
}
}

View File

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

View File

@@ -0,0 +1,127 @@
#pragma warning disable CS1591
#pragma warning disable CS0108
#if (UNITASK_NETCORE && !NETSTANDARD2_0) || UNITY_2022_3_OR_NEWER
#define SUPPORT_VALUETASK
#endif
using System;
using System.Runtime.CompilerServices;
namespace Cysharp.Threading.Tasks
{
public enum UniTaskStatus
{
/// <summary>The operation has not yet completed.</summary>
Pending = 0,
/// <summary>The operation completed successfully.</summary>
Succeeded = 1,
/// <summary>The operation completed with an error.</summary>
Faulted = 2,
/// <summary>The operation completed due to cancellation.</summary>
Canceled = 3
}
// similar as IValueTaskSource
public interface IUniTaskSource
#if SUPPORT_VALUETASK
: System.Threading.Tasks.Sources.IValueTaskSource
#endif
{
UniTaskStatus GetStatus(short token);
void OnCompleted(Action<object> continuation, object state, short token);
void GetResult(short token);
UniTaskStatus UnsafeGetStatus(); // only for debug use.
#if SUPPORT_VALUETASK
System.Threading.Tasks.Sources.ValueTaskSourceStatus System.Threading.Tasks.Sources.IValueTaskSource.GetStatus(short token)
{
return (System.Threading.Tasks.Sources.ValueTaskSourceStatus)(int)((IUniTaskSource)this).GetStatus(token);
}
void System.Threading.Tasks.Sources.IValueTaskSource.GetResult(short token)
{
((IUniTaskSource)this).GetResult(token);
}
void System.Threading.Tasks.Sources.IValueTaskSource.OnCompleted(Action<object> continuation, object state, short token, System.Threading.Tasks.Sources.ValueTaskSourceOnCompletedFlags flags)
{
// ignore flags, always none.
((IUniTaskSource)this).OnCompleted(continuation, state, token);
}
#endif
}
public interface IUniTaskSource<out T> : IUniTaskSource
#if SUPPORT_VALUETASK
, System.Threading.Tasks.Sources.IValueTaskSource<T>
#endif
{
new T GetResult(short token);
#if SUPPORT_VALUETASK
new public UniTaskStatus GetStatus(short token)
{
return ((IUniTaskSource)this).GetStatus(token);
}
new public void OnCompleted(Action<object> continuation, object state, short token)
{
((IUniTaskSource)this).OnCompleted(continuation, state, token);
}
System.Threading.Tasks.Sources.ValueTaskSourceStatus System.Threading.Tasks.Sources.IValueTaskSource<T>.GetStatus(short token)
{
return (System.Threading.Tasks.Sources.ValueTaskSourceStatus)(int)((IUniTaskSource)this).GetStatus(token);
}
T System.Threading.Tasks.Sources.IValueTaskSource<T>.GetResult(short token)
{
return ((IUniTaskSource<T>)this).GetResult(token);
}
void System.Threading.Tasks.Sources.IValueTaskSource<T>.OnCompleted(Action<object> continuation, object state, short token, System.Threading.Tasks.Sources.ValueTaskSourceOnCompletedFlags flags)
{
// ignore flags, always none.
((IUniTaskSource)this).OnCompleted(continuation, state, token);
}
#endif
}
public static class UniTaskStatusExtensions
{
/// <summary>status != Pending.</summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool IsCompleted(this UniTaskStatus status)
{
return status != UniTaskStatus.Pending;
}
/// <summary>status == Succeeded.</summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool IsCompletedSuccessfully(this UniTaskStatus status)
{
return status == UniTaskStatus.Succeeded;
}
/// <summary>status == Canceled.</summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool IsCanceled(this UniTaskStatus status)
{
return status == UniTaskStatus.Canceled;
}
/// <summary>status == Faulted.</summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool IsFaulted(this UniTaskStatus status)
{
return status == UniTaskStatus.Faulted;
}
}
}

View File

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

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: b27fab7a9e61bf849ac95416967a62c3
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,150 @@
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
using System;
using System.Threading;
namespace Cysharp.Threading.Tasks.Internal
{
// Same interface as System.Buffers.ArrayPool<T> but only provides Shared.
internal sealed class ArrayPool<T>
{
// Same size as System.Buffers.DefaultArrayPool<T>
const int DefaultMaxNumberOfArraysPerBucket = 50;
static readonly T[] EmptyArray = new T[0];
public static readonly ArrayPool<T> Shared = new ArrayPool<T>();
readonly MinimumQueue<T[]>[] buckets;
readonly SpinLock[] locks;
ArrayPool()
{
// see: GetQueueIndex
buckets = new MinimumQueue<T[]>[18];
locks = new SpinLock[18];
for (int i = 0; i < buckets.Length; i++)
{
buckets[i] = new MinimumQueue<T[]>(4);
locks[i] = new SpinLock(false);
}
}
public T[] Rent(int minimumLength)
{
if (minimumLength < 0)
{
throw new ArgumentOutOfRangeException("minimumLength");
}
else if (minimumLength == 0)
{
return EmptyArray;
}
var size = CalculateSize(minimumLength);
var index = GetQueueIndex(size);
if (index != -1)
{
var q = buckets[index];
var lockTaken = false;
try
{
locks[index].Enter(ref lockTaken);
if (q.Count != 0)
{
return q.Dequeue();
}
}
finally
{
if (lockTaken) locks[index].Exit(false);
}
}
return new T[size];
}
public void Return(T[] array, bool clearArray = false)
{
if (array == null || array.Length == 0)
{
return;
}
var index = GetQueueIndex(array.Length);
if (index != -1)
{
if (clearArray)
{
Array.Clear(array, 0, array.Length);
}
var q = buckets[index];
var lockTaken = false;
try
{
locks[index].Enter(ref lockTaken);
if (q.Count > DefaultMaxNumberOfArraysPerBucket)
{
return;
}
q.Enqueue(array);
}
finally
{
if (lockTaken) locks[index].Exit(false);
}
}
}
static int CalculateSize(int size)
{
size--;
size |= size >> 1;
size |= size >> 2;
size |= size >> 4;
size |= size >> 8;
size |= size >> 16;
size += 1;
if (size < 8)
{
size = 8;
}
return size;
}
static int GetQueueIndex(int size)
{
switch (size)
{
case 8: return 0;
case 16: return 1;
case 32: return 2;
case 64: return 3;
case 128: return 4;
case 256: return 5;
case 512: return 6;
case 1024: return 7;
case 2048: return 8;
case 4096: return 9;
case 8192: return 10;
case 16384: return 11;
case 32768: return 12;
case 65536: return 13;
case 131072: return 14;
case 262144: return 15;
case 524288: return 16;
case 1048576: return 17; // max array length
default:
return -1;
}
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: f83ebad81fb89fb4882331616ca6d248
timeCreated: 1532361008
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,115 @@
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
namespace Cysharp.Threading.Tasks.Internal
{
internal static class ArrayPoolUtil
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static void EnsureCapacity<T>(ref T[] array, int index, ArrayPool<T> pool)
{
if (array.Length <= index)
{
EnsureCapacityCore(ref array, index, pool);
}
}
[MethodImpl(MethodImplOptions.NoInlining)]
static void EnsureCapacityCore<T>(ref T[] array, int index, ArrayPool<T> pool)
{
if (array.Length <= index)
{
var newSize = array.Length * 2;
var newArray = pool.Rent((index < newSize) ? newSize : (index * 2));
Array.Copy(array, 0, newArray, 0, array.Length);
pool.Return(array, clearArray: !RuntimeHelpersAbstraction.IsWellKnownNoReferenceContainsType<T>());
array = newArray;
}
}
public static RentArray<T> Materialize<T>(IEnumerable<T> source)
{
if (source is T[] array)
{
return new RentArray<T>(array, array.Length, null);
}
var defaultCount = 32;
if (source is ICollection<T> coll)
{
if (coll.Count == 0)
{
return new RentArray<T>(Array.Empty<T>(), 0, null);
}
defaultCount = coll.Count;
var pool = ArrayPool<T>.Shared;
var buffer = pool.Rent(defaultCount);
coll.CopyTo(buffer, 0);
return new RentArray<T>(buffer, coll.Count, pool);
}
else if (source is IReadOnlyCollection<T> rcoll)
{
defaultCount = rcoll.Count;
}
if (defaultCount == 0)
{
return new RentArray<T>(Array.Empty<T>(), 0, null);
}
{
var pool = ArrayPool<T>.Shared;
var index = 0;
var buffer = pool.Rent(defaultCount);
foreach (var item in source)
{
EnsureCapacity(ref buffer, index, pool);
buffer[index++] = item;
}
return new RentArray<T>(buffer, index, pool);
}
}
public struct RentArray<T> : IDisposable
{
public readonly T[] Array;
public readonly int Length;
ArrayPool<T> pool;
public RentArray(T[] array, int length, ArrayPool<T> pool)
{
this.Array = array;
this.Length = length;
this.pool = pool;
}
public void Dispose()
{
DisposeManually(!RuntimeHelpersAbstraction.IsWellKnownNoReferenceContainsType<T>());
}
public void DisposeManually(bool clearArray)
{
if (pool != null)
{
if (clearArray)
{
System.Array.Clear(Array, 0, Length);
}
pool.Return(Array, clearArray: false);
pool = null;
}
}
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 424cc208fb61d4e448b08fcfa0eee25e
timeCreated: 1532361007
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,73 @@
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
namespace Cysharp.Threading.Tasks.Internal
{
internal static class ArrayUtil
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void EnsureCapacity<T>(ref T[] array, int index)
{
if (array.Length <= index)
{
EnsureCore(ref array, index);
}
}
// rare case, no inlining.
[MethodImpl(MethodImplOptions.NoInlining)]
static void EnsureCore<T>(ref T[] array, int index)
{
var newSize = array.Length * 2;
var newArray = new T[(index < newSize) ? newSize : (index * 2)];
Array.Copy(array, 0, newArray, 0, array.Length);
array = newArray;
}
/// <summary>
/// Optimizing utility to avoid .ToArray() that creates buffer copy(cut to just size).
/// </summary>
public static (T[] array, int length) Materialize<T>(IEnumerable<T> source)
{
if (source is T[] array)
{
return (array, array.Length);
}
var defaultCount = 4;
if (source is ICollection<T> coll)
{
defaultCount = coll.Count;
var buffer = new T[defaultCount];
coll.CopyTo(buffer, 0);
return (buffer, defaultCount);
}
else if (source is IReadOnlyCollection<T> rcoll)
{
defaultCount = rcoll.Count;
}
if (defaultCount == 0)
{
return (Array.Empty<T>(), 0);
}
{
var index = 0;
var buffer = new T[defaultCount];
foreach (var item in source)
{
EnsureCapacity(ref buffer, index);
buffer[index++] = item;
}
return (buffer, index);
}
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 23146a82ec99f2542a87971c8d3d7988
timeCreated: 1532361007
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

Some files were not shown because too many files have changed in this diff Show More