Пример #1
0
//needs to remain int (instead of int32) since numbers are derived from TPL that uses int
void FLiveEditorManager::Dispatch( int Status, int Data1, int Data2, const struct FLiveEditorDeviceData &Data )
{
	int Type = (Status & 0xF0) >> 4;
	int Channel = (Status % 16) + 1;
	int ControlID = Data1;
	int ID = LISTENER_ID(Channel,ControlID);
	
	int Delta = 0;	//needs to remain int (instead of int32) since numbers are derived from TPL that uses int

	//
	// Dispatch the MIDI data to all Active Listners
	//
	TArray<ILiveEditListener*> Results;
	EventListeners.MultiFind( ID, Results );
	for ( TArray<ILiveEditListener*>::TIterator It(Results); It; It++ )
	{
		ILiveEditListener *Listener = *It;
		if ( !Listener || !Listener->Target.IsValid() )
		{
			continue;
		}

		switch ( Listener->Binding.ControlType )
		{
			case ELiveEditControllerType::NoteOnOff:
				Delta = 0;
				break;
			case ELiveEditControllerType::ControlChangeContinuous:
				if ( Data2 == Data.ContinuousIncrement )
					Delta = 1;
				else if ( Data2 == Data.ContinuousDecrement )
					Delta = -1;
				else
					Delta = 0;
				break;
			case ELiveEditControllerType::ControlChangeFixed:
				Delta = Data2 - Listener->Binding.LastValue;
				Listener->Binding.LastValue = Data2;
			default:
				break;
		}

		UObject *Target = Listener->Target.Get();
		FLiveEditorManager_Dispatch_Parms Parms;
		Parms.Delta = Delta;
		Parms.MidiValue = (int32)Data2;
		Parms.ControlType = Listener->Binding.ControlType;
		Target->ProcessEvent( Target->FindFunctionChecked( Listener->Name ), &Parms );
	}
}
Пример #2
0
void FObjectReplicator::PostReceivedBunch()
{
	// Call PostNetReceive
	const bool bIsServer = (OwningChannel->Connection->Driver->ServerConnection == NULL);
	if (!bIsServer && bHasReplicatedProperties)
	{
		PostNetReceive();
		bHasReplicatedProperties = false;
	}

	// Check if PostNetReceive() destroyed Object
	UObject *Object = GetObject();
	if (Object == NULL || Object->IsPendingKill())
	{
		return;
	}

	RepLayout->CallRepNotifies( RepState, Object );

	// Call RepNotifies
	if ( RepNotifies.Num() > 0 )
	{
		for (int32 RepNotifyIdx = 0; RepNotifyIdx < RepNotifies.Num(); RepNotifyIdx++)
		{
			//UE_LOG(LogNet, Log,  TEXT("Calling Object->%s with %s"), *RepNotifies(RepNotifyIdx)->RepNotifyFunc.ToString(), *RepNotifies(RepNotifyIdx)->GetName()); 						
			UProperty* RepProperty = RepNotifies[RepNotifyIdx];
			UFunction* RepNotifyFunc = Object->FindFunctionChecked(RepProperty->RepNotifyFunc);
						
			if (RepNotifyFunc->NumParms == 0)
			{
				Object->ProcessEvent(RepNotifyFunc, NULL);
			}
			else if (RepNotifyFunc->NumParms == 1)
			{
				Object->ProcessEvent(RepNotifyFunc, RepProperty->ContainerPtrToValuePtr<uint8>(RepState->StaticBuffer.GetTypedData()) );
			}
			else if (RepNotifyFunc->NumParms == 2)
			{
				// Fixme: this isn't as safe as it could be. Right now we have two types of parameters: MetaData (a TArray<uint8>)
				// and the last local value (pointer into the Recent[] array).
				//
				// Arrays always expect MetaData. Everything else, including structs, expect last value.
				// This is enforced with UHT only. If a ::NetSerialize function ever starts producing a MetaData array thats not in UArrayProperty,
				// we have no static way of catching this and the replication system could pass the wrong thing into ProcessEvent here.
				//
				// But this is all sort of an edge case feature anyways, so its not worth tearing things up too much over.

				FMemMark Mark(FMemStack::Get());
				uint8* Parms = new(FMemStack::Get(),MEM_Zeroed,RepNotifyFunc->ParmsSize)uint8;
				
				TFieldIterator<UProperty> Itr(RepNotifyFunc);
				check(Itr);
				
				Itr->CopyCompleteValue( Itr->ContainerPtrToValuePtr<void>(Parms), RepProperty->ContainerPtrToValuePtr<uint8>(RepState->StaticBuffer.GetTypedData()) );
				++Itr;
				check(Itr);

				TArray<uint8> *NotifyMetaData = RepNotifyMetaData.Find(RepNotifies[RepNotifyIdx]);
				check(NotifyMetaData);
				Itr->CopyCompleteValue( Itr->ContainerPtrToValuePtr<void>(Parms), NotifyMetaData );
				
				Object->ProcessEvent(RepNotifyFunc, Parms );

				Mark.Pop();
			}
 						
 			if (Object == NULL || Object->IsPendingKill())
 			{
 				// script event destroyed Object
 				break;
 			}
		}
	}

	RepNotifies.Reset();
	RepNotifyMetaData.Empty();
}