async_cb.cpp 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. #include "async_cb.h"
  2. #if __ANDROID__
  3. #include <jni.h>
  4. #endif
  5. namespace bbAsync{
  6. struct AsyncCallback;
  7. AsyncCallback *cb_first,*cb_free;
  8. std::mutex cb_mutex;
  9. int cb_nextid;
  10. struct AsyncCallback : public Event{
  11. AsyncCallback *succ;
  12. bbFunction<void()> func;
  13. std::atomic<int> posted;
  14. bool oneshot;
  15. int id;
  16. void dispatch(){
  17. int n=posted.exchange( 0 );
  18. for( int i=0;i<n;++i ) func();
  19. if( !oneshot ) return;
  20. std::lock_guard<std::mutex> lock( cb_mutex );
  21. succ=cb_free;
  22. cb_free=this;
  23. id=0;
  24. }
  25. };
  26. int createAsyncCallback( bbFunction<void()> func,bool oneshot ){
  27. std::lock_guard<std::mutex> lock( cb_mutex );
  28. AsyncCallback *cb=cb_free;
  29. if( cb ){
  30. cb_free=cb->succ;
  31. }else{
  32. cb=new AsyncCallback;
  33. }
  34. cb->func=func;
  35. cb->posted=0;
  36. cb->oneshot=oneshot;
  37. cb->id=++cb_nextid;
  38. cb->succ=cb_first;
  39. cb_first=cb;
  40. return cb->id;
  41. }
  42. void destroyAsyncCallback( int callback ){
  43. std::lock_guard<std::mutex> lock( cb_mutex );
  44. AsyncCallback **prev=&cb_first;
  45. while( AsyncCallback *cb=*prev ){
  46. if( cb->id!=callback ){
  47. prev=&cb->succ;
  48. continue;
  49. }
  50. if( cb->posted ) return; //OOPS, can't destroy posted callback.
  51. *prev=cb->succ;
  52. cb->succ=cb_free;
  53. cb_free=cb;
  54. return;
  55. }
  56. }
  57. void invokeAsyncCallback( int callback ){
  58. std::lock_guard<std::mutex> lock( cb_mutex );
  59. AsyncCallback **prev=&cb_first;
  60. while( AsyncCallback *cb=*prev ){
  61. if( cb->id!=callback ){
  62. prev=&cb->succ;
  63. continue;
  64. }
  65. if( cb->oneshot ) *prev=cb->succ;
  66. if( ++cb->posted==1 ) cb->post();
  67. break;
  68. }
  69. }
  70. #if __ANDROID__
  71. extern "C"{
  72. JNIEXPORT void JNICALL Java_com_monkey2_lib_Monkey2Async_invokeAsyncCallback( JNIEnv *env,jclass clazz,jint callback ){
  73. invokeAsyncCallback( callback );
  74. }
  75. }
  76. #endif
  77. }