Web: Some fix for critical runtime error and cleanups.

This commit is contained in:
verylowfreq 2022-08-08 15:52:51 +09:00 committed by ruevs
parent cf597277fa
commit b5cde57bb6

View File

@ -346,6 +346,7 @@ MenuBarRef GetOrCreateMainMenu(bool *unique) {
class TouchEventHelper { class TouchEventHelper {
public: public:
// FIXME(emscripten): Workaround. touchstart and touchend repeats two times.
bool touchActionStarted = false; bool touchActionStarted = false;
int previousNumTouches = 0; int previousNumTouches = 0;
@ -356,10 +357,10 @@ public:
// double startPinchDistance = 0; // double startPinchDistance = 0;
double previousPinchDistance = 0; double previousPinchDistance = 0;
std::function<void(MouseEvent*)> onPointerDown; std::function<void(MouseEvent*, void*)> onPointerDown;
std::function<void(MouseEvent*)> onPointerMove; std::function<void(MouseEvent*, void*)> onPointerMove;
std::function<void(MouseEvent*)> onPointerUp; std::function<void(MouseEvent*, void*)> onPointerUp;
std::function<void(MouseEvent*)> onScroll; std::function<void(MouseEvent*, void*)> onScroll;
void clear(void) { void clear(void) {
touchActionStarted = false; touchActionStarted = false;
@ -370,43 +371,31 @@ public:
previousPinchDistance = 0; previousPinchDistance = 0;
} }
void calculateCenterPosition(const EmscriptenTouchEvent *emEvent, double* dst_x, double* dst_y) { void calculateCenterPosition(const EmscriptenTouchEvent& emEvent, double& dst_x, double& dst_y) {
if (!emEvent) {
return;
}
double x = 0; double x = 0;
double y = 0; double y = 0;
for (int i = 0; i < emEvent->numTouches; i++) { for (int i = 0; i < emEvent.numTouches; i++) {
x += emEvent->touches[i].clientX; x += emEvent.touches[i].clientX;
y += emEvent->touches[i].clientY; y += emEvent.touches[i].clientY;
}
if (dst_x) {
*dst_x = x / emEvent->numTouches;
}
if (dst_y) {
*dst_y = y / emEvent->numTouches;
} }
dst_x = x / emEvent.numTouches;
dst_y = y / emEvent.numTouches;
} }
void calculatePinchDistance(const EmscriptenTouchEvent *emEvent, double* dst_distance) { void calculatePinchDistance(const EmscriptenTouchEvent& emEvent, double& dst_distance) {
if (!emEvent) { if (emEvent.numTouches < 2) {
return; return;
} }
if (emEvent->numTouches < 2) { double x1 = emEvent.touches[0].clientX;
return; double y1 = emEvent.touches[0].clientY;
} double x2 = emEvent.touches[1].clientX;
double x1 = emEvent->touches[0].clientX; double y2 = emEvent.touches[1].clientY;
double y1 = emEvent->touches[0].clientY; dst_distance = std::sqrt(std::pow(x1 - x2, 2) + std::pow(y1 - y2, 2));
double x2 = emEvent->touches[1].clientX;
double y2 = emEvent->touches[1].clientY;
if (dst_distance) {
*dst_distance = std::sqrt(std::pow(x1 - x2, 2) + std::pow(y1 - y2, 2));
}
} }
void createMouseEventPRESS(const EmscriptenTouchEvent& emEvent, MouseEvent& dst_mouseevent) { void createMouseEventPRESS(const EmscriptenTouchEvent& emEvent, MouseEvent& dst_mouseevent) {
double x = 0, y = 0; double x = 0, y = 0;
this->calculateCenterPosition(&emEvent, &x, &y); this->calculateCenterPosition(emEvent, x, y);
this->centerX = x; this->centerX = x;
this->centerY = y; this->centerY = y;
this->touchActionStarted = true; this->touchActionStarted = true;
@ -423,7 +412,7 @@ public:
case 2: { case 2: {
dst_mouseevent.button = MouseEvent::Button::RIGHT; dst_mouseevent.button = MouseEvent::Button::RIGHT;
// double distance = 0; // double distance = 0;
this->calculatePinchDistance(&emEvent, &this->previousPinchDistance); this->calculatePinchDistance(emEvent, this->previousPinchDistance);
// this->startPinchDistance = distance; // this->startPinchDistance = distance;
// this->previousPinchDistance = distance; // this->previousPinchDistance = distance;
break; break;
@ -434,68 +423,57 @@ public:
} }
} }
bool createMouseEventRELEASE(const EmscriptenTouchEvent &emEvent, MouseEvent* dst_mouseevent) { void createMouseEventRELEASE(const EmscriptenTouchEvent& emEvent, MouseEvent& dst_mouseevent) {
double x = 0, y = 0; this->calculateCenterPosition(emEvent, this->centerX, this->centerY);
this->calculateCenterPosition(&emEvent, &x, &y);
this->centerX = x;
this->centerY = y;
this->previousNumTouches = 0; this->previousNumTouches = 0;
dst_mouseevent->type = MouseEvent::Type::RELEASE; dst_mouseevent.type = MouseEvent::Type::RELEASE;
dst_mouseevent->x = x; dst_mouseevent.x = this->centerX;
dst_mouseevent->y = y; dst_mouseevent.y = this->centerY;
dst_mouseevent->shiftDown = emEvent.shiftKey; dst_mouseevent.shiftDown = emEvent.shiftKey;
dst_mouseevent->controlDown = emEvent.ctrlKey; dst_mouseevent.controlDown = emEvent.ctrlKey;
switch(this->previousNumTouches) { switch(this->previousNumTouches) {
case 1: case 1:
dst_mouseevent->button = MouseEvent::Button::LEFT; dst_mouseevent.button = MouseEvent::Button::LEFT;
break; break;
case 2: case 2:
dst_mouseevent->button = MouseEvent::Button::RIGHT; dst_mouseevent.button = MouseEvent::Button::RIGHT;
break; break;
default: default:
dst_mouseevent->button = MouseEvent::Button::MIDDLE; dst_mouseevent.button = MouseEvent::Button::MIDDLE;
break; break;
} }
return true;
} }
bool createMouseEventMOTION(const EmscriptenTouchEvent *emEvent, MouseEvent* dst_mouseevent) { void createMouseEventMOTION(const EmscriptenTouchEvent& emEvent, MouseEvent& dst_mouseevent) {
dst_mouseevent->type = MouseEvent::Type::MOTION; dst_mouseevent.type = MouseEvent::Type::MOTION;
double x = 0, y = 0; this->calculateCenterPosition(emEvent, this->centerX, this->centerY);
this->calculateCenterPosition(emEvent, &x, &y); dst_mouseevent.x = this->centerX;
this->centerX = x; dst_mouseevent.y = this->centerY;
this->centerY = y; dst_mouseevent.shiftDown = emEvent.shiftKey;
dst_mouseevent->x = this->centerX; dst_mouseevent.controlDown = emEvent.ctrlKey;
dst_mouseevent->y = this->centerY; switch(emEvent.numTouches) {
dst_mouseevent->shiftDown = emEvent->shiftKey;
dst_mouseevent->controlDown = emEvent->ctrlKey;
switch(emEvent->numTouches) {
case 1: case 1:
dst_mouseevent->button = MouseEvent::Button::LEFT; dst_mouseevent.button = MouseEvent::Button::LEFT;
break; break;
case 2: case 2:
dst_mouseevent->button = MouseEvent::Button::RIGHT; dst_mouseevent.button = MouseEvent::Button::RIGHT;
break; break;
default: default:
dst_mouseevent->button = MouseEvent::Button::MIDDLE; dst_mouseevent.button = MouseEvent::Button::MIDDLE;
break; break;
} }
return true;
} }
bool createMouseEventSCROLL(const EmscriptenTouchEvent* emEvent, MouseEvent& event) { void createMouseEventSCROLL(const EmscriptenTouchEvent& emEvent, MouseEvent& event) {
event.type = MouseEvent::Type::SCROLL_VERT; event.type = MouseEvent::Type::SCROLL_VERT;
double newDistance = 0; double newDistance = 0;
this->calculatePinchDistance(emEvent, &newDistance); this->calculatePinchDistance(emEvent, newDistance);
double x = 0, y = 0; this->calculateCenterPosition(emEvent, this->centerX, this->centerY);
this->calculateCenterPosition(emEvent, &x, &y);
this->centerX = x;
this->centerY = y;
event.x = this->centerX; event.x = this->centerX;
event.y = this->centerY; event.y = this->centerY;
event.shiftDown = emEvent->shiftKey; event.shiftDown = emEvent.shiftKey;
event.controlDown = emEvent->ctrlKey; event.controlDown = emEvent.ctrlKey;
// FIXME(emscripten): best value range for scrollDelta ?
event.scrollDelta = (newDistance - this->previousPinchDistance) / 25.0; event.scrollDelta = (newDistance - this->previousPinchDistance) / 25.0;
if (std::abs(event.scrollDelta) > 2) { if (std::abs(event.scrollDelta) > 2) {
event.scrollDelta = 2; event.scrollDelta = 2;
@ -504,180 +482,84 @@ public:
} }
} }
this->previousPinchDistance = newDistance; this->previousPinchDistance = newDistance;
return true;
} }
void onTouchStart(const EmscriptenTouchEvent *emEvent) { void onTouchStart(const EmscriptenTouchEvent& emEvent, void* callbackParameter) {
if (!emEvent) {
return;
}
if (this->touchActionStarted) { if (this->touchActionStarted) {
dbp("onTouchStart(): Break due to already started."); // dbp("onTouchStart(): Break due to already started.");
return; return;
} }
MouseEvent event; MouseEvent event;
this->createMouseEventPRESS(*emEvent, event); this->createMouseEventPRESS(emEvent, event);
this->previousNumTouches = emEvent->numTouches; this->previousNumTouches = emEvent.numTouches;
if (this->onPointerDown) { if (this->onPointerDown) {
dbp("onPointerDown(): numTouches=%d, timestamp=%f", emEvent->numTouches, emEvent->timestamp); // dbp("onPointerDown(): numTouches=%d, timestamp=%f", emEvent.numTouches, emEvent.timestamp);
this->onPointerDown(&event); this->onPointerDown(&event, callbackParameter);
} }
} }
void onTouchMove(const EmscriptenTouchEvent *emEvent) { void onTouchMove(const EmscriptenTouchEvent& emEvent, void* callbackParameter) {
if (!emEvent) { this->calculateCenterPosition(emEvent, this->centerX, this->centerY);
return; int newNumTouches = emEvent.numTouches;
}
this->calculateCenterPosition(emEvent, &this->centerX, &this->centerY);
int newNumTouches = emEvent->numTouches;
if (newNumTouches != this->previousNumTouches) { if (newNumTouches != this->previousNumTouches) {
// MouseEvent event = { }; MouseEvent releaseEvent;
// event.type = MouseEvent::Type::RELEASE;
// event.x = this->centerX; this->createMouseEventRELEASE(emEvent, releaseEvent);
// event.y = this->centerY;
// event.shiftDown = emEvent->shiftKey;
// event.controlDown = emEvent->ctrlKey;
// switch(this->previousNumTouches) {
// case 1:
// event.button = MouseEvent::Button::LEFT;
// break;
// case 2:
// event.button = MouseEvent::Button::RIGHT;
// {
// double distance = 0;
// this->calculatePinchDistance(emEvent, &distance);
// this->startPinchDistance = distance;
// this->previousPinchDistance = this->startPinchDistance;
// }
// break;
// default:
// event.button = MouseEvent::Button::MIDDLE;
// break;
// }
MouseEvent event;
if (!this->createMouseEventRELEASE(*emEvent, &event)) {
dbp("Failed to createMouseEventRELEASE() at L%d", __LINE__);
return;
}
if (this->onPointerUp) { if (this->onPointerUp) {
dbp("onPointerUp(): numTouches=%d, timestamp=%f", emEvent->numTouches, emEvent->timestamp); // dbp("onPointerUp(): numTouches=%d, timestamp=%f", emEvent.numTouches, emEvent.timestamp);
this->onPointerUp(&event); this->onPointerUp(&releaseEvent, callbackParameter);
} }
// event.type = MouseEvent::Type::PRESS; MouseEvent pressEvent;
// switch(emEvent->numTouches) {
// case 1: this->createMouseEventPRESS(emEvent, pressEvent);
// event.button = MouseEvent::Button::LEFT;
// break;
// case 2:
// event.button = MouseEvent::Button::RIGHT;
// break;
// default:
// event.button = MouseEvent::Button::MIDDLE;
// break;
// }
// if (!this->createMouseEventPRESS(emEvent, &event)) {
// dbp("Failed to createMouseEventPRESS() at L%d", __LINE__);
// return;
// }
this->createMouseEventPRESS(*emEvent, event);
if (this->onPointerDown) { if (this->onPointerDown) {
dbp("onPointerDown(): numTouches=%d, timestamp=%f", emEvent->numTouches, emEvent->timestamp); // dbp("onPointerDown(): numTouches=%d, timestamp=%f", emEvent.numTouches, emEvent.timestamp);
this->onPointerDown(&event); this->onPointerDown(&pressEvent, callbackParameter);
} }
} }
MouseEvent event = { }; MouseEvent motionEvent = { };
// event.type = MouseEvent::Type::MOTION; this->createMouseEventMOTION(emEvent, motionEvent);
// event.x = this->centerX;
// event.y = this->centerY;
// event.shiftDown = emEvent->shiftKey;
// event.controlDown = emEvent->ctrlKey;
// switch(emEvent->numTouches) {
// case 1:
// event.button = MouseEvent::Button::LEFT;
// break;
// case 2:
// event.button = MouseEvent::Button::RIGHT;
// break;
// default:
// event.button = MouseEvent::Button::MIDDLE;
// break;
// }
this->createMouseEventMOTION(emEvent, &event);
if (this->onPointerMove) { if (this->onPointerMove) {
dbp("onPointerMove(): numTouches=%d, timestamp=%f", emEvent->numTouches, emEvent->timestamp); // dbp("onPointerMove(): numTouches=%d, timestamp=%f", emEvent.numTouches, emEvent.timestamp);
this->onPointerMove(&event); this->onPointerMove(&motionEvent, callbackParameter);
} }
if (emEvent->numTouches == 2) { if (emEvent.numTouches == 2) {
// double newDistance = 0; MouseEvent scrollEvent;
// this->calculatePinchDistance(emEvent, &newDistance); this->createMouseEventSCROLL(emEvent, scrollEvent);
// if (newDistance != this->previousPinchDistance) { if (scrollEvent.scrollDelta != 0) {
// dbp("Scroll %f", (newDistance - this->previousPinchDistance)); if (this->onScroll) {
// MouseEvent scrollEvent = { }; // dbp("Scroll %f", scrollEvent.scrollDelta);
// scrollEvent.type = MouseEvent::Type::SCROLL_VERT; this->onScroll(&scrollEvent, callbackParameter);
// scrollEvent.scrollDelta = (newDistance - this->previousPinchDistance) / 10.0;
// if (this->onScroll) {
// this->onScroll(&scrollEvent);
// }
// this->previousPinchDistance = newDistance;
// }
MouseEvent event;
if (this->createMouseEventSCROLL(emEvent, event)) {
if (event.scrollDelta != 0) {
if (this->onScroll) {
dbp("Scroll %f", event.scrollDelta);
this->onScroll(&event);
}
} }
} }
} }
this->previousNumTouches = emEvent->numTouches; this->previousNumTouches = emEvent.numTouches;
} }
void onTouchEnd(const EmscriptenTouchEvent *emEvent) { void onTouchEnd(const EmscriptenTouchEvent& emEvent, void* callbackParameter) {
if (!emEvent) {
return;
}
if (!this->touchActionStarted) { if (!this->touchActionStarted) {
return; return;
} }
MouseEvent event = { }; MouseEvent releaseEvent = { };
// event.type = MouseEvent::Type::RELEASE; this->createMouseEventRELEASE(emEvent, releaseEvent);
// event.x = this->centerX;
// event.y = this->centerY;
// event.shiftDown = emEvent->shiftKey;
// event.controlDown = emEvent->ctrlKey;
// switch(this->previousNumTouches) {
// case 1:
// event.button = MouseEvent::Button::LEFT;
// break;
// case 2:
// event.button = MouseEvent::Button::RIGHT;
// break;
// default:
// event.button = MouseEvent::Button::MIDDLE;
// break;
// }
this->createMouseEventRELEASE(*emEvent, &event);
if (this->onPointerUp) { if (this->onPointerUp) {
dbp("onPointerUp(): numTouches=%d, timestamp=%d", emEvent->numTouches, emEvent->timestamp); // dbp("onPointerUp(): numTouches=%d, timestamp=%d", emEvent.numTouches, emEvent.timestamp);
this->onPointerUp(&event); this->onPointerUp(&releaseEvent, callbackParameter);
} }
this->clear(); this->clear();
} }
void onTouchCancel(const EmscriptenTouchEvent *emEvent) { void onTouchCancel(const EmscriptenTouchEvent& emEvent, void* callbackParameter) {
this->onTouchEnd(emEvent); this->onTouchEnd(emEvent, callbackParameter);
} }
}; };
@ -852,22 +734,26 @@ public:
WindowImplHtml *window = (WindowImplHtml *)data; WindowImplHtml *window = (WindowImplHtml *)data;
if (!initialized) { if (!initialized) {
touchEventHelper.onPointerDown = [window](MouseEvent* event) -> void { touchEventHelper.onPointerDown = [](MouseEvent* event, void* param) -> void {
WindowImplHtml* window = (WindowImplHtml*)param;
if (window->onMouseEvent) { if (window->onMouseEvent) {
window->onMouseEvent(*event); window->onMouseEvent(*event);
} }
}; };
touchEventHelper.onPointerMove = [window](MouseEvent* event) -> void { touchEventHelper.onPointerMove = [](MouseEvent* event, void* param) -> void {
WindowImplHtml* window = (WindowImplHtml*)param;
if (window->onMouseEvent) { if (window->onMouseEvent) {
window->onMouseEvent(*event); window->onMouseEvent(*event);
} }
}; };
touchEventHelper.onPointerUp = [window](MouseEvent* event) -> void { touchEventHelper.onPointerUp = [](MouseEvent* event, void* param) -> void {
WindowImplHtml* window = (WindowImplHtml*)param;
if (window->onMouseEvent) { if (window->onMouseEvent) {
window->onMouseEvent(*event); window->onMouseEvent(*event);
} }
}; };
touchEventHelper.onScroll = [window](MouseEvent* event) -> void { touchEventHelper.onScroll = [](MouseEvent* event, void* param) -> void {
WindowImplHtml* window = (WindowImplHtml*)param;
if (window->onMouseEvent) { if (window->onMouseEvent) {
window->onMouseEvent(*event); window->onMouseEvent(*event);
} }
@ -877,16 +763,16 @@ public:
switch(emEventType) { switch(emEventType) {
case EMSCRIPTEN_EVENT_TOUCHSTART: case EMSCRIPTEN_EVENT_TOUCHSTART:
touchEventHelper.onTouchStart(emEvent); touchEventHelper.onTouchStart(*emEvent, window);
break; break;
case EMSCRIPTEN_EVENT_TOUCHMOVE: case EMSCRIPTEN_EVENT_TOUCHMOVE:
touchEventHelper.onTouchMove(emEvent); touchEventHelper.onTouchMove(*emEvent, window);
break; break;
case EMSCRIPTEN_EVENT_TOUCHEND: case EMSCRIPTEN_EVENT_TOUCHEND:
touchEventHelper.onTouchEnd(emEvent); touchEventHelper.onTouchEnd(*emEvent, window);
break; break;
case EMSCRIPTEN_EVENT_TOUCHCANCEL: case EMSCRIPTEN_EVENT_TOUCHCANCEL:
touchEventHelper.onTouchCancel(emEvent); touchEventHelper.onTouchCancel(*emEvent, window);
break; break;
default: default:
return EM_FALSE; return EM_FALSE;