{"id":175,"date":"2015-02-20T11:50:57","date_gmt":"2015-02-20T11:50:57","guid":{"rendered":"http:\/\/anthroponaute.fr\/blog-informatique\/?p=175"},"modified":"2016-08-29T16:33:21","modified_gmt":"2016-08-29T16:33:21","slug":"un-systeme-de-process-et-de-processmanager","status":"publish","type":"post","link":"https:\/\/www.la-porte-des-nebuleuses.net\/blog-informatique\/?p=175","title":{"rendered":"Un syst\u00e8me de Process et de ProcessManager"},"content":{"rendered":"<p><strong>\u00a0<\/strong><\/p>\n<p><a href=\"https:\/\/anthropoya.cluster014.ovh.net\/blog-informatique\/wp-content\/uploads\/2015\/02\/WoWScrnShot_082916_183045.jpg\"><img decoding=\"async\" loading=\"lazy\" class=\"alignnone  wp-image-5597\" src=\"https:\/\/anthropoya.cluster014.ovh.net\/blog-informatique\/wp-content\/uploads\/2015\/02\/WoWScrnShot_082916_183045.jpg\" alt=\"WoWScrnShot_082916_183045\" width=\"542\" height=\"305\" srcset=\"https:\/\/www.la-porte-des-nebuleuses.net\/blog-informatique\/wp-content\/uploads\/2015\/02\/WoWScrnShot_082916_183045.jpg 1600w, https:\/\/www.la-porte-des-nebuleuses.net\/blog-informatique\/wp-content\/uploads\/2015\/02\/WoWScrnShot_082916_183045-300x169.jpg 300w, https:\/\/www.la-porte-des-nebuleuses.net\/blog-informatique\/wp-content\/uploads\/2015\/02\/WoWScrnShot_082916_183045-1024x576.jpg 1024w, https:\/\/www.la-porte-des-nebuleuses.net\/blog-informatique\/wp-content\/uploads\/2015\/02\/WoWScrnShot_082916_183045-624x351.jpg 624w\" sizes=\"(max-width: 542px) 100vw, 542px\" \/><\/a><\/p>\n<p><strong>Intro :<\/strong><\/p>\n<p>Dans un jeu vid\u00e9o on fait souvent appel \u00e0 plusieurs sous-syst\u00e8mes et pour les mettre \u00e0 jour fr\u00e9quemment.<\/p>\n<p>On va utiliser deux classes permettant de g\u00e9rer ces sous syst\u00e8mes.<\/p>\n<p><strong>class Process<\/strong> : classe de base, on peut la d\u00e9river puis red\u00e9finir la m\u00e9thode VUpdate().<br \/>\n<strong>class ProcessManager<\/strong> : gestionnaire d&rsquo;instances de Process.<\/p>\n<p>Un Process peut \u00eatre n&rsquo;importe quoi : il faut juste tout simplement que ce soit un objet qui n\u00e9cessite d&rsquo;\u00eatre mise \u00e0 jour.<\/p>\n<p>Par exemple on peut l&rsquo;utiliser pour : le syst\u00e8me de script, des collisions, de l&rsquo;audio, de l&rsquo;IA, du rendu de certaines entit\u00e9s.<\/p>\n<p>Si on veut mettre le jeu en pause il\u00a0 suffira de faire appel aux m\u00e9thodes Pause() et UnPause().<\/p>\n<p>Pour le fichier include Process.h<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\n\r\nclass Process\r\n{\r\n\u00a0\u00a0 \u00a0friend class ProcessManager;\r\n\r\npublic:\r\n\u00a0\u00a0 \u00a0enum State\r\n\u00a0\u00a0 \u00a0{\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0UNINITIALIZED = 0,\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0REMOVED,\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0RUNNING,\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0PAUSED,\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0SUCCEEDED,\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0FAILED,\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0ABORTED,\r\n\u00a0\u00a0 \u00a0};\r\n\u00a0\u00a0 \u00a0\r\nprivate:\r\n\u00a0\u00a0 \u00a0State m_state; \r\n\r\npublic:\r\n\r\n\u00a0\u00a0\u00a0 Process(void);\r\n\u00a0\u00a0 \u00a0virtual ~Process(void);\r\n\u00a0\u00a0 \u00a0\r\nprotected:\r\n\u00a0\u00a0 \u00a0virtual void VOnInit(void) { m_state = RUNNING; }\r\n\u00a0\u00a0 \u00a0virtual void VOnUpdate(unsigned long deltaMs) = 0;\r\n\u00a0\u00a0 \u00a0virtual void VOnSuccess(void) { }\r\n\u00a0\u00a0 \u00a0virtual void VOnFail(void) { }\r\n\u00a0\u00a0 \u00a0virtual void VOnAbort(void) { }\r\n\r\npublic:\r\n\u00a0\u00a0 \u00a0inline void Succeed(void);\r\n\u00a0\u00a0 \u00a0inline void Fail(void);\r\n\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0 \u00a0inline void Pause(void);\r\n\u00a0\u00a0 \u00a0inline void UnPause(void);\r\n\u00a0\u00a0 \u00a0State GetState(void) const { return m_state; }\r\n\u00a0\u00a0 \u00a0bool IsAlive(void) const { return (m_state == RUNNING\r\n                               || m_state == PAUSED); }\r\n\u00a0\u00a0 \u00a0bool IsDead(void) const { return (m_state == SUCCEEDED\r\n                              || m_state == FAILED\r\n                              || m_state == ABORTED); }\r\n\u00a0\u00a0 \u00a0bool IsRemoved(void) const { return (m_state == REMOVED); }\r\n\u00a0\u00a0 \u00a0bool IsPaused(void) const { return m_state == PAUSED; }\r\n\r\n\u00a0\u00a0 \u00a0inline void AttachChild(Process* pChild);\r\n\u00a0\u00a0  Process* RemoveChild(void);\r\n\u00a0\u00a0 \u00a0Process* PeekChild(void) { return m_pChild; }\r\n\r\nprivate:\r\n\u00a0\u00a0 \u00a0void SetState(State newState) { m_state = newState; }\r\n};\r\n<\/pre>\n<p>Dans le fichier Process.cpp :<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\n\r\nProcess::Process(void)\r\n{\r\n\u00a0\u00a0 \u00a0m_state = UNINITIALIZED;\r\n}\r\n\r\nProcess::~Process(void)\r\n{\r\n\u00a0\u00a0 \u00a0if (m_pChild)\r\n\u00a0\u00a0 \u00a0{\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0m_pChild-&gt;VOnAbort();\r\n\u00a0\u00a0 \u00a0}\r\n}\r\n\r\ninline void Process::Succeed(void)\r\n{\r\n\u00a0\u00a0  assert(m_state == RUNNING || m_state == PAUSED);\r\n\u00a0\u00a0 \u00a0m_state = SUCCEEDED;\r\n}\r\n\r\ninline void Process::Fail(void)\r\n{\r\n\u00a0\u00a0 \u00a0assert(m_state == RUNNING || m_state == PAUSED);\r\n\u00a0\u00a0 \u00a0m_state = FAILED;\r\n}\r\n\r\ninline void Process::AttachChild(StrongProcessPtr pChild)\r\n{\r\n\u00a0\u00a0 \u00a0if (m_pChild)\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0m_pChild-&gt;AttachChild(pChild);\r\n\u00a0\u00a0 \u00a0else\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0m_pChild = pChild;\r\n}\r\n\r\ninline void Process::Pause(void)\r\n{\r\n\u00a0\u00a0 \u00a0if (m_state == RUNNING)\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0m_state = PAUSED;\r\n\u00a0\u00a0 \u00a0else\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0std::cout &lt;&lt;\r\n        &quot;Attempting to pause a process that isn't running&quot;\r\n        &lt;&lt; std::endl;\r\n}\r\n\r\ninline void Process::UnPause(void)\r\n{\r\n\u00a0\u00a0 \u00a0if (m_state == PAUSED)\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0m_state = RUNNING;\r\n\u00a0\u00a0 \u00a0else\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0std::cout &lt;&lt;\r\n        &quot;Attempting to unpause a process that isn't paused&quot;\r\n        &lt;&lt; std::endl;\r\n}\r\n\r\nProcess* Process::RemoveChild(void)\r\n{\r\n\u00a0\u00a0 \u00a0if (m_pChild)\r\n\u00a0\u00a0 \u00a0{\r\n\u00a0       m_pChild = NULL;\r\n\u00a0\u00a0 \u00a0}\r\n\r\n\u00a0\u00a0 \u00a0return NULL;\r\n}\r\n<\/pre>\n<p>Maintenant pour le fichier include ProcessManager.h :<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\n\r\n#include &quot;Process.h&quot;\r\n\r\nclass ProcessManager\r\n{\r\n\u00a0\u00a0 \u00a0typedef std::list&lt;Process*&gt; ProcessList;\r\n\r\n\u00a0\u00a0 \u00a0ProcessList m_processList;\r\n\r\npublic:\r\n\r\n\u00a0\u00a0 \u00a0~ProcessManager(void);\r\n\r\n\u00a0\u00a0 \u00a0unsigned int UpdateProcesses(unsigned long deltaMs);\r\n\u00a0\u00a0 \u00a0Process* AttachProcess(Process* pProcess);\r\n\u00a0\u00a0 \u00a0void AbortAllProcesses(bool immediate);\r\n\r\n\u00a0\u00a0 \u00a0unsigned int GetProcessCount(void) const {\r\n                 return m_processList.size(); }\r\n\r\nprivate:\r\n\u00a0\u00a0 \u00a0void ClearAllProcesses(void);\r\n};\r\n\r\n<\/pre>\n<p>Pour le fichier ProcessManager.cpp :<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\n\r\nProcessManager::~ProcessManager(void)\r\n{\r\n\u00a0\u00a0\u00a0 ClearAllProcesses();\r\n}\r\n\r\nunsigned int ProcessManager::UpdateProcesses(unsigned long deltaMs)\r\n{\r\n\u00a0\u00a0\u00a0 unsigned short int successCount = 0;\r\n\u00a0\u00a0\u00a0 unsigned short int failCount = 0;\r\n\r\n\u00a0\u00a0\u00a0 ProcessList::iterator it = m_processList.begin();\r\n\u00a0\u00a0\u00a0 while (it != m_processList.end())\r\n\u00a0\u00a0\u00a0 {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Process* pCurrProcess = (*it);\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ProcessList::iterator thisIt = it;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ++it;\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 if (pCurrProcess-&gt;GetState() == Process::UNINITIALIZED)\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 pCurrProcess-&gt;VOnInit();\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 if (pCurrProcess-&gt;GetState() == Process::RUNNING)\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 pCurrProcess-&gt;VOnUpdate(deltaMs);\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 if (pCurrProcess-&gt;IsDead())\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 switch (pCurrProcess-&gt;GetState())\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 case Process::SUCCEEDED :\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 pCurrProcess-&gt;VOnSuccess();\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Process* pChild = pCurrProcess-&gt;RemoveChild();\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 if (pChild)\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 AttachProcess(pChild);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 else\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ++successCount;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 break;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 case Process::FAILED :\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 pCurrProcess-&gt;VOnFail();\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ++failCount;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 break;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 case Process::ABORTED :\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 pCurrProcess-&gt;VOnAbort();\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ++failCount;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 break;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 m_processList.erase(thisIt);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }\r\n\u00a0\u00a0\u00a0 }\r\n\r\n\u00a0\u00a0\u00a0 return ((successCount &lt;&lt; 16) | failCount);\r\n}\r\n\r\nProcess* ProcessManager::AttachProcess(Process* pProcess)\r\n{\r\n\u00a0\u00a0 \u00a0m_processList.push_front(pProcess);\r\n\u00a0\u00a0\u00a0 return pProcess;\r\n}\r\n\r\nvoid ProcessManager::ClearAllProcesses(void)\r\n{\r\n\u00a0\u00a0\u00a0 m_processList.clear();\r\n}\r\n\r\nvoid ProcessManager::AbortAllProcesses(bool immediate)\r\n{\r\n\u00a0\u00a0\u00a0 ProcessList::iterator it = m_processList.begin();\r\n\u00a0\u00a0\u00a0 while (it != m_processList.end())\r\n\u00a0\u00a0\u00a0 {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ProcessList::iterator tempIt = it;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ++it;\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 StrongProcessPtr pProcess = *tempIt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 if (pProcess-&gt;IsAlive())\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 pProcess-&gt;SetState(Process::ABORTED);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 if (immediate)\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 pProcess-&gt;VOnAbort();\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 m_processList.erase(tempIt);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }\r\n\u00a0\u00a0\u00a0 }\r\n}\r\n\r\n<\/pre>\n<p><strong><br \/>\nR\u00e9sum\u00e9 :<\/strong><\/p>\n<p>Ces classes vous seront utiles pour impl\u00e9menter vos propres syst\u00e8mes \/ process.<\/p>\n<p><strong>R\u00e9f\u00e9rences :<\/strong><\/p>\n<p>&#8211; Game Coding Complete 4 (code LGPL)<\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u00a0 Intro : Dans un jeu vid\u00e9o on fait souvent appel \u00e0 plusieurs sous-syst\u00e8mes et pour les mettre \u00e0 jour fr\u00e9quemment. On va utiliser deux classes permettant de g\u00e9rer ces sous syst\u00e8mes. class Process : classe de base, on peut la d\u00e9river puis red\u00e9finir la m\u00e9thode VUpdate(). class ProcessManager : gestionnaire d&rsquo;instances de Process. Un [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[4],"tags":[],"_links":{"self":[{"href":"https:\/\/www.la-porte-des-nebuleuses.net\/blog-informatique\/index.php?rest_route=\/wp\/v2\/posts\/175"}],"collection":[{"href":"https:\/\/www.la-porte-des-nebuleuses.net\/blog-informatique\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.la-porte-des-nebuleuses.net\/blog-informatique\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.la-porte-des-nebuleuses.net\/blog-informatique\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.la-porte-des-nebuleuses.net\/blog-informatique\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=175"}],"version-history":[{"count":56,"href":"https:\/\/www.la-porte-des-nebuleuses.net\/blog-informatique\/index.php?rest_route=\/wp\/v2\/posts\/175\/revisions"}],"predecessor-version":[{"id":3096,"href":"https:\/\/www.la-porte-des-nebuleuses.net\/blog-informatique\/index.php?rest_route=\/wp\/v2\/posts\/175\/revisions\/3096"}],"wp:attachment":[{"href":"https:\/\/www.la-porte-des-nebuleuses.net\/blog-informatique\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=175"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.la-porte-des-nebuleuses.net\/blog-informatique\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=175"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.la-porte-des-nebuleuses.net\/blog-informatique\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=175"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}