diff options
Diffstat (limited to 'cli_ure/source/ure/uno/util/WeakComponentBase.cs')
-rw-r--r-- | cli_ure/source/ure/uno/util/WeakComponentBase.cs | 185 |
1 files changed, 185 insertions, 0 deletions
diff --git a/cli_ure/source/ure/uno/util/WeakComponentBase.cs b/cli_ure/source/ure/uno/util/WeakComponentBase.cs new file mode 100644 index 000000000..48715afc6 --- /dev/null +++ b/cli_ure/source/ure/uno/util/WeakComponentBase.cs @@ -0,0 +1,185 @@ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +using System; +using unoidl.com.sun.star.lang; + +namespace uno.util +{ + +/** This class can be used as a base class for UNO objects. + It implements the capability to be kept weakly + (unoidl.com.sun.star.uno.XWeak) and it implements + unoidl.com.sun.star.lang.XTypeProvider which is necessary for + using the object from StarBasic. + In addition, it implements the interface + unoidl.com.sun.star.lang.XComponent to be disposed explicitly. +*/ +public class WeakComponentBase : WeakBase, XComponent +{ + private delegate void t_disposing( EventObject evt ); + private t_disposing m_disposing = null; + private bool m_inDispose = false; + private bool m_disposed = false; + + /** Indicates whether object is already disposed. + + @return + true, if object has been disposed + */ + protected bool isDisposed() + { + lock (this) + { + return m_disposed; + } + } + + /** Checks whether this object is disposed and throws a DisposedException + if it is already disposed. + */ + protected void checkUnDisposed() + { + if (! isDisposed()) + { + throw new unoidl.com.sun.star.lang.DisposedException( + "object already disposed!", this ); + } + } + + ~WeakComponentBase() + { + bool doDispose; + lock (this) + { + doDispose = (!m_inDispose && !m_disposed); + } + if (doDispose) + { + dispose(); + } + } + + /** Override to perform extra clean-up work. Provided for subclasses. + It is called during dispose() + */ + protected void preDisposing() + { + } + + /** Override to become notified right before the disposing action is + performed. + */ + protected void postDisposing() + { + } + + // XComponent impl + /** This method is called by the owner of this object to explicitly + dispose it. This implementation of dispose() first notifies this object + via preDisposing(), then all registered event listeners and + finally this object again calling postDisposing(). + */ + public void dispose() + { + // Determine in a thread-safe way if this is the first call to this + // method. Only then we proceed with the notification of event + // listeners. It is an error to call this method more than once. + bool doDispose = false; + t_disposing call = null; + lock (this) + { + if (! m_inDispose && !m_disposed) + { + call = m_disposing; + m_disposing = null; + m_inDispose = true; + doDispose = true; + } + } + // The notification occurs in an unsynchronized block in order to avoid + // deadlocks if one of the listeners calls back in a different thread on + // a synchronized method which uses the same object. + if (doDispose) + { + try + { + // call sub class + preDisposing(); + // send disposing notifications to listeners + if (null != call) + { + EventObject evt = new EventObject( this ); + call( evt ); + } + // call sub class + postDisposing(); + } + finally + { + // finally makes sure that the flags are set ensuring + // that this function is only called once. + m_disposed = true; + m_inDispose = false; + } + } + else + { + // in a multithreaded environment, it can't be avoided, + // that dispose is called twice. + // However this condition is traced, because it MAY indicate an + // error. +#if DEBUG + Console.WriteLine( + "WeakComponentBase.dispose() - dispose called twice" ); +#endif +// Debug.Fail( "WeakComponentBase.dispose() - dispose called twice" ); + } + } + /** Registers an event listener being notified when this object is disposed. + + @param xListener event listener + */ + public void addEventListener( XEventListener xListener ) + { + bool add; + lock (this) + { + add = (! m_inDispose && !m_disposed); + if (add) + m_disposing += new t_disposing( xListener.disposing ); + } + if (! add) + xListener.disposing( new EventObject( this ) ); + } + /** Revokes an event listener from being notified when this object + is disposed. + + @param xListener event listener + */ + public void removeEventListener( XEventListener xListener ) + { + lock (this) + { + if (! m_inDispose && !m_disposed) + m_disposing -= new t_disposing( xListener.disposing ); + } + } +} + +} |