<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.hydrogenaudio.org/index.php?action=history&amp;feed=atom&amp;title=Foobar2000%3ADevelopment%3AServices</id>
	<title>Foobar2000:Development:Services - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.hydrogenaudio.org/index.php?action=history&amp;feed=atom&amp;title=Foobar2000%3ADevelopment%3AServices"/>
	<link rel="alternate" type="text/html" href="https://wiki.hydrogenaudio.org/index.php?title=Foobar2000:Development:Services&amp;action=history"/>
	<updated>2026-05-04T21:48:28Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.44.2</generator>
	<entry>
		<id>https://wiki.hydrogenaudio.org/index.php?title=Foobar2000:Development:Services&amp;diff=35771&amp;oldid=prev</id>
		<title>DEATH at 12:47, 22 June 2022</title>
		<link rel="alternate" type="text/html" href="https://wiki.hydrogenaudio.org/index.php?title=Foobar2000:Development:Services&amp;diff=35771&amp;oldid=prev"/>
		<updated>2022-06-22T12:47:32Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 12:47, 22 June 2022&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l59&quot;&gt;Line 59:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 59:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;FB2K_SERVICE_FACTORY(myinitquit);&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;FB2K_SERVICE_FACTORY(myinitquit);&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;/pre&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;/pre&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;=== Examples of entrypoint services ===&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;==== initquit, init_stage_callback ====&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;* Implemented by: everyone.&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;* Called by: core, on app startup and shutdown.&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;==== input_entry ====&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;* Implemented by: decoder components.&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;* Called by: everyone decoding audio files.&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;* This service is not implemented directly, but with help of &amp;lt;code&amp;gt;input_factory_t&amp;lt;&amp;gt;&amp;lt;/code&amp;gt; templates that implement all input services using your supplied class.&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;==== playlist_loader ====&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;* Implemented by: core (standard playlist format), you (if you want to add your own playlist format).&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;* Called by: any code loading or saving a playlist file.&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;==== popup_message ====&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;* Implemented by: core. Do not reimplement!&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;* Called by: everyone.&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>DEATH</name></author>
	</entry>
	<entry>
		<id>https://wiki.hydrogenaudio.org/index.php?title=Foobar2000:Development:Services&amp;diff=35767&amp;oldid=prev</id>
		<title>DEATH: Created page with &quot;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...&quot;</title>
		<link rel="alternate" type="text/html" href="https://wiki.hydrogenaudio.org/index.php?title=Foobar2000:Development:Services&amp;diff=35767&amp;oldid=prev"/>
		<updated>2022-06-22T12:19:35Z</updated>

		<summary type="html">&lt;p&gt;Created page with &amp;quot;&lt;a href=&quot;/index.php?title=Category:Foobar2000_Development&quot; title=&quot;Category:Foobar2000 Development&quot;&gt;Category:Foobar2000 Development&lt;/a&gt;  == Services == A service type is an interface class, deriving directly or indirectly from service_base class. A service type class must no...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;[[Category:Foobar2000 Development]]&lt;br /&gt;
&lt;br /&gt;
== Services ==&lt;br /&gt;
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 &amp;lt;code&amp;gt;FB2K_MAKE_SERVICE_INTERFACE() / FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT()&amp;lt;/code&amp;gt; macro to implement standard service behaviors for the class; additionally, class_guid needs to be defined outside class declaration (e.g. &amp;lt;code&amp;gt;const GUID someclass::class_guid = {….};&amp;lt;/code&amp;gt; ). Note that most of components will not declare their own service types, they will only implement existing ones declared in the SDK.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
You cannot directly instantiate a service implementation object because it&amp;#039;s still missing virtual methods of service_base.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class myworker : public threaded_process_callback { /* threaded_process_callback methods overridden here */ };&lt;br /&gt;
auto obj = new myworker; // error&lt;br /&gt;
auto obj = fb2k::service_new&amp;lt;myworker&amp;gt;(); // good&lt;br /&gt;
service_ptr_t&amp;lt;myworker&amp;gt; obj = new service_impl_t&amp;lt;myworker&amp;gt;; // longer equivalent of fb2k::service_new&amp;lt;&amp;gt;, commonly used in older code, not auto-friendly&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
fb2k::service_new&amp;lt;&amp;gt; takes care of implementing common methods (service_base) needed by all services and returns an autopointer object that manages reference counting for you.&lt;br /&gt;
&lt;br /&gt;
Note that service_base methods:&lt;br /&gt;
* &amp;lt;code&amp;gt;service_add_ref()&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;service_release()&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;service_query()&amp;lt;/code&amp;gt;&lt;br /&gt;
... are only intended for autopointer classes and should never be called directly in your code.&lt;br /&gt;
&lt;br /&gt;
See also: [[Foobar2000:Development:Auto Pointers|Auto Pointers]]&lt;br /&gt;
&lt;br /&gt;
== Entrypoint services ==&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
Registered entrypoint services can be accessed using:&lt;br /&gt;
&lt;br /&gt;
* For services types with variable number of implementations registered: &lt;br /&gt;
* &amp;lt;code&amp;gt;enumerate()&amp;lt;/code&amp;gt; static methods of the service class&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
for( auto ptr : someclass::enumerate() ) { /* do stuff with ptr */ }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* Or, &amp;lt;code&amp;gt;service_enum_t&amp;lt;&amp;gt;&amp;lt;/code&amp;gt;, commonly used in older code:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
service_enum_t&amp;lt;someclass&amp;gt; e; service_ptr_t&amp;lt;someclass&amp;gt; ptr; while(e.next(ptr)) ptr-&amp;gt;dosomething();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* For services types with a single always-present implementation registered - such as core services like playlist_manager - using someclass::get(), e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
auto api = someclass::get(); api-&amp;gt;dosomething(); api-&amp;gt;dosomethingelse();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Using per-service-type defined static helper functions, e.g. &amp;lt;code&amp;gt;someclass::g_dosomething()&amp;lt;/code&amp;gt; - those use relevant service enumeration methods internally.&lt;br /&gt;
An entrypoint service type must use &amp;lt;code&amp;gt;FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT()&amp;lt;/code&amp;gt; macro to implement standard entrypoint service behaviors, as opposed to all other service types that use &amp;lt;code&amp;gt;FB2K_MAKE_SERVICE_INTERFACE()&amp;lt;/code&amp;gt; macro instead.&lt;br /&gt;
&lt;br /&gt;
You can register your own entrypoint service implementations using &amp;lt;code&amp;gt;FB2K_SERVICE_FACTORY()&amp;lt;/code&amp;gt; macro. It creates a static instance of your object and makes it available for everyone else to enumerate and access.&lt;br /&gt;
Some services need to be registered differently, see documentation of individual services for details.&lt;br /&gt;
&lt;br /&gt;
A typical entrypoint service implementation looks like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class myinitquit : public initquit {&lt;br /&gt;
public:&lt;br /&gt;
	void on_init() override {};&lt;br /&gt;
	void on_quit() override {};&lt;br /&gt;
};&lt;br /&gt;
FB2K_SERVICE_FACTORY(myinitquit);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>DEATH</name></author>
	</entry>
</feed>