• Immutable Page
  • Info
  • Attachments

Class Definition

template <class T>
class PluginStateWriter
{
    public:

        template <class Archive>
        void serialize (Archive &ar, const unsigned int version)
        {
             ar & *mClassPtr;;
        };    

        virtual void postLoad () {};
        
        /* Classes get destroyed in the order of:
         * derived -> this. Because variables might
         * have thier destructors called, we provide
         * a method to intercept this process
         * and immediately serialize data such that it
         * won't be unintentionally destroyed before the
         * base CompPluginStateWriter destructor gets called
         */
        
        void writeSerializedData ()
        {
            if (!screen->shouldSerializePlugins ())
                return;

            CompOption::Vector atomTemplate = mPw.getReadTemplate ();     
            std::string str;  
            std::ostringstream oss (str);
            boost::archive::text_oarchive oa (oss);
            
            oa << *this;
            
            CompOption::Value v (oss.str ().c_str ());
            atomTemplate.at (0).set (v);

            mPw.updateProperty (mResource, atomTemplate, XA_STRING);
        }       
        
        PluginStateWriter (T *instance,
                           Window xid) :
            mResource (xid),
            mClassPtr (instance)
        {
            if (screen->shouldSerializePlugins ())

            {
                CompString atomName = compPrintf ("_COMPIZ_%s_STATE",
                                                  typeid (T).name ());
                CompOption::Vector o;

                o.resize (1);
                o.at (0).setName ("data", CompOption::TypeString);

                mPw = PropertyWriter (atomName, o);

                mTimeout.setCallback (boost::bind (&PluginStateWriter::checkTimeout,
                                                 this));
                mTimeout.setTimes (0, 0);
                mTimeout.start ();
            }
        }
        
        virtual ~PluginStateWriter () {};

};

Description

Sometimes you might need to store some information about execution when your plugin is not actually loaded. For example the user may have enabled some effect and they expect it to be on when the plugin is re-loaded. Also, your plugin may be unloaded and then reloaded from time-to-time in order to accommodate new plugins being loaded.

The serialized data is stored in an X11 property, on a window ID that you specify.

Usage

PluginStateWriter should never be instantiated directly, instead it should be inherited from the class that you want to serialize. It takes one template argument, which is the name of the class you wish to serialize.

Classes should implement a public template member function called serialize which looks like this:

template <class Archive>
void serialize (Archive &ar, const unsigned int version)
{
    ar & mVariable1;
    ar & mVariable2;
    ...
}

This is similar to the specification defined in the boost::serialization.

The function is defined as a template, as it should be ready to take any kind of archive boost might give it. serialize is used for both writing data to and reading data from the archive and the operator& is automatically overloaded in different ways depending on the use at the time.

const unsigned int version is also important. If you change which variables are serialized throughout the lifetime of your plugin, you need to check the version number of what is being serialized, otherwise your plugin could crash when trying to read data from the archive.

Plugins should also implement the constructor for this base class in their own constructor.

Class::Class :
    PluginStateWriter <Class> (Class *instance, Window xid)

For the instance, you should provide a pointer to the current instance of your class, eg this. The xid is the window you wish to read and write data from as your plugin loads and unloads. The general rule of thumb here is to keep window class information on windows themselves and screen class information on the root window.

Note that if an X11 window is destroyed, all of your property data goes with it, so your plugin should be written so that if a window ID disappears, then there is no loss in functionality.

Also keep in mind that the class will automatically restore your plugin state after the class constructor has finished, so there is no need to worry about overwriting the saved plugin state with the default one.

There is some data that cannot be serialized effectively, such as core states which your plugin has set. Since it is the job of your plugin in the first place to set them, you can easily check whether they need to be set again after your plugin has restored it's state. To do this, you can overload the void postLoad () function. In this function, you can check the loaded variables and enable any wrapped functions previously disabled and the like.

Finally, when your class is destroyed, the serialized data is not written automatically. You must call writeSerializedData () at the end of your class destructor to save all the data in your class to a window property.

Development/zero-nine/CoreClasses/PluginStateWriter (last edited 2010-08-23 08:44:15 by 203-173-33-106)