2024-02-12 19:47:28 +01:00
# CORE FRAMEWORK SOURCE FILE
# Copyright (c) 2024 The StarOpenSource Project & Contributors
2024-03-03 18:53:09 +01:00
# Licensed under the GNU Affero General Public License v3
2024-02-12 19:47:28 +01:00
#
# This program is free software: you can redistribute it and/or modify
2024-03-03 18:53:09 +01:00
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
2024-02-12 19:47:28 +01:00
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2024-03-03 18:53:09 +01:00
# GNU Affero General Public License for more details.
2024-02-12 19:47:28 +01:00
#
2024-03-03 18:53:09 +01:00
# You should have received a copy of the GNU Affero General Public License
2024-02-12 19:47:28 +01:00
# along with this program. If not, see <https://www.gnu.org/licenses/>.
2024-04-08 20:14:38 +02:00
## Contains various utility functions.
2024-02-12 19:47:28 +01:00
##
2024-04-08 20:14:38 +02:00
## This module contains many methods that don't fit into any other module
## and generally make your life as a developer easier.
2024-02-04 21:36:30 +01:00
extends CoreBaseModule
2024-04-15 21:52:27 +02:00
# Configuration
var config_stringify_show_type : bool
var config_stringify_color_range8 : bool
var config_stringify_array : bool
var config_stringify_dictionary : bool
# +++ module +++
func _pull_config ( ) - > void :
config_stringify_show_type = core . config . misc_stringify_show_type
config_stringify_color_range8 = core . config . misc_stringify_color_range8
config_stringify_array = core . config . misc_stringify_array
config_stringify_dictionary = core . config . misc_stringify_dictionary
2024-04-08 20:14:38 +02:00
# +++ data type conversion +++
## Converts a number of bytes into mebibytes.[br]
## [br]
## If [code]flatten[/code] is set to [code]true[/code], the decimal part will be discarded.
2024-02-09 15:28:42 +01:00
@ warning_ignore ( " integer_division " )
func byte2mib ( bytes : int , flatten : bool = true ) - > float :
if flatten : return bytes / 1048576
return bytes / float ( 1048576 )
2024-04-08 20:14:38 +02:00
## Converts a number of mebibytes into bytes.[br]
## [br]
## If [code]flatten[/code] is set to [code]true[/code], the decimal part will be discarded.
2024-02-10 18:48:37 +01:00
func mib2byte ( mib : float , flatten : bool = true ) - > float :
if flatten : return int ( mib * 1048576 )
return mib * 1048576
2024-02-09 15:28:42 +01:00
2024-04-08 20:14:38 +02:00
## Converts a number of mebibytes into gibibytes.[br]
## [br]
## If [code]flatten[/code] is set to [code]true[/code], the decimal part will be discarded.
2024-02-09 15:28:42 +01:00
func mib2gib ( mib : float , flatten : bool = true ) - > float :
2024-02-10 18:48:37 +01:00
if flatten : return int ( mib / 1024 )
return mib / 1024
2024-02-09 15:28:42 +01:00
2024-04-08 20:14:38 +02:00
## Converts a number of gebibytes into mebibytes.[br]
## [br]
## If [code]flatten[/code] is set to [code]true[/code], the decimal part will be discarded.
2024-02-10 18:48:37 +01:00
func gib2mib ( gib : float , flatten : bool = true ) - > float :
if flatten : return int ( gib * 1024 )
return gib * 1024
2024-03-24 15:42:38 +01:00
2024-04-08 20:14:38 +02:00
# +++ type formatting +++
## Converts a string array into a normal, nicely formatted string.[br]
## [br]
## With [code]item_before[/code] and [code]item_after[/code] you can customize the lists apperance. Here's an example on how to format every item bold:
## [codeblock]
## extends Node
##
## var core: Core = get_node("/root/CORE")
## var misc: CoreBaseModule = core.misc
## var logger: CoreLoggerInstance = core.logger.get_instance("some/script.gd")
##
## func _ready() -> void:
2024-04-08 21:19:24 +02:00
## var array: Array[String] = ["Apples", "Bananas", "Oranges"]
##
## logger.info(misc.format_stringarray(array))
## logger.info(misc.format_stringarray(array, "[b]", "[/b]"))
2024-04-08 20:14:38 +02:00
## [/codeblock]
2024-03-24 15:42:38 +01:00
func format_stringarray ( array : Array [ String ] , item_before : String = " " , item_after : String = " " , separator_list : String = " , " , separator_final : String = " & " ) - > String :
var output : String = " "
if array . size ( ) == 0 :
2024-04-08 21:30:24 +02:00
loggeri . warn ( " Unable to format a string with a size of 0 " )
2024-03-24 15:42:38 +01:00
return " "
elif array . size ( ) == 1 :
2024-04-08 21:30:24 +02:00
loggeri . warn ( " Unable to format a string with a size of 1 " )
2024-03-24 15:42:38 +01:00
return array [ 0 ]
for item in array :
if output == " " : output = item_before + item + item_after
else : output = output . replace ( " If you somehow see this text report this at https://git.staropensource.de/StarOpenSource/CORE/issues, thank you! " , separator_list ) + " If you somehow see this text report this at https://git.staropensource.de/StarOpenSource/CORE/issues, thank you! " + item_before + item + item_after
output = output . replace ( " If you somehow see this text report this at https://git.staropensource.de/StarOpenSource/CORE/issues, thank you! " , separator_final )
return output
2024-03-24 15:56:45 +01:00
2024-04-08 20:14:38 +02:00
# +++ array conversion +++
## Converts an array into a string array.[br]
## [br]
## If an item is found that is not of type [code]String[/code], an empty array is returned.
2024-03-24 15:56:45 +01:00
func array_to_stringarray ( array : Array ) - > Array [ String ] :
var output : Array [ String ] = [ ]
for item in array :
if typeof ( item ) != TYPE_STRING :
logger . error ( " Cannot convert Array to Array[String]: Item ' " + str ( item ) + " ' is not of type String " )
return [ ]
output . append ( item )
return output
2024-03-24 22:59:57 +01:00
2024-04-08 20:14:38 +02:00
## Converts a string array into an array.
2024-03-24 22:59:57 +01:00
func stringarray_to_array ( array : Array [ String ] ) - > Array :
var output : Array = [ ]
for item in array :
output . append ( item )
return output
2024-03-25 17:43:13 +01:00
2024-04-08 20:14:38 +02:00
# +++ etc +++
## Calculates the center of the child in the area of the parent.[br]
## [br]
## Example:
## [codeblock]
## extends Control
##
## var core: Core = get_node("/root/CORE")
## var misc: CoreBaseModule = core.misc
##
## func _ready() -> void:
2024-04-08 21:19:24 +02:00
## position = misc.center_object(get_parent().size, size)
2024-04-08 20:14:38 +02:00
## [/codeblock]
2024-03-25 21:10:59 +01:00
func get_center ( parent_size : Vector2 , child_size : Vector2 ) - > Vector2 :
2024-03-25 17:43:13 +01:00
return Vector2 ( parent_size . x / 2 - child_size . x / 2 , parent_size . y / 2 - child_size . y / 2 )
2024-04-08 20:14:38 +02:00
2024-04-15 21:52:27 +02:00
## Makes variables as look correct inside strings.[br]
## Short examples:[br]
## [code]true[/code] -> [code]'true'[/code][br]
## [code]Vector2(69.064, PI)[/code] -> [code]'x=69.064 y=3.14159265358979'[/code][br]
## [code]"This is a test string"[/code] -> [code]'"This is a test string"'[/code][br]
## Full example:[br]
## [codeblock]
## Code:
## logger.diag(stringify_variables("Triggered %trigger% (pos=%position%, successful=%success%)", { "trigger": "shoot", "position": Vector2(5156.149, 581.69), "success": true }))
##
## Output:
## [16:44:35] [DIAG Test.gd] Triggered '"shoot"' (pos='x=5156.149 y=581.69', successful='true')
## [/codeblock]
func stringify_variables ( template : String , variables : Dictionary , no_quotes : bool = false ) - > String :
# To decrease allocations
var value
var type : String = " "
var replacement : String = " "
for placeholder in variables :
# Check key type
if typeof ( placeholder ) != TYPE_STRING :
logger . error ( " Invalid placeholder type ' \" " + type_string ( typeof ( placeholder ) ) + " \" , skipping " )
continue
# Check for correct type
value = variables [ placeholder ]
match ( typeof ( value ) ) :
# Primitives
Variant . Type . TYPE_NIL : replacement = " null "
Variant . Type . TYPE_BOOL : replacement = str ( value )
Variant . Type . TYPE_INT : replacement = str ( value )
Variant . Type . TYPE_FLOAT : replacement = str ( value )
Variant . Type . TYPE_STRING : replacement = " \" " + value + " \" "
Variant . Type . TYPE_STRING_NAME : replacement = " \" " + value + " \" "
# Non-primitives
Variant . Type . TYPE_OBJECT : replacement = str ( value )
Variant . Type . TYPE_COLOR :
if config_stringify_color_range8 : replacement = " r= " + _sa ( value . r8 ) + " g= " + _sa ( value . g8 ) + " b= " + _sa ( value . b8 ) + " a= " + _sa ( value . a8 )
else : replacement = " r= " + _sa ( value . r ) + " g= " + _sa ( value . g ) + " b= " + _sa ( value . b ) + " a= " + _sa ( value . a )
Variant . Type . TYPE_RID : replacement = " id= " + _sa ( value . get_id ( ) ) + " valid= " + _sa ( value . is_valid ( ) )
Variant . Type . TYPE_ARRAY :
if config_stringify_array :
if value . size ( ) == 0 :
replacement = " [] "
else :
replacement = " [ "
for item in value :
if replacement == " [ " : replacement += _sa ( item )
else : replacement += " , " + _sa ( item )
replacement += " ] "
else : replacement = str ( value )
Variant . Type . TYPE_DICTIONARY :
if config_stringify_dictionary :
if value . size ( ) == 0 : replacement = " {} "
else :
replacement = " { "
for key in value :
if replacement == " { " : replacement += _sa ( key ) + " : " + _sa ( value [ key ] )
else : replacement += " , " + _sa ( key )
replacement += " } "
else : replacement = str ( value )
# TODO: Packed Arrays
# Nodes & scripting
Variant . Type . TYPE_NODE_PATH : replacement = str ( value )
Variant . Type . TYPE_CALLABLE : replacement = " valid= " + _sa ( value . is_valid ( ) ) + " standard= " + _sa ( value . is_standard ( ) ) + " object= " + _sa ( value . get_object ( ) ) + " method= " + value . get_method ( ) + " args= " + _sa ( value . get_bound_arguments ( ) )
Variant . Type . TYPE_SIGNAL : replacement = " name= " + _sa ( value . get_name ( ) ) + " object= " + _sa ( value . get_object ( ) )
# 2D
Variant . Type . TYPE_VECTOR2 : replacement = " x= " + _sa ( value . x ) + " y= " + _sa ( value . y )
Variant . Type . TYPE_VECTOR2I : replacement = " x= " + _sa ( value . x ) + " y= " + _sa ( value . y )
Variant . Type . TYPE_RECT2 : replacement = " size= " + _sa ( value . size ) + " pos= " + _sa ( value . position ) + " end= " + _sa ( value . end )
Variant . Type . TYPE_RECT2I : replacement = " size= " + _sa ( value . size ) + " pos= " + _sa ( value . position ) + " end= " + _sa ( value . end )
Variant . Type . TYPE_TRANSFORM2D : replacement = " x= " + _sa ( value . x ) + " y= " + _sa ( value . y ) + " origin= " + _sa ( value . origin )
# 3D
Variant . Type . TYPE_VECTOR3 : replacement = " x= " + _sa ( value . x ) + " y= " + _sa ( value . y ) + " z= " + _sa ( value . z )
Variant . Type . TYPE_VECTOR3I : replacement = " x= " + _sa ( value . x ) + " y= " + _sa ( value . y ) + " z= " + _sa ( value . z )
Variant . Type . TYPE_PLANE : replacement = " x= " + _sa ( value . x ) + " y= " + _sa ( value . y ) + " z= " + _sa ( value . z ) + " d= " + _sa ( value . d ) + " normal= " + _sa ( value . normal )
Variant . Type . TYPE_QUATERNION : replacement = " x= " + _sa ( value . x ) + " y= " + _sa ( value . y ) + " z= " + _sa ( value . z ) + " w= " + _sa ( value . w )
Variant . Type . TYPE_AABB : replacement = " size= " + _sa ( value . size ) + " pos= " + _sa ( value . position ) + " end= " + _sa ( value . end )
Variant . Type . TYPE_TRANSFORM3D : replacement = " basis= " + _sa ( value . basis ) + " origin= " + _sa ( value . origin )
Variant . Type . TYPE_BASIS : replacement = " x= " + _sa ( value . x ) + " y= " + _sa ( value . y ) + " z= " + _sa ( value . z )
Variant . Type . TYPE_PROJECTION : replacement = " x= " + _sa ( value . x ) + " y= " + _sa ( value . y ) + " z= " + _sa ( value . z ) + " w= " + _sa ( value . w )
# 4D
Variant . Type . TYPE_VECTOR4 : replacement = " x= " + _sa ( value . x ) + " y= " + _sa ( value . y ) + " z= " + _sa ( value . z ) + " w= " + _sa ( value . w )
Variant . Type . TYPE_VECTOR4I : replacement = " x= " + _sa ( value . x ) + " y= " + _sa ( value . y ) + " z= " + _sa ( value . z ) + " w= " + _sa ( value . w )
# etc
Variant . Type . TYPE_MAX : replacement = str ( value )
_ :
replacement = str ( value )
type = " (unknown) "
# Replace
if config_stringify_show_type and type == " " :
match ( typeof ( value ) ) :
Variant . Type . TYPE_NIL : type = " "
Variant . Type . TYPE_MAX : type = " (invalid) "
Variant . Type . TYPE_ARRAY :
if value . get_typed_builtin ( ) != TYPE_NIL :
type = " ( " + type_string ( typeof ( value ) ) . to_lower ( ) + " [ " + type_string ( typeof ( value . get_typed_builtin ( ) ) ) . to_lower ( ) + " ]) "
_ : type = " ( " + type_string ( typeof ( value ) ) . to_lower ( ) + " ) " # something is causing almost everything to be displayed as a boolean, which is not true. i don't know what's the problem here however.
var quote : String = " ' " if ! no_quotes else " "
template = template . replace ( " % " + placeholder + " % " , quote + type + replacement + quote )
return template
# Makes calls shorter
func _sa ( value ) - > String :
return stringify_variables ( " % var % " , { " var " : value } , true )
2024-04-08 21:42:03 +02:00
## Moved to [method Core.quit_safely].
## @deprecated
func quit_safely ( exitcode : int = 0 ) - > void : await core . quit_safely ( exitcode )