From 795db238bb8899880cb3049819307250c81bc450 Mon Sep 17 00:00:00 2001 From: Gabriel Machado <97042217+GabrielBRDeveloper@users.noreply.github.com> Date: Tue, 23 Jul 2024 23:39:36 -0400 Subject: [PATCH] [core] Update loop structure and application structure -> Move application static to modular runtime. -> Enable multi-application support. -> Migrate Looper to modular structure -> More Flags -> Disable System Exit -> Add AssetsLoader structure -> Migrate GLES and HardwareSurface to texel-core. -> Organize texel core --- .idea/artifacts/core_jar.xml | 2 +- .idea/artifacts/texel_jar.xml | 2 +- core/src/br/nullexcept/mux/C.java | 29 +++ core/src/br/nullexcept/mux/app/Activity.java | 6 +- .../br/nullexcept/mux/app/Application.java | 169 +------------ .../mux/app/ApplicationRuntime.java | 231 ++++++++++++++++++ core/src/br/nullexcept/mux/app/Context.java | 20 +- core/src/br/nullexcept/mux/app/Looper.java | 20 ++ core/src/br/nullexcept/mux/app/Project.java | 8 - .../mux/app/{ => base}/CoreBoostrap.java | 3 +- .../br/nullexcept/mux/app/base/Lifecycle.java | 8 + .../br/nullexcept/mux/app/base/Project.java | 12 + .../br/nullexcept/mux/res/AssetsManager.java | 31 ++- .../br/nullexcept/mux/res/ResourceCache.java | 1 + core/src/br/nullexcept/mux/res/Resources.java | 19 +- .../nullexcept/mux/utils/LinearAnimation.java | 6 +- core/src/br/nullexcept/mux/view/View.java | 6 +- .../br/nullexcept/mux/widget/TextView.java | 9 +- .../mux/core/texel/CanvasTexel.java | 1 - .../mux/core/{hardware => texel}/GLES.java | 2 +- .../mux/core/texel/GLFramebuffer.java | 2 +- .../nullexcept/mux/core/texel/GLProgram.java | 2 +- .../mux/core/texel/GLProgramView.java | 1 - .../br/nullexcept/mux/core/texel/GLTexel.java | 2 +- .../nullexcept/mux/core/texel/GlesUtils.java | 2 +- .../nullexcept/mux/core/texel/GlfwWindow.java | 13 +- .../nullexcept/mux/core/texel/TexelAPI.java | 6 +- .../mux/core/texel/TexelBitmap.java | 2 +- .../mux/core/texel/TexelProject.java | 4 +- .../br/nullexcept/mux/core/texel/VgTexel.java | 1 - .../mux/{core => }/test/Example.java | 2 +- 31 files changed, 386 insertions(+), 236 deletions(-) create mode 100644 core/src/br/nullexcept/mux/app/ApplicationRuntime.java delete mode 100644 core/src/br/nullexcept/mux/app/Project.java rename core/src/br/nullexcept/mux/app/{ => base}/CoreBoostrap.java (75%) create mode 100644 core/src/br/nullexcept/mux/app/base/Lifecycle.java create mode 100644 core/src/br/nullexcept/mux/app/base/Project.java rename texel/src/br/nullexcept/mux/core/{hardware => texel}/GLES.java (60%) rename texel/src/br/nullexcept/mux/{core => }/test/Example.java (94%) diff --git a/.idea/artifacts/core_jar.xml b/.idea/artifacts/core_jar.xml index 1b29aa5..5e4ac1b 100644 --- a/.idea/artifacts/core_jar.xml +++ b/.idea/artifacts/core_jar.xml @@ -1,6 +1,6 @@ - $PROJECT_DIR$/out/artifacts/core_jar + $PROJECT_DIR$/out/artifacts/core diff --git a/.idea/artifacts/texel_jar.xml b/.idea/artifacts/texel_jar.xml index e857764..d5e4bff 100644 --- a/.idea/artifacts/texel_jar.xml +++ b/.idea/artifacts/texel_jar.xml @@ -1,6 +1,6 @@ - $PROJECT_DIR$/out/artifacts/texel_jar + $PROJECT_DIR$/out/artifacts/texel diff --git a/core/src/br/nullexcept/mux/C.java b/core/src/br/nullexcept/mux/C.java index fa19e19..dfc507b 100644 --- a/core/src/br/nullexcept/mux/C.java +++ b/core/src/br/nullexcept/mux/C.java @@ -2,8 +2,11 @@ import br.nullexcept.mux.graphics.BitmapFactory; import br.nullexcept.mux.graphics.fonts.TypefaceFactory; +import br.nullexcept.mux.lang.ValuedFunction; +import br.nullexcept.mux.res.AssetsManager; import br.nullexcept.mux.utils.Log; +import java.io.InputStream; import java.util.ArrayList; import java.util.Arrays; @@ -13,6 +16,7 @@ public class C { public static long GLFW_CONTEXT = 0; public static BitmapFactory BITMAP_FACTORY; public static TypefaceFactory TYPEFACE_FACTORY; + public static ArrayList ASSETS_LOADER = new ArrayList<>(); public static class Config { public static boolean SET_WINDOW_GL_HINT = true; @@ -23,6 +27,9 @@ public static class Flags { public static final boolean FULL_DRAW; public static final boolean DEBUG_OVERLAY; public static final boolean DISABLE_AUTO_REDRAW; + public static final boolean AUTO_GC = true; + public static boolean RESOURCES_CACHE_XML = true; + public static boolean RESOURCES_CACHE_FONTS = true; static { ArrayList flags = new ArrayList<>(); @@ -36,4 +43,26 @@ public static class Flags { DISABLE_AUTO_REDRAW = flags.contains("DISABLE_AUTO_REDRAW"); } } + + static { + ASSETS_LOADER.add(new AssetsManager.AssetsLoader() { + @Override + public InputStream open(Class loader, String directory) throws Exception { + return loader.getResourceAsStream(directory); + } + + @Override + public boolean exists(Class loader, String directory) { + try { + InputStream in = open(loader, directory); + if (in == null) { + return false; + } + in.close(); + return true; + } catch (Exception e) {} + return false; + } + }); + } } diff --git a/core/src/br/nullexcept/mux/app/Activity.java b/core/src/br/nullexcept/mux/app/Activity.java index bdeec1e..77e365c 100644 --- a/core/src/br/nullexcept/mux/app/Activity.java +++ b/core/src/br/nullexcept/mux/app/Activity.java @@ -77,13 +77,13 @@ public void startActivity(Launch launch) { nw._args = launch; nw.mWindow = window; - window.setWindowObserver(Application.buildObserver(nw)); + window.setWindowObserver(getApplication().buildObserver(nw)); window.getWindowObserver().onCreated(); } else { Activity nw = launch.make(); nw._args = launch; nw.stack = new ActivityStack(nw); - Application.boot(Application.getProject().getCoreBootstrap().makeWindow(), nw); + getApplication().boot(getApplication().getBootstrap().makeWindow(), nw); } } @@ -105,7 +105,7 @@ protected void post(Runnable runnable) { } protected void postDelayed(Runnable runnable, int time){ - Looper.getMainLooper().postDelayed(()->{ + getApplication().getLooper().postDelayed(()->{ if(isRunning()) { runnable.run(); } diff --git a/core/src/br/nullexcept/mux/app/Application.java b/core/src/br/nullexcept/mux/app/Application.java index 4a76b8a..e43e7f6 100644 --- a/core/src/br/nullexcept/mux/app/Application.java +++ b/core/src/br/nullexcept/mux/app/Application.java @@ -1,176 +1,11 @@ package br.nullexcept.mux.app; -import br.nullexcept.mux.view.Window; - -import java.io.File; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Map; +import br.nullexcept.mux.app.base.Project; public class Application { - private static long lastGc = System.currentTimeMillis(); - private static final HashMap services = new HashMap<>(); - private static final ArrayList activities = new ArrayList<>(); - private static Project current; - - public static Project getProject() { - return current; - } - public static void initialize(Project project){ - CoreBoostrap boostrap = project.getCoreBootstrap();; - Application.current = project; - Looper loop = new Looper(); - Looper.mainLooper = loop; - Files.build(); - loop.initialize(); - boostrap.boot(); - - Activity nw = project.getLaunch().make(); - nw.stack = new ActivityStack(nw); - loop.postDelayed(()->boot(boostrap.makeWindow(), nw), 0); - loop.post(Application::loop); - loop.loop(); - boostrap.finish(); - System.gc(); - Looper.sleep(2000); // Wait for all services stop - System.exit(0); - } - - private static void loop(){ - if (System.currentTimeMillis() - lastGc > 5000){ - System.gc(); - lastGc = System.currentTimeMillis(); - } - if (activities.size() == 0) { // Stop if contains 0 activity - stop(); - return; - } - synchronized (activities) { - ArrayList stack2 = new ArrayList<>(activities); - for (ActivityStack stack: stack2) { - if (stack == null || !stack.isValid()) { - activities.remove(stack); - } - } - } - Looper.getMainLooper().post(Application::loop); - } - - static Window.WindowObserver buildObserver(Activity activity) { - synchronized (activities) { - activities.add(activity.stack); - } - return new Window.WindowObserver() { - @Override - public void onCreated() { - activity.onCreate(); - } - - @Override - public void onVisibilityChanged(boolean visible) { - if (visible) { - activity.onResume(); - } else { - activity.onPause(); - } - } - - @Override - public void onResize(int width, int height) { - } - - @Override - public void onDestroy() { - ArrayList stacks = new ArrayList<>(); - ActivityStack stack = activity.stack; - while (stack != null) { - stacks.add(0, stack); - stack = stack.getBackItem(); - } - - // Fire all stack list - stacks.forEach((item)-> { - if (item.isValid()) { - item.getActivity().finish(); - } - }); - } - }; - } - - static void boot(Window window, Activity activity) { - window.destroy(); - window.setWindowObserver(buildObserver(activity)); - activity.mWindow = window; - window.create(); - window.setVisible(true); - } - - public static void stop(){ - for (Service service: services.values()) - service.myLooper.stop(); - Looper.getMainLooper().stop(); - } - - static synchronized T beginService(Launch launch) { - String name = launch.getLaunchClass().getName(); - - if (services.containsKey(name)) { - Service service = services.get(name); - service._args = launch; - service.onParcelChanged(launch); - return (T) service; - } - - Service service = launch.make(); - - Looper looper = new Looper(); - service.myLooper = looper; - service._args = launch; - - services.put(name, service); new Thread(()->{ - looper.initialize(); - looper.post(service::onCreate); - looper.loop(); - services.remove(name); - service.onDestroy(); + new ApplicationRuntime(project).start(); }).start(); - return (T) service; - } - - - protected static class Files { - public static File DEVICE_DATA; - public static File APP_DIR; - - private static void build() { - String appId = ""; - { - final String allowed = " ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789._-"; - String pack = current.getPackage() + ""; - for (int i = 0; i < pack.length(); i++) { - if (allowed.indexOf(pack.charAt(i)) >= 0) { - appId += pack.charAt(i); - } else { - appId += '.'; - } - } - } - Map env = System.getenv(); - { // Obtain app data dir - if (env.containsKey("APPDATA")) { - DEVICE_DATA = new File(env.get("APPDATA")); // WINDOWS DEVICE - } else if (env.containsKey("HOME")) { // UNIX DEVICES (MAC-OS, LINUX, UNIX) - DEVICE_DATA = new File(env.get("HOME"), ".local/share"); - } else { - DEVICE_DATA = new File(System.getProperty("user.home"), ".var"); - } - DEVICE_DATA.mkdirs(); - APP_DIR = new File(DEVICE_DATA, "MasterApps/" + appId).getAbsoluteFile(); - APP_DIR.mkdirs(); - } - } } } diff --git a/core/src/br/nullexcept/mux/app/ApplicationRuntime.java b/core/src/br/nullexcept/mux/app/ApplicationRuntime.java new file mode 100644 index 0000000..de23c78 --- /dev/null +++ b/core/src/br/nullexcept/mux/app/ApplicationRuntime.java @@ -0,0 +1,231 @@ +package br.nullexcept.mux.app; + +import br.nullexcept.mux.C; +import br.nullexcept.mux.app.base.CoreBoostrap; +import br.nullexcept.mux.app.base.Project; +import br.nullexcept.mux.res.Resources; +import br.nullexcept.mux.view.Window; + +import java.io.File; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; + +public class ApplicationRuntime extends Context { + private final Looper looper; + private final Project project; + private final CoreBoostrap bootstrap; + private long lastGc; + private final HashMap services = new HashMap<>(); + private final ArrayList activities = new ArrayList<>(); + private Resources resources; + private final File appDir; + + ApplicationRuntime(Project project) { + this.bootstrap = project.getCoreBootstrap(); + this.looper = new Looper(); + this.project = project; + this.appDir = findAppDir(); + } + + private File findAppDir() { + { + File DEVICE_DATA; + String appId = ""; + { + final String allowed = " ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789._-"; + String pack = project.getPackage() + ""; + for (int i = 0; i < pack.length(); i++) { + if (allowed.indexOf(pack.charAt(i)) >= 0) { + appId += pack.charAt(i); + } else { + appId += '.'; + } + } + } + Map env = System.getenv(); + { // Obtain app data dir + if (env.containsKey("APPDATA")) { + DEVICE_DATA = new File(env.get("APPDATA")); // WINDOWS DEVICE + } else if (env.containsKey("HOME")) { // UNIX DEVICES (MAC-OS, LINUX, UNIX) + DEVICE_DATA = new File(env.get("HOME"), ".local/share"); + } else { + DEVICE_DATA = new File(System.getProperty("user.home"), ".var"); + } + DEVICE_DATA.mkdirs(); + File app = new File(DEVICE_DATA, "MasterApps/" + appId).getAbsoluteFile(); + app.mkdirs(); + return app; + } + } + } + + CoreBoostrap getBootstrap() { + return bootstrap; + } + + void start() { + looper.initialize(); + if (Looper.getMainLooper() == null) { + Looper.mainLooper = looper; + } + bootstrap.boot(); + this.resources = new Resources(this); + + Activity nw = project.getLaunch().make(); + nw.appRuntime = this; + nw.stack = new ActivityStack(nw); + looper.postDelayed(() -> boot(bootstrap.makeWindow(), nw), 0); + looper.post(this::loop); + looper.loop(); + bootstrap.finish(); + System.gc(); + Looper.sleep(2000); // Wait for all services stop + } + + void boot(Window window, Activity activity) { + window.destroy(); + window.setWindowObserver(buildObserver(activity)); + activity.appRuntime = this; + activity.mWindow = window; + window.create(); + window.setVisible(true); + } + + synchronized T beginService(Launch launch) { + synchronized (services) { + String name = launch.getLaunchClass().getName(); + if (services.containsKey(name)) { + Service service = services.get(name); + service._args = launch; + service.onParcelChanged(launch); + return (T) service; + } + + Service service = launch.make(); + + Looper serviceLooper = new Looper(); + service.myLooper = serviceLooper; + service._args = launch; + service.appRuntime = this; + + services.put(name, service); + new Thread(() -> { + serviceLooper.initialize(); + serviceLooper.post(service::onCreate); + serviceLooper.loop(); + services.remove(name); + service.onDestroy(); + }).start(); + return (T) service; + } + } + + private void stop() { + synchronized (services) { + for (Service service : services.values()) { + service.getLooper().stop(); + } + services.clear(); + if (Looper.mainLooper == looper) { + Looper.mainLooper = null; + } + looper.stop(); + } + } + + @Override + public T startService(Launch service) { + return beginService(service); + } + + private void loop() { + if (System.currentTimeMillis() - lastGc > 5000 && C.Flags.AUTO_GC) { + System.gc(); + lastGc = System.currentTimeMillis(); + } + if (activities.size() == 0) { // Stop if contains 0 activity + stop(); + return; + } + synchronized (activities) { + ArrayList stack2 = new ArrayList<>(activities); + for (ActivityStack stack : stack2) { + if (stack == null || !stack.isValid()) { + activities.remove(stack); + } + } + } + looper.postDelayed(this::loop, 0); + } + + @Override + public Resources getResources() { + return resources; + } + + @Override + public File getFilesDir() { + return appDir; + } + + @Override + public T getApplet(String name) { + return (T) bootstrap.getSystemApplets().get(name); + } + + public Looper getLooper() { + return looper; + } + + + Window.WindowObserver buildObserver(Activity activity) { + synchronized (activities) { + activities.add(activity.stack); + } + return new WindowObserver(activity); + } + + private static class WindowObserver implements Window.WindowObserver { + private final Activity activity; + + private WindowObserver(Activity activity) { + this.activity = activity; + } + + @Override + public void onCreated() { + activity.onCreate(); + } + + @Override + public void onVisibilityChanged(boolean visible) { + if (visible) { + activity.onResume(); + } else { + activity.onPause(); + } + } + + @Override + public void onResize(int width, int height) { + } + + @Override + public void onDestroy() { + ArrayList stacks = new ArrayList<>(); + ActivityStack stack = activity.stack; + while (stack != null) { + stacks.add(0, stack); + stack = stack.getBackItem(); + } + + // Fire all stack list + stacks.forEach((item) -> { + if (item.isValid()) { + item.getActivity().finish(); + } + }); + } + } +} \ No newline at end of file diff --git a/core/src/br/nullexcept/mux/app/Context.java b/core/src/br/nullexcept/mux/app/Context.java index 5358736..41d2927 100644 --- a/core/src/br/nullexcept/mux/app/Context.java +++ b/core/src/br/nullexcept/mux/app/Context.java @@ -6,21 +6,23 @@ import br.nullexcept.mux.res.Resources; import java.io.File; -import java.util.HashMap; public class Context { public static final String CLIPBOARD_APPLET = "applet.os.clipboard"; public static final String DISPLAY_APPLET = "applet.os.display"; - private final Resources mResource; + ApplicationRuntime appRuntime; Launch _args; public Context(){ - mResource = new Resources(this); } public File getFilesDir() { - return Application.Files.APP_DIR; + return appRuntime.getFilesDir(); + } + + public ApplicationRuntime getApplication() { + return appRuntime; } protected void onParcelChanged(Parcel parcel) {} @@ -30,19 +32,19 @@ protected Parcel getParcel() { } public T startService(Launch service) { - return Application.beginService(service); + return appRuntime.beginService(service); } public String getString(String id) { - return mResource.getString(id); + return getResources().getString(id); } public T getApplet(String name) { - return (T) Application.getProject().getCoreBootstrap().getSystemApplets().get(name); + return appRuntime.getApplet(name); } public LayoutInflater getLayoutInflater(){ - return mResource.getInflater(); + return getResources().getInflater(); } public AssetsManager getAssetsManager() { @@ -50,6 +52,6 @@ public AssetsManager getAssetsManager() { } public Resources getResources() { - return mResource; + return appRuntime.getResources(); } } diff --git a/core/src/br/nullexcept/mux/app/Looper.java b/core/src/br/nullexcept/mux/app/Looper.java index 94d5b2e..601b735 100644 --- a/core/src/br/nullexcept/mux/app/Looper.java +++ b/core/src/br/nullexcept/mux/app/Looper.java @@ -1,12 +1,25 @@ package br.nullexcept.mux.app; import java.util.ArrayList; +import java.util.HashMap; public class Looper { + private static final HashMap activeLoops = new HashMap<>(); private final ArrayList executions = new ArrayList<>(); static Looper mainLooper; private boolean stop = false; + + public static Looper getCurrentLooper() { + Thread current = Thread.currentThread(); + synchronized (activeLoops) { + if (activeLoops.containsKey(current.getId())) { + return activeLoops.get(current.getId()); + } + } + return getMainLooper(); + } + public static Looper getMainLooper() { return mainLooper; } @@ -28,6 +41,10 @@ public void post(Runnable runnable){ } public void loop(){ + Long threadID = Thread.currentThread().getId(); + synchronized (activeLoops) { + activeLoops.put(threadID, this); + } while (!stop) { Callback[] list; int i = 0; @@ -48,6 +65,9 @@ public void loop(){ } sleep(0, (int) (Math.random()*100)); } + synchronized (activeLoops) { + activeLoops.remove(threadID); + } } public static void sleep(int ms) { diff --git a/core/src/br/nullexcept/mux/app/Project.java b/core/src/br/nullexcept/mux/app/Project.java deleted file mode 100644 index b91cbc5..0000000 --- a/core/src/br/nullexcept/mux/app/Project.java +++ /dev/null @@ -1,8 +0,0 @@ -package br.nullexcept.mux.app; - -public interface Project { - String getPackage(); - Launch getLaunch(); - - CoreBoostrap getCoreBootstrap(); -} \ No newline at end of file diff --git a/core/src/br/nullexcept/mux/app/CoreBoostrap.java b/core/src/br/nullexcept/mux/app/base/CoreBoostrap.java similarity index 75% rename from core/src/br/nullexcept/mux/app/CoreBoostrap.java rename to core/src/br/nullexcept/mux/app/base/CoreBoostrap.java index 8b088c2..e434f14 100644 --- a/core/src/br/nullexcept/mux/app/CoreBoostrap.java +++ b/core/src/br/nullexcept/mux/app/base/CoreBoostrap.java @@ -1,5 +1,6 @@ -package br.nullexcept.mux.app; +package br.nullexcept.mux.app.base; +import br.nullexcept.mux.app.Applet; import br.nullexcept.mux.view.Window; import java.util.Map; diff --git a/core/src/br/nullexcept/mux/app/base/Lifecycle.java b/core/src/br/nullexcept/mux/app/base/Lifecycle.java new file mode 100644 index 0000000..ef85eec --- /dev/null +++ b/core/src/br/nullexcept/mux/app/base/Lifecycle.java @@ -0,0 +1,8 @@ +package br.nullexcept.mux.app.base; + +public interface Lifecycle { + void onCreate(); + void onPause(); + void onResume(); + void onDestroy(); +} diff --git a/core/src/br/nullexcept/mux/app/base/Project.java b/core/src/br/nullexcept/mux/app/base/Project.java new file mode 100644 index 0000000..1962631 --- /dev/null +++ b/core/src/br/nullexcept/mux/app/base/Project.java @@ -0,0 +1,12 @@ +package br.nullexcept.mux.app.base; + +import br.nullexcept.mux.app.Activity; +import br.nullexcept.mux.app.Launch; +import br.nullexcept.mux.app.base.CoreBoostrap; + +public interface Project { + String getPackage(); + Launch getLaunch(); + + CoreBoostrap getCoreBootstrap(); +} \ No newline at end of file diff --git a/core/src/br/nullexcept/mux/res/AssetsManager.java b/core/src/br/nullexcept/mux/res/AssetsManager.java index 127730c..7032e9d 100644 --- a/core/src/br/nullexcept/mux/res/AssetsManager.java +++ b/core/src/br/nullexcept/mux/res/AssetsManager.java @@ -1,5 +1,8 @@ package br.nullexcept.mux.res; +import br.nullexcept.mux.C; +import br.nullexcept.mux.lang.ValuedFunction; + import java.io.InputStream; public class AssetsManager { @@ -13,20 +16,30 @@ public class AssetsManager { /** @TODO: NEED FIX FOR NATIVE COMPILE */ public InputStream openDocument(String dir){ - return clazz.getResourceAsStream((prefix+"/"+dir).replaceAll("//","/")); + String abs = (prefix+"/"+dir).replaceAll("//","/"); + InputStream stream; + for (AssetsLoader loader : C.ASSETS_LOADER) { + try { + if ((stream = loader.open(clazz, abs)) != null) { + return stream; + } + } catch (Exception e){} + } + return null; } public boolean exists(String dir) { - try { - InputStream input = openDocument(dir); - if (input.read() != -1){ - input.close(); + String abs = (prefix+"/"+dir).replaceAll("//","/"); + for (AssetsLoader loader: C.ASSETS_LOADER) { + if (loader.exists(clazz, abs)) { return true; } - input.close(); - return false; - } catch (Exception e){ - return false; } + return false; + } + + public interface AssetsLoader { + InputStream open(Class loader, String directory) throws Exception; + boolean exists(Class loader, String directory); } } diff --git a/core/src/br/nullexcept/mux/res/ResourceCache.java b/core/src/br/nullexcept/mux/res/ResourceCache.java index 743e77d..b798ec0 100644 --- a/core/src/br/nullexcept/mux/res/ResourceCache.java +++ b/core/src/br/nullexcept/mux/res/ResourceCache.java @@ -1,5 +1,6 @@ package br.nullexcept.mux.res; +import br.nullexcept.mux.C; import br.nullexcept.mux.graphics.fonts.Typeface; import br.nullexcept.mux.lang.xml.XmlElement; diff --git a/core/src/br/nullexcept/mux/res/Resources.java b/core/src/br/nullexcept/mux/res/Resources.java index 192ba58..2b165f6 100644 --- a/core/src/br/nullexcept/mux/res/Resources.java +++ b/core/src/br/nullexcept/mux/res/Resources.java @@ -1,5 +1,6 @@ package br.nullexcept.mux.res; +import br.nullexcept.mux.C; import br.nullexcept.mux.app.Context; import br.nullexcept.mux.app.applets.DisplayApplet; import br.nullexcept.mux.graphics.Drawable; @@ -125,8 +126,10 @@ public DisplayMetrics getDisplayMetrics() { } Typeface requestFont(String path) { - if (ResourceCache.hasFont(path)) { - return ResourceCache.obtainTypeface(path); + if (C.Flags.RESOURCES_CACHE_FONTS) { + if (ResourceCache.hasFont(path)) { + return ResourceCache.obtainTypeface(path); + } } String pth = path + ".ttf"; @@ -139,11 +142,15 @@ Typeface requestFont(String path) { } XmlElement requestXml(String path){ - if (ResourceCache.hasXml(path)){ - return ResourceCache.obtainXml(path); + if (C.Flags.RESOURCES_CACHE_XML) { + if (ResourceCache.hasXml(path)) { + return ResourceCache.obtainXml(path); + } + ResourceCache.store(path, XmlElement.parse(Resources.Manager.openDocument(path + ".xml"))); + return requestXml(path); + } else { + return XmlElement.parse(Manager.openDocument(path+".xml")); } - ResourceCache.store(path, XmlElement.parse(Resources.Manager.openDocument(path+".xml"))); - return requestXml(path); } StylePreset obtainStyle(String id) { diff --git a/core/src/br/nullexcept/mux/utils/LinearAnimation.java b/core/src/br/nullexcept/mux/utils/LinearAnimation.java index 69c895f..6c4637b 100644 --- a/core/src/br/nullexcept/mux/utils/LinearAnimation.java +++ b/core/src/br/nullexcept/mux/utils/LinearAnimation.java @@ -5,8 +5,10 @@ public abstract class LinearAnimation { private int duration; private boolean loop = false; + private final Looper looper; public LinearAnimation(int duration) { this.duration = duration; + this.looper = Looper.getCurrentLooper(); } public void play() { @@ -26,11 +28,11 @@ public void play() { onFrame((double)data[1]/data[0]); data[1] += (System.currentTimeMillis() - data[2]); data[2] = System.currentTimeMillis(); - Looper.getMainLooper().post(loops[0]); + looper.post(loops[0]); }; loops[0] = update; onBegin(); - Looper.getMainLooper().post(update); + looper.post(update); } public void setLoop(boolean loop) { diff --git a/core/src/br/nullexcept/mux/view/View.java b/core/src/br/nullexcept/mux/view/View.java index d636687..51da1d4 100644 --- a/core/src/br/nullexcept/mux/view/View.java +++ b/core/src/br/nullexcept/mux/view/View.java @@ -64,6 +64,7 @@ public View(Context context, AttributeList attrs) { if (attrs == null){ attrs = context.getResources().obtainStyled("Widget."+getClass().getSimpleName()); } + attributes = attrs; { // SETUP PADDING attrs.searchDimension(AttrList.padding, value -> setPadding(value.intValue(), value.intValue(), value.intValue(), value.intValue())); @@ -93,8 +94,7 @@ public View(Context context, AttributeList attrs) { state.set(StateList.CLICKABLE, false); - attributes = attrs; - Looper.getMainLooper().post(()-> attributes = null); + Looper.getCurrentLooper().postDelayed(()-> attributes = null,2); } protected void showMenu(MenuItem menu, int x, int y) { @@ -258,7 +258,7 @@ public void setOnClickListener(OnClickListener clickListener) { } public void post(Runnable runnable, long time) { - Looper.getMainLooper().postDelayed(() -> { + Looper.getCurrentLooper().postDelayed(() -> { if (isVisible()) { runnable.run(); } diff --git a/core/src/br/nullexcept/mux/widget/TextView.java b/core/src/br/nullexcept/mux/widget/TextView.java index 01d41a7..84b2845 100644 --- a/core/src/br/nullexcept/mux/widget/TextView.java +++ b/core/src/br/nullexcept/mux/widget/TextView.java @@ -24,9 +24,9 @@ public TextView(Context context) { this(context, null); } - public TextView(Context context, AttributeList attrs) { - super(context, attrs); - attrs = initialAttributes(); + public TextView(Context context, AttributeList initial) { + super(context, initial); + AttributeList attrs = initialAttributes(); attrs.searchText(AttrList.text, this::setText); attrs.searchColorList(AttrList.textColor, value -> textColor = value); attrs.searchDimension(AttrList.textSize, this::setTextSize); @@ -105,6 +105,9 @@ protected void onMeasure(int width, int height) { } public void setText(CharSequence text) { + if (text == null) { + text = ""; + } this.text.delete(0, this.text.length()); this.text.insert(text); layout.update(); diff --git a/texel/src/br/nullexcept/mux/core/texel/CanvasTexel.java b/texel/src/br/nullexcept/mux/core/texel/CanvasTexel.java index 8f2d70d..5fba721 100644 --- a/texel/src/br/nullexcept/mux/core/texel/CanvasTexel.java +++ b/texel/src/br/nullexcept/mux/core/texel/CanvasTexel.java @@ -2,7 +2,6 @@ import br.nullexcept.mux.graphics.*; import br.nullexcept.mux.graphics.shape.ShapeList; -import br.nullexcept.mux.hardware.GLES; import br.nullexcept.mux.utils.Log; import org.lwjgl.opengles.GLES20; diff --git a/texel/src/br/nullexcept/mux/core/hardware/GLES.java b/texel/src/br/nullexcept/mux/core/texel/GLES.java similarity index 60% rename from texel/src/br/nullexcept/mux/core/hardware/GLES.java rename to texel/src/br/nullexcept/mux/core/texel/GLES.java index 3ecb737..a6c2096 100644 --- a/texel/src/br/nullexcept/mux/core/hardware/GLES.java +++ b/texel/src/br/nullexcept/mux/core/texel/GLES.java @@ -1,4 +1,4 @@ -package br.nullexcept.mux.hardware; +package br.nullexcept.mux.core.texel; public class GLES extends org.lwjgl.opengles.GLES20 { } diff --git a/texel/src/br/nullexcept/mux/core/texel/GLFramebuffer.java b/texel/src/br/nullexcept/mux/core/texel/GLFramebuffer.java index f0d13cb..c9d617a 100644 --- a/texel/src/br/nullexcept/mux/core/texel/GLFramebuffer.java +++ b/texel/src/br/nullexcept/mux/core/texel/GLFramebuffer.java @@ -4,7 +4,7 @@ import br.nullexcept.mux.lang.Bindable; import br.nullexcept.mux.lang.Disposable; -import static br.nullexcept.mux.hardware.GLES.*; +import static br.nullexcept.mux.core.texel.GLES.*; class GLFramebuffer implements Disposable, Bindable { private int width, height; diff --git a/texel/src/br/nullexcept/mux/core/texel/GLProgram.java b/texel/src/br/nullexcept/mux/core/texel/GLProgram.java index 1b83845..c88db67 100644 --- a/texel/src/br/nullexcept/mux/core/texel/GLProgram.java +++ b/texel/src/br/nullexcept/mux/core/texel/GLProgram.java @@ -3,7 +3,7 @@ import br.nullexcept.mux.lang.Bindable; import br.nullexcept.mux.lang.Disposable; -import static br.nullexcept.mux.hardware.GLES.*; +import static br.nullexcept.mux.core.texel.GLES.*; abstract class GLProgram implements Bindable, Disposable { diff --git a/texel/src/br/nullexcept/mux/core/texel/GLProgramView.java b/texel/src/br/nullexcept/mux/core/texel/GLProgramView.java index 6f51eb1..aafe6cc 100644 --- a/texel/src/br/nullexcept/mux/core/texel/GLProgramView.java +++ b/texel/src/br/nullexcept/mux/core/texel/GLProgramView.java @@ -1,6 +1,5 @@ package br.nullexcept.mux.core.texel; -import br.nullexcept.mux.hardware.GLES; import br.nullexcept.mux.utils.BufferUtils; class GLProgramView extends GLProgram { diff --git a/texel/src/br/nullexcept/mux/core/texel/GLTexel.java b/texel/src/br/nullexcept/mux/core/texel/GLTexel.java index fe82267..d5baae4 100644 --- a/texel/src/br/nullexcept/mux/core/texel/GLTexel.java +++ b/texel/src/br/nullexcept/mux/core/texel/GLTexel.java @@ -5,7 +5,7 @@ import java.nio.FloatBuffer; -import static br.nullexcept.mux.hardware.GLES.*; +import static br.nullexcept.mux.core.texel.GLES.*; class GLTexel { private static final FloatBuffer bufferRect = BufferUtils.createFloatBuffer(2*4); diff --git a/texel/src/br/nullexcept/mux/core/texel/GlesUtils.java b/texel/src/br/nullexcept/mux/core/texel/GlesUtils.java index cfeb9a4..00fab0c 100644 --- a/texel/src/br/nullexcept/mux/core/texel/GlesUtils.java +++ b/texel/src/br/nullexcept/mux/core/texel/GlesUtils.java @@ -1,6 +1,6 @@ package br.nullexcept.mux.core.texel; -import static br.nullexcept.mux.hardware.GLES.*; +import static br.nullexcept.mux.core.texel.GLES.*; class GlesUtils { public static int compileShader(String source, int type){ diff --git a/texel/src/br/nullexcept/mux/core/texel/GlfwWindow.java b/texel/src/br/nullexcept/mux/core/texel/GlfwWindow.java index fd97330..2ff11a8 100644 --- a/texel/src/br/nullexcept/mux/core/texel/GlfwWindow.java +++ b/texel/src/br/nullexcept/mux/core/texel/GlfwWindow.java @@ -6,20 +6,15 @@ import br.nullexcept.mux.graphics.Point; import br.nullexcept.mux.graphics.Rect; import br.nullexcept.mux.graphics.Size; -import br.nullexcept.mux.graphics.fonts.Typeface; -import br.nullexcept.mux.hardware.GLES; import br.nullexcept.mux.input.CharEvent; import br.nullexcept.mux.input.KeyEvent; import br.nullexcept.mux.input.MotionEvent; import br.nullexcept.mux.input.MouseEvent; import br.nullexcept.mux.view.View; -import br.nullexcept.mux.view.ViewGroup; import br.nullexcept.mux.view.Window; import org.lwjgl.BufferUtils; import org.lwjgl.glfw.GLFW; import org.lwjgl.glfw.GLFWImage; -import org.lwjgl.nanovg.NVGColor; -import org.lwjgl.nanovg.NanoVG; import org.lwjgl.opengles.GLES20; import java.nio.ByteBuffer; @@ -36,16 +31,18 @@ class GlfwWindow extends Window { private boolean visible; private boolean running = false; private final Point position = new Point(); + private final Looper looper; private WindowObserver observer; private CharSequence title; public GlfwWindow() { + looper = Looper.getCurrentLooper(); window = GLFW.glfwCreateWindow(900, 512, title = "[MasterUI:Window]", 0, C.GLFW_CONTEXT); eventManager = new GlfwEventManager(this); GLFW.glfwIconifyWindow(window); GLFW.glfwSetWindowSizeCallback(window, (l, w,h) -> { windowSize.set(w,h); - Looper.getMainLooper().post(()-> drawSurface()); + looper.post(this::drawSurface); }); GLFW.glfwSetWindowPosCallback(window, (l, x, y) -> { }); @@ -132,7 +129,7 @@ private void update() { time = 1; } if (!destroyed) { - Looper.getMainLooper().postDelayed(this::update, time); + looper.postDelayed(this::update, time); } else { running = false; } @@ -305,7 +302,7 @@ public void setIcon(Drawable icon) { flipY.flip(); - Looper.getMainLooper().post(()->{ + looper.post(()->{ if (!destroyed) { GLFWImage ic = GLFWImage.malloc(); ic.set(iconSize, iconSize, flipY); diff --git a/texel/src/br/nullexcept/mux/core/texel/TexelAPI.java b/texel/src/br/nullexcept/mux/core/texel/TexelAPI.java index 0343a36..031593c 100644 --- a/texel/src/br/nullexcept/mux/core/texel/TexelAPI.java +++ b/texel/src/br/nullexcept/mux/core/texel/TexelAPI.java @@ -2,7 +2,7 @@ import br.nullexcept.mux.C; import br.nullexcept.mux.app.Applet; -import br.nullexcept.mux.app.CoreBoostrap; +import br.nullexcept.mux.app.base.CoreBoostrap; import br.nullexcept.mux.app.Looper; import br.nullexcept.mux.view.PointerIcon; import br.nullexcept.mux.view.Window; @@ -59,12 +59,12 @@ public void boot() { C.GLFW_CONTEXT = window; GLES.createCapabilities(); TexelAPI.initialize(); - Looper.getMainLooper().postDelayed(this::loop, 1); + Looper.getCurrentLooper().postDelayed(this::loop, 1); } private void loop() { glfwPollEvents(); - Looper.getMainLooper().postDelayed(this::loop,1); + Looper.getCurrentLooper().postDelayed(this::loop,1); } private static void setupEGL() { diff --git a/texel/src/br/nullexcept/mux/core/texel/TexelBitmap.java b/texel/src/br/nullexcept/mux/core/texel/TexelBitmap.java index af63560..9363d3c 100644 --- a/texel/src/br/nullexcept/mux/core/texel/TexelBitmap.java +++ b/texel/src/br/nullexcept/mux/core/texel/TexelBitmap.java @@ -67,7 +67,7 @@ public void dispose() { @Override protected void finalize() throws Throwable { - Looper.getMainLooper().post(()->{ + Looper.getCurrentLooper().post(()->{ try { NanoVG.nvgDeleteImage(C.VG_CONTEXT, id); } catch (Exception e){} diff --git a/texel/src/br/nullexcept/mux/core/texel/TexelProject.java b/texel/src/br/nullexcept/mux/core/texel/TexelProject.java index fe7639c..4c46425 100644 --- a/texel/src/br/nullexcept/mux/core/texel/TexelProject.java +++ b/texel/src/br/nullexcept/mux/core/texel/TexelProject.java @@ -1,9 +1,9 @@ package br.nullexcept.mux.core.texel; import br.nullexcept.mux.app.Activity; -import br.nullexcept.mux.app.CoreBoostrap; +import br.nullexcept.mux.app.base.CoreBoostrap; import br.nullexcept.mux.app.Launch; -import br.nullexcept.mux.app.Project; +import br.nullexcept.mux.app.base.Project; public class TexelProject implements Project { private final String package_; diff --git a/texel/src/br/nullexcept/mux/core/texel/VgTexel.java b/texel/src/br/nullexcept/mux/core/texel/VgTexel.java index 049fb12..eabbcad 100644 --- a/texel/src/br/nullexcept/mux/core/texel/VgTexel.java +++ b/texel/src/br/nullexcept/mux/core/texel/VgTexel.java @@ -2,7 +2,6 @@ import br.nullexcept.mux.C; import br.nullexcept.mux.graphics.*; -import br.nullexcept.mux.hardware.GLES; import br.nullexcept.mux.utils.Log; import org.lwjgl.nanovg.*; import org.lwjgl.opengles.GLES20; diff --git a/texel/src/br/nullexcept/mux/core/test/Example.java b/texel/src/br/nullexcept/mux/test/Example.java similarity index 94% rename from texel/src/br/nullexcept/mux/core/test/Example.java rename to texel/src/br/nullexcept/mux/test/Example.java index 2aa5e9d..7f1ba49 100644 --- a/texel/src/br/nullexcept/mux/core/test/Example.java +++ b/texel/src/br/nullexcept/mux/test/Example.java @@ -1,4 +1,4 @@ -package br.nullexcept.mux.core.test; +package br.nullexcept.mux.test; import br.nullexcept.mux.app.Activity; import br.nullexcept.mux.app.Application;