From 8068dae4d40feacfd861ede0d4c3f769c9e20392 Mon Sep 17 00:00:00 2001 From: "neeti%netscape.com" Date: Tue, 6 Apr 1999 20:54:09 +0000 Subject: [PATCH] initial checkin for ObserverService api --- base/public/makefile.win | 3 + base/public/nsIObserver.h | 45 +++++++ base/public/nsIObserverList.h | 48 +++++++ base/public/nsIObserverService.h | 49 +++++++ base/src/makefile.win | 6 + base/src/nsBaseDLL.cpp | 56 ++++++++ base/src/nsObserver.cpp | 123 +++++++++++++++++ base/src/nsObserver.h | 61 +++++++++ base/src/nsObserverList.cpp | 124 +++++++++++++++++ base/src/nsObserverList.h | 51 +++++++ base/src/nsObserverService.cpp | 202 ++++++++++++++++++++++++++++ base/src/nsObserverService.h | 45 +++++++ base/tests/TestObserverService.cpp | 86 ++++++++++++ base/tests/makefile.win | 7 + xpcom/ds/nsIObserver.h | 45 +++++++ xpcom/ds/nsIObserverList.h | 48 +++++++ xpcom/ds/nsIObserverService.h | 49 +++++++ xpcom/ds/nsObserver.cpp | 123 +++++++++++++++++ xpcom/ds/nsObserver.h | 61 +++++++++ xpcom/ds/nsObserverList.cpp | 124 +++++++++++++++++ xpcom/ds/nsObserverList.h | 51 +++++++ xpcom/ds/nsObserverService.cpp | 202 ++++++++++++++++++++++++++++ xpcom/ds/nsObserverService.h | 45 +++++++ xpcom/tests/TestObserverService.cpp | 86 ++++++++++++ 24 files changed, 1740 insertions(+) create mode 100644 base/public/nsIObserver.h create mode 100644 base/public/nsIObserverList.h create mode 100644 base/public/nsIObserverService.h create mode 100644 base/src/nsObserver.cpp create mode 100644 base/src/nsObserver.h create mode 100644 base/src/nsObserverList.cpp create mode 100644 base/src/nsObserverList.h create mode 100644 base/src/nsObserverService.cpp create mode 100644 base/src/nsObserverService.h create mode 100644 base/tests/TestObserverService.cpp create mode 100644 xpcom/ds/nsIObserver.h create mode 100644 xpcom/ds/nsIObserverList.h create mode 100644 xpcom/ds/nsIObserverService.h create mode 100644 xpcom/ds/nsObserver.cpp create mode 100644 xpcom/ds/nsObserver.h create mode 100644 xpcom/ds/nsObserverList.cpp create mode 100644 xpcom/ds/nsObserverList.h create mode 100644 xpcom/ds/nsObserverService.cpp create mode 100644 xpcom/ds/nsObserverService.h create mode 100644 xpcom/tests/TestObserverService.cpp diff --git a/base/public/makefile.win b/base/public/makefile.win index e9052dddd882..086cca631d9d 100644 --- a/base/public/makefile.win +++ b/base/public/makefile.win @@ -34,6 +34,9 @@ EXPORTS = \ nsIThread.h \ nsSpecialSystemDirectory.h \ nsIByteBufferInputStream.h \ + nsIObserverService.h \ + nsIObserverList.h \ + nsIObserver.h \ $(NULL) MODULE = raptor diff --git a/base/public/nsIObserver.h b/base/public/nsIObserver.h new file mode 100644 index 000000000000..1939612f14a6 --- /dev/null +++ b/base/public/nsIObserver.h @@ -0,0 +1,45 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef nsIObserver_h__ +#define nsIObserver_h__ + +#include "nsISupports.h" +#include "nscore.h" + + +// {DB242E01-E4D9-11d2-9DDE-000064657374} +#define NS_IOBSERVER_IID \ +{ 0xdb242e01, 0xe4d9, 0x11d2, { 0x9d, 0xde, 0x0, 0x0, 0x64, 0x65, 0x73, 0x74 } }; + + +// {DB242E03-E4D9-11d2-9DDE-000064657374} +#define NS_OBSERVER_CID \ +{ 0xdb242e03, 0xe4d9, 0x11d2, { 0x9d, 0xde, 0x0, 0x0, 0x64, 0x65, 0x73, 0x74 } }; + +class nsIObserver : public nsISupports { +public: + static const nsIID& GetIID() { static nsIID iid = NS_IOBSERVER_IID; return iid; } + NS_IMETHOD Notify(nsISupports** result) = 0; +}; + +extern NS_BASE nsresult NS_NewObserver(nsIObserver** anObserver); + +#define NS_OBSERVER_PROGID "component:||netscape|Observer" + +#endif /* nsIObserver_h__ */ diff --git a/base/public/nsIObserverList.h b/base/public/nsIObserverList.h new file mode 100644 index 000000000000..8d44081b0578 --- /dev/null +++ b/base/public/nsIObserverList.h @@ -0,0 +1,48 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef nsIObserverList_h__ +#define nsIObserverList_h__ + +#include "nsISupports.h" +#include "nsIObserver.h" +#include "nsIEnumerator.h" +#include "nscore.h" + + +// {E777D482-E6E3-11d2-8ACD-00105A1B8860} +#define NS_IOBSERVERLIST_IID \ +{ 0xe777d482, 0xe6e3, 0x11d2, { 0x8a, 0xcd, 0x0, 0x10, 0x5a, 0x1b, 0x88, 0x60 } }; + +// {E777D484-E6E3-11d2-8ACD-00105A1B8860} +#define NS_OBSERVERLIST_CID \ +{ 0xe777d484, 0xe6e3, 0x11d2, { 0x8a, 0xcd, 0x0, 0x10, 0x5a, 0x1b, 0x88, 0x60 } }; + +class nsIObserverList : public nsISupports { +public: + static const nsIID& GetIID() { static nsIID iid = NS_IOBSERVERLIST_IID; return iid; } + + NS_IMETHOD AddObserver(nsIObserver** anObserver) = 0; + NS_IMETHOD RemoveObserver(nsIObserver** anObserver) = 0; + NS_IMETHOD EnumerateObserverList(nsIEnumerator** anEnumerator) = 0; + +}; + +extern NS_BASE nsresult NS_NewObserverList(nsIObserverList** anObserverList); + +#endif /* nsIObserverList_h__ */ diff --git a/base/public/nsIObserverService.h b/base/public/nsIObserverService.h new file mode 100644 index 000000000000..bee6747c9f78 --- /dev/null +++ b/base/public/nsIObserverService.h @@ -0,0 +1,49 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef nsIObserverService_h__ +#define nsIObserverService_h__ + +#include "nsISupports.h" +#include "nsIObserverList.h" +#include "nsString.h" + + +// {D07F5192-E3D1-11d2-8ACD-00105A1B8860} +#define NS_IOBSERVERSERVICE_IID \ +{ 0xd07f5192, 0xe3d1, 0x11d2, { 0x8a, 0xcd, 0x0, 0x10, 0x5a, 0x1b, 0x88, 0x60 } }; + + +// {D07F5195-E3D1-11d2-8ACD-00105A1B8860} +#define NS_OBSERVERSERVICE_CID \ +{ 0xd07f5195, 0xe3d1, 0x11d2, { 0x8a, 0xcd, 0x0, 0x10, 0x5a, 0x1b, 0x88, 0x60 } }; + + +class nsIObserverService : public nsISupports { +public: + static const nsIID& GetIID() { static nsIID iid = NS_IOBSERVERSERVICE_IID; return iid; } + + NS_IMETHOD GetObserverList(nsString* aTopic, nsIObserverList** anObserverList) = 0; +}; + +extern NS_BASE nsresult NS_NewObserverService(nsIObserverService** anObserverService); + +#define NS_OBSERVERSERVICE_PROGID "component:||netscape|ObserverService" + + +#endif /* nsIObserverService_h__ */ diff --git a/base/src/makefile.win b/base/src/makefile.win index c49019623997..2e626666e752 100644 --- a/base/src/makefile.win +++ b/base/src/makefile.win @@ -48,6 +48,9 @@ CPPSRCS = \ nsIFileStream.cpp \ nsThread.cpp \ nsSpecialSystemDirectory.cpp \ + nsObserverService.cpp \ + nsObserverList.cpp \ + nsObserver.cpp \ $(NULL) CPP_OBJS = \ @@ -75,6 +78,9 @@ CPP_OBJS = \ .\$(OBJDIR)\nsThread.obj \ .\$(OBJDIR)\nsIStringStream.obj \ .\$(OBJDIR)\nsSpecialSystemDirectory.obj \ + .\$(OBJDIR)\nsObserverService.obj \ + .\$(OBJDIR)\nsObserverList.obj \ + .\$(OBJDIR)\nsObserver.obj \ $(NULL) EXPORTS=nscore.h nsIArena.h nsIAtom.h nsIByteBuffer.h \ diff --git a/base/src/nsBaseDLL.cpp b/base/src/nsBaseDLL.cpp index e143d35be4de..24c69607a33c 100644 --- a/base/src/nsBaseDLL.cpp +++ b/base/src/nsBaseDLL.cpp @@ -24,8 +24,20 @@ #include "nsIServiceManager.h" #include "nsCOMPtr.h" +#ifdef XP_PC +#include "nsIObserverService.h" +#include "nsObserverService.h" +#include "nsIObserver.h" +#include "nsObserver.h" +#endif + static NS_DEFINE_CID(kComponentManagerCID, NS_COMPONENTMANAGER_CID); +#ifdef XP_PC +static NS_DEFINE_IID(kObserverServiceCID, NS_OBSERVERSERVICE_CID); +static NS_DEFINE_IID(kObserverCID, NS_OBSERVER_CID); +#endif + PRInt32 gLockCount = 0; NS_DEFINE_IID(kIFactoryIID, NS_IFACTORY_IID); @@ -46,6 +58,16 @@ NSRegisterSelf(nsISupports* aServMgr, const char* path) rv = compMgr->RegisterComponent(kPropertiesCID, NULL, NULL, path, PR_TRUE, PR_TRUE); +#ifdef XP_PC + rv = compMgr->RegisterComponent(kObserverServiceCID, + "ObserverService", + NS_OBSERVERSERVICE_PROGID, + path,PR_TRUE, PR_TRUE); + rv = compMgr->RegisterComponent(kObserverCID, + "Observer", + NS_OBSERVER_PROGID, + path,PR_TRUE, PR_TRUE); +#endif (void)servMgr->ReleaseService(kComponentManagerCID, compMgr); return rv; @@ -67,6 +89,11 @@ NSUnregisterSelf(nsISupports* aServMgr, const char* path) rv = compMgr->UnregisterFactory(kPropertiesCID, path); +#ifdef XP_PC + rv = compMgr->UnregisterFactory(kObserverServiceCID, path); + rv = compMgr->UnregisterFactory(kObserverCID, path); +#endif + (void)servMgr->ReleaseService(kComponentManagerCID, compMgr); return rv; } @@ -97,6 +124,35 @@ NSGetFactory(nsISupports* aServMgr, return res; } +#ifdef XP_PC + else if (aClass.Equals(kObserverServiceCID)) { + nsObserverServiceFactory *observerServiceFactory = new nsObserverServiceFactory(); + + if (observerServiceFactory == nsnull) + return NS_ERROR_OUT_OF_MEMORY; + + res = observerServiceFactory->QueryInterface(kIFactoryIID, (void**) aFactory); + if (NS_FAILED(res)) { + *aFactory = nsnull; + delete observerServiceFactory; + } + + return res; + } else if (aClass.Equals(kObserverCID)) { + nsObserverFactory *observerFactory = new nsObserverFactory(); + + if (observerFactory == nsnull) + return NS_ERROR_OUT_OF_MEMORY; + + res = observerFactory->QueryInterface(kIFactoryIID, (void**) aFactory); + if (NS_FAILED(res)) { + *aFactory = nsnull; + delete observerFactory; + } + + return res; + } +#endif return NS_NOINTERFACE; } diff --git a/base/src/nsObserver.cpp b/base/src/nsObserver.cpp new file mode 100644 index 000000000000..5dc9e56b3761 --- /dev/null +++ b/base/src/nsObserver.cpp @@ -0,0 +1,123 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#define NS_IMPL_IDS +#include "pratom.h" +#include "nsIFactory.h" +#include "nsIServiceManager.h" +#include "nsRepository.h" +#include "nsIObserver.h" +#include "nsObserver.h" +#include "nsString.h" + +static NS_DEFINE_IID(kIObserverIID, NS_IOBSERVER_IID); +static NS_DEFINE_IID(kObserverCID, NS_OBSERVER_CID); + + +//////////////////////////////////////////////////////////////////////////////// +// nsObserver Implementation + + +NS_IMPL_ISUPPORTS(nsObserver, kIObserverIID); + +NS_BASE nsresult NS_NewObserver(nsIObserver** anObserver) +{ + if (anObserver == NULL) + { + return NS_ERROR_NULL_POINTER; + } + + nsObserver* it = new nsObserver(); + + if (it == 0) { + return NS_ERROR_OUT_OF_MEMORY; + } + + return it->QueryInterface(kIObserverIID, (void **) anObserver); +} + +nsObserver::nsObserver() +{ + NS_INIT_REFCNT(); +} + +nsObserver::~nsObserver(void) +{ + +} + +nsresult nsObserver::Notify(nsISupports** result) +{ + return NS_OK; + +} + + +//////////////////////////////////////////////////////////////////////////////// +// nsObserverFactory Implementation + +static NS_DEFINE_IID(kIFactoryIID, NS_IFACTORY_IID); +NS_IMPL_ISUPPORTS(nsObserverFactory, kIFactoryIID); + +nsObserverFactory::nsObserverFactory(void) +{ + NS_INIT_REFCNT(); +} + +nsObserverFactory::~nsObserverFactory(void) +{ + +} + +nsresult +nsObserverFactory::CreateInstance(nsISupports *aOuter, REFNSIID aIID, void **aResult) +{ + if (! aResult) + return NS_ERROR_NULL_POINTER; + + if (aOuter) + return NS_ERROR_NO_AGGREGATION; + + *aResult = nsnull; + + nsresult rv; + nsIObserver* inst = nsnull; + + if (NS_FAILED(rv = NS_NewObserver(&inst))) + return rv; + + if (!inst) + return NS_ERROR_OUT_OF_MEMORY; + + rv = inst->QueryInterface(aIID, aResult); + + if (NS_FAILED(rv)) { + *aResult = NULL; + } + return rv; +} + +nsresult +nsObserverFactory::LockFactory(PRBool aLock) +{ + return NS_OK; +} + + + +//////////////////////////////////////////////////////////////////////////////// diff --git a/base/src/nsObserver.h b/base/src/nsObserver.h new file mode 100644 index 000000000000..cf8eef47f9ab --- /dev/null +++ b/base/src/nsObserver.h @@ -0,0 +1,61 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef nsObserver_h___ +#define nsObserver_h___ + +#include "nsIFactory.h" +#include "nsIObserver.h" + +class nsObserver : public nsIObserver { +public: + + NS_IMETHOD Notify(nsISupports** result); + + nsObserver(); + ~nsObserver(void); + + NS_DECL_ISUPPORTS + + +private: + +}; + +class nsObserverFactory : public nsIFactory { +public: + + NS_DECL_ISUPPORTS + + // nsIFactory methods: + + NS_IMETHOD CreateInstance(nsISupports *aOuter, + REFNSIID aIID, + void **aResult); + + NS_IMETHOD LockFactory(PRBool aLock); + + // nsObserver methods: + + nsObserverFactory(void); + virtual ~nsObserverFactory(void); + +}; + + +#endif /* nsObserver_h___ */ diff --git a/base/src/nsObserverList.cpp b/base/src/nsObserverList.cpp new file mode 100644 index 000000000000..1d2ac8f51adb --- /dev/null +++ b/base/src/nsObserverList.cpp @@ -0,0 +1,124 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#define NS_IMPL_IDS +#include "pratom.h" +//#include "nsIFactory.h" +//#include "nsIServiceManager.h" +#include "nsRepository.h" +#include "nsIObserverList.h" +#include "nsObserverList.h" +#include "nsHashtable.h" +#include "nsString.h" +#include "nsAutoLock.h" + + +#define NS_AUTOLOCK(__monitor) nsAutoLock __lock(__monitor) + +static NS_DEFINE_IID(kIObserverListIID, NS_IOBSERVERLIST_IID); +static NS_DEFINE_IID(kObserverListCID, NS_OBSERVERLIST_CID); + + +//////////////////////////////////////////////////////////////////////////////// +// nsObserverList Implementation + + +NS_IMPL_ISUPPORTS(nsObserverList, kIObserverListIID); + +NS_BASE nsresult NS_NewObserverList(nsIObserverList** anObserverList) +{ + + if (anObserverList == NULL) + { + return NS_ERROR_NULL_POINTER; + } + nsObserverList* it = new nsObserverList(); + + if (it == 0) { + return NS_ERROR_OUT_OF_MEMORY; + } + + return it->QueryInterface(kIObserverListIID, (void **) anObserverList); +} + +nsObserverList::nsObserverList() + : mObserverList(NULL), + mLock(nsnull) +{ + NS_INIT_REFCNT(); + mLock = PR_NewLock(); +} + +nsObserverList::~nsObserverList(void) +{ + PR_DestroyLock(mLock); +} + + +nsresult nsObserverList::AddObserver(nsIObserver** anObserver) +{ + nsresult rv; + + NS_AUTOLOCK(mLock); + + if (anObserver == NULL) + { + return NS_ERROR_NULL_POINTER; + } + + if(!mObserverList) { + rv = NS_NewISupportsArray(&mObserverList); + if (NS_FAILED(rv)) return rv; + } + + if(*anObserver) { + mObserverList->AppendElement(*anObserver); + } + + return NS_OK; +} + +nsresult nsObserverList::RemoveObserver(nsIObserver** anObserver) +{ + NS_AUTOLOCK(mLock); + + if (anObserver == NULL) + { + return NS_ERROR_NULL_POINTER; + } + + if(*anObserver) { + mObserverList->RemoveElement(*anObserver); + } + + return NS_OK; + +} + +NS_IMETHODIMP nsObserverList::EnumerateObserverList(nsIEnumerator** anEnumerator) +{ + NS_AUTOLOCK(mLock); + + if (anEnumerator == NULL) + { + return NS_ERROR_NULL_POINTER; + } + + return mObserverList->Enumerate(anEnumerator); +} + diff --git a/base/src/nsObserverList.h b/base/src/nsObserverList.h new file mode 100644 index 000000000000..eb4442b259bb --- /dev/null +++ b/base/src/nsObserverList.h @@ -0,0 +1,51 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef nsObserverList_h___ +#define nsObserverList_h___ + +#include "nsIObserverList.h" +#include "nsIEnumerator.h" +#include "nsISupportsArray.h" + + +class nsObserverList : public nsIObserverList { +public: + + NS_IMETHOD AddObserver(nsIObserver** anObserver); + NS_IMETHOD RemoveObserver(nsIObserver** anObserver); + + NS_IMETHOD EnumerateObserverList(nsIEnumerator** anEnumerator); + + nsObserverList(); + ~nsObserverList(void); + + // This is ObserverList monitor object. + PRLock* mLock; + + NS_DECL_ISUPPORTS + + +private: + + nsISupportsArray *mObserverList; + +}; + + +#endif /* nsObserverList_h___ */ diff --git a/base/src/nsObserverService.cpp b/base/src/nsObserverService.cpp new file mode 100644 index 000000000000..e01828b71bfc --- /dev/null +++ b/base/src/nsObserverService.cpp @@ -0,0 +1,202 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#define NS_IMPL_IDS +#include "prlock.h" +#include "nsIFactory.h" +#include "nsIServiceManager.h" +#include "nsRepository.h" +#include "nsIObserverService.h" +#include "nsObserverService.h" +#include "nsIObserverList.h" +#include "nsObserverList.h" +#include "nsHashtable.h" +#include "nsVoidArray.h" +#include "nsString.h" + +static NS_DEFINE_IID(kIObserverServiceIID, NS_IOBSERVERSERVICE_IID); +static NS_DEFINE_IID(kObserverServiceCID, NS_OBSERVERSERVICE_CID); + + +//////////////////////////////////////////////////////////////////////////////// + +class nsObserverService : public nsIObserverService { +public: + static nsresult GetObserverService(nsIObserverService** anObserverService); + + NS_IMETHOD GetObserverList(nsString* aTopic, nsIObserverList** anObserverList); + + nsObserverService(); + ~nsObserverService(void); + + NS_DECL_ISUPPORTS + + +private: + + nsHashtable *mObserverTopicTable; + +}; + +static nsObserverService* gObserverService = nsnull; // The one-and-only ObserverService + +//////////////////////////////////////////////////////////////////////////////// +// nsObserverService Implementation + + +NS_IMPL_ISUPPORTS(nsObserverService, kIObserverServiceIID); + +NS_BASE nsresult NS_NewObserverService(nsIObserverService** anObserverService) +{ + return nsObserverService::GetObserverService(anObserverService); +} + +nsObserverService::nsObserverService() + : mObserverTopicTable(NULL) +{ + NS_INIT_REFCNT(); + mObserverTopicTable = nsnull; +} + +nsObserverService::~nsObserverService(void) +{ + if(mObserverTopicTable) + delete mObserverTopicTable; + gObserverService = nsnull; +} + + +nsresult nsObserverService::GetObserverService(nsIObserverService** anObserverService) +{ + if (! gObserverService) { + nsObserverService* it = new nsObserverService(); + if (! it) + return NS_ERROR_OUT_OF_MEMORY; + gObserverService = it; + } + + NS_ADDREF(gObserverService); + *anObserverService = gObserverService; + return NS_OK; +} + +nsresult nsObserverService::GetObserverList(nsString* aTopic, nsIObserverList** anObserverList) +{ + if (anObserverList == NULL) + { + return NS_ERROR_NULL_POINTER; + } + + if(mObserverTopicTable == NULL) { + mObserverTopicTable = new nsHashtable(256, PR_TRUE); + if (mObserverTopicTable == NULL) + return NS_ERROR_OUT_OF_MEMORY; + } + + + // Safely convert to a C-string + char buf[128]; + char* topic = buf; + + if ((*aTopic).Length() >= sizeof(buf)) + topic = new char[(*aTopic).Length() + 1]; + + if (topic == nsnull) + return NS_ERROR_OUT_OF_MEMORY; + + (*aTopic).ToCString(topic, (*aTopic).Length() + 1); + + nsCStringKey key(topic); + + nsIObserverList *topicObservers = nsnull; + if(mObserverTopicTable->Exists(&key)) { + topicObservers = (nsIObserverList *) mObserverTopicTable->Get(&key); + if (topicObservers != NULL) { + *anObserverList = topicObservers; + } else { + NS_NewObserverList(&topicObservers); + mObserverTopicTable->Put(&key, topicObservers); + } + } else { + NS_NewObserverList(&topicObservers); + *anObserverList = topicObservers; + mObserverTopicTable->Put(&key, topicObservers); + + } + + return NS_OK; +} + + + +//////////////////////////////////////////////////////////////////////////////// +// nsObserverServiceFactory Implementation + +static NS_DEFINE_IID(kIFactoryIID, NS_IFACTORY_IID); +NS_IMPL_ISUPPORTS(nsObserverServiceFactory, kIFactoryIID); + +nsObserverServiceFactory::nsObserverServiceFactory(void) +{ + NS_INIT_REFCNT(); +} + +nsObserverServiceFactory::~nsObserverServiceFactory(void) +{ + +} + +nsresult +nsObserverServiceFactory::CreateInstance(nsISupports *aOuter, REFNSIID aIID, void **aResult) +{ + if (! aResult) + return NS_ERROR_NULL_POINTER; + + if (aOuter) + return NS_ERROR_NO_AGGREGATION; + + *aResult = nsnull; + + nsresult rv; + nsIObserverService* inst = nsnull; + + + if (NS_FAILED(rv = NS_NewObserverService(&inst))) + return rv; + + + if (!inst) + return NS_ERROR_OUT_OF_MEMORY; + + rv = inst->QueryInterface(aIID, aResult); + + if (NS_FAILED(rv)) { + *aResult = NULL; + } + return rv; +} + +nsresult +nsObserverServiceFactory::LockFactory(PRBool aLock) +{ + return NS_OK; +} + + + +//////////////////////////////////////////////////////////////////////////////// + diff --git a/base/src/nsObserverService.h b/base/src/nsObserverService.h new file mode 100644 index 000000000000..6d04c07e89a1 --- /dev/null +++ b/base/src/nsObserverService.h @@ -0,0 +1,45 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef nsObserverService_h___ +#define nsObserverService_h___ + +#include "nsIFactory.h" + +class nsObserverServiceFactory : public nsIFactory { +public: + + NS_DECL_ISUPPORTS + + // nsIFactory methods: + + NS_IMETHOD CreateInstance(nsISupports *aOuter, + REFNSIID aIID, + void **aResult); + + NS_IMETHOD LockFactory(PRBool aLock); + + // nsObserverService methods: + + nsObserverServiceFactory(void); + virtual ~nsObserverServiceFactory(void); + +}; + + +#endif /* nsObserverService_h___ */ diff --git a/base/tests/TestObserverService.cpp b/base/tests/TestObserverService.cpp new file mode 100644 index 000000000000..e9ed41260c85 --- /dev/null +++ b/base/tests/TestObserverService.cpp @@ -0,0 +1,86 @@ +#define NS_IMPL_IDS +#include "nsISupports.h" +#include "nsRepository.h" +#include "nsIObserverService.h" +#include "nsIObserverList.h" +#include "nsIObserver.h" +#include "nsString.h" + +static NS_DEFINE_IID(kIObserverServiceIID, NS_IOBSERVERSERVICE_IID); +static NS_DEFINE_IID(kObserverServiceCID, NS_OBSERVERSERVICE_CID); + + +static NS_DEFINE_IID(kIObserverIID, NS_IOBSERVER_IID); +static NS_DEFINE_IID(kObserverCID, NS_OBSERVER_CID); + +#define BASE_DLL "raptorbase.dll" + +int main(int argc, char *argv[]) +{ + + nsIObserverService *anObserverService = NULL; + nsresult rv; + + /* nsComponentManager::RegisterComponent(kObserverServiceCID, + "ObserverService", + NS_OBSERVERSERVICE_PROGID, + BASE_DLL,PR_TRUE, PR_TRUE);*/ + + nsresult res = nsRepository::CreateInstance(kObserverServiceCID, + NULL, + kIObserverServiceIID, + (void **) &anObserverService); + + + if (res == NS_OK) { + + nsString aTopic("tagobserver"); + + nsIObserverList* anObserverList; + nsIObserver *anObserver; + nsIObserver *aObserver = nsnull; + nsIObserver *bObserver = nsnull; + + nsresult res = nsRepository::CreateInstance(kObserverCID, + NULL, + kIObserverIID, + (void **) &anObserver); + + + rv = anObserverService->GetObserverList(&aTopic, &anObserverList); + if (NS_FAILED(rv)) return rv; + + NS_NewObserver(&aObserver); + + + if (anObserverList) { + anObserverList->AddObserver(&aObserver); + } + + NS_NewObserver(&bObserver); + + + if (anObserverList) { + anObserverList->AddObserver(&bObserver); + } + + + nsIEnumerator* e; + rv = anObserverList->EnumerateObserverList(&e); + if (NS_FAILED(rv)) return rv; + nsISupports *inst; + + for (e->First(); e->IsDone() != NS_OK; e->Next()) { + rv = e->CurrentItem(&inst); + if (NS_SUCCEEDED(rv)) { + rv = inst->QueryInterface(nsIObserver::GetIID(), (void**)&anObserver); + } + anObserver->Notify(nsnull); + } + + + + } + return NS_OK; +} + diff --git a/base/tests/makefile.win b/base/tests/makefile.win index 1f3e7f391662..4c7dfd7c5d03 100644 --- a/base/tests/makefile.win +++ b/base/tests/makefile.win @@ -26,6 +26,7 @@ PROG4 = .\$(OBJDIR)\FilesTest.exe PROG5 = .\$(OBJDIR)\PropertiesTest.exe PROG6 = .\$(OBJDIR)\TestAutoLock.exe PROG7 = .\$(OBJDIR)\TestThreads.exe +PROG8 = .\$(OBJDIR)\TestObserverService.exe RESFILE = timer.res PROGRAMS = $(PROG0) $(PROG1) \ !ifdef MODULAR_NETLIB @@ -36,6 +37,7 @@ PROGRAMS = $(PROG0) $(PROG1) \ $(PROG4) \ $(PROG6) \ $(PROG7) \ + $(PROG8) \ $(NULL) LINCS=-I..\src -I$(PUBLIC)\xpcom -I$(PUBLIC)\netlib -I$(PUBLIC)\raptor @@ -67,6 +69,7 @@ install:: $(PROGRAMS) $(MAKE_INSTALL) $(PROG4) $(DIST)\bin $(MAKE_INSTALL) $(PROG6) $(DIST)\bin $(MAKE_INSTALL) $(PROG7) $(DIST)\bin + $(MAKE_INSTALL) $(PROG8) $(DIST)\bin clobber:: rm -f $(DIST)\bin\TimerTest.exe @@ -79,6 +82,7 @@ clobber:: !endif rm -f $(DIST)\bin\FilesTest.exe rm -f $(DIST)\bin\TestAutoLock.exe + rm -f $(DIST)\bin\TestObserverService.exe # Move this into config/obj.inc when it's allowed .cpp{.\$(OBJDIR)\}.exe: @@ -114,4 +118,7 @@ $(PROG6): $(OBJDIR) TestAutoLock.cpp $(PROG7): $(OBJDIR) TestThreads.cpp +$(PROG8): $(OBJDIR) TestObserverService.cpp + + diff --git a/xpcom/ds/nsIObserver.h b/xpcom/ds/nsIObserver.h new file mode 100644 index 000000000000..1939612f14a6 --- /dev/null +++ b/xpcom/ds/nsIObserver.h @@ -0,0 +1,45 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef nsIObserver_h__ +#define nsIObserver_h__ + +#include "nsISupports.h" +#include "nscore.h" + + +// {DB242E01-E4D9-11d2-9DDE-000064657374} +#define NS_IOBSERVER_IID \ +{ 0xdb242e01, 0xe4d9, 0x11d2, { 0x9d, 0xde, 0x0, 0x0, 0x64, 0x65, 0x73, 0x74 } }; + + +// {DB242E03-E4D9-11d2-9DDE-000064657374} +#define NS_OBSERVER_CID \ +{ 0xdb242e03, 0xe4d9, 0x11d2, { 0x9d, 0xde, 0x0, 0x0, 0x64, 0x65, 0x73, 0x74 } }; + +class nsIObserver : public nsISupports { +public: + static const nsIID& GetIID() { static nsIID iid = NS_IOBSERVER_IID; return iid; } + NS_IMETHOD Notify(nsISupports** result) = 0; +}; + +extern NS_BASE nsresult NS_NewObserver(nsIObserver** anObserver); + +#define NS_OBSERVER_PROGID "component:||netscape|Observer" + +#endif /* nsIObserver_h__ */ diff --git a/xpcom/ds/nsIObserverList.h b/xpcom/ds/nsIObserverList.h new file mode 100644 index 000000000000..8d44081b0578 --- /dev/null +++ b/xpcom/ds/nsIObserverList.h @@ -0,0 +1,48 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef nsIObserverList_h__ +#define nsIObserverList_h__ + +#include "nsISupports.h" +#include "nsIObserver.h" +#include "nsIEnumerator.h" +#include "nscore.h" + + +// {E777D482-E6E3-11d2-8ACD-00105A1B8860} +#define NS_IOBSERVERLIST_IID \ +{ 0xe777d482, 0xe6e3, 0x11d2, { 0x8a, 0xcd, 0x0, 0x10, 0x5a, 0x1b, 0x88, 0x60 } }; + +// {E777D484-E6E3-11d2-8ACD-00105A1B8860} +#define NS_OBSERVERLIST_CID \ +{ 0xe777d484, 0xe6e3, 0x11d2, { 0x8a, 0xcd, 0x0, 0x10, 0x5a, 0x1b, 0x88, 0x60 } }; + +class nsIObserverList : public nsISupports { +public: + static const nsIID& GetIID() { static nsIID iid = NS_IOBSERVERLIST_IID; return iid; } + + NS_IMETHOD AddObserver(nsIObserver** anObserver) = 0; + NS_IMETHOD RemoveObserver(nsIObserver** anObserver) = 0; + NS_IMETHOD EnumerateObserverList(nsIEnumerator** anEnumerator) = 0; + +}; + +extern NS_BASE nsresult NS_NewObserverList(nsIObserverList** anObserverList); + +#endif /* nsIObserverList_h__ */ diff --git a/xpcom/ds/nsIObserverService.h b/xpcom/ds/nsIObserverService.h new file mode 100644 index 000000000000..bee6747c9f78 --- /dev/null +++ b/xpcom/ds/nsIObserverService.h @@ -0,0 +1,49 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef nsIObserverService_h__ +#define nsIObserverService_h__ + +#include "nsISupports.h" +#include "nsIObserverList.h" +#include "nsString.h" + + +// {D07F5192-E3D1-11d2-8ACD-00105A1B8860} +#define NS_IOBSERVERSERVICE_IID \ +{ 0xd07f5192, 0xe3d1, 0x11d2, { 0x8a, 0xcd, 0x0, 0x10, 0x5a, 0x1b, 0x88, 0x60 } }; + + +// {D07F5195-E3D1-11d2-8ACD-00105A1B8860} +#define NS_OBSERVERSERVICE_CID \ +{ 0xd07f5195, 0xe3d1, 0x11d2, { 0x8a, 0xcd, 0x0, 0x10, 0x5a, 0x1b, 0x88, 0x60 } }; + + +class nsIObserverService : public nsISupports { +public: + static const nsIID& GetIID() { static nsIID iid = NS_IOBSERVERSERVICE_IID; return iid; } + + NS_IMETHOD GetObserverList(nsString* aTopic, nsIObserverList** anObserverList) = 0; +}; + +extern NS_BASE nsresult NS_NewObserverService(nsIObserverService** anObserverService); + +#define NS_OBSERVERSERVICE_PROGID "component:||netscape|ObserverService" + + +#endif /* nsIObserverService_h__ */ diff --git a/xpcom/ds/nsObserver.cpp b/xpcom/ds/nsObserver.cpp new file mode 100644 index 000000000000..5dc9e56b3761 --- /dev/null +++ b/xpcom/ds/nsObserver.cpp @@ -0,0 +1,123 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#define NS_IMPL_IDS +#include "pratom.h" +#include "nsIFactory.h" +#include "nsIServiceManager.h" +#include "nsRepository.h" +#include "nsIObserver.h" +#include "nsObserver.h" +#include "nsString.h" + +static NS_DEFINE_IID(kIObserverIID, NS_IOBSERVER_IID); +static NS_DEFINE_IID(kObserverCID, NS_OBSERVER_CID); + + +//////////////////////////////////////////////////////////////////////////////// +// nsObserver Implementation + + +NS_IMPL_ISUPPORTS(nsObserver, kIObserverIID); + +NS_BASE nsresult NS_NewObserver(nsIObserver** anObserver) +{ + if (anObserver == NULL) + { + return NS_ERROR_NULL_POINTER; + } + + nsObserver* it = new nsObserver(); + + if (it == 0) { + return NS_ERROR_OUT_OF_MEMORY; + } + + return it->QueryInterface(kIObserverIID, (void **) anObserver); +} + +nsObserver::nsObserver() +{ + NS_INIT_REFCNT(); +} + +nsObserver::~nsObserver(void) +{ + +} + +nsresult nsObserver::Notify(nsISupports** result) +{ + return NS_OK; + +} + + +//////////////////////////////////////////////////////////////////////////////// +// nsObserverFactory Implementation + +static NS_DEFINE_IID(kIFactoryIID, NS_IFACTORY_IID); +NS_IMPL_ISUPPORTS(nsObserverFactory, kIFactoryIID); + +nsObserverFactory::nsObserverFactory(void) +{ + NS_INIT_REFCNT(); +} + +nsObserverFactory::~nsObserverFactory(void) +{ + +} + +nsresult +nsObserverFactory::CreateInstance(nsISupports *aOuter, REFNSIID aIID, void **aResult) +{ + if (! aResult) + return NS_ERROR_NULL_POINTER; + + if (aOuter) + return NS_ERROR_NO_AGGREGATION; + + *aResult = nsnull; + + nsresult rv; + nsIObserver* inst = nsnull; + + if (NS_FAILED(rv = NS_NewObserver(&inst))) + return rv; + + if (!inst) + return NS_ERROR_OUT_OF_MEMORY; + + rv = inst->QueryInterface(aIID, aResult); + + if (NS_FAILED(rv)) { + *aResult = NULL; + } + return rv; +} + +nsresult +nsObserverFactory::LockFactory(PRBool aLock) +{ + return NS_OK; +} + + + +//////////////////////////////////////////////////////////////////////////////// diff --git a/xpcom/ds/nsObserver.h b/xpcom/ds/nsObserver.h new file mode 100644 index 000000000000..cf8eef47f9ab --- /dev/null +++ b/xpcom/ds/nsObserver.h @@ -0,0 +1,61 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef nsObserver_h___ +#define nsObserver_h___ + +#include "nsIFactory.h" +#include "nsIObserver.h" + +class nsObserver : public nsIObserver { +public: + + NS_IMETHOD Notify(nsISupports** result); + + nsObserver(); + ~nsObserver(void); + + NS_DECL_ISUPPORTS + + +private: + +}; + +class nsObserverFactory : public nsIFactory { +public: + + NS_DECL_ISUPPORTS + + // nsIFactory methods: + + NS_IMETHOD CreateInstance(nsISupports *aOuter, + REFNSIID aIID, + void **aResult); + + NS_IMETHOD LockFactory(PRBool aLock); + + // nsObserver methods: + + nsObserverFactory(void); + virtual ~nsObserverFactory(void); + +}; + + +#endif /* nsObserver_h___ */ diff --git a/xpcom/ds/nsObserverList.cpp b/xpcom/ds/nsObserverList.cpp new file mode 100644 index 000000000000..1d2ac8f51adb --- /dev/null +++ b/xpcom/ds/nsObserverList.cpp @@ -0,0 +1,124 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#define NS_IMPL_IDS +#include "pratom.h" +//#include "nsIFactory.h" +//#include "nsIServiceManager.h" +#include "nsRepository.h" +#include "nsIObserverList.h" +#include "nsObserverList.h" +#include "nsHashtable.h" +#include "nsString.h" +#include "nsAutoLock.h" + + +#define NS_AUTOLOCK(__monitor) nsAutoLock __lock(__monitor) + +static NS_DEFINE_IID(kIObserverListIID, NS_IOBSERVERLIST_IID); +static NS_DEFINE_IID(kObserverListCID, NS_OBSERVERLIST_CID); + + +//////////////////////////////////////////////////////////////////////////////// +// nsObserverList Implementation + + +NS_IMPL_ISUPPORTS(nsObserverList, kIObserverListIID); + +NS_BASE nsresult NS_NewObserverList(nsIObserverList** anObserverList) +{ + + if (anObserverList == NULL) + { + return NS_ERROR_NULL_POINTER; + } + nsObserverList* it = new nsObserverList(); + + if (it == 0) { + return NS_ERROR_OUT_OF_MEMORY; + } + + return it->QueryInterface(kIObserverListIID, (void **) anObserverList); +} + +nsObserverList::nsObserverList() + : mObserverList(NULL), + mLock(nsnull) +{ + NS_INIT_REFCNT(); + mLock = PR_NewLock(); +} + +nsObserverList::~nsObserverList(void) +{ + PR_DestroyLock(mLock); +} + + +nsresult nsObserverList::AddObserver(nsIObserver** anObserver) +{ + nsresult rv; + + NS_AUTOLOCK(mLock); + + if (anObserver == NULL) + { + return NS_ERROR_NULL_POINTER; + } + + if(!mObserverList) { + rv = NS_NewISupportsArray(&mObserverList); + if (NS_FAILED(rv)) return rv; + } + + if(*anObserver) { + mObserverList->AppendElement(*anObserver); + } + + return NS_OK; +} + +nsresult nsObserverList::RemoveObserver(nsIObserver** anObserver) +{ + NS_AUTOLOCK(mLock); + + if (anObserver == NULL) + { + return NS_ERROR_NULL_POINTER; + } + + if(*anObserver) { + mObserverList->RemoveElement(*anObserver); + } + + return NS_OK; + +} + +NS_IMETHODIMP nsObserverList::EnumerateObserverList(nsIEnumerator** anEnumerator) +{ + NS_AUTOLOCK(mLock); + + if (anEnumerator == NULL) + { + return NS_ERROR_NULL_POINTER; + } + + return mObserverList->Enumerate(anEnumerator); +} + diff --git a/xpcom/ds/nsObserverList.h b/xpcom/ds/nsObserverList.h new file mode 100644 index 000000000000..eb4442b259bb --- /dev/null +++ b/xpcom/ds/nsObserverList.h @@ -0,0 +1,51 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef nsObserverList_h___ +#define nsObserverList_h___ + +#include "nsIObserverList.h" +#include "nsIEnumerator.h" +#include "nsISupportsArray.h" + + +class nsObserverList : public nsIObserverList { +public: + + NS_IMETHOD AddObserver(nsIObserver** anObserver); + NS_IMETHOD RemoveObserver(nsIObserver** anObserver); + + NS_IMETHOD EnumerateObserverList(nsIEnumerator** anEnumerator); + + nsObserverList(); + ~nsObserverList(void); + + // This is ObserverList monitor object. + PRLock* mLock; + + NS_DECL_ISUPPORTS + + +private: + + nsISupportsArray *mObserverList; + +}; + + +#endif /* nsObserverList_h___ */ diff --git a/xpcom/ds/nsObserverService.cpp b/xpcom/ds/nsObserverService.cpp new file mode 100644 index 000000000000..e01828b71bfc --- /dev/null +++ b/xpcom/ds/nsObserverService.cpp @@ -0,0 +1,202 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#define NS_IMPL_IDS +#include "prlock.h" +#include "nsIFactory.h" +#include "nsIServiceManager.h" +#include "nsRepository.h" +#include "nsIObserverService.h" +#include "nsObserverService.h" +#include "nsIObserverList.h" +#include "nsObserverList.h" +#include "nsHashtable.h" +#include "nsVoidArray.h" +#include "nsString.h" + +static NS_DEFINE_IID(kIObserverServiceIID, NS_IOBSERVERSERVICE_IID); +static NS_DEFINE_IID(kObserverServiceCID, NS_OBSERVERSERVICE_CID); + + +//////////////////////////////////////////////////////////////////////////////// + +class nsObserverService : public nsIObserverService { +public: + static nsresult GetObserverService(nsIObserverService** anObserverService); + + NS_IMETHOD GetObserverList(nsString* aTopic, nsIObserverList** anObserverList); + + nsObserverService(); + ~nsObserverService(void); + + NS_DECL_ISUPPORTS + + +private: + + nsHashtable *mObserverTopicTable; + +}; + +static nsObserverService* gObserverService = nsnull; // The one-and-only ObserverService + +//////////////////////////////////////////////////////////////////////////////// +// nsObserverService Implementation + + +NS_IMPL_ISUPPORTS(nsObserverService, kIObserverServiceIID); + +NS_BASE nsresult NS_NewObserverService(nsIObserverService** anObserverService) +{ + return nsObserverService::GetObserverService(anObserverService); +} + +nsObserverService::nsObserverService() + : mObserverTopicTable(NULL) +{ + NS_INIT_REFCNT(); + mObserverTopicTable = nsnull; +} + +nsObserverService::~nsObserverService(void) +{ + if(mObserverTopicTable) + delete mObserverTopicTable; + gObserverService = nsnull; +} + + +nsresult nsObserverService::GetObserverService(nsIObserverService** anObserverService) +{ + if (! gObserverService) { + nsObserverService* it = new nsObserverService(); + if (! it) + return NS_ERROR_OUT_OF_MEMORY; + gObserverService = it; + } + + NS_ADDREF(gObserverService); + *anObserverService = gObserverService; + return NS_OK; +} + +nsresult nsObserverService::GetObserverList(nsString* aTopic, nsIObserverList** anObserverList) +{ + if (anObserverList == NULL) + { + return NS_ERROR_NULL_POINTER; + } + + if(mObserverTopicTable == NULL) { + mObserverTopicTable = new nsHashtable(256, PR_TRUE); + if (mObserverTopicTable == NULL) + return NS_ERROR_OUT_OF_MEMORY; + } + + + // Safely convert to a C-string + char buf[128]; + char* topic = buf; + + if ((*aTopic).Length() >= sizeof(buf)) + topic = new char[(*aTopic).Length() + 1]; + + if (topic == nsnull) + return NS_ERROR_OUT_OF_MEMORY; + + (*aTopic).ToCString(topic, (*aTopic).Length() + 1); + + nsCStringKey key(topic); + + nsIObserverList *topicObservers = nsnull; + if(mObserverTopicTable->Exists(&key)) { + topicObservers = (nsIObserverList *) mObserverTopicTable->Get(&key); + if (topicObservers != NULL) { + *anObserverList = topicObservers; + } else { + NS_NewObserverList(&topicObservers); + mObserverTopicTable->Put(&key, topicObservers); + } + } else { + NS_NewObserverList(&topicObservers); + *anObserverList = topicObservers; + mObserverTopicTable->Put(&key, topicObservers); + + } + + return NS_OK; +} + + + +//////////////////////////////////////////////////////////////////////////////// +// nsObserverServiceFactory Implementation + +static NS_DEFINE_IID(kIFactoryIID, NS_IFACTORY_IID); +NS_IMPL_ISUPPORTS(nsObserverServiceFactory, kIFactoryIID); + +nsObserverServiceFactory::nsObserverServiceFactory(void) +{ + NS_INIT_REFCNT(); +} + +nsObserverServiceFactory::~nsObserverServiceFactory(void) +{ + +} + +nsresult +nsObserverServiceFactory::CreateInstance(nsISupports *aOuter, REFNSIID aIID, void **aResult) +{ + if (! aResult) + return NS_ERROR_NULL_POINTER; + + if (aOuter) + return NS_ERROR_NO_AGGREGATION; + + *aResult = nsnull; + + nsresult rv; + nsIObserverService* inst = nsnull; + + + if (NS_FAILED(rv = NS_NewObserverService(&inst))) + return rv; + + + if (!inst) + return NS_ERROR_OUT_OF_MEMORY; + + rv = inst->QueryInterface(aIID, aResult); + + if (NS_FAILED(rv)) { + *aResult = NULL; + } + return rv; +} + +nsresult +nsObserverServiceFactory::LockFactory(PRBool aLock) +{ + return NS_OK; +} + + + +//////////////////////////////////////////////////////////////////////////////// + diff --git a/xpcom/ds/nsObserverService.h b/xpcom/ds/nsObserverService.h new file mode 100644 index 000000000000..6d04c07e89a1 --- /dev/null +++ b/xpcom/ds/nsObserverService.h @@ -0,0 +1,45 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef nsObserverService_h___ +#define nsObserverService_h___ + +#include "nsIFactory.h" + +class nsObserverServiceFactory : public nsIFactory { +public: + + NS_DECL_ISUPPORTS + + // nsIFactory methods: + + NS_IMETHOD CreateInstance(nsISupports *aOuter, + REFNSIID aIID, + void **aResult); + + NS_IMETHOD LockFactory(PRBool aLock); + + // nsObserverService methods: + + nsObserverServiceFactory(void); + virtual ~nsObserverServiceFactory(void); + +}; + + +#endif /* nsObserverService_h___ */ diff --git a/xpcom/tests/TestObserverService.cpp b/xpcom/tests/TestObserverService.cpp new file mode 100644 index 000000000000..e9ed41260c85 --- /dev/null +++ b/xpcom/tests/TestObserverService.cpp @@ -0,0 +1,86 @@ +#define NS_IMPL_IDS +#include "nsISupports.h" +#include "nsRepository.h" +#include "nsIObserverService.h" +#include "nsIObserverList.h" +#include "nsIObserver.h" +#include "nsString.h" + +static NS_DEFINE_IID(kIObserverServiceIID, NS_IOBSERVERSERVICE_IID); +static NS_DEFINE_IID(kObserverServiceCID, NS_OBSERVERSERVICE_CID); + + +static NS_DEFINE_IID(kIObserverIID, NS_IOBSERVER_IID); +static NS_DEFINE_IID(kObserverCID, NS_OBSERVER_CID); + +#define BASE_DLL "raptorbase.dll" + +int main(int argc, char *argv[]) +{ + + nsIObserverService *anObserverService = NULL; + nsresult rv; + + /* nsComponentManager::RegisterComponent(kObserverServiceCID, + "ObserverService", + NS_OBSERVERSERVICE_PROGID, + BASE_DLL,PR_TRUE, PR_TRUE);*/ + + nsresult res = nsRepository::CreateInstance(kObserverServiceCID, + NULL, + kIObserverServiceIID, + (void **) &anObserverService); + + + if (res == NS_OK) { + + nsString aTopic("tagobserver"); + + nsIObserverList* anObserverList; + nsIObserver *anObserver; + nsIObserver *aObserver = nsnull; + nsIObserver *bObserver = nsnull; + + nsresult res = nsRepository::CreateInstance(kObserverCID, + NULL, + kIObserverIID, + (void **) &anObserver); + + + rv = anObserverService->GetObserverList(&aTopic, &anObserverList); + if (NS_FAILED(rv)) return rv; + + NS_NewObserver(&aObserver); + + + if (anObserverList) { + anObserverList->AddObserver(&aObserver); + } + + NS_NewObserver(&bObserver); + + + if (anObserverList) { + anObserverList->AddObserver(&bObserver); + } + + + nsIEnumerator* e; + rv = anObserverList->EnumerateObserverList(&e); + if (NS_FAILED(rv)) return rv; + nsISupports *inst; + + for (e->First(); e->IsDone() != NS_OK; e->Next()) { + rv = e->CurrentItem(&inst); + if (NS_SUCCEEDED(rv)) { + rv = inst->QueryInterface(nsIObserver::GetIID(), (void**)&anObserver); + } + anObserver->Notify(nsnull); + } + + + + } + return NS_OK; +} +