/*
 * Copyright (C) 2009 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef ANDROID_RS_OBJECT_BASE_H
#define ANDROID_RS_OBJECT_BASE_H

#include "rsUtils.h"

#define RS_OBJECT_DEBUG 0

#if RS_OBJECT_DEBUG
    #include <utils/CallStack.h>
#endif

namespace android {
namespace renderscript {

class Context;
class OStream;

// An element is a group of Components that occupies one cell in a structure.
class ObjectBase
{
public:
    ObjectBase(Context *rsc);

    void incSysRef() const;
    bool decSysRef() const;

    void incUserRef() const;
    bool decUserRef() const;
    bool zeroUserRef() const;

    static bool checkDelete(const ObjectBase *);

    const char * getName() const {
        return mName.string();
    }
    void setName(const char *);
    void setName(const char *, uint32_t len);

    Context * getContext() const {return mRSC;}

    static void zeroAllUserRef(Context *rsc);
    static void dumpAll(Context *rsc);

    virtual void dumpLOGV(const char *prefix) const;
    virtual void serialize(OStream *stream) const = 0;
    virtual RsA3DClassID getClassId() const = 0;

    static bool isValid(const Context *rsc, const ObjectBase *obj);

    // The async lock is taken during object creation in non-rs threads
    // and object deletion in the rs thread.
    static void asyncLock();
    static void asyncUnlock();

protected:
    // Called inside the async lock for any object list management that is
    // necessary in derived classes.
    virtual void preDestroy() const;

    Context *mRSC;
    virtual ~ObjectBase();

private:
    static pthread_mutex_t gObjectInitMutex;

    void add() const;
    void remove() const;

    String8 mName;
    mutable int32_t mSysRefCount;
    mutable int32_t mUserRefCount;

    mutable const ObjectBase * mPrev;
    mutable const ObjectBase * mNext;

#if RS_OBJECT_DEBUG
    CallStack mStack;
#endif

};

template<class T>
class ObjectBaseRef
{
public:
    ObjectBaseRef() {
        mRef = NULL;
    }

    ObjectBaseRef(const ObjectBaseRef &ref) {
        mRef = ref.get();
        if (mRef) {
            mRef->incSysRef();
        }
    }

    ObjectBaseRef(T *ref) {
        mRef = ref;
        if (mRef) {
            ref->incSysRef();
        }
    }

    ObjectBaseRef & operator= (const ObjectBaseRef &ref) {
        return ObjectBaseRef(ref);
    }

    ~ObjectBaseRef() {
        clear();
    }

    void set(T *ref) {
        if (mRef != ref) {
            clear();
            mRef = ref;
            if (mRef) {
                ref->incSysRef();
            }
        }
    }

    void set(const ObjectBaseRef &ref) {
        set(ref.mRef);
    }

    void clear() {
        if (mRef) {
            mRef->decSysRef();
        }
        mRef = NULL;
    }

    inline T * get() const {
        return mRef;
    }

    inline T * operator-> () const {
        return mRef;
    }

protected:
    T * mRef;

};


}
}

#endif //ANDROID_RS_OBJECT_BASE_H

