[原创]lua 实现2048

Posted by 涵曦 at 2014-04-28 with tags console, 2048, lua

主要逻辑很简单,总共上下左右四个操作。数据结构就是一个2维的数组。 具体实现看代码就ok了。打印这个2维数组格式化对齐有点乱。

mysql driver for lua

Posted by 涵曦 at 2014-04-14 with tags lua, mysql

在lua中操作mysql,封装基本的操作接口。

操作接口:

  • 创建连接:mysql.connect (host,user,pass,dbname,dbport)
    • return db object
  • 关闭连接:db:close()

  • 查询:db:query(sql)

    • return result table
  • 插入:db:insert(sql)

    • return result insert id
  • 更新:db:update(sql)

    • return 0 if right
  • 设置语言:db:character_set(character_type)

query 执行结果示例

local mysql = require "mysql"
local db = mysql.connect("192.168.1.25","root","root","mysql",3306)
print ("db=",db)
local tbl = db:query("select * from user")
for k,v in pairs(tbl) do
    print(k,v.Host,v.User)
end

实现原理

  1. 在c中创建MYSQL指针,然后push到lua中,每次操作第一个参数都为MYSQL指针(在lua中为lightuserdata)。
  2. 将接口导出到lua后,使用lua的metatable将接口封装成一个对象的成员函数形式。
  3. 使用mysql.connect创建db对象,然后通过db对象去调用操作函数起到隐藏MYSQL指针的效果,防止误操作导致的内存泄露。

源码地址

使用python搭建http服务器,供cocos2dx的AssetsManager更新

Posted by 涵曦 at 2014-03-03 with tags python, http, Linux

1. 简单http服务器

使用python开http服务很简单,执行

    python -m SimpleHTTPServer 8080

就可以开一个简单http服务了。它会已当前目录为web目录。有index.html则打开它。没有则显示文件目录。

2. 功能加强的http服务器

这个python服务器太简单,不能满足我的需求。我需要通过网页操作完成一些打包zip和更新svn代码的工作。则可以使用python提供的BaseHTTPRequestHandler, HTTPServer即可实现。

基本代码如下:具体需求就可以慢慢加进去了。

class MyRequestHandler(BaseHTTPRequestHandler):
    def do_GET(self):
        self.process(2)

    def do_POST(self):
        self.process(1)

    def process(self,type):
        # 在这里处理get和post。。。

        # 获取get的参数
        query = urllib.splitquery(self.path)
        action = query[0]
        queryParams = {}
        if '?' in self.path:
            if query[1]:#接收get参数
                for qp in query[1].split('&'):
                    kv = qp.split('=')
                    queryParams[kv[0]] = urllib.unquote(kv[1]).decode("utf-8", 'ignore')

        
        # 这里处理对应需要直行的shell命令并返回需要的http的contentType,和文件
        content_type,f = page(action,queryParams)
        self.send_response(200)
        self.send_header("Content-type", content_type)
        #self.send_header("Content-Length", str(len(content)))
        self.end_headers()
        shutil.copyfileobj(f,self.wfile)

server = HTTPServer(('', 8081), MyRequestHandler)

3. 具体操作的实现

现在主要工作都交给的了 page 函数处理,根据对应的action和参数做出对应的操作,并返回对应的file给客户端。

比如我接收到action=="/" 则返回index.html

    #index.html我直接放在执行脚本时的目录下
    if action=="/": #主页index.html
        f = open('index.html')
        f.seek(0)
        content_type = "text/html"

4. 完整代码

我还用到了打包zip文件,获取zip文件以及获取版本号的操作。全部代码请移步到github

参考资料:

非常简单的Python HTTP服务

Python执行系统命令并获得输出的几种方法

Python的http服务(SimpleHTTPServer,BaseHTTPServer,CGIHTTPServer)

android开发入门之luaIDE

Posted by 涵曦 at 2014-01-15 with tags android, lua

1. TextView高亮关键字

可以使用android.text.SpannableStringBuildersetSpan(Object what, int start, int end, int flags) 来实现高亮关键字。

SpannableStringBuild用于经常变动的字符串,SpannableString则用于不变的字符串。例如:

    String str="SpannableStringBuilder class";
    SpannableStringBuilder sp=new SpannableStringBuilder(str);
    sp.setSpan(new ForegroundColorSpan(Color.RED), 1, 4, Spannable.SPAN_EXCLUSIVE_INCLUSIVE); //把str的前4个字符的前景色设置为红色

这个类还可以用来完成类似于QQ表情的功能。具体用法参考android api吧。我只用来修改颜色,用正则匹配关键字。可以浏览源代码:KeywordHighlight.java。根据Jota修改而来。

2. Activity界面跳转

界面跳转用到了android.content.Intent

    // MainActivity 中这样写
    btn.setOnClickListener(new View.OnClickListener() { // 点击按钮,从MainActivity跳转到ResultActivity
        @Override
        public void onClick(View arg0) {
            Intent intent = new Intent();
            intent.setClass(MainActivity.this,ResultActivity.class);
            Bundle bundle = new Bundle();               // 跳转参数传递
            bundle.putString("result", res);
            intent.putExtras(bundle); 
            startActivity(intent);
        }
    });
    
    // ResultActivity 中这样写
    Bundle bunde = this.getIntent().getExtras();        // 取参数
    String str=bunde.getString("result").toString();
    btn.setOnClickListener(new View.OnClickListener(){  // 自定义返回按钮
        @Override
        public void onClick(View arg0) {
            finish(); //停止当前的Activity,返回上一个Activity
        }            
    });

代码写完之后需要在AndroidManifest.xml中添加

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name">
        <activity
            android:name="com.hanxi.luarun.MainActivity"
            android:label="@string/app_name"
            android:theme="@style/MyTheme">
             <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name=".ResultActivity"
            android:label="@string/app_name"
            android:theme="@style/MyTheme">
        </activity>
    </application>

3. luajava的使用

为了在安卓上解释lua,采用了现成的luajava库,编译luajava可以参考http://www.cnblogs.com/astin/archive/2011/07/26/2117590.html

luajava.h可以使用javah生成。后台我找到了现成AndroLua。直接把它集成到我的项目中的了。

    import org.keplerproject.luajava.*;
    
    LuaState L = LuaStateFactory.newLuaState();
    L.openLibs();
    L.LdoString("text = 'Hello Android, I am Lua.'");
    L.getGlobal("text");
    String text = L.toString(-1);

看上去和c与lua交互很类似的。

4. WebView的使用

最初以为高亮代码很难自己实现,就试着找现成的源码,结果没找到。就想着看看有没有js实现的代码编辑器,后面找到了一个不错的codemirror。并且集成到我的项目中在android4.0以上设备显示还不错,但是在2.3的设备上不能滑动(webview不支持div的滑动),底层的硬伤,试过修改codemirror和使用iscroll都没搞定,最后才找到jota(2年前见过这玩意,用过一两次没注意到它是开源的),然后研究它的源代码,就有了现在的高亮了。

WebView控件很简单的。js和java交互网上也找到很多教程js和java交互

    WebView webView = new WebView(this); 
    webView.getSettings().setJavaScriptEnabled(true);   // 开启js,不打开这个设置,就只能显示静态的html网页
    webView.loadUrl("http://www.baidu.com/");           // 远程网页
    //webView.loadUrl("file:///android_asset/demo.html"); // 本地assert目录下demo.html

差不多就这样子,我打算用这个来显示about.html的东西。

5. 文件浏览

这个功能一开始就不打算自己实现,现在开发安卓的这么多,一定能找到这种源码,结果一下子就找到了现成的文件选择对话框Android开发 打开文件 选择文件对话框。已经集成到我的项目中了,我还模仿它完成了保存文件对话框的功能。

实现保存文件对话框的时候难点就在于如何在静态的layout中添加动态的layout,android: 静态XML和动态加载XML混合使用,以及重写Layout控件 这篇文章对我帮助挺大的。

封装静态的layout,其中预留动态layout的位置,方便添加动态layout的时候整理布局不变。

        static public class SaveDialogLayout extends LinearLayout{ 
            public SaveDialogLayout(Context context) {
                super(context);
                ((Activity) getContext()).getLayoutInflater().inflate(R.layout.dialog, this); 
            }        
        }
        
        public static Dialog createSaveDialog(int id, Context context, ... ){
            AlertDialog.Builder builder = new AlertDialog.Builder(context);
            final SaveDialogLayout saveDialogLayout = new SaveDialogLayout(context);   
            LinearLayout openLayout = (LinearLayout) saveDialogLayout.findViewById(R.id.openLayout); // 预留放文件列表
            FileSelectView fileListView = new FileSelectView(context, id, callback, suffix, images,path); // 文件列表
            openLayout.addView(fileListView); // 添加到预留位置
            builder.setView(saveDialogLayout);
            ...        
        }    

6. 添加设置

android提供了PreferenceActivity,所以添加设置是比较简单的。

    public class SetActivity extends PreferenceActivity {
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            SysApplication.getInstance().addActivity(this); 
    
            addPreferencesFromResource(R.xml.preferences);
        }
    }

具体preferences.xml是什么样子的就参考代码吧。

7. 添加广告

我使用了有米广告,查看它的sdk文档就能搞定,非常简单的。我这里模拟器运行广告报错,但是实体机没问题。

8. 优化界面

最初一直再想去找别的应用中的ui元素,但是直接拿过来又有一堆的不搭配。最后找到了官方的ui编辑工具,超好用。网址:http://android-ui-utils.googlecode.com/hg/asset-studio/dist/index.html

lua动态链接库之单个so文件包含多个模块(luaL_requiref函数的使用)

Posted by 涵曦 at 2014-01-07 with tags lua, 代码阅读

hive的hive.lua文件中,第一行就是local c = require "hive.core"。

根据上一篇文章所说的,它是调用的hive文件夹下的core.so文件。

然而在其他hive文件夹下的system.lua前两行是

local cell = require "cell",local system = require "cell.system",

但没有看到这两个so文件。

这个是怎么回事呢?查看src下的hive*lib.c都含有luaL_Reg这样类似于hive.c中的用法。

然后找到hive.start()函数对应的scheduler_start(),看到了和cell.system相关的一行代码luaL_requiref(sL, "cell.system", cell_system_lib, 0);

接着去网上搜了下luaL_requiref()函数的作用,找到了lua源代码的实现,作用就是调用cell_system_lib然后把该模块绑定到cell.system模块名字下。

下面我就实现了一个so库包含两个模块。

lua动态链接库就到这里了,接下来会继续阅读hive代码