Foobar2000:Development:Services: Difference between revisions
(Created page with "Category:Foobar2000 Development == Services == A service type is an interface class, deriving directly or indirectly from service_base class. A service type class must no...") |
No edit summary |
||
Line 59: | Line 59: | ||
FB2K_SERVICE_FACTORY(myinitquit); | FB2K_SERVICE_FACTORY(myinitquit); | ||
</pre> | </pre> | ||
=== Examples of entrypoint services === | |||
==== initquit, init_stage_callback ==== | |||
* Implemented by: everyone. | |||
* Called by: core, on app startup and shutdown. | |||
==== input_entry ==== | |||
* Implemented by: decoder components. | |||
* Called by: everyone decoding audio files. | |||
* This service is not implemented directly, but with help of <code>input_factory_t<></code> templates that implement all input services using your supplied class. | |||
==== playlist_loader ==== | |||
* Implemented by: core (standard playlist format), you (if you want to add your own playlist format). | |||
* Called by: any code loading or saving a playlist file. | |||
==== popup_message ==== | |||
* Implemented by: core. Do not reimplement! | |||
* Called by: everyone. |
Latest revision as of 12:47, 22 June 2022
Services
A service type is an interface class, deriving directly or indirectly from service_base class. A service type class must not have any data members; it can only provide virtual methods (to be overridden by service implementation), helper non-virtual methods built around virtual methods, static helper methods, and constants / enums. Each service interface class must have a static class_guid member, used for identification when enumerating services or querying for supported functionality. A service type declaration should declare a class with public virtual/helper/static methods, and use FB2K_MAKE_SERVICE_INTERFACE() / FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT()
macro to implement standard service behaviors for the class; additionally, class_guid needs to be defined outside class declaration (e.g. const GUID someclass::class_guid = {….};
). Note that most of components will not declare their own service types, they will only implement existing ones declared in the SDK.
A service implementation is a class derived from relevant service type class, implementing virtual methods declared by service type class. Note that service implementation class does not implement virtual methods declared by service_base; those are implemented automatically.
You cannot directly instantiate a service implementation object because it's still missing virtual methods of service_base.
class myworker : public threaded_process_callback { /* threaded_process_callback methods overridden here */ }; auto obj = new myworker; // error auto obj = fb2k::service_new<myworker>(); // good service_ptr_t<myworker> obj = new service_impl_t<myworker>; // longer equivalent of fb2k::service_new<>, commonly used in older code, not auto-friendly
fb2k::service_new<> takes care of implementing common methods (service_base) needed by all services and returns an autopointer object that manages reference counting for you.
Note that service_base methods:
service_add_ref()
service_release()
service_query()
... are only intended for autopointer classes and should never be called directly in your code.
See also: Auto Pointers
Entrypoint services
An entrypoint service type is a special case of a service type that can be registered using service_factory templates, and then accessed from any point of service system (excluding DLL startup/shutdown code, such as code inside static object constructors/destructors). An entrypoint service type class must directly derive from service_base.
Registered entrypoint services can be accessed using:
- For services types with variable number of implementations registered:
enumerate()
static methods of the service class>
for( auto ptr : someclass::enumerate() ) { /* do stuff with ptr */ }
- Or,
service_enum_t<>
, commonly used in older code:
service_enum_t<someclass> e; service_ptr_t<someclass> ptr; while(e.next(ptr)) ptr->dosomething();
- For services types with a single always-present implementation registered - such as core services like playlist_manager - using someclass::get(), e.g.:
auto api = someclass::get(); api->dosomething(); api->dosomethingelse();
Using per-service-type defined static helper functions, e.g. someclass::g_dosomething()
- those use relevant service enumeration methods internally.
An entrypoint service type must use FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT()
macro to implement standard entrypoint service behaviors, as opposed to all other service types that use FB2K_MAKE_SERVICE_INTERFACE()
macro instead.
You can register your own entrypoint service implementations using FB2K_SERVICE_FACTORY()
macro. It creates a static instance of your object and makes it available for everyone else to enumerate and access.
Some services need to be registered differently, see documentation of individual services for details.
A typical entrypoint service implementation looks like this:
class myinitquit : public initquit { public: void on_init() override {}; void on_quit() override {}; }; FB2K_SERVICE_FACTORY(myinitquit);
Examples of entrypoint services
initquit, init_stage_callback
- Implemented by: everyone.
- Called by: core, on app startup and shutdown.
input_entry
- Implemented by: decoder components.
- Called by: everyone decoding audio files.
- This service is not implemented directly, but with help of
input_factory_t<>
templates that implement all input services using your supplied class.
playlist_loader
- Implemented by: core (standard playlist format), you (if you want to add your own playlist format).
- Called by: any code loading or saving a playlist file.
popup_message
- Implemented by: core. Do not reimplement!
- Called by: everyone.