Merge lp://staging/~smspillaz/compiz-libcompizconfig/refactor-context into lp://staging/~compiz-team/compiz-libcompizconfig/0.9.8

Proposed by Sam Spilsbury
Status: Superseded
Proposed branch: lp://staging/~smspillaz/compiz-libcompizconfig/refactor-context
Merge into: lp://staging/~compiz-team/compiz-libcompizconfig/0.9.8
Prerequisite: lp://staging/~smspillaz/compiz-libcompizconfig/ccs-object
Diff against target: 882 lines (+339/-96)
6 files modified
backend/src/ini.c (+2/-2)
include/ccs.h (+52/-12)
plugin/ccp/src/ccp.cpp (+6/-9)
src/ccs-private.h (+12/-1)
src/compiz.cpp (+15/-5)
src/main.c (+252/-67)
To merge this branch: bzr merge lp://staging/~smspillaz/compiz-libcompizconfig/refactor-context
Reviewer Review Type Date Requested Status
Alan Griffiths Pending
Review via email: mp+104469@code.staging.launchpad.net

This proposal supersedes a proposal from 2012-04-29.

Description of the change

This is all about bug 990690.

!! - It probably isn't a good idea to test this branch in isolation, as it is part of a pipeline to get compiz-libcompizconfig under test. If you want to test the result of this work, you should probably look at testing

lp:~smspillaz/compiz-libcompizconfig/setting-mock
lp:~smspillaz/compiz-compizconfig-python/compiz-compizconfig-python.setting-api
lp:~smspillaz/compiz-compizconfig-gconf/compiz-compizconfig-gconf.adapt-to-new-interfaces

.. that's all !!

Refactors CCSContext to indirect all variables behind a private ptr

To post a comment you must log in.
Revision history for this message
Alan Griffiths (alan-griffiths) wrote : Posted in a previous version of this proposal

There's not much point to a structure that only contains a void pointer.

The pattern I'd expect is:

// *.h
typedef struct CCSContext CCSContext;
CCSContext* ccsContextCreate();
CCSPluginList ccsContextGetPlugins(CCSContext*);
...
void ccsContextDestroy(CCSContext*);

// *.cpp
struct CCSContext
{
    CCSBackend *backend;
    CCSPluginList plugins; /* list of plugins settings were loaded for */
    CCSPluginCategory *categories; /* list of plugin categories */
    void *privatePtr; /* private pointer that can be used by the caller */
    char *profile;
    Bool deIntegration;
    Bool pluginListAutoSort;

    unsigned int configWatchId;

    CCSSettingList changedSettings; /* list of settings changed since last settings write */

    unsigned int screenNum; /* screen number this context is assigned to */
    const CCSInterfaceTable *object_interfaces;
    const CCSContextInterface *interface;
} CCSContextPrivate;
...
CCSPluginList
ccsContextGetPluginsDefault (CCSContext* context)
{
  return context->plugins;
}
...

Maybe there is a reason for the extra complexity? But it escapes me.

review: Needs Fixing
Revision history for this message
Alan Griffiths (alan-griffiths) wrote : Posted in a previous version of this proposal

> There's not much point to a structure that only contains a void pointer.
>
> The pattern I'd expect is:
>
> // *.h
> typedef struct CCSContext CCSContext;
> CCSContext* ccsContextCreate();
> CCSPluginList ccsContextGetPlugins(CCSContext*);
> ...
> void ccsContextDestroy(CCSContext*);
>
> // *.cpp
> struct CCSContext
> {
> CCSBackend *backend;
> CCSPluginList plugins; /* list of plugins settings were loaded for */
> CCSPluginCategory *categories; /* list of plugin categories */
> void *privatePtr; /* private pointer that can be used by the caller */
> char *profile;
> Bool deIntegration;
> Bool pluginListAutoSort;
>
> unsigned int configWatchId;
>
> CCSSettingList changedSettings; /* list of settings changed since last
> settings write */
>
> unsigned int screenNum; /* screen number this context is assigned to */
> const CCSInterfaceTable *object_interfaces;
> const CCSContextInterface *interface;
> } CCSContextPrivate;

Cut&past error - that should be "> };"

> ...
> CCSPluginList
> ccsContextGetPluginsDefault (CCSContext* context)
> {
> return context->plugins;
> }
> ...
>
> Maybe there is a reason for the extra complexity? But it escapes me.

Revision history for this message
Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal

Agreed, changing to opaque pointers was something I didn't remember to do yet. doing it now.

Revision history for this message
Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal

> There's not much point to a structure that only contains a void pointer.
>
> The pattern I'd expect is:
>
> // *.h
> typedef struct CCSContext CCSContext;
> CCSContext* ccsContextCreate();
> CCSPluginList ccsContextGetPlugins(CCSContext*);
> ...
> void ccsContextDestroy(CCSContext*);
>
> // *.cpp
> struct CCSContext
> {
> CCSBackend *backend;
> CCSPluginList plugins; /* list of plugins settings were loaded for */
> CCSPluginCategory *categories; /* list of plugin categories */
> void *privatePtr; /* private pointer that can be used by the caller */
> char *profile;
> Bool deIntegration;
> Bool pluginListAutoSort;
>
> unsigned int configWatchId;
>
> CCSSettingList changedSettings; /* list of settings changed since last
> settings write */
>
> unsigned int screenNum; /* screen number this context is assigned to */
> const CCSInterfaceTable *object_interfaces;
> const CCSContextInterface *interface;
> } CCSContextPrivate;
> ...
> CCSPluginList
> ccsContextGetPluginsDefault (CCSContext* context)
> {
> return context->plugins;
> }
> ...
>
> Maybe there is a reason for the extra complexity? But it escapes me.

See the next pipe - it contains a struct that contains a CCSObject (not by pointer). All this does is move the data behind an indirection pimpl.

Revision history for this message
Sam Spilsbury (smspillaz) wrote :

A clarification - the way CCSObject works means that "object types" in libcompizconfig can't be behind opaque pointers is because at the moment we are just doing allocation manually (eg no fooNew ... yet as its nontrivial with the current design). In order to ensure that we get enough allocated for CCSObject and can access it easily from any object type is to make it the first member of the struct and then hide everything behind the priv pointer it provides.

Revision history for this message
Alan Griffiths (alan-griffiths) wrote : Posted in a previous version of this proposal

I can think of no good reason that ccsPrivate is void* instead of CCSContextPrivate* - that would allow the implementation code to be simpler by removing the need for casts.

And I don't see why CONTEXT_PRIV and _CCSContextPrivate/CCSContextPrivate are defined in a header.

Which is "the next pipe"?

Revision history for this message
Sam Spilsbury (smspillaz) wrote :

Each of these branches is part of a pipeline (eg, changes are made in serial and each is dependent on the last). This can be traversed backwards from setting-mock.

At the moment, the pattern I'm using here is

1) Move private data behind a pimpl and use accessor methods to get at the data
2) Create an interface structure and make all method calls for that object go through that interface structure.

Hence the reason why ccsPrivate is void * (for the time being).

Revision history for this message
Sam Spilsbury (smspillaz) wrote :

CONTEXT_PRIV and related things are defined in headers because they are used in multiple source files. This will be changed eventually, but in another branch (for the sake of /not/ rewriting libcompizconfig in one MP)

Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

> CONTEXT_PRIV and related things are defined in headers because they are used
> in multiple source files. This will be changed eventually, but in another
> branch (for the sake of /not/ rewriting libcompizconfig in one MP)

AFAICS CONTEXT_PRIV, _CCSContextPrivate and CCSContextPrivate are only used in main.c (but that isn't the real point).

Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

I'm still struggling to identify the design goals here.

Indirecting calls via a CCSContextInterface member pointer gives the capability to change the implementation of individual functions on an instance by instance basis. Is this needed? Or just a seam for testing? If the latter, then there's no need for objects to carry around a pointer.

I also don't see what the additional indirection through CCSInterfaceTable* is for. The only use is ccsEmptyContextNew which assigns to object_interfaces, but where is it used? And what for?

Revision history for this message
Sam Spilsbury (smspillaz) wrote :

On Fri, 4 May 2012, Alan Griffiths wrote:

> I'm still struggling to identify the design goals here.
>
> Indirecting calls via a CCSContextInterface member pointer gives the capability to change the implementation of individual functions on an instance by instance basis. Is this needed? Or just a seam for testing? If the latter, then there's no need for objects to carry around a pointer.
>

Sure, it is a seam for testing. However, its useful in that we can test by
having a real CCSPlugin, CCSContext and a mocked CCSSetting or vice-versa.
We may also want to test interactiosn between individual setting objects
themselves vis-a-vis keybinding conflicts.

> I also don't see what the additional indirection through CCSInterfaceTable* is for. The only use is ccsEmptyContextNew which assigns to object_interfaces, but where is it used? And what for?
>

At the moment, this is so that you can override the kind of objet that
might be constructed by a CCSContexted or CCSPlugin internally. This will
be replaced when the code is further refactored to truly do dependency
injection.

>
> --
> https://code.launchpad.net/~smspillaz/compiz-libcompizconfig/refactor-context/+merge/104469
> You are the owner of lp:~smspillaz/compiz-libcompizconfig/refactor-context.
>

437. By Sam Spilsbury

Merged ccs-object into refactor-context.

438. By Sam Spilsbury

Merged ccs-object into refactor-context.

439. By Sam Spilsbury

Merged ccs-object into refactor-context.

440. By Sam Spilsbury

Merged ccs-object into refactor-context.

441. By Sam Spilsbury

Merged ccs-object into refactor-context.

442. By Sam Spilsbury

Merged ccs-object into refactor-context.

Unmerged revisions

442. By Sam Spilsbury

Merged ccs-object into refactor-context.

441. By Sam Spilsbury

Merged ccs-object into refactor-context.

440. By Sam Spilsbury

Merged ccs-object into refactor-context.

439. By Sam Spilsbury

Merged ccs-object into refactor-context.

438. By Sam Spilsbury

Merged ccs-object into refactor-context.

437. By Sam Spilsbury

Merged ccs-object into refactor-context.

436. By Sam Spilsbury

Merged ccs-object into refactor-context.

435. By Sam Spilsbury

Merged ccs-object into refactor-context.

434. By Sam Spilsbury

Merged ccs-object into refactor-context.

433. By Sam Spilsbury

Merged ccs-object into refactor-context.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
The diff is not available at this time. You can reload the page or download it.

Subscribers

People subscribed via source and target branches