Пример #1
0
static void remove_object_listener_target_from_list(MCObjectListenerTarget *&p_target, MCObjectListenerTarget *p_prev_target, MCObjectListener* &p_listener, MCObjectListener* p_prev_listener)
{
	p_target -> target -> Release();
	if (p_prev_target != nil)
		p_prev_target -> next = p_target -> next;
	else
		p_listener -> targets = p_target -> next;
	if (p_listener -> targets == nil)
		remove_object_listener_from_list(p_listener, p_prev_listener);
	MCMemoryDelete(p_target);
	p_target = p_prev_target;
}
Пример #2
0
void MCInternalObjectListenerListListeners(MCExecPoint &ep)
{
	ep . clear();
	MCObjectHandle *t_current_object;
	t_current_object = ep . getobj() -> gethandle();
	
	bool t_first;
	t_first = true;
	
	MCObjectListener *t_prev_listener;
	t_prev_listener = nil;
	
	MCObjectListener *t_listener;
	t_listener = s_object_listeners;
	while(t_listener != nil)
	{
		if (!t_listener -> object -> Exists())
			remove_object_listener_from_list(t_listener, t_prev_listener);
		else
		{				
			MCObjectListenerTarget *t_target;
			t_target = nil;
			MCObjectListenerTarget *t_prev_target;
			t_prev_target = nil;	
			
			MCExecPoint ep1(ep);
			t_listener -> object -> Get() -> getprop(0, P_LONG_ID, ep1, false);
						
			for (t_target = t_listener -> targets; t_target != nil; t_target = t_target -> next)
			{
				if (!t_target -> target -> Exists())
					remove_object_listener_target_from_list(t_target, t_prev_target, t_listener, t_prev_listener);
				else if (t_target -> target ==  t_current_object)
				{
					ep . concatmcstring(ep1 . getsvalue(), EC_RETURN, t_first);
					t_first = false;		
				}
			}
			
			t_prev_listener = t_listener;
		}
		
		if (t_listener != nil)
			t_listener = t_listener -> next;
		else
			t_listener = s_object_listeners;
	}
}
Пример #3
0
void MCInternalObjectListenerGetListeners(MCExecContext& ctxt, MCStringRef*& r_listeners, uindex_t& r_count)
{
	MCObjectHandle *t_current_object;
	t_current_object = ctxt . GetObject() -> gethandle();
	
	MCObjectListener *t_prev_listener;
	t_prev_listener = nil;
	
	MCObjectListener *t_listener;
	t_listener = s_object_listeners;
    
    MCAutoArray<MCStringRef> t_listeners;
	while(t_listener != nil)
	{
        MCStringRef t_string;
		if (!t_listener -> object -> Exists())
			remove_object_listener_from_list(t_listener, t_prev_listener);
		else
		{
			MCObjectListenerTarget *t_target;
			t_target = nil;
			MCObjectListenerTarget *t_prev_target;
			t_prev_target = nil;
            
            MCAutoValueRef t_long_id;
			t_listener -> object -> Get() -> names(P_LONG_ID, &t_long_id);
            
			for (t_target = t_listener -> targets; t_target != nil; t_target = t_target -> next)
			{
				if (!t_target -> target -> Exists())
					remove_object_listener_target_from_list(t_target, t_prev_target, t_listener, t_prev_listener);
				else if (t_target -> target ==  t_current_object)
                {
                    ctxt . ConvertToString(*t_long_id, t_string);
                    t_listeners . Push(t_string);
                }
			}
			
			t_prev_listener = t_listener;
		}
		
		if (t_listener != nil)
			t_listener = t_listener -> next;
		else
			t_listener = s_object_listeners;
	}
    t_listeners . Take(r_listeners, r_count);
}
Пример #4
0
static void remove_object_listener_target_from_list(MCObjectListenerTarget *&p_target, MCObjectListenerTarget *p_prev_target, MCObjectListener* &p_listener, MCObjectListener* p_prev_listener)
{
	p_target -> target -> Release();
	if (p_prev_target != nil)
		p_prev_target -> next = p_target -> next;
	else
		p_listener -> targets = p_target -> next;
	if (p_listener -> targets == nil)
		remove_object_listener_from_list(p_listener, p_prev_listener);
	// MW-2013-08-27: [[ Bug 11126 ]] If this pointer is going away, make sure we fetch the next
	//   target into the static.
	if (p_target == s_next_listener_target_to_process)
		s_next_listener_target_to_process = p_target -> next;
	MCMemoryDelete(p_target);
	p_target = p_prev_target;
}
Пример #5
0
void MCInternalObjectListenerMessagePendingListeners(void)
{
	if (MCobjectpropertieschanged)
	{
		MCobjectpropertieschanged = False;
		
		MCObjectListener *t_prev_listener;
		t_prev_listener = nil;
		
		MCObjectListener *t_listener;
		t_listener = s_object_listeners;
		while(t_listener != nil)
		{
			// MW-2013-08-27: [[ Bug 11126 ]] This static is updated by the remove_* functions
			//   to ensure we don't get any dangling pointers.
			s_next_listener_to_process = t_listener -> next;
			
			if (!t_listener -> object -> Exists())
				remove_object_listener_from_list(t_listener, t_prev_listener);
			else
			{
				uint8_t t_properties_changed;
				t_properties_changed = t_listener -> object -> Get() -> propertieschanged();
				if (t_properties_changed != kMCPropertyChangedMessageTypeNone)
				{			
					MCExecPoint ep(nil, nil, nil);
					t_listener -> object -> Get() -> getprop(0, P_LONG_ID, ep, False);			
					
					MCObjectListenerTarget *t_target;
					t_target = nil;
					MCObjectListenerTarget *t_prev_target;
					t_prev_target = nil;	
					
					double t_new_time;
					t_new_time = MCS_time();
					if (t_listener -> last_update_time + MCpropertylistenerthrottletime / 1000.0 < t_new_time)
					{
						t_listener -> last_update_time = t_new_time;
						t_target = t_listener->targets;
						while (t_target != nil)
						{
							// MW-2013-08-27: [[ Bug 11126 ]] This static is updated by the remove_* functions
							//   to ensure we don't get any dangling pointers.
							s_next_listener_target_to_process = t_target -> next;
							
							if (!t_target -> target -> Exists())
								remove_object_listener_target_from_list(t_target, t_prev_target, t_listener, t_prev_listener);
							else
							{
								// MM-2012-11-06: Added resizeControl(Started/Ended) and gradientEdit(Started/Ended) messages.
								if (t_properties_changed & kMCPropertyChangedMessageTypePropertyChanged)								
									t_target -> target -> Get() -> message_with_args(MCM_property_changed, ep . getsvalue());
								if (t_properties_changed & kMCPropertyChangedMessageTypeResizeControlStarted)								
									t_target -> target -> Get() -> message_with_args(MCM_resize_control_started, ep . getsvalue());
								if (t_properties_changed & kMCPropertyChangedMessageTypeResizeControlEnded)								
									t_target -> target -> Get() -> message_with_args(MCM_resize_control_ended, ep . getsvalue());
								if (t_properties_changed & kMCPropertyChangedMessageTypeGradientEditStarted)								
									t_target -> target -> Get() -> message_with_args(MCM_gradient_edit_started, ep . getsvalue());
								if (t_properties_changed & kMCPropertyChangedMessageTypeGradientEditEnded)								
									t_target -> target -> Get() -> message_with_args(MCM_gradient_edit_ended, ep . getsvalue());
								
								t_prev_target = t_target;					
							}
							
							t_target = s_next_listener_target_to_process;
						}
					}
					else
						t_listener -> object -> Get() -> signallistenerswithmessage(t_properties_changed);
				}
				
				t_prev_listener = t_listener;
			}
			
			// MW-2013-08-27: [[ Bug 11126 ]] Use the static as the next in the chain.
			t_listener = s_next_listener_to_process;
		}
	}
}