1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  *   Licensed to the Apache Software Foundation (ASF) under one or more
12  *   contributor license agreements. See the NOTICE file distributed
13  *   with this work for additional information regarding copyright
14  *   ownership. The ASF licenses this file to you under the Apache
15  *   License, Version 2.0 (the "License"); you may not use this file
16  *   except in compliance with the License. You may obtain a copy of
17  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #ifndef INCLUDED_SD_SOURCE_UI_FRAMEWORK_CONFIGURATION_CONFIGURATIONUPDATER_HXX
21 #define INCLUDED_SD_SOURCE_UI_FRAMEWORK_CONFIGURATION_CONFIGURATIONUPDATER_HXX
22 
23 #include <com/sun/star/uno/Reference.hxx>
24 #include <vcl/timer.hxx>
25 #include <memory>
26 #include <vector>
27 
28 namespace com { namespace sun { namespace star { namespace drawing { namespace framework { class XConfiguration; } } } } }
29 namespace com { namespace sun { namespace star { namespace drawing { namespace framework { class XControllerManager; } } } } }
30 namespace com { namespace sun { namespace star { namespace drawing { namespace framework { class XResourceId; } } } } }
31 
32 namespace sd { namespace framework {
33 
34 class ConfigurationClassifier;
35 class ConfigurationUpdaterLock;
36 class ConfigurationControllerResourceManager;
37 class ConfigurationControllerBroadcaster;
38 
39 /** This is a helper class for the ConfigurationController.  It handles the
40     update of the current configuration so that it looks like a requested
41     configuration.  An update is made by activating or deactivating drawing
42     framework resources.
43 
44     When an update is not successful, i.e. after the update the current
45     configuration is not equivalent to the requested configuration, then a
46     timer is started to repeat the update after a short time.
47 */
48 class ConfigurationUpdater
49 {
50 public:
51     /** Create a new ConfigurationUpdater object that notifies configuration
52         changes and the start and end of updates via the given broadcaster.
53     */
54     ConfigurationUpdater (
55         const std::shared_ptr<ConfigurationControllerBroadcaster>& rpBroadcaster,
56         const std::shared_ptr<ConfigurationControllerResourceManager>& rpResourceManager,
57         const css::uno::Reference<
58             css::drawing::framework::XControllerManager>& rxControllerManager);
59     ~ConfigurationUpdater();
60 
61     /** Request an update of the current configuration so that it looks like
62         the given requested configuration.  It checks whether an update of
63         the current configuration can be done.  Calls UpdateConfiguration()
64         if that is the case.  Otherwise it schedules a later call to
65         UpdateConfiguration().
66     */
67     void RequestUpdate (const css::uno::Reference<
68         css::drawing::framework::XConfiguration>& rxRequestedConfiguration);
69 
70     const css::uno::Reference<
GetCurrentConfiguration() const71         css::drawing::framework::XConfiguration>& GetCurrentConfiguration() const { return mxCurrentConfiguration;}
72 
73     friend class ConfigurationUpdaterLock;
74     /** Return a lock of the called ConfigurationUpdater.  While the
75         returned object exists no update of the current configuration is
76         made.
77     */
78     std::shared_ptr<ConfigurationUpdaterLock> GetLock();
79 
80 private:
81     /** A reference to the XControllerManager is kept so that
82         UpdateConfiguration() has access to the other sub controllers.
83     */
84     css::uno::Reference<
85         css::drawing::framework::XControllerManager> mxControllerManager;
86 
87     std::shared_ptr<ConfigurationControllerBroadcaster> mpBroadcaster;
88 
89     /** The current configuration holds the resources that are currently
90         active.  It is modified during an update.
91     */
92     css::uno::Reference<
93         css::drawing::framework::XConfiguration> mxCurrentConfiguration;
94 
95     /** The requested configuration holds the resources that have been
96         requested to activate or to deactivate since the last update.  It is
97         (usually) not modified during an update.  This configuration is
98         maintained by the ConfigurationController and given to the
99         ConfigurationUpdater in the RequestUpdate() method.
100     */
101     css::uno::Reference<
102         css::drawing::framework::XConfiguration> mxRequestedConfiguration;
103 
104     /** This flag is set to </sal_True> when an update of the current
105         configuration was requested (because the last request in the queue
106         was processed) but could not be executed because the
107         ConfigurationController was locked.  A call to UpdateConfiguration()
108         resets the flag to </sal_False>.
109     */
110     bool mbUpdatePending;
111 
112     /** This flag is set to </sal_True> while the UpdateConfiguration() method
113         is running.  It is used to prevent reentrance problems with this
114         method.
115     */
116     bool mbUpdateBeingProcessed;
117 
118     /** The ConfigurationController is locked when this count has a value
119         larger then zero.  If the controller is locked then updates of the
120         current configuration are not made.
121     */
122     sal_Int32 mnLockCount;
123 
124     /** This timer is used to check from time to time whether the requested
125         configuration and the current configuration are identical and request
126         an update when they are not.
127         This is used to overcome problems with resources that become
128         available asynchronously.
129     */
130     Timer  maUpdateTimer;
131 
132     /** The number of failed updates (those after which the current
133         configuration is not equivalent to the requested configuration) is
134         used to determine how long to wait before another update is made.
135     */
136     sal_Int32 mnFailedUpdateCount;
137 
138     std::shared_ptr<ConfigurationControllerResourceManager> mpResourceManager;
139 
140     /** This method does the main work of an update.  It calls the sub
141         controllers that are responsible for the various types of resources
142         and tells them to update their active resources.  It notifies
143         listeners about the start and end of the configuration update.
144     */
145     void UpdateConfiguration();
146 
147     /** Basically calls UpdaterStart() andUpdateEnd() and makes some debug
148         output.
149     */
150     void UpdateCore (const ConfigurationClassifier& rClassifier);
151 
152     /** Check for all pure anchors if they have at least one child.
153         Childless pure anchors are deactivated.
154         This affects only the current configuration.
155     */
156     void CheckPureAnchors (
157         const css::uno::Reference<css::drawing::framework::XConfiguration>& rxConfiguration,
158         ::std::vector<css::uno::Reference<css::drawing::framework::XResourceId> >&
159             rResourcesToDeactivate);
160 
161     /** Remove from the requested configuration all pure anchors that have no
162         child.  Requested but not yet activated anchors can not be removed
163         because without the actual resource the 'pureness' of an anchor can
164         not be determined.
165     */
166     void CleanRequestedConfiguration();
167 
168     /** Check the success of a recently executed configuration update.
169         When the update failed then start the timer.
170     */
171     void CheckUpdateSuccess();
172 
173     /** This method sets the mbUpdateBeingProcessed member that is used to
174         prevent reentrance problems.  This method allows function objects
175         easily and safely to modify the variable.
176     */
177     void SetUpdateBeingProcessed (bool bValue);
178 
179     /** Return whether it is possible to do an update of the configuration.
180         This takes into account whether another update is currently being
181         executed, the lock count, and whether the configuration controller
182         is still valid.
183     */
184     bool IsUpdatePossible() const;
185 
186     /** Lock updates of the current configuration.  For intermediate requests
187         for updates mbUpdatePending is set to <TRUE/>.
188     */
189     void LockUpdates();
190 
191     /** When an update was requested since the last LockUpdates() call then
192         RequestUpdate() is called.
193     */
194     void UnlockUpdates();
195 
196     DECL_LINK(TimeoutHandler, Timer *, void);
197 };
198 
199 } } // end of namespace sd::framework
200 
201 #endif
202 
203 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
204