Package org.terasology.persistence.internal

Source Code of org.terasology.persistence.internal.GlobalStoreLoader

/*
* Copyright 2013 MovingBlocks
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.terasology.persistence.internal;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import gnu.trove.set.TIntSet;
import gnu.trove.set.hash.TIntHashSet;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.terasology.asset.AssetType;
import org.terasology.asset.AssetUri;
import org.terasology.asset.Assets;
import org.terasology.engine.SimpleUri;
import org.terasology.entitySystem.Component;
import org.terasology.entitySystem.entity.internal.EngineEntityManager;
import org.terasology.entitySystem.metadata.ComponentLibrary;
import org.terasology.entitySystem.metadata.ComponentMetadata;
import org.terasology.entitySystem.prefab.Prefab;
import org.terasology.entitySystem.prefab.PrefabData;
import org.terasology.entitySystem.prefab.PrefabManager;
import org.terasology.math.Vector3i;
import org.terasology.module.Module;
import org.terasology.module.ModuleEnvironment;
import org.terasology.persistence.ModuleContext;
import org.terasology.persistence.serializers.EntitySerializer;
import org.terasology.persistence.serializers.PrefabSerializer;
import org.terasology.protobuf.EntityData;

import java.util.List;
import java.util.Map;

/**
* @author Immortius
*/
final class GlobalStoreLoader {

    private static final Logger logger = LoggerFactory.getLogger(GlobalStoreLoader.class);

    private ModuleEnvironment environment;
    private EngineEntityManager entityManager;
    private PrefabManager prefabManager;
    private ComponentLibrary componentLibrary;
    private EntitySerializer entitySerializer;
    private PrefabSerializer prefabSerializer;
    private List<StoreMetadata> refTables;

    public GlobalStoreLoader(ModuleEnvironment environment, EngineEntityManager entityManager, PrefabSerializer prefabSerializer) {
        this.entityManager = entityManager;
        this.prefabManager = entityManager.getPrefabManager();
        this.environment = environment;
        this.componentLibrary = entityManager.getComponentLibrary();
        this.entitySerializer = new EntitySerializer(entityManager);
        this.prefabSerializer = prefabSerializer;
    }

    public void load(EntityData.GlobalStore globalStore) {
        entityManager.clear();
        entityManager.setNextId(globalStore.getNextEntityId());
        entityManager.getFreedIds().addAll(globalStore.getFreedEntityIdList());

        loadComponentMapping(globalStore);
        loadMissingPrefabs(globalStore);

        for (EntityData.Entity entityData : globalStore.getEntityList()) {
            entitySerializer.deserialize(entityData);
        }

        refTables = Lists.newArrayListWithCapacity(globalStore.getStoreReferenceSetCount());
        for (EntityData.EntityStoreMetadata metadataData : globalStore.getStoreReferenceSetList()) {
            TIntSet refs = new TIntHashSet(metadataData.getReferenceList());
            StoreId id;
            switch (metadataData.getType()) {
                case ChunkStoreType:
                    id = new ChunkStoreId(new Vector3i(metadataData.getStoreIntegerId(0), metadataData.getStoreIntegerId(1), metadataData.getStoreIntegerId(2)));
                    break;
                default:
                    id = new PlayerStoreId(metadataData.getStoreStringId());
                    break;

            }
            StoreMetadata metadata = new StoreMetadata(id, refs);
            refTables.add(metadata);
        }
    }

    public List<StoreMetadata> getStoreMetadata() {
        return refTables;
    }

    private void loadMissingPrefabs(EntityData.GlobalStore globalStore) {
        // Prefabs that still need to be created, by their name
        Map<String, EntityData.Prefab> pendingPrefabs = Maps.newHashMap();
        for (EntityData.Prefab prefabData : globalStore.getPrefabList()) {
            if (!prefabManager.exists(prefabData.getName())) {
                if (!prefabData.hasParentName()) {
                    Module module = environment.get(new SimpleUri(prefabData.getName()).getModuleName());
                    try (ModuleContext.ContextSpan ignored = ModuleContext.setContext(module)) {
                        createPrefab(prefabData);
                    } catch (Exception e) {
                        logger.error("Failed to load prefab {}", prefabData.getName(), e);
                    }
                } else {
                    pendingPrefabs.put(prefabData.getName(), prefabData);
                }
            }
        }

        for (EntityData.Prefab prefabData : pendingPrefabs.values()) {
            loadPrefab(prefabData, pendingPrefabs);
        }
    }

    private Prefab loadPrefab(EntityData.Prefab prefabData, Map<String, EntityData.Prefab> pendingPrefabs) {
        Prefab result = Assets.getPrefab(prefabData.getName());
        if (result == null) {
            if (prefabData.hasParentName() && pendingPrefabs.containsKey(prefabData.getParentName())) {
                loadPrefab(pendingPrefabs.get(prefabData.getParentName()), pendingPrefabs);
            }
            Module module = environment.get(new SimpleUri(prefabData.getName()).getModuleName());
            try (ModuleContext.ContextSpan ignored = ModuleContext.setContext(module)) {
                result = createPrefab(prefabData);
            } catch (Exception e) {
                logger.error("Failed to load prefab {}", prefabData.getParentName(), e);
            }
        }
        return result;
    }

    private Prefab createPrefab(EntityData.Prefab prefabData) {
        PrefabData protoPrefab = prefabSerializer.deserialize(prefabData);
        Prefab prefab = Assets.generateAsset(new AssetUri(AssetType.PREFAB, prefabData.getName()), protoPrefab, Prefab.class);
        return prefab;
    }

    private void loadComponentMapping(EntityData.GlobalStore globalStore) {
        Map<Class<? extends Component>, Integer> componentIdTable = Maps.newHashMap();
        for (int index = 0; index < globalStore.getComponentClassCount(); ++index) {
            ComponentMetadata<?> componentMetadata = componentLibrary.resolve(globalStore.getComponentClass(index));
            if (componentMetadata != null) {
                componentIdTable.put(componentMetadata.getType(), index);
            } else {
                logger.warn("Unable to resolve component '{}'", globalStore.getComponentClass(index));
            }
        }

        prefabSerializer.setComponentIdMapping(componentIdTable);
        entitySerializer.setComponentIdMapping(componentIdTable);
    }
}
TOP

Related Classes of org.terasology.persistence.internal.GlobalStoreLoader

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.