Isle
Loading...
Searching...
No Matches
mxdiskstreamcontroller.cpp
Go to the documentation of this file.
2
4#include "mxautolock.h"
7#include "mxmisc.h"
8#include "mxomni.h"
9#include "mxticklemanager.h"
10
11#include <assert.h>
12
14
15// FUNCTION: LEGO1 0x100c7120
17{
18 m_unk0x8c = 0;
19}
20
21// FUNCTION: LEGO1 0x100c7530
22// FUNCTION: BETA10 0x10153a2d
24{
26
27 m_unk0xc4 = FALSE;
28 m_unk0x70 = FALSE;
29
30 if (m_provider) {
31#ifdef COMPAT_MODE
32 {
33 MxDSAction action;
34 m_provider->VTable0x20(&action);
35 }
36#else
38#endif
39 }
40
41 assert(m_subscribers.size() == 0);
42
43 MxDSObject* object;
44 while (m_unk0x3c.PopFront(object)) {
45 delete object;
46 }
47
48 if (m_provider) {
49 delete m_provider;
51 }
52
53 FUN_100c8720();
54
55 while (m_list0x80.PopFront(object)) {
57 }
58
59 while (m_list0x64.PopFront(object)) {
61 }
62
63 while (!m_list0x74.empty()) {
64 MxDSBuffer* buffer = m_list0x74.front();
65 m_list0x74.pop_front();
66 FUN_100c7ce0(buffer);
67 }
68
70}
71
72// FUNCTION: LEGO1 0x100c7790
73// FUNCTION: BETA10 0x10153ea8
75{
77 MxResult result = MxStreamController::Open(p_filename);
78
79 if (result != SUCCESS) {
80 goto done;
81 }
82
84 if (m_provider == NULL) {
85 result = FAILURE;
86 goto done;
87 }
88
89 result = m_provider->SetResourceToGet(this);
90 if (result != SUCCESS) {
91 delete m_provider;
93 goto done;
94 }
95
96 TickleManager()->RegisterClient(this, 10);
97
98done:
99 return result;
100}
101
102// FUNCTION: LEGO1 0x100c7880
104{
105 return SUCCESS;
106}
107
108// FUNCTION: LEGO1 0x100c7890
109// FUNCTION: BETA10 0x101543bb
111{
113 if (p_action == NULL) {
114 return FAILURE;
115 }
116
117 m_list0x80.PushBack(p_action);
118 FUN_100c7970();
119 return SUCCESS;
120}
121
122// FUNCTION: LEGO1 0x100c7960
124{
125 return FAILURE;
126}
127
128// FUNCTION: LEGO1 0x100c7970
129void MxDiskStreamController::FUN_100c7970()
130{
131 // Empty
132}
133
134// FUNCTION: LEGO1 0x100c7980
135// FUNCTION: BETA10 0x10154848
136void MxDiskStreamController::FUN_100c7980()
137{
138 MxDSBuffer* buffer;
139 MxDSStreamingAction* action = NULL;
140
141 {
143
144 if (m_unk0x3c.size() && m_unk0x8c < m_provider->GetStreamBuffersNum()) {
145 buffer = new MxDSBuffer();
146
148 if (buffer) {
149 delete buffer;
150 }
151 return;
152 }
153
154 action = VTable0x28();
155 if (!action) {
156 if (buffer) {
157 delete buffer;
158 }
159 return;
160 }
161
162 action->SetUnknowna0(buffer);
163 m_unk0x8c++;
164 }
165 }
166
167 if (action) {
168 ((MxDiskStreamProvider*) m_provider)->FUN_100d1780(action);
169 }
170}
171
172// FUNCTION: LEGO1 0x100c7ac0
173// FUNCTION: BETA10 0x10154abb
175{
177 MxDSObject* oldAction;
178
179 assert(m_provider);
180 MxDSStreamingAction* request = NULL;
181 MxU32 filesize = m_provider->GetFileSize();
182
183 if (!m_unk0x3c.PopFront(oldAction)) {
184 goto done;
185 }
186
187 request = new MxDSStreamingAction((MxDSStreamingAction&) *oldAction);
188 assert(request);
189
190 if (!request) {
191 goto done;
192 }
193
194 ((MxDSStreamingAction*) oldAction)->SetUnknown94(request->GetBufferOffset() + filesize);
195 ((MxDSStreamingAction*) oldAction)->SetBufferOffset(((MxDSStreamingAction*) oldAction)->GetUnknown94());
196 m_unk0x3c.PushBack(oldAction);
197
198done:
199 return request;
200}
201
202// FUNCTION: LEGO1 0x100c7c00
204{
206 MxResult result = MxStreamController::VTable0x30(p_action);
207
209 while (TRUE) {
210 item = (MxDSStreamingAction*) m_list0x90.FindAndErase(p_action);
211 if (item == NULL) {
212 break;
213 }
214 FUN_100c7cb0(item);
215 }
216
217 while (TRUE) {
218 item = (MxDSStreamingAction*) m_list0x64.FindAndErase(p_action);
219 if (item == NULL) {
220 break;
221 }
222 FUN_100c7cb0(item);
223 }
224
225 return result;
226}
227
228// FUNCTION: LEGO1 0x100c7cb0
230{
231 if (p_action->GetUnknowna0()) {
232 FUN_100c7ce0(p_action->GetUnknowna0());
233 }
234 p_action->SetUnknowna0(NULL);
235 delete p_action;
236}
237
238// FUNCTION: LEGO1 0x100c7ce0
239void MxDiskStreamController::FUN_100c7ce0(MxDSBuffer* p_buffer)
240{
241 switch (p_buffer->GetMode()) {
243 m_unk0x8c--;
246 delete p_buffer;
247 break;
248 }
249}
250
251// FUNCTION: LEGO1 0x100c7d10
252MxResult MxDiskStreamController::FUN_100c7d10()
253{
255 MxDSStreamingAction* action = FUN_100c7db0();
256
257 if (!action) {
258 return FAILURE;
259 }
260
261 if (FUN_100c8360(action) != SUCCESS) {
262 VTable0x24(action);
263 FUN_100c7cb0(action);
264 return FAILURE;
265 }
266
267 return SUCCESS;
268}
269
270// FUNCTION: LEGO1 0x100c7db0
271// FUNCTION: BETA10 0x101551d0
272MxDSStreamingAction* MxDiskStreamController::FUN_100c7db0()
273{
275
276 for (MxNextActionDataStartList::iterator it = m_nextActionList.begin(); it != m_nextActionList.end(); it++) {
277 MxNextActionDataStart* data = *it;
278
279 for (MxDSObjectList::iterator it2 = m_list0x64.begin(); it2 != m_list0x64.end(); it2++) {
280 MxDSStreamingAction* streamingAction = (MxDSStreamingAction*) *it2;
281
282 if (streamingAction->GetObjectId() == data->GetObjectId() &&
283 streamingAction->GetUnknown24() == data->GetUnknown24() &&
284 streamingAction->GetBufferOffset() == data->GetData()) {
285 m_nextActionList.erase(it);
286
287 data->SetData(m_provider->GetFileSize() + data->GetData());
289
290 m_list0x64.erase(it2);
291 return streamingAction;
292 }
293 }
294 }
295
296 return NULL;
297}
298
299// FUNCTION: LEGO1 0x100c7f40
300// FUNCTION: BETA10 0x101553e0
302{
304 if (p_streamingaction) {
305 m_list0x64.PushBack(p_streamingaction);
306 }
307}
308
309// FUNCTION: LEGO1 0x100c7ff0
310// FUNCTION: BETA10 0x10155471
312{
314 MxDSStreamingAction* entry = (MxDSStreamingAction*) m_list0x80.Find(p_action); // TODO: is this a seperate class?
315
316 if (entry) {
317 MxDSStreamingAction* action = new MxDSStreamingAction(*p_action, 0);
318 action->SetUnknown28(entry->GetUnknown28());
319 action->SetUnknown84(entry->GetUnknown84());
320 action->SetOrigin(entry->GetOrigin());
321 action->SetUnknowna0(entry->GetUnknowna4());
322
323 FUN_100c7f40(action);
324
325 if (VTable0x2c(p_action, entry->GetUnknown94()) != SUCCESS) {
326 return FAILURE;
327 }
328 }
329 else if (MxStreamController::VTable0x20(p_action) != SUCCESS) {
330 return FAILURE;
331 }
332
333 m_unk0x70 = TRUE;
334 m_unk0xc4 = TRUE;
335 return SUCCESS;
336}
337
338// FUNCTION: LEGO1 0x100c8120
340{
341 VTable0x30(p_action);
342
343 if (m_provider) {
344 m_provider->VTable0x20(p_action);
345 }
346
347 while (TRUE) {
348 MxDSObject* found = m_unk0x54.FindAndErase(p_action);
349 if (!found) {
350 break;
351 }
352 delete found;
353 }
354}
355
356// FUNCTION: LEGO1 0x100c8160
358{
360 if (m_unk0x54.Find(p_action) == NULL) {
361 if (VTable0x30(p_action) == SUCCESS) {
364 );
365 }
366 }
367
368 MxDSAction action;
369 if (m_provider) {
370 m_provider->VTable0x20(p_action);
371 }
372
373 do {
374 if (m_action0x60 != NULL) {
375 delete m_action0x60;
377 }
378
379 action = *p_action;
381 } while (m_action0x60 != NULL);
382
383 if (m_unk0x3c.empty()) {
384 m_unk0x70 = FALSE;
385 m_unk0xc4 = FALSE;
386 }
387
388 return SUCCESS;
389}
390
391// FUNCTION: LEGO1 0x100c8360
392MxResult MxDiskStreamController::FUN_100c8360(MxDSStreamingAction* p_action)
393{
395 MxDSBuffer* buffer = p_action->GetUnknowna0();
396 MxDSStreamingAction* action2 = (MxDSStreamingAction*) m_list0x90.FindAndErase(p_action);
397 buffer->FUN_100c6f80(p_action->GetUnknown94() - p_action->GetBufferOffset());
398 buffer->FUN_100c67b0(this, p_action, &action2);
399
400 if (buffer->GetRefCount()) {
401 p_action->SetUnknowna0(NULL);
402 InsertToList74(buffer);
403 }
404
405 if (action2) {
406 if (action2->GetUnknowna0() == NULL) {
407 FUN_100c7cb0(action2);
408 }
409 else {
410 if (action2->GetObjectId() == -1) {
411 action2->SetObjectId(p_action->GetObjectId());
412 }
413
414 m_list0x90.PushBack(action2);
415 }
416 }
417
418 FUN_100c7cb0(p_action);
419 return SUCCESS;
420}
421
422// FUNCTION: LEGO1 0x100c84a0
424{
426 m_list0x74.push_back(p_buffer);
427}
428
429// FUNCTION: LEGO1 0x100c8540
430// FUNCTION: BETA10 0x10155a05
431void MxDiskStreamController::FUN_100c8540()
432{
434 for (list<MxDSBuffer*>::iterator it = m_list0x74.begin(); it != m_list0x74.end();) {
435 MxDSBuffer* buf = *it;
436 if (buf->GetRefCount() == 0) {
437 m_list0x74.erase(it++);
438 FUN_100c7ce0(buf);
439 }
440 else {
441 it++;
442 }
443 }
444
445 if (m_nextActionList.empty()) {
446 while (!m_list0x64.empty()) {
447 MxDSStreamingAction* action = (MxDSStreamingAction*) m_list0x64.front();
448 m_list0x64.pop_front();
449 FUN_100c7cb0(action);
450 }
451 }
452}
453
454// FUNCTION: LEGO1 0x100c8640
455// FUNCTION: BETA10 0x10155ba0
457{
458 if (m_unk0xc4) {
459 FUN_100c7d10();
460 }
461
462 FUN_100c8540();
463 FUN_100c8720();
464
465 if (m_unk0x70) {
466 FUN_100c7980();
467 }
468
469 return SUCCESS;
470}
471
472// FUNCTION: LEGO1 0x100c8670
474{
475 AUTOLOCK(m_critical9c);
476 m_list0xb8.push_back(p_streamingAction);
477}
478
479// FUNCTION: LEGO1 0x100c8720
480void MxDiskStreamController::FUN_100c8720()
481{
482 AUTOLOCK(m_critical9c);
483
484 MxDSStreamingAction* action;
485 while (!m_list0xb8.empty()) {
486 action = (MxDSStreamingAction*) m_list0xb8.front();
487 m_list0xb8.pop_front();
488 FUN_100c7cb0(action);
489 }
490}
[AI] Represents an action deserialized from SI chunks, holding key animation or script parameters suc...
Definition: mxdsaction.h:17
MxCore * GetUnknown84()
[AI] Returns a pointer to an associated or auxiliary core object.
Definition: mxdsaction.h:248
void SetOrigin(MxCore *p_origin)
[AI] Sets the origin core pointer for this action, if spatially transforming/localizing this action.
Definition: mxdsaction.h:265
void SetUnknown84(MxCore *p_unk0x84)
[AI] Sets the auxiliary core pointer for this action.
Definition: mxdsaction.h:254
MxCore * GetOrigin()
[AI] Returns a pointer to the "origin" core object, which may be used to localize the action.
Definition: mxdsaction.h:259
[AI] Buffer for managing streamed DS (Data Stream) chunks and actions.
Definition: mxdsbuffer.h:50
MxU16 GetRefCount()
[AI] Returns the current buffer reference count.
Type GetMode()
[AI] Returns the current buffer management mode.
MxResult AllocateBuffer(MxU32 p_bufferSize, Type p_mode)
[AI] Allocates a buffer of a given size and memory mode.
Definition: mxdsbuffer.cpp:60
void FUN_100c6f80(MxU32 p_writeOffset)
[AI] Sets the buffer's internal streaming position to the given write offset.
Definition: mxdsbuffer.cpp:450
MxResult FUN_100c67b0(MxStreamController *p_controller, MxDSAction *p_action, MxDSStreamingAction **p_streamingAction)
[AI] Executes streaming action startup and object creation loop from an initial SI chunk.
Definition: mxdsbuffer.cpp:102
@ e_allocate
[AI] Newly allocated memory with new[].
Definition: mxdsbuffer.h:57
@ e_chunk
[AI] Chunk-managed memory (from Streamer pool).
Definition: mxdsbuffer.h:56
@ e_unknown
[AI] Unknown/other (may be unused or special).
Definition: mxdsbuffer.h:59
MxDSObject * FindAndErase(MxDSObject *p_action)
[AI] Finds the matching object and removes it from the list.
Definition: mxdsobject.h:23
MxDSObject * Find(MxDSObject *p_action)
[AI] Finds a matching object in the list without removing it.
Definition: mxdsobject.h:28
[AI] Base class for any object deserialized from an SI (script/data) file in the LEGO Island engine.
Definition: mxdsobject.h:44
void SetUnknown28(MxPresenter *p_unk0x28)
[AI] Sets the pointer at 0x28 (presenter or handler).
Definition: mxdsobject.h:155
MxPresenter * GetUnknown28()
[AI] Returns the pointer stored at 0x28, likely a presenter or handler for this DS object.
Definition: mxdsobject.h:139
MxS16 GetUnknown24()
[AI] Returns the unknown 0x24 value (may be data version or usage state). [AI]
Definition: mxdsobject.h:136
void SetObjectId(MxU32 p_objectId)
[AI] Sets the object id (for serialization or lookup).
Definition: mxdsobject.h:147
MxU32 GetObjectId()
[AI] Returns the object id numeric value.
Definition: mxdsobject.h:130
[AI] Represents an action that streams data from a buffer within a DirectScript (DS) media timeline.
void SetUnknowna0(MxDSBuffer *p_unk0xa0)
[AI] Assigns a streaming buffer to this action (ownership rules apply).
MxDSBuffer * GetUnknowna0()
[AI] Returns a pointer to the first streaming buffer (possibly current read buffer).
MxU32 GetUnknown94()
[AI] Gets the streaming offset or status value at 0x94.
MxU32 GetBufferOffset()
[AI] Gets the buffer offset where streaming is currently positioned.
MxDSBuffer * GetUnknowna4()
[AI] Returns a pointer to the second streaming buffer (possibly for prefetch or double buffering).
[AI] Controller for streaming from disk-based SI resources, manages buffers and streaming actions.
virtual MxResult VTable0x34(undefined4)
[AI] Cleans up/aborts all queued streaming actions associated with the specified action.
~MxDiskStreamController() override
[AI] Destructor. Cleans up streaming actions, buffers, and provider. Unregisters from tickle manager.
void FUN_100c7f40(MxDSStreamingAction *p_streamingaction)
[AI] Adds a streaming action to m_list0x64 for processing.
MxResult VTable0x18(undefined4, undefined4) override
[AI] Opens the given resource file for streaming.
MxResult VTable0x30(MxDSAction *p_action) override
[AI] Pops a queued (ready) streaming action and prepares it for buffer assignment....
MxDiskStreamController()
[AI] Constructor. Initializes internal state and buffer counters.
void FUN_100c8120(MxDSAction *p_action)
[AI] Cleans up an action and all associated resources, notifies provider.
MxResult VTable0x24(MxDSAction *p_action) override
[AI] Start or queue the streaming action for the given action, potentially using buffer reuse and str...
void FUN_100c7cb0(MxDSStreamingAction *p_action)
[AI] Destroys the given streaming action and any associated buffers.
void FUN_100c8670(MxDSStreamingAction *p_streamingAction)
[AI] Pushes an action to a private list (m_list0xb8) for later cleanup.
MxResult Tickle() override
[AI] Called by tickle managers to allow the object to update itself.
MxResult Open(const char *p_filename) override
[AI] Opens a data stream with the specified resource filename.
MxResult VTable0x20(MxDSAction *p_action) override
[AI] Placeholder/overridden method—purpose unknown from context.
MxResult FUN_100c7890(MxDSStreamingAction *p_action)
[AI] Adds a streaming action to the list (m_list0x80) and possibly processes buffer allocation.
MxDSStreamingAction * VTable0x28() override
[AI] Marks an action as completed and cleans up associated resources.
void InsertToList74(MxDSBuffer *p_buffer)
[AI] Inserts a buffer to the buffer reuse list (m_list0x74).
[AI] Disk-based stream provider for resource loading using background streaming and multithreading.
[AI] Notification parameter marking the end of an action, specialization of MxActionNotificationParam...
[AI] Contains data for scheduling the next action in a process, storing an object id,...
MxS16 GetUnknown24() const
[AI] Gets the unknown parameter or code for the action (purpose unclear in decompilation output).
MxU32 GetObjectId() const
[AI] Gets the identifier for the object the action applies to.
MxU32 GetData() const
[AI] Retrieves the extra data associated with the action dispatch.
void SetData(MxU32 p_data)
[AI] Sets the data value for this action instance.
static MxOmni * GetInstance()
[AI] Returns the singleton instance of the MxOmni subsystem coordinator.
Definition: mxomni.cpp:289
virtual void NotifyCurrentEntity(const MxNotificationParam &p_param)
[AI] [VIRTUAL BASE] Placeholder for derived implementations—sends a notification to the currently act...
Definition: mxomni.cpp:46
virtual MxResult VTable0x24(MxDSAction *p_action)
[AI] Matches and processes an action in the "unk0x54" (pending) list and triggers sending to subscrib...
MxDSSubscriberList m_subscribers
[AI] List of current subscribers (listening entities for streamed data).
MxCriticalSection m_criticalSection
[AI] Protects streaming controller state for thread-safety.
virtual MxResult VTable0x20(MxDSAction *p_action)
[AI] Streams data for the provided action by determining data offset and reading required chunk.
MxNextActionDataStartList m_nextActionList
[AI] List mapping from streamed object/action to starting offset (used for internal tracking).
MxDSObjectList m_unk0x3c
[AI] List of actions currently being processed/streamed ("in progress" actions).
MxDSAction * m_action0x60
[AI] Current action pointer used during processing, moved from pending to active as actions are proce...
virtual MxResult Open(const char *p_filename)
[AI] Opens a data stream with the specified resource filename.
MxStreamProvider * m_provider
[AI] Stream provider abstraction, handling resource IO (RAM/disk).
MxDSObjectList m_unk0x54
[AI] List of actions queued and ready to be streamed ("pending" actions).
virtual MxResult VTable0x30(MxDSAction *p_action)
[AI] Removes a completed action from in-progress ("unk0x3c") list and deletes its data block.
virtual MxResult VTable0x2c(MxDSAction *p_action, MxU32 p_bufferval)
[AI] Handles allocation and setup of a new streaming action and associated chunk for the action,...
virtual MxU32 GetFileSize()=0
[AI] Gets the file size, in bytes, of the underlying SI file resource.
virtual MxResult SetResourceToGet(MxStreamController *p_pLookup)
[AI] Attaches a stream controller as the resource to provide data for.
virtual void VTable0x20(MxDSAction *p_action)
[AI] Virtual hook for subclasses to react to new stream actions being queued.
virtual void UnregisterClient(MxCore *p_client)
[AI] Unregisters (marks for destruction) a previously registered client.
virtual void RegisterClient(MxCore *p_client, MxTime p_interval)
[AI] Registers an MxCore object to receive periodic tickles.
void PushBack(T p_obj)
[AI] Pushes a copy of the provided object to the back of the list.
Definition: mxutilitylist.h:38
MxBool PopFront(T &p_obj)
[AI] Removes and returns the first element of the list.
Definition: mxutilitylist.h:22
#define TRUE
Definition: d3drmdef.h:28
#define FALSE
Definition: d3drmdef.h:27
#define DECOMP_SIZE_ASSERT(T, S)
Definition: decomp.h:19
unsigned int undefined4
Definition: decomp.h:28
#define NULL
[AI] Null pointer value (C/C++ semantics).
Definition: legotypes.h:26
#define FAILURE
[AI] Used to indicate a failed operation in result codes.
Definition: legotypes.h:34
#define SUCCESS
[AI] Used to indicate a successful operation in result codes.
Definition: legotypes.h:30
#define AUTOLOCK(CS)
[AI] Macro for automatic locking using the MxAutoLock class. This macro instantiates an MxAutoLock ob...
Definition: mxautolock.h:5
MxTickleManager * TickleManager()
[AI] Provides access to the global tickle manager.
Definition: mxmisc.cpp:25
@ c_notificationEndAction
[AI] Indicates the end of an action [AI]
MxLong MxResult
[AI]
Definition: mxtypes.h:106
unsigned int MxU32
[AI]
Definition: mxtypes.h:32