Commit 474e1ec2 authored by Nico Mack's avatar Nico Mack

Further generalized the Interaction/Delegate pattern by introducing the

Doable annotation.
parent 125b8855
ABOUT_NODE=about
ACTION_ATTRIBUTE=action
ACTIVATE_WITH_HANDLE_NODE=activateWithHandle
ALPHA_NODE=alpha
ANIMATED_PROPERTIES_ELEMENT=animatedProperties
......@@ -50,6 +49,7 @@ DESELECTED_ELEMENT=deselected
DISPLAY_NAME_NODE=displayName
DISPLAY_TIME_NODE=displayTime
DISTANCE_NODE=distance
DO_ATTRIBUTE=do
DRAGGABLE_NODE=draggable
DRAW_BORDER_NODE=drawBorder
DRAW_PRIORITY_NODE=drawPriority
......@@ -129,6 +129,7 @@ NAMESPACE_SEPARATOR=.
NETWORK_ADAPTER_NODE=networkAdapter
OBJECT_NODE=object
OBJECTS_NODE=objects
ON_ATTRIBUTE=on
OPACITY_NODE=opacity
ORIGIN_NODE=origin
ORIGIN_OFFSET_NODE=originOffset
......
UNDEFINED=undefined
ON_DROP=onDrop
ON_TRANSLATE_BEGIN=onTranslateBegin
ON_TRANSLATE_END=onTranslateEnd
ON_ROTATE_BEGIN=onRotateBegin
ON_ROTATE_END=onRotateEnd
ON_LIFT=onLift
ON_DROP=drop
ON_TRANSLATE_BEGIN=translateBegin
ON_TRANSLATE_END=translateEnd
ON_ROTATE_BEGIN=rotateBegin
ON_ROTATE_END=rotateEnd
ON_LIFT=lift
ON_TOUCHED=onTouched
ON_DRAG_BEGIN=onDragBegin
ON_DRAG_END=onDragEnd
ON_RELEASED=onReleased
ON_TOUCHED=touched
ON_DRAG_BEGIN=dragBegin
ON_DRAG_END=dragEnd
ON_RELEASED=released
ON_TETHER_ESTABLISHED=onTetherEstablished
ON_TETHER_TORN_DOWN=onTetherTornDown
\ No newline at end of file
ON_TETHER_ESTABLISHED=tetherEstablished
ON_TETHER_TORN_DOWN=tetherTornDown
\ No newline at end of file
......@@ -70,7 +70,7 @@ public abstract class BaseInteractionBuilder<B extends BaseInteractionBuilder<B>
// ---------------------------------------------------------------------------
private void buildFromBootstrap(@Nullable Element rootElement, BootstrapContext context, BootstrapCallback callback) throws BuildException {
action = BootstrappingUtils.getAttributeAsString(rootElement, Externalization.ACTION_ATTRIBUTE, BootstrappingUtils.OPTIONAL, Signature.UNDEFINED);;
action = BootstrappingUtils.getAttributeAsString(rootElement, Externalization.ON_ATTRIBUTE, BootstrappingUtils.OPTIONAL, Signature.UNDEFINED);;
}
// ---------------------------------------------------------------------------
......
......@@ -24,7 +24,9 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.lang.reflect.Method;
import java.net.URL;
import java.util.Map;
import javax.media.Controller;
import javax.media.Format;
......@@ -49,6 +51,7 @@ import javax.media.format.AudioFormat;
public class AudioDelegate extends MediaDelegate implements Playable {
private Player player;
private Map<String, Method> doableMethods;
// ***************************************************************************
// * Constants *
......@@ -90,6 +93,9 @@ public class AudioDelegate extends MediaDelegate implements Playable {
// ---------------------------------------------------------------------------
private void setupFromProperties() {
doableMethods = Delegate.getDoableMethods(AudioDelegate.class);
StringBuilder urlBuilder = new StringBuilder(this.baseUrl.toString());
urlBuilder.append(this.media);
try {
......@@ -107,25 +113,34 @@ public class AudioDelegate extends MediaDelegate implements Playable {
// ***************************************************************************
// * Class Body *
// ***************************************************************************
// ---------------------------------------------------------------------------
@Override
public boolean handle(Interaction action) {
Runnable play = () -> {
play();
};
if (doableMethods.containsKey(this.doable)) {
Runnable doIt = () -> {
Delegate.invokeDoableMethod(doableMethods.get(this.doable), this, null);
};
Thread playThread = new Thread(play);
playThread.start();
Thread playThread = new Thread(doIt);
playThread.start();
return true;
return true;
}
LOGGER.warn("Don't know how to do {}!", this.doable); //$NON-NLS-1$
return false;
}
// ---------------------------------------------------------------------------
/** {@inheritDoc} */
// ---------------------------------------------------------------------------
@Doable(identifier = "play")
@Override
public void play() {
if (this.player != null) {
this.player.setMediaTime(BEGIN);
......@@ -137,7 +152,9 @@ public class AudioDelegate extends MediaDelegate implements Playable {
/** {@inheritDoc} */
// ---------------------------------------------------------------------------
@Doable(identifier = "pause")
@Override
public void pause() {
if ((this.player != null) && (player.getState() == Controller.Started)) {
this.player.stop();
......@@ -148,7 +165,9 @@ public class AudioDelegate extends MediaDelegate implements Playable {
/** {@inheritDoc} */
// ---------------------------------------------------------------------------
@Doable(identifier = "stop")
@Override
public void stop() {
if ((this.player != null) && (player.getState() == Controller.Started)) {
this.player.stop();
......@@ -156,4 +175,10 @@ public class AudioDelegate extends MediaDelegate implements Playable {
}
}
// ---------------------------------------------------------------------------
// ***************************************************************************
// * End of Class *
// ***************************************************************************
// ---------------------------------------------------------------------------
}
\ No newline at end of file
......@@ -19,6 +19,14 @@ package lu.list.itis.dkd.tui.event.interaction.delegate;
import lu.list.itis.dkd.tui.event.interaction.Handler;
import lu.list.itis.dkd.tui.event.interaction.delegate.builder.BaseDelegateBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
/**
* @author Nico Mack [nico.mack@list.lu]
* @since 2.5
......@@ -31,6 +39,13 @@ import lu.list.itis.dkd.tui.event.interaction.delegate.builder.BaseDelegateBuild
public abstract class Delegate implements Handler<Delegate> {
protected String name;
protected String doable;
// ***************************************************************************
// * Constants *
// ***************************************************************************
private static final Logger LOGGER = LoggerFactory.getLogger(Delegate.class.getSimpleName());
// ---------------------------------------------------------------------------
// ***************************************************************************
......@@ -44,6 +59,7 @@ public abstract class Delegate implements Handler<Delegate> {
public Delegate(BaseDelegateBuilder<?> builder) {
this.name = builder.name;
this.doable = builder.doable;
}
// ---------------------------------------------------------------------------
......@@ -54,6 +70,42 @@ public abstract class Delegate implements Handler<Delegate> {
public Delegate(Delegate original) {
this.name = original.name;
this.doable = original.doable;
}
// ---------------------------------------------------------------------------
// ***************************************************************************
// * Primitive(s) *
// ***************************************************************************
// ---------------------------------------------------------------------------
protected static Map<String, Method> getDoableMethods(Class<?> clazz) {
Map<String, Method> doables = new HashMap<>();
try {
for (Method method : clazz.getDeclaredMethods()) {
Doable doable = method.getAnnotation(Doable.class);
if (doable != null) {
String identifier = doable.identifier();
doables.put(identifier, method);
}
}
} catch (Exception e) {
LOGGER.error("Failed to lookup doable methods for class {}!", clazz.getSimpleName()); //$NON-NLS-1$
}
return doables;
}
// ---------------------------------------------------------------------------
protected static Object invokeDoableMethod(Method method, Delegate delegate, Object[] parameters) {
Object result = null;
try {
result = method.invoke(delegate, parameters);
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
LOGGER.error("Failed to invoke method {} on Delegate {}!", method.getName(), delegate.getClass(), e); //$NON-NLS-1$
}
return result;
}
// ---------------------------------------------------------------------------
......@@ -69,6 +121,9 @@ public abstract class Delegate implements Handler<Delegate> {
throw new NullPointerException();
String clazzName = this.getClass().getName();
int comparison = clazzName.compareTo(delegate.getClass().getName());
if (comparison == 0) {
comparison = this.doable.compareTo(delegate.doable);
}
if (comparison == 0) {
comparison = this.name.compareTo(delegate.name);
}
......
/**
* Copyright Luxembourg Institute of Science and Technology, 2018. All rights reserved.
*
* This file is part of TULIP.
*
* TULIP is free software: you can redistribute it and/or modify it under the terms of the GNU
* Lesser General Public License as published by the Free Software Foundation, version 3 of the
* License.
*
* TULIP is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
* General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with TULIP. If
* not, see <http://www.gnu.org/licenses/lgpl-3.0.html>.
*/
package lu.list.itis.dkd.tui.event.interaction.delegate;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
@Retention(RUNTIME)
@Target(METHOD)
/**
* @author mack
* @since [major].[minor]
* @version [major].[minor].[micro]
*/
public @interface Doable {
String identifier() default "";
}
......@@ -26,6 +26,7 @@ import org.jdom2.Element;
public abstract class BaseDelegateBuilder<B extends BaseDelegateBuilder<B>> {
/** The name that will be given to the delegate. */
public String name;
public String doable;
// ---------------------------------------------------------------------------
// ***************************************************************************
......@@ -36,6 +37,7 @@ public abstract class BaseDelegateBuilder<B extends BaseDelegateBuilder<B>> {
/** Constructor initialising the fields. */
public BaseDelegateBuilder() {
name = Externalization.EMPTY_STRING;
doable = Externalization.EMPTY_STRING;
}
// ---------------------------------------------------------------------------
......@@ -69,6 +71,7 @@ public abstract class BaseDelegateBuilder<B extends BaseDelegateBuilder<B>> {
// ---------------------------------------------------------------------------
private void buildFromBootstrap(@Nullable Element rootElement, BootstrapContext context, BootstrapCallback callback) throws BuildException {
doable = BootstrappingUtils.getAttributeAsString(rootElement, Externalization.DO_ATTRIBUTE, BootstrappingUtils.MANDATORY, null);
name = BootstrappingUtils.getContentAsString(rootElement, Externalization.NAME_NODE, BootstrappingUtils.OPTIONAL, Externalization.EMPTY_STRING, context);
}
......
......@@ -34,7 +34,6 @@ public class Externalization extends NLS {
private static final String BUNDLE_NAME = "externalization"; //$NON-NLS-1$
public static String ABOUT_NODE;
public static String ACTION_ATTRIBUTE;
public static String ACTIVATE_WITH_HANDLE_NODE;
public static String ALPHA_NODE;
public static String ANIMATED_PROPERTIES_ELEMENT;
......@@ -85,6 +84,7 @@ public class Externalization extends NLS {
public static String DISPLAY_NAME_NODE;
public static String DISPLAY_TIME_NODE;
public static String DISTANCE_NODE;
public static String DO_ATTRIBUTE;
public static String DRAGGABLE_NODE;
public static String DRAW_BORDER_NODE;
public static String DRAW_PRIORITY_NODE;
......@@ -165,6 +165,7 @@ public class Externalization extends NLS {
public static String OBJECT_NODE;
public static String OBJECTS_NODE;
public static String OPACITY_NODE;
public static String ON_ATTRIBUTE;
public static String ORIGIN_NODE;
public static String ORIGIN_OFFSET_NODE;
public static String OUTER_RADIUS_NODE;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment