cmd/ebitenmobile: Add Android

Updates #863
This commit is contained in:
Hajime Hoshi 2019-08-18 15:53:25 +09:00
parent 787f2d72c0
commit e735e26450
2 changed files with 177 additions and 4 deletions

View File

@ -67,7 +67,7 @@ func run() error {
prefixUpper := strings.Title(*prefix) + strings.Title(pkgs[0].Name) prefixUpper := strings.Title(*prefix) + strings.Title(pkgs[0].Name)
writeFile := func(filename string, content string) error { writeFile := func(filename string, content string) error {
if err := ioutil.WriteFile(filepath.Join(*outdir, "src", "gobind", filename), []byte(content), 0644); err != nil { if err := ioutil.WriteFile(filepath.Join(*outdir, filename), []byte(content), 0644); err != nil {
return err return err
} }
return nil return nil
@ -75,6 +75,7 @@ func run() error {
replacePrefixes := func(content string) string { replacePrefixes := func(content string) string {
content = strings.ReplaceAll(content, "{{.PrefixUpper}}", prefixUpper) content = strings.ReplaceAll(content, "{{.PrefixUpper}}", prefixUpper)
content = strings.ReplaceAll(content, "{{.PrefixLower}}", prefixLower) content = strings.ReplaceAll(content, "{{.PrefixLower}}", prefixLower)
content = strings.ReplaceAll(content, "{{.JavaPkg}}", *javaPkg)
return content return content
} }
@ -84,12 +85,19 @@ func run() error {
switch lang { switch lang {
case "objc": case "objc":
// iOS // iOS
if err := writeFile(prefixLower+"ebitenviewcontroller_ios.m", replacePrefixes(objcM)); err != nil { if err := writeFile(filepath.Join("src", "gobind", prefixLower+"ebitenviewcontroller_ios.m"), replacePrefixes(objcM)); err != nil {
return err return err
} }
case "java": case "java":
// Android // Android
// TODO: Insert a Java file and let the original gobind compile it. dir := filepath.Join(strings.Split(*javaPkg, ".")...)
dir = filepath.Join(dir, prefixLower)
if err := writeFile(filepath.Join("java", dir, "EbitenView.java"), replacePrefixes(viewJava)); err != nil {
return err
}
if err := writeFile(filepath.Join("java", dir, "EbitenSurfaceView.java"), replacePrefixes(surfaceViewJava)); err != nil {
return err
}
case "go": case "go":
// Do nothing. // Do nothing.
default: default:
@ -197,3 +205,168 @@ const objcM = `// Code generated by ebitenmobile. DO NOT EDIT.
@end @end
` `
const viewJava = `// Code generated by ebitenmobile. DO NOT EDIT.
package {{.JavaPkg}}.{{.PrefixLower}};
import android.content.Context;
import android.util.AttributeSet;
import android.view.ViewGroup;
import {{.JavaPkg}}.ebitenmobileview.Ebitenmobileview;
import {{.JavaPkg}}.ebitenmobileview.ViewRectSetter;
public class EbitenView extends ViewGroup {
private double getDeviceScale() {
if (deviceScale_ == 0.0) {
deviceScale_ = getResources().getDisplayMetrics().density;
}
return deviceScale_;
}
private double pxToDp(double x) {
return x / getDeviceScale();
}
private double dpToPx(double x) {
return x * getDeviceScale();
}
private double deviceScale_ = 0.0;
public EbitenView(Context context) {
super(context);
ebitenSurfaceView_ = new EbitenSurfaceView(context);
}
public EbitenView(Context context, AttributeSet attrs) {
super(context, attrs);
ebitenSurfaceView_ = new EbitenSurfaceView(context, attrs);
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
if (!initialized_) {
LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
addView(ebitenSurfaceView_, params);
initialized_ = true;
}
int widthInDp = (int)Math.floor(pxToDp(right - left));
int heightInDp = (int)Math.floor(pxToDp(bottom - top));
Ebitenmobileview.layout(widthInDp, heightInDp, new ViewRectSetter() {
@Override
public void setViewRect(long xInDp, long yInDp, long widthInDp, long heightInDp) {
int widthInPx = (int)Math.ceil(dpToPx(widthInDp));
int heightInPx = (int)Math.ceil(dpToPx(heightInDp));
int xInPx = (int)Math.ceil(dpToPx(xInDp));
int yInPx = (int)Math.ceil(dpToPx(yInDp));
ebitenSurfaceView_.layout(xInPx, yInPx, xInPx + widthInPx, yInPx + heightInPx);
}
});
}
public void onPause() {
if (initialized_) {
ebitenSurfaceView_.onPause();
}
}
public void onResume() {
if (initialized_) {
ebitenSurfaceView_.onPause();
}
}
private EbitenSurfaceView ebitenSurfaceView_;
private boolean initialized_ = false;
}
`
const surfaceViewJava = `// Code generated by ebitenmobile. DO NOT EDIT.
package {{.JavaPkg}}.{{.PrefixLower}};
import android.content.Context;
import android.opengl.GLSurfaceView;
import android.util.Log;
import android.util.AttributeSet;
import android.view.MotionEvent;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import {{.JavaPkg}}.ebitenmobileview.Ebitenmobileview;
class EbitenSurfaceView extends GLSurfaceView {
private class EbitenRenderer implements Renderer {
private boolean errored_ = false;
@Override
public void onDrawFrame(GL10 gl) {
if (errored_) {
return;
}
try {
Ebitenmobileview.update();
} catch (Exception e) {
for (String line : e.toString().split("\\n")) {
Log.e("Go Error", line);
}
errored_ = true;
}
}
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
}
}
public EbitenSurfaceView(Context context) {
super(context);
initialize();
}
public EbitenSurfaceView(Context context, AttributeSet attrs) {
super(context, attrs);
initialize();
}
private void initialize() {
setEGLContextClientVersion(2);
setEGLConfigChooser(8, 8, 8, 8, 0, 0);
setRenderer(new EbitenRenderer());
}
private double getDeviceScale() {
if (deviceScale_ == 0.0) {
deviceScale_ = getResources().getDisplayMetrics().density;
}
return deviceScale_;
}
private double pxToDp(double x) {
return x / getDeviceScale();
}
@Override
public boolean onTouchEvent(MotionEvent e) {
for (int i = 0; i < e.getPointerCount(); i++) {
int id = e.getPointerId(i);
int x = (int)e.getX(i);
int y = (int)e.getY(i);
Ebitenmobileview.updateTouchesOnAndroid(e.getActionMasked(), id, (int)pxToDp(x), (int)pxToDp(y));
}
return true;
}
private double deviceScale_ = 0.0;
}
`

File diff suppressed because one or more lines are too long