作者存档: 朱坤乾 - 第14页

学习下makefile

.PHONY : mingw ej2d linux undefined

CFLAGS = -g -Wall -Ilib -D EJOY2D_OS=$(OS)

// CFLAGS gcc接收的参数

// -g 生成调试信息,可用来gdb调试

// -Wall 输出gcc翻译时生成的警告信息

// -Ilib 将lib目录添加至编译查找路径,用来查找头文件

// gcc中命令行以tab开头

LDFLAGS :=

SRC := \
lib/shader.c \
lib/lshader.c \
lib/ejoy2dgame.c \
lib/fault.c \
lib/screen.c \
lib/texture.c \
lib/ppm.c \
lib/spritepack.c \
lib/sprite.c \
lib/lsprite.c \
lib/matrix.c \
lib/lmatrix.c \
lib/dfont.c \
lib/label.c \
lib/particle.c \
lib/lparticle.c \
lib/scissor.c

UNAME=$(shell uname)
SYS=$(if $(filter Linux%,$(UNAME)),linux,\
$(if $(filter MINGW%,$(UNAME)),mingw,\
$(if $(filter Darwin%,$(UNAME)),macosx,\
undefined\
)))

all: $(SYS)

undefined:
@echo “I can’t guess your platform, please do ‘make PLATFORM’ where PLATFORM is one of these:”
@echo ”      linux mingw macosx”

mingw : OS := WINDOWS
mingw : TARGET := ej2d.exe
mingw : CFLAGS += -I/usr/include -I/usr/local/include
mingw : LDFLAGS += -L/usr/bin -lgdi32 -lglew32 -lopengl32 -L/usr/local/bin -llua52
mingw : SRC += mingw/window.c mingw/winfw.c mingw/winfont.c

mingw : $(SRC) ej2d

linux : OS := LINUX
linux : TARGET := ej2d
linux : CFLAGS += -I/usr/include -I/usr/local/include $(shell freetype-config –cflags)
linux : LDFLAGS +=  -lGLEW -lGL -lX11 -lfreetype -llua -lm -Wl,-E
linux : SRC += posix/window.c posix/winfw.c posix/winfont.c

linux : $(SRC) ej2d

macosx : OS := MACOSX
macosx : TARGET := ej2d
macosx : CFLAGS += -I/usr/X11R6/include -I/usr/include -I/usr/local/include $(shell freetype-config –cflags) -D __MACOSX
macosx : LDFLAGS += -L/usr/X11R6/lib  -lGLEW -lGL -lX11 -lfreetype -llua -lm -Wl,-E -ldl
macosx : SRC += posix/window.c posix/winfw.c posix/winfont.c

macosx : $(SRC) ej2d

ej2d :
gcc $(CFLAGS) -o $(TARGET) $(SRC) $(LDFLAGS)

// gcc需要以tab开头

clean :
-rm -f ej2d.exe
-rm -f ej2d

.PHONY : all clean 

CFLAGS = -g -Wall 
LDFLAGS = -lpthread -llua -lm

uname_S := $(shell sh -c 'uname -s 2>/dev/null || echo not')
ifeq ($(uname_S), Darwin)
	SHARED = -fPIC -dynamiclib -Wl,-undefined,dynamic_lookup
// -fPIC 生成的地址改为相对地址,生成共享库时需要指定为相对地址
// -dynamiclib darwin系统中生成动态链接库参数
// -Wl,option 将option当做一个参数传给linker
else
	LDFLAGS += -lrt -Wl,-E
	SHARED = -fPIC --shared
endif

ifneq ($(uname_S), FreeBSD)
	LDFLAGS += -ldl
endif

all : \
  skynet \
  service/snlua.so \
  service/logger.so \
  service/gate.so \
  service/client.so \
  service/master.so \
  service/multicast.so \
  service/tunnel.so \
  service/harbor.so \
  service/localcast.so \
  luaclib/skynet.so \
  luaclib/socketdriver.so \
  luaclib/int64.so \
  luaclib/mcast.so \
  luaclib/bson.so \
  luaclib/mongo.so \
  client

skynet : \
  skynet-src/skynet_main.c \
  skynet-src/skynet_handle.c \
  skynet-src/skynet_module.c \
  skynet-src/skynet_mq.c \
  skynet-src/skynet_server.c \
  skynet-src/skynet_start.c \
  skynet-src/skynet_timer.c \
  skynet-src/skynet_error.c \
  skynet-src/skynet_harbor.c \
  skynet-src/skynet_multicast.c \
  skynet-src/skynet_group.c \
  skynet-src/skynet_env.c \
  skynet-src/skynet_monitor.c \
  skynet-src/skynet_socket.c \
  skynet-src/socket_server.c \
  luacompat/compat52.c
	gcc $(CFLAGS) -Iluacompat -o $@ $^ -Iskynet-src $(LDFLAGS)

luaclib:
	mkdir luaclib

service/tunnel.so : service-src/service_tunnel.c
	gcc $(CFLAGS) $(SHARED) $^ -o $@ -Iskynet-src

service/multicast.so : service-src/service_multicast.c
	gcc $(CFLAGS) $(SHARED) $^ -o $@ -Iskynet-src

service/master.so : service-src/service_master.c
	gcc $(CFLAGS) $(SHARED) $^ -o $@ -Iskynet-src

service/harbor.so : service-src/service_harbor.c
	gcc $(CFLAGS) $(SHARED) $^ -o $@ -Iskynet-src

service/logger.so : skynet-src/skynet_logger.c
	gcc $(CFLAGS) $(SHARED) $^ -o $@ -Iskynet-src

service/snlua.so : service-src/service_lua.c service-src/luacode_cache.c service-src/luaalloc.c
	gcc $(CFLAGS) $(SHARED) -Iluacompat $^ -o $@ -Iskynet-src

service/gate.so : service-src/service_gate.c
	gcc $(CFLAGS) $(SHARED) $^ -o $@ -Iskynet-src

service/localcast.so : service-src/service_localcast.c
	gcc $(CFLAGS) $(SHARED) $^ -o $@ -Iskynet-src

luaclib/skynet.so : lualib-src/lua-skynet.c lualib-src/lua-seri.c lualib-src/trace_service.c lualib-src/timingqueue.c | luaclib
	gcc $(CFLAGS) $(SHARED) -Iluacompat $^ -o $@ -Iskynet-src -Iservice-src -Ilualib-src

service/client.so : service-src/service_client.c
	gcc $(CFLAGS) $(SHARED) $^ -o $@ -Iskynet-src

luaclib/socketdriver.so : lualib-src/lua-socket.c | luaclib
	gcc $(CFLAGS) $(SHARED) -Iluacompat $^ -o $@ -Iskynet-src -Iservice-src

luaclib/int64.so : lua-int64/int64.c | luaclib
	gcc $(CFLAGS) $(SHARED) -Iluacompat -O2 $^ -o $@ 

luaclib/mcast.so : lualib-src/lua-localcast.c | luaclib
	gcc $(CFLAGS) $(SHARED) -Iluacompat $^ -o $@ -Iskynet-src -Iservice-src

luaclib/bson.so : lualib-src/lua-bson.c | luaclib
	gcc $(CFLAGS) $(SHARED) -Iluacompat $^ -o $@ 

luaclib/mongo.so : lualib-src/lua-mongo.c | luaclib
	gcc $(CFLAGS) $(SHARED) -Iluacompat $^ -o $@ 

client : client-src/client.c
	gcc $(CFLAGS) $^ -o $@ -lpthread

clean :
	rm skynet client service/*.so luaclib/*.so

找到一个编辑json表格ajax grid控件

jQuery UI Widgets

策划还是比较喜欢原来的类似表格来编辑,不喜欢直接编辑json格式。

在网上找到了jqwidgets,里面的grid控件正好满足需求。

<script type="text/javascript">
        $(document).ready(function () {
        	var url='<c:url value='/gm/Gm/readParameter?id=${parameter.id}'/>';
            var source =
            {
                datatype: "json",
                datafields: [
                    { name: 'id', type: 'int' },
                    { name: 'name', type: 'string' },
                    { name: 'gmLoginUrl', type: 'string' },
                    { name: 'ip', type: 'string' },
                    { name: 'port', type: 'int' },
                    { name: 'status', type: 'int' },
                    { name: 'recommend', type: 'bool' }
                ],
                id: 'id',
                url: url
            };
            var dataAdapter = new $.jqx.dataAdapter(source);
            $("#jqxgrid").jqxGrid(
            {
                width: 1200,
                source: dataAdapter,
                columnsresize: true,
                editable: true,
                columns: [
                  { text: 'id', datafield: 'id', width: 50 },
                  { text: 'name', datafield: 'name', width: 150 },
                  { text: 'ip', datafield: 'ip', width: 120 },
                  { text: 'port', datafield: 'port', minwidth: 120 },
                  { text: '状态', datafield: 'status', minwidth: 50 },
                  { text: '推荐', datafield: 'recommend', maxwidth: 50,columntype: 'checkbox' },
                  { text: '后台连接', datafield: 'gmLoginUrl', width: 280 }
                ]
            });
            $("#jsonExport").jqxButton({});
            $("#jsonExport").click(function () {
                var gridContent=$("#jqxgrid").jqxGrid('exportdata', 'json');
                $("#editParameterForm_json").val(gridContent);
                $("#editParameterForm").submit();
            });
        });</script>

在使用grid导出json时,数字被3个一组分组了,12345被格式化为 12,345 生成后面一堆错误。

最终未找到的完美的解决方式,只好设置这一列为字符串,避免被分组。

 

java上的协程

最近几天,有时间查看了一下java的中协程。

在java中大大小小的协程框架竟然有20多个,-.-!

总的来说java本身不支持协程,因此需要在vm级别进行修改才可以支持协程。

vm修改,分为两种,一种是直接修改生成的class bytecode如kilim之类。

另一类是直接运行在vm上的语言级别的支持,比如:akka。

kilim和akka也是目前公认的性能最好的框架。

我先测试了一下kilim,确实非常不错。多线程完全避免了线程切换和内存锁,而且使用url和sleep也不会阻塞线程运行。

我的电脑是8核cpu,在kilim中使用sleep,达到8个时会被线程阻塞。查找下解决方案。

我在kilim中使用的是Thread.sleep,如果改为使用kilim自带的sleep,则不会阻塞线程。

基本上搞明白了,kilim只是将线程改为了协程,避免了线程的上下文切换,但如果计算会阻塞,依旧会阻塞kilim,看来,httpclient及数据库操作和io需要改为non-blocking,才可以发挥kilim的全部性能。

kilim中还需要解决同步访问数据库、操作文件等问题,这些都必须改为non-blocking。

接着尝试下将server改为kilim,比较下性能。

查找服务器一个内存溢出的bug

最近两天晚上以每分钟一次的频率进行热更新,测试这种压力程度是否会引起bug。

早上到公司一看服务器已经死掉了,提示outofmemory,看来应该是有一个内存举出的地方。

服务器直接挂掉,连dump内存都无法成功。

使用jprofiler观察内存中的对象时时变化。

jprofiler中发现classloader没有被释放掉?

google之:

http://zeroturnaround.com/rebellabs/rjc201/

http://frankkieviet.blogspot.com/2006/10/how-to-fix-dreaded-permgen-space.html

Classloader leaks I – How to find classloader leaks with Eclipse Memory Analyser (MAT)

得知:classloader中会引用所加载类中的静态属性,从而导致classloader内存泄露。

将内存dump出来后,使用clipse Memory Analyser (MAT),查看具体哪里泄露。

直接在eclipse 中查找memory analyser 出来好多个软件。

mat 的update site:http://download.eclipse.org/mat/1.3.1/update-site/

其它的memory analyser软件,有时间再去了解下。

 

学习小记

今天跑通了ejoy2d。

了解到了mingw的功能,真是c/c++开发必备利器。基本上无缝移植至linux系统。

了解到了glew,跨平台的opengl开发工具包。不过好像只支持windows,linux,ios,android的支持未发现。

下载了powervr sdk,看起来powervr sdk支持所有平台,需要试一下。

另外需要学习luabinding。

 

 

eclipse-c 在windows平台下编译lua

最近几天有点空闲,想重拾c及lua。

目前c及lua的开发方式还是很火的一种方式,也是非常便捷。

云风使用c+lua做的服务器skynet及游戏引擎enjoy2d。

我也准备以上面两个开源项目来学习。

因能力所限,还只能借助于ide来进行开发学习。

下载eclipse-c

下载mingw,这个东西用起来感觉比cygwin方便。

在preferences->c/c++->build->enviroment设置环境变量。

这里我设置了PATH MINGW_HOME C_INCULUDE_PATH CPLUS_INCLUDE_PATH 4个环境变量

然后在lua工程中properties -> c/c++ general -> paths and symbos。

将C_INCLUDE_PATH 及 CPLUS_INCLUDE_PATH 添加至GNU C。

OK,可以正常的编译lua,也不报“Unresolved inclusion”错误。

编译云风大神的ejoy2d,成功后无法运行,直接程序就死掉,没有任何提示信息,偶然见到有个人提到驱动更新,把自己的显卡驱动更新为最新,顺利解决掉问题。

 

判断一个类为虚拟类

Modifier.isAbstract(clazz.getModifiers())

以上方式用来判断是clazz是否为虚拟类。

classloader重新加载资源

app在tomcat中运行,默认使用的是WebappClassLoader。

InputStream inputStream =Thread.currentThread().getContextClassLoader().getResourceAsStream(“xls/” +
xlsName);

inputStream只要加载过一次后,就会被WebappClassLoader缓存起来,如果需要加载新的资源文件,需要修改为以下方式:

// 因为webappclassloader会缓存加载的资源,所以每次手动去打开文件
			// InputStream inputStream =
			// GameInstance.gameClassLoader.getResourceAsStream("xls/" +
			// xlsName);
			URL xlsURL = GameInstance.gameClassLoader.getResource("xls/" + xlsName);
			URLConnection resConn = xlsURL.openConnection();
			resConn.setUseCaches(false);
			InputStream inputStream = resConn.getInputStream();

freemark关闭日志

改为logback后就发现freemark疯狂的输出log。

Logger.selectLoggerLibrary(Logger.LIBRARY_NONE);

struts2.3.15升级后

需要在struts.xml中添加:

<constant name=”struts.enable.DynamicMethodInvocation” value=”true” />

 


Warning: Use of undefined constant XML - assumed 'XML' (this will throw an Error in a future version of PHP) in /opt/wordpress/wp-content/plugins/wp-syntaxhighlighter/wp-syntaxhighlighter.php on line 1048