{"action":"created","comment":{"url":"https://api.github.com/repos/citra-emu/citra/pulls/comments/31170077","id":31170077,"diff_hunk":"@@ -0,0 +1,77 @@\n+// Copyright 2015 Citra Emulator Project\n+// Licensed under GPLv2 or any later version\n+// Refer to the license.txt file included.\n+\n+#include \"common/assert.h\"\n+#include \"common/logging/log.h\"\n+\n+#include \"core/core_timing.h\"\n+#include \"core/hle/applets/applet.h\"\n+#include \"core/hle/applets/swkbd.h\"\n+\n+////////////////////////////////////////////////////////////////////////////////////////////////////\n+\n+// Specializes std::hash for AppletId, so that we can use it in std::unordered_map.\n+// Workaround for libstdc++ bug: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60970\n+namespace std {\n+    template <>\n+    struct hash<Service::APT::AppletId> {\n+        typedef Service::APT::AppletId argument_type;\n+        typedef std::size_t result_type;\n+\n+        result_type operator()(const argument_type& id_code) const {\n+            typedef std::underlying_type<argument_type>::type Type;\n+            return std::hash<Type>()(static_cast<Type>(id_code));\n+        }\n+    };\n+}\n+\n+namespace HLE {\n+namespace Applets {\n+\n+static std::unordered_map<Service::APT::AppletId, std::shared_ptr<Applet>> applets;\n+static u32 applet_update_event = -1; ///< The CoreTiming event identifier for the Applet update callback.\n+static const u64 applet_update_interval = 1000000; ///< The interval at which the Applet update callback will be called.\n+std::shared_ptr<Applet> g_current_applet = nullptr; ///< The applet that is currently executing\n+\n+ResultCode Applet::Create(Service::APT::AppletId id) {\n+    switch (id) {\n+    case Service::APT::AppletId::SoftwareKeyboard1:\n+    case Service::APT::AppletId::SoftwareKeyboard2:\n+        applets[id] = std::make_shared<SoftwareKeyboard>(id);\n+        break;\n+    default:\n+        // TODO(Subv): Find the right error code\n+        return ResultCode(ErrorDescription::NotFound, ErrorModule::Applet, ErrorSummary::NotSupported, ErrorLevel::Permanent);\n+    }\n+\n+    return RESULT_SUCCESS;\n+}\n+\n+std::shared_ptr<Applet> Applet::Get(Service::APT::AppletId id) {\n+    auto itr = applets.find(id);\n+    if (itr != applets.end())\n+        return itr->second;\n+    return nullptr;\n+}\n+\n+/// Handles updating the current Applet every time it's called.\n+static void AppletUpdateEvent(u64, int cycles_late) {\n+    if (g_current_applet && g_current_applet->IsRunning())\n+        g_current_applet->Update();\n+\n+    CoreTiming::ScheduleEvent(usToCycles(applet_update_interval) - cycles_late,\n+        applet_update_event);\n+}\n+\n+void Init() {\n+    applet_update_event = CoreTiming::RegisterEvent(\"HLE Applet Update Event\", AppletUpdateEvent);\n+    CoreTiming::ScheduleEvent(usToCycles(applet_update_interval), applet_update_event);","path":"src/core/hle/applets/applet.cpp","position":70,"original_position":69,"commit_id":"904914dbe12f38856c7848798738490eedcd8679","original_commit_id":"5305c13c9aa60a2c73cad664e8895b5ea82c1dc6","user":{"login":"yuriks","id":341401,"avatar_url":"https://avatars.githubusercontent.com/u/341401?v=3","gravatar_id":"","url":"https://api.github.com/users/yuriks","html_url":"https://github.com/yuriks","followers_url":"https://api.github.com/users/yuriks/followers","following_url":"https://api.github.com/users/yuriks/following{/other_user}","gists_url":"https://api.github.com/users/yuriks/gists{/gist_id}","starred_url":"https://api.github.com/users/yuriks/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/yuriks/subscriptions","organizations_url":"https://api.github.com/users/yuriks/orgs","repos_url":"https://api.github.com/users/yuriks/repos","events_url":"https://api.github.com/users/yuriks/events{/privacy}","received_events_url":"https://api.github.com/users/yuriks/received_events","type":"User","site_admin":false},"body":"The timing event should only be active while the applet is running.","created_at":"2015-05-27T19:19:07Z","updated_at":"2015-05-27T19:19:07Z","html_url":"https://github.com/citra-emu/citra/pull/823#discussion_r31170077","pull_request_url":"https://api.github.com/repos/citra-emu/citra/pulls/823","_links":{"self":{"href":"https://api.github.com/repos/citra-emu/citra/pulls/comments/31170077"},"html":{"href":"https://github.com/citra-emu/citra/pull/823#discussion_r31170077"},"pull_request":{"href":"https://api.github.com/repos/citra-emu/citra/pulls/823"}}},"pull_request":{"url":"https://api.github.com/repos/citra-emu/citra/pulls/823","id":36233905,"html_url":"https://github.com/citra-emu/citra/pull/823","diff_url":"https://github.com/citra-emu/citra/pull/823.diff","patch_url":"https://github.com/citra-emu/citra/pull/823.patch","issue_url":"https://api.github.com/repos/citra-emu/citra/issues/823","number":823,"state":"open","locked":false,"title":"[RFC] Library applet support","user":{"login":"Subv","id":357072,"avatar_url":"https://avatars.githubusercontent.com/u/357072?v=3","gravatar_id":"","url":"https://api.github.com/users/Subv","html_url":"https://github.com/Subv","followers_url":"https://api.github.com/users/Subv/followers","following_url":"https://api.github.com/users/Subv/following{/other_user}","gists_url":"https://api.github.com/users/Subv/gists{/gist_id}","starred_url":"https://api.github.com/users/Subv/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Subv/subscriptions","organizations_url":"https://api.github.com/users/Subv/orgs","repos_url":"https://api.github.com/users/Subv/repos","events_url":"https://api.github.com/users/Subv/events{/privacy}","received_events_url":"https://api.github.com/users/Subv/received_events","type":"User","site_admin":false},"body":"These changes add a new interface for implementing library applets, and adds an implementation of it for the SoftwareKeyboard (swkbd).\r\n\r\nAn applet's lifetime goes like this\r\n* PrepareToLaunchLibraryApplet creates the applet.\r\n* Application sends signal 2 to the applet, and the applet responds with signal 3.\r\n* StartLibraryApplet signals the applet to start doing its thing (Drawing to the screen, etc).\r\n* Once the applet finishes, it sends signal 0xA to the application.\r\n* Application now restores the framebuffers and continues execution.\r\n\r\nIn this HLE implementation, the drawing and handling of touch events / keys should be done in the Applet::Update method.\r\nThe implementation of the SoftwareKeyboard currently only returnrs \"Citra\" as the text, without asking the user for input, but this can change in the future by means of just drawing the keyboard to the framebuffer inside SoftwareKeyboard::DrawScreenKeyboard, and handling the input events + updating the framebuffer in SoftwareKeyboard::Update. I didn't do it because I'm not good at drawing stuff.\r\n\r\nFurthermore, this PR should fix #718 ","created_at":"2015-05-26T18:56:45Z","updated_at":"2015-05-27T19:19:07Z","closed_at":null,"merged_at":null,"merge_commit_sha":"7623466d90a7bac6fe923e4233ece3387cab52a7","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/citra-emu/citra/pulls/823/commits","review_comments_url":"https://api.github.com/repos/citra-emu/citra/pulls/823/comments","review_comment_url":"https://api.github.com/repos/citra-emu/citra/pulls/comments{/number}","comments_url":"https://api.github.com/repos/citra-emu/citra/issues/823/comments","statuses_url":"https://api.github.com/repos/citra-emu/citra/statuses/904914dbe12f38856c7848798738490eedcd8679","head":{"label":"Subv:applets_drawing","ref":"applets_drawing","sha":"904914dbe12f38856c7848798738490eedcd8679","user":{"login":"Subv","id":357072,"avatar_url":"https://avatars.githubusercontent.com/u/357072?v=3","gravatar_id":"","url":"https://api.github.com/users/Subv","html_url":"https://github.com/Subv","followers_url":"https://api.github.com/users/Subv/followers","following_url":"https://api.github.com/users/Subv/following{/other_user}","gists_url":"https://api.github.com/users/Subv/gists{/gist_id}","starred_url":"https://api.github.com/users/Subv/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Subv/subscriptions","organizations_url":"https://api.github.com/users/Subv/orgs","repos_url":"https://api.github.com/users/Subv/repos","events_url":"https://api.github.com/users/Subv/events{/privacy}","received_events_url":"https://api.github.com/users/Subv/received_events","type":"User","site_admin":false},"repo":{"id":22818827,"name":"citra","full_name":"Subv/citra","owner":{"login":"Subv","id":357072,"avatar_url":"https://avatars.githubusercontent.com/u/357072?v=3","gravatar_id":"","url":"https://api.github.com/users/Subv","html_url":"https://github.com/Subv","followers_url":"https://api.github.com/users/Subv/followers","following_url":"https://api.github.com/users/Subv/following{/other_user}","gists_url":"https://api.github.com/users/Subv/gists{/gist_id}","starred_url":"https://api.github.com/users/Subv/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Subv/subscriptions","organizations_url":"https://api.github.com/users/Subv/orgs","repos_url":"https://api.github.com/users/Subv/repos","events_url":"https://api.github.com/users/Subv/events{/privacy}","received_events_url":"https://api.github.com/users/Subv/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/Subv/citra","description":"Nintendo 3DS emulator/debugger","fork":true,"url":"https://api.github.com/repos/Subv/citra","forks_url":"https://api.github.com/repos/Subv/citra/forks","keys_url":"https://api.github.com/repos/Subv/citra/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Subv/citra/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Subv/citra/teams","hooks_url":"https://api.github.com/repos/Subv/citra/hooks","issue_events_url":"https://api.github.com/repos/Subv/citra/issues/events{/number}","events_url":"https://api.github.com/repos/Subv/citra/events","assignees_url":"https://api.github.com/repos/Subv/citra/assignees{/user}","branches_url":"https://api.github.com/repos/Subv/citra/branches{/branch}","tags_url":"https://api.github.com/repos/Subv/citra/tags","blobs_url":"https://api.github.com/repos/Subv/citra/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Subv/citra/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Subv/citra/git/refs{/sha}","trees_url":"https://api.github.com/repos/Subv/citra/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Subv/citra/statuses/{sha}","languages_url":"https://api.github.com/repos/Subv/citra/languages","stargazers_url":"https://api.github.com/repos/Subv/citra/stargazers","contributors_url":"https://api.github.com/repos/Subv/citra/contributors","subscribers_url":"https://api.github.com/repos/Subv/citra/subscribers","subscription_url":"https://api.github.com/repos/Subv/citra/subscription","commits_url":"https://api.github.com/repos/Subv/citra/commits{/sha}","git_commits_url":"https://api.github.com/repos/Subv/citra/git/commits{/sha}","comments_url":"https://api.github.com/repos/Subv/citra/comments{/number}","issue_comment_url":"https://api.github.com/repos/Subv/citra/issues/comments{/number}","contents_url":"https://api.github.com/repos/Subv/citra/contents/{+path}","compare_url":"https://api.github.com/repos/Subv/citra/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Subv/citra/merges","archive_url":"https://api.github.com/repos/Subv/citra/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Subv/citra/downloads","issues_url":"https://api.github.com/repos/Subv/citra/issues{/number}","pulls_url":"https://api.github.com/repos/Subv/citra/pulls{/number}","milestones_url":"https://api.github.com/repos/Subv/citra/milestones{/number}","notifications_url":"https://api.github.com/repos/Subv/citra/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Subv/citra/labels{/name}","releases_url":"https://api.github.com/repos/Subv/citra/releases{/id}","created_at":"2014-08-10T21:13:43Z","updated_at":"2015-05-07T23:57:36Z","pushed_at":"2015-05-27T19:17:11Z","git_url":"git://github.com/Subv/citra.git","ssh_url":"git@github.com:Subv/citra.git","clone_url":"https://github.com/Subv/citra.git","svn_url":"https://github.com/Subv/citra","homepage":null,"size":10171,"stargazers_count":0,"watchers_count":0,"language":"C++","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"citra-emu:master","ref":"master","sha":"3c47522e67ab80f69b29969ff2027cf5f8181c8c","user":{"login":"citra-emu","id":7605670,"avatar_url":"https://avatars.githubusercontent.com/u/7605670?v=3","gravatar_id":"","url":"https://api.github.com/users/citra-emu","html_url":"https://github.com/citra-emu","followers_url":"https://api.github.com/users/citra-emu/followers","following_url":"https://api.github.com/users/citra-emu/following{/other_user}","gists_url":"https://api.github.com/users/citra-emu/gists{/gist_id}","starred_url":"https://api.github.com/users/citra-emu/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/citra-emu/subscriptions","organizations_url":"https://api.github.com/users/citra-emu/orgs","repos_url":"https://api.github.com/users/citra-emu/repos","events_url":"https://api.github.com/users/citra-emu/events{/privacy}","received_events_url":"https://api.github.com/users/citra-emu/received_events","type":"Organization","site_admin":false},"repo":{"id":19866730,"name":"citra","full_name":"citra-emu/citra","owner":{"login":"citra-emu","id":7605670,"avatar_url":"https://avatars.githubusercontent.com/u/7605670?v=3","gravatar_id":"","url":"https://api.github.com/users/citra-emu","html_url":"https://github.com/citra-emu","followers_url":"https://api.github.com/users/citra-emu/followers","following_url":"https://api.github.com/users/citra-emu/following{/other_user}","gists_url":"https://api.github.com/users/citra-emu/gists{/gist_id}","starred_url":"https://api.github.com/users/citra-emu/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/citra-emu/subscriptions","organizations_url":"https://api.github.com/users/citra-emu/orgs","repos_url":"https://api.github.com/users/citra-emu/repos","events_url":"https://api.github.com/users/citra-emu/events{/privacy}","received_events_url":"https://api.github.com/users/citra-emu/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/citra-emu/citra","description":"Nintendo 3DS emulator/debugger","fork":false,"url":"https://api.github.com/repos/citra-emu/citra","forks_url":"https://api.github.com/repos/citra-emu/citra/forks","keys_url":"https://api.github.com/repos/citra-emu/citra/keys{/key_id}","collaborators_url":"https://api.github.com/repos/citra-emu/citra/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/citra-emu/citra/teams","hooks_url":"https://api.github.com/repos/citra-emu/citra/hooks","issue_events_url":"https://api.github.com/repos/citra-emu/citra/issues/events{/number}","events_url":"https://api.github.com/repos/citra-emu/citra/events","assignees_url":"https://api.github.com/repos/citra-emu/citra/assignees{/user}","branches_url":"https://api.github.com/repos/citra-emu/citra/branches{/branch}","tags_url":"https://api.github.com/repos/citra-emu/citra/tags","blobs_url":"https://api.github.com/repos/citra-emu/citra/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/citra-emu/citra/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/citra-emu/citra/git/refs{/sha}","trees_url":"https://api.github.com/repos/citra-emu/citra/git/trees{/sha}","statuses_url":"https://api.github.com/repos/citra-emu/citra/statuses/{sha}","languages_url":"https://api.github.com/repos/citra-emu/citra/languages","stargazers_url":"https://api.github.com/repos/citra-emu/citra/stargazers","contributors_url":"https://api.github.com/repos/citra-emu/citra/contributors","subscribers_url":"https://api.github.com/repos/citra-emu/citra/subscribers","subscription_url":"https://api.github.com/repos/citra-emu/citra/subscription","commits_url":"https://api.github.com/repos/citra-emu/citra/commits{/sha}","git_commits_url":"https://api.github.com/repos/citra-emu/citra/git/commits{/sha}","comments_url":"https://api.github.com/repos/citra-emu/citra/comments{/number}","issue_comment_url":"https://api.github.com/repos/citra-emu/citra/issues/comments{/number}","contents_url":"https://api.github.com/repos/citra-emu/citra/contents/{+path}","compare_url":"https://api.github.com/repos/citra-emu/citra/compare/{base}...{head}","merges_url":"https://api.github.com/repos/citra-emu/citra/merges","archive_url":"https://api.github.com/repos/citra-emu/citra/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/citra-emu/citra/downloads","issues_url":"https://api.github.com/repos/citra-emu/citra/issues{/number}","pulls_url":"https://api.github.com/repos/citra-emu/citra/pulls{/number}","milestones_url":"https://api.github.com/repos/citra-emu/citra/milestones{/number}","notifications_url":"https://api.github.com/repos/citra-emu/citra/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/citra-emu/citra/labels{/name}","releases_url":"https://api.github.com/repos/citra-emu/citra/releases{/id}","created_at":"2014-05-16T18:33:15Z","updated_at":"2015-05-27T18:15:58Z","pushed_at":"2015-05-27T19:17:12Z","git_url":"git://github.com/citra-emu/citra.git","ssh_url":"git@github.com:citra-emu/citra.git","clone_url":"https://github.com/citra-emu/citra.git","svn_url":"https://github.com/citra-emu/citra","homepage":null,"size":25036,"stargazers_count":863,"watchers_count":863,"language":"C++","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":213,"mirror_url":null,"open_issues_count":67,"forks":213,"open_issues":67,"watchers":863,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/citra-emu/citra/pulls/823"},"html":{"href":"https://github.com/citra-emu/citra/pull/823"},"issue":{"href":"https://api.github.com/repos/citra-emu/citra/issues/823"},"comments":{"href":"https://api.github.com/repos/citra-emu/citra/issues/823/comments"},"review_comments":{"href":"https://api.github.com/repos/citra-emu/citra/pulls/823/comments"},"review_comment":{"href":"https://api.github.com/repos/citra-emu/citra/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/citra-emu/citra/pulls/823/commits"},"statuses":{"href":"https://api.github.com/repos/citra-emu/citra/statuses/904914dbe12f38856c7848798738490eedcd8679"}}}}