summaryrefslogtreecommitdiff
path: root/source/core/slang-destroyable.h
blob: f2c9670716199faea8635c809d5efc146ad38a54 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#ifndef SLANG_CORE_DESTROYABLE_H
#define SLANG_CORE_DESTROYABLE_H

#include "slang-string.h"

#include "../../slang-com-helper.h"
#include "../../slang-com-ptr.h"

namespace Slang
{

/* An interface that allows for an object to implement 'destruction'. A destroyed 
interface/object should release any other contained references. 
Behavior of an interface that is IDestroyed should be defined on the interface. Typically 
it will produce an assert on debug builds. 
Calling destroy/isDestroyed can always be performed. */
class IDestroyable : public ICastable
{
    SLANG_COM_INTERFACE(0x99c6228e, 0xa82, 0x43eb, { 0x8f, 0xd1, 0xf3, 0x54, 0x3e, 0x2e, 0x86, 0xc0 } );

        /// Destroy. Can call on destroyed - is a no op.
    virtual SLANG_NO_THROW void SLANG_MCALL destroy() = 0;
        /// Once destroyed *no* functionality is supported other than IUnknown and destroy/isDestroyed
    virtual SLANG_NO_THROW bool SLANG_MCALL isDestroyed() = 0;
};

// Dynamic cast of ICastable derived types
template <typename T>
SLANG_FORCE_INLINE T* dynamicCast(ICastable* castable)
{
    if (castable)
    {
        void* obj = castable->castAs(T::getTypeGuid());
        return obj ? reinterpret_cast<T*>(obj) : ((T*)nullptr);
    }
    return nullptr;
}

// as style cast
template <typename T>
SLANG_FORCE_INLINE T* as(ICastable* castable)
{
    if (castable)
    {
        void* obj = castable->castAs(T::getTypeGuid());
        return obj ? reinterpret_cast<T*>(obj) : ((T*)nullptr);
    }
    return nullptr;
}

// A way to clone an interface (that derives from IClonable) such that it returns an interface 
// of the same type.
template <typename T>
SLANG_FORCE_INLINE ComPtr<T> cloneInterface(T* in)
{
    SLANG_ASSERT(in);
    // Must be derivable from clonable
    IClonable* clonable = in;
    // We can clone with the same interface
    T* clone = (T*)clonable->clone(T::getTypeGuid());
    // Clone must exist
    SLANG_ASSERT(clone);
    return ComPtr<T>(clone);
}

}

#endif // SLANG_CORE_DESTROYABLE_H