async.cpp 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. #include "async.h"
  2. #include "../../../std/async/native/async.h"
  3. #include "../../../std/fiber/native/fiber.h"
  4. #include <SDL.h>
  5. #include <thread>
  6. #include <chrono>
  7. bbInt g_mojo_app_AppInstance_AddAsyncCallback( bbFunction<void()> callback );
  8. namespace{
  9. const int INVOKE=0x40000000;
  10. const int REMOVE=0x80000000;
  11. static void postEvent( int code ){
  12. SDL_UserEvent event;
  13. event.type=SDL_USEREVENT;
  14. event.code=code;
  15. event.data1=0;
  16. event.data2=0;
  17. if( SDL_PeepEvents( (SDL_Event*)&event,1,SDL_ADDEVENT,SDL_FIRSTEVENT,SDL_LASTEVENT )!=1 ){
  18. printf(" SDL_PeepEvents error!\n" );fflush( stdout );
  19. }
  20. }
  21. }
  22. int bbAddAsyncCallback( bbFunction<void()> callback ){
  23. return g_mojo_app_AppInstance_AddAsyncCallback( callback );
  24. }
  25. void bbInvokeAsyncCallback( int callback,bool remove ){
  26. int code=callback|INVOKE;
  27. if( remove ) code|=REMOVE;
  28. postEvent( code );
  29. }
  30. void bbRemoveAsyncCallback( int callback ){
  31. int code=callback|REMOVE;
  32. postEvent( code );
  33. }
  34. void bbAppFiberSleep( int millis ){
  35. int timeout=SDL_GetTicks()+millis;
  36. struct Resumer : public bbFunction<void()>::Rep{
  37. int fiber;
  38. Resumer():fiber( bbFiber::getCurrentFiber() ){
  39. }
  40. void invoke(){
  41. bbFiber::resumeFiber( fiber );
  42. }
  43. };
  44. bbFunction<void()> resumer( new Resumer );
  45. int resume=bbAddAsyncCallback( resumer );
  46. std::thread( [=](){
  47. int dur=timeout-SDL_GetTicks();
  48. if( dur>0 ) SDL_Delay( dur );
  49. bbInvokeAsyncCallback( resume,true );
  50. } ).detach();
  51. bbFiber::suspendCurrentFiber();
  52. }
  53. void bbAppPostEventFilter( bbAsync::Event *event ){
  54. SDL_UserEvent uevent;
  55. uevent.type=SDL_USEREVENT;
  56. uevent.code=0;
  57. uevent.data1=event;
  58. uevent.data2=0;
  59. if( SDL_PeepEvents( (SDL_Event*)&uevent,1,SDL_ADDEVENT,SDL_FIRSTEVENT,SDL_LASTEVENT )!=1 ){
  60. printf( "SDL_PeepEvents error!\n" );fflush( stdout );
  61. }
  62. }
  63. void bbAppSetPostEventFilter(){
  64. bbAsync::setPostEventFilter( bbAppPostEventFilter );
  65. }