Skip to content

Commit

Permalink
Added initial test demonstrating android support for gestalt-entity-s…
Browse files Browse the repository at this point in the history
…ystem

Removed reflectasm from gestalt-entity-system. Replaced previous usage with default implementations using reflection.
Created new library gestalt-es-perf, which provides higher performance implementations that are not supported under android api < 26.
ComponentManager is now no longer an interface with multiple implementations - instead it is constructed with a ComponentTypeFactory.
EventReceiverMethodSupport is no longer a static class, and is now intended to be instantiated with a EventHandlerFactory.
Changed the use of ThreadLocal in TransactionManager to use functionality available on pre-26 versions of Android
  • Loading branch information
immortius committed Nov 12, 2019
1 parent 001c776 commit 8ea5f49
Show file tree
Hide file tree
Showing 57 changed files with 2,042 additions and 410 deletions.
1 change: 1 addition & 0 deletions gestalt-android-testbed/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ dependencies {
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
implementation project(':gestalt-android')
implementation project(':gestalt-asset-core')
implementation project(":gestalt-entity-system")
implementation 'com.google.guava:guava:27.0.1-android'
implementation 'org.slf4j:slf4j-api:1.7.25'
implementation 'com.github.tony19:logback-android:1.3.0-3'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,17 @@
import org.terasology.assets.ResourceUrn;
import org.terasology.assets.module.ModuleAwareAssetTypeManager;
import org.terasology.assets.module.ModuleAwareAssetTypeManagerImpl;
import org.terasology.entitysystem.component.ReflectionComponentTypeFactory;
import org.terasology.entitysystem.core.EntityManager;
import org.terasology.entitysystem.core.EntityRef;
import org.terasology.entitysystem.entity.inmemory.InMemoryEntityManager;
import org.terasology.entitysystem.transaction.TransactionManager;
import org.terasology.gestalt.android.AndroidModuleClassLoader;
import org.terasology.gestalt.android.testbed.assettypes.Text;
import org.terasology.gestalt.android.testbed.assettypes.TextData;
import org.terasology.gestalt.android.testbed.assettypes.TextFactory;
import org.terasology.gestalt.android.testbed.assettypes.TextFileFormat;
import org.terasology.gestalt.android.testbed.packageModuleA.TextComponent;
import org.terasology.module.Module;
import org.terasology.module.ModuleEnvironment;
import org.terasology.module.ModuleFactory;
Expand Down Expand Up @@ -148,6 +154,19 @@ protected void onCreate(Bundle savedInstanceState) {
});
}
assetTypeManager.disposedUnusedAssets();

TransactionManager transactionManager = new TransactionManager();
EntityManager entityManager = new InMemoryEntityManager(new ReflectionComponentTypeFactory(), transactionManager);
transactionManager.begin();
EntityRef entity = entityManager.createEntity();
TextComponent textComponent = entity.addComponent(TextComponent.class);
textComponent.setText("Hello");
transactionManager.commit();
transactionManager.begin();
displayText.append("\n-== Entity System Test ==-\n");
displayText.append(entity.getComponent(TextComponent.class).get().getText());
transactionManager.rollback();

text.setText(displayText);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* Copyright 2019 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.gestalt.android.testbed.packageModuleA;

import org.terasology.entitysystem.core.Component;

public class TextComponent implements Component {

private boolean dirty;
private String text;

public String getText() {
return text;
}

public void setText(String text) {
this.text = text;
}

@Override
public boolean isDirty() {
return dirty;
}

@Override
public void setDirty(boolean dirty) {
this.dirty = dirty;
}

@Override
public void copy(Component other) {
this.text = ((TextComponent)other).text;
this.dirty = true;
}
}
9 changes: 5 additions & 4 deletions gestalt-android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,18 @@ apply plugin: 'com.android.library'
android {
compileSdkVersion 28



defaultConfig {
minSdkVersion 24
targetSdkVersion 28
versionCode 1
versionName "1.0"

testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"

}

compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
buildTypes {
release {
minifyEnabled false
Expand All @@ -43,6 +43,7 @@ android {
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
api project(':gestalt-module')
implementation project(':gestalt-util')
implementation 'org.slf4j:slf4j-api:1.7.25'

implementation 'com.android.support:appcompat-v7:28.0.0'
Expand Down
1 change: 0 additions & 1 deletion gestalt-entity-system/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ dependencies {
implementation 'com.android.support:support-annotations:28.0.0'
implementation 'net.jcip:jcip-annotations:1.0'
implementation 'net.sf.trove4j:trove4j:3.0.3'
implementation 'com.esotericsoftware:reflectasm:1.11.0'
implementation 'com.google.protobuf:protobuf-java:3.4.0'
implementation 'com.google.code.gson:gson:2.8.5'

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,40 @@

package org.terasology.entitysystem.component;

import com.google.common.collect.Maps;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.terasology.entitysystem.core.Component;

import java.util.Map;

/**
* Manager for components. Provides the ability to create or copy components, or retrieve information on the properties of the component that allows the individual
* properties to be accessed.
*/
public interface ComponentManager {
public class ComponentManager {

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

private ComponentTypeFactory componentTypeFactory;
private Map<Class<?>, ComponentType<?>> componentTypes = Maps.newLinkedHashMap();

/**
* Creates the ComponentManager using the default {@link ComponentTypeFactory} - {@link ReflectionComponentTypeFactory}.
* In environments where it they are available it is recommended to use a high performance replacements from gestalt-es-perf
*/
public ComponentManager() {
this.componentTypeFactory = new ReflectionComponentTypeFactory();
}

/**
* Creates the ComponentManager using the provided componentTypeFactory
* @param componentTypeFactory The ComponentTypeFactory to use to generate ComponentTypes
*/
public ComponentManager(ComponentTypeFactory componentTypeFactory) {
this.componentTypeFactory = componentTypeFactory;
}

/**
* Create an instance of a component of the given type
Expand All @@ -31,7 +58,10 @@ public interface ComponentManager {
* @param <T> The type of the component
* @return A new instance of the component
*/
<T extends Component> T create(Class<T> type);
public <T extends Component> T create(Class<T> type) {
ComponentType<T> typeInfo = getType(type);
return typeInfo.create();
}

/**
* Creates a new instance that is a copy of an existing component instance
Expand All @@ -40,7 +70,10 @@ public interface ComponentManager {
* @param <T> The type of the component
* @return A new instance of the component
*/
<T extends Component> T copy(T instance);
public <T extends Component> T copy(T instance) {
ComponentType<T> typeInfo = getType(instance);
return typeInfo.createCopy(instance);
}

/**
* Provides a ComponentType, allowing for reflection like operations.
Expand All @@ -49,7 +82,15 @@ public interface ComponentManager {
* @param <T> The type of component
* @return The ComponentType for the given type of component.
*/
<T extends Component> ComponentType<T> getType(Class<T> type);
@SuppressWarnings("unchecked")
public <T extends Component> ComponentType<T> getType(Class<T> type) {
ComponentType<T> typeInfo = (ComponentType<T>) componentTypes.get(type);
if (typeInfo == null) {
typeInfo = componentTypeFactory.createComponentType(type);
componentTypes.put(type, typeInfo);
}
return typeInfo;
}

/**
* Provides a ComponentType, allowing for reflection like operations.
Expand All @@ -58,5 +99,8 @@ public interface ComponentManager {
* @param <T> The type of component
* @return The ComponentType for the given type of component.
*/
<T extends Component> ComponentType<T> getType(T instance);
@SuppressWarnings("unchecked")
public <T extends Component> ComponentType<T> getType(T instance) {
return (ComponentType<T>) getType(instance.getClass());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* Copyright 2019 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.component;

import android.support.annotation.NonNull;

import org.terasology.entitysystem.core.Component;

/**
* Interface for generating ComponentTypes from a component class
*/
@FunctionalInterface
public interface ComponentTypeFactory {

/**
* @param type The class of component to generate a ComponentType for
* @param <T> The class of component to generate a ComponentType for
* @return A generated component type
* @throws ComponentTypeGenerationException If there is a problem generating a component type
*/
@NonNull
<T extends Component> ComponentType<T> createComponentType(Class<T> type);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* Copyright 2019 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.component;

/**
* The exception thrown if there is an error generating a component type for a component
*/
public class ComponentTypeGenerationException extends RuntimeException {

public ComponentTypeGenerationException() {
}

public ComponentTypeGenerationException(String message) {
super(message);
}

public ComponentTypeGenerationException(String message, Throwable cause) {
super(message, cause);
}
}
Loading

0 comments on commit 8ea5f49

Please sign in to comment.