Next Previous Contents

5. The virtual registry

#Specification: virtual registry / introduction ([modregister.cc,10])

The registry system provides a inexpensive mean for various modules to publish "variables". Those variables are readable and writable from other modules. The variables correspond to fields in various dialogs. Planned uses for this module:

#Specbeg: dialog / sample code / using the virtual registry ([samples.cc,766])

        /*
            The virtual registry allows one part of an application to export
            some variables to other parts of the application, potentially
            accross shared object (which can't share C++ variable).
        
            Setting and getting values with the registry is very easy.
            The registry is mapped on the user interface. This is especially
            useful for Linuxconf since it needs all kinds of dialog to manipulate
            the various configuration. Reusing this code is the key. As you
            will see below, publishing variables tied to a dialog is simple.
        
            In the following example, we present a small dialog which edits
            two field of a configuration file /tmp/sample.data. This
            configuration file is a shell like file. It may look like
        
            <sgml>
            <tscreen><verb>
                # Some comments
                var1="Some value"
                # more comments
                other_variable="value"
                var2="value"
            </verb></tscreen>
            </sgml>
        
            The small dialog will only touch var1 and var2 and preserve the comments
            and the ordering of sample.data. This is really the goal of linuxconf
            to provide some user interface for various configuration file. The
            bulk of the code goes like that
        
            <sgml>
            <itemize>
            <item>Parsing the configuration files.
            <item>Presenting the dialog.
            <item>Updating the configuration file.
            </itemize>
            </sgml>
        
            Sometime, it is done using several functions, various C++ classes.
            It can be complex. The goal of the registry is to be able to reuse
            this functionality
        
        */
        static void sample_registrydialog()
        {
            DIALOG dia;
            SSTRING s1,s2;
            CONFIG_FILE f_config ("/tmp/sample.data",help_nil,CONFIGF_OPTIONAL);
            VIEWITEMS items;
            items.read (f_config);
            char tmp[1000];
            s1.setfrom (items.locateval ("var1",tmp));
            s2.setfrom (items.locateval ("var2",tmp));
            dia.newf_str (MSG_U(F_SAMPLEFIELD1,"Sample field1"),s1);
            dia.newf_str (MSG_U(F_SAMPLEFIELD2,"Sample field2"),s2);
            int nof = 0;
            while (1){
                MENU_STATUS code = dia.edit ("Sample data","",help_nil,nof);
                if (code == MENU_ESCAPE || code == MENU_CANCEL){
                    break;
                }else{
                    // We must update the file
                    items.update ("var1",s1);
                    items.update ("var2",s2);
                    items.write (f_config,NULL);
                    break;
                }
            }
        }
        
        /*
            Here we publish the two variables. As you can see, this is
            very simple. Each variable (var1, var2) is associated with
            a dialog ID (NULL here and most of the time), a field prompt
            and a trigger function. This function simply calls the dialog
        */
        #include "modregister.h"
        
        static REGISTER_VARIABLE_LOOKUP_MSG sample_var_list1[]={
            {"var1",NULL,P_MSG_R(F_SAMPLEFIELD1),sample_registrydialog,NULL},
            {"var2",NULL,P_MSG_R(F_SAMPLEFIELD2),sample_registrydialog,NULL},
            { NULL }
        };
        
        static REGISTER_VARIABLES sample_registry1("sample",sample_var_list1);
        
        /*
            This function perform the following sequence
        
            <sgml>
            <itemize>
            <item>Execute the dialog so you look at it.
            <item>Execute it again so you can  see that your input was saved.
            <item>Retrieve var1 and var2 using the registry.
            <item>Setting var1 and var2 to new values using the registry.
            <item>Execute the dialog so you can see the new values.
            </itemize>
            </sgml>
        */
        static void sample_useregistry()
        {
            xconf_notice ("Ok, we call the dialog to edit /tmp/sample.data\n"
                "Enter some values and accept");
            sample_registrydialog();
            xconf_notice ("We call it again to see if the data was saved properly");
            sample_registrydialog();
            // Now we will retrieve the values
            master_registry.start_session();
            SSTRING v1 (master_registry.get("sample.var1"));
            SSTRING v2 (master_registry.get("sample.var2"));
            master_registry.end_session();
            xconf_notice ("Using the virtual registry, we get\n"
                "var1=%s\n"
                "var2=%s\n"
                "\n"
                "We will put new values now"
                ,v1.get(),v2.get());
            master_registry.start_session();
            master_registry.set("sample.var1","New value for var1");
            master_registry.set("sample.var2","New value for var2");
            master_registry.end_session();
            xconf_notice ("Ok, the values are updated, now we visit the dialog again");
            sample_registrydialog();
        }

5.1 Using the registry

MASTER_REGISTRY::start_session()

        PUBLIC int MASTER_REGISTRY::start_session(
                void)
        

MASTER_REGISTRY::end_session()

        PUBLIC int MASTER_REGISTRY::end_session(
                void)
        

MASTER_REGISTRY::get()

Get the value of a variable. Return NULL if not found. This is the function used by clients.

        PUBLIC const char *MASTER_REGISTRY::get(
                const char *_module,
                const char *_key)       // Single word, or word.record
        

MASTER_REGISTRY::get()

Get the value of a module.variable variable. This is probably the function used by most clients.

        PUBLIC const char *MASTER_REGISTRY::get(
                const char *_key)
        

MASTER_REGISTRY::set()

Set the value of a registry variable. Return -1 if the variable does not exist.

        PUBLIC int MASTER_REGISTRY::set(
                const char *_key,       // module.variable or module.variable.record
                const char *_value)
        

MASTER_REGISTRY::set()

        PUBLIC int MASTER_REGISTRY::set(
                const char *_key,       // module.variable or module.variable.record
                const SSTRING&_value)
        

MASTER_REGISTRY::set()

        PUBLIC int MASTER_REGISTRY::set(
                const char *_key,       // module.variable or module.variable.record
                int val)
        

5.2 Publishing variables

#Specbeg: publishing variable / REGISTER_VARIABLE_LOOKUP_MSG ([modregister.h,31])

        // This is used with P_MSG_R() macros
        struct REGISTER_VARIABLE_LOOKUP_MSG{
            const char *varname;
            const char *dialog_id;
            TRANS_NOTLOAD *notloaded;
            // Functions to trigger to execution of the dialog, so variables
            // can be moved (get or set)
            void (*exec_dialog)();
            void (*exec_dialog_record)(const char * record, bool setting);
        };

#Specbeg: publishing variable / REGISTER_VARIABLE_LOOKUP ([modregister.h,14])

        // This is used with strings
        struct REGISTER_VARIABLE_LOOKUP{
            const char *varname;
            const char *dialog_id;
            const char *prompt;
            // Functions to trigger to execution of the dialog, so variables
            // can be moved (get or set)
            void (*exec_dialog)();
            void (*exec_dialog_record)(const char * record, bool setting);
        };

REGISTER_VARIABLES::REGISTER_VARIABLES()

        PUBLIC REGISTER_VARIABLES::REGISTER_VARIABLES(
                const char *_module_id,
                REGISTER_VARIABLE_LOOKUP _tb[])
        

REGISTER_VARIABLES::REGISTER_VARIABLES()

        PUBLIC REGISTER_VARIABLES::REGISTER_VARIABLES(
                const char *_module_id,
                REGISTER_VARIABLE_LOOKUP_MSG _tb[])
        

MASTER_REGISTRY

Classe MASTER_REGISTRY, vue publique

REGISTER_VARIABLES

Classe REGISTER_VARIABLES, vue publique

REGISTER_VARIABLE

Classe REGISTER_VARIABLE, vue publique


Next Previous Contents