<commit_before>﻿// Nu Game Engine.
// Copyright (C) <NAME>, 2013-2018.

namespace Nu
open System
open System.IO
open System.Reflection
open Prime
open Nu

/// Describes the overlay state of a property.
type [<Struct>] internal OverlayState =
    | Bare
    | Altered
    | Overlaid

/// An overlay.
[<Syntax
    ("EntityDispatcher GuiDispatcher",
     "NodeFacet EffectFacet ScriptFacet RigidBodyFacet StaticSpriteFacet AnimatedSpriteFacet",
     "", "", "",
     Constants.PrettyPrinter.StructuredThresholdMin,
     Constants.PrettyPrinter.DefaultThresholdMax)>]
type Overlay =
    { OverlayName : string
      OverlayIncludeNames : string list
      OverlayProperties : Map<string, Symbol> }

[<AutoOpen>]
module OverlayerModule =

    /// Defines the manner in which overlays are applied to targets.
    type [<ReferenceEquality>] Overlayer =
        private
            { IntrinsicOverlays : Overlay list
              ExtrinsicOverlays : Overlay list
              Overlays : Map<string, Overlay> }

    [<RequireQualifiedAccess; CompilationRepresentation (CompilationRepresentationFlags.ModuleSuffix)>]
    module Overlayer =

        let rec private getOverlaySymbols2 overlayName overlayer =
            match Map.tryFind overlayName overlayer.Overlays with
            | Some overlay ->
                List.fold (fun overlaySymbols overlayName ->
                    let overlaySymbols' = getOverlaySymbols2 overlayName overlayer
                    Map.concat overlaySymbols' overlaySymbols)
                    overlay.OverlayProperties
                    overlay.OverlayIncludeNames
            | None -> Map.empty

        let internal getOverlaySymbols overlayName facetNames overlayer =
            let overlaySymbols = getOverlaySymbols2 overlayName overlayer
            Seq.fold (fun overlaySymbols facetName ->
                let overlaySymbols' = getOverlaySymbols2 facetName overlayer
                Map.concat overlaySymbols' overlaySymbols)
                overlaySymbols
                facetNames

        let internal getPropertyState propertyName propertyType target overlaySymbols =
            match Map.tryFind propertyName overlaySymbols with
            | Some propertySymbol -> 
                let targetType = target.GetType ()
                let propertyOpt = targetType.GetProperty propertyName
                let xtensionOpt =
                    match targetType.GetProperty "Xtension" with
                    | null -> None
                    | xtensionProperty ->
                        match xtensionProperty.GetValue target with
                        | :? Xtension as xtension -> Some xtension
                        | _ -> None
                let propertyValueOpt =
                    match (propertyOpt, xtensionOpt) with
                    | (null, Some xtension) ->
                        match Xtension.tryGetProperty propertyName xtension with
                        | Some property -> Some property.PropertyValue
                        | None -> None
                    | (null, None) -> None
                    | (targetProperty, _) -> Some (targetProperty.GetValue target)
                match propertyValueOpt with
                | Some propertyValue ->
                    match propertySymbol with
                    | Symbols ([String (str, _); _], _) when isNotNull (Type.GetType str) ->
                        let converter = SymbolicConverter (false, None, propertyType)
                        if converter.CanConvertFrom typeof<Symbol> then
                            let overlayValue = converter.ConvertFrom propertySymbol
                            if overlayValue = propertyValue then Overlaid else Altered
                        else Bare
                    | _ -> Bare
                | None -> Bare
            | None -> Bare
            
        let internal shouldPropertySerialize propertyName propertyType target overlaySymbols =
            match getPropertyState propertyName propertyType target overlaySymbols with
            | Altered | Bare -> true
            | Overlaid -> false

        let internal shouldApplyOverlay (property : PropertyInfo) target oldOverlaySymbols =
            if property.PropertyType <> typeof<Xtension> then
                match getPropertyState property.Name property.PropertyType target oldOverlaySymbols with
                | Bare -> true
                | Altered -> false
                | Overlaid -> true
            else false
<commit_msg>Attempt to fix entity serialization bug.<commit_after>﻿// Nu Game Engine.
// Copyright (C) <NAME>, 2013-2018.

namespace Nu
open System
open System.IO
open System.Reflection
open Prime
open Nu

/// Describes the overlay state of a property.
type [<Struct>] internal OverlayState =
    | Bare
    | Altered
    | Overlaid

/// An overlay.
[<Syntax
    ("EntityDispatcher GuiDispatcher",
     "NodeFacet EffectFacet ScriptFacet RigidBodyFacet StaticSpriteFacet AnimatedSpriteFacet",
     "", "", "",
     Constants.PrettyPrinter.StructuredThresholdMin,
     Constants.PrettyPrinter.DefaultThresholdMax)>]
type Overlay =
    { OverlayName : string
      OverlayIncludeNames : string list
      OverlayProperties : Map<string, Symbol> }

[<AutoOpen>]
module OverlayerModule =

    /// Defines the manner in which overlays are applied to targets.
    type [<ReferenceEquality>] Overlayer =
        private
            { IntrinsicOverlays : Overlay list
              ExtrinsicOverlays : Overlay list
              Overlays : Map<string, Overlay> }

    [<RequireQualifiedAccess; CompilationRepresentation (CompilationRepresentationFlags.ModuleSuffix)>]
    module Overlayer =

        let rec private getOverlaySymbols2 overlayName overlayer =
            match Map.tryFind overlayName overlayer.Overlays with
            | Some overlay ->
                List.fold (fun overlaySymbols overlayName ->
                    let overlaySymbols' = getOverlaySymbols2 overlayName overlayer
                    Map.concat overlaySymbols' overlaySymbols)
                    overlay.OverlayProperties
                    overlay.OverlayIncludeNames
            | None -> Map.empty

        let internal getOverlaySymbols overlayName facetNames overlayer =
            let overlaySymbols = getOverlaySymbols2 overlayName overlayer
            Seq.fold (fun overlaySymbols facetName ->
                let overlaySymbols' = getOverlaySymbols2 facetName overlayer
                Map.concat overlaySymbols' overlaySymbols)
                overlaySymbols
                facetNames

        let internal getPropertyState propertyName propertyType target overlaySymbols =
            match Map.tryFind propertyName overlaySymbols with
            | Some propertySymbol -> 
                let targetType = target.GetType ()
                let propertyOpt = targetType.GetProperty propertyName
                let xtensionOpt =
                    match targetType.GetProperty "Xtension" with
                    | null -> None
                    | xtensionProperty ->
                        match xtensionProperty.GetValue target with
                        | :? Xtension as xtension -> Some xtension
                        | _ -> None
                let propertyValueOpt =
                    match (propertyOpt, xtensionOpt) with
                    | (null, Some xtension) ->
                        match Xtension.tryGetProperty propertyName xtension with
                        | Some property -> Some property.PropertyValue
                        | None -> None
                    | (null, None) -> None
                    | (targetProperty, _) -> Some (targetProperty.GetValue target)
                match propertyValueOpt with
                | Some propertyValue ->
                    let converter = SymbolicConverter (false, None, propertyType)
                    if converter.CanConvertFrom typeof<Symbol> then
                        let overlayValue = converter.ConvertFrom propertySymbol
                        if overlayValue = propertyValue then Overlaid else Altered
                    else Bare
                | None -> Bare
            | None -> Bare
            
        let internal shouldPropertySerialize propertyName propertyType target overlaySymbols =
            match getPropertyState propertyName propertyType target overlaySymbols with
            | Altered | Bare -> true
            | Overlaid -> false

        let internal shouldApplyOverlay (property : PropertyInfo) target oldOverlaySymbols =
            if property.PropertyType <> typeof<Xtension> then
                match getPropertyState property.Name property.PropertyType target oldOverlaySymbols with
                | Bare -> true
                | Altered -> false
                | Overlaid -> true
            else false

{'fraction_non_alphanumeric': 0.05737332424448989, 'fraction_numerical': 0.0027266530334014998, 'mean_word_length': 1.815158298688839, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 71, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6372299', 'n_tokens_mistral': 2136, 'n_tokens_neox': 1956, 'n_words': 588}