JSBinding绑定 -- CCTableView

[i=s] 本帖最后由 [email protected] 于 2012-12-27 10:51 编辑 

http://www.cocoachina.com/bbs/read.php?tid=156356

这几天公司要把一款以前用cocos2d(object-c)版本的游戏翻译成可以跨平台的,我个人是想要用C++的,因为我对C++还是有点经验的,但是没理法,才刚毕业,老板不是很相信,很是怀疑我的C++能力,在加上公司只有我一个懂C++,于是,他问了另外一个做服务端的,用PHP写的,基本上他只会PHP的,然后他说用JS来,说JS的开发效率高。本来我是比较担心JS的心能,但是他发了三天时间,终于把-x里面的jsdemo下到安卓上面,然后说js的性能应该没有问题,但是我对其还是比较怀疑的。看了一下-x,后来发现,-x里面的jsbinding里面调用的还是原生的C++,也就是说渲染引擎跟C++其实应该是一样的,性能应该跟原生的效率不会差很多,个人理解。那就只能用JS了,发了点牢骚,进入正题 
在手机上面,-x通过jsbingding,将C++的源生库给绑定成JS可以直接调用的方式。但是基本看不到关于将C++绑定成JS的相关资料,而且后来2.0加上去的一些扩展类都没有做相应的绑定。既然上头说要用JS开发,那这些控件肯定是要绑定的。所以这个事情就落到了我的头上了。 

既然没有相关的资料,没有理法,只能看源代码,参考着绑定。刚开始做这个的时候,我决定从CCTableView开始入手,因为个人感觉这个东西涉及到的应该会比较全面,有JS调用C++和C++调用JS,如果这个可以绑定成功了,后面的应该都没有什么问题了吧。开始的时候,可以先看一下cocos2d_specifics.cpp 、cocos2dx.cpp这两个文件,只要照着这个上面的方式做,一些简单的方法绑定应该都没有太大的问题,核心是ibjs_static.a这个静态库,有点大,>20M,按照这两个文件的写法,封装好要传递的参数和要要调用的函数,基本上不会有很大的问题,浪费时间,体力活。开始CCTableView的绑定。一开始我自己是这样认为的。首先我们在JS创建一个CCTableView的控件,比如要用到Create方法,也就是JS要调用C++的代码,这个的绑定方法很简单,参考下cocos2d_specifics.cpp 、cocos2dx.cpp的方式写一个,可以发现C++的Create被调用到了,而且JS也到了一个CCTableView的对象了(JS上面用的对象),创建成功之后,CCTableView的三个调用数据源的委托方法要被实现,也就是说我们要在JS上面重写这些委托方法,然后C++去调用JS的方法。这时,我发现这个方式就是跟touch事件的处理有点相似了,接着看CCLayer 
复制代码
  1. bool CCLayer::ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent)
  2. {
  3. if (kScriptTypeNone != m_eScriptType)
  4. {
  5. return excuteScriptTouchHandler(CCTOUCHBEGAN, pTouch) == 0 ? false : true;
  6. }
  7. CC_UNUSED_PARAM(pTouch);
  8. CC_UNUSED_PARAM(pEvent);
  9. CCAssert(false, "Layer#ccTouchBegan override me");
  10. return true;
  11. }
这边我们可以看到,如果是lua或者js脚本的时候,会去执行一个方法,这个方法可以让C++调用到JS,跟踪后我们发现最终在ScriptingCore.cpp这个文件里面发现了调用JS的方法,int ScriptingCore::executeLayerTouchEvent(CCLayer* pLayer, int eventType, CCTouch *pTouch);所以这个在这个tableview里面我们是不是也要弄个分支,让他去执行一个可以让C++调到js的方法呢。但是在CCTableView.cpp里面,我们发现这些委托方法被调用的地方有很多,这样要写分支的地方也就会很多,这样一来代码的维护就会出现问题,没理法,只能把CCTableView在往上面封装一层,这边我把他给封装成了JSTableView的样子 
JSTableView.h 
复制代码
  1. //
  2. // JSTableView.h
  3. // tableview
  4. //
  5. // Created by mac on 12-12-25.
  6. //
  7. //
  8. #ifndef __tableview__JSTableView__
  9. #define __tableview__JSTableView__
  10. #include "cocos2d.h"
  11. #include "CCTableView.h"
  12. #include "CCTableViewCell.h"
  13. USING_NS_CC;
  14. USING_NS_CC_EXT;
  15. NS_CC_EXT_BEGIN
  16. class JSTableView;
  17. class JSTableViewDelegate
  18. {
  19. public:
  20. virtual void executeTableCellTouched(JSTableView* table, CCTableViewCell* cell) = 0;
  21. };
  22. class JSTableViewDataSource
  23. {
  24. public:
  25. virtual CCSize executeCellSizeForTable(JSTableView *table) = 0;
  26. virtual CCTableViewCell* executeTableCellAtIndex(JSTableView *table, unsigned int idx) = 0;
  27. virtual unsigned int executeNumberOfCellsInTableView(JSTableView *table) = 0;
  28. };
  29. class JSTableView:public CCTableView,public CCTableViewDataSource,public CCTableViewDelegate
  30. {
  31. public:
  32. JSTableView()
  33. {
  34. CCTableView::setDataSource(this);
  35. }
  36. static JSTableView* create(JSTableViewDataSource* dataSource, CCSize size,CCNode *container = NULL)
  37. {
  38. JSTableView *table = new JSTableView();
  39. table->initWithViewSize(size, container);
  40. table->autorelease();
  41. table->setDataSource(dataSource);
  42. table->_updateContentSize();
  43. return table;
  44. }
  45. virtual void scrollViewDidScroll(cocos2d::extension::CCScrollView* view)
  46. {
  47. CCTableView::scrollViewDidScroll(view);
  48. }
  49. virtual void scrollViewDidZoom(cocos2d::extension::CCScrollView* view)
  50. {
  51. CCTableView::scrollViewDidZoom(view);
  52. }
  53. virtual void tableCellTouched(CCTableView* table, CCTableViewCell* cell);
  54. virtual CCSize cellSizeForTable(CCTableView *table);
  55. virtual CCTableViewCell* tableCellAtIndex(CCTableView *table, unsigned int idx);
  56. virtual unsigned int numberOfCellsInTableView(CCTableView *table);
  57. inline void setDelegate(JSTableViewDelegate* p)
  58. {
  59. CCTableView::setDelegate(this);
  60. m_pJSTableViewDelegate = p;
  61. }
  62. inline void setDataSource(JSTableViewDataSource* p)
  63. {
  64. CCTableView::setDataSource(this);
  65. m_pJSTableViewDataSource = p;
  66. }
  67. private:
  68. JSTableViewDataSource *m_pJSTableViewDataSource;
  69. JSTableViewDelegate *m_pJSTableViewDelegate;
  70. };
  71. NS_CC_EXT_END
  72. #endif /* defined(__tableview__JSTableView__) */

JSTableView.cpp 
复制代码
  1. //
  2. // JSTableView.cpp
  3. // tableview
  4. //
  5. // Created by mac on 12-12-25.
  6. //
  7. //
  8. #include "JSTableView.h"
  9. NS_CC_EXT_BEGIN
  10. void JSTableView::tableCellTouched(CCTableView* table, CCTableViewCell* cell)
  11. {
  12. if (m_pJSTableViewDelegate)
  13. {
  14. CCScriptEngineManager::sharedManager()->getScriptEngine()->executeTableCellTouch((JSTableViewDelegate*)m_pJSTableViewDelegate, this, cell);
  15. }
  16. }
  17. CCSize JSTableView::cellSizeForTable(CCTableView *table)
  18. {
  19. if (m_pJSTableViewDataSource)
  20. {
  21. return CCScriptEngineManager::sharedManager()->getScriptEngine()->executeCellSizeForTable(m_pJSTableViewDataSource, this);
  22. }
  23. return CCSizeZero;
  24. }
  25. CCTableViewCell* JSTableView::tableCellAtIndex(CCTableView *table, unsigned int idx)
  26. {
  27. if (m_pJSTableViewDataSource)
  28. {
  29. return CCScriptEngineManager::sharedManager()->getScriptEngine()->executeTableCellAtIndex(m_pJSTableViewDataSource, this, idx);
  30. }
  31. return NULL;
  32. }
  33. unsigned int JSTableView::numberOfCellsInTableView(CCTableView *table)
  34. {
  35. if (m_pJSTableViewDataSource)
  36. {
  37. return CCScriptEngineManager::sharedManager()->getScriptEngine()->executeNumberOfCellsInTableView(m_pJSTableViewDataSource, this);
  38. }
  39. return 0;
  40. }
  41. NS_CC_EXT_END
这样一来省去了要去CCTableView查找每个委托被调用到的地方,然后在添加调用JS的方法 

ScriptingCore.cpp 添加方法 
复制代码
  1. unsigned int ScriptingCore::executeNumberOfCellsInTableView(JSTableViewDataSource *dest,JSTableView *table)
  2. {
  3. std::string funcName = "numberOfCellsInTableView";
  4. js_proxy_t * p;
  5. JS_GET_PROXY(p, dest);
  6. if (!p) return NULL;
  7. jsval value1;
  8. js_proxy_t * p1;
  9. p1 = js_get_or_create_proxy(this->getGlobalContext(),table);
  10. value1 = OBJECT_TO_JSVAL(p1->obj);
  11. jsval *date = new jsval();
  12. date[0] = value1;
  13. jsval retval;
  14. executeJSFunctionWithName(this->cx_, p->obj, funcName.c_str(), *date, retval,1);
  15. return JSVAL_TO_INT(retval);
  16. }

现在,基本上就可以把CCTableView的库给绑定成功了。主要核心是那个20多兆的库,只要参考着-x已有的绑定方法和CCTableView的绑定方式,构建好要传递的参数和方法,后面的绑定应该不会有很大的问题了 

不想在写绑定过程遇到的问题了,还要苦逼的上班呢。直接上代码,希望交流,我也是刚开始做的,有错的留言 
源代码就:http://download.csdn.net/detail/zjf526655060/4932847 

你可能感兴趣的:(JSBinding绑定 -- CCTableView)