js/ipc/ContextWrapperChild.h
author Robert Longson <longsonr@gmail.com>
Fri, 01 Jun 2012 16:53:57 -0700
changeset 99658 123be65017577f98542852fc557efa66581100f7
parent 98529 f4157e8c410708d76703f19e4dfb61859bfe32d8
child 139479 5bf9771e1a2830d8ef70114b31e4219164f9c5e0
permissions -rw-r--r--
Bug 758505, Part 3: Avoid unnecessary invalidations on repeated calls to set the same animated value (for SMIL animations of CSS, mapped attrs, and motion). r=dholbert

/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
 * vim: set ts=8 sw=4 et tw=80:
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef mozilla_jsipc_ContextWrapperChild_h__
#define mozilla_jsipc_ContextWrapperChild_h__

#include "mozilla/jsipc/PContextWrapperChild.h"
#include "mozilla/jsipc/ObjectWrapperChild.h"

#include "jsapi.h"
#include "nsClassHashtable.h"
#include "nsHashKeys.h"

namespace mozilla {
namespace jsipc {

class ContextWrapperChild
    : public PContextWrapperChild
{
public:

    ContextWrapperChild(JSContext* cx)
        : mContext(cx)
    {
        mResidentObjectTable.Init();
    }

    JSContext* GetContext() { return mContext; }

    PObjectWrapperChild* GetOrCreateWrapper(JSObject* obj,
                                            bool makeGlobal = false)
    {
        if (!obj) // Don't wrap nothin'!
            return NULL;
        PObjectWrapperChild* wrapper;
        while (!mResidentObjectTable.Get(obj, &wrapper)) {
            wrapper = SendPObjectWrapperConstructor(AllocPObjectWrapper(obj),
                                                    makeGlobal);
            if (wrapper)
                mResidentObjectTable.Put(obj, wrapper);
            else
                return NULL;
        }
        return wrapper;
    }

protected:

    PObjectWrapperChild* AllocPObjectWrapper(JSObject* obj) {
        return new ObjectWrapperChild(mContext, obj);
    }
    
    PObjectWrapperChild* AllocPObjectWrapper(const bool&) {
        return AllocPObjectWrapper(JS_GetGlobalObject(mContext));
    }

    bool DeallocPObjectWrapper(PObjectWrapperChild* actor) {
        ObjectWrapperChild* owc = static_cast<ObjectWrapperChild*>(actor);
        mResidentObjectTable.Remove(owc->GetJSObject());
        return true;
    }

private:

    JSContext* const mContext;

    nsClassHashtable<nsPtrHashKey<JSObject>,
                     PObjectWrapperChild> mResidentObjectTable;

};

}}

#endif