Showing posts with label scala. Show all posts
Showing posts with label scala. Show all posts

Saturday, January 28, 2012

Porting Unity3d's coroutines to Android/iOS

I have been quite away from Android development.
I have been coding a game for iOS: Shaman Doctor and now I am testing Unity3d.
This blog describes my wish to port that coroutines to other platforms.

Introduction

In Unity3d I am coding in C# and I learned about coroutines.
To give you an idea of how they work, check this blog posts:

Unity3d implementation for coroutines is somehow different.
To understand what I am saying, read the first link.
It gives an explanation of how it should be working inside Unity3d.

Usage
In the code where I use Unity3d coroutines is where I need to do a state machine code.
A super simple example would be:

Imagine you need to add a button but you can only click it once every two seconds.
I can imagine two possible implementations. Bare in mind that I didn't test this code.

Using time. objective-c code:

#define SECONDS_TO_ENABLE 2
@synthesize lastTimeUsed;

@implementation PotionController

- (id)init {
self = [super init];
if (self) {
self.lastTimeUsed = 0;
}

return self;
}

- (void)click {

NSTimeInterval now = [[NSDate date] timeIntervalSince1970];
NSTimeInterval difference = fabs(self.lastTimeUsed - now);

// if two seconds haven't pass, return.
if ( difference < SECONDS_TO_ENABLE ) {
return;
}

self.lastTimeUsed = now;

// Click logic here.
}

Disabling and sending an enable msg to be run after 2 seconds. Android code.

In this case it's a done with the View's postDelayed() method. It could be done
with a Handler as well.

public void click(final View view) {
view.setEnabled(false);

// Send a postDelayed to turn it on again.
view.postDelayed(new Runnable() {

@Override
public void run() {
view.setEnabled(True);
}

}, 2000L);

// Click logic here.
}

The same thing done with C# inside Unity3d would be:

void OnMouseDown() {
StartCoroutine(this.ClickLogic());
}

private IEnumerator ClickLogic() {
// Click Logic
yield return new WaitForSeconds(2.0f);
}

What happens when you click more than once in a two seconds time frame?
Honestly, I am not sure what happens when you call StartCoroutine() when
a previous coroutine was started, but it works.
I hope that someone can clarify this.

Now try to port this code from Unity3d to android or iOS.

IEnumerator TellMeASecret()
{
PlayAnimation("LeanInConspiratorially");
while(playingAnimation)
yield return null;

Say("I stole the cookie from the cookie jar!");
while(speaking)
yield return null;

PlayAnimation("LeanOutRelieved");
while(playingAnimation)
yield return null;
}

How can this be used in Android/iOS

Ordinary coroutines
Although Unity3d's coroutines are different from the ordinary, I wanted to know if it was possible to implement them in Android/iOS.

Android
My first google search about this was "java coroutines" and I learned that ordinary coroutines would need one of this options:
  • Modified JVMs (Can't be used in Android)
  • Modified Bytecode (Can't be used in Android)
  • Platform-specific JNI mechanisms (Not sure if it would work in Android)
  • Thread abstractions (Not sure how performant would work inside Android)
I feel this is a dead end for Android.

iOS

I didn't research a lot about iOS.
Here is a list of links that look interesting:

Unity3d implementation alike

After reading Richard Fine's blog post I thought it would be interesting to achieve something similar to that in the different platforms.
My big doubt is finding a way to implement something similar to an IEnumerator.

Using scala

Inside cocos2d-iphone
I am not sure if cocos2d's internal would support something like this.

Inside cocos2d-x
This is the real challenge.
Finding a way to implement Unity3d's coroutines but keeping it multiplatform.
Perhaps finding a way of doing it in C++.

What do you guys think?

Monday, November 14, 2011

Installing dependencies on the device

This last two weeks I have been giving it a try to Scala on Android. While learning how to do it, I found something interesting I would like to share.

Developing Android apps using scala

The big problem of developing in Scala is that Android doesn't provide a way to install dependencies on the device. So, if you want to use Scala you need to place the scala's jar in your apk.

Placing the scala jar inside the apk bring another problem, apk size. To fix this, scala developers use proguard to remove all unused classes from the scala jar.

Using proguard to remove unused classes works like charm but it brings a third problem. Compilation time. For me, it takes a whole minute to compile an application with a single Activity coded in scala.

Conclusion:
Coding scala in Android is as frustrating as testing android apps :)

While looking for a solution for this, I asked a question in stackoverflow and it was answered by @jberkel. He pointed me to a project called scala-android-libs created by Johannes Rudolph.

What this project does is very interesting. It installs the scala's jars in a rooted device and allows the application to use it through the AndroidManifest tag uses-library.

How does it work?

It creates a serie of XMLs in /system/etc/permissions that look like this:

file="/data/data/net.virtualvoid.android.scalainstaller/files/scala_actors.jar" />

This means that if inside the AndroidManifest the app says:


It will be able to use the scala_actors.jar file inside the /data/data/net.virtualvoid.android.scalainstaller/files/ folder as a dependency.

Since now we have the jar installed in our device, we can avoid the proguard step and the build times are very similar to build an ordinary java app.

Taking it further
Every time I develop an android application I start creating a maven project because I know that I will use certain dependencies. After learning about this approach I thought about leaving my dependencies inside the device.

Why don't extending scala-android-libs approach to provide a way to manage dependencies inside the device to make the build times faster?
Perhaps having an android app that allows to install/remove jar files and automatically generate this XMLs with the proper permissions.

What do you think?
Would you use it?