All Stories

为了无界面运行Redmine

  项目组把mantis换成了redmine,相比之下,redmine似乎提供了更多功能,也更符合我们目前的需要。redmine是一个ROR(Ruby On Rails)应用,于是简单起见,我们使用了InstantRails这个傻瓜包,但是,有一个问题是,我们总是在InstantRails的界面上使用Mongrel启动Redmine,于是会出现一个Ruby运行的黑窗口,一直到运行结束。  从网上找了一些资料,发现至少有两种办法可以解决这个问题。一种使用Apache之类的专业Web服务器,然后安装FastCGI,把ROR在后台运行,所有外部请求由Apache来转发。另一种是使用Mongrel_service,把mongrel注册成Windows服务,这样就可以在后台运行了。于是我想试一下第二种方案。  本来gem install mongrel_service这样一条命令似乎就可以把这个gem包安装到本地,但实际上我发现我根本不能安装任何一个远程服务器上的gem包,可能跟网络环境有关。于是我只好到它的官方网站下一个gem文件下来,用gem install mongrel_service -l命令进行本地安装。这时会提示需要win32-service包,于是到Rubyforge上去找到官方发布,也下载到本地安装,然后又提示说要windows-pr,下来安装以提示说要windows-api、继续下来安装,继续提示说要win32-api,再下来安装,然后反向这个顺序依次安装,到了后来,提示win32-service的版本要是≥0.5.2或<0.6.0的,而我装的是0.6.1的,于是只好反安装,rubyforge上又找不到0.5.2的,从其他地方搜了一个源代码包,解开后,执行命令ruby win32-service.gemspec,会生成gem包文件,再来安装,又提示要VC,而且经过试验,如果是用的InstantRails 2.0中的Ruby,则要用6.0版本的VC才能正常编译。终于mongrel_service也安装好了,可以注册一个Windows服务器,启动这个服务,则用ruby运行一个rails应用,我这里就是redmine了,当然redmine需要MySQL支持,不想直接使用Instantrails了,把MySQL也添加到服务中,Apache是不需要了,启动这2个服务,就能无界面运行redmine了,哈,开源的东西,还真是有点麻烦呢!

这个世界有点疯

  偶然看到一则消息,遨游将自主开发浏览器内核,真是让我觉得有点不可理喻。当今世界,IE、Firefox、Opera、Safari几大流行浏览器正拼了个你死我活,遨游从MyIE开始,多少年来一直使用IE内核的外壳程序突然从中插一脚,在我看来,实在是前途困难重重,希望渺茫啊!  先不说遨游是否有这个技术实力,就算有了水平堪与一流产品比肩的成品,最后的宣传推广,以及后续维护发展,也是前景相当不乐观的!

困了累了不想动了

  总觉得心事重重,走在路上焦躁不安,忍不住安慰自己“熬过这个六月就好了”,心里刚刚默念完,突然觉得这句话很熟悉,似乎以前自己说过。不过要说真的说过的,那肯定得是一年前才可能的事了,去年的六月我又在烦些什么呢!确实好像这一年多来,一直过得很不顺心,每次都劝自己说“熬过这段时间就好了”,结果这样的时间一段接着一段。  计划有点宏伟,但对于我这么一个懒散的人来说,着实有点困难:WallpaperHelper——VC/MFC;SourceCoding——MinGW/wxWidgets;DCoding——MinGW/wxWidgets;CppCoding——MinGW/wxWidgets;PHPCoding——MinGW/wxWidgets;RubyCoding——MinGW/wxWidgets;PyCoding——MinGW/wxWidgets;LuaCoding——MinGW/wxWidgets;TclCoding——MinGW/wxWidgets;PerlCoding——MinGW/wxWidgets;TeXCoding——MinGW/wxWidgets;XMLCoding——MinGW/wxWidgets;Flowchart——MinGW/wxWidgets;SoftwareDiagram——MinGW/wxWidgets;NetworkDiagram——MinGW/wxWidgets;Go——MinGW/wxWidgets;Chess——MinGW/wxWidgets。

可以不用商业化的开发工具啦

  鉴于编辑器模块的重构任务已完成大部分,从两个View中提取出了一个基类View,这样总的说来大概减少了近2000行代码吧,中途也遇到些小麻烦,不过最后都没花什么大力气解决了。  今天就又看了一天的lex和yacc的资料,真是犯贱呀,在学校的时候这么大把的时间不好好学习,现在却要临时抱佛脚。回来看了几篇blog,难道最近流行学习编译原理?从理论到实践,都有人在搞。以前还是很不在乎的,因为再怎么样,也很少有可能需要自己去写一个编译器出来。其实现在若不是要整编辑器,也很可能再也不会去碰这玩意儿了。  昨天看到网上提到一个软件CodeLite,于是好奇心起,装了一个来试试,使用wxWidgets开发,所以横跨Windows、Linux、Mac三大桌面系统。它只是一个编辑环境,编译器还是使用其他的解决方案,比如MinGW,不过除开编译器因素不谈,它是个自消费系统,跟Code::Blocks一样,在自己的环境下开发自己,如果下载了它的源代码想自己编译一把的话,除了要装必要的编译器和程序库外,还得先装一个它的Release安装包,这个过程很明显又给自己打了一把广告。  突然我有个大胆的想法,这似乎是给我一个完全抛弃盗版软件的机会。在Windows平台上软件的丰富程序,确实很大程度上影响了我们的日常生活。记得还在大学的时候,就很雄心壮志地想所有的软件都不用盗版的,如果遇到找不到开源免费的,就自己写一个。但很严重的一个问题是,我当时只会用C++ Builder,所以开发工具只能用盗版的。现在也没好过到哪里去,只不过从C++ Builder换成了VC而已。可目前,就似乎有另外一种选择,使用MinGW+wxWidgets,从CodeLite和Code::Blocks的表现看来,完全可以满足我目前绝大多数的需求,而且还带来另外一个意外的好处,就是跨平台!虽然都没怎么想过在其他平台发展,但现在有这样的低成本扩张机会,何不放手一试呢!从此可以不用商业化的开发工具啦,哇哈哈哈哈!

IDE的编辑器就要这样做

  又看到José León新发的blog,再结合吃晚饭时,同事的抱怨,不禁羞愧难当,伟大的Borland,伟大的Delphi,哪怕是几经更名,哪怕是几经易主,曾经的IDE霸主,编辑器就是应该这样的做的。  今天花了点时间重构编辑器的auto completion、call tips模块,框架早已完成,剩下的是只让整个流程运作起来。中途发现几处笔误和遗漏,都不是大问题。清理了原来的代码,从原来的几百行的规模,拆分成现在几十个文件和类,本意是让设计更容易理解和维护,也尽量往容易进行单元测试的方向靠拢。不过等都完成后,回想起来,这样的设计仍然觉得不是很爽。类与类之前的关系略显得混乱,有些依赖关系感觉不是很符合OO的那些基本原则,但具体怎么做能更好,我却没什么头绪,大概也是因为理论理论和实践经验的两重不足引起的吧,只能靠不断修炼,逐步提升自己的exp了。  同事抱怨说自动提示功能很少能正常工作,我觉得很惭愧,当时刚做出个样子来时,心里还是比较自豪和骄傲的,不过现在事实摆在眼前,离真正可用,好用还差得很远。幸好现在已经有了思路,用lex和yacc来做,再好好设计一下,争取让这功能真正好用起来,计划花一周的时间完成。再花两天,把编辑器View的基类提取出来,以后所有需要代码编辑功能的View,只要从这个类继承,就可以得到功能基本完善的编辑特性集合。最后,花两周时间,把外部脚本扩展的框架实现。

丰富Scintilla的AutoCompletion

  今天又读了一点Scintilla的源代码,因为要达到现在比较流行的AutoCompletion的下拉列表,旁边还能显示一个tooltip描述选中项,那种效果,所以要先熟悉一下代码流程。  总结一下思路,要至少增加2个消息,用于显示或隐藏描述选中项的tooltip用。增加1个回送通知,用于告诉用户有机会对选中项进行额外操作,这里也就是显示这tooltip。修改listbox的显示方式,主要有效内容要加粗,其他的不加粗。修改选中项上屏函数,用于过滤出确实要上屏的内容。  总的说来,工作量似乎并不大,但实际上我却很懒得动手,而且为了以后发展的需要,最好这部分功能能合入官方源代码中,而确实Scintilla的原作者Neil Hudgson曾经说过,自己不会去做这个功能,并且并没有说,即使别人贡献了这样的代码,他一定会合入。  今天顺便看了一会儿notepad++的源代码,有几个小功能还值得学习,不过我个人认为这代码写得并不好,至少不如Scintilla的代码,但有些设计确实不错,而且它还能支持简单的插件。但我认为它最不好的是,似乎它使用自己修改的Scintilla,这样它的通用性就不好了。

Code Insight in Delphi for PHP

  偶然看到这篇文章,Delphi for PHP已经升级到2.0了,不愧为曾经最强大的IDE生产商,把PHP的开发工具都做得这么神!  Code insight,也就是auto completion、call tips等功能的集合,想当年,第一次用Borland C++ Builder 5.0的时候,就很诧异它的auto completion,不过那个版本并不稳定,后来没多久就出了6.0,发现稳定好多,不过以现在的眼光看来,它的速度就慢了点,还看到国内有个牛人自己写了个增强插件CodeFast,速度,内容上都有很大提升,但极其不稳定,几乎处于不可用状态。当时用得多开心的,而且以VCL出色的设计,开发GUI程序,尤其对于初学者,有极大的鼓励作用。由此,我也就以为,Borland出的IDE是世界上最好的IDE,这个原因,也一定程度上让我不再愿意去费力气转向其他工具,包括VC。  后来用上了装了Visual Assist.X的VC,发现VAX的能力太过惊人,再后来就是工作中,直接使用VC作为开发工具,就已经离不开VAX了,VAX的智能提示功能实在是太好用了。  工作中,负责的也是一个IDE的编辑模块,其中的auto completion和call tips则是重头戏,前段时间计划着增强该功能,但一直没有动手。曾经考察过几种当前甚为流行的IDE的这个功能,包括VC(其实是VAX)、C++Builder/Delphi、Netbeans、Eclipse、Visual SlickEdit,当时的比较结果看来,C++ Builder/Delphi的似乎是其中最弱的,Netbeans的则看起来比较炫,太显得啰嗦,VAX的比较适中(可能也是因为看习惯了)。但有一条明显的需求是,当光标在下拉候选列表项中移动时,旁边应该可以弹出一个tooltip来详细描述当前被选中的项。但是项目中使用的Scintilla控件似乎并不直接提供此类支持,因此需要修改控件的源代码,而这是我最不愿意做的事情,我希望这个支持应该由官方来做。  而今看到这篇blog,则提供了一个可以学习的范例,同样是脚本语言开发环境,别个是当前业界最先进的,当然应该取其所长,补我所短了。

关于打谱程序突然想到的

  今天突然有个想法,关于前段时间的用WTL写个围棋打谱程序的念头,是否可以把棋盘、棋子绘画动作也抽象出来,棋子的位置、走法规则都提取出来,有一组严谨的约束,而且这组约束可以通过配置文件,或者脚本来描述,最后,C/C++代码则只用来完成具体的绘画操作,对这些约束完全一无所知,比如它只知道在哪个坐标画一个什么样的图形,而为什么要画这个图形,这个图形有什么其他的含义,都不是它需要知道的。  如果确实能高度抽象地完成这个描述,那么带来的灵活性则是非常有用的。对于单纯是一个围棋打谱程序来说,也许带来的好处并不明显。但再换个角度考虑,在这一套架构下,很容易通过写少量脚本或配置文件,而不需要修改一行C++代码,一个围棋打谱程序立马摇身一变,成了一个象棋打谱程序,或者五子棋打谱程序了。这样的诱惑,对目前的我来说,实在是巨大呀!  这个想法的灵感,源于Eclipse的编辑器,《Contributing to Eclipse》中有一小段描述可以贡献一个编辑器,当时看到这段描述,甚是激动,差点想把那个IDE项目中的编辑器模块也这样做了。这次又联想到打谱程序,同样是画棋盘棋子的,只要合理设计,理应也可以达到类似的效果。  不过随便想想,以在世界范围最流行的4种棋类(围棋、中国象棋、国际象棋、五子棋)为目标,要想尽可能简单且灵活地实现,还有点困难。如何表示棋子的类型、如何表示行棋规则、如何定义精确的棋子位置以便程序绘制等等,都是摆在眼前最大的障碍。五子棋最容易表示,只有2种棋子,直接落子,虽也有像五手两打,三手交换之类的奇怪规则,但这些似乎都是在棋谱解析部分的工作。围棋则略为复杂,一个明显的问题是,要能计算出死子,并提出棋盘,这个工作如果纯粹交给外部脚本做,怕是会有心无力,但照现在的设计思想又不能让C/C++代码来做。两种象棋就更复杂了,棋子的类型就相比多了很多,每种棋子的合理行棋方式又都不一样,虽然从纯粹打谱的角度讲,比围棋、五子棋也复杂不了多少,但是在棋谱录入时,则很让我头痛了,如何表示一个棋子从一个位置移动到另一个位置,是否可以移动,移动后是否棋子的属性有变化(中国象棋中兵过河可横行,国际象棋中兵到底线可变身),移动后是否影响了其他棋子(吃掉了)等等,关键是一套界面和逻辑的交互协议,不能设计得太偏向于是为某种任务而特意为之,但又得有足够的信息在两者之间传递!

初学lex

  其实学的是flex,从公司网上找的,大概也是gnuwin32中的某个版本。顺便在公司网上又找了些资料来学,纯粹只是看的话,是跨不过那道坎的,所以要自己写几行来玩。生成的C代码倒是能直接用MinGW中的gcc编译,这让人觉得很舒心。开始的时候不明白,为什么写的正则表达式好像不起作用,总是把该扫描分析的文本全都打印出来了,而我明明只是想让它打印被匹配上的那些内容就行了啊,经过仔细观察,最后发现,其实是flex生成的C代码中,自动把不匹配任何自定义正则表达的内容也输出到控制台上去了。所以有两个办法可以解决此问题,一是把匹配内容输出到文件中,另一是修改下flex生成的C代码,把默认输出的那个ECHO修改了。  让它分析一个3万行的rb文件,匹配几种常见的token,如常量、变量、数字等等,速度奇快无比,可能不到1秒吧,想想我原来用Greta写的全文匹配5种模式,不知道要多久,不过幸好在不是很晚的时候发现了这个解决方案。从中已经可以看到曙光,原来我的猜想、直觉应该是正确的。flex可以解析出token,因为我需要的是其中的子模式,所以光是flex还不够,需要借助yacc(现在用bison的比较正常吧)进行语法分析。我猜即使加上了bison生成的语法分析过程,扫描那个3万行的rb文件,得到需要的结果,应该也不会超过3秒钟吧。不过另外有个问题需要注意,flex和bison生成的代码里都有一些全局变量,如果在多线程环境中使用,需要非常小心地进行同步,不过也许,自己也是可以对生成的代码略作修改的吧,尽管这些代码的可读性在我看来真的十分糟糕。