SkInstCnt.h revision 4d73ac22a1b99402fc8cff78a4eb4b27aa8fe019
1f6747b0b90b3a270ec7b7bdfdc211cf5c19f28c2robertphillips@google.com/*
2f6747b0b90b3a270ec7b7bdfdc211cf5c19f28c2robertphillips@google.com * Copyright 2012 Google Inc.
3f6747b0b90b3a270ec7b7bdfdc211cf5c19f28c2robertphillips@google.com *
4f6747b0b90b3a270ec7b7bdfdc211cf5c19f28c2robertphillips@google.com * Use of this source code is governed by a BSD-style license that can be
5f6747b0b90b3a270ec7b7bdfdc211cf5c19f28c2robertphillips@google.com * found in the LICENSE file.
6977b9c8af3ef1b9a2fa2a0037cf3734cf2ba13d9robertphillips@google.com */
7977b9c8af3ef1b9a2fa2a0037cf3734cf2ba13d9robertphillips@google.com
8977b9c8af3ef1b9a2fa2a0037cf3734cf2ba13d9robertphillips@google.com
9977b9c8af3ef1b9a2fa2a0037cf3734cf2ba13d9robertphillips@google.com#ifndef SkInstCnt_DEFINED
10977b9c8af3ef1b9a2fa2a0037cf3734cf2ba13d9robertphillips@google.com#define SkInstCnt_DEFINED
11977b9c8af3ef1b9a2fa2a0037cf3734cf2ba13d9robertphillips@google.com
12977b9c8af3ef1b9a2fa2a0037cf3734cf2ba13d9robertphillips@google.com/*
13977b9c8af3ef1b9a2fa2a0037cf3734cf2ba13d9robertphillips@google.com * The instance counting system consists of three macros that create the
14977b9c8af3ef1b9a2fa2a0037cf3734cf2ba13d9robertphillips@google.com * instance counting machinery. A class is added to the system by adding:
154d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com *   SK_DECLARE_INST_COUNT at the top of its declaration for derived classes
164d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com *   SK_DECLARE_INST_COUNT_ROOT at the top of its declaration for a root class
174d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com *   SK_DEFINE_INST_COUNT at the top of its .cpp file (for both kinds).
184d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com * At the end of an application a call to all the "root" objects'
194d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com * CheckInstanceCount methods should be made
20977b9c8af3ef1b9a2fa2a0037cf3734cf2ba13d9robertphillips@google.com */
21977b9c8af3ef1b9a2fa2a0037cf3734cf2ba13d9robertphillips@google.com#ifdef SK_DEBUG
224d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com#include "SkTArray.h"
234d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com
244d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com#define SK_DECLARE_INST_COUNT(className)                                    \
254d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com    SK_DECLARE_INST_COUNT_INTERNAL(className,                               \
264d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com                                INHERITED::AddInstChild(CheckInstanceCount);)
274d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com
284d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com#define SK_DECLARE_INST_COUNT_ROOT(className)                               \
294d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com    SK_DECLARE_INST_COUNT_INTERNAL(className, ;)
304d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com
314d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com#define SK_DECLARE_INST_COUNT_INTERNAL(className, initStep)                 \
324d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com    class SkInstanceCountHelper {                                           \
334d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com    public:                                                                 \
344d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com        typedef void (*PFCheckInstCnt)();                                   \
354d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com        SkInstanceCountHelper() {                                           \
364d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com            if (!gInited) {                                                 \
374d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com                initStep                                                    \
384d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com                gInited = true;                                             \
394d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com            }                                                               \
404d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com            gInstanceCount++;                                               \
414d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com        }                                                                   \
424d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com                                                                            \
434d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com        SkInstanceCountHelper(const SkInstanceCountHelper& other) {         \
444d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com            gInstanceCount++;                                               \
454d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com        }                                                                   \
464d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com                                                                            \
474d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com        ~SkInstanceCountHelper() {                                          \
484d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com            gInstanceCount--;                                               \
494d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com        }                                                                   \
504d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com                                                                            \
514d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com        static int32_t gInstanceCount;                                      \
524d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com        static bool gInited;                                                \
534d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com        static SkTArray<PFCheckInstCnt> gChildren;                          \
544d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com    } fInstanceCountHelper;                                                 \
554d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com                                                                            \
564d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com    static void CheckInstanceCount() {                                      \
574d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com        if (0 != SkInstanceCountHelper::gInstanceCount) {                   \
584d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com            SkDebugf("Leaked %s objects: %d\n", #className,                 \
594d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com                     SkInstanceCountHelper::gInstanceCount);                \
604d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com        }                                                                   \
614d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com        for (int i = 0; i < SkInstanceCountHelper::gChildren.count(); ++i) { \
624d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com            (*SkInstanceCountHelper::gChildren[i])();                       \
634d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com        }                                                                   \
644d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com    }                                                                       \
654d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com                                                                            \
664d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com    static void AddInstChild(SkInstanceCountHelper::PFCheckInstCnt          \
674d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com                                                       childCheckInstCnt) { \
684d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com        if (CheckInstanceCount != childCheckInstCnt) {                      \
694d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com            SkInstanceCountHelper::gChildren.push_back(childCheckInstCnt);  \
704d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com        }                                                                   \
71977b9c8af3ef1b9a2fa2a0037cf3734cf2ba13d9robertphillips@google.com    }
72977b9c8af3ef1b9a2fa2a0037cf3734cf2ba13d9robertphillips@google.com
734d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com#define SK_DEFINE_INST_COUNT(className)                                     \
744d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com    int32_t className::SkInstanceCountHelper::gInstanceCount = 0;           \
754d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com    bool className::SkInstanceCountHelper::gInited = false;                 \
764d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com    SkTArray<className::SkInstanceCountHelper::PFCheckInstCnt>              \
774d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com                        className::SkInstanceCountHelper::gChildren;
78977b9c8af3ef1b9a2fa2a0037cf3734cf2ba13d9robertphillips@google.com
79977b9c8af3ef1b9a2fa2a0037cf3734cf2ba13d9robertphillips@google.com#else
804d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com#define SK_DECLARE_INST_COUNT(className)
814d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com#define SK_DECLARE_INST_COUNT_ROOT(className)
824d73ac22a1b99402fc8cff78a4eb4b27aa8fe019robertphillips@google.com#define SK_DEFINE_INST_COUNT(className)
83977b9c8af3ef1b9a2fa2a0037cf3734cf2ba13d9robertphillips@google.com#endif
84977b9c8af3ef1b9a2fa2a0037cf3734cf2ba13d9robertphillips@google.com
85977b9c8af3ef1b9a2fa2a0037cf3734cf2ba13d9robertphillips@google.com#endif // SkInstCnt_DEFINED
86