/** * PANDA 3D SOFTWARE * Copyright (c) Carnegie Mellon University. All rights reserved. * * All use of this software is subject to the terms of the revised BSD * license. You should have received a copy of this license along * with this source code in a file named "LICENSE." * * @file nodePointerToBase.I * @author drose * @date 2005-05-07 */ /** * */ template INLINE NodePointerToBase:: NodePointerToBase(To *ptr) { reassign(ptr); } /** * */ template INLINE NodePointerToBase:: NodePointerToBase(const NodePointerToBase ©) { reassign(copy); } /** * */ template INLINE NodePointerToBase:: ~NodePointerToBase() { reassign(nullptr); } /** * */ template INLINE NodePointerToBase:: NodePointerToBase(NodePointerToBase &&from) noexcept { _void_ptr = from._void_ptr; from._void_ptr = nullptr; } /** * This version of reassign is called when a NodePointerTo is assigned to this * Node PointerTo as an rvalue. In this case, we can steal the reference * count from the other PointerTo, without needing to call ref() and unref() * unnecessarily. */ template INLINE void NodePointerToBase:: reassign(NodePointerToBase &&from) noexcept { To *old_ptr = (To *)this->_void_ptr; this->_void_ptr = from._void_ptr; from._void_ptr = nullptr; // Now delete the old pointer. if (old_ptr != nullptr) { node_unref_delete(old_ptr); } } /** * This is the main work of the NodePointerTo family. When the pointer is * reassigned, decrement the old reference count and increment the new one. */ template void NodePointerToBase:: reassign(To *ptr) { if (ptr != (To *)_void_ptr) { // First save the old pointer; we won't delete it until we have assigned // the new one. We do this just in case there are cascading effects from // deleting this pointer that might inadvertently delete the new one. // (Don't laugh--it's happened!) To *old_ptr = (To *)_void_ptr; _void_ptr = (void *)ptr; if (ptr != nullptr) { ptr->node_ref(); #ifdef DO_MEMORY_USAGE if (MemoryUsage::get_track_memory_usage()) { // Make sure the MemoryUsage record knows what the TypeHandle is, if // we know it ourselves. TypeHandle type = get_type_handle(To); if (type == TypeHandle::none()) { do_init_type(To); type = get_type_handle(To); } if (type != TypeHandle::none()) { MemoryUsage::update_type(ptr, type); } } #endif } // Now delete the old pointer. if (old_ptr != nullptr) { node_unref_delete(old_ptr); } } } /** * */ template INLINE void NodePointerToBase:: reassign(const NodePointerToBase ©) { reassign((To *)copy._void_ptr); } /** * A convenient way to set the NodePointerTo object to NULL. (Assignment to a * NULL pointer also works, of course.) */ template INLINE void NodePointerToBase:: clear() { reassign(nullptr); } /** * A handy function to output NodePointerTo's as a hex pointer followed by a * reference count. */ template INLINE void NodePointerToBase:: output(std::ostream &out) const { out << _void_ptr; if (_void_ptr != nullptr) { out << ":" << ((To *)_void_ptr)->get_node_ref_count() << "/" << ((To *)_void_ptr)->get_ref_count(); } }