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