First this is the cheat, and I say cheat because it cheats built in language security of classes protected\private functionality, that I used to make my profiler possable. The rest of my system is like ok; its another profiler what ever, but personally i did this because its used in a system where it MUST NOT KNOW the type it is contained in. Otherwise i would not go to the trouble, although for code reuse its fine. Ok here is how i let my profiler gain access to the profiler sample of any object in my engine\modules\game. Platform::u64 btw is a unsigned 64bit simple data type, declaration was encapsulated by Platform namespace(just posting my code exactly as it is sorry if its weird i ALWAYS do my own basic data types and never use data containers\interface\whatever directly but typedef my own types that i need to use them for end user\me\its just plain safer and looks cleaner plus the data type itself contains more information saying so much more why not)
#define SCRUT_PROFILERSAMPLE_INTERFACE_DECLARATION private: Scrut_ProfiledObject_AccessGrant m_sScrut_ProfiledObject_AccessGrant; public:class CProfilerSample;typedef ProfilerSample* ProfilerSamplePointer;typedef std::list< ProfilerSamplePointer > ProfilerSampleList;typedef ProfilerSampleList::iterator ProfilerSampleIterator;struct Scrut_ProfiledObject_AccessGrant;typedef Scrut_ProfiledObject_AccessGrant* Scrut_ProfiledObject_ProfilerSamplePointer;typedef std::list< Scrut_ProfiledObject_AccessGrantPointer > Scrut_ProfiledObject_AccessGrantList;typedef Scrut_ProfiledObject_AccessGrantList::iterator Scrut_ProfiledObject_AccessGrantIterator;struct Scrut_ProfiledObject_AccessGrant { Scrut_ProfiledObject_AccessGrantPointer m_pstParentObject; Scrut_ProfiledObject_AccessGrantList m_tpstNestedObject; ProfilerSampleList m_tpProfilerSampleTable; Scrut_ProfilerSample_CreateList(); Scrut_ProfilerSample_DestroyList(); Scrut_ProfilerSample_Register( Platform::u64, ProfilerSamplePointer ); Scrut_ProfilerSample_Obtain( Platform::u64 );};
Then inside the Scrut::System::CProfilerSample declaration i place SCRUT_PROFILERSAMPLE_INTERFACE_DECLARATION like so at the beginning. MUST BE AT BEGINNING so its does not run time error on ya. I assume the structure in memory will offset the memory address of say your object by 0. You can NEVER know the offset if this if it was after a section of data sense it does not know the objects its working with so they might just throw in another 32 bit variable and WAM addresses change. This should be very obvious sorry, this design is all soooooooo simple and i made it to be just 5 seconds of coding to get most reward in the end. AUTO_SIZE just declares and defines the implementation of functionality to take the size of your object, should be obvious but not needed for this class in particular just included for fullness and making everything uniform and its meant for a designed system, which i will not show you currently because i am writing up the past already, to be able to function and could not without it not going into it as u need not know my engine i am using at this current moment on such a lovely day. Again only included to keep what i have coded and what posted identical.
class CProfilerSample {SCRUT_PROFILERSAMPLE_INTERFACE_DECLARATIONAUTO_SIZE
Do the same with every object in your program and u can profile every method of your implementation, sorry not included declarations so u can profiler functions. I wanted to get some feedback on the design in the way of how i made it able to work with objects that it cant know anything about as far as type identification. And i do not wanna make a uniform interface for all objects and do more polymorphism when i have a uniform object interface for all objects at another layer so i refuse(u cant make me wanna try!?!?!) make a uniform interface for a uniform interface.
Other part i will explain is really helpful on how it initializes at start of your methods\function. a Macro is used to declare a CProfilerSamplePointer and initialize its value. it just check if a method with that identifier for that particular Scrut::System::CProfilerSample is already on the parent's CProfilerSampleList within the Scrut::System::Scrut_ProfiledObject_AccessGrant structer if not it allocates one initializes it and pass it back, if it is in the list then it just passes back the current instance of that particular Scrut::System::CProfilerSample. also have a macro for the footer of your function at the very end of everything u wanna profile which when profiling functions and all that good stuff i pretty much leave this after every last line of code contain in that function.
and here is the rest of what i will go into now. just ask and ill explain the rest if you want but this i am explaining to much and sure this is prob just the opposite of elite so u do not need to tell me "hey this is not state of the art!" because yes i know i came up with this in 5 seconds and coded it in 5 seconds so its prob gimp. But here is the rest for now.
more macros exists, made it simplistic, for the purpose of being referenced and placed inside the objects constructor where it creates one Scrut::System::CProfilerSample for the object by default. You have one sample that has the information per object then the following samples in the std:list are place by the flow and order of there execution at run time so u then have statistics about whats this or that function did then u have the summations of all the data processed into one representation. but u must pass every object declared in that object too the macro system adding them to the Scrut::System::Scrut_ProfiledObject_AccessGrant::m_tpstNestedObject list and during this it just happens to also obviously u can guess it sets the Scrut::System::Scrut_ProfiledObject_AccessGrant::m_pstParentObject to the value of this sense this is done inside the parent objects constructor but not inside the children(nested objects), aka jumping execution(calling a function or procedure) and doing it a stupid way like passing the parent object's memory address or value of "this" as a argument to the subset. I built the tree so you can very easy without doing weird code watch the values during debug but also so i can make my life easier as i did not want to have this interact with my stream system which would let you not make the tree in memory at run time to print the values. This setup allows me to traverse the tree up and down where ever i need to go plus you need to know your parent so if you took x ms execution time with your current sample then you must update your parent with this new information so it actually works and not just useless functionality for no reason.
Ok well already spent more time writing this than i spent on the profiler WOW. Well anyways tell me what you guys think, and yes i expect well you should of done it this way your going to get this manifestation or error and your a noob. But hey all is well so here you go. Want any more info feel free to ask i will jump straight over to you and get you where you need to go as if you need help with a profiler(simplest things really so easy anyone can do it) i explain what ever i can also give you a version that excludes all the extra functionality so u can learn what your doing which actually i do not see happening as this stuff is really 100% straight beginner level.
[Edited by - Scrut on October 17, 2010 12:04:15 PM]