Skip to content

Commit

Permalink
[core] Update loop structure and application structure
Browse files Browse the repository at this point in the history
-> 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
  • Loading branch information
GabrielBRDeveloper committed Jul 24, 2024
1 parent ef77f6c commit 795db23
Show file tree
Hide file tree
Showing 31 changed files with 386 additions and 236 deletions.
2 changes: 1 addition & 1 deletion .idea/artifacts/core_jar.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion .idea/artifacts/texel_jar.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

29 changes: 29 additions & 0 deletions core/src/br/nullexcept/mux/C.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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<AssetsManager.AssetsLoader> ASSETS_LOADER = new ArrayList<>();

public static class Config {
public static boolean SET_WINDOW_GL_HINT = true;
Expand All @@ -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<String> flags = new ArrayList<>();
Expand All @@ -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;
}
});
}
}
6 changes: 3 additions & 3 deletions core/src/br/nullexcept/mux/app/Activity.java
Original file line number Diff line number Diff line change
Expand Up @@ -77,13 +77,13 @@ public <T extends Activity> void startActivity(Launch<T> 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);
}
}

Expand All @@ -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();
}
Expand Down
169 changes: 2 additions & 167 deletions core/src/br/nullexcept/mux/app/Application.java
Original file line number Diff line number Diff line change
@@ -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<String, Service> services = new HashMap<>();
private static final ArrayList<ActivityStack> 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<ActivityStack> 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<ActivityStack> 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 extends Service> T beginService(Launch<T> 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<String, String> 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();
}
}
}
}
Loading

0 comments on commit 795db23

Please sign in to comment.