示例#1
0
        protected override void OnEntityAdded(Entity entity, AssociatedData data)
        {
            var shadowMapPermutation = data.LightComponent.Get(LightProcessor.ShadowMapKey);

            data.CurrentShadowMapPermutation = shadowMapPermutation;
            if (shadowMapPermutation != null)
            {
                data.LightShaftsPlugin = new LightShaftsPlugin("LightShaftsPlugin")
                {
                    Debug          = false,
                    RenderPass     = lightShaftsPass,
                    ShadowMap      = entity.Get(LightComponent.Key).Get(LightProcessor.ShadowMapKey).ShadowMap,
                    RenderTarget   = mainTargetPlugin.RenderTarget,
                    DepthStencil   = mainTargetPlugin.DepthStencil,
                    ViewParameters = mainPlugin.ViewParameters,
                };
                data.LightShaftsPlugin.BoundingBoxes.AddRange(data.LightShaftsComponent.LightShaftsBoundingBoxes);

                renderSystem.RenderPassPlugins.Add(data.LightShaftsPlugin);
            }
        }
示例#2
0
        protected override void OnEntityRemoved(Entity entity, AssociatedData data)
        {
            base.OnEntityRemoved(entity, data);

            // Return AnimationClipEvaluators to pool
            foreach (var playingAnimation in data.AnimationComponent.PlayingAnimations)
            {
                var evaluator = playingAnimation.Evaluator;
                if (evaluator != null)
                {
                    data.AnimationComponent.Blender.ReleaseEvaluator(evaluator);
                    playingAnimation.Evaluator = null;
                }
            }

            // Return AnimationClipResult to pool
            if (data.AnimationClipResult != null)
            {
                data.AnimationComponent.Blender.FreeIntermediateResult(data.AnimationClipResult);
            }
        }
示例#3
0
        protected override void OnEntityAdding(Entity entity, AssociatedData data)
        {
            base.OnEntityAdding(entity, data);

            // initialize the AudioEmitter first position
            data.TransformComponent.UpdateWorldMatrix(); // ensure the worldMatrix is correct
            data.AudioEmitter = new AudioEmitter {
                Position = data.TransformComponent.WorldMatrix.TranslationVector
            };                                                                                                         // valid position is needed at first Update loop to compute velocity.

            // create a SoundEffectInstance for each listener activated and for each sound controller of the EmitterComponent.
            foreach (var listener in audioSystem.Listeners.Keys)
            {
                foreach (var soundController in data.AudioEmitterComponent.SoundEffectToController.Values)
                {
                    data.ListenerControllerToSoundInstance[Tuple.Create(listener, soundController)] = soundController.CreateSoundInstance();
                }
            }

            data.AudioEmitterComponent.ControllerCollectionChanged += OnSoundControllerListChanged;
        }
示例#4
0
        private void CheckMeshes(DecalComponent decalComponent, AssociatedData data)
        {
            if (data.RenderMesh == null)
            {
                var model = data.Model;

                // Create render mesh
                var mesh     = model.Meshes[0];
                var material = data.Material;

                var renderMesh = new RenderMesh
                {
                    Source      = decalComponent,
                    RenderModel = new RenderModel
                    {
                        Model     = model,
                        Meshes    = new RenderMesh[1],  // Cyclic relationship... renderMesh is assigned in here below.
                        Materials = new[]
                        {
                            new RenderModel.MaterialInfo
                            {
                                Material       = material,
                                MeshCount      = 1,
                                MeshStartIndex = 0
                            }
                        }
                    },
                    Mesh = mesh,
                };
                renderMesh.RenderModel.Meshes[0] = renderMesh;

                // Update material
                UpdateMaterial(renderMesh, material.Passes[0], model.Materials.GetItemOrNull(0), decalComponent);

                data.RenderMesh = renderMesh;

                // Update before first add so that RenderGroup is properly set
                UpdateAssociatedData(decalComponent, data);
            }
        }
示例#5
0
        private void UpdateNavigationMesh(AssociatedData data)
        {
            var navigationMeshToLoad = data.Component.NavigationMesh;

            if (navigationMeshToLoad == null && dynamicNavigationMeshSystem != null)
            {
                // Load dynamic navigation mesh when no navigation mesh is specified on the component
                navigationMeshToLoad = dynamicNavigationMeshSystem?.CurrentNavigationMesh;
            }

            NavigationMeshGroupData loadedGroup = Load(navigationMeshToLoad, data.Component.GroupId);

            if (data.LoadedGroup != null)
            {
                Unload(data.LoadedGroup);
            }

            data.Component.RecastNavigationMesh = loadedGroup?.RecastNavigationMesh;
            data.LoadedGroup = loadedGroup;

            UpdateSceneOffset(data);
        }
示例#6
0
        private void UpdateNavigationMesh(NavigationComponent component, AssociatedData data)
        {
            // Remove old reference
            RemoveReference(component, data);

            if (component.NavigationMesh != null)
            {
                NavigationMeshInternal navigationMeshInternal;
                if (!loadedNavigationMeshes.TryGetValue(component.NavigationMesh, out navigationMeshInternal))
                {
                    navigationMeshInternal = new NavigationMeshInternal(component.NavigationMesh);
                    loadedNavigationMeshes.Add(component.NavigationMesh, navigationMeshInternal);
                }
                data.NavigationMeshInternal = navigationMeshInternal;
                navigationMeshInternal.AddReference(component);

                SelectLayer(component, data);

                // Mark new navigation mesh as loaded
                data.LoadedNavigationMesh = component.NavigationMesh;
            }
        }
示例#7
0
 protected override bool IsAssociatedDataValid([NotNull] Entity entity, [NotNull] NetworkEntityComponent component, [NotNull] AssociatedData associatedData)
 {
     return(associatedData.TransformComponent == entity.Transform &&
            associatedData.MovementSnapshotsComponent == entity.Get <MovementSnapshotsComponent>() &&
            associatedData.NetworkEntityComponent == entity.Get <NetworkEntityComponent>() &&
            associatedData.ClientPredictionSnapshotsComponent == entity.Get <ClientPredictionSnapshotsComponent>() &&
            associatedData.CharacterComponent == entity.Get <CharacterComponent>());
 }
        protected override void OnEntityComponentRemoved(Entity entity, AudioEmitterComponent component, AssociatedData data)
        {
            base.OnEntityComponentRemoved(entity, component, data);

            // dispose and delete all SoundEffectInstances associated to the EmitterComponent.
            foreach (var soundController in data.AudioEmitterComponent.SoundEffectToController.Values)
            {
                soundController.DestroyAllSoundInstances();
            }

            data.AudioEmitterComponent.ControllerCollectionChanged -= OnSoundControllerListChanged;
        }
示例#9
0
        void NewElement(PhysicsElement element, AssociatedData data, Entity entity)
        {
            if (element.Shape == null)
            {
                return;                        //no shape no purpose
            }
            var shape = element.Shape.Shape;

            element.Data      = data;
            element.BoneIndex = -1;

            if (!element.Sprite && element.LinkedBoneName != null && data.ModelComponent != null)
            {
                //find the linked bone, if can't be found we just skip this element
                for (var index = 0; index < data.ModelComponent.ModelViewHierarchy.Nodes.Length; index++)
                {
                    var node = data.ModelComponent.ModelViewHierarchy.Nodes[index];
                    if (node.Name != element.LinkedBoneName)
                    {
                        continue;
                    }
                    element.BoneIndex = index;
                    break;
                }

                if (element.BoneIndex == -1)
                {
                    throw new Exception("The specified LinkedBoneName doesn't exist in the model hierarchy.");
                }
            }

            //complex hierarchy models not implemented yet
            if (element.BoneIndex != -1)
            {
                throw new NotImplementedException("Physics on complex hierarchy model's bones is not implemented yet.");
            }

            var defaultGroups = element.CanCollideWith == 0 || element.CollisionGroup == 0;

            switch (element.Type)
            {
            case PhysicsElement.Types.PhantomCollider:
            {
                var c = physicsSystem.PhysicsEngine.CreateCollider(shape);

                element.Collider = c;                   //required by the next call
                element.Collider.EntityObject = entity; //required by the next call
                element.UpdatePhysicsTransformation();  //this will set position and rotation of the collider

                c.IsTrigger = true;

                if (defaultGroups)
                {
                    physicsSystem.PhysicsEngine.AddCollider(c);
                }
                else
                {
                    physicsSystem.PhysicsEngine.AddCollider(c, (CollisionFilterGroups)element.CollisionGroup, element.CanCollideWith);
                }
            }
            break;

            case PhysicsElement.Types.StaticCollider:
            {
                var c = physicsSystem.PhysicsEngine.CreateCollider(shape);

                element.Collider = c;                   //required by the next call
                element.Collider.EntityObject = entity; //required by the next call
                element.UpdatePhysicsTransformation();  //this will set position and rotation of the collider

                c.IsTrigger = false;

                if (defaultGroups)
                {
                    physicsSystem.PhysicsEngine.AddCollider(c);
                }
                else
                {
                    physicsSystem.PhysicsEngine.AddCollider(c, (CollisionFilterGroups)element.CollisionGroup, element.CanCollideWith);
                }
            }
            break;

            case PhysicsElement.Types.StaticRigidBody:
            {
                var rb = physicsSystem.PhysicsEngine.CreateRigidBody(shape);

                rb.EntityObject = entity;
                rb.GetWorldTransformCallback = (out Matrix transform) => RigidBodyGetWorldTransform(element, out transform);
                rb.SetWorldTransformCallback = transform => RigidBodySetWorldTransform(element, transform);
                element.Collider             = rb;
                element.UpdatePhysicsTransformation();         //this will set position and rotation of the collider

                rb.Type = RigidBodyTypes.Static;

                if (defaultGroups)
                {
                    physicsSystem.PhysicsEngine.AddRigidBody(rb);
                }
                else
                {
                    physicsSystem.PhysicsEngine.AddRigidBody(rb, (CollisionFilterGroups)element.CollisionGroup, element.CanCollideWith);
                }
            }
            break;

            case PhysicsElement.Types.DynamicRigidBody:
            {
                var rb = physicsSystem.PhysicsEngine.CreateRigidBody(shape);

                rb.EntityObject = entity;
                rb.GetWorldTransformCallback = (out Matrix transform) => RigidBodyGetWorldTransform(element, out transform);
                rb.SetWorldTransformCallback = transform => RigidBodySetWorldTransform(element, transform);
                element.Collider             = rb;
                element.UpdatePhysicsTransformation();         //this will set position and rotation of the collider

                rb.Type = RigidBodyTypes.Dynamic;
                rb.Mass = 1.0f;

                if (defaultGroups)
                {
                    physicsSystem.PhysicsEngine.AddRigidBody(rb);
                }
                else
                {
                    physicsSystem.PhysicsEngine.AddRigidBody(rb, (CollisionFilterGroups)element.CollisionGroup, element.CanCollideWith);
                }
            }
            break;

            case PhysicsElement.Types.KinematicRigidBody:
            {
                var rb = physicsSystem.PhysicsEngine.CreateRigidBody(shape);

                rb.EntityObject = entity;
                rb.GetWorldTransformCallback = (out Matrix transform) => RigidBodyGetWorldTransform(element, out transform);
                rb.SetWorldTransformCallback = transform => RigidBodySetWorldTransform(element, transform);
                element.Collider             = rb;
                element.UpdatePhysicsTransformation();         //this will set position and rotation of the collider

                rb.Type = RigidBodyTypes.Kinematic;
                rb.Mass = 0.0f;

                if (defaultGroups)
                {
                    physicsSystem.PhysicsEngine.AddRigidBody(rb);
                }
                else
                {
                    physicsSystem.PhysicsEngine.AddRigidBody(rb, (CollisionFilterGroups)element.CollisionGroup, element.CanCollideWith);
                }
            }
            break;

            case PhysicsElement.Types.CharacterController:
            {
                var ch = physicsSystem.PhysicsEngine.CreateCharacter(shape, element.StepHeight);

                element.Collider = ch;
                element.Collider.EntityObject = entity;
                element.UpdatePhysicsTransformation();         //this will set position and rotation of the collider

                if (defaultGroups)
                {
                    physicsSystem.PhysicsEngine.AddCharacter(ch);
                }
                else
                {
                    physicsSystem.PhysicsEngine.AddCharacter(ch, (CollisionFilterGroups)element.CollisionGroup, element.CanCollideWith);
                }

                characters.Add(element);
            }
            break;
            }

            elements.Add(element);
        }
示例#10
0
 protected override bool IsAssociatedDataValid(Entity entity, PhysicsComponent physicsComponent, AssociatedData associatedData)
 {
     return
         (physicsComponent == associatedData.PhysicsComponent &&
          entity.Transform == associatedData.TransformComponent &&
          entity.Get <ModelComponent>() == associatedData.ModelComponent);
 }
示例#11
0
        protected override void OnEntityComponentAdding(Entity entity, PhysicsComponent component, AssociatedData data)
        {
            component.Attach(data);

            var character = component as CharacterComponent;

            if (character != null)
            {
                characters.Add(character);
            }

            if (colliderShapesRendering)
            {
                component.AddDebugEntity(debugScene, Simulation.ColliderShapesRenderGroup);
            }

            elements.Add(component);

            if (component.BoneIndex != -1)
            {
                boneElements.Add((PhysicsSkinnedComponentBase)component);
            }
        }
示例#12
0
        protected override void OnEntityAdding(Entity entity, AssociatedData associatedData)
        {
            base.OnEntityAdding(entity, associatedData);

            associatedData.MeshAnimationUpdater = new MeshAnimationUpdater();
        }
示例#13
0
 protected override void OnEntityComponentRemoved(Entity entity, [NotNull] DecalComponent component, [NotNull] AssociatedData data)
 {
     if (data.RenderMesh != null)
     {
         // Unregister from render system
         VisibilityGroup.RenderObjects.Remove(data.RenderMesh);
     }
 }
示例#14
0
        protected override void OnEntityComponentAdding(Entity entity, [NotNull] DecalComponent component, [NotNull] AssociatedData data)
        {
            var model = new Model();
            // We create the cube via the *ProceduralModel class rather than GeometricPrimitive.*.New
            // because there are additional vertext data that gets created through this which are required by the Material
            var procCube = new CubeProceduralModel();
            // Set up a new material with our decal shader.
            var shader = new ComputeShaderClassColor
            {
                MixinReference = "DecalShader"      // This is referring to our shader at Effects\DecalShader.xksl
            };

            var materialDescription = new MaterialDescriptor
            {
                Attributes =
                {
                    DiffuseModel = new MaterialDiffuseLambertModelFeature(),
                    Diffuse      = new MaterialDiffuseMapFeature(shader),
                    Transparency = new MaterialTransparencyBlendFeature(),
                    CullMode     = CullMode.Back,
                }
            };

            procCube.MaterialInstance.IsShadowCaster = false;
            procCube.Generate(Services, model);

            var material = Material.New(_graphicsDevice, materialDescription);

            UpdateMaterialParameters(component, data.TransformComponent, material);
            data.Material = material;
            data.Model    = model;
        }
示例#15
0
 protected override bool IsAssociatedDataValid([NotNull] Entity entity, [NotNull] DecalComponent component, [NotNull] AssociatedData data)
 {
     return(true);
 }
示例#16
0
 protected override void OnEntityComponentRemoved(Entity entity, PhysicsComponent component, AssociatedData data)
 {
     component.Detach();
 }
示例#17
0
 protected override bool IsAssociatedDataValid([NotNull] Entity entity, [NotNull] MovementSnapshotsComponent component, [NotNull] AssociatedData associatedData)
 {
     return(associatedData.TransformComponent == entity.Transform &&
            associatedData.CharacterComponent == entity.Get <CharacterComponent>() &&
            associatedData.InputSnapshotsComponent == entity.Get <InputSnapshotsComponent>());
 }
示例#18
0
 /// <inheritdoc />
 protected override bool IsAssociatedDataValid(Entity entity, LightShaftComponent component, AssociatedData associatedData)
 {
     return(component == associatedData.Component &&
            entity.Get <LightComponent>() == associatedData.LightComponent);
 }
示例#19
0
        private void NewElement(PhysicsElement element, AssociatedData data, Entity entity)
        {
            if (element.Shape == null || element.Shape.Descriptions == null || element.Shape.Shape == null)
            {
                return;                                                                                             //no shape no purpose
            }
            var shape = element.Shape.Shape;

            element.Data      = data;
            element.BoneIndex = -1;

            if (!element.LinkedBoneName.IsNullOrEmpty())
            {
                element.BoneIndex = data.ModelComponent.ModelViewHierarchy.Nodes.IndexOf(x => x.Name == element.LinkedBoneName);

                if (element.BoneIndex == -1)
                {
                    throw new Exception("The specified LinkedBoneName doesn't exist in the model hierarchy.");
                }

                element.BoneWorldMatrixOut = element.BoneWorldMatrix = data.ModelComponent.ModelViewHierarchy.NodeTransformations[element.BoneIndex].WorldMatrix;
            }

            var defaultGroups = element.CanCollideWith == 0 || element.CollisionGroup == 0;

            switch (element.Type)
            {
            case PhysicsElement.Types.PhantomCollider:
            {
                var c = Simulation.CreateCollider(shape);

                element.Collider        = c;           //required by the next call
                element.Collider.Entity = entity;      //required by the next call
                element.UpdatePhysicsTransformation(); //this will set position and rotation of the collider

                c.IsTrigger = true;

                if (defaultGroups)
                {
                    simulation.AddCollider(c);
                }
                else
                {
                    simulation.AddCollider(c, (CollisionFilterGroupFlags)element.CollisionGroup, element.CanCollideWith);
                }
            }
            break;

            case PhysicsElement.Types.StaticCollider:
            {
                var c = Simulation.CreateCollider(shape);

                element.Collider        = c;           //required by the next call
                element.Collider.Entity = entity;      //required by the next call
                element.UpdatePhysicsTransformation(); //this will set position and rotation of the collider

                c.IsTrigger = false;

                if (defaultGroups)
                {
                    simulation.AddCollider(c);
                }
                else
                {
                    simulation.AddCollider(c, (CollisionFilterGroupFlags)element.CollisionGroup, element.CanCollideWith);
                }
            }
            break;

            case PhysicsElement.Types.StaticRigidBody:
            {
                var rb = Simulation.CreateRigidBody(shape);

                rb.Entity = entity;
                rb.GetWorldTransformCallback = (out Matrix transform) => RigidBodyGetWorldTransform(element, out transform);
                rb.SetWorldTransformCallback = transform => RigidBodySetWorldTransform(element, transform);
                element.Collider             = rb;
                element.UpdatePhysicsTransformation();         //this will set position and rotation of the collider

                rb.Type = RigidBodyTypes.Static;

                if (defaultGroups)
                {
                    simulation.AddRigidBody(rb);
                }
                else
                {
                    simulation.AddRigidBody(rb, (CollisionFilterGroupFlags)element.CollisionGroup, element.CanCollideWith);
                }
            }
            break;

            case PhysicsElement.Types.DynamicRigidBody:
            {
                var rb = Simulation.CreateRigidBody(shape);

                rb.Entity = entity;
                rb.GetWorldTransformCallback = (out Matrix transform) => RigidBodyGetWorldTransform(element, out transform);
                rb.SetWorldTransformCallback = transform => RigidBodySetWorldTransform(element, transform);
                element.Collider             = rb;
                element.UpdatePhysicsTransformation();         //this will set position and rotation of the collider

                rb.Type = RigidBodyTypes.Dynamic;
                rb.Mass = 1.0f;

                if (defaultGroups)
                {
                    simulation.AddRigidBody(rb);
                }
                else
                {
                    simulation.AddRigidBody(rb, (CollisionFilterGroupFlags)element.CollisionGroup, element.CanCollideWith);
                }
            }
            break;

            case PhysicsElement.Types.KinematicRigidBody:
            {
                var rb = Simulation.CreateRigidBody(shape);

                rb.Entity = entity;
                rb.GetWorldTransformCallback = (out Matrix transform) => RigidBodyGetWorldTransform(element, out transform);
                rb.SetWorldTransformCallback = transform => RigidBodySetWorldTransform(element, transform);
                element.Collider             = rb;
                element.UpdatePhysicsTransformation();         //this will set position and rotation of the collider

                rb.Type = RigidBodyTypes.Kinematic;
                rb.Mass = 0.0f;

                if (defaultGroups)
                {
                    simulation.AddRigidBody(rb);
                }
                else
                {
                    simulation.AddRigidBody(rb, (CollisionFilterGroupFlags)element.CollisionGroup, element.CanCollideWith);
                }
            }
            break;

            case PhysicsElement.Types.CharacterController:
            {
                var ch = Simulation.CreateCharacter(shape, element.StepHeight);

                element.Collider        = ch;
                element.Collider.Entity = entity;
                element.UpdatePhysicsTransformation();         //this will set position and rotation of the collider

                if (defaultGroups)
                {
                    simulation.AddCharacter(ch);
                }
                else
                {
                    simulation.AddCharacter(ch, (CollisionFilterGroupFlags)element.CollisionGroup, element.CanCollideWith);
                }

                characters.Add(element);
            }
            break;
            }

            elements.Add(element);
            if (element.BoneIndex != -1)
            {
                boneElements.Add(element);
            }
        }
示例#20
0
 protected override bool IsAssociatedDataValid(Entity entity, AnimationComponent component, AssociatedData associatedData)
 {
     return
         (component == associatedData.AnimationComponent &&
          entity.Get <ModelComponent>() == associatedData.ModelComponent);
 }
示例#21
0
 protected override void OnEntityComponentRemoved(Entity entity, PhysicsComponent component, AssociatedData data)
 {
     currentFrameRemovals.Add(component);
 }
示例#22
0
        protected override void OnEntityComponentAdding(Entity entity, AnimationComponent component, AssociatedData data)
        {
            base.OnEntityComponentAdding(entity, component, data);

            data.AnimationUpdater = new AnimationUpdater();
        }
示例#23
0
 protected override bool IsAssociatedDataValid(Entity entity, AssociatedData associatedData)
 {
     return
         (entity.Get(AudioEmitterComponent.Key) == associatedData.AudioEmitterComponent &&
          entity.Get(TransformComponent.Key) == associatedData.TransformComponent);
 }
示例#24
0
 /// <inheritdoc />
 protected override void OnEntityComponentRemoved(Entity entity, VideoComponent component, AssociatedData data)
 {
     try
     {
         data.Dispose();
     }
     catch (Exception ex)
     {
         // FIXME log only certains exceptions, rethrow all the rest
         Logger.Error($"An error occurred while removing a {nameof(VideoComponent)}", ex);
         throw;
     }
 }
示例#25
0
 protected override bool IsAssociatedDataValid(Entity entity, AssociatedData associatedData)
 {
     return(entity.Get(ScriptComponent.Key) == associatedData.Component);
 }
示例#26
0
 /// <inheritdoc />
 protected override bool IsAssociatedDataValid(Entity entity, VideoComponent component, AssociatedData associatedData)
 {
     return(component == associatedData.VideoComponent);
 }
 protected override bool IsAssociatedDataValid(Entity entity, AudioEmitterComponent component, AssociatedData associatedData)
 {
     return
         (component == associatedData.AudioEmitterComponent &&
          entity.Transform == associatedData.TransformComponent);
 }
        protected override void OnEntityRemoved(Entity entity, AssociatedData data)
        {
            base.OnEntityRemoved(entity, data);

            ((TrackingCollection <LightComponent>)data.LightReceiverComponent.LightComponents).CollectionChanged -= data.LightComponentsChanged;
        }
示例#29
0
        internal void Initialize()
        {
            var commandGroups = new Dictionary <string, List <ModelNodeCommandWrapper> >();

            foreach (var node in combinedNodes)
            {
                if (node.IsDestroyed)
                {
                    throw new InvalidOperationException("One of the combined node is already disposed.");
                }

                foreach (var command in node.Commands)
                {
                    var list = commandGroups.GetOrCreateValue(command.Name);
                    list.Add((ModelNodeCommandWrapper)command);
                }
            }

            foreach (var commandGroup in commandGroups)
            {
                var mode = commandGroup.Value.First().CombineMode;
                if (commandGroup.Value.Any(x => x.CombineMode != mode))
                {
                    throw new InvalidOperationException($"Inconsistent combine mode among command {commandGroup.Key}");
                }

                var shouldCombine = mode != CombineMode.DoNotCombine && (mode == CombineMode.AlwaysCombine || commandGroup.Value.Count == combinedNodes.Count);

                if (shouldCombine)
                {
                    var command = new CombinedNodeCommandWrapper(ServiceProvider, commandGroup.Key, commandGroup.Value);
                    AddCommand(command);
                }
            }

            if (!HasList || HasDictionary)
            {
                var commonChildren = GetCommonChildren();
                GenerateChildren(commonChildren);
            }
            else
            {
                var commonChildren = GetCommonChildrenInList();
                if (commonChildren != null)
                {
                    // TODO: Disable list children for now - they need to be improved a lot (resulting combinaison is very random, especially for list of ints
                    GenerateChildren(commonChildren);
                }
            }
            foreach (var key in AssociatedData.Keys.ToList())
            {
                RemoveAssociatedData(key);
            }

            // TODO: we add associatedData added to SingleObservableNode this way, but it's a bit dangerous. Maybe we should check that all combined nodes have this data entry, and all with the same value.
            foreach (var singleData in CombinedNodes.SelectMany(x => x.AssociatedData).Where(x => !AssociatedData.ContainsKey(x.Key)))
            {
                AddAssociatedData(singleData.Key, singleData.Value);
            }

            FinalizeChildrenInitialization();

            CheckDynamicMemberConsistency();
        }
示例#30
0
 /// <summary>
 /// Returns the additionnal data with the matching name.
 /// </summary>
 /// <param name="name">The name of the additionnal data to look for.</param>
 /// <returns>The corresponding additionnal data, or <c>null</c> if no data with the given name exists.</returns>
 public object GetAssociatedData(string name)
 {
     return(AssociatedData.FirstOrDefault(x => x.Key == name).Value);
 }