diff --git a/README.md b/README.md index 874fb7664..35ab03220 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ The easiest way to create a new TeaVM project is to type in the command line: mvn -DarchetypeCatalog=local \ -DarchetypeGroupId=org.teavm \ -DarchetypeArtifactId=teavm-maven-webapp \ - -DarchetypeVersion=0.3.2 archetype:generate + -DarchetypeVersion=0.4.0 archetype:generate Now you can execute `mvn clean package` and get the generated `war` file. Deploy this `war` in Tomcat or another container, or simply unzip it and open the `index.html` page. @@ -38,7 +38,7 @@ Deploy this `war` in Tomcat or another container, or simply unzip it and open th It is much easier to develop TeaVM applications using Eclipse. If you prefer Eclipse, please read [this tutorial](https://github.com/konsoletyper/teavm/wiki/Eclipse-tutorial). -To learn TeaVM deeper, you take a look at the [teavm-samples](teavm-samples) module, +To learn TeaVM deeper, you take a look at the [samples](samples) module, containing examples of TeaVM-based projects. Also you can read [project's wiki](https://github.com/konsoletyper/teavm/wiki/). diff --git a/classlib/src/main/java/org/teavm/classlib/java/lang/TClass.java b/classlib/src/main/java/org/teavm/classlib/java/lang/TClass.java index 8aa91e7e5..4ea2a9129 100644 --- a/classlib/src/main/java/org/teavm/classlib/java/lang/TClass.java +++ b/classlib/src/main/java/org/teavm/classlib/java/lang/TClass.java @@ -15,12 +15,15 @@ */ package org.teavm.classlib.java.lang; +import java.io.ByteArrayInputStream; +import java.io.InputStream; import java.util.HashMap; import java.util.Map; import org.teavm.classlib.impl.DeclaringClassMetadataGenerator; import org.teavm.classlib.java.lang.annotation.TAnnotation; import org.teavm.classlib.java.lang.reflect.TAnnotatedElement; +import org.teavm.jso.JSBody; import org.teavm.platform.Platform; import org.teavm.platform.PlatformClass; import org.teavm.platform.metadata.ClassResource; @@ -266,4 +269,24 @@ public class TClass extends TObject implements TAnnotatedElement { annotationsByType.put((TClass) (Object) annot.annotationType(), annot); } } + + @JSBody(params = "res", script = + "if (!window.teaVMResources) return null;\n" + + "var data = window.teaVMResources[res];\n" + + "return data ? window.atob(data) : null;\n" + ) + private static native String readResource(String message); + + public InputStream getResourceAsStream(String name) { + TString clazzName = getName(); + int lastDot = clazzName.lastIndexOf('.'); + String resName; + if (lastDot == -1) { + resName = name; + } else { + resName = clazzName.substring(0, lastDot).replace('.', '/') + "/" + name; + } + String data = readResource(resName); + return data == null ? null : new ByteArrayInputStream(data.getBytes()); + } } diff --git a/html4j/src/main/java/org/teavm/html4j/HTML4JPlugin.java b/html4j/src/main/java/org/teavm/html4j/HTML4JPlugin.java index 1530d308d..118a3ab80 100644 --- a/html4j/src/main/java/org/teavm/html4j/HTML4JPlugin.java +++ b/html4j/src/main/java/org/teavm/html4j/HTML4JPlugin.java @@ -29,5 +29,6 @@ public class HTML4JPlugin implements TeaVMPlugin { host.add(new JavaScriptBodyTransformer()); host.add(new JCLHacks()); host.add(new JavaScriptResourceInterceptor()); + host.add(new ResourcesInterceptor()); } } diff --git a/html4j/src/main/java/org/teavm/html4j/ResourcesInterceptor.java b/html4j/src/main/java/org/teavm/html4j/ResourcesInterceptor.java new file mode 100644 index 000000000..6c7cc0715 --- /dev/null +++ b/html4j/src/main/java/org/teavm/html4j/ResourcesInterceptor.java @@ -0,0 +1,66 @@ +/* + * Copyright 2014 Alexey Andreev. + * + * 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.teavm.html4j; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.Base64; +import java.util.HashSet; +import java.util.Set; +import org.apache.commons.io.IOUtils; +import org.teavm.codegen.SourceWriter; +import org.teavm.javascript.RenderingContext; +import org.teavm.vm.BuildTarget; +import org.teavm.vm.spi.AbstractRendererListener; + +/** + * + * @author Jaroslav Tulach + */ +public class ResourcesInterceptor extends AbstractRendererListener { + private final Set processed = new HashSet<>(); + @Override + public void begin(RenderingContext context, BuildTarget buildTarget) throws IOException { + boolean hasOneResource = false; + for (String className : context.getClassSource().getClassNames()) { + final int lastDot = className.lastIndexOf('.'); + if (lastDot == -1) { + continue; + } + String packageName = className.substring(0, lastDot); + String resourceName = packageName.replace('.', '/') + "/" + "jvm.txt"; + try (InputStream input = context.getClassLoader().getResourceAsStream(resourceName)) { + if (input == null || !processed.add(resourceName)) { + continue; + } + ByteArrayOutputStream arr = new ByteArrayOutputStream(); + IOUtils.copy(input, arr); + String base64 = Base64.getEncoder().encodeToString(arr.toByteArray()); + input.close(); + final SourceWriter w = context.getWriter(); + w.append("// Resource " + resourceName + " included by " + className).newLine(); + w.append("if (!window.teaVMResources) window.teaVMResources = {};").newLine(); + w.append("window.teaVMResources['" + resourceName + "'] = '"); + w.append(base64).append("';").newLine().newLine(); + } + hasOneResource = true; + } + if (hasOneResource) { + context.getWriter().append("// TeaVM generated classes").newLine(); + } + } +} diff --git a/html4j/src/test/java/org/teavm/html4j/test/JavaScriptBodyTest.java b/html4j/src/test/java/org/teavm/html4j/test/JavaScriptBodyTest.java index 02ebb9e75..9c3f679f4 100644 --- a/html4j/src/test/java/org/teavm/html4j/test/JavaScriptBodyTest.java +++ b/html4j/src/test/java/org/teavm/html4j/test/JavaScriptBodyTest.java @@ -15,9 +15,14 @@ */ package org.teavm.html4j.test; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; import static org.junit.Assert.assertEquals; import java.util.Calendar; import net.java.html.js.JavaScriptBody; +import static org.junit.Assert.assertNotNull; import org.junit.Test; /** @@ -25,6 +30,16 @@ import org.junit.Test; * @author Alexey Andreev */ public class JavaScriptBodyTest { + @Test + public void readResource() throws IOException { + InputStream is = JavaScriptBodyTest.class.getResourceAsStream("jvm.txt"); + assertNotNull("Resource jvm.txt found", is); + try (BufferedReader r = new BufferedReader(new InputStreamReader(is))) { + String line = r.readLine(); + assertEquals("Line read", "TeaVM", line); + } + } + @Test public void javaScriptBodyHandled() { assertEquals(23, simpleNativeMethod()); diff --git a/html4j/src/test/resources/org/teavm/html4j/test/jvm.txt b/html4j/src/test/resources/org/teavm/html4j/test/jvm.txt new file mode 100644 index 000000000..6d8fe9182 --- /dev/null +++ b/html4j/src/test/resources/org/teavm/html4j/test/jvm.txt @@ -0,0 +1 @@ +TeaVM diff --git a/samples/benchmark/pom.xml b/samples/benchmark/pom.xml index be110be8e..03634bc92 100644 --- a/samples/benchmark/pom.xml +++ b/samples/benchmark/pom.xml @@ -17,6 +17,10 @@ TeaVM performance benchmark Compares performance of the JavaScript code produced by TeaVM and GWT + + + 0.14 + @@ -43,6 +47,12 @@ sources provided + + org.apidesign.bck2brwsr + emul + ${bck2brwsr.version} + rt + com.google.gwt gwt-user @@ -54,6 +64,20 @@ html5-canvas 0.7.2 + + com.dukescript.canvas + canvas-api + 0.7.2 + bck2brwsr + provided + + + org.apidesign.bck2brwsr + ko-bck2brwsr + ${bck2brwsr.version} + bck2brwsr + provided + org.netbeans.html net.java.html.boot @@ -136,6 +160,32 @@ + + org.apidesign.bck2brwsr + bck2brwsr-maven-plugin + ${bck2brwsr.version} + + + prepare-package + + aot + + + + + NONE + lib + ${project.build.directory}/generated/js/b2b-benchmark.js + ${project.build.directory}/generated/js/bck2brwsr.js + + org.teavm.samples.benchmark.htmljava.BenchmarkStarter + org/jbox2d/collision/shapes/ + org/jbox2d/common/ + org/jbox2d/dynamics/ + org/jbox2d/dynamics/joints/ + + + org.apache.maven.plugins maven-checkstyle-plugin @@ -191,4 +241,4 @@ - \ No newline at end of file + diff --git a/samples/benchmark/src/main/webapp/bck2brwsr.html b/samples/benchmark/src/main/webapp/bck2brwsr.html new file mode 100644 index 000000000..7aa17d72c --- /dev/null +++ b/samples/benchmark/src/main/webapp/bck2brwsr.html @@ -0,0 +1,46 @@ + + + + + + Bck2Brwsr jbox2d benchmark + + +

Bck2Brwsr performance

+
+ +
+ + + + + + + + + +
SecondTime spent computing, ms
+ + + + + + diff --git a/samples/benchmark/src/main/webapp/index.html b/samples/benchmark/src/main/webapp/index.html index 6c8f5de14..f5f789deb 100644 --- a/samples/benchmark/src/main/webapp/index.html +++ b/samples/benchmark/src/main/webapp/index.html @@ -17,13 +17,14 @@ - TeaVM vs. GWT performance comparison + TeaVM vs. GWT vs. Bck2Brwsr performance comparison -

TeaVM vs. GWT performance

+

TeaVM vs. GWT vs. Bck2Brwsr performance

\ No newline at end of file