Seite 1 von 1

Beliebige Map() an Procedure übergeben???

Verfasst: 28.08.2019 12:22
von Thorsten1867
Hat jemand eine Idee wie ich eine beliebige Map() als Parameter für InsertJSONMap() an eine Procedure übergeben kann?

Code: Alles auswählen

NewMap Colors.s()
Colors("red")   = "$0000FF"
Colors("green") = "$00FF00"
Colors("blue")  = "$FF0000"
  
Procedure StoreJSON(???())
 
  If CreateJSON(0)
    InsertJSONMap(JSONValue(0), ???())
    Debug ComposeJSON(0, #PB_JSON_PrettyPrint)
  EndIf
  
EndProcedure

StoreJSON(Colors())

Re: Beliebige Map() an Procedure übergeben???

Verfasst: 28.08.2019 12:31
von Mijikai
Eigentlich sollte ein Pointer übergeben werden können...

Im Englischen Forum gibt es momentan ein Bug Report dazu:
https://www.purebasic.fr/english/viewto ... =4&t=73485

Re: Beliebige Map() an Procedure übergeben???

Verfasst: 28.08.2019 13:05
von STARGÅTE
"beliebig" geht in der Form nicht, aber du kannst Maps von gleichen Typ übergeben, z.B. hier Strings:

Code: Alles auswählen

NewMap Colors.s()
Colors("red")   = "$0000FF"
Colors("green") = "$00FF00"
Colors("blue")  = "$FF0000"
  
Procedure StoreJSON(Map StringMap.s())
 
  If CreateJSON(0)
    InsertJSONMap(JSONValue(0), StringMap())
    Debug ComposeJSON(0, #PB_JSON_PrettyPrint)
  EndIf
  
EndProcedure

StoreJSON(Colors())

Re: Beliebige Map() an Procedure übergeben???

Verfasst: 28.08.2019 13:41
von Thorsten1867
Genau das ist mein Problem. Es muss eine beliebige Map sein.

Re: Beliebige Map() an Procedure übergeben???

Verfasst: 28.08.2019 13:51
von STARGÅTE
Dan würde ich dir zu einem Macro raten.

Code: Alles auswählen

NewMap Colors.s()
Colors("red")   = "$0000FF"
Colors("green") = "$00FF00"
Colors("blue")  = "$FF0000"
  
NewMap Indices.i()
Indices("red")   = 1
Indices("green") = 2
Indices("blue")  = 3
  
Macro StoreJSON(MapName)
 
  If CreateJSON(0)
    InsertJSONMap(JSONValue(0), MapName)
    Debug ComposeJSON(0, #PB_JSON_PrettyPrint)
  EndIf
  
EndMacro

StoreJSON(Colors())

StoreJSON(Indices())

Re: Beliebige Map() an Procedure übergeben???

Verfasst: 28.08.2019 14:10
von mhs
Oder du arbeitest mit einer Struktur als Wrapper:

Code: Alles auswählen

Enumeration
  #MAP_ABC
  #MAP_NUM
EndEnumeration

Structure Maps

  type.i
  
  Map abc.s()
  Map num.i()
  
EndStructure

Procedure Test(*items.Maps)

  If *items\type = #MAP_ABC
    ForEach *items\abc()
      Debug *items\abc()
    Next
  EndIf

  If *items\type = #MAP_NUM
    ForEach *items\num()
      Debug *items\num()
    Next
  EndIf
  
EndProcedure

; ---

Define map_1.Maps, map_2.Maps

map_1\type = #MAP_ABC
map_1\abc("a") = "A"
map_1\abc("b") = "B"
map_1\abc("c") = "C"

map_2\type = #MAP_NUM
map_2\num("1") = 1
map_2\num("2") = 2
map_2\num("3") = 3

Test(map_1)
Test(map_2)
(ja, auch keine wirklich schöne Lösung...)

Re: Beliebige Map() an Procedure übergeben???

Verfasst: 28.08.2019 16:56
von Thorsten1867
Die Ideen sind schon gut, aber leider funktionieren sie in Kombination mit einem Modul leider nicht.

Re: Beliebige Map() an Procedure übergeben???

Verfasst: 28.08.2019 17:02
von mhs
Hast du uns ein Beispiel?

Re: Beliebige Map() an Procedure übergeben???

Verfasst: 29.08.2019 08:15
von Thorsten1867

Code: Alles auswählen

DeclareModule Pack
  Declare AddJSONMap(Pack.i, PackedName.s, MapName())
EndDeclareModule

Module Pack
  
  Procedure AddJSONMap(Pack.i, PackedName.s, MapName())
    Define.i JSON, Size
    Define   *Buffer
    
    JSON = CreateJSON(#PB_Any)
    If JSON 
      
      InsertJSONMap(JSONValue(JSON), MapName())
      
      Size = ExportJSONSize(JSON)
      *Buffer = AllocateMemory(Size)
      If *Buffer
        
        If ExportJSON(JSON, *Buffer, Size)    
          AddPackMemory(Pack, *Buffer, Size, PackedName)
        EndIf
   
        FreeMemory(*Buffer)
      EndIf  
      
     
      FreeJSON(JSON)
    EndIf

  EndProcedure
  
EndModule

Re: Beliebige Map() an Procedure übergeben???

Verfasst: 29.08.2019 09:03
von mhs
Beide Varianten funktionieren in einem Modul:

Code: Alles auswählen

DeclareModule Pack

  Enumeration
    #MAP_ABC
    #MAP_NUM
  EndEnumeration
  
  Structure Maps
  
    type.i
   
    Map abc.s()
    Map num.i()
   
  EndStructure

  Macro StoreJSON(MapName)
   
    If CreateJSON(0)
      InsertJSONMap(JSONValue(0), MapName)
      Debug ComposeJSON(0, #PB_JSON_PrettyPrint)
    EndIf
   
  EndMacro

  Declare AddJSONMap(Pack.i, PackedName.s, *Map.Maps)
  
EndDeclareModule

Module Pack
 
  Procedure AddJSONMap(Pack.i, PackedName.s, *Map.Maps)
    Define.i JSON, Size
    Define   *Buffer
   
    JSON = CreateJSON(#PB_Any)
    If JSON
     
      Select *Map\type
        Case #MAP_ABC: InsertJSONMap(JSONValue(JSON), *Map\abc())
        Case #MAP_NUM: InsertJSONMap(JSONValue(JSON), *Map\num())
      EndSelect
     
     Debug ComposeJSON(JSON, #PB_JSON_PrettyPrint)
     
      Size = ExportJSONSize(JSON)
      *Buffer = AllocateMemory(Size)
      If *Buffer
       
        If ExportJSON(JSON, *Buffer, Size)   
          AddPackMemory(Pack, *Buffer, Size, PackedName)
        EndIf
   
        FreeMemory(*Buffer)
      EndIf 
     
     
      FreeJSON(JSON)
    EndIf

  EndProcedure
 
EndModule

; ---

NewMap num.i()
num("1") = 1
num("3") = 2
num("4") = 3

Define maps.Pack::Maps

maps\type = Pack::#MAP_ABC
maps\abc("a") = "A"
maps\abc("b") = "B"
maps\abc("c") = "C"

Pack::StoreJSON(num())
Pack::AddJSONMap(0, "Pack", maps)
Das Makro ist die universelle Lösung, dem du wirklich jede Map übergeben kannst, was in deinem Fall sinnvoller erscheint wenn du ein allgemeingültiges Modul schreibst. Die Wrapperstruktur wäre mehr etwas für spezifisches Projekt, in dem es nur eine Hand voll festgelegter Maps geben kann.

Du kannst auch eine Kombination aus Makro und Prozedur schreiben, im Makro erzeugst du das JSON und fügst die Map ein, dann übergibst du innerhalb des Makros das JSON an eine Prozedur, die den Rest erledigt.