<commit_before>//
// Copyright (c) XSharp B.V.  All Rights Reserved.  
// Licensed under the Apache License, Version 2.0.  
// See License.txt in the project root for license information.
//

USING System.Collections.Generic
USING System.Threading
USING XSharp.RDD
USING XSharp.RDD.Enums
USING System.Runtime.CompilerServices
/// <summary>
/// Container Class that holds the XSharp Runtime state
/// </summary>
/// <remarks>
/// Please note that unlike in Visual Objects and Vulcan.NET every thread has its own copy of the runtime state.<br/>
/// The runtime state from a new thread is a copy of the state of the main thread at that moment.
/// </remarks>


CLASS XSharp.RuntimeState
	// Static Fields
	PRIVATE INITONLY STATIC initialState  AS RuntimeState 
	// Static Methods and Constructor
	private STATIC currentState := ThreadLocal<RuntimeState>{ {=>  initialState:Clone()},TRUE }  AS ThreadLocal<RuntimeState> 
	STATIC CONSTRUCTOR
		initialState	:= RuntimeState{TRUE}
		
	/// <summary>Retrieve the runtime state for the current thread</summary>
	PUBLIC STATIC METHOD GetInstance() AS RuntimeState
		RETURN currentState:Value

	PRIVATE oSettings AS Dictionary<XSharp.Set, OBJECT>
    /// <summary>The dictionary that stores most of the settings in the runtime state. The key to the index is the number from the Set Enum</summary>
    /// <seealso cref="T:XSharp.Set" >Set Enum</seealso>
    PUBLIC PROPERTY Settings AS Dictionary<XSharp.Set, OBJECT> GET oSettings

	PRIVATE CONSTRUCTOR(initialize AS LOGIC)       
		VAR oThread := Thread.CurrentThread
		SELF:Name := "ThreadState for "+oThread:ManagedThreadId:ToString()
		oSettings := Dictionary<XSharp.Set, OBJECT>{}
		IF initialize
			SELF:BreakLevel := 0
            // Set default values
            FOREACH nSet AS XSharp.Set IN System.Enum.GetValues(typeof(XSharp.Set))
                VAR def := RuntimeStateDefaultValue(nSet)
                IF def != NULL
                    SELF:_SetThreadValue(nSet, def)
                ENDIF
            NEXT
            // The following were skipped above bcause of the NULL check
            SELF:_SetThreadValue<Exception>(Set.FileException,NULL)
            SELF:_SetThreadValue<Exception>(Set.LastRddError,NULL)
            SELF:_SetThreadValue<Exception>(Set.Patharray,NULL)
            SELF:_SetThreadValue<BYTE[]>(Set.CollationTable, NULL )
			IF System.Environment.OSVersion:Platform == System.PlatformID.Win32NT
                SELF:_SetThreadValue<LONG>(Set.DosCodepage, Win32.GetDosCodePage())
                SELF:_SetThreadValue<LONG>(Set.WinCodepage, Win32.GetWinCodePage())
            ELSE
                SELF:_SetThreadValue(Set.CollationMode, CollationMode.Unicode )
            ENDIF
			// Date and time settings
			SELF:_SetInternationalWindows()


		ENDIF
		RETURN
    /// <exclude />
	DESTRUCTOR()
		// What do we need to clean ?
		IF oSettings != NULL
			oSettings:Clear()
		ENDIF

    /// <summary>This method closes all open Workareas for all threads. It is automatically called ad shutdown.</summary>
    /// <remarks>It is usually better to manage the lifetime of your Workarea yourself in code, so don't trust on the runtime to close the Workareas.</remarks>
    STATIC METHOD CloseWorkareasForAllThreads() AS VOID
        TRY
            FOREACH VAR state IN currentState:Values
                IF state:_Workareas != NULL
                    state:_Workareas:CloseAll()
                ENDIF
            NEXT
        CATCH e AS Exception
            System.Diagnostics.Debug.WriteLine(e:ToString())
        END TRY
	PRIVATE METHOD Clone() AS RuntimeState
		LOCAL oNew AS RuntimeState
		oNew := RuntimeState{FALSE}		
		BEGIN LOCK oSettings
			// Copy all values from Current State to New state
			FOREACH VAR element IN oSettings     
				oNew:oSettings[element:Key] := element:Value
			NEXT
		END LOCK
		RETURN oNew     
		
	/// <summary>Retrieve state name</summary>
	/// <returns>String value, such as "State for Thread 123"</returns>IDb
	PUBLIC PROPERTY Name AS STRING AUTO
	/// <summary>Current Break Level. Gets set by compiler generated code for BEGIN SEQUENCE .. END constructs.</summary>
    /// <include file="CoreComments.xml" path="Comments/PerThread/*" />
	PUBLIC PROPERTY BreakLevel AS INT AUTO
	/// <summary>ToString() override</summary>
	/// <returns>String value, such as "State for Thread 123"</returns>
	PUBLIC OVERRIDE METHOD ToString() AS STRING<commit_msg>[Runtime] Do not clone the initialstate for the main thread<commit_after>//
// Copyright (c) XSharp B.V.  All Rights Reserved.  
// Licensed under the Apache License, Version 2.0.  
// See License.txt in the project root for license information.
//

USING System.Collections.Generic
USING System.Threading
USING XSharp.RDD
USING XSharp.RDD.Enums
USING System.Runtime.CompilerServices
/// <summary>
/// Container Class that holds the XSharp Runtime state
/// </summary>
/// <remarks>
/// Please note that unlike in Visual Objects and Vulcan.NET every thread has its own copy of the runtime state.<br/>
/// The runtime state from a new thread is a copy of the state of the main thread at that moment.
/// </remarks>


CLASS XSharp.RuntimeState
	// Static Fields
	PRIVATE INITONLY STATIC initialState  AS RuntimeState
	PRIVATE INITONLY Thread AS Thread
	// Static Methods and Constructor
	private STATIC currentState := ThreadLocal<RuntimeState>{ {=>  initialState:Clone()},TRUE }  AS ThreadLocal<RuntimeState> 
	STATIC CONSTRUCTOR
		initialState	:= RuntimeState{TRUE}

	/// <summary>Retrieve the runtime state for the current thread</summary>
	PUBLIC STATIC METHOD GetInstance() AS RuntimeState
		RETURN currentState:Value

	PRIVATE oSettings AS Dictionary<XSharp.Set, OBJECT>
    /// <summary>The dictionary that stores most of the settings in the runtime state. The key to the index is the number from the Set Enum</summary>
    /// <seealso cref="T:XSharp.Set" >Set Enum</seealso>
    PUBLIC PROPERTY Settings AS Dictionary<XSharp.Set, OBJECT> GET oSettings

	PRIVATE CONSTRUCTOR(initialize AS LOGIC)       
		VAR oThread := Thread.CurrentThread
        SELF:Thread := oThread
		oSettings := Dictionary<XSharp.Set, OBJECT>{}
		IF initialize
			SELF:BreakLevel := 0
            // Set default values
            FOREACH nSet AS XSharp.Set IN System.Enum.GetValues(typeof(XSharp.Set))
                VAR def := RuntimeStateDefaultValue(nSet)
                IF def != NULL
                    SELF:_SetThreadValue(nSet, def)
                ENDIF
            NEXT
            // The following were skipped above bcause of the NULL check
            SELF:_SetThreadValue<Exception>(Set.FileException,NULL)
            SELF:_SetThreadValue<Exception>(Set.LastRddError,NULL)
            SELF:_SetThreadValue<Exception>(Set.Patharray,NULL)
            SELF:_SetThreadValue<BYTE[]>(Set.CollationTable, NULL )
			IF System.Environment.OSVersion:Platform == System.PlatformID.Win32NT
                SELF:_SetThreadValue<LONG>(Set.DosCodepage, Win32.GetDosCodePage())
                SELF:_SetThreadValue<LONG>(Set.WinCodepage, Win32.GetWinCodePage())
            ELSE
                SELF:_SetThreadValue(Set.CollationMode, CollationMode.Unicode )
            ENDIF
			// Date and time settings
			SELF:_SetInternationalWindows()


		ENDIF
		RETURN
    /// <exclude />
	DESTRUCTOR()
		// What do we need to clean ?
		IF oSettings != NULL
			oSettings:Clear()
		ENDIF

    /// <summary>This method closes all open Workareas for all threads. It is automatically called ad shutdown.</summary>
    /// <remarks>It is usually better to manage the lifetime of your Workarea yourself in code, so don't trust on the runtime to close the Workareas.</remarks>
    STATIC METHOD CloseWorkareasForAllThreads() AS VOID
        TRY
            FOREACH VAR state IN currentState:Values
                IF state:_Workareas != NULL
                    state:_Workareas:CloseAll()
                ENDIF
            NEXT
        CATCH e AS Exception
            System.Diagnostics.Debug.WriteLine(e:ToString())
        END TRY
	PRIVATE METHOD Clone() AS RuntimeState
		LOCAL oNew AS RuntimeState
        IF Thread.CurrentThread == initialState:Thread
            RETURN initialState
        ENDIF
		oNew := RuntimeState{FALSE}		
		BEGIN LOCK oSettings
			// Copy all values from Current State to New state
			FOREACH VAR element IN oSettings     
				oNew:oSettings[element:Key] := element:Value
			NEXT
		END LOCK
		RETURN oNew     
		
	/// <summary>Retrieve state name</summary>
	/// <returns>String value, such as "State for Thread 123"</returns>IDb
	PUBLIC PROPERTY Name AS STRING
    GET
        IF SELF:Thread == NULL
            RETURN "ThreadState for Unknown Thread"
        ELSE
            RETURN "ThreadState for "+SELF:Thread:ManagedThreadId:ToString()
        ENDIF
    END GET
    END PROPERTY
	/// <summary>Current Break Level. Gets set by compiler generated code for BEGIN SEQUENCE .. END constructs.</summary>
    /// <include file="CoreComments.xml" path="Comments/PerThread/*" />
	PUBLIC PROPERTY BreakLevel AS INT AUTO
	/// <summary>ToString() override</summary>
	/// <returns>String value, such as "State for Thread 123"</returns>
	PUBLIC OVERRIDE METHOD ToString() AS STRING
{'fraction_non_alphanumeric': 0.08623693379790941, 'fraction_numerical': 0.0032665505226480837, 'mean_word_length': 2.9118398637137988, 'pattern_counts': {'":': 0, '<': 79, '<?xml version=': 0, '>': 81, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 2}, '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': '3379714', 'n_tokens_mistral': 2744, 'n_tokens_neox': 2494, 'n_words': 843}