187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger
21cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/*
31cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Copyright 2010 Google Inc.
41cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger *
51cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Use of this source code is governed by a BSD-style license that can be
61cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * found in the LICENSE file.
787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger */
887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger
91cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger#ifndef SkTRelay_DEFINED
1187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger#define SkTRelay_DEFINED
1287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger
1387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger#include "SkRefCnt.h"
1487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger
1587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger/**
1687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger *  Similar to a weakptr in java, a Relay allows for a back-ptr to an
1787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger *  object to be "safe", without using a hard reference-count.
1887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger *
1987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger *  Typically, the target creates a Relay with a pointer to itself. Whenever it
2087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger *  wants to have another object maintain a safe-ptr to it, it gives them a
2187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger *  Relay, which they ref()/unref(). Through the Relay each external object can
2287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger *  retrieve a pointer to the Target. However, when the Target goes away, it
2387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger *  clears the Relay pointer to it (relay->set(NULL)) and then unref()s the
2487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger *  Relay. The other objects still have a ref on the Relay, but now when they
2587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger *  call get() the receive a NULL.
2687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger */
2787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergertemplate <template T> class SkTRelay : public SkRefCnt {
2887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergerpublic:
2987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    SkTRelay(T* ptr) : fPtr(ptr) {}
3087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger
3187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    // consumers call this
3287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    T* get() const { return fPtr; }
3387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger
3487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    // producer calls this
3587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    void set(T* ptr) { fPtr = ptr; }
3687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger
3787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    void clear() { this->set(NULL); }
3887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger
3987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergerprivate:
4087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    T* fPtr;
4187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger};
4287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger
4387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger#endif
44