|
9 | 9 | // Kinda a silly way to keep track of this, but it works |
10 | 10 | // and I'm lazy |
11 | 11 | static std::vector<int *> vphysEnvironments; |
12 | | -static std::vector<int *> vphysEnvironmentsLast; |
| 12 | +static bool lastWasFast = false; |
13 | 13 |
|
14 | 14 | // INFRA memory leak |
15 | 15 | // The game has a "fast load" feature that skips a bunch of stuff, including |
16 | 16 | // destroying the old physics environment. This leaks ~4MB (one env) per load. |
17 | | -// Slow loads destroy the two environments that are in use, and create a new |
18 | | -// two. We detect this and destroy the old environments that are no longer in |
19 | | -// use. There are other leaks, but this is the most significant. |
| 17 | +// There are other leaks, but this is the most significant. |
20 | 18 | ON_EVENT(SESSION_START) { |
21 | 19 | if (!sar.game->Is(SourceGame_INFRA)) return; |
22 | | - vphysEnvironmentsLast = vphysEnvironments; |
23 | 20 | vphysEnvironments = {}; |
24 | 21 | for (int i = 0; ; ++i) { |
25 | 22 | int *env = vphysics->GetActivePhysicsEnvironmentByIndex(i); |
26 | 23 | if (!env) break; |
27 | 24 | vphysEnvironments.push_back(env); |
28 | 25 | } |
29 | 26 |
|
30 | | - // console->Print("%d active physics environment(s)\n", (int)vphysEnvironments.size()); |
31 | | - // int i = 0; |
32 | | - // for (const auto &env : vphysEnvironmentsLast) { |
33 | | - // if (std::find(vphysEnvironments.begin(), vphysEnvironments.end(), env) == vphysEnvironments.end()) { |
34 | | - // console->ColorMsg(Color(255,96,64), "- %d %p\n", i, env); |
35 | | - // } |
36 | | - // i++; |
37 | | - // } |
38 | | - // i = 0; |
39 | | - // for (const auto &env : vphysEnvironments) { |
40 | | - // if (std::find(vphysEnvironmentsLast.begin(), vphysEnvironmentsLast.end(), env) == vphysEnvironmentsLast.end()) { |
41 | | - // console->ColorMsg(Color(96,255,64), "+ %d %p\n", i, env); |
42 | | - // } else { |
43 | | - // console->Print(" %d %p\n", i, env); |
44 | | - // } |
45 | | - // i++; |
46 | | - // } |
47 | | - |
48 | | - int newEnvs = 0; |
49 | | - for (const auto &env : vphysEnvironments) { |
50 | | - if (std::find(vphysEnvironmentsLast.begin(), vphysEnvironmentsLast.end(), env) == vphysEnvironmentsLast.end()) { |
51 | | - newEnvs++; |
52 | | - } |
53 | | - } |
54 | | - if (newEnvs == 2) { |
55 | | - for (const auto &env : vphysEnvironments) { |
56 | | - if (std::find(vphysEnvironmentsLast.begin(), vphysEnvironmentsLast.end(), env) != vphysEnvironmentsLast.end()) { |
57 | | - vphysics->DestroyPhysicsEnvironment(env); |
58 | | - } |
59 | | - } |
| 27 | + switch (vphysEnvironments.size()) { |
| 28 | + default: |
| 29 | + lastWasFast = false; |
| 30 | + break; |
| 31 | + case 3: |
| 32 | + // Fast load, destroy one unused environment |
| 33 | + // The first env is unused, and the second one persists through |
| 34 | + // fast load(s). That means on the first fast load we'll destroy |
| 35 | + // the first environment, and subsequent fast loads we'll destroy |
| 36 | + // the second environment. (since it's now using the first one) |
| 37 | + int *env = vphysEnvironments[lastWasFast ? 1 : 0]; |
| 38 | + vphysics->DestroyPhysicsEnvironment(env); |
| 39 | + lastWasFast = true; |
| 40 | + break; |
60 | 41 | } |
61 | 42 | } |
62 | 43 |
|
|
0 commit comments