public LoadedArea(LoadAreaJob.AreaRequest request)
 {
     _request = request;
 }
    public void GetToken(TokenRequest request, string persistentDataPath, Action <WorldDataToken> onComplete)
    {
        int leftArea   = request.left / _worldIndex.AreaDimensions;
        int rightArea  = (request.right - 1) / _worldIndex.AreaDimensions;
        int topArea    = request.top / _worldIndex.AreaDimensions;
        int bottomArea = (request.bottom - 1) / _worldIndex.AreaDimensions;

        int horizontalAreaCount = (rightArea - leftArea) + 1;
        int verticalAreaCount   = (bottomArea - topArea) + 1;

        LoadedArea[,] jobsResult = new LoadedArea[horizontalAreaCount, verticalAreaCount];
        Dictionary <AreaIndex, string> filepaths = new Dictionary <AreaIndex, string>();

        List <LoadedArea> loadedAreas           = new List <LoadedArea>();
        List <LoadedArea> newLoadedAreaRequests = new List <LoadedArea>();

        for (int i = 0; i < horizontalAreaCount; i++)
        {
            for (int j = 0; j < verticalAreaCount; j++)
            {
                int        areaX      = i + leftArea;
                int        areaY      = j + topArea;
                string     areaKey    = String.Join("_", new string[] { areaX.ToString(), areaY.ToString() });
                LoadedArea loadedArea = null;

                lock (_cache)
                {
                    _cache.TryGetValue(areaKey, out loadedArea);

                    if (loadedArea == null)
                    {
                        LoadAreaJob.AreaRequest loadRequest = new LoadAreaJob.AreaRequest(areaX, areaY);
                        loadedArea = new LoadedArea(loadRequest);
                        newLoadedAreaRequests.Add(loadedArea);
                        _cache.Add(areaKey, loadedArea);
                    }
                }

                loadedAreas.Add(loadedArea);
            }
        }

        LoadAreaJob loadAreaJob = null;

        loadAreaJob = new LoadAreaJob(_worldIndex, _dataConfig, newLoadedAreaRequests, persistentDataPath);
        loadAreaJob.Start();

        loadAreaJob.OnComplete += (job) =>
        {
            loadedAreas.ForEach((loadedArea) =>
            {
                jobsResult[loadedArea.Request.areaX - leftArea, loadedArea.Request.areaY - topArea] = loadedArea;
            });

            WorldDataToken token = new WorldDataToken(request, _worldIndex, jobsResult);
            onComplete(token);
        };

        //wait until all areas loaded

        /*while (loadedAreas.Find((loadedArea) => loadedArea.Result == null) != null)
         * {
         *  Thread.Sleep(10);
         * }*/

        //_loadJobPool.Add(loadAreaJob);
    }