feat(core): add StormDestroy stub

This commit is contained in:
Adam Heinermann 2025-10-03 00:46:08 -07:00 committed by fallenoak
parent 982a89b6da
commit 02f5e26f36
14 changed files with 160 additions and 64 deletions

27
storm/Core.cpp Normal file
View file

@ -0,0 +1,27 @@
#include "Core.hpp"
#include "Event.hpp"
int32_t STORMAPI StormDestroy() {
// Combined list of all calls from every game
// SErrSetBlizzardErrorFunction(nullptr);
// SDlgDestroy();
// SGdiDestroy();
// SVidDestroy();
// SDrawDestroy();
// SRgnDestroy();
// SMsgDestroy();
// SNetDestroy();
SEvtDestroy();
// SBltDestroy();
// SCodeDestroy();
// SCmdDestroy();
// SFileDestroy();
// SCompDestroy();
// SStrDestroy();
// SRegDestroy();
// SErrDestroy();
// SLogDestroy();
// STransDestroy();
return 1;
}

View file

@ -13,5 +13,6 @@
#endif #endif
#endif #endif
int32_t STORMAPI StormDestroy();
#endif #endif

View file

@ -1,5 +1,4 @@
#include "storm/Big.hpp" #include "BigTest.hpp"
#include "test/Test.hpp"
#include <string> #include <string>
TEST_CASE("SBigAdd", "[big]") { TEST_CASE("SBigAdd", "[big]") {

18
test/BigTest.hpp Normal file
View file

@ -0,0 +1,18 @@
#include "Test.hpp"
#include "storm/Big.hpp"
class BigData;
// Fixture for repetitive handling of BigData objects.
struct BigDataTest {
using BigDataPtr = BigData*;
BigData* num;
BigDataTest() { SBigNew(&num); }
~BigDataTest() { SBigDel(num); }
BigData** operator &() { return &num; }
operator BigDataPtr() const { return num; }
BigData* operator->() const { return num; }
};

View file

@ -2,7 +2,9 @@
if(WHOA_TEST_STORMDLL) if(WHOA_TEST_STORMDLL)
set(TEST_SOURCES set(TEST_SOURCES
#Big.cpp #Big.cpp
#Event.cpp Core.cpp
Event.cpp
EventTest.cpp
Memory.cpp Memory.cpp
Region.cpp Region.cpp
String.cpp String.cpp

40
test/Core.cpp Normal file
View file

@ -0,0 +1,40 @@
#include "test/Test.hpp"
#include "EventTest.hpp"
#include "storm/Core.hpp"
TEST_CASE("StormDestroy", "[core]") {
SECTION("always returns 1") {
CHECK(StormDestroy() == 1);
}
SECTION("SEvt") {
EventHandlerTest test;
SECTION("destroys all event handlers") {
SEvtRegisterHandler(1, 1, 1, 0, &TestEventHandler1);
CHECK(SEvtDispatch(1, 1, 1, nullptr) == 1);
CHECK(test.NumCalls() == 1);
CHECK(SEvtDispatch(1, 1, 1, nullptr) == 1);
CHECK(test.NumCalls() == 2);
CHECK(StormDestroy() == 1);
// Can't increment calls since the handler was destroyed
CHECK(SEvtDispatch(1, 1, 1, nullptr) == 0);
CHECK(test.NumCalls() == 2);
}
SECTION("doesn't destroy break data") {
// not ideal but it's official behaviour
SEvtBreakHandlerChain(nullptr);
CHECK(StormDestroy() == 1);
SEvtRegisterHandler(0, 0, 0, 0, &TestEventHandler1);
CHECK(SEvtDispatch(0, 0, 0, nullptr) == 0);
CHECK(SEvtDispatch(0, 0, 0, nullptr) == 1);
}
}
}

View file

@ -10,8 +10,7 @@ static void STORMAPI TestBreakEventHandlerSelf(void* data) {
static void STORMAPI TestBreakEventHandlerOther(void* data) { static void STORMAPI TestBreakEventHandlerOther(void* data) {
EventHandlerTest::RegisterCall(10, data); EventHandlerTest::RegisterCall(10, data);
int bunk = 0; CHECK(SEvtBreakHandlerChain(nullptr) == 1);
CHECK(SEvtBreakHandlerChain(&bunk) == 1);
} }
TEST_CASE("SEvtBreakHandlerChain", "[event]") { TEST_CASE("SEvtBreakHandlerChain", "[event]") {
@ -22,6 +21,7 @@ TEST_CASE("SEvtBreakHandlerChain", "[event]") {
SEvtRegisterHandler(7357, 1, 0, 0, &TestEventHandler1); SEvtRegisterHandler(7357, 1, 0, 0, &TestEventHandler1);
CHECK(SEvtDispatch(7357, 1, 0, nullptr) == 0); CHECK(SEvtDispatch(7357, 1, 0, nullptr) == 0);
CHECK(SEvtDispatch(7357, 1, 0, nullptr) == 1);
} }
SECTION("causes SEvtDispatch to break early if one of many data matches") { SECTION("causes SEvtDispatch to break early if one of many data matches") {
@ -34,6 +34,11 @@ TEST_CASE("SEvtBreakHandlerChain", "[event]") {
SEvtRegisterHandler(7357, 1, 0, 0, &TestEventHandler1); SEvtRegisterHandler(7357, 1, 0, 0, &TestEventHandler1);
CHECK(SEvtDispatch(7357, 1, 0, &data2) == 0); CHECK(SEvtDispatch(7357, 1, 0, &data2) == 0);
// CLEANUP - SEvtDestroy doesn't erase registered breaks, avoid polluting other tests
CHECK(SEvtDispatch(7357, 1, 0, nullptr) == 0);
CHECK(SEvtDispatch(7357, 1, 0, &data1) == 0);
CHECK(SEvtDispatch(7357, 1, 0, &data3) == 0);
} }
SECTION("doesn't break SEvtDispatch if no data matches") { SECTION("doesn't break SEvtDispatch if no data matches") {
@ -46,6 +51,12 @@ TEST_CASE("SEvtBreakHandlerChain", "[event]") {
SEvtRegisterHandler(7357, 1, 0, 0, &TestEventHandler1); SEvtRegisterHandler(7357, 1, 0, 0, &TestEventHandler1);
CHECK(SEvtDispatch(7357, 1, 0, &test) == 1); CHECK(SEvtDispatch(7357, 1, 0, &test) == 1);
// CLEANUP - SEvtDestroy doesn't erase registered breaks, avoid polluting other tests
CHECK(SEvtDispatch(7357, 1, 0, nullptr) == 0);
CHECK(SEvtDispatch(7357, 1, 0, &data1) == 0);
CHECK(SEvtDispatch(7357, 1, 0, &data2) == 0);
CHECK(SEvtDispatch(7357, 1, 0, &data3) == 0);
} }
SECTION("deduplicates multiple same-data breaks") { SECTION("deduplicates multiple same-data breaks") {
@ -75,15 +86,20 @@ TEST_CASE("SEvtBreakHandlerChain", "[event]") {
SEvtRegisterHandler(0, 0, 0, 0, &TestBreakEventHandlerOther); SEvtRegisterHandler(0, 0, 0, 0, &TestBreakEventHandlerOther);
SEvtRegisterHandler(0, 0, 0, 0, &TestEventHandler2); SEvtRegisterHandler(0, 0, 0, 0, &TestEventHandler2);
CHECK(SEvtDispatch(0, 0, 0, nullptr) == 1); int data = 42;
CHECK(SEvtDispatch(0, 0, 0, &data) == 1);
CHECK(test.NumCalls() == 3); CHECK(test.NumCalls() == 3);
// Calls are reverse order, TestEventHandler1 doesn't get called // Calls are reverse order, TestEventHandler1 doesn't get called
CHECK_THAT(test.CallResult(), MatchesCall({ 2, nullptr })); CHECK_THAT(test.CallResult(), MatchesCall({ 2, &data }));
CHECK_THAT(test.CallResult(), MatchesCall({ 10, nullptr })); CHECK_THAT(test.CallResult(), MatchesCall({ 10, &data }));
CHECK_THAT(test.CallResult(), MatchesCall({ 1, nullptr })); CHECK_THAT(test.CallResult(), MatchesCall({ 1, &data }));
// CLEANUP - SEvtDestroy doesn't erase registered breaks, avoid polluting other tests
CHECK(SEvtDispatch(0, 0, 0, nullptr) == 0);
} }
} }
#if !defined(WHOA_TEST_STORMDLL)
TEST_CASE("SEvtDestroy", "[event]") { TEST_CASE("SEvtDestroy", "[event]") {
EventHandlerTest test; EventHandlerTest test;
@ -117,6 +133,7 @@ TEST_CASE("SEvtDestroy", "[event]") {
CHECK(SEvtDispatch(0, 0, 0, nullptr) == 1); CHECK(SEvtDispatch(0, 0, 0, nullptr) == 1);
} }
} }
#endif
static void STORMAPI TestNestedDispatchEventHandler(void* data) { static void STORMAPI TestNestedDispatchEventHandler(void* data) {
EventHandlerTest::RegisterCall(20, data); EventHandlerTest::RegisterCall(20, data);

29
test/EventTest.cpp Normal file
View file

@ -0,0 +1,29 @@
#include "EventTest.hpp"
std::deque<EventHandlerCalledWith> EventHandlerCallResults;
void STORMAPI TestEventHandler1(void* data) {
EventHandlerTest::RegisterCall(1, data);
}
void STORMAPI TestEventHandler2(void* data) {
EventHandlerTest::RegisterCall(2, data);
}
void STORMAPI TestEventHandler3(void* data) {
EventHandlerTest::RegisterCall(3, data);
}
void STORMAPI TestEventHandler4(void* data) {
EventHandlerTest::RegisterCall(4, data);
}
std::ostream& operator <<(std::ostream& os, EventHandlerCalledWith const& value) {
os << "{ TestEventHandler" << value.handler << ", " << value.data << " }";
return os;
}
EventHandlerCalledWithMatcher<EventHandlerCalledWith> MatchesCall(EventHandlerCalledWith arg) {
return { arg };
}

View file

@ -1,25 +1,22 @@
#include "test/Test.hpp" #include "test/Test.hpp"
#include "storm/Core.hpp"
#include "storm/Event.hpp" #include "storm/Event.hpp"
#include <deque> #include <deque>
#include <sstream> #include <sstream>
void SEvtCleanExtraDataForTests();
struct EventHandlerCalledWith { struct EventHandlerCalledWith {
int handler; int handler;
void* data; void* data;
}; };
static std::deque<EventHandlerCalledWith> EventHandlerCallResults; extern std::deque<EventHandlerCalledWith> EventHandlerCallResults;
struct EventHandlerTest { struct EventHandlerTest {
EventHandlerTest() { EventHandlerTest() {
EventHandlerCallResults.clear(); EventHandlerCallResults.clear();
SEvtDestroy(); StormDestroy();
SEvtCleanExtraDataForTests();
} }
static void RegisterCall(int handler, void* data) { static void RegisterCall(int handler, void* data) {
@ -43,28 +40,14 @@ struct EventHandlerTest {
}; };
static void STORMAPI TestEventHandler1(void* data) { void STORMAPI TestEventHandler1(void* data);
EventHandlerTest::RegisterCall(1, data); void STORMAPI TestEventHandler2(void* data);
} void STORMAPI TestEventHandler3(void* data);
void STORMAPI TestEventHandler4(void* data);
static void STORMAPI TestEventHandler2(void* data) {
EventHandlerTest::RegisterCall(2, data);
}
static void STORMAPI TestEventHandler3(void* data) {
EventHandlerTest::RegisterCall(3, data);
}
static void STORMAPI TestEventHandler4(void* data) {
EventHandlerTest::RegisterCall(4, data);
}
// Helpers for comparing EventHandlerCalledWith structs // Helpers for comparing EventHandlerCalledWith structs
std::ostream& operator <<(std::ostream& os, EventHandlerCalledWith const& value) { std::ostream& operator <<(std::ostream& os, EventHandlerCalledWith const& value);
os << "{ TestEventHandler" << value.handler << ", " << value.data << " }";
return os;
}
template <class T> template <class T>
class EventHandlerCalledWithMatcher : public Catch::MatcherBase<T> { class EventHandlerCalledWithMatcher : public Catch::MatcherBase<T> {
@ -85,6 +68,4 @@ public:
} }
}; };
EventHandlerCalledWithMatcher<EventHandlerCalledWith> MatchesCall(EventHandlerCalledWith arg) { EventHandlerCalledWithMatcher<EventHandlerCalledWith> MatchesCall(EventHandlerCalledWith arg);
return { arg };
}

View file

@ -1,6 +1,2 @@
#define CATCH_CONFIG_MAIN #define CATCH_CONFIG_MAIN
#include "test/Test.hpp" #include "test/Test.hpp"
#include "storm/Big.hpp"
BigDataTest::BigDataTest() { SBigNew(&num); }
BigDataTest::~BigDataTest() { SBigDel(num); }

View file

@ -1,17 +1 @@
#include "vendor/catch-2.13.10/catch.hpp" #include "vendor/catch-2.13.10/catch.hpp"
class BigData;
// Fixture for repetitive handling of BigData objects.
struct BigDataTest {
using BigDataPtr = BigData*;
BigData* num;
BigDataTest();
~BigDataTest();
BigData** operator &() { return &num; }
operator BigDataPtr() const { return num; }
BigData* operator->() const { return num; }
};

View file

@ -1,6 +1,5 @@
#include "storm/Big.hpp" #include "test/BigTest.hpp"
#include "storm/big/Ops.hpp" #include "storm/big/Ops.hpp"
#include "test/Test.hpp"
#include <vector> #include <vector>
TEST_CASE("Add", "[big]") { TEST_CASE("Add", "[big]") {

View file

@ -128,7 +128,7 @@ EXPORTS
; Main ; Main
; This is the only *Destroy function exported, tests will need to use it instead ; This is the only *Destroy function exported, tests will need to use it instead
;StormDestroy @301 NONAME StormDestroy @301 NONAME
;StormGetInstance @302 NONAME ;StormGetInstance @302 NONAME
;StormGetOption @303 NONAME ;StormGetOption @303 NONAME
;StormSetOption @304 NONAME ;StormSetOption @304 NONAME
@ -176,7 +176,7 @@ EXPORTS
;SDrawUpdatePalette @357 NONAME ;SDrawUpdatePalette @357 NONAME
;SDrawUpdateScreen @358 NONAME ;SDrawUpdateScreen @358 NONAME
;SDrawWaitForVerticalBlank @359 NONAME ;SDrawWaitForVerticalBlank @359 NONAME
; Event ; Event
;SEvtDestroy @371 NONAME ;SEvtDestroy @371 NONAME
SEvtDispatch @372 NONAME SEvtDispatch @372 NONAME

View file

@ -1,3 +1,7 @@
#include <storm/Core.hpp>
int32_t STORMAPI StormDestroy() { return 0; }
#include <storm/Big.hpp> #include <storm/Big.hpp>
void STORMAPI SBigAdd(BigData*, BigData*, BigData*) {} void STORMAPI SBigAdd(BigData*, BigData*, BigData*) {}
@ -40,7 +44,6 @@ void STORMAPI SErrSetLastError(uint32_t) {}
uint32_t STORMAPI SErrGetLastError() { return 0; } uint32_t STORMAPI SErrGetLastError() { return 0; }
void STORMAPI SErrSuppressErrors(uint32_t) {} void STORMAPI SErrSuppressErrors(uint32_t) {}
#include <storm/Event.hpp> #include <storm/Event.hpp>
int32_t STORMAPI SEvtBreakHandlerChain(void*) { return 0; } int32_t STORMAPI SEvtBreakHandlerChain(void*) { return 0; }