Ver Fonte

- added global easing function to Tween
- refactoring on multithreading loading

dmuratshin há 9 anos atrás
pai
commit
3b109d72c0

+ 10 - 0
examples/Demo/src/TestTweens.h

@@ -17,6 +17,8 @@ public:
         addButton("ease", "ease: Linear");
         addButton("TweenAnim", "Add TweenAnim");
         addButton("TweenRotation", "Add TweenRotation");
+        addButton("TweenRotationGlobalEase", "Add TweenRotation with GlobalEase");
+
         addButton("TweenScale", "Add TweenScale");
         addButton("TweenPosition", "Add TweenPosition");
         addButton("TweenColor", "Add TweenColor");
@@ -109,10 +111,18 @@ public:
         {
             _addTween(createTween(TweenAnim(resources.getResAnim("anim")), dur / 4, 10));
         }
+
         if (id == "TweenRotation")
         {
             _addTween(createTween(Actor::TweenRotation(_sprite->getRotation() + (float)MATH_PI * 2), dur, 1));
         }
+
+        if (id == "TweenRotationGlobalEase")
+        {
+            _addTween(createTween2(Actor::TweenRotation(_sprite->getRotation() + (float)MATH_PI * 2),
+                                   TweenOptions(500).loops(10)));
+        }
+
         if (id == "TweenPosition")
         {
             _addTween(createTween(Actor::TweenPosition(_sprite->getPosition() + Vector2(0, -200)), dur, 1, true));

+ 3 - 1
oxygine/src/Actor.h

@@ -57,17 +57,19 @@ namespace oxygine
     class TweenOptions
     {
     public:
-        explicit TweenOptions(timeMS duration = 500) : _duration(duration), _delay(0), _ease(Tween::ease_linear), _loops(1), _twoSides(false), _detach(false) {}
+        explicit TweenOptions(timeMS duration = 500) : _duration(duration), _delay(0), _ease(Tween::ease_linear), _globalEase(Tween::ease_linear), _loops(1), _twoSides(false), _detach(false) {}
         TweenOptions& duration(timeMS duration) { _duration = duration; return *this; }
         TweenOptions& delay(timeMS delay) { _delay = delay; return *this; }
         TweenOptions& loops(int loops) { _loops = loops; return *this; }
         TweenOptions& twoSides(bool enabled = true) { _twoSides = enabled; return *this; }
         TweenOptions& ease(Tween::EASE ease) { _ease = ease; return *this; }
         TweenOptions& detach(bool detach_ = true) { _detach = detach_; return *this; }
+        TweenOptions& globalEase(Tween::EASE ease) { _globalEase = ease; return *this; }
 
         timeMS  _duration;
         timeMS  _delay;
         Tween::EASE _ease;
+        Tween::EASE _globalEase;
         int     _loops;
         bool    _twoSides;
         bool    _detach;

+ 7 - 2
oxygine/src/DebugActor.cpp

@@ -413,16 +413,21 @@ namespace oxygine
 
     void DebugActor::onEvent(Event* ev)
     {
+        TouchEvent* te = safeCast<TouchEvent*>(ev);
         spActor actor = safeSpCast<Actor>(ev->target);
         spColorRectSprite cr = new ColorRectSprite;
         cr->setTouchEnabled(false);
-        //cr->setAlpha(100);
         cr->setColor(Color(rand() % 255, rand() % 255, rand() % 255, 0));
         cr->setSize(actor->getSize());
         cr->addTween(ColorRectSprite::TweenColor(Color(Color::White, 200)), 700, 1, true, 0, Tween::ease_inCubic)->setDetachActor(true);
         actor->addChild(cr);
         std::string dmp = actor->dump(0);
-        log::messageln("touched actor:\n%s", dmp.c_str());
+        log::messageln("touched actor '%s' local pos: (%.0f,%.0f), pos: (%.0f,%.0f)\n%s",
+                       actor->getName().c_str(),
+                       te->localPosition.x, te->localPosition.y,
+                       te->position.x, te->position.y,
+                       dmp.c_str());
+
         actor = actor->getParent();
         while (actor)
         {

+ 5 - 32
oxygine/src/Multithreading.cpp

@@ -43,26 +43,6 @@ namespace oxygine
     }
 #endif
 
-    class Mem2Native;
-    class LoadResourcesContextMT: public LoadResourcesContext
-    {
-    public:
-        LoadResourcesContextMT(Mem2Native* m2n): _m2n(m2n) {}
-        ~LoadResourcesContextMT() {}
-
-        void createTexture(const CreateTextureTask& opt) OVERRIDE
-        {
-            _m2n->push(opt);
-        }
-
-        bool isNeedProceed(spNativeTexture t)
-        {
-            return t->getHandle() == 0;
-        }
-
-    private:
-        Mem2Native* _m2n;
-    };
 
     void ThreadLoading::copyFrom(const ThreadLoading& src, cloneOptions opt)
     {
@@ -85,12 +65,6 @@ namespace oxygine
         //  pthread_join(_thread, 0);
     }
 
-    /*
-    float ThreadLoading::getProgress() const
-    {
-        return 0;
-    }
-    */
 
     void ThreadLoading::add(Resources* res)
     {
@@ -114,14 +88,13 @@ namespace oxygine
     void* ThreadLoading::_staticThreadFunc(void* t)
     {
         ThreadLoading* This = (ThreadLoading*)t;
-        LoadResourcesContextMT ctx(&This->_m2n);
-        This->_threadFunc(&ctx);
+        This->_threadFunc();
         return 0;
     }
 
     void ThreadLoading::load()
     {
-        _threadFunc(0);
+        _threadFunc();
     }
 
     void ThreadLoading::unload()
@@ -139,19 +112,19 @@ namespace oxygine
         }
     }
 
-    void ThreadLoading::_threadFunc(LoadResourcesContextMT* ctx)
+    void ThreadLoading::_threadFunc()
     {
         for (resources::iterator i = _resources.begin(); i != _resources.end(); ++i)
         {
             Resources* res = *i;
-            res->load(ctx);
+            res->load();
         }
 
         for (ress::iterator i = _ress.begin(); i != _ress.end(); ++i)
         {
             Resource* res = *i;
             //log::messageln("loading res: %s", res->getName().c_str());
-            res->load(ctx);
+            res->load();
         }
 
         MutexAutoLock k(_m);

+ 1 - 1
oxygine/src/Multithreading.h

@@ -45,7 +45,7 @@ namespace oxygine
 
     private:
         static void* _staticThreadFunc(void* t);
-        virtual void _threadFunc(LoadResourcesContextMT* ctx);
+        virtual void _threadFunc();
         void doUpdate(const UpdateState& us);
 
         Mem2Native _m2n;

+ 11 - 3
oxygine/src/Tween.cpp

@@ -10,7 +10,7 @@ namespace oxygine
 		_loopsDone(0),
         _percent(0),
         _status(status_not_started),
-        _elapsed(0), _twoSides(false), _ease(ease_linear), _detach(false), _delay(0), _client(0)
+        _elapsed(0), _twoSides(false), _ease(ease_linear), _detach(false), _delay(0), _client(0), _globalEase(ease_linear)
     {
 
     }
@@ -49,6 +49,7 @@ namespace oxygine
 		_twoSides = opt._twoSides;
 		_delay = opt._delay;
 		_detach = opt._detach;
+		_globalEase = opt._globalEase;
 
 		if (_duration <= 0)
 		{
@@ -147,10 +148,17 @@ namespace oxygine
                 if (_duration)
                 {
                     timeMS localElapsed = _elapsed - _delay;
+					
+					if (_globalEase != ease_linear)
+					{
+						float p = localElapsed / float(_duration * _loops);						
+						timeMS nv = calcEase(_globalEase, std::min(p, 1.0f)) * _duration * _loops;;
+						localElapsed = nv;
+					}
 
-                    int loopsDone = localElapsed / _duration;
+					int loopsDone = localElapsed / _duration;					
+					_percent = _calcEase(((float)(localElapsed - loopsDone * _duration)) / _duration);
 
-                    _percent = _calcEase(((float)(localElapsed - loopsDone * _duration)) / _duration);
 					while(_loopsDone < loopsDone)
 					{
 						_loopDone(actor, us);

+ 4 - 0
oxygine/src/Tween.h

@@ -107,6 +107,7 @@ namespace oxygine
         timeMS      getDuration() const { return _duration; }
         timeMS      getElapsed() const { return _elapsed; }
         EASE        getEase() const { return _ease; }
+        EASE        getGlobalEase() const { return _globalEase; }
         timeMS      getDelay() const { return _delay; }
         Actor*      getClient() const { return _client; }
         float       getPercent() const { return _percent; }
@@ -125,6 +126,8 @@ namespace oxygine
         void addDoneCallback(const EventCallback& cb);
         /**set Easing function*/
         void setEase(EASE ease) { _ease = ease; }
+        /**set Global Easing functiont */
+        void setGlobalEase(EASE ease) { _globalEase = ease; }
         /**set Delay before starting tween*/
         void setDelay(timeMS delay) { _delay = delay; }
         /** loops = -1 means infinity repeat cycles*/
@@ -174,6 +177,7 @@ namespace oxygine
         int _loops;
         int _loopsDone;
         EASE _ease;
+        EASE _globalEase;
         bool _twoSides;
 
         float _percent;

+ 99 - 70
oxygine/src/core/ThreadMessages.cpp

@@ -13,6 +13,25 @@ namespace oxygine
 
 
 
+
+    void mywait(pthread_cond_t* cond, pthread_mutex_t* mutex)
+    {
+#ifdef __S3E__
+        timespec ts;
+        clock_gettime(CLOCK_REALTIME, &ts);
+        addtime(ts, 300);
+        pthread_cond_timedwait(cond, mutex, &ts);
+#elif __ANDROID__
+        timespec ts;
+        clock_gettime(CLOCK_REALTIME, &ts);
+        addtime(ts, 500);
+        pthread_cond_timedwait(cond, mutex, &ts);
+#else
+        pthread_cond_wait(cond, mutex);
+#endif
+    }
+
+
     MutexPthreadLock::MutexPthreadLock(pthread_mutex_t& m, bool lock) : _mutex(m), _locked(lock)
     {
         if (_locked)
@@ -24,7 +43,7 @@ namespace oxygine
         pthread_mutex_unlock(&_mutex);
     }
 
-    ThreadMessages::ThreadMessages(): _id(0), _waitReplyID(0)
+    ThreadMessages::ThreadMessages(): _id(0), _waitReplyID(0), _result(0)
     {
         pthread_cond_init(&_cond, 0);
 
@@ -43,14 +62,19 @@ namespace oxygine
         pthread_cond_destroy(&_cond);
     }
 
-    void ThreadMessages::wait()
+    void ThreadMessages::_waitMessage()
     {
-        MutexPthreadLock lock(_mutex);
         _replyLast(0);
         while (_events.empty())
             pthread_cond_wait(&_cond, &_mutex);
     }
 
+    void ThreadMessages::wait()
+    {
+        MutexPthreadLock lock(_mutex);
+        _waitMessage();
+    }
+
     void addtime(timespec& ts, int ms)
     {
         ts.tv_nsec += ms * 1000000;
@@ -62,35 +86,12 @@ namespace oxygine
     }
 
 
-    void mywait(pthread_cond_t* cond, pthread_mutex_t* mutex)
-    {
-#ifdef __S3E__
-        timespec ts;
-        clock_gettime(CLOCK_REALTIME, &ts);
-        addtime(ts, 300);
-        pthread_cond_timedwait(cond, mutex, &ts);
-#elif __ANDROID__
-        timespec ts;
-        clock_gettime(CLOCK_REALTIME, &ts);
-        addtime(ts, 500);
-        pthread_cond_timedwait(cond, mutex, &ts);
-#else
-        pthread_cond_wait(cond, mutex);
-#endif
-    }
-
     void ThreadMessages::get(message& ev)
     {
         MutexPthreadLock lock(_mutex);
         LOGDN("ThreadMessages::get");
 
-        _replyLast(0);
-
-        while (_events.empty())
-        {
-            LOGDN("ThreadMessages::get pthread_cond_wait");
-            mywait(&_cond, &_mutex);
-        }
+        _waitMessage();
 
         ev = _events.front();
         _events.erase(_events.begin());
@@ -148,26 +149,29 @@ namespace oxygine
     void ThreadMessages::_replyLast(void* val)
     {
         LOGDN("ThreadMessages::_replyLast");
-        if (!_last._replied)
-        {
-            LOGDN("ThreadMessages::_replyLast not replied yet");
-            _last._replied = true;
-            _last._result = val;
 
-            if (_last.cb)
-            {
-                LOGDN("ThreadMessages::running callback");
-                _last.cb(_last);
-            }
+        if (_last.cb)
+        {
+            LOGDN("ThreadMessages::running callback");
+            _last.cb(_last);
+            _last.cb = 0;
+        }
 
 #ifndef __S3E__
-            if (_last.cbFunction)
-            {
-                LOGDN("ThreadMessages::running callback function");
-                _last.cbFunction();
-            }
+        if (_last.cbFunction)
+        {
+            LOGDN("ThreadMessages::running callback function");
+            _last.cbFunction();
+            _last.cbFunction = std::function< void() >();
+        }
 #endif
 
+        if (_waitReplyID == _last._id)
+        {
+            LOGDN("ThreadMessages::_replyLast not replied yet");
+            _result = val;
+
+
             LOGDN("ThreadMessages::_replyLast pre _waitReplyID = %d, _last._id = %d, _last.msgid=%d", _waitReplyID, _last._id, _last.msgid);
 
             if (_waitReplyID && _last._id == _waitReplyID)
@@ -189,6 +193,17 @@ namespace oxygine
     }
 
 
+    void ThreadMessages::_waitReply()
+    {
+        while (_last._id != _waitReplyID)
+        {
+            //LOGDN("ThreadMessages::send msgid=%d waiting reply...", msgid);
+            mywait(&_cond, &_mutex);
+        }
+
+        _waitReplyID = 0;// ?
+    }
+
     void* ThreadMessages::send(int msgid, void* arg1, void* arg2)
     {
         message ev;
@@ -198,32 +213,53 @@ namespace oxygine
 
 
         MutexPthreadLock lock(_mutex);
-        ev._id = ++_id;
-
-        _waitReplyID = ev._id;
-        _events.push_back(ev);
+        _pushMessageWithReply(ev);
 
         LOGDN("ThreadMessages::send msgid=%d pthread_cond_signal.. _waitReplyID=%d", msgid, _waitReplyID);
-        pthread_cond_signal(&_cond);
+        _waitReply();
 
+        LOGDN("ThreadMessages::send msgid=%d done", msgid);
 
-        if (_last._replied)
-        {
-            LOGDN("ThreadMessages::send msgid=%d already replied", msgid);
-        }
 
-        while (!_last._replied || _last._id != _waitReplyID)
-        {
-            LOGDN("ThreadMessages::send msgid=%d waiting reply...", msgid);
-            mywait(&_cond, &_mutex);
-        }
 
-        LOGDN("ThreadMessages::send msgid=%d done", msgid);
+        return _result;
+    }
+
+    void* ThreadMessages::sendCallback(int msgid, void* arg1, void* arg2, callback cb, void* cbData)
+    {
+        message ev;
+        ev.msgid = msgid;
+        ev.arg1 = arg1;
+        ev.arg2 = arg2;
+        ev.cb = cb;
+        ev.cbData = cbData;
+
+        MutexPthreadLock lock(_mutex);
+        _pushMessageWithReply(ev);
+        LOGDN("ThreadMessages::sendCallback msgid=%d pthread_cond_signal.. _waitReplyID=%d", msgid, _waitReplyID);
+
+        _waitReply();
+
+        LOGDN("ThreadMessages::sendCallback msgid=%d done", msgid);
 
-        _waitReplyID = 0;
-        _last._replied = false;
 
-        return _last._result;
+
+        return _result;
+    }
+
+    void ThreadMessages::_pushMessageWithReply(message& msg)
+    {
+        msg._id = ++_id;
+        _waitReplyID = msg._id;
+        _events.push_back(msg);
+        pthread_cond_signal(&_cond);
+    }
+
+    void ThreadMessages::_pushMessage(message& msg)
+    {
+        msg._id = ++_id;
+        _events.push_back(msg);
+        pthread_cond_signal(&_cond);
     }
 
     void ThreadMessages::post(int msgid, void* arg1, void* arg2)
@@ -234,9 +270,7 @@ namespace oxygine
         ev.arg2 = arg2;
 
         MutexPthreadLock lock(_mutex);
-        ev._id = ++_id;
-        _events.push_back(ev);
-        pthread_cond_signal(&_cond);
+        _pushMessage(ev);
     }
 
     void ThreadMessages::postCallback(int msgid, void* arg1, void* arg2, callback cb, void* cbData)
@@ -249,9 +283,7 @@ namespace oxygine
         ev.cbData = cbData;
 
         MutexPthreadLock lock(_mutex);
-        ev._id = ++_id;
-        _events.push_back(ev);
-        pthread_cond_signal(&_cond);
+        _pushMessage(ev);
     }
 
     void ThreadMessages::removeCallback(int msgid, callback cb, void* cbData)
@@ -266,7 +298,6 @@ namespace oxygine
                 break;
             }
         }
-
     }
 
 #ifndef __S3E__
@@ -281,9 +312,7 @@ namespace oxygine
         ev.cbFunction = f;
 
         MutexPthreadLock lock(_mutex);
-        ev._id = ++_id;
-        _events.push_back(ev);
-        pthread_cond_signal(&_cond);
+        _pushMessage(ev);
     }
 #endif
 }

+ 10 - 3
oxygine/src/core/ThreadMessages.h

@@ -31,7 +31,7 @@ namespace oxygine
         typedef void (*callback)(const message& m);
         struct message
         {
-            message(): msgid(0), arg1(0), arg2(0), cb(0), cbData(0), _id(0), _result(0), _replied(false) {}
+            message(): msgid(0), arg1(0), arg2(0), cb(0), cbData(0), _id(0) {}
 
             int     msgid;
             void*   arg1;
@@ -44,8 +44,6 @@ namespace oxygine
 #endif
 
             unsigned int _id;
-            void*   _result;
-            bool    _replied;
         };
 
         struct peekMessage: public message
@@ -69,6 +67,7 @@ namespace oxygine
         void* send(int msgid, void* arg1, void* arg2);
         void post(int msgid, void* arg1, void* arg2);
         void postCallback(int msgid, void* arg1, void* arg2, callback cb, void* cbData);
+        void* sendCallback(int msgid, void* arg1, void* arg2, callback cb, void* cbData);
         void removeCallback(int msgid, callback cb, void* cbData);
 
 #ifndef __S3E__
@@ -78,9 +77,17 @@ namespace oxygine
         void reply(void* val);
 
     private:
+        void _waitMessage();
+        void _waitReply();
+
+        void _pushMessage(message&);
+        void _pushMessageWithReply(message&);
+
         void _replyLast(void* val);
         unsigned int _id;
         unsigned int _waitReplyID;
+        void*   _result;
+
         typedef std::vector<message> messages;
         messages _events;
         message _last;

+ 1 - 0
oxygine/src/core/oxygine.cpp

@@ -401,6 +401,7 @@ namespace oxygine
 #endif
 
 #endif
+            LoadResourcesContext::init();
             init2();
         }
 

+ 59 - 0
oxygine/src/res/CreateResourceContext.cpp

@@ -1,9 +1,26 @@
 #include "CreateResourceContext.h"
 #include "core/NativeTexture.h"
 #include "MemoryTexture.h"
+#include "core/ThreadMessages.h"
+#include "core/oxygine.h"
 
 namespace oxygine
 {
+    thread_local bool _isMainThread = false;
+
+
+    void LoadResourcesContext::init()
+    {
+        _isMainThread = true;
+    }
+
+    LoadResourcesContext* LoadResourcesContext::get()
+    {
+        LoadResourcesContext* mtcontext = &MTLoadingResourcesContext::instance;
+        LoadResourcesContext* scontext = &SingleThreadResourcesContext::instance;
+        return _isMainThread ? scontext : mtcontext;
+    }
+
     CreateTextureTask::CreateTextureTask(): linearFilter(true), clamp2edge(true)
     {
     }
@@ -172,4 +189,46 @@ namespace oxygine
     {
         return t->getHandle() == 0;
     }
+
+
+    MTLoadingResourcesContext MTLoadingResourcesContext::instance;
+
+    void copyTexture(const ThreadMessages::message& msg)
+    {
+        const CreateTextureTask* task = (const CreateTextureTask*)msg.cbData;
+
+
+        MemoryTexture* src = task->src.get();
+        NativeTexture* dest = task->dest.get();
+
+        bool done = false;
+
+        if (isCompressedFormat(src->getFormat()))
+        {
+            dest->init(src->lock(), false);
+            done = true;
+        }
+        else
+        {
+
+            Rect textureRect(0, 0, src->getWidth(), src->getHeight());
+
+            if (dest->getHandle() == 0)
+                dest->init(textureRect.getWidth(), textureRect.getHeight(), src->getFormat());
+
+            dest->updateRegion(0, 0, src->lock());
+        }
+
+        task->ready();
+    }
+
+    void MTLoadingResourcesContext::createTexture(const CreateTextureTask& opt)
+    {
+        core::getMainThreadMessages().sendCallback(0, 0, 0, copyTexture, (void*)&opt);
+    }
+
+    bool MTLoadingResourcesContext::isNeedProceed(spNativeTexture t)
+    {
+        return t->getHandle() == 0;
+    }
 }

+ 12 - 1
oxygine/src/res/CreateResourceContext.h

@@ -96,6 +96,9 @@ namespace oxygine
     class LoadResourcesContext
     {
     public:
+        static LoadResourcesContext* get();
+        static void init();
+
         virtual ~LoadResourcesContext() {}
 
 
@@ -108,7 +111,15 @@ namespace oxygine
     public:
         static SingleThreadResourcesContext instance;
         void createTexture(const CreateTextureTask& opt) OVERRIDE;
-        bool isNeedProceed(spNativeTexture t);
+        bool isNeedProceed(spNativeTexture t) OVERRIDE;
+    };
+
+    class MTLoadingResourcesContext : public LoadResourcesContext
+    {
+    public:
+        static MTLoadingResourcesContext instance;
+        void createTexture(const CreateTextureTask& opt) OVERRIDE;
+        bool isNeedProceed(spNativeTexture t) OVERRIDE;
     };
 
     class RestoreResourcesContext: public LoadResourcesContext

+ 3 - 1
oxygine/src/res/Resource.cpp

@@ -17,8 +17,10 @@ namespace oxygine
 
     void Resource::load(LoadResourcesContext* context /* = 0 */)
     {
+        LoadResourcesContext* getContext();
+
         if (!context)
-            context = &SingleThreadResourcesContext::instance;
+            context = LoadResourcesContext::get();
 
         if (_loadCounter == 0)
             _load(context);