
/*
 * Copyright 2006 The Android Open Source Project
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */


#include "SkEvent.h"

void SkEvent::initialize(const char* type, size_t typeLen,
                         SkEventSinkID targetID) {
    fType = NULL;
    setType(type, typeLen);
    f32 = 0;
    fTargetID = targetID;
    fTargetProc = NULL;
#ifdef SK_DEBUG
    fTime = 0;
    fNextEvent = NULL;
#endif
}

SkEvent::SkEvent()
{
    initialize("", 0, 0);
}

SkEvent::SkEvent(const SkEvent& src)
{
    *this = src;
    if (((size_t) fType & 1) == 0)
        setType(src.fType);
}

SkEvent::SkEvent(const SkString& type, SkEventSinkID targetID)
{
    initialize(type.c_str(), type.size(), targetID);
}

SkEvent::SkEvent(const char type[], SkEventSinkID targetID)
{
    SkASSERT(type);
    initialize(type, strlen(type), targetID);
}

SkEvent::~SkEvent()
{
    if (((size_t) fType & 1) == 0)
        sk_free((void*) fType);
}

static size_t makeCharArray(char* buffer, size_t compact)
{
    size_t bits = (size_t) compact >> 1;
    memcpy(buffer, &bits, sizeof(compact));
    buffer[sizeof(compact)] = 0;
    return strlen(buffer);
}

void SkEvent::getType(SkString* str) const 
{ 
    if (str) 
    {
        if ((size_t) fType & 1) // not a pointer
        {
            char chars[sizeof(size_t) + 1];
            size_t len = makeCharArray(chars, (size_t) fType);
            str->set(chars, len);
        }
        else
            str->set(fType);
    }
}

bool SkEvent::isType(const SkString& str) const 
{
    return this->isType(str.c_str(), str.size()); 
}

bool SkEvent::isType(const char type[], size_t typeLen) const 
{ 
    if (typeLen == 0)
        typeLen = strlen(type);
    if ((size_t) fType & 1) {   // not a pointer
        char chars[sizeof(size_t) + 1];
        size_t len = makeCharArray(chars, (size_t) fType);
        return len == typeLen && strncmp(chars, type, typeLen) == 0;
    }
    return strncmp(fType, type, typeLen) == 0 && fType[typeLen] == 0; 
}

void SkEvent::setType(const char type[], size_t typeLen)
{
    if (typeLen == 0)
        typeLen = strlen(type);
    if (typeLen <= sizeof(fType)) {
        size_t slot = 0;
        memcpy(&slot, type, typeLen);
        if (slot << 1 >> 1 != slot)
            goto useCharStar;
        slot <<= 1;
        slot |= 1;
        fType = (char*) slot;
    } else {
useCharStar:
        fType = (char*) sk_malloc_throw(typeLen + 1);
        SkASSERT(((size_t) fType & 1) == 0);
        memcpy(fType, type, typeLen);
        fType[typeLen] = 0;
    }
}

void SkEvent::setType(const SkString& type)
{
    setType(type.c_str());
}

////////////////////////////////////////////////////////////////////////////

#include "SkParse.h"

void SkEvent::inflate(const SkDOM& dom, const SkDOM::Node* node)
{
    const char* name = dom.findAttr(node, "type");
    if (name)
        this->setType(name);

    const char* value;
    if ((value = dom.findAttr(node, "fast32")) != NULL)
    {
        int32_t n;
        if (SkParse::FindS32(value, &n))
            this->setFast32(n);
    }

    for (node = dom.getFirstChild(node); node; node = dom.getNextSibling(node))
    {
        if (strcmp(dom.getName(node), "data"))
        {
            SkDEBUGCODE(SkDebugf("SkEvent::inflate unrecognized subelement <%s>\n", dom.getName(node));)
            continue;
        }

        name = dom.findAttr(node, "name");
        if (name == NULL)
        {
            SkDEBUGCODE(SkDebugf("SkEvent::inflate missing required \"name\" attribute in <data> subelement\n");)
            continue;
        }

        if ((value = dom.findAttr(node, "s32")) != NULL)
        {
            int32_t n;
            if (SkParse::FindS32(value, &n))
                this->setS32(name, n);
        }
        else if ((value = dom.findAttr(node, "scalar")) != NULL)
        {
            SkScalar x;
            if (SkParse::FindScalar(value, &x))
                this->setScalar(name, x);
        }
        else if ((value = dom.findAttr(node, "string")) != NULL)
            this->setString(name, value);
#ifdef SK_DEBUG
        else
        {
            SkDebugf("SkEvent::inflate <data name=\"%s\"> subelement missing required type attribute [S32 | scalar | string]\n", name);
        }
#endif
    }
}

#ifdef SK_DEBUG

    #ifndef SkScalarToFloat
        #define SkScalarToFloat(x)  ((x) / 65536.f)
    #endif

    void SkEvent::dump(const char title[])
    {
        if (title)
            SkDebugf("%s ", title);
            
        SkString    etype;
        this->getType(&etype);
        SkDebugf("event<%s> fast32=%d", etype.c_str(), this->getFast32());

        const SkMetaData&   md = this->getMetaData();
        SkMetaData::Iter    iter(md);
        SkMetaData::Type    mtype;
        int                 count;
        const char*         name;
        
        while ((name = iter.next(&mtype, &count)) != NULL)
        {
            SkASSERT(count > 0);

            SkDebugf(" <%s>=", name);
            switch (mtype) {
            case SkMetaData::kS32_Type:     // vector version???
                {
                    int32_t value;
                    md.findS32(name, &value);
                    SkDebugf("%d ", value);
                }
                break;
            case SkMetaData::kScalar_Type:
                {
                    const SkScalar* values = md.findScalars(name, &count, NULL);
                    SkDebugf("%f", SkScalarToFloat(values[0]));
                    for (int i = 1; i < count; i++)
                        SkDebugf(", %f", SkScalarToFloat(values[i]));
                    SkDebugf(" ");
                }
                break;
            case SkMetaData::kString_Type:
                {
                    const char* value = md.findString(name);
                    SkASSERT(value);
                    SkDebugf("<%s> ", value);
                }
                break;
            case SkMetaData::kPtr_Type:     // vector version???
                {
                    void*   value;
                    md.findPtr(name, &value);
                    SkDebugf("%p ", value);
                }
                break;
            case SkMetaData::kBool_Type:    // vector version???
                {
                    bool    value;
                    md.findBool(name, &value);
                    SkDebugf("%s ", value ? "true" : "false");
                }
                break;
            default:
                SkASSERT(!"unknown metadata type returned from iterator");
                break;
            }
        }
        SkDebugf("\n");
    }
#endif

///////////////////////////////////////////////////////////////////////////////////////

#ifdef SK_DEBUG
// #define SK_TRACE_EVENTSx
#endif

#ifdef SK_TRACE_EVENTS
    static void event_log(const char s[])
    {
        SkDEBUGF(("%s\n", s));
    }

    #define EVENT_LOG(s)        event_log(s)
    #define EVENT_LOGN(s, n)    do { SkString str(s); str.append(" "); str.appendS32(n); event_log(str.c_str()); } while (0)
#else
    #define EVENT_LOG(s)
    #define EVENT_LOGN(s, n)
#endif

#include "SkGlobals.h"
#include "SkThread.h"
#include "SkTime.h"

#define SK_Event_GlobalsTag     SkSetFourByteTag('e', 'v', 'n', 't')

class SkEvent_Globals : public SkGlobals::Rec {
public:
    SkMutex     fEventMutex;
    SkEvent*    fEventQHead, *fEventQTail;
    SkEvent*    fDelayQHead;
    SkDEBUGCODE(int fEventCounter;)
};

static SkGlobals::Rec* create_globals()
{
    SkEvent_Globals* rec = new SkEvent_Globals;
    rec->fEventQHead = NULL;
    rec->fEventQTail = NULL;
    rec->fDelayQHead = NULL;
    SkDEBUGCODE(rec->fEventCounter = 0;)
    return rec;
}

///////////////////////////////////////////////////////////////////////////////

void SkEvent::postDelay(SkMSec delay) {
    if (!fTargetID && !fTargetProc) {
        delete this;
        return;
    }
    
    if (delay) {
        this->postTime(SkTime::GetMSecs() + delay);
        return;
    }

    SkEvent_Globals& globals = *(SkEvent_Globals*)SkGlobals::Find(SK_Event_GlobalsTag, create_globals);

    globals.fEventMutex.acquire();
    bool wasEmpty = SkEvent::Enqueue(this);
    globals.fEventMutex.release();
    
    // call outside of us holding the mutex
    if (wasEmpty) {
        SkEvent::SignalNonEmptyQueue();
    }
}

void SkEvent::postTime(SkMSec time) {
    if (!fTargetID && !fTargetProc) {
        delete this;
        return;
    }

    SkEvent_Globals& globals = *(SkEvent_Globals*)SkGlobals::Find(SK_Event_GlobalsTag, create_globals);
    
    globals.fEventMutex.acquire();
    SkMSec queueDelay = SkEvent::EnqueueTime(this, time);
    globals.fEventMutex.release();
    
    // call outside of us holding the mutex
    if ((int32_t)queueDelay != ~0) {
        SkEvent::SignalQueueTimer(queueDelay);
    }
}

bool SkEvent::Enqueue(SkEvent* evt) {
    SkEvent_Globals& globals = *(SkEvent_Globals*)SkGlobals::Find(SK_Event_GlobalsTag, create_globals);
    //  gEventMutex acquired by caller

    SkASSERT(evt);

    bool wasEmpty = globals.fEventQHead == NULL;

    if (globals.fEventQTail)
        globals.fEventQTail->fNextEvent = evt;
    globals.fEventQTail = evt;
    if (globals.fEventQHead == NULL)
        globals.fEventQHead = evt;
    evt->fNextEvent = NULL;

    SkDEBUGCODE(++globals.fEventCounter);

    return wasEmpty;
}

SkEvent* SkEvent::Dequeue() {
    SkEvent_Globals& globals = *(SkEvent_Globals*)SkGlobals::Find(SK_Event_GlobalsTag, create_globals);
    globals.fEventMutex.acquire();

    SkEvent* evt = globals.fEventQHead;
    if (evt) {
        SkDEBUGCODE(--globals.fEventCounter);

        globals.fEventQHead = evt->fNextEvent;
        if (globals.fEventQHead == NULL) {
            globals.fEventQTail = NULL;
        }
    }
    globals.fEventMutex.release();

    return evt;
}

bool SkEvent::QHasEvents() {
    SkEvent_Globals& globals = *(SkEvent_Globals*)SkGlobals::Find(SK_Event_GlobalsTag, create_globals);

    // this is not thread accurate, need a semaphore for that
    return globals.fEventQHead != NULL;
}

#ifdef SK_TRACE_EVENTS
    static int gDelayDepth;
#endif

SkMSec SkEvent::EnqueueTime(SkEvent* evt, SkMSec time) {
    SkEvent_Globals& globals = *(SkEvent_Globals*)SkGlobals::Find(SK_Event_GlobalsTag, create_globals);
    //  gEventMutex acquired by caller

    SkEvent* curr = globals.fDelayQHead;
    SkEvent* prev = NULL;

    while (curr) {
        if (SkMSec_LT(time, curr->fTime)) {
            break;
        }
        prev = curr;
        curr = curr->fNextEvent;
    }

    evt->fTime = time;
    evt->fNextEvent = curr;
    if (prev == NULL) {
        globals.fDelayQHead = evt;
    } else {
        prev->fNextEvent = evt;
    }

    SkMSec delay = globals.fDelayQHead->fTime - SkTime::GetMSecs();
    if ((int32_t)delay <= 0) {
        delay = 1;
    }
    return delay;
}

///////////////////////////////////////////////////////////////////////////////

#include "SkEventSink.h"

bool SkEvent::ProcessEvent() {
    SkEvent*                evt = SkEvent::Dequeue();
    SkAutoTDelete<SkEvent>  autoDelete(evt);
    bool                    again = false;

    EVENT_LOGN("ProcessEvent", (int32_t)evt);

    if (evt) {
        (void)SkEventSink::DoEvent(*evt);
        again = SkEvent::QHasEvents();
    }
    return again;
}

void SkEvent::ServiceQueueTimer()
{
    SkEvent_Globals& globals = *(SkEvent_Globals*)SkGlobals::Find(SK_Event_GlobalsTag, create_globals);

    globals.fEventMutex.acquire();

    bool        wasEmpty = false;
    SkMSec      now = SkTime::GetMSecs();
    SkEvent*    evt = globals.fDelayQHead;

    while (evt)
    {
        if (SkMSec_LT(now, evt->fTime))
            break;

#ifdef SK_TRACE_EVENTS
        --gDelayDepth;
        SkDebugf("dequeue-delay %s (%d)", evt->getType(), gDelayDepth);
        const char* idStr = evt->findString("id");
        if (idStr)
            SkDebugf(" (%s)", idStr);
        SkDebugf("\n");
#endif

        SkEvent* next = evt->fNextEvent;
        if (SkEvent::Enqueue(evt))
            wasEmpty = true;
        evt = next;
    }
    globals.fDelayQHead = evt;

    SkMSec time = evt ? evt->fTime - now : 0;

    globals.fEventMutex.release();

    if (wasEmpty)
        SkEvent::SignalNonEmptyQueue();

    SkEvent::SignalQueueTimer(time);
}

int SkEvent::CountEventsOnQueue() {
    SkEvent_Globals& globals = *(SkEvent_Globals*)SkGlobals::Find(SK_Event_GlobalsTag, create_globals);
    globals.fEventMutex.acquire();
    
    int count = 0;
    const SkEvent* evt = globals.fEventQHead;
    while (evt) {
        count += 1;
        evt = evt->fNextEvent;
    }
    globals.fEventMutex.release();

    return count;
}

////////////////////////////////////////////////////////////////

void SkEvent::Init()
{
}

void SkEvent::Term()
{
    SkEvent_Globals& globals = *(SkEvent_Globals*)SkGlobals::Find(SK_Event_GlobalsTag, create_globals);

    SkEvent* evt = globals.fEventQHead;
    while (evt)
    {
        SkEvent* next = evt->fNextEvent;
        delete evt;
        evt = next;
    }

    evt = globals.fDelayQHead;
    while (evt)
    {
        SkEvent* next = evt->fNextEvent;
        delete evt;
        evt = next;
    }
}

