Page 2 of 2
Re: Using adresses as a key for AddMapElements ???
Posted: Thu Dec 19, 2019 5:59 pm
by wilbert
Joris wrote:it can vary by user use of the program, but I suppose it will mostly be less then 100, but yeah, that's my guess...
With that little items, you could probably also do with a simple structured array with key / value fields.
But I'll probably trie to create a simple numeric map myself.
Re: Using adresses as a key for AddMapElements ???
Posted: Thu Dec 19, 2019 6:32 pm
by C87
There are several statements in this Topic that these functions aren't referenced in the HELP file. Can I ask a what may be a stupid question? :
If they aren't in the HELP file, how on earth does anyone know they exist?
( an earlier Topic NumericMap by idle made reference to these functions and I just gave up in the end
)
Re: Using adresses as a key for AddMapElements ???
Posted: Thu Dec 19, 2019 6:44 pm
by Tenaja
C87 wrote:If they aren't in the HELP file, how on earth does anyone know they exist?
Look at the asm code that is generated when you use Maps. (There are quite a few forum threads on this topic.)
This actually brings up the point that if someone were to rely on the code suggested that the PB version should be listed, as well as assumptions (such as the Map library has not been updated...).
Re: Using adresses as a key for AddMapElements ???
Posted: Thu Dec 19, 2019 9:06 pm
by idle
Tenaja wrote:C87 wrote:If they aren't in the HELP file, how on earth does anyone know they exist?
Look at the asm code that is generated when you use Maps. (There are quite a few forum threads on this topic.)
This actually brings up the point that if someone were to rely on the code suggested that the PB version should be listed, as well as assumptions (such as the Map library has not been updated...).
you can find the headers in the sdk /PureBasic/sdk/c/PureLibraries/
These headers can change with a new version of PB so yes any code using them could break with a new release of PB, so version checking would be the sane thing to do.
Re: Using adresses as a key for AddMapElements ???
Posted: Tue Jan 14, 2020 7:08 pm
by chi
idle wrote:chi wrote:This is fantastic! Thank you, idle
Now I can finally get rid of converting the hWnd to a string first...
try this, think I've got it sorted so you can use native types but might not work on osx
Code: Select all
;NumericMap hack for structured Numeric keyed Maps
;windows linux osx
Import ""
PB_NewNumericMap(ElementSize.i,*StructureMap,*Address,HashTabelSize.l);
PB_FreeMap(*Map) ;
PB_ResetMap(*Map) ;
PB_ClearMap(*Map) ;
PB_MapSize(*Map) ;
PB_PushMapPosition(*map) ;
PB_PopMapPosition(*map) ;
PB_NextMapElement(*Map) ;
PB_FindNumericMapElement(*Map,Key.i) ;
PB_AddNumericMapElement(*Map,Key.i) ;
PB_AddNumericMapElement2(*Map,Key.i,ElementCheck=#PB_Map_ElementCheck);
PB_DeleteNumericMapElement2(*Map,Key.i) ;
PB_DeleteNumericMapElement(*Map) ;
PB_CopyMap(*Map,*DestinationMap) ;
PB_CopyMap2(*Map,*DestinationMap,Clear.l) ;
EndImport
Macro NewNumericMap(pmap,HashTableSize,StructureType,IsStructure=0)
Global structadr=0
EnableASM
CompilerIf #PB_Compiler_Processor = #PB_Processor_x64
CompilerIf IsStructure
lea rax,[s_#StructureType]
mov [v_structadr],rax
CompilerEndIf
CompilerElse
CompilerIf IsStructure
lea eax,[s_#StructureType]
mov [v_structadr],eax
CompilerEndIf
CompilerEndIf
DisableASM
PB_NewNumericMap(SizeOf(StructureType),structadr,@pmap,HashTableSize)
EndMacro
Procedure NumericMapkey(*Map)
Protected ele,key
ele = PeekI(*map)
key = PeekI(ele+SizeOf(Integer))
ProcedureReturn key
EndProcedure
CompilerIf #PB_Compiler_IsMainFile
;Note you need to use a structured element pointer even for native types
Structure foo
List controls.i()
i.i
s.s
EndStructure
Procedure test()
Protected mp, *el.foo
NewNumericMap(mp,512,foo,#PB_Structure) ;create the map and pass map variable, number of elements, the name of the structure
*el = PB_AddNumericMapElement(mp,123)
AddElement(*el\controls())
*el\controls() = 111
AddElement(*el\controls())
*el\controls() = 112
*el\i = 123
*el\s = "Hello"
;
*el = PB_AddNumericMapElement2(mp,345)
AddElement(*el\controls())
*el\controls() = 113
AddElement(*el\controls())
*el\controls() = 114
*el\i = 345
*el\s = "World"
;
*el = PB_FindNumericMapElement(mp,123)
ForEach *el\controls()
Debug "list Controls " + *el\controls()
Next
Debug "integer " + *el\i
Debug "string " + *el\s
*el = PB_FindNumericMapElement(mp,345)
ForEach *el\controls()
Debug "list Controls " + *el\controls()
Next
Debug "integer " + *el\i
Debug "string " + *el\s
Debug "+++++++++++"
Debug "walk the map"
Debug "+++++++++++"
PB_ResetMap(mp)
Repeat
*el = PB_NextMapElement(mp)
If *el
Debug "mapkey " + NumericMapkey(mp)
ForEach *el\controls()
Debug "list Controls " + *el\controls()
Next
Debug "integer " + *el\i
Debug "string " + *el\s
EndIf
Until *el=0
Debug "++++++++++++++"
Debug "clear map"
PB_ClearMap(mp);
PB_ResetMap(mp)
Repeat
*el = PB_NextMapElement(mp)
If *el
Debug "mapkey " + NumericMapkey(mp)
ForEach *el\controls()
Debug "list Controls " + *el\controls()
Next
Debug "integer " + *el\i
Debug "string " + *el\s
EndIf
Until *el=0
Debug "should be nothing"
PB_FreeMap(mp)
Debug "++++++++++++"
Debug "test with a native type via pointer"
Protected *elf.float
NewNumericMap(mp,512,float) ;create the map and pass map variable, number of elements, the name of the structure
*elf = PB_AddNumericMapElement(mp,123)
*elf\f = #PI
*elf = PB_AddNumericMapElement(mp,345)
*elf\f = 2*#PI
*elf = PB_FindNumericMapElement(mp,123)
Debug *elf\f
*elf = PB_FindNumericMapElement(mp,345)
If *elf
Debug *elf\f
EndIf
Debug NumericMapkey(mp)
PB_FreeMap(mp)
EndProcedure
test()
CompilerEndIf
[/size]
@idle: Unfortunately your code only works with the Debugger enabled. With a disabled Debugger or trying to create an executable, I get a bunch of POLINK errors
Edit: Btw, it works if you call "NewMap dummy.foo()" somewhere and remove all "PB_FreeMap(mp) " calls...
Re: Using adresses as a key for AddMapElements ???
Posted: Wed Jan 15, 2020 12:31 am
by idle
hmmm never thought to try it without the debugger, still need to create dummy map and the PB_FreeNumericMap macro will need some fix up for x86 linux and osx.
Code: Select all
;NumericMap hack for structured Numeric keyed Maps
;windows linux osx
NewMap dummy()
FreeMap(dummy())
Import ""
PB_InitMap()
PB_NewNumericMap(ElementSize.i,*StructureMap,*Address,HashTabelSize.l);
PB_FreeMap(*Map) ;
PB_ResetMap(*Map) ;
PB_ClearMap(*Map) ;
PB_MapSize(*Map) ;
PB_PushMapPosition(*map) ;
PB_PopMapPosition(*map) ;
PB_NextMapElement(*Map) ;
PB_FindNumericMapElement(*Map,Key.i) ;
PB_AddNumericMapElement(*Map,Key.i) ;
PB_AddNumericMapElement2(*Map,Key.i,ElementCheck=#PB_Map_ElementCheck);
PB_DeleteNumericMapElement2(*Map,Key.i) ;
PB_DeleteNumericMapElement(*Map) ;
PB_CopyMap(*Map,*DestinationMap) ;
PB_CopyMap2(*Map,*DestinationMap,Clear.l) ;
EndImport
Macro PB_FreeNumericMap(pmap)
EnableASM
CompilerIf #PB_Compiler_Processor = #PB_Processor_x64
PUSH pmap
POP rdi
CALL PB_FreeMap
CompilerElse
PUSH pmap
CALL _PB_FreeMap@4 ;might need changing for x86 linux osx
CompilerEndIf
DisableASM
EndMacro
Macro NewNumericMap(pmap,HashTableSize,StructureType,IsStructure=0)
Global structadr=0
EnableASM
CompilerIf #PB_Compiler_Processor = #PB_Processor_x64
CompilerIf IsStructure
lea rax,[s_#StructureType]
mov [v_structadr],rax
CompilerEndIf
CompilerElse
CompilerIf IsStructure
lea eax,[s_#StructureType]
mov [v_structadr],eax
CompilerEndIf
CompilerEndIf
DisableASM
PB_NewNumericMap(SizeOf(StructureType),structadr,@pmap,HashTableSize)
EndMacro
Procedure NumericMapkey(*Map)
Protected ele,key
ele = PeekI(*map)
key = PeekI(ele+SizeOf(Integer))
ProcedureReturn key
EndProcedure
CompilerIf #PB_Compiler_IsMainFile
;Note you need to use a structured element pointer even for native types
OpenConsole()
;PB_InitMap()
Structure foo
List controls.i()
i.i
s.s
EndStructure
Procedure test()
Protected mp, *el.foo
NewNumericMap(mp,512,foo,#PB_Structure) ;create the map and pass map variable, number of elements, the name of the structure
*el = PB_AddNumericMapElement(mp,123)
AddElement(*el\controls())
*el\controls() = 111
AddElement(*el\controls())
*el\controls() = 112
*el\i = 123
*el\s = "Hello"
;
*el = PB_AddNumericMapElement2(mp,345)
AddElement(*el\controls())
*el\controls() = 113
AddElement(*el\controls())
*el\controls() = 114
*el\i = 345
*el\s = "World"
;
*el = PB_FindNumericMapElement(mp,123)
ForEach *el\controls()
PrintN( "list Controls " + *el\controls())
Next
PrintN( "integer " + *el\i)
PrintN( "string " + *el\s)
*el = PB_FindNumericMapElement(mp,345)
ForEach *el\controls()
PrintN( "list Controls " + *el\controls())
Next
PrintN( "integer " + *el\i)
PrintN( "string " + *el\s)
PrintN( "+++++++++++")
PrintN( "walk the map")
PrintN( "+++++++++++")
PB_ResetMap(mp)
Repeat
*el = PB_NextMapElement(mp)
If *el
PrintN( "mapkey " + NumericMapkey(mp))
ForEach *el\controls()
PrintN( "list Controls " + *el\controls())
Next
PrintN( "integer " + *el\i)
PrintN( "string " + *el\s)
EndIf
Until *el=0
PrintN( "++++++++++++++")
PrintN( "clear map")
PB_ClearMap(mp);
PB_ResetMap(mp)
Repeat
*el = PB_NextMapElement(mp)
If *el
PrintN( "mapkey " + NumericMapkey(mp))
ForEach *el\controls()
PrintN( "list Controls " + *el\controls())
Next
PrintN( "integer " + *el\i)
PrintN( "string " + *el\s)
EndIf
Until *el=0
PrintN( "should be nothing")
PB_FreeNumericMap(mp)
PrintN( "++++++++++++")
PrintN( "test with a native type via pointer")
Protected *elf.float
NewNumericMap(mp,512,float) ;create the map and pass map variable, number of elements, the name of the structure
*elf = PB_AddNumericMapElement(mp,123)
*elf\f = #PI
*elf = PB_AddNumericMapElement(mp,345)
*elf\f = 2*#PI
*elf = PB_FindNumericMapElement(mp,123)
PrintN(StrF(*elf\f))
*elf = PB_FindNumericMapElement(mp,345)
If *elf
PrintN(StrF(*elf\f))
EndIf
PrintN(Str(NumericMapkey(mp)))
PB_FreeNumericMap(mp)
EndProcedure
test()
Input()
CompilerEndIf
Re: Using adresses as a key for AddMapElements ???
Posted: Thu Jan 16, 2020 12:17 pm
by chi
idle wrote:hmmm never thought to try it without the debugger...
Neither did I
idle wrote:...and the PB_FreeNumericMap macro will need some fix up for x86 linux and osx
Now I get an IMA on PB_FreeNumericMap (Win7 x64, PB5.71 x64) with the debugger enabled
But don't waste your precious time on this! Who knows in what state Fred left NumericMaps and since he never bothered to answer what's wrong with it and why he didn't finish the implementation, one can only say: "Don't use 'em". I personally switched to wilbert's
NKMaps, which are even slightly faster in my tests...
Re: Using adresses as a key for AddMapElements ???
Posted: Thu Jan 16, 2020 9:14 pm
by idle
chi wrote:idle wrote:hmmm never thought to try it without the debugger...
Neither did I
idle wrote:...and the PB_FreeNumericMap macro will need some fix up for x86 linux and osx
Now I get an IMA on PB_FreeNumericMap (Win7 x64, PB5.71 x64) with the debugger enabled
But don't waste your precious time on this! Who knows in what state Fred left NumericMaps and since he never bothered to answer what's wrong with it and why he didn't finish the implementation, one can only say: "Don't use 'em". I personally switched to wilbert's
NKMaps, which are even slightly faster in my tests...
That's the problem with dirty hacks they often fall over. Wilberts NKMap should be fine