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() );
45 inline T*
get_ptr()
const throw() {
return m_ptr;}
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();
69 service_ptr_t(
const t_self & p_source)
throw() {_init(p_source.get_ptr());}
71 template<
typename t_source>
service_ptr_t(t_source * p_ptr)
throw() {_init(p_ptr);}
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();
117 inline T*
get_ptr()
const throw() {
return this->m_ptr;}
119 inline bool is_valid()
const throw() {
return this->m_ptr != NULL;}
120 inline bool is_empty()
const throw() {
return this->m_ptr == NULL;}
126 inline bool operator<(const service_ptr_base_t<T> & p_item)
const throw() {
return this->m_ptr < p_item.get_ptr();}
128 inline bool operator==(
T * p_item)
const throw() {
return this->m_ptr == p_item;}
129 inline bool operator!=(
T * p_item)
const throw() {
return this->m_ptr != p_item;}
131 inline bool operator>(
T * p_item)
const throw() {
return this->m_ptr > p_item;}
132 inline bool operator<(
T * p_item)
const throw() {
return this->m_ptr < p_item;}
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() {
158 PFC_ASSERT( _as_base_ptr_check() );
166 template<
typename otherPtr_t>
167 void operator ^= ( otherPtr_t other ) {
168 PFC_ASSERT( other.is_valid() );
173 template<
typename otherPtr_t>
174 bool operator &= ( otherPtr_t other ) {
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;}
225 inline T*
get_ptr()
const throw() {
return this->m_ptr;}
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();}
236 inline bool operator==(
T * p_item)
const throw() {
return this->m_ptr == p_item;}
237 inline bool operator!=(
T * p_item)
const throw() {
return this->m_ptr != p_item;}
239 inline bool operator>(
T * p_item)
const throw() {
return this->m_ptr > p_item;}
240 inline bool operator<(
T * p_item)
const throw() {
return this->m_ptr < p_item;}
250 PFC_ASSERT( _as_base_ptr_check() );
261 enum { realloc_safe =
true, constructor_may_fail =
false};
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) \ 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;}
559 m_data.set_size(count);
560 for(
t_size n=0;n<count;n++) m_data[n] = helper.
create(n);
572 template<
typename t_
interface>
580 template<
typename t_query>
586 template<
typename t_query>
593 while(__next(temp)) {
594 if (temp->service_query_t(p_out))
return true;
602 return m_helper.create(p_out,m_index++);
676 template<
typename what>
681 if (ptr->get_guid() == id) {out = ptr;
return true;}
686 template<
typename what>
691 bool ready()
const {
return m_inited;}
695 if (m_inited)
return;
699 for(
t_size walk = 0; walk < servCount; ++walk) {
702 m_order.set(temp->get_guid(), walk);
709 PFC_ASSERT(m_inited);
711 if (!m_order.query(theID,index))
return false;
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<someclass> 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)
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 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 create(pfc::string_formatter &p_out, const t_entry_list &p_data)
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...
virtual int service_add_ref()=0
Increments reference count. This is normally not called directly but managed by service_ptr_t<> templ...
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 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<myclass> 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)
This is free and unencumbered software released into the public domain Anyone is free to copy
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()