Skip to content

Commit 6848c90

Browse files
committed
[[ Engine ]] Add 'attachment' abstraction to MCStack to allow objects to register for interest in window-related events.
1 parent 4cd5dbc commit 6848c90

File tree

6 files changed

+139
-0
lines changed

6 files changed

+139
-0
lines changed

engine/src/dispatch.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1703,6 +1703,28 @@ MCStack *MCDispatch::findstackid(uint4 fid)
17031703
return NULL;
17041704
}
17051705

1706+
bool MCDispatch::foreachstack(MCStackForEachCallback p_callback, void *p_context)
1707+
{
1708+
bool t_continue;
1709+
t_continue = true;
1710+
1711+
if (stacks)
1712+
{
1713+
MCStack *t_stack;
1714+
t_stack = stacks;
1715+
1716+
do
1717+
{
1718+
t_continue = t_stack->foreachstack(p_callback, p_context);
1719+
1720+
t_stack = (MCStack*)t_stack->next();
1721+
}
1722+
while (t_continue && t_stack != stacks);
1723+
}
1724+
1725+
return t_continue;
1726+
}
1727+
17061728
bool MCDispatch::foreachchildstack(MCStack *p_stack, MCStackForEachCallback p_callback, void *p_context)
17071729
{
17081730
bool t_continue;

engine/src/dispatch.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,8 @@ class MCDispatch : public MCObject
210210

211211
// IM-2014-07-23: [[ Bug 12930 ]] Replace findchildstack method with iterating method
212212
bool foreachchildstack(MCStack *p_stack, MCStackForEachCallback p_callback, void *p_context);
213+
214+
bool foreachstack(MCStackForEachCallback p_callback, void *p_context);
213215

214216
MCObject *getobjid(Chunk_term type, uint4 inid);
215217
MCObject *getobjname(Chunk_term type, MCNameRef);

engine/src/stack.cpp

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,8 @@ MCStack::MCStack()
293293
cursoroverride = false ;
294294
old_rect.x = old_rect.y = old_rect.width = old_rect.height = 0 ;
295295

296+
m_attachments = nil;
297+
296298
view_init();
297299
}
298300

@@ -489,6 +491,8 @@ MCStack::MCStack(const MCStack &sref) : MCObject(sref)
489491
m_view_need_redraw = sref.m_view_need_redraw;
490492
m_view_need_resize = sref.m_view_need_resize;
491493

494+
m_attachments = nil;
495+
492496
view_copy(sref);
493497
}
494498

@@ -2890,6 +2894,8 @@ Boolean MCStack::del()
28902894
if (cards != NULL)
28912895
cards->message(MCM_delete_stack);
28922896

2897+
notifyattachments(kMCStackAttachmentEventDeleting);
2898+
28932899
if (MCdispatcher->ismainstack(this))
28942900
{
28952901
MCdispatcher->removestack(this);
@@ -3049,6 +3055,8 @@ void MCStack::recompute()
30493055

30503056
void MCStack::loadexternals(void)
30513057
{
3058+
notifyattachments(kMCStackAttachmentEventRealizing);
3059+
30523060
if (MCStringIsEmpty(externalfiles) || m_externals != NULL || !MCSecureModeCanAccessExternal())
30533061
return;
30543062

@@ -3076,6 +3084,8 @@ void MCStack::loadexternals(void)
30763084

30773085
void MCStack::unloadexternals(void)
30783086
{
3087+
notifyattachments(kMCStackAttachmentEventUnrealizing);
3088+
30793089
if (m_externals == NULL)
30803090
return;
30813091

@@ -3391,3 +3401,54 @@ void MCStack::setasscriptonly(MCStringRef p_script)
33913401
cards->setparent(this);
33923402
}
33933403
}
3404+
3405+
//////////
3406+
3407+
bool MCStack::attach(void *p_context, MCStackAttachmentCallback p_callback)
3408+
{
3409+
MCStackAttachment *t_attachment;
3410+
for(t_attachment = m_attachments; t_attachment != nil; t_attachment = t_attachment -> next)
3411+
if (t_attachment -> context == p_context && t_attachment -> callback == p_callback)
3412+
return true;
3413+
3414+
if (!MCMemoryNew(t_attachment))
3415+
return false;
3416+
3417+
t_attachment -> next = m_attachments;
3418+
t_attachment -> context = p_context;
3419+
t_attachment -> callback = p_callback;
3420+
m_attachments = t_attachment;
3421+
3422+
// If we are already realized, then notify.
3423+
if (window != nil)
3424+
p_callback(p_context, this, kMCStackAttachmentEventRealizing);
3425+
3426+
return true;
3427+
}
3428+
3429+
void MCStack::detach(void *p_context, MCStackAttachmentCallback p_callback)
3430+
{
3431+
MCStackAttachment *t_attachment, *t_previous;
3432+
for(t_previous = nil, t_attachment = m_attachments; t_attachment != nil; t_attachment = t_attachment -> next)
3433+
{
3434+
if (t_attachment -> context == p_context && t_attachment -> callback == p_callback)
3435+
break;
3436+
t_previous = t_attachment;
3437+
}
3438+
3439+
if (t_attachment == nil)
3440+
return;
3441+
3442+
if (t_previous != nil)
3443+
t_previous -> next = t_attachment -> next;
3444+
else
3445+
m_attachments = t_attachment -> next;
3446+
3447+
MCMemoryDelete(t_attachment);
3448+
}
3449+
3450+
void MCStack::notifyattachments(MCStackAttachmentEvent p_event)
3451+
{
3452+
for(MCStackAttachment *t_attachment = m_attachments; t_attachment != nil; t_attachment = t_attachment -> next)
3453+
t_attachment -> callback(t_attachment -> context, this, p_event);
3454+
}

engine/src/stack.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,21 @@ typedef bool (*MCStackUpdateCallback)(MCStackSurface *p_surface, MCRegionRef p_r
131131

132132
typedef bool (*MCStackForEachCallback)(MCStack *p_stack, void *p_context);
133133

134+
enum MCStackAttachmentEvent
135+
{
136+
kMCStackAttachmentEventDeleting,
137+
kMCStackAttachmentEventRealizing,
138+
kMCStackAttachmentEventUnrealizing,
139+
kMCStackAttachmentEventToolChanged,
140+
};
141+
typedef void (*MCStackAttachmentCallback)(void *context, MCStack *stack, MCStackAttachmentEvent event);
142+
struct MCStackAttachment
143+
{
144+
MCStackAttachment *next;
145+
void *context;
146+
MCStackAttachmentCallback callback;
147+
};
148+
134149
class MCStack : public MCObject
135150
{
136151
friend class MCHcstak;
@@ -271,6 +286,8 @@ class MCStack : public MCObject
271286
// IM-2014-05-27: [[ Bug 12321 ]] Indicate if we need to purge fonts when reopening the window
272287
bool m_purge_fonts;
273288

289+
MCStackAttachment *m_attachments;
290+
274291
public:
275292
Boolean menuwindow;
276293

@@ -609,6 +626,7 @@ class MCStack : public MCObject
609626

610627
Window getwindow();
611628
Window getparentwindow();
629+
Window getwindowalways() { return window; }
612630

613631
// IM-2014-07-23: [[ Bug 12930 ]] Set the stack whose window is parent to this stack
614632
void setparentstack(MCStack *p_parent);
@@ -819,6 +837,8 @@ class MCStack : public MCObject
819837

820838
// IM-2014-07-23: [[ Bug 12930 ]] Replace findchildstack method with iterating method
821839
bool foreachchildstack(MCStackForEachCallback p_callback, void *p_context);
840+
841+
bool foreachstack(MCStackForEachCallback p_callback, void *p_context);
822842

823843
void realize();
824844
void sethints();
@@ -995,6 +1015,10 @@ class MCStack : public MCObject
9951015
void enablewindow(bool p_enable);
9961016
bool haswindow(void);
9971017

1018+
bool attach(void *ctxt, MCStackAttachmentCallback callback);
1019+
void detach(void *ctxt, MCStackAttachmentCallback callback);
1020+
void notifyattachments(MCStackAttachmentEvent event);
1021+
9981022
void mode_openasmenu(MCStack *grab);
9991023
void mode_closeasmenu(void);
10001024

engine/src/stack2.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3326,6 +3326,28 @@ MCRectangle MCStack::getvisiblerect(void)
33263326

33273327
////////////////////////////////////////////////////////////////////////////////
33283328

3329+
bool MCStack::foreachstack(MCStackForEachCallback p_callback, void *p_context)
3330+
{
3331+
if (!p_callback(this, p_context))
3332+
return false;
3333+
3334+
bool t_continue;
3335+
t_continue = true;
3336+
3337+
if (substacks != NULL)
3338+
{
3339+
MCStack *t_stack = substacks;
3340+
do
3341+
{
3342+
t_continue = p_callback(t_stack, p_context);
3343+
t_stack = (MCStack *)t_stack->next();
3344+
}
3345+
while (t_continue && t_stack != substacks);
3346+
}
3347+
3348+
return t_continue;
3349+
}
3350+
33293351
bool MCStack::foreachchildstack(MCStackForEachCallback p_callback, void *p_context)
33303352
{
33313353
bool t_continue;

engine/src/util.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2002,6 +2002,12 @@ void MCU_getshift(uint4 mask, uint2 &shift, uint2 &outmask)
20022002
outmask = j;
20032003
}
20042004

2005+
static bool _MCStackNotifyToolChange(MCStack *p_stack, void *p_context)
2006+
{
2007+
p_stack -> notifyattachments(kMCStackAttachmentEventToolChanged);
2008+
return true;
2009+
}
2010+
20052011
void MCU_choose_tool(MCExecContext& ctxt, MCStringRef p_input, Tool p_tool)
20062012
{
20072013
Tool t_new_tool;
@@ -2061,6 +2067,8 @@ void MCU_choose_tool(MCExecContext& ctxt, MCStringRef p_input, Tool p_tool)
20612067
for(MCPlayer *t_player = MCplayers; t_player != NULL; t_player = t_player -> getnextplayer())
20622068
t_player -> syncbuffering(nil);
20632069

2070+
MCdispatcher -> foreachstack(_MCStackNotifyToolChange, nil);
2071+
20642072
ctxt . GetObject()->message_with_valueref_args(MCM_new_tool, *t_tool_name);
20652073
}
20662074

0 commit comments

Comments
 (0)