2014-04-24

Making python module with C++ using boost.python (mac)


1. Install Python 

For most of the case, the python is already installed.
The paths of my mac are as followings:
  • bin: /usr/bin/python2.7
  • include:  /System/Library/Frameworks/Python.framework/Versions/2.7/include/python2.7
  • library: /usr/lib/python2.7
  • archive library:  /usr/lib/python2.7/lib/libpython.a

2. Install boost

Download boost at http://www.boost.org/users/download/
Build the library: 
./bootstrap.sh
and 
./b2 install

When success, can find the include and library in the following path:
include path: /usr/local/boost/boost/
library path:  /usr/local/boost/stage/lib

3. Create the hello world program
Find out the detail in boost.python doc; it is clear.
http://www.boost.org/doc/libs/1_55_0/libs/python/doc/tutorial/doc/html/index.html

4. Build the program to share library


Create a make script as follows:
--------------------------------------------------------------------------------------------------------------
#!/bin/sh

BOOST_ROOT=/usr/local/boost
PYTHON_ROOT=/System/Library/Frameworks/Python.framework/Versions/2.7/include/python2.7

LD_LIBRARY_PATH=/usr/local/boost/stage/lib
PYTHON_LIBRARY_PATH=/usr/lib/python2.7/lib

echo $PYTHON_ROOT

g++ -c hello.cpp -I $PYTHON_ROOT -I $BOOST_ROOT
g++ -shared -o hello.so hello.o -lboost_python -lpython \
     -L $LD_LIBRARY_PATH \
     -L $PYTHON_LIBRARY_PATH

--------------------------------------------------------------------------------------------------------------
and run it.

Note:
  • to compile successfully, need to define the correct python and boost include path
  • to link successfully, need to define the boost.python and python library location



5. Play the module in python

First, need configure the environment so that python know boost.python
DYLD_LIBRARY_PATH=$BOOST_ROOT/stage/lib

Then run ‘python’ and type 
import hello
print hello_ext.greet()



If the DYLD_LIBRARY_PATH not define, may receive the following error message:
Library not loaded: libboost_python.dylib




2014-04-15

Make your Mysql friendly to Emoji character

In my last projects, Mysql is usually UTF-8 as the core encoding. However, it is not good for my current project now because we will play with Emoji Character;

Emoji Character is using an extended utf-8 Encoding, called UTF-8 mb4 (utf8mb4).

If inserting string with Emoji Character, the mysql will alert "incorrect string" and make the SQL fail.
To fix this, we need to:

  • Change the database and table to utf8mb4 encoding 
  • Change the connection encoding to utf8mb4 as well

External Reference:
  • http://mathiasbynens.be/notes/mysql-utf8mb4
  • http://info.michael-simons.eu/2013/01/21/java-mysql-and-multi-byte-utf-8-support/
  • http://my.oschina.net/wingyiu/blog/153357

2014-03-17

Calculate the distance between two geo locations

We are developing a location based app and we encounter a problem about the geo location yesterday. Which is "how to get the distance between two points in the map". It seem to be easy if using our usual XY coordination system (the Cartesian coordinate). However, the inputs are the latitude and longitude, not the unit of meter;



Formula:

acos( 
   cos(a.lat) x cos(a.long) x cos(b.lat) x cos(b.long) 
   + cos(a.lat) x sin(a.long) x  cos(b.lat) x sin(b.long)
   + sin(a.lat)*sin(b.lat)
)  x  earth.radius

Where:

a.lat, a.long  = latitude and longitude of the 1st point ( in radians)
b.lat, b.long  = latitude and longitude of the 2nd point ( in radians)
earth.radius = the radius of the earth;  (which is: 3443.9 nautical miles or 6378 km)


Source Code (in java):


public static double distanceBetween(double lat1, double long1, double lat2, double long2)
{
 double rLat1 = Math.toRadians(lat1);
 double rLong1 = Math.toRadians(long1);
 double rLat2 = Math.toRadians(lat2);
 double rLong2 = Math.toRadians(long2);
  
 double part1 = Math.cos(rLat1) * Math.cos(rLong1) * Math.cos(rLat2) * Math.cos(rLong2);
 double part2 = Math.cos(rLat1) * Math.sin(rLong1) * Math.cos(rLat2) * Math.sin(rLong2);
 double part3 = Math.sin(rLat1) * Math.sin(rLat2);
 
 return Math.acos(part1 + part2 + part3) * RADIUS;
}

Reference: 

There are more documentation talking about the distance calculation, also google provide API to do so.




2014-03-16

Abnormal java.net.UnknownHostException on resin

Recently, I encountered a problem while I am calling to Google API in my java code running on Resin. The problem is that: The http call raise an UnknownHostException;



It doesn't caused by Java itself because the UnitTest show it is correct.
It doesn't caused by Resin because it work in my development platform.

So what go wrong? Finally, I has discovered it is wrong in the staging server environment;
The /etc/hosts isn't configured as the resin want to. (... maybe it is the problem of resin too ..)

To fix it:
- type "hostname" to find your hostname . e.g "my.pc"
- edit /etc/hosts and add the line "127.0.0.1 my.pc"
- restart the server to make it effective

Notes:
- This problem may not be happened in all environment. My macbook doesn't have the problem.

Related Links:






2014-03-13

Make java connection pool auto reconnect

Recently we encountered a problem when using java db connection pool. The problem is that the connection is being closed by the DB server since it is already timeout. To due with this, need to configure two more parameters.

They are:
testOnBorrow  ;  define it as "true"
validationQuery ; define it as "SELECT 1 FROM dual" if you are also using MySQL

Yes, It is easy to config it. But how to test it? (Many sites may not give the answer). 

To verify the configuration is work, we can make a simple Unit Test;

Step 1: Make a failure case

Make an unit test base on the following code;


Properties p = new Properties(); 
prop.put("driver", "org.gjt.mm.mysql.Driver");
prop.put("url", "jdbc://localhost:3306/db");
prop.put("username", "user");
prop.put("password", "123456");
p.setProperties("testOnBorrow", "false");
p.setProperties("validationQuery", "");

BasicDataSource ds = BasicDataSourceFactory.createDataSource(prop);
ds.setMaxActive(1);
ds.setMaxIdle(1);
ds.setMinIdle(0);

Connection conn = ds.getConnection();
System.out.println("First connection");


System.out.println("Sleep start");
Thread.sleep(10000);
System.out.println("Sleep end");

Connection conn = ds.getConnection();
System.out.println("Second connection");


To make the connection fail at the second time, try to kill the connection in DB side while "Thread.sleep";


Step 2: Fix the failure 

Simply change "testOnBorrow=false" and "validationQuery=" to 
 "testOnBorrow=true" and "validationQuery=SELECT 1 FROM dual"

Then, run the test again. we will see "Second connection" show up instead of Exception message.



2014-01-27

Cocos2d-x Error: "Skipping selector 'onPopupYesPressed' since no CCBSelectorResolver is present."

Today, I failed to bind a button and the log said "Skipping selector 'onPopupYesPressed' since no CCBSelectorResolver is present.";

The reason is that simply because I forget to define the "Custom Class" name in CocosBuilder !! =.=

2014-01-23

制作游戏的难点


最近和友人談談各自製作遊戲的情況,發現真有點難; 


難一:難在找到志同道合及能力互補的團隊! 

難二:難在找出好的賣點! 

難三:難在製作出好的體驗! 

難四:難在把抽象的事情具體化!

難五:難在把設計實現出來! 

難六:難在放下主觀想法,拿起玩家的想法

游戏开发是梦幻的工业,这是事实,但是令一个事情,就做出好的游戏,是困难重重的,需要热情和能力兼备; 

真正製作的遊戲開發者,就是在不斷克服困難,不斷改进的勇者們!