Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Sectors/pools: v2.0.0 branch #3009

Merged
merged 11 commits into from
Jul 21, 2017
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
/*
* Copyright 2017 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.entitySystem;

import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.terasology.assets.AssetFactory;
import org.terasology.assets.management.AssetManager;
import org.terasology.assets.module.ModuleAwareAssetTypeManager;
import org.terasology.context.Context;
import org.terasology.context.internal.ContextImpl;
import org.terasology.engine.bootstrap.EntitySystemSetupUtil;
import org.terasology.engine.module.ModuleManager;
import org.terasology.entitySystem.entity.EntityManager;
import org.terasology.entitySystem.entity.EntityRef;
import org.terasology.entitySystem.entity.internal.PojoEntityManager;
import org.terasology.entitySystem.prefab.Prefab;
import org.terasology.entitySystem.prefab.PrefabData;
import org.terasology.entitySystem.prefab.internal.PojoPrefab;
import org.terasology.network.NetworkSystem;
import org.terasology.registry.CoreRegistry;
import org.terasology.testUtil.ModuleManagerFactory;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import static org.terasology.entitySystem.entity.internal.EntityScope.GLOBAL;
import static org.terasology.entitySystem.entity.internal.EntityScope.SECTOR;

public class BaseEntityRefTest {

private static Context context;
private PojoEntityManager entityManager;
private EntityRef ref;

@BeforeClass
public static void setupClass() throws Exception {
context = new ContextImpl();
ModuleManager moduleManager = ModuleManagerFactory.create();
context.put(ModuleManager.class, moduleManager);
ModuleAwareAssetTypeManager assetTypeManager = new ModuleAwareAssetTypeManager();
assetTypeManager.registerCoreAssetType(Prefab.class,
(AssetFactory<Prefab, PrefabData>) PojoPrefab::new, "prefabs");
assetTypeManager.switchEnvironment(moduleManager.getEnvironment());
context.put(AssetManager.class, assetTypeManager.getAssetManager());
CoreRegistry.setContext(context);
}

@Before
public void setup() {
context.put(NetworkSystem.class, mock(NetworkSystem.class));
EntitySystemSetupUtil.addReflectionBasedLibraries(context);
EntitySystemSetupUtil.addEntityManagementRelatedClasses(context);
entityManager = (PojoEntityManager) context.get(EntityManager.class);

ref = entityManager.create();
}

@Test
public void testSetScope() {
assertEquals(ref.getScope(), GLOBAL);
assertTrue(entityManager.getGlobalPool().contains(ref.getId()));
assertFalse(entityManager.getSectorManager().contains(ref.getId()));

//Move into sector scope
ref.setScope(SECTOR);
assertEquals(ref.getScope(), SECTOR);
assertTrue(entityManager.getSectorManager().contains(ref.getId()));
assertFalse(entityManager.getGlobalPool().contains(ref.getId()));

//And move back to global scope
ref.setScope(GLOBAL);
assertEquals(ref.getScope(), GLOBAL);
assertTrue(entityManager.getGlobalPool().contains(ref.getId()));
assertFalse(entityManager.getSectorManager().contains(ref.getId()));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import org.terasology.entitySystem.entity.EntityManager;
import org.terasology.entitySystem.entity.EntityRef;
import org.terasology.entitySystem.entity.internal.PojoEntityManager;
import org.terasology.entitySystem.entity.internal.PojoEntityPool;
import org.terasology.entitySystem.entity.lifecycleEvents.BeforeDeactivateComponent;
import org.terasology.entitySystem.entity.lifecycleEvents.BeforeRemoveComponent;
import org.terasology.entitySystem.entity.lifecycleEvents.OnActivatedComponent;
Expand Down Expand Up @@ -59,6 +60,7 @@
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.terasology.entitySystem.entity.internal.EntityScope.GLOBAL;

/**
*/
Expand Down Expand Up @@ -97,6 +99,7 @@ public void setup() {
public void testCreateEntity() {
EntityRef entity = entityManager.create();
assertNotNull(entity);
assertEquals(entity.getScope(), GLOBAL);
}

@Test
Expand Down Expand Up @@ -382,4 +385,24 @@ public void testDestructionOfUnloadedEntitiesPrevented() {
entity.destroy();
assertTrue(entity.exists());
}

@Test
public void testMoveToPool() {
EntityRef entity = entityManager.create();
long id = entity.getId();

PojoEntityPool pool1 = new PojoEntityPool(entityManager);
PojoEntityPool pool2 = new PojoEntityPool(entityManager);

assertFalse(pool1.contains(id));
assertFalse(pool2.contains(id));

assertTrue(entityManager.moveToPool(id, pool1));
assertTrue(pool1.contains(id));
assertFalse(pool2.contains(id));

assertTrue(entityManager.moveToPool(id, pool2));
assertTrue(pool2.contains(id));
assertFalse(pool1.contains(id));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
/*
* Copyright 2017 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.entitySystem;

import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.terasology.assets.AssetFactory;
import org.terasology.assets.management.AssetManager;
import org.terasology.assets.module.ModuleAwareAssetTypeManager;
import org.terasology.context.Context;
import org.terasology.context.internal.ContextImpl;
import org.terasology.engine.bootstrap.EntitySystemSetupUtil;
import org.terasology.engine.module.ModuleManager;
import org.terasology.entitySystem.entity.EntityManager;
import org.terasology.entitySystem.entity.EntityRef;
import org.terasology.entitySystem.entity.internal.PojoEntityManager;
import org.terasology.entitySystem.entity.internal.PojoEntityPool;
import org.terasology.entitySystem.prefab.Prefab;
import org.terasology.entitySystem.prefab.PrefabData;
import org.terasology.entitySystem.prefab.internal.PojoPrefab;
import org.terasology.network.NetworkSystem;
import org.terasology.registry.CoreRegistry;
import org.terasology.testUtil.ModuleManagerFactory;

import static junit.framework.TestCase.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;

/**
*/
public class PojoEntityPoolTest {

private PojoEntityPool pool;
private static Context context;
private PojoEntityManager entityManager;

@BeforeClass
public static void setupClass() throws Exception {
context = new ContextImpl();
ModuleManager moduleManager = ModuleManagerFactory.create();
context.put(ModuleManager.class, moduleManager);
ModuleAwareAssetTypeManager assetTypeManager = new ModuleAwareAssetTypeManager();
assetTypeManager.registerCoreAssetType(Prefab.class,
(AssetFactory<Prefab, PrefabData>) PojoPrefab::new, "prefabs");
assetTypeManager.switchEnvironment(moduleManager.getEnvironment());
context.put(AssetManager.class, assetTypeManager.getAssetManager());
CoreRegistry.setContext(context);
}

@Before
public void setup() {
context.put(NetworkSystem.class, mock(NetworkSystem.class));
EntitySystemSetupUtil.addReflectionBasedLibraries(context);
EntitySystemSetupUtil.addEntityManagementRelatedClasses(context);
entityManager = (PojoEntityManager) context.get(EntityManager.class);

pool = new PojoEntityPool(entityManager);
}


@Test
public void testContains() {
assertFalse(pool.contains(PojoEntityManager.NULL_ID));
assertFalse(pool.contains(1000000));
EntityRef ref = pool.create();
assertTrue(pool.contains(ref.getId()));
}

@Test
public void testRemove() {
EntityRef ref = pool.create();
assertTrue(pool.contains(ref.getId()));

pool.remove(ref.getId());
assertFalse(pool.contains(ref.getId()));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,14 @@
package org.terasology.entitySystem.entity;

import com.google.common.collect.Maps;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.terasology.entitySystem.Component;
import org.terasology.entitySystem.MutableComponentContainer;
import org.terasology.entitySystem.entity.internal.EngineEntityManager;
import org.terasology.entitySystem.entity.internal.EntityInfoComponent;
import org.terasology.entitySystem.entity.internal.EntityScope;
import org.terasology.entitySystem.prefab.Prefab;

import java.util.Map;

Expand All @@ -30,11 +34,60 @@
*/
public class EntityBuilder implements MutableComponentContainer {


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

private Map<Class<? extends Component>, Component> components = Maps.newHashMap();
private EngineEntityManager manager;
private EntityPool pool;
private EngineEntityManager entityManager;

private boolean sendLifecycleEvents = true;
private EntityScope scope;

public EntityBuilder(EngineEntityManager entityManager) {
this.entityManager = entityManager;
this.pool = entityManager.getGlobalPool();
}

public EntityBuilder(EngineEntityManager entityManager, EntityPool pool) {
this.entityManager = entityManager;
this.pool = pool;
}

public EntityBuilder(EngineEntityManager manager) {
this.manager = manager;
/**
* Adds all of the components from a prefab to this builder
*
* @param prefabName the name of the prefab to add
* @return whether the prefab was successfully added
*/
public boolean addPrefab(String prefabName) {
if (prefabName != null && !prefabName.isEmpty()) {
Prefab prefab = entityManager.getPrefabManager().getPrefab(prefabName);
if (prefab == null) {
logger.warn("Unable to instantiate unknown prefab: \"{}\"", prefabName);
return false;
}
addPrefab(prefab);
return true;
} else {
return false;
}
}
/**
* Adds all of the components from a prefab to this builder
*
* @param prefab the prefab to add
* @return whether the prefab was successfully added
*/
public void addPrefab(Prefab prefab) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this method also have return type boolean like the one above? At least the Javadoc suggests so and it would be consistent with the API.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I just copied the Javadoc without properly checking it.

It currently doesn't have anywhere it can fail, though I guess passing a null prefab might cause it to return false. The addPrefab(String) one only fails because a non-null string can fail to return a prefab (though, looking at it again, it will fail and not add an EntityInfoComponent on a nulll string, so changing one of them would make them consistent).

Currently adding a null prefab is fine, and is used to create an entity when you want to add a location, but not a prefab.

if (prefab != null) {
for (Component component : prefab.iterateComponents()) {
addComponent(entityManager.getComponentLibrary().copy(component));
}
addComponent(new EntityInfoComponent(prefab, prefab.isPersisted(), prefab.isAlwaysRelevant()));
} else {
addComponent(new EntityInfoComponent());
}
}

/**
Expand All @@ -43,11 +96,19 @@ public EntityBuilder(EngineEntityManager manager) {
* @return The built entity.
*/
public EntityRef build() {
return manager.create(components.values());
EntityRef entity = pool.create(components.values(), sendLifecycleEvents);
if (scope != null) {
entity.setScope(scope);
}
return entity;
}

public EntityRef buildWithoutLifecycleEvents() {
return manager.createEntityWithoutLifecycleEvents(components.values());
EntityRef entity = pool.create(components.values(), false);
if (scope != null) {
entity.setScope(scope);
}
return entity;
}

@Override
Expand Down Expand Up @@ -97,6 +158,14 @@ public void setAlwaysRelevant(boolean alwaysRelevant) {
getEntityInfo().alwaysRelevant = alwaysRelevant;
}

public void setScope(EntityScope scope) {
this.scope = scope;
}

public EntityScope getScope() {
return scope;
}

public void setOwner(EntityRef owner) {
getEntityInfo().owner = owner;
}
Expand All @@ -113,4 +182,12 @@ private EntityInfoComponent getEntityInfo() {
return entityInfo;
}

public boolean willSendLifecycleEvents() {
return sendLifecycleEvents;
}

public void setSendLifecycleEvents(boolean sendLifecycleEvents) {
this.sendLifecycleEvents = sendLifecycleEvents;
}

}
Loading