YSTest  PreAlpha_b500_20140530
The YSLib Test Project
 全部  命名空间 文件 函数 变量 类型定义 枚举 枚举值 友元 宏定义  
Helper/Host.cpp
浏览该文件的文档.
1 /*
2  © 2013-2014 FrankHB.
3 
4  This file is part of the YSLib project, and may only be used,
5  modified, and distributed under the terms of the YSLib project
6  license, LICENSE.TXT. By continuing to use, modify, or distribute
7  this file you indicate that you have read the license and
8  understand and accept it fully.
9 */
10 
28 #include "Helper/YModules.h"
29 #include YFM_Helper_Host
30 #include YFM_Helper_ShellHelper // for YSL_DEBUG_DECL_TIMER;
31 
32 namespace YSLib
33 {
34 
35 using namespace Drawing;
36 
37 namespace
38 {
39 
40 #if YCL_Win32 && 0
41 yconstexpr double g_max_free_fps(1000);
42 std::chrono::nanoseconds host_sleep(u64(1000000000 / g_max_free_fps));
43 #endif
44 
45 } // unnamed namespace;
46 
47 
48 #if YF_Hosted
49 namespace Host
50 {
51 
52 namespace
53 {
54 
55 # if YCL_Win32
56 ::LRESULT CALLBACK
57 WndProc(::HWND h_wnd, ::UINT msg, ::WPARAM w_param, ::LPARAM l_param)
58 {
59  const auto p(reinterpret_cast<Window*>(::GetWindowLongPtrW(h_wnd,
60  GWLP_USERDATA)));
61 
62  if(YB_LIKELY(p))
63  {
65 
66  if(msg == WM_INPUT)
67  {
68  ::UINT size(sizeof(::RAWINPUT));
69  byte lpb[sizeof(::RAWINPUT)]{};
70 
71  if(YB_LIKELY(::GetRawInputData(::HRAWINPUT(l_param), RID_INPUT, lpb,
72  &size, sizeof(::RAWINPUTHEADER)) != ::UINT(-1)))
73  {
74  const auto p_raw(reinterpret_cast<::RAWINPUT*>(lpb));
75 
76  if(YB_LIKELY(p_raw->header.dwType == RIM_TYPEMOUSE))
77  {
78  if(p_raw->data.mouse.usButtonFlags == RI_MOUSE_WHEEL)
79  p->GetHost().RawMouseButton
80  = p_raw->data.mouse.usButtonData;
81  }
82  }
83  }
84 
85  auto& m(p->MessageMap);
86  const auto i(m.find(msg));
87 
88  if(i != m.cend())
89  {
90  i->second(w_param, l_param);
91  return 0;
92  }
93  }
94  return ::DefWindowProcW(h_wnd, msg, w_param, l_param);
95 }
96 # endif
97 
98 } // unnamed namespace;
99 
100 
101 Environment::Environment()
102  : wnd_map(), wmap_mtx()
103 # if YF_Multithread == 1
104  , wnd_thrd_count()
105 # if YCL_Win32
106  , window_class(WindowClassName, WndProc)
107 # endif
108 # endif
109 {}
110 Environment::~Environment()
111 {
112  YCL_Trace(Debug, "Host environment lifetime ended.");
113 
114 # if !YCL_Android
115  using ystdex::get_value;
116 
117  std::for_each(wnd_map.cbegin() | get_value, wnd_map.cend() | get_value,
118  [](Window* const& p){
119  p->Close();
120  });
121 # endif
122 }
123 
124 Window*
125 Environment::GetForegroundWindow() const ynothrow
126 {
127 #ifdef YCL_Win32
128  return FindWindow(::GetForegroundWindow());
129 #else
130  return {};
131 #endif
132 }
133 
134 void
135 Environment::AddMappedItem(NativeWindowHandle h, Window* p)
136 {
137  std::unique_lock<std::mutex> lck(wmap_mtx);
138 
139  // TODO: Use %emplace.
140  wnd_map.insert(make_pair(h, p));
141 }
142 
143 Window*
144 Environment::FindWindow(NativeWindowHandle h) const ynothrow
145 {
146  std::unique_lock<std::mutex> lck(wmap_mtx);
147  const auto i(wnd_map.find(h));
148 
149  return i == wnd_map.end() ? nullptr : i->second;
150 }
151 
152 void
153 Environment::HostLoop()
154 {
155  YTraceDe(Notice, "Host loop beginned.");
156 # if YCL_Win32
157  while(true)
158  {
159  ::MSG msg{nullptr, 0, 0, 0, 0, {0, 0}};
160 
161  if(::PeekMessageW(&msg, nullptr, 0, 0, PM_REMOVE) != 0)
162  {
163  if(msg.message == WM_QUIT)
164  break;
165  // if(!PreTranslateMessage(&msg))
166  {
167  ::TranslateMessage(&msg);
168  ::DispatchMessageW(&msg);
169  }
170  // if(CheckCloseDialog(frm, false))
171  // break;
172  }
173  else
174  // std::this_thread::yield();
175  // std::this_thread::sleep_for(host_sleep);
176  // NOTE: Failure ignored.
177  ::WaitMessage();
178  }
179 # endif
180  YTraceDe(Notice, "Host loop ended.");
181 }
182 
183 # if YF_Multithread == 1
184 void
185 Environment::LeaveWindowThread()
186 {
187  if(--wnd_thrd_count == 0 && ExitOnAllWindowThreadCompleted)
189 }
190 # endif
191 
192 void
193 Environment::RemoveMappedItem(NativeWindowHandle h) ynothrow
194 {
195  std::unique_lock<std::mutex> lck(wmap_mtx);
196  const auto i(wnd_map.find(h));
197 
198  if(i != wnd_map.end())
199  wnd_map.erase(i);
200 }
201 
202 void
203 Environment::UpdateRenderWindows()
204 {
205  std::unique_lock<std::mutex> lck(wmap_mtx);
206 
207  for(const auto& pr : wnd_map)
208  if(pr.second)
209  pr.second->Refresh();
210 }
211 
212 } // namespace Host;
213 #endif
214 
215 } // namespace YSLib;
216 
yconstexpr wchar_t WindowClassName[]
YF_API void PostQuitMessage(int nExitCode, Messaging::Priority p=0xF0)
以优先级 p 发起 Shell 终止请求,返回 nExitCode。
Definition: yapp.cpp:83
std::uint64_t u64
Definition: yadaptor.h:70
unsigned char byte
字节类型。
Definition: ydef.h:555
#define YCL_Trace(_lv,...)
YCLib 默认调试跟踪。
Definition: Debug.h:249
窗口背景。
Definition: ystyle.h:182
const second_tag get_value
Definition: iterator.hpp:785
#define ynothrow
YSLib 无异常抛出保证:若支持 noexcept 关键字, 指定特定的 noexcept 异常规范。
Definition: ydef.h:514
if(YB_LIKELY(!error)) if(YB_LIKELY(!(error
#define YF_Multithread
多线程环境。
Definition: Platform.h:139
::ANativeWindow * NativeWindowHandle
Definition: Android.h:50
std::string to_string(unsigned char val)
转换为字符串。
Definition: string.hpp:353
#define YTraceDe(...)
YCLib 默认调试跟踪。
Definition: Debug.h:269
#define yconstexpr
指定编译时常量表达式。
Definition: ydef.h:462
#define YB_LIKELY(expr)
Definition: ydef.h:297
#define YSL_DEBUG_DECL_TIMER(_name,...)
Definition: ShellHelper.h:56