//*** CUACount -- user-assistance counter w/ decay // #define XXX_DELETE 1 #define XXX_VERSIONED 0 //*** NRW -- named i/o // DESCRIPTION // i/o to a 'named' location (e.g. registry) typedef struct { void *self; LPCTSTR pszName; } NRWINFO, *PNRWINFO; typedef HRESULT (*PFNNRW)(void *pvBuf, DWORD cbBuf, PNRWINFO prwi); typedef struct { PFNNRW _pfnRead; PFNNRW _pfnWrite; PFNNRW _pfnDelete; } FNNRW3, *PFNNRW3; //*** UAQ_* -- quantum // NOTES // todo: for now everything is flat typedef enum { UAQ_TASK=0, UAQ_DOC=0, UAQ_APP=0, UAQ_SESSION=0 } UAQUANTUM; #define UAQ_DEFAULT UAQ_SESSION // currently implemented quanta #define UAQ_COUNT (UAQ_SESSION + 1) typedef DWORD UATIME; // 1 minute (approx) #define UAT_MINUTE1 ((UATIME)1) // 1 minute #define UAT_HOUR12 ((UATIME)(12 * 60)) // 12 hours (see FTToUATime) extern UATIME GetUaTime(LPSYSTEMTIME pst); //*** UATTOMSEC -- convert UATIME to mSec's // NOTES // ISSUE: we should be more accurate. currently we just assume a UATIME // is exactly 1 minute, which it's not... easy enough to do, but we'll // wait until i have time to do the math. #define UATTOMSEC(uat) ((uat) * 60 * 1000) class IUASession { public: virtual void SetSession(UAQUANTUM uaq, BOOL fForce) PURE; virtual int GetSessionId() PURE; }; class CUASession : public IUASession { struct SUASession { #if XXX_VERSIONED UINT _cbSize; #endif UATIME _qtMru; int _cCnt; }; public: void SetSession(UAQUANTUM uaq, BOOL fForce); int GetSessionId(); CUASession(); // n.b. public so can stack-alloc HRESULT Initialize(); HRESULT LoadFrom(PFNNRW3 pfnIO, PNRWINFO pRwi); HRESULT SaveTo(BOOL fForce, PFNNRW3 pfnIO, PNRWINFO pRwi); protected: // for xfers directly into me w/o an extra copy-ctor // e.g. p->QueryValue(pszName, aUac.GetRawData(), &cb); // e.g. p->SetValue (pszName, aUac.GetRawData(), aUac.GetRawCount()); _inline BYTE * _GetRawData() { return (BYTE *)&_qtMru; }; _inline DWORD _GetRawCount() { return SIZEOF(SUASession); }; //struct SUASession { #if XXX_VERSIONED UINT _cbSize; #endif UATIME _qtMru; int _cCnt; //}; BITBOOL _fInited : 1; // 1:we've been initialized BITBOOL _fDirty : 1; // 1:save me (e.g. _sidMru was xformed) }; // all special values are < 0 for easy check #define SID_SNOWREAD (-1) // like SID_SNOWINIT, but no auto-save #define SID_SNOWINIT (-2) // convert to 'now' on 1st read #define SID_SNOWALWAYS (-3) // always 'now' #define ISSID_SSPECIAL(s) ((int)(s) < 0) // tunable values for IncCount (talk to your neighborhood PM) #define UAC_NEWCOUNT 2 // brand-new count starts from here #define UAC_MINCOUNT 6 // incr to a minimum of this class CUACount { // must match CUACount semi-embedded struct struct SUACount { #define UAC_d0 _sidMruDisk #if XXX_VERSIONED #undef UAC_d0 #define UAC_d0 _cbSize UINT _cbSize; #endif UINT _sidMruDisk; // MRU for this entry // todo: eventually we'll want task,doc,app,session // so this will be _cCnt[UAQ_COUNT], and we'll index by _cCnt[quanta] int _cCnt; // use count (lazily decayed) FILETIME _ftExecuteTime; }; public: CUACount(); // n.b. public so can stack-alloc HRESULT Initialize(IUASession *puas); HRESULT LoadFrom(PFNNRW3 pfnIO, PNRWINFO pRwi); HRESULT SaveTo(BOOL fForce, PFNNRW3 pfnIO, PNRWINFO pRwi); #ifdef DEBUG BOOL DBIsInit(); #endif int GetCount(); void IncCount(); void AddCount(int i); void SetCount(int cCnt); void UpdateFileTime(); FILETIME GetFileTime(); void SetFileTime(const FILETIME *pft); // most people should *not* call these void _SetMru(UINT sidMru) { _sidMruDisk = sidMru; Initialize(_puas); }; int _GetCount() { return _cCnt; }; #if XXX_DELETE DWORD _SetFlags(DWORD dwMask, DWORD dwValue); #define UACF_INHERITED 0x01 #define UACF_NODECAY 0x02 #endif protected: int _DecayCount(BOOL fWrite); UINT _ExpandSpecial(UINT sidMru); // for xfers directly into me w/o an extra copy-ctor // e.g. p->QueryValue(pszName, aUac.GetRawData(), &cb); // e.g. p->SetValue (pszName, aUac.GetRawData(), aUac.GetRawCount()); _inline BYTE * _GetRawData() { return (BYTE *)&UAC_d0; }; _inline DWORD _GetRawCount() { return SIZEOF(SUACount); }; // struct SUACount { #if XXX_VERSIONED UINT _cbSize; // SIZEOF #endif UINT _sidMruDisk; // MRU for this entry // todo: eventually we'll want task,doc,app,session // so this will be cCnt[UAQ_COUNT], and we'll index by cCnt[quanta] int _cCnt; // use count (lazily decayed) FILETIME _ftExecuteTime; // } UINT _sidMru; // MRU for this entry IUASession * _puas; // session callback BITBOOL _fInited : 1; // 1:we've been initialized BITBOOL _fDirty : 1; // 1:save me (e.g. _sidMru was xformed) #if XXX_DELETE BITBOOL _fInherited : 1; // 1:we didn't exist #else BITBOOL _fUnused : 1; #endif BITBOOL _fNoDecay : 1; // 1:don't decay me BITBOOL _fNoPurge : 1; // 1:don't auto-delete me (debug) private: };