Несколько тяжелых методов подряд в UniRx
Делаю загрузку мира. Есть несколько тяжелых методов для каждой стадии загрузки. Пытаюсь сделать их последовательно в другом потоке, при этом после каждого переключая надпись в загрузочном экране. Но, пока что, сделал какой-то костыль, и, мне кажется, что оно задействует так не два, а больше потоков:
/// PLAYGROUND GENERATION
LoadScreenHandler.SetProgressText(LoadScreenHandler.LoadingProgressType.WorldGeneration);
disposable = Observable.WhenAll(Observable.Start(() =>
{
Playground.Initialize_Stage0(CurrentWorldData.RegionsSizes, GridGenerator.GenType.Lake);
})).ObserveOnMainThread().Subscribe(result =>
{
/// TERRAIN INIT
LoadScreenHandler.SetProgressText(LoadScreenHandler.LoadingProgressType.TerrainInit);
disposable = Observable.WhenAll(Observable.Start(() =>
{
Playground.Initialize_Stage1();
})).ObserveOnMainThread().Subscribe(result =>
{
/// TEXTURING
LoadScreenHandler.SetProgressText(LoadScreenHandler.LoadingProgressType.Texturing);
disposable = Observable.WhenAll(Observable.Start(() =>
{
Playground.Initialize_Stage2();
})).ObserveOnMainThread().Subscribe(result =>
{
/// VILLAGE GENERATION
LoadScreenHandler.SetProgressText(LoadScreenHandler.LoadingProgressType.VillageInit);
CharacterNew.InstData[] charactersData = null;
disposable = Observable.WhenAll(Observable.Start(() =>
{
Playground.Initialize_Stage3();
charactersData = CurrentLoadType != LoadType.FromLoadedSave ?
Playground.CharactersGenerate() : SavesHandler.CurrentSubsave.CharactersData;
})).ObserveOnMainThread().Subscribe(result =>
{
/// GROUND RES GENERATION
GroundRes.InstData[,] groundResData = null;
LoadScreenHandler.SetProgressText(LoadScreenHandler.LoadingProgressType.GroundResGen);
disposable = Observable.WhenAll(Observable.Start(() =>
{
groundResData = CurrentLoadType != LoadType.FromLoadedSave ?
GridGenerator.GenerateGroundRes() : SavesHandler.CurrentSubsave.GroundResData;
})).ObserveOnMainThread().Subscribe(result =>
{
/// INSTANTIATING
LinksHandler.inst.camh.Teleport(Playground.VillageStartPos);
Playground.Mesh_Instantiate();
Playground.Water_Instantiate();
BarrierHandler.Initialize();
Playground.GroundRes_Instantiate(groundResData);
Playground.Village_Instantiate();
Playground.Characters_Instantiate(charactersData);
});
});
});
});
});
И вот ещё, чтобы, если загрузка прерывается посредине, то не сломать:
private void OnApplicationQuit()
{
if (disposable != null && !_isPlaygroundGenerated)
{
disposable.Dispose();
Debug.Log("<color=red>Threads terminated.</color>");
}
}
Как правильно это написать, чтобы было нормально, по порядку?
ps: Хотелось бы чтобы оно выполнялось в одном не основном потоке, последовательно друг за другом, и в промежутках после выполнения каждой стадии, можно было выполнять что то в основном потоке (в данном случае смена надписи на лоадскрине, но есть и другие нужды)
Ответы (1 шт):
Пока что придумал вот такое решение тестовое. Кажется мне что это все равно костыли какие-то, но работает как мне надо.
private void Test8()
{
var heavyMethod1 = Observable.Start(() =>
{
var timeToSleep = 1000;
var returnedValue = 10;
Debug.Log(string.Format("<color=magenta>1 Thread = {0} UtcNow = {1}</color>", Thread.CurrentThread.ManagedThreadId, System.DateTime.UtcNow));
Thread.Sleep(timeToSleep);
return returnedValue;
});
var heavyMethod2 = Observable.Start(() =>
{
var timeToSleep = 2000;
var returnedValue = 20;
Debug.Log(string.Format("<color=magenta>2 Thread = {0} UtcNow = {1}</color>", Thread.CurrentThread.ManagedThreadId, System.DateTime.UtcNow));
Thread.Sleep(timeToSleep);
return returnedValue;
});
Part0();
void Part0()
{
var observale = Observable.Zip(heavyMethod1)
.ObserveOnMainThread().Subscribe(result =>
{
Debug.Log("<color=magenta>Part0 complete</color>");
Part1();
});
}
void Part1()
{
var observale = Observable.Zip(heavyMethod2)
.ObserveOnMainThread().Subscribe(result =>
{
Debug.Log("<color=magenta>Part1 complete</color>");
Part2();
});
}
void Part2()
{
var observale = Observable.Zip(heavyMethod1)
.ObserveOnMainThread().Subscribe(result =>
{
Debug.Log("<color=magenta>Part2 complete</color>");
OnComplete();
});
}
void OnComplete()
{
Debug.Log("<color=magenta>All complete</color>");
}
}