1 #ifndef _foobar2000_sdk_service_h_included_
2 #define _foobar2000_sdk_service_h_included_
11 #define FOOGUIDDECL __declspec(selectany)
17 #define DECLARE_GUID(NAME,A,S,D,F,G,H,J,K,L,Z,X) FOOGUIDDECL const GUID NAME = {A,S,D,{F,G,H,J,K,L,Z,X}};
18 #define DECLARE_CLASS_GUID(NAME,A,S,D,F,G,H,J,K,L,Z,X) FOOGUIDDECL const GUID NAME::class_guid = {A,S,D,{F,G,H,J,K,L,Z,X}};
32 if (p_ptr != NULL) PFC_ASSERT_NO_EXCEPTION( p_ptr->service_release() );
37 if (p_ptr != NULL) PFC_ASSERT_NO_EXCEPTION( p_ptr->service_add_ref() );
59 template<
typename t_source>
void _init(t_source * in)
throw() {
61 if (this->
m_ptr) this->
m_ptr->service_add_ref();
63 template<
typename t_source>
void _init(t_source && in) throw() {
64 this->
m_ptr = in.detach();
78 template<
typename t_source>
79 void copy(t_source * p_ptr)
throw() {
85 template<
typename t_source>
88 template<
typename t_source>
92 inline const t_self &
operator=(
const t_self & p_source)
throw() {
copy(p_source);
return *
this;}
93 inline const t_self &
operator=(t_self && p_source) throw() {
copy(std::move(p_source));
return *
this;}
94 inline const t_self &
operator=(
T * p_ptr)
throw() {
copy(p_ptr);
return *
this;}
98 template<
typename t_source>
inline t_self &
operator=(t_source * p_ptr)
throw() {
copy(p_ptr);
return *
this;}
102 t_source * ptr = p_ptr.get_ptr();
103 ptr->service_add_ref();
126 inline bool operator<(const service_ptr_base_t<T> & p_item)
const throw() {
return this->
m_ptr < p_item.get_ptr();}
134 template<
typename t_other>
135 inline t_self & operator<<(service_ptr_t<t_other> & p_source)
throw() {
attach(p_source.detach());
return *
this;}
136 template<
typename t_other>
149 template<
typename t_source>
150 inline void attach(t_source * p_ptr)
throw() {
166 template<
typename otherPtr_t>
168 PFC_ASSERT( other.is_valid() );
173 template<
typename otherPtr_t>
175 PFC_ASSERT( other.is_valid() );
176 return other->cast(*
this);
189 template<
typename t_source>
void _init(t_source * in) {
191 this->
m_ptr->service_add_ref();
204 template<
typename t_source>
205 void copy(t_source * p_ptr)
throw() {
206 p_ptr->service_add_ref();
207 this->
m_ptr->service_release();
211 template<
typename t_source>
215 inline const t_self &
operator=(
const t_self & p_source)
throw() {
copy(p_source);
return *
this;}
219 template<
typename t_source>
inline t_self &
operator=(t_source * p_ptr)
throw() {
copy(p_ptr);
return *
this;}
227 inline bool is_valid()
const throw() {
return true;}
228 inline bool is_empty()
const throw() {
return false;}
234 inline bool operator<(const service_ptr_base_t<T> & p_item)
const throw() {
return this->
m_ptr < p_item.get_ptr();}
269 template<
typename T,
template<
typename>
class t_alloc =
pfc::alloc_fast>
279 #define FB2K_MAKE_SERVICE_INTERFACE(THISCLASS,PARENTCLASS) \
281 typedef THISCLASS t_interface; \
282 typedef PARENTCLASS t_interface_parent; \
284 static const GUID class_guid; \
286 virtual bool service_query(service_ptr_t<service_base> & p_out,const GUID & p_guid) { \
287 if (p_guid == class_guid) {p_out = this; return true;} \
288 else return PARENTCLASS::service_query(p_out,p_guid); \
290 typedef service_ptr_t<t_interface> ptr; \
291 typedef service_nnptr_t<t_interface> nnptr; \
293 typedef nnptr nnref; \
298 const THISCLASS & operator=(const THISCLASS &) {throw pfc::exception_not_implemented();} \
299 THISCLASS(const THISCLASS &) {throw pfc::exception_not_implemented();} \
301 void __private__service_declaration_selftest() { \
302 pfc::assert_same_type<PARENTCLASS,PARENTCLASS::t_interface>(); \
303 __validate_service_class_helper<THISCLASS>(); \
304 pfc::implicit_cast<service_base*>(this); \
311 #define FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(THISCLASS) \
313 typedef THISCLASS t_interface_entrypoint; \
314 FB2K_MAKE_SERVICE_INTERFACE(THISCLASS,service_base)
317 #define FB2K_DECLARE_SERVICE_BEGIN(THISCLASS,BASECLASS) \
318 class NOVTABLE THISCLASS : public BASECLASS { \
319 FB2K_MAKE_SERVICE_INTERFACE(THISCLASS,BASECLASS); \
322 #define FB2K_DECLARE_SERVICE_END() \
325 #define FB2K_DECLARE_SERVICE_ENTRYPOINT_BEGIN(THISCLASS) \
326 class NOVTABLE THISCLASS : public service_base { \
327 FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(THISCLASS) \
338 virtual int service_release()
throw() = 0;
341 virtual int service_add_ref()
throw() = 0;
356 template<
typename outPtr_t>
357 bool cast( outPtr_t & outPtr ) {
return service_query_t( outPtr ); }
374 __validate_service_class_helper<typename T::t_interface_parent>();
424 PFC_ASSERT( ptr->service_query_t(test) );
428 #define FB2K_ASSERT_VALID_SERVICE_PTR(ptr) _validate_service_ptr(ptr)
430 #define FB2K_ASSERT_VALID_SERVICE_PTR(ptr)
437 p_out =
static_cast<T*
>(ptr.get_ptr());
450 template<
typename what>
461 FB2K_ASSERT_VALID_SERVICE_PTR( out );
495 FB2K_ASSERT_VALID_SERVICE_PTR(p_out);
499 if (!temp->service_query_t(p_out))
throw exception_service_extension_not_found();
516 typedef typename T::t_interface_entrypoint EP;
518 if (helper.
get_count() != 1)
return false;
521 if (!helper.
create(0)->service_query_t(t))
return false;
526 #define FB2K_API_AVAILABLE(API) static_api_test_t<API>()
532 template<
typename t_
interface>
547 const t_self &
operator=(
const t_self & in) {
return *
this;}
572 template<
typename t_
interface>
580 template<
typename t_query>
586 template<
typename t_query>
594 if (temp->service_query_t(p_out))
return true;
676 template<
typename what>
681 if (ptr->get_guid() == id) {out = ptr;
return true;}
686 template<
typename what>
699 for(
t_size walk = 0; walk < servCount; ++walk) {
715 service_ptr_t<what> temp;
if (!crete(temp,theID))
throw exception_service_not_found();
return temp;
724 template<
typename what>
732 template<
typename what>
737 template<
typename what>
747 FB2K_DebugLog() <<
"Warning: service_by_guid() used in non-main thread without initialization, using fallback";
751 return data.create(out,theID);
753 template<
typename what>
760 #define FB2K_FOR_EACH_SERVICE(type, call) {service_enum_t<typename type::t_interface_entrypoint> e; service_ptr_t<type> ptr; while(e.next(ptr)) {ptr->call;} }
766 template<
typename what>
static int compare(
const what & v1,
const what & v2) {
return pfc::compare_t(v1->get_guid(), v2->get_guid()); }
770 #endif //_foobar2000_sdk_service_h_included_
bool operator>(const service_ptr_base_t< T > &p_item) const
t_self & operator=(const service_ptr_base_t< t_source > &p_source)
bool operator!=(const service_ptr_base_t< T > &p_item) const
service_ptr_t(const service_nnptr_t< t_source > &p_source)
service_factory_base(const GUID &p_guid, service_factory_base *&factoryList)
bool create(service_ptr_t< what > &out, const GUID &theID) const
t_interface * get_ptr() const
Template implementing reference-counting features of service_base. Intended for dynamic instantiation...
static bool service_by_guid(service_ptr_t< what > &out, const GUID &theID)
const t_self & operator=(const t_self &in)
const t_self & operator=(T *p_ptr)
service_ptr_t(const service_ptr_base_t< t_source > &p_source)
static bool service_enum_create_t(service_ptr_t< T > &p_out, t_size p_index)
void copy(const service_ptr_base_t< t_source > &p_source)
service_ptr_t< T > create(t_size p_index) const
static_api_ptr_t(const t_self &in)
const T & get_static_instance() const
bool operator==(T *p_item) const
service_nnptr_t(const service_ptr_base_t< t_source > &p_source)
const t_self & operator=(T *p_ptr)
t_type replace_null_t(t_type &p_var)
virtual bool service_query(service_ptr_t< service_base > &p_out, const GUID &p_guid)
Queries whether the object supports specific interface and retrieves a pointer to that interface...
service_class_helper_t< t_interface > m_helper
TEMPLATE_CONSTRUCTOR_FORWARD_FLOOD(service_factory_single_transparent_t, service_impl_single_t< T >) void instance_create(service_ptr_t< service_base > &p_out)
void __validate_service_class_helper< service_base >()
bool first(service_ptr_t< t_query > &p_out)
service_impl_single_t< T > g_instance
service_ptr_t(const t_self &p_source)
service_factory_single_ref_t(T ¶m)
void copy(t_source *p_ptr)
bool operator>(T *p_item) const
Special hack to ensure errors when someone tries to ->service_add_ref()/->service_release() on a serv...
TEMPLATE_CONSTRUCTOR_FORWARD_FLOOD(service_factory_single_t, g_instance) void instance_create(service_ptr_t< service_base > &p_out)
service_obscure_refcounting< t_interface > * operator->() const
void standard_api_create_t(service_ptr_t< T > &p_out)
t_ret * safe_ptr_cast(t_param *p_param)
static_api_ptr_t< t_interface > t_self
static service_obscure_refcounting< T > * service_obscure_refcounting_cast(T *p_source)
Converts a service interface pointer to a pointer that obscures service counter functionality.
bool __next(service_ptr_t< t_interface > &p_out)
t_self & operator=(const service_ptr_base_t< t_source > &p_source)
service_class_ref m_servClass
Helper; simulates array with instance of each available implementation of given service class...
Template implementing dummy version of reference-counting features of service_base. Intended for static/local/member instantiation: "static service_impl_single_t myvar(params);". Because reference counting features are disabled (dummy reference counter), code instantiating it is responsible for deleting it as well as ensuring that no references are active when the object gets deleted. Note that some constructor parameters such as NULL will need explicit typecasts to ensure correctly guessed types for constructor function template (null string needs to be (const char*)NULL rather than just NULL, etc).
pfc::map_t< GUID, t_size > m_order
const t_self & operator=(t_self &&p_source)
void operator^=(otherPtr_t other)
Forced cast operator - obtains a valid service pointer to the expected class or crashes the app if su...
service_ptr_t< T > t_self
t_self & operator>>(service_ptr_t< t_other > &p_dest)
bool operator>(const service_ptr_base_t< T > &p_item) const
static service_factory_base * __internal__list
FOR INTERNAL USE ONLY.
service_nnptr_t(const t_self &p_source)
service_ptr_t< what > create(const GUID &theID) const
service_nnptr_t(service_ptr_t< t_source > &&p_source)
service_nnptr_t(t_source *p_ptr)
const void * service_class_ref
t_self & operator=(service_ptr_t< t_source > &&p_source)
bool operator==(const service_ptr_base_t< T > &p_item) const
const t_self & operator=(const t_self &p_source)
static bool _as_base_ptr_check()
T & get_static_instance()
T * _duplicate_ptr() const
PFC_DECLARE_EXCEPTION(exception_service_not_found, pfc::exception,"Service not found")
t_self & operator=(service_ptr_t< t_source > &&p_source)
T & get_static_instance()
bool operator==(const service_ptr_base_t< T > &p_item) const
const t_self & operator=(const t_self &p_source)
static t_size enum_get_count(service_class_ref p_class)
bool test(const char *str, const char *pattern, bool b_separate_by_semicolon=false)
bool create(service_ptr_t< T > &p_out, t_size p_index) const
service_ptr_t(t_self &&p_source)
service_class_ref m_class
Autopointer class to be used with all services. Manages reference counter calls behind-the-scenes. This assumes that the pointers are valid all the time (can't point to null). Mainly intended to be used for scenarios where null pointers are not valid and relevant code should crash ASAP if somebody passes invalid pointers around. You want to use service_ptr_t<> rather than service_nnptr_t<> most of the time.
service_nnptr_t< service_base > service_nnptr
const GUID & get_class_guid() const
service_ptr_t(t_source *p_ptr)
void copy(service_ptr_t< t_source > &&p_source)
static service_class_ref _service_find_class()
static void service_add_ref_safe(T *p_ptr)
t_self & operator=(const service_nnptr_t< t_source > &p_ptr)
Base class for all service classes. Provides interfaces for reference counter and querying for differ...
int compare_t(const hasher_md5_result &p_item1, const hasher_md5_result &p_item2)
static void service_by_guid_init()
service_nnptr_t(T *p_ptr)
void instance_create(service_ptr_t< service_base > &p_out)
Throws std::bad_alloc or another exception on failure.
pfc::array_t< t_ptr > m_data
t_self & operator=(t_source *p_ptr)
void _standard_api_create_internal(service_ptr &out, const GUID &classID)
void _init(t_source &&in)
service_ptr_t< service_base > & _as_base_ptr()
const t_ptr & operator[](t_size p_index) const
static void service_release_safe(T *p_ptr)
static service_class_ref enum_find_class(const GUID &p_guid)
static service_factory_base *& factory_list()
service_ptr_t< service_base > service_ptr
void set(const _t_key &p_key, const _t_value &p_value)
bool operator==(T *p_item) const
T * _duplicate_ptr() const
T & get_static_instance()
service_obscure_refcounting< T > * operator->() const
static void _validate_service_ptr(service_ptr_t< T > const &ptr)
bool service_query_t(service_ptr_t< T > &p_out)
Queries whether the object supports specific interface and retrieves a pointer to that interface...
service_nnptr_t< T > t_self
void instance_create(service_ptr_t< service_base > &p_out)
Throws std::bad_alloc or another exception on failure.
t_ret implicit_cast(t_ret val)
void attach(t_source *p_ptr)
static bool enum_create(service_ptr_t< service_base > &p_out, service_class_ref p_class, t_size p_index)
bool operator!=(const service_ptr_base_t< T > &p_item) const
void __validate_service_class_helper()
Autopointer class to be used with all services. Manages reference counter calls behind-the-scenes.
service_factory_base * __internal__next
FOR INTERNAL USE ONLY.
t_self & operator=(t_source *p_ptr)
static int compare(const what &v1, const what &v2)
bool operator<(T *p_item) const
bool operator!=(T *p_item) const
bool is_main_thread()
Returns true if calling thread is main app thread, false otherwise.
bool operator&=(otherPtr_t other)
Conditional cast operator - attempts to obtain a vaild service pointer to the expected class; returns...
bool cast(outPtr_t &outPtr)
New shortened version, same as service_query_t.
service_obscure_refcounting< T > * operator->() const
const service_base & operator=(const service_base &)
Helper template used to easily access core services. Usage: static_api_ptr_t api; api->doso...
static bool is_service_present(const GUID &g)
PFC_NORETURN void SHARED_EXPORT uBugCheck()
static bool service_by_guid_fallback(service_ptr_t< what > &out, const GUID &id)
virtual void instance_create(service_ptr_t< service_base > &p_out)=0
Throws std::bad_alloc or another exception on failure.
service_ptr_t< service_base > & _as_base_ptr()
bool operator>(T *p_item) const
service_ptr_t(service_ptr_t< t_source > &&p_source)
bool next(service_ptr_t< t_query > &p_out)
void copy(const service_ptr_base_t< t_source > &p_source)
static bool _service_instantiate_helper(service_ptr_t< what > &out, service_class_ref servClass, t_size index)
bool are_services_available()
Tests whether services are available at this time. They are not available only during DLL startup or ...
service_base(const service_base &)
static service_by_guid_data< what > data
bool operator!=(T *p_item) const
bool operator<(T *p_item) const
t_ptr & operator[](t_size p_index)
static bool _as_base_ptr_check()
void copy(t_source *p_ptr)
service_class_ref get_class() const
service_instance_array_t()
bool query(const _t_key &p_key, _t_value &p_value) const