Ich will nicht wissen wie deine Messie Wohnung aussieht
Aber jeder nach seiner Fason, wenn er sonst nicht zu tun hat ......... oder zu faul ist

Das ist genau der Punkt, bei dem Du Dich irrst. Außerhalb des eigenen Mikrokosmos gelten evtl. andere "Naturgesetze" als die, die man aus eigener Erfahrung kennt. Ich habe aber gelernt damit umzugehen, dass die meisten Mitmenschen nur ihre eigene Meinung und Einschätzungen gelten lassen. Von daher alles gut.ts-soft hat geschrieben:...der Aufwand steht in keinem Verhältnis zum Ergebnis und bringt niemanden etwas.


Da gebe ich dir recht. Unbenutze Feld-Variablen von Strukturen sollte man ebenfalls besser drin lassen...ts-soft hat geschrieben:Ich deklariere auch gerne Konstanten, die zwar nicht genutzt werden, aber zum Thema gehören. Wenn das "Unsauberer Code" ist, dann will ich nur noch unsauberen Code
Ich denke da eher an ein einfaches Tool. Um wirklich alles zu prüfen, ob es unbenutzt ist, wäre ein Mammutprojekt und nahezu ein kompletter PureBasic-Code-Parser.ts-soft hat geschrieben:Im Ernst, der Aufwand steht in keinem Verhältnis zum Ergebnis und bringt niemanden etwas. Aber jeder nach seiner Fason, wenn er sonst nicht zu tun hat

Hallo Sicro, Du musst Dir da nicht so viel Arbeit mit machen. Also von meiner Seite aus war das keine Programmier-Bitte an Dich.Sicro hat geschrieben:Mein erster Gedanke war alle Objekte-Vorkommnisse zu zählen. Die Zählung wäre dabei natürlich pro Module und Procedure separat behandelt worden.
Probleme:
Keine Unterscheidung zwischen globalen und lokalen Objekten
Objekt-Typ (Procedure? Variable? Array?) wird dabei nicht ermittelt (Ok, zwischen normaler Variable und Procedure/Array/Liste könnte man anhand der angehängten geöffneten Klammer unterscheiden)
... es steht also nur jeweils der Objekt-Name und die Anzahl der Vorkommnisse in der Baum-strukturierten Ergebnisliste.
Die Sache mit dem Programmierstil ist immer so eine Sache... Ich hänge mal den Code meines aktuellen, aber unfertigen Moduls hier rein, dann kannst Du beurteilen, ob Deine Einwände oben zutreffen.Sicro hat geschrieben:@Kurzer:
Am besten wäre sicherlich, wenn du deinen Programmierstil verbesserst:Danach sollte es nicht mehr so viele Variablen in einem Scope (Haupt-Code, Modul, Procedure) geben. Code-Leichen durch Entfernen von Code wird dadurch ebenfalls weitestgehend vermieden.
- Globale Variablen weitestgehend vermeiden
- Code modularer gestalten: Codes in mehr Proceduren auslagern (vorzugsweise sollten die Proceduren in anderen Projekten einfach wiederverwendbar sein)
- Proceduren schlank halten, damit sie ohne zu scrollen vollständig sichtbar sind

Code: Alles auswählen
;*************************************************************************
;*
;* GraphGadget (c) Kurzer
;*
;*************************************************************************
;*
;* Modulname : GraphGadget
;* Filename : mod_GraphGadget.pbi
;* Filetype : Module [MainApp, Formular, Include, Module, Data]
;* Programming lang. : Purebasic 5.62
;* String-Format : Unicode [Ascii, Unicode, Multi]
;* Platform : Windows [Windows, Mac, Linux, Multi]
;* Processor : Multi [x86, x64, Multi]
;* Compileroptions : -
;* Version : 1.00
;* Date : xx.xx.20xx
;* Autor : Kurzer
;* -----------------------------------------------------------------------
;* DESCRIPTION:
;*
;* ...
;*
;* -----------------------------------------------------------------------
;* Changelog:
;* 1.00 - rel xx.xx.xx:
;* Erste Version
;*
;*************************************************************************
;*************************************************************************
;- Constants global scope
;*************************************************************************
Enumeration 1
#GG_DATAMODE_BYTE
#GG_DATAMODE_WORD
#GG_DATAMODE_LONG
#GG_DATAMODE_INTEGER
#GG_DATAMODE_QUAD
#GG_DATAMODE_FLOAT
#GG_DATAMODE_DOUBLE
EndEnumeration
DeclareModule GraphGadget
;- --- [Declaration] -------------------------------------------------------
;*************************************************************************
;- Compiler directives (module scope only)
;*************************************************************************
EnableExplicit
;*************************************************************************
;- Macros (module scope only)
;*************************************************************************
;*************************************************************************
;- Constants (module scope only)
;*************************************************************************
Enumeration 1
#GG_DATAMODE_BYTE
#GG_DATAMODE_WORD
#GG_DATAMODE_LONG
#GG_DATAMODE_INTEGER
#GG_DATAMODE_QUAD
#GG_DATAMODE_FLOAT
#GG_DATAMODE_DOUBLE
EndEnumeration
#GG_MINBORDERSIZE = 0
#GG_MINBUTTONSIZE = 10
#GG_MINGRIDSIZE = 2
#GG_MINVIEWHEIGHT = 10
#GG_MAXBUFFERS = 10 ; 0 - 9
#GG_DEFAULT_SHOWDATA = #False
#GG_DEFAULT_SHOWGRID = #True
#GG_DEFAULT_GRIDSIZE = 90
#GG_DEFAULT_BORDERSIZE = 5
#GG_DEFAULT_BUTTONSIZE =25
#GG_DEFAULT_BACKGROUNDCOLOUR = $474746
#GG_DEFAULT_BORDERCOLOUR = $F6F6F5
#GG_DEFAULT_GRAPHCOLOUR = $D3FFDA
#GG_DEFAULT_GRIDCOLOUR = $BFFEFF
#GG_GRIDFONTSIZE = 8
;*************************************************************************
;- Structures (module scope only)
;*************************************************************************
Structure Graph
iGraphCanvasID.i
iGraphFontID.i
iGraphX.i ; Position within the Container Canvas gadeget
iGraphY.i ; -"-
iGraphWidth.i ; Size of the graph view (will be calculated)
iGraphHeight.i ; -"-
iGraphBackgroundColour.i ; Backgroundcolour of the graph view
EndStructure
Structure Buttons
iButtonSize.i ; Size of the controllbuttons (width & heigth)
iButtonBeginID.i
iButtonBeginX.i
iButtonBeginY.i
iButtonPageBackID.i
iButtonPageBackX.i
iButtonPageBackY.i
iButtonBackID.i
iButtonBackX.i
iButtonBackY.i
iButtonForwardID.i
iButtonForwardX.i
iButtonForwardY.i
iButtonPageForwarID.i
iButtonPageForwardX.i
iButtonPageForwardY.i
iButtonEndID.i
iButtonEndX.i
iButtonEndY.i
iScrollBarID.i
iScrollBarWidth.i
iScrollBarX.i
iScrollBarY.i
EndStructure
Structure Buffer
iBufferAddress.i ; Startaddress of the databuffer
iBufferLengthInBytes.i ; Length of the databuffer in bytes
iBufferLengthInRecords.i ; Length of the databuffer in records (entries)
iBufferOffsetInRecords.i ; Offset in records of the read pointer starting from the buffer address
iBufferDataMode.i ; How to interpret the data in the buffer (see #GG_DATAMODE_XY constants)
iBufferRecordSize.i ; How many bytes does a single value in the buffer need (depending on the Datamode)?
iBufferShowData.i ; Set to #True if the buffer data have to be shown in the graph, otherwise set to #False
iBufferShowGrid.i ; Set to #True if the scaling grid have to be shown in the graph, otherwise set to #False
iBufferGraphGridSize.i ; Size of the scale grid that belongs to the buffer data
iBufferGraphGridYPos.i ; Y-Position of the scale grid within the graph canvas in pixels
iBufferGraphColour.i ; Color of the graph that belongs to the buffer data
iBufferGraphGridColour.i ; Color of the scale grid that belongs to the buffer data
EndStructure
Structure GraphGadget
; Gadget
iGadgetCanvasID.i
iGadgetX.i ; Position of the Container Canvas gadeget
iGadgetY.i ; -"-
iGadgetWidth.i ; Size of the whole gadget
iGadgetHeight.i ; -"-
iGadgetBorderSize.i ; Size of the gadget border
iGadgetBorderColour.i ; Bordercolour of the view
iGadgetMutex.i ; Mutex object for internal functions. Prevents collisions when accessing a gadget from multiple threads.
stGraph.Graph ; Graph canvas
; Buttons
stButtons.Buttons ; Controllbuttons
; Buffers
stBuffer.Buffer[10]
EndStructure
;*************************************************************************
;- Variables, Arrays, Linked Lists, Maps (module scope only)
;*************************************************************************
;*************************************************************************
;- Interfaces, Prototypes (module scope only)
;*************************************************************************
;*************************************************************************
;- Procedures (public)
;*************************************************************************
Declare.i Create(x.i, y.i, iGadgetWidth.i, iGadgetHeight.i, iGadgetBorderSize=#GG_DEFAULT_BORDERSIZE, iButtonSize=#GG_DEFAULT_BUTTONSIZE, iGadgetBorderColour.i=#GG_DEFAULT_BORDERCOLOUR, iGraphBackgroundColour.i=#GG_DEFAULT_BACKGROUNDCOLOUR)
Declare Free(*GraphGadget.GraphGadget)
Declare Update(*GraphGadget.GraphGadget)
Declare.i SetBuffer(*GraphGadget.GraphGadget, iBufferNumber.i, iBufferAddress.i, iBufferLength.i, iBufferOffset.i=0, iBufferDataMode=#GG_DATAMODE_INTEGER, iBufferGraphColour.i=#GG_DEFAULT_GRAPHCOLOUR)
Declare.i SetBufferOffset(*GraphGadget.GraphGadget, iBufferNumber.i, iBufferOffsetInRecords.i=0)
Declare.i SetBufferGrid(*GraphGadget.GraphGadget, iBufferNumber.i, iBufferShowGrid.i=#False, iBufferGraphGridSize.i=#GG_DEFAULT_GRIDSIZE, iBufferGraphGridYPos.i=-1, iBufferGraphGridColour.i=#GG_DEFAULT_GRIDCOLOUR)
Declare ClearBuffer(*GraphGadget.GraphGadget, iBufferNumber.i)
Declare.i Id(*GraphGadget.GraphGadget)
EndDeclareModule
Module GraphGadget
;-
;- --- [Implementation] -------------------------------------------------------
;-
;*************************************************************************
;- Private Procedures
;*************************************************************************
Procedure CalcGUI(*GraphGadget.GraphGadget)
; +-----------------------------------------------------------------
; |Description : -
; |Arguments : arg1 : Handle to struct
; |Results : -
; |Remarks : -
; +-----------------------------------------------------------------
With *GraphGadget
\stGraph\iGraphX = \iGadgetBorderSize
\stGraph\iGraphY = \iGadgetBorderSize
\stGraph\iGraphWidth = \iGadgetWidth - \iGadgetBorderSize * 2
\stGraph\iGraphHeight = \iGadgetHeight - \stButtons\iButtonSize - (\iGadgetBorderSize * 3)
\stButtons\iButtonBeginY = \iGadgetHeight - \iGadgetBorderSize - \stButtons\iButtonSize
\stButtons\iButtonPageBackY = \stButtons\iButtonBeginY
\stButtons\iButtonBackY = \stButtons\iButtonBeginY
\stButtons\iButtonForwardY = \stButtons\iButtonBeginY
\stButtons\iButtonPageForwardY = \stButtons\iButtonBeginY
\stButtons\iButtonEndY = \stButtons\iButtonBeginY
\stButtons\iScrollBarY = \stButtons\iButtonBeginY
\stButtons\iButtonBeginX = \iGadgetBorderSize
\stButtons\iButtonPageBackX = \stButtons\iButtonBeginX + \stButtons\iButtonSize + \iGadgetBorderSize
\stButtons\iButtonBackX = \stButtons\iButtonPageBackX + \stButtons\iButtonSize + \iGadgetBorderSize
\stButtons\iButtonForwardX = \stButtons\iButtonBackX + \stButtons\iButtonSize + \iGadgetBorderSize
\stButtons\iButtonPageForwardX = \stButtons\iButtonForwardX + \stButtons\iButtonSize + \iGadgetBorderSize
\stButtons\iButtonEndX = \stButtons\iButtonPageForwardX + \stButtons\iButtonSize + \iGadgetBorderSize
\stButtons\iScrollBarX = \stButtons\iButtonEndX + \stButtons\iButtonSize + \iGadgetBorderSize
\stButtons\iScrollBarWidth = \iGadgetWidth - \stButtons\iScrollBarX - \iGadgetBorderSize
EndWith
EndProcedure
Procedure SetScrollBarValues(*GraphGadget.GraphGadget, iBufferNumber.i)
; +-----------------------------------------------------------------
; |Description : -
; |Arguments : arg1 : Handle to struct
; |Results : -
; |Remarks : -
; +-----------------------------------------------------------------
With *GraphGadget
SetGadgetAttribute(\stButtons\iScrollBarID, #PB_ScrollBar_Minimum, 0)
; SetGadgetAttribute(\stButtons\iScrollBarID, #PB_ScrollBar_Maximum, \stBuffer[iBufferNumber]\iBufferLength)
; HIER
EndWith
ProcedureReturn #True
EndProcedure
Procedure.i IsBufferValid(*GraphGadget.GraphGadget, iBufferNumber.i)
; +-----------------------------------------------------------------
; |Description : -
; |Arguments : arg1 : Handle to struct
; |Results : #True if buffer is valid, otherwise #False
; |Remarks : -
; +-----------------------------------------------------------------
With *GraphGadget
If \stBuffer[iBufferNumber]\iBufferAddress = 0 Or
\stBuffer[iBufferNumber]\iBufferLengthInBytes = 0 Or
\stBuffer[iBufferNumber]\iBufferLengthInRecords = 0 Or
\stBuffer[iBufferNumber]\iBufferOffsetInRecords >= \stBuffer[iBufferNumber]\iBufferLengthInRecords Or
\stBuffer[iBufferNumber]\iBufferDataMode = 0 Or
\stBuffer[iBufferNumber]\iBufferGraphGridSize < #GG_MINGRIDSIZE
ProcedureReturn #False
EndIf
EndWith
ProcedureReturn #True
EndProcedure
Procedure DrawGrid(*GraphGadget.GraphGadget)
; +-----------------------------------------------------------------
; |Description : -
; |Arguments : arg1 : Handle to struct
; |Results : -
; |Remarks : -
; +-----------------------------------------------------------------
Protected.i x, iGridValue, iBufferNumber, iGridOffset, iGridLineLength
Protected.s sGridValue
With *GraphGadget
If StartDrawing(CanvasOutput(\stGraph\iGraphCanvasID))
; Erase Background
DrawingMode(#PB_2DDrawing_Default)
Box(0, 0, \stGraph\iGraphWidth, \stGraph\iGraphHeight, \stGraph\iGraphBackgroundColour)
For iBufferNumber = 0 To #GG_MAXBUFFERS - 1
; Debug "Nr.: " + Str(iBufferNumber) + ", Adr:" + Str(\stBuffer[iBufferNumber]\iBufferAddress) + ", Len:" + Str(\stBuffer[iBufferNumber]\iBufferLength) + ", GridSize: " + Str(\stBuffer[iBufferNumber]\iBufferGraphGridSize) + ", Valid: " + Str(IsBufferValid(*GraphGadget, iBufferNumber))
If IsBufferValid(*GraphGadget, iBufferNumber) = #True And \stBuffer[iBufferNumber]\iBufferShowGrid = #True
; Correct the buffer offset to display only up to the buffer length in the graph.
If \stBuffer[iBufferNumber]\iBufferOffsetInRecords + \stGraph\iGraphWidth > \stBuffer[iBufferNumber]\iBufferLengthInRecords
iGridOffset = \stBuffer[iBufferNumber]\iBufferLengthInRecords - \stGraph\iGraphWidth
iGridLineLength = \stBuffer[iBufferNumber]\iBufferLengthInRecords - 1
If iGridOffset < 1 : iGridOffset = 0 : x = 0 : EndIf
x = - iGridOffset % \stBuffer[iBufferNumber]\iBufferGraphGridSize
; Draw END line
Line(iGridLineLength, \stBuffer[iBufferNumber]\iBufferGraphGridYPos-15, 1, 30, \stBuffer[iBufferNumber]\iBufferGraphGridColour)
Else
iGridOffset = \stBuffer[iBufferNumber]\iBufferOffsetInRecords
iGridLineLength = \stGraph\iGraphWidth - 1
x = - iGridOffset % \stBuffer[iBufferNumber]\iBufferGraphGridSize
EndIf
iGridValue = iGridOffset + x
; Draw scaling grid and values
DrawingFont(FontID(\stGraph\iGraphFontID))
Box(0, \stBuffer[iBufferNumber]\iBufferGraphGridYPos, iGridLineLength, 1, \stBuffer[iBufferNumber]\iBufferGraphGridColour)
Repeat
If x < \stBuffer[iBufferNumber]\iBufferLengthInRecords
DrawingMode(#PB_2DDrawing_Default)
Line(x, \stBuffer[iBufferNumber]\iBufferGraphGridYPos-5, 1, 10, \stBuffer[iBufferNumber]\iBufferGraphGridColour)
; Draw grid values
sGridValue = Str(iGridValue)
DrawingMode(#PB_2DDrawing_Transparent)
DrawText(x - TextWidth(sGridValue) / 2, \stBuffer[iBufferNumber]\iBufferGraphGridYPos + #GG_GRIDFONTSIZE, sGridValue, \stBuffer[iBufferNumber]\iBufferGraphGridColour)
EndIf
iGridValue + \stBuffer[iBufferNumber]\iBufferGraphGridSize
x + \stBuffer[iBufferNumber]\iBufferGraphGridSize
Until x >= iGridLineLength + iGridOffset % \stBuffer[iBufferNumber]\iBufferGraphGridSize
EndIf
Next iBufferNumber
StopDrawing()
EndIf
EndWith
EndProcedure
;-
;*************************************************************************
;- Public Procedures
;*************************************************************************
Procedure.i Create(x.i, y.i, iGadgetWidth.i, iGadgetHeight.i, iGadgetBorderSize=#GG_DEFAULT_BORDERSIZE, iButtonSize=#GG_DEFAULT_BUTTONSIZE, iGadgetBorderColour.i=#GG_DEFAULT_BORDERCOLOUR, iGraphBackgroundColour.i=#GG_DEFAULT_BACKGROUNDCOLOUR)
; +-----------------------------------------------------------------
; |Description : -
; |Arguments : arg1 : Handle to struct
; |Results : #False (0) in case of errors, Pointer to gadget structure, if all went ok
; |Remarks : -
; +-----------------------------------------------------------------
Protected *GraphGadget.GraphGadget
; Parametercheck
If iGadgetWidth - 8 * (iButtonSize + iGadgetBorderSize) - iGadgetBorderSize * 2 < 0 Or ; 8 x because of the scrollbar gadget, this counts 2 times of the buttonsize
iGadgetHeight - #GG_MINVIEWHEIGHT - iButtonSize - iGadgetBorderSize * 3 < 0 Or
iGadgetBorderSize < #GG_MINBORDERSIZE Or
iButtonSize < #GG_MINBUTTONSIZE
ProcedureReturn #False
EndIf
; Allocate memory for the gadgetstructure
*GraphGadget = AllocateStructure(GraphGadget)
If *GraphGadget <> 0
With *GraphGadget
; Store gadget parameters into internal structure
\iGadgetX = x
\iGadgetY = y
\iGadgetHeight = iGadgetHeight
\iGadgetWidth = iGadgetWidth
\iGadgetBorderSize = iGadgetBorderSize
\stButtons\iButtonSize = iButtonsize
\stGraph\iGraphBackgroundColour = iGraphBackgroundColour
\iGadgetBorderColour = iGadgetBorderColour
\iGadgetMutex = CreateMutex()
If \iGadgetMutex <> 0
; Calculate internal GUI positions
CalcGUI(*GraphGadget.GraphGadget)
;- Outer canvas act as container
\iGadgetCanvasID = CanvasGadget(#PB_Any, \iGadgetX, \iGadgetY, iGadgetWidth, iGadgetHeight, #PB_Canvas_Container)
If \iGadgetCanvasID <> 0
; Store the gadgetstructure handle into the gadgetdata
SetGadgetData(\iGadgetCanvasID,*GraphGadget)
; Draw gadget background (border)
If StartDrawing(CanvasOutput(\iGadgetCanvasID))
DrawingMode(#PB_2DDrawing_Default)
Box(0, 0, \iGadgetWidth, \iGadgetHeight, \iGadgetBorderColour)
StopDrawing()
EndIf
; Add control buttons
\stButtons\iButtonBeginID = ButtonGadget(#PB_Any, \stButtons\iButtonBeginX, \stButtons\iButtonBeginY, \stButtons\iButtonSize, \stButtons\iButtonSize, "|<")
\stButtons\iButtonPageBackID = ButtonGadget(#PB_Any, \stButtons\iButtonPageBackX, \stButtons\iButtonPageBackY, \stButtons\iButtonSize, \stButtons\iButtonSize, "<<")
\stButtons\iButtonBackID = ButtonGadget(#PB_Any, \stButtons\iButtonBackX, \stButtons\iButtonBackY, \stButtons\iButtonSize, \stButtons\iButtonSize, "<")
\stButtons\iButtonForwardID = ButtonGadget(#PB_Any, \stButtons\iButtonForwardX, \stButtons\iButtonForwardY, \stButtons\iButtonSize, \stButtons\iButtonSize, ">")
\stButtons\iButtonPageForwarID = ButtonGadget(#PB_Any, \stButtons\iButtonPageForwardX, \stButtons\iButtonPageForwardY, \stButtons\iButtonSize, \stButtons\iButtonSize, ">>")
\stButtons\iButtonEndID = ButtonGadget(#PB_Any, \stButtons\iButtonEndX, \stButtons\iButtonEndY, \stButtons\iButtonSize, \stButtons\iButtonSize, ">|")
\stButtons\iScrollBarID = ScrollBarGadget(#PB_Any, \stButtons\iScrollBarX, \stButtons\iScrollBarY, \stButtons\iScrollBarWidth, \stButtons\iButtonSize, 0, 99, 100)
; Inner canvas for waveform
\stGraph\iGraphCanvasID = CanvasGadget(#PB_Any, \stGraph\iGraphX, \stGraph\iGraphY, \stGraph\iGraphWidth, \stGraph\iGraphHeight)
CloseGadgetList()
If \stGraph\iGraphCanvasID <> 0
; Draw graph gadget background
If StartDrawing(CanvasOutput(\stGraph\iGraphCanvasID))
DrawingMode(#PB_2DDrawing_Default)
Box(0, 0, \stGraph\iGraphWidth, \stGraph\iGraphHeight, \stGraph\iGraphBackgroundColour)
StopDrawing()
EndIf
; Font for waveform canvas scale
\stGraph\iGraphFontID = LoadFont(#PB_Any, "Arial", #GG_GRIDFONTSIZE)
If \stGraph\iGraphFontID <> 0
; Evtl. BindEvent...
; If all went ok, return the handle to the gadgetstructure
ProcedureReturn *GraphGadget
EndIf
EndIf
EndIf
EndIf
; In case of errors, the programm execute this part
Free(*GraphGadget.GraphGadget)
EndWith
EndIf
ProcedureReturn #False
EndProcedure
Procedure Free(*GraphGadget.GraphGadget)
; +-----------------------------------------------------------------
; |Description : -
; |Arguments : arg1 : Handle to struct
; |Results : -
; |Remarks : -
; +-----------------------------------------------------------------
; Parametercheck
If *GraphGadget = 0
ProcedureReturn
EndIf
; Wait until the Gadget is unlocked
LockMutex(*GraphGadget\iGadgetMutex)
With *GraphGadget
If \stGraph\iGraphFontID <> 0 : FreeFont(\stGraph\iGraphFontID) : EndIf
If \stGraph\iGraphCanvasID <> 0 : FreeGadget(\stGraph\iGraphCanvasID) : EndIf
If \iGadgetCanvasID <> 0 : FreeGadget(\iGadgetCanvasID) : EndIf
EndWith
UnlockMutex(*GraphGadget\iGadgetMutex)
FreeMutex(*GraphGadget\iGadgetMutex)
FreeStructure(*GraphGadget)
EndProcedure
;
Procedure Update(*GraphGadget.GraphGadget)
; +-----------------------------------------------------------------
; |Description : Draws the graph
; |Arguments : arg1 : Handle to struct
; |Results : -
; |Remarks : -
; +-----------------------------------------------------------------
; Parametercheck
If *GraphGadget = 0
ProcedureReturn
EndIf
; Wait until the Gadget is unlocked
LockMutex(*GraphGadget\iGadgetMutex)
With *GraphGadget
DrawGrid(*GraphGadget.GraphGadget)
; If StartDrawing(CanvasOutput(*GraphGadget\stGraph\iGraphCanvasID))
; StopDrawing()
; EndIf
EndWith
UnlockMutex(*GraphGadget\iGadgetMutex)
EndProcedure
Procedure.i SetBuffer(*GraphGadget.GraphGadget, iBufferNumber.i, iBufferAddress.i, iBufferLengthInRecords.i, iBufferOffsetInRecords.i=0, iBufferDataMode=#GG_DATAMODE_INTEGER, iBufferGraphColour.i=#GG_DEFAULT_GRAPHCOLOUR)
; +-----------------------------------------------------------------
; |Description : -
; |Arguments : arg1 : Handle to struct
; |Results : #False in case of error, #True if all went ok
; |Remarks : -
; +-----------------------------------------------------------------
; Parametercheck
If *GraphGadget = 0 Or
iBufferNumber >= #GG_MAXBUFFERS Or
iBufferAddress = 0 Or
iBufferLengthInRecords = 0 Or
iBufferOffsetInRecords >= iBufferLengthInRecords
ProcedureReturn #False
EndIf
; Wait until the Gadget is unlocked
LockMutex(*GraphGadget\iGadgetMutex)
With *GraphGadget
\stBuffer[iBufferNumber]\iBufferAddress = iBufferAddress
\stBuffer[iBufferNumber]\iBufferLengthInRecords = iBufferLengthInRecords
\stBuffer[iBufferNumber]\iBufferOffsetInRecords = iBufferOffsetInRecords
\stBuffer[iBufferNumber]\iBufferDataMode = iBufferDataMode
\stBuffer[iBufferNumber]\iBufferGraphColour = iBufferGraphColour
Select iBufferDataMode
Case #GG_DATAMODE_BYTE
\stBuffer[iBufferNumber]\iBufferRecordSize = SizeOf(Byte)
Case #GG_DATAMODE_WORD
\stBuffer[iBufferNumber]\iBufferRecordSize = SizeOf(Word)
Case #GG_DATAMODE_LONG
\stBuffer[iBufferNumber]\iBufferRecordSize = SizeOf(Long)
Case #GG_DATAMODE_INTEGER
\stBuffer[iBufferNumber]\iBufferRecordSize = SizeOf(Integer)
Case #GG_DATAMODE_QUAD
\stBuffer[iBufferNumber]\iBufferRecordSize = SizeOf(Quad)
Case #GG_DATAMODE_FLOAT
\stBuffer[iBufferNumber]\iBufferRecordSize = SizeOf(Float)
Case #GG_DATAMODE_DOUBLE
\stBuffer[iBufferNumber]\iBufferRecordSize = SizeOf(Double)
Default
\stBuffer[iBufferNumber]\iBufferRecordSize = 1
EndSelect
\stBuffer[iBufferNumber]\iBufferLengthInBytes = iBufferLengthInRecords * \stBuffer[iBufferNumber]\iBufferRecordSize
\stBuffer[iBufferNumber]\iBufferShowGrid = #GG_DEFAULT_SHOWGRID
\stBuffer[iBufferNumber]\iBufferShowData = #GG_DEFAULT_SHOWDATA
\stBuffer[iBufferNumber]\iBufferGraphGridSize = #GG_DEFAULT_GRIDSIZE
\stBuffer[iBufferNumber]\iBufferGraphGridColour = #GG_DEFAULT_GRIDCOLOUR
EndWith
UnlockMutex(*GraphGadget\iGadgetMutex)
ProcedureReturn #True
EndProcedure
Procedure.i SetBufferOffset(*GraphGadget.GraphGadget, iBufferNumber.i, iBufferOffsetInRecords.i=0)
; +-----------------------------------------------------------------
; |Description : -
; |Arguments : arg1 : Handle to struct
; |Results : #False in case of error, #True if all went ok
; |Remarks : -
; +-----------------------------------------------------------------
; Wait until the Gadget is unlocked
LockMutex(*GraphGadget\iGadgetMutex)
; Parametercheck
If *GraphGadget = 0 Or
iBufferNumber >= #GG_MAXBUFFERS Or
*GraphGadget\stBuffer[iBufferNumber]\iBufferAddress = 0 Or
iBufferOffsetInRecords >= *GraphGadget\stBuffer[iBufferNumber]\iBufferLengthInRecords
UnlockMutex(*GraphGadget\iGadgetMutex)
ProcedureReturn #False
EndIf
With *GraphGadget
\stBuffer[iBufferNumber]\iBufferOffsetInRecords = iBufferOffsetInRecords
EndWith
UnlockMutex(*GraphGadget\iGadgetMutex)
ProcedureReturn #True
EndProcedure
Procedure.i SetBufferGrid(*GraphGadget.GraphGadget, iBufferNumber.i, iBufferShowGrid.i=#False, iBufferGraphGridSize.i=#GG_DEFAULT_GRIDSIZE, iBufferGraphGridYPos.i=-1, iBufferGraphGridColour.i=#GG_DEFAULT_GRIDCOLOUR)
; +-----------------------------------------------------------------
; |Description : -
; |Arguments : arg1 : Handle to struct
; |Results : #False in case of error, #True if all went ok
; |Remarks : -
; +-----------------------------------------------------------------
; Wait until the Gadget is unlocked
LockMutex(*GraphGadget\iGadgetMutex)
; Parametercheck
If *GraphGadget = 0 Or
iBufferNumber >= #GG_MAXBUFFERS Or
iBufferGraphGridSize < #GG_MINGRIDSIZE Or
iBufferGraphGridYPos < -1 Or
iBufferGraphGridYPos > *GraphGadget\stGraph\iGraphHeight
UnlockMutex(*GraphGadget\iGadgetMutex)
ProcedureReturn #False
EndIf
With *GraphGadget
\stBuffer[iBufferNumber]\iBufferShowGrid = iBufferShowGrid
\stBuffer[iBufferNumber]\iBufferGraphGridSize = iBufferGraphGridSize
\stBuffer[iBufferNumber]\iBufferGraphGridColour = iBufferGraphGridColour
If iBufferGraphGridYPos = -1
\stBuffer[iBufferNumber]\iBufferGraphGridYPos = \stGraph\iGraphY + \stGraph\iGraphHeight / 2
Else
\stBuffer[iBufferNumber]\iBufferGraphGridYPos = iBufferGraphGridYPos
EndIf
EndWith
UnlockMutex(*GraphGadget\iGadgetMutex)
ProcedureReturn #True
EndProcedure
Procedure ClearBuffer(*GraphGadget.GraphGadget, iBufferNumber.i)
; +-----------------------------------------------------------------
; |Description : Discards all settings of an active buffer. However, the buffer memory is NOT released and must be handled by the user.
; |Arguments : arg1 : Handle to struct
; |Results : -
; |Remarks : -
; +-----------------------------------------------------------------
; Wait until the Gadget is unlocked
LockMutex(*GraphGadget\iGadgetMutex)
; Parametercheck
If *GraphGadget = 0 Or
iBufferNumber >= #GG_MAXBUFFERS
UnlockMutex(*GraphGadget\iGadgetMutex)
ProcedureReturn
EndIf
With *GraphGadget
ClearStructure(\stBuffer[iBufferNumber], Buffer)
EndWith
UnlockMutex(*GraphGadget\iGadgetMutex)
EndProcedure
Procedure.i Id(*GraphGadget.GraphGadget)
; +-----------------------------------------------------------------
; |Description : Returns the ID of the canvas gadget
; |Arguments : arg1 : Handle to struct
; |Results : -
; |Remarks : -
; +-----------------------------------------------------------------
; Parametercheck
If *GraphGadget = 0
ProcedureReturn 0
EndIf
ProcedureReturn *GraphGadget\iGadgetCanvasID
EndProcedure
;-
;*************************************************************************
;- Data Section
;*************************************************************************
DataSection
EndDataSection
EndModuleNehmen wir mal an, nach ein paar Jahren möchte man selbst oder jemand anderes den Code erweitern. Der Programmierer liest sich also die Kommentare und die Code-Zeilen durch, um den Code (wieder) zu verstehen. Es wäre ärgerlich für den Programmierer, wenn er zum Beispiel eine Variable im Code verfolgt und nach vielen Zeilen an Code plötzlich feststellt, dass die Variable gar nicht wirklich verwendet wird.ts-soft hat geschrieben:In der erstellten ausführbaren Datei taucht es in keinster Weise auf, so sehe ich den Sinn nicht so ganz?
Alles gut.Kurzer hat geschrieben:Hallo Sicro, Du musst Dir da nicht so viel Arbeit mit machen. Also von meiner Seite aus war das keine Programmier-Bitte an Dich.
Wenn Du selber Spaß dran hast, dann ist es okay und dann mach auch nur so viel wie Du Lust dran hast.
Code: Alles auswählen
; Hier ist offensichtlich, dass "a" sinnvoll verwendet wird:
Define a = 1
x = a + 2
; vorausgesetzt, "x" wird später im Code ausgelesenCode: Alles auswählen
; Hier ist es unklar:
; - Liest die WinAPI-Funktion "a", dann wird "a" sinnvoll verwendet
; - Schreibt die WinAPI-Funktion in "a", dann wird "a" nicht sinnvoll verwendet,
; wenn "a" im späteren Code nicht ausgelesen wird
Define a = 1
WinAPI_GetInfo(@a)Sehr hilfreich ist, wie schon geschrieben, so viel Code wie möglich in unabhängige Modules/Procedures auszulagern. Die Modules/Procedures können dann später auch leicht in anderen Projekten wieder verwendet werden. Wenn eine bessere Lösung für eine Aufgabe gefunden wurde, muss im besten Fall nur der alte Procedure-Code umgeschrieben werden. Wenn die Procedure-Parameter angepasst werden müssen, dann ist die Änderung im Haupt-Code dennoch gering.Kurzer hat geschrieben:Ich denke eher, dass es daran liegt, dass Programmieren ein evolutionärer Prozess ist (zumindest bei mir) und man zwangsläufig im Laufe der Projektpflege immer wieder Dinge umstellt oder erweitert, weil man dafür einfach nun eine bessere Lösung oder eine neue Idee gefunden hat.
Danke für den Code. Sieht ganz gut aus. Manche Procedures sind horizontal und manche Code-Zeilen vertikal zu lang, aber wenn du das Projekt alleine programmierst und du eine hohe Bildschirmauflösung verwendest, wodurch die Procedure-Blöcke/Code-Zeilen vollständig (ohne zu scrollen) anzeigt werden, ist alles ok. Außer du verwendest eine Versionsverwaltung wie Git und vergleichst immer wieder mal verschiedene Code-Versionen. Dann wäre es am besten, wenn du die Code-Zeilen auf die Hälfte der Bildschirmbreite reduzierst, damit zwei unterschiedliche Code-Versionen nebeneinander betrachtet werden können. Im Team sollte man sich am besten an den Programmierer mit der niedrigsten Auflösung oder an die gängige Code-Zeilenlänge von max. 80 Zeichen richten.Kurzer hat geschrieben:Hier wie versprochen, mein unfertiger Modulcode für ein Customgadget (Graphanzeige mit Unterstützung mehrere Datenbuffer, die dann als Kurvenform visualisiert werden sollen). Der Code ist allein nicht lauffähig, aber man kann hoffentlich gut meinen "Programmierstil" darin erkennen.

Das stimmt, die Module nutze ich für so etwas auch gern. Ich arbeite aber auch gerne mit Programm- bzw. Projekttemplates. Also komplette Programmhülsen, die bereits mehrere Fenster enthalten sowie alle Verwaltungsfunktionen dafür (Event- Programmstruktur- und Resizehandler sowie Funktionen um Settings zu speichern / zu laden usw.). Schade, dass es die bei PB nicht standardmäßig gibt. Also quasi ein Templatemanager/Designer, der noch eine Ebene über dem integrierten Formdesigner angesiedelt ist.Sehr hilfreich ist, wie schon geschrieben, so viel Code wie möglich in unabhängige Modules/Procedures auszulagern. Die Modules/Procedures können dann später auch leicht in anderen Projekten wieder verwendet werden. Wenn eine bessere Lösung für eine Aufgabe gefunden wurde, muss im besten Fall nur der alte Procedure-Code umgeschrieben werden. Wenn die Procedure-Parameter angepasst werden müssen, dann ist die Änderung im Haupt-Code dennoch gering.
Auch das stimmt und ich habe das bei einem Projekt explizit und minutiös angewendet, weil ich wusste, dass ich es nicht in einem Zug fertigstellen würde. Es ist komplex, abstrakt und kompliziert (im Gegensatz zur Verarbeitungsfähigkeit meines DenkapparatesHilfreich ist auch, wenn man das Projekt mehr plant. Wir Hobby-Programmierer programmieren manchmal einfach los, ohne das Projekt vorher im Detail zu planen...
Zu lange Codezeilen kann ich noch nachvollziehen, speziell wo du GitHub erwähnst (habe ich allerdings noch nie genutzt), wobei sich natürlich die "vertikale Länge" der Prozeduren vergrößert, wenn man die Zeile früher umbricht.Danke für den Code. Sieht ganz gut aus. Manche Procedures sind horizontal und manche Code-Zeilen vertikal zu lang, aber wenn du das Projekt alleine programmierst und du eine hohe Bildschirmauflösung verwendest, wodurch die Procedure-Blöcke/Code-Zeilen vollständig (ohne zu scrollen) anzeigt werden, ist alles ok. Außer du verwendest eine Versionsverwaltung wie Git und vergleichst immer wieder mal verschiedene Code-Versionen. Dann wäre es am besten, wenn du die Code-Zeilen auf die Hälfte der Bildschirmbreite reduzierst, damit zwei unterschiedliche Code-Versionen nebeneinander betrachtet werden können. Im Team sollte man sich am besten an den Programmierer mit der niedrigsten Auflösung oder an die gängige Code-Zeilenlänge von max. 80 Zeichen richten:
btw: Kann es sein, dass du in deinem letzten Beitrag einen link auf dein IDE Tool hattest? Also so eine "mal eben kurz programmiert" Tool bzgl. der ungenutzten Variablen. Ich habe den BEitrag vor ein paar tagen von Smartphone aus schon einmal gelesen und war der Meinung, dass du in deinem Beitrag einen link auf ein GitHub Projekt drin hattest, unter dem das Tool zu finden sein sollte. Jetzt ist jedenfalls kein link mehr zu sehen.Für weitere Programmierstil-Tipps sollten wir am besten einen neuen Thread aufmachen.
Ich halte die Procedures vertikal kurz, weil ich so den kompletten Code im Blick habe und so permanent sehe, welche lokalen Variablen vorhanden sind. Der PureBasic-Editor beachtet bei Variablen nämlich nicht immer den Scope: Auto-completion should observe the scopeKurzer hat geschrieben:Prozeduren, die länger (höher) als eine Bildschirmseite sind, finde ich dann nicht schlimm, wenn sich ein Teil des Inhalts aufgrund von Wiederverwendbarkeit *nicht* auslagern lässt. Was ich meine ist, dass ich keinen Code aus einer Prozedur auslagern würde, *nur* weil er die ursprüngliche Prozedur zu lang macht. Anders sieht es aus, wenn der ausgelagerte Codeteil auch von anderen Prozeduren nutzbar wäre - es also eine Wiederverwendbarkeit innerhalb des Projekts gäbe.
Genau so sieht es bei mir auch aus. Alles bezüglich Computer habe ich mir selbst beigebracht. Beruflich habe ich mit Computern auch nichts zu tun.Kurzer hat geschrieben:Allerdings bin ich auch offen für Neues und eigene mir gern aktuelle Standards an, wenn sie mir sinnvoll erscheinen. Ich kenne ich deinen Background in puncto Programmierung nicht - nur meinen eigenen. Ich selbst bin bis dato immer Autodidakt gewesen, habe mir hier und da was angesehen und mit das passenste für mein eigenes Paradigma heraussucht. Bzgl. Softwareentwicklung habe ich nie irgend eine Schulbank gedrückt und mir hat man nie eine Sprache offiziell und vollständig beigebracht, wie man sie heute als Schüler oder Student vermutlich beigebracht bekommt. Als ich angefangen habe, gab es diese Bereiche in der schulischen / beruflichen Ausbildung noch gar nicht.
Das Tool habe ich wieder offline genommen, weil ich empfand, dass es noch nicht ausgereift genug war, um es schon zu veröffentlichen.Kurzer hat geschrieben:btw: Kann es sein, dass du in deinem letzten Beitrag einen link auf dein IDE Tool hattest? Also so eine "mal eben kurz programmiert" Tool bzgl. der ungenutzten Variablen. Ich habe den BEitrag vor ein paar tagen von Smartphone aus schon einmal gelesen und war der Meinung, dass du in deinem Beitrag einen link auf ein GitHub Projekt drin hattest, unter dem das Tool zu finden sein sollte. Jetzt ist jedenfalls kein link mehr zu sehen.
Code: Alles auswählen
; Tool Settings:
; - Arguments: "%HOME" "%FILE" "%TEMPFILE"
; - Event: Menu Or ShortcutCode: Alles auswählen
*lexer = PBLexer::Create(code$, 400) ; Unterstützt z. B. Token-Werte mit maximal 400 Zeichen