mirror of
https://github.com/justinian/jsix.git
synced 2025-12-10 08:24:32 -08:00
Handles already had a field for badge, but did not touch it in the constructors or in assignment operators.
100 lines
2.8 KiB
C++
100 lines
2.8 KiB
C++
#pragma once
|
|
/// \file handle.h
|
|
/// Definition of kobject handles
|
|
|
|
#include <j6/types.h>
|
|
#include "objects/kobject.h"
|
|
|
|
namespace obj {
|
|
|
|
struct handle
|
|
{
|
|
constexpr static uint64_t id_mask = 0x00000000ffffffff;
|
|
constexpr static uint64_t cap_mask = 0x00ffffff00000000;
|
|
constexpr static uint64_t type_mask = 0xff00000000000000;
|
|
|
|
constexpr static unsigned cap_shift = 32;
|
|
constexpr static unsigned type_shift = 56;
|
|
|
|
// A j6_handle_t is an id in the low 32 bits, caps in bits 32-55, and type in 56-63
|
|
static inline j6_handle_t make_id(j6_handle_t id, j6_cap_t caps, kobject *obj) {
|
|
return (id & 0xffffffffull) |
|
|
((static_cast<j6_handle_t>(caps) << cap_shift) & cap_mask) |
|
|
static_cast<j6_handle_t>(obj ? obj->get_type() : kobject::type::none) << type_shift;
|
|
}
|
|
|
|
inline handle() : id {j6_handle_invalid}, badge {0}, object {nullptr} {}
|
|
|
|
inline handle(j6_handle_t in_id, kobject *in_obj, j6_cap_t caps, uint64_t in_badge = 0) :
|
|
id {make_id(in_id, caps, in_obj)}, badge {in_badge}, object {in_obj} {
|
|
if (object) object->handle_retain();
|
|
}
|
|
|
|
inline handle(const handle &o) :
|
|
id {o.id}, badge {o.badge}, object {o.object} {
|
|
if (object) object->handle_retain();
|
|
}
|
|
|
|
inline handle(handle &&o) :
|
|
id {o.id}, badge {o.badge}, object {o.object} {
|
|
o.id = 0;
|
|
o.object = nullptr;
|
|
}
|
|
|
|
inline handle & operator=(const handle &o) {
|
|
if (object) object->handle_release();
|
|
id = o.id; badge = o.badge; object = o.object;
|
|
if (object) object->handle_retain();
|
|
return *this;
|
|
}
|
|
|
|
inline handle & operator=(handle &&o) {
|
|
if (object) object->handle_release();
|
|
id = o.id; badge = o.badge; object = o.object;
|
|
o.id = 0; o.badge = 0; o.object = nullptr;
|
|
return *this;
|
|
}
|
|
|
|
inline ~handle() {
|
|
if (object) object->handle_release();
|
|
}
|
|
|
|
inline j6_cap_t caps() const { return (id & cap_mask) >> cap_shift; }
|
|
|
|
inline bool has_cap(j6_cap_t test) const {
|
|
return (caps() & test) == test;
|
|
}
|
|
|
|
inline kobject::type type() const {
|
|
return static_cast<kobject::type>(id >> 56);
|
|
}
|
|
|
|
inline int compare(const handle &o) {
|
|
return id > o.id ? 1 : id < o.id ? -1 : 0;
|
|
}
|
|
|
|
template <typename T>
|
|
inline T * as() {
|
|
if (type() != T::type) return nullptr;
|
|
return reinterpret_cast<T*>(object);
|
|
}
|
|
|
|
template <typename T>
|
|
inline const T * as() const {
|
|
if (type() != T::type) return nullptr;
|
|
return reinterpret_cast<const T*>(object);
|
|
}
|
|
|
|
template <>
|
|
inline kobject * as<kobject>() { return object; }
|
|
|
|
template <>
|
|
inline const kobject * as<kobject>() const { return object; }
|
|
|
|
j6_handle_t id;
|
|
uint64_t badge;
|
|
kobject *object;
|
|
};
|
|
|
|
} // namespace obj
|