00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifndef _COMPPLUGINCLASSHANDLER_H
00027 #define _COMPPLUGINCLASSHANDLER_H
00028
00029 #include <typeinfo>
00030 #include <boost/preprocessor/cat.hpp>
00031
00032 #include <compiz.h>
00033 #include <core/screen.h>
00034 #include <core/pluginclasses.h>
00035
00036 extern unsigned int pluginClassHandlerIndex;
00037
00038 template<class Tp, class Tb, int ABI = 0>
00039 class PluginClassHandler {
00040 public:
00041 PluginClassHandler (Tb *);
00042 ~PluginClassHandler ();
00043
00044 void setFailed () { mFailed = true; };
00045 bool loadFailed () { return mFailed; };
00046
00047 Tb * get () { return mBase; };
00048 static Tp * get (Tb *);
00049
00050 private:
00051 static CompString keyName ()
00052 {
00053 return compPrintf ("%s_index_%lu", typeid (Tp).name (), ABI);
00054 }
00055
00056 private:
00057 bool mFailed;
00058 Tb *mBase;
00059
00060 static PluginClassIndex mIndex;
00061 };
00062
00063 template<class Tp, class Tb, int ABI>
00064 PluginClassIndex PluginClassHandler<Tp,Tb,ABI>::mIndex;
00065
00066 template<class Tp, class Tb, int ABI>
00067 PluginClassHandler<Tp,Tb,ABI>::PluginClassHandler (Tb *base) :
00068 mFailed (false),
00069 mBase (base)
00070 {
00071 if (mIndex.pcFailed)
00072 {
00073 mFailed = true;
00074 }
00075 else
00076 {
00077 if (!mIndex.initiated)
00078 {
00079 mIndex.index = Tb::allocPluginClassIndex ();
00080 if (mIndex.index != (unsigned)~0)
00081 {
00082 mIndex.initiated = true;
00083 mIndex.failed = false;
00084 mIndex.pcIndex = pluginClassHandlerIndex;
00085
00086 CompPrivate p;
00087 p.uval = mIndex.index;
00088
00089 if (!screen->hasValue (keyName ()))
00090 {
00091 screen->storeValue (keyName (), p);
00092 pluginClassHandlerIndex++;
00093 }
00094 else
00095 {
00096 compLogMessage ("core", CompLogLevelFatal,
00097 "Private index value \"%s\" already stored in screen.",
00098 keyName ().c_str ());
00099 }
00100 }
00101 else
00102 {
00103 mIndex.failed = true;
00104 mIndex.initiated = false;
00105 mIndex.pcFailed = true;
00106 mIndex.pcIndex = pluginClassHandlerIndex;
00107 mFailed = true;
00108 }
00109 }
00110
00111 if (!mIndex.failed)
00112 {
00113 mIndex.refCount++;
00114 mBase->pluginClasses[mIndex.index] = static_cast<Tp *> (this);
00115 }
00116 }
00117 }
00118
00119 template<class Tp, class Tb, int ABI>
00120 PluginClassHandler<Tp,Tb,ABI>::~PluginClassHandler ()
00121 {
00122 if (!mIndex.pcFailed)
00123 {
00124 mIndex.refCount--;
00125
00126 if (mIndex.refCount == 0)
00127 {
00128 Tb::freePluginClassIndex (mIndex.index);
00129 mIndex.initiated = false;
00130 mIndex.failed = false;
00131 mIndex.pcIndex = pluginClassHandlerIndex;
00132 screen->eraseValue (keyName ());
00133 pluginClassHandlerIndex++;
00134 }
00135 }
00136 }
00137
00138 template<class Tp, class Tb, int ABI>
00139 Tp *
00140 PluginClassHandler<Tp,Tb,ABI>::get (Tb *base)
00141 {
00142 if (mIndex.initiated && pluginClassHandlerIndex == mIndex.pcIndex)
00143 {
00144 return static_cast<Tp *>
00145 (base->pluginClasses[mIndex.index]);
00146 }
00147 if (mIndex.failed && pluginClassHandlerIndex == mIndex.pcIndex)
00148 return NULL;
00149
00150 if (screen->hasValue (keyName ()))
00151 {
00152 mIndex.index = screen->getValue (keyName ()).uval;
00153 mIndex.initiated = true;
00154 mIndex.failed = false;
00155 mIndex.pcIndex = pluginClassHandlerIndex;
00156 return static_cast<Tp *> (base->pluginClasses[mIndex.index]);
00157 }
00158 else
00159 {
00160 mIndex.initiated = false;
00161 mIndex.failed = true;
00162 mIndex.pcIndex = pluginClassHandlerIndex;
00163 return NULL;
00164 }
00165 }
00166
00167 #endif