タイトルが私の質問が求めているものと正確に一致していない場合は申し訳ありません。これをどのように尋ねるのが最善の方法なのか、少しわかりません。
基本的に、もちろん Win32 関数を利用する DirectX C++ アプリケーションを作成しました。だから私は以下の静的メソッドを持っています
static LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
上記のメソッドには、次の case ステートメントが含まれています。
case WM_INPUT:
{
unsigned __int32 dwSize;
GetRawInputData((HRAWINPUT__*)lParam, RID_INPUT, NULL, &dwSize, sizeof(RAWINPUTHEADER));
unsigned char *lpb = new unsigned char[dwSize];
GetRawInputData((HRAWINPUT__*)lParam, RID_INPUT, lpb, &dwSize, sizeof(RAWINPUTHEADER));
tagRAWINPUT* raw = (tagRAWINPUT*)lpb;
InputSystem::handleRawMessage(raw);
delete[] lpb;
}
break;
よし、メソッドInputSystem::handleRawMessage(raw); 以下を行います。
__int32 KEY_STATE[8] = {0, 0, 0, 0, 0, 0, 0, 0};
void InputSystem::handleRawMessage(tagRAWINPUT *raw)
{
if (raw->header.dwType == RIM_TYPEKEYBOARD)
{
int key = raw->data.keyboard.VKey & 0xFF;
KEY_STATE[key >> 5] |= 1 << (key & 0x1F);
}
}
したがって、WindowProc は別のスレッドであると想定しているため、これらの配列にアクセスして値を格納するようにしています。問題が発生する可能性があると感じましたが、1 つのメソッドのみが読み取り、1 つのメソッドが書き込みを行うため、これが安全かどうかはわかりません。
void InputSystem::handleInput(void)
{
PREVIOUS_STATE = CURRENT_STATE;
CURRENT_STATE = 0;
for (int i = 0; i < MAPPING_SIZE; ++i)
{
if (isKeyPressed(MAPPED_KEYS[i]))
{
CURRENT_STATE |= 1 << i;
if (PREVIOUS_STATE & 1 << (0x10 | i))
CURRENT_STATE |= 1 << (0x10 | i);
}
}
clearKeyStates();
}
bool InputSystem::isKeyPressed(unsigned __int8 key)
{
return (KEY_STATE[key >> 5] & 1 << (key & 0x1F)) != 0x0;
}
上記コード「InputSystem::handleInput();」DirectX グラフィックスの描画を続行するために開始される while ループ内で呼び出されます。
上記のコードは安全な実行ですか、それとも両方のスレッドが同じ値で何かを実行しているときに問題が発生しますか?
私は Win32 を扱うのはまったく初めてで、最近 DirectX を始めたばかりで、DirectX が実際にこれと関係があるというわけではありません。同時実行性についてあまり心配する必要があったことは一度もなかったので、そうしたこともありませんでしたが、この特定の状況と、可能であれば安全である場合とそうでない場合の他の状況を理解したいと思います。ありがとう。
while ループは、以下のコードから生成されます。
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
Dx3DEngine engine = Dx3DEngine(hInstance, hPrevInstance, lpCmdLine, nCmdShow);
int code = engine.run();
if (code != 0)
{
engine.createUnsupportedWindow(code);
}
return code;
}
int Dx3DEngine::run()
{
MSG msg;
msg.message = WM_NULL;
__int64 cntsPerSec = 0;
__int64 prevTimeStamp = 0;
__int64 currTimeStamp = 0;
QueryPerformanceFrequency((LARGE_INTEGER*)&cntsPerSec);
QueryPerformanceCounter((LARGE_INTEGER*)&prevTimeStamp);
const float secsPerCnt = 1.0F / (float)cntsPerSec;
while(msg.message != WM_QUIT)
{
while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
QueryPerformanceCounter((LARGE_INTEGER*)&currTimeStamp);
float dt = (currTimeStamp - prevTimeStamp)*secsPerCnt;
update(dt);
draw();
prevTimeStamp = currTimeStamp;
}
clean();
return (int)msg.wParam;
}