diff --git a/app/src/main/java/com/annimon/hotarufx/bundles/Bundle.java b/app/src/main/java/com/annimon/hotarufx/bundles/Bundle.java new file mode 100644 index 0000000..be5f5da --- /dev/null +++ b/app/src/main/java/com/annimon/hotarufx/bundles/Bundle.java @@ -0,0 +1,8 @@ +package com.annimon.hotarufx.bundles; + +import com.annimon.hotarufx.lib.Context; + +public interface Bundle { + + void load(Context context); +} diff --git a/app/src/main/java/com/annimon/hotarufx/bundles/BundleLoader.java b/app/src/main/java/com/annimon/hotarufx/bundles/BundleLoader.java new file mode 100644 index 0000000..ed0d9f4 --- /dev/null +++ b/app/src/main/java/com/annimon/hotarufx/bundles/BundleLoader.java @@ -0,0 +1,26 @@ +package com.annimon.hotarufx.bundles; + +import com.annimon.hotarufx.lib.Context; +import java.util.Collections; +import java.util.List; +import lombok.val; + +public final class BundleLoader { + + public static void loadSingle(Context context, Class clazz) { + load(context, Collections.singletonList(clazz)); + } + + public static void load(Context context, List> bundles) { + if (bundles == null || bundles.isEmpty()) { + return; + } + + for (Class clazz : bundles) { + try { + val bundle = clazz.newInstance(); + bundle.load(context); + } catch (IllegalAccessException | InstantiationException ignore) {} + } + } +} diff --git a/app/src/main/java/com/annimon/hotarufx/bundles/CompositionBundle.java b/app/src/main/java/com/annimon/hotarufx/bundles/CompositionBundle.java new file mode 100644 index 0000000..cd28c89 --- /dev/null +++ b/app/src/main/java/com/annimon/hotarufx/bundles/CompositionBundle.java @@ -0,0 +1,48 @@ +package com.annimon.hotarufx.bundles; + +import com.annimon.hotarufx.lib.Context; +import com.annimon.hotarufx.lib.NumberValue; +import com.annimon.hotarufx.visual.Composition; +import lombok.val; + +public class CompositionBundle implements Bundle { + + @Override + public void load(Context context) { + context.functions().put("composition", args -> { + final int width, height; + final double frameRate; + switch (args.length) { + case 0: + width = 1280; + height = 720; + frameRate = 30d; + break; + case 1: + width = 1280; + height = 720; + frameRate = args[0].asNumber(); + break; + case 2: + width = args[0].asInt(); + height = args[1].asInt(); + frameRate = 30d; + break; + case 3: + default: + width = args[0].asInt(); + height = args[1].asInt(); + frameRate = args[2].asNumber(); + break; + } + val composition = new Composition(width, height, frameRate); + val scene = composition.getScene(); + context.composition(composition); + context.variables().put("Width", NumberValue.of(scene.getVirtualWidth())); + context.variables().put("Height", NumberValue.of(scene.getVirtualHeight())); + context.variables().put("HalfWidth", NumberValue.of(scene.getVirtualWidth() / 2)); + context.variables().put("HalfHeight", NumberValue.of(scene.getVirtualHeight() / 2)); + return NumberValue.ZERO; + }); + } +} diff --git a/app/src/main/java/com/annimon/hotarufx/lib/Context.java b/app/src/main/java/com/annimon/hotarufx/lib/Context.java index 20eaf6e..d6363fc 100644 --- a/app/src/main/java/com/annimon/hotarufx/lib/Context.java +++ b/app/src/main/java/com/annimon/hotarufx/lib/Context.java @@ -1,5 +1,6 @@ package com.annimon.hotarufx.lib; +import com.annimon.hotarufx.visual.Composition; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @@ -7,6 +8,7 @@ public final class Context { private final Map variables; private final Map functions; + private Composition composition; public Context() { variables = new ConcurrentHashMap<>(); @@ -20,4 +22,12 @@ public final class Context { public Map functions() { return functions; } + + public Composition composition() { + return composition; + } + + public void composition(Composition composition) { + this.composition = composition; + } } diff --git a/app/src/test/java/com/annimon/hotarufx/bundles/CompositionBundleTest.java b/app/src/test/java/com/annimon/hotarufx/bundles/CompositionBundleTest.java new file mode 100644 index 0000000..5ec0385 --- /dev/null +++ b/app/src/test/java/com/annimon/hotarufx/bundles/CompositionBundleTest.java @@ -0,0 +1,36 @@ +package com.annimon.hotarufx.bundles; + +import com.annimon.hotarufx.lib.Context; +import com.annimon.hotarufx.lib.NumberValue; +import lombok.val; +import org.junit.jupiter.api.Test; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.*; + +class CompositionBundleTest { + + @Test + void testBundle() { + val context = new Context(); + BundleLoader.loadSingle(context, CompositionBundle.class); + + assertThat(context.functions(), hasKey("composition")); + assertThat(context.composition(), nullValue()); + assertThat(context.variables(), allOf( + not(hasKey("Width")), + not(hasKey("Height")), + not(hasKey("HalfWidth")), + not(hasKey("HalfHeight")) + )); + + context.functions().get("composition").execute(); + + assertThat(context.composition(), notNullValue()); + assertThat(context.variables(), allOf( + hasEntry("Width", NumberValue.of(1920)), + hasEntry("Height", NumberValue.of(1080)), + hasEntry("HalfWidth", NumberValue.of(960)), + hasEntry("HalfHeight", NumberValue.of(540)) + )); + } +} \ No newline at end of file