Aktuelle Zeit: 19.07.2019 05:47

Alle Zeiten sind UTC + 1 Stunde [ Sommerzeit ]




Ein neues Thema erstellen Auf das Thema antworten  [ 54 Beiträge ]  Gehe zu Seite 1, 2, 3, 4, 5, 6  Nächste
Autor Nachricht
 Betreff des Beitrags: Modul BaseClass (Modul als Objekt)
BeitragVerfasst: 13.12.2015 22:30 
Offline
Benutzeravatar

Registriert: 24.11.2004 13:12
Wohnort: Germany
Wollte schon mein OOP-Precompiler auf Module umschreiben.
Stelle aber fest das es auch ohne Pre-Compiler zu lösen ist.

Mein Ziel ist es ohne viele neuen Schlüsselnamen ein Modul als ein Objekt zu programmieren . Ich glaube es ist mir gelungen.

Das Modul BaseClass bringt dazu alle erforderlichen Komponenten mit:
- Neue Klasse anlegen mit der BaseClass oder einer geerbten Klasse.
- Die Basisfunktion Object\Release() und Object\AddRef().
- Deklarierung von Aufruf Umgebung "Initalize" und "Dispose", auch bei Vererbung.
- Deklarierung von Methoden.

Es gibt nur wenige Regeln:
- Die Struktur für die Variablen (Properties) muss mit "Extends sBaseClass" oder mit "Extends sVererbung" definiert werden.
- Das Interface für die Methoden muss mit "Extends iBaseClass" oder mit "Extends iVererbung" definiert werden.
- Bei Vererbung muss die zu erbende Klasse eine BaseClass haben.

Update v1.07
- Bugfix FreeMutex

Update v1.08
- Die Klassen in der Procedure 'AddClass(...)' gekapselt
- Überprüfung der neuen Klasse in der Procedure 'AddClass(...)' erweitert
- Macros geändert da die Klassen nicht mehr global sind
- Geändert CheckInterface. Der Parameter wird nicht mehr benötigt
- Die Namen der Klassen sind nicht mehr 'Case Sensitive'

Update v1.10
- Geändert ClassName Management

Update v1.13
- CheckInterface optimiert

Modul_BaseClassSmall.pb
Code:
;-Begin Module BaseClass Small Version

; Comment : Module as Object
; Author  : mk-soft
; Version : v1.13
; Created : 16.08.2017
; Updated : 03.05.2019
; Link GE : http://www.purebasic.fr/german/viewtopic.php?f=8&t=29343
; Link EN : http://www.purebasic.fr/english/viewtopic.php?f=12&t=64305

; OS      : All
; License : MIT

; ***************************************************************************************

DeclareModule BaseClass
 
  ; ---------------------------------------------------------------------------
 
  ; Internal class declaration
 
  Prototype ProtoInvoke(*This)
 
  Structure udtInvoke
    *Invoke.ProtoInvoke
  EndStructure
 
  Structure udtClass
    Array *vTable(3)
    Array Initialize.udtInvoke(0)
    Array Dispose.udtInvoke(0)
  EndStructure
 
  ; ---------------------------------------------------------------------------
 
  ; BaseClass declaration
 
  Structure sBaseSystem
    *vTable
    *Self.udtClass
    RefCount.i
    Mutex.i
  EndStructure
 
  ; Public Structure
  Structure sBaseClass
    System.sBaseSystem
  EndStructure
 
  ; Public Interface
  Interface iBaseClass
    QueryInterface(*riid, *addr)
    AddRef()
    Release()
  EndInterface
 
  ; ---------------------------------------------------------------------------
 
  Macro dq
    "
  EndMacro
 
  ; ---------------------------------------------------------------------------
 
  ; Added New Class
  Declare AddClass(ClassName.s, ClassExtends.s, Size) ; Internal
 
  Macro NewClass(ClassInterface, ClassExtends=)
    ; Interface helper
    Interface __Interface Extends ClassInterface
    EndInterface
    ; Internal class pointer
    Global *__Class.udtClass
    ; Add new class
    Procedure __NewClass()
      *__Class = AddClass(dq#ClassInterface#dq, dq#ClassExtends#dq, SizeOf(ClassInterface) / SizeOf(integer))
    EndProcedure : __NewClass()
  EndMacro
 
  ; ---------------------------------------------------------------------------
 
  ; Macro for init object (short)
  Macro InitObject(sProperty)
    Protected *Object.sProperty, __cnt, __index
    *Object = AllocateStructure(sProperty)
    If *Object
      *Object\System\vTable = *__Class\vTable()
      *Object\System\Self = *__Class
      *Object\System\RefCount = 0
      *Object\System\Mutex = CreateMutex()
      __cnt = ArraySize(*Object\System\Self\Initialize())
      For __index = 1 To __cnt
        *Object\System\Self\Initialize(__index)\Invoke(*Object)
      Next
    EndIf
    ProcedureReturn *Object
  EndMacro
 
  ; ---------------------------------------------------------------------------
 
  ; Macros for init object (advanced)
  Macro AllocateObject(Object, sProperty)
    Object = AllocateStructure(sProperty)
    If Object
      Object\System\vTable = *__Class\vTable()
      Object\System\Self = *__Class
      Object\System\RefCount = 0
      Object\System\Mutex = CreateMutex()
    EndIf
  EndMacro
 
  Macro InitializeObject(Object)
    If Object
      Protected __cnt, __index
      __cnt = ArraySize(Object\System\Self\Initialize())
      For __index = 1 To __cnt
        Object\System\Self\Initialize(__index)\Invoke(Object)
      Next
    EndIf
  EndMacro
 
  ; ---------------------------------------------------------------------------
 
  ; Macros for clone object
  Macro CloneObject(This, Clone, sProperty)
    Clone = AllocateStructure(sProperty)
    If Clone
      CopyStructure(This, Clone, sProperty)
      Clone\System\RefCount = 0
      Clone\System\Mutex = CreateMutex()
    EndIf
  EndMacro
 
  ; ---------------------------------------------------------------------------
 
  Macro LockObject(This)
    LockMutex(This\System\Mutex)
  EndMacro
 
  Macro UnlockObject(This)
    UnlockMutex(This\System\Mutex)
  EndMacro
 
  ; ---------------------------------------------------------------------------
 
  ; Macros to defined Initialize, Dispose, Methods
 
  ; Add Procedure as Initialize Object
  Macro AsInitializeObject(Name)
    Procedure __AddInitializeObject#Name()
      Protected index
      index = ArraySize(*__Class\Initialize()) + 1
      ReDim *__Class\Initialize(index)
      *__Class\Initialize(index)\Invoke = @Name()
    EndProcedure : __AddInitializeObject#Name()
  EndMacro
 
  ; Add Procedure as Dispose Object
  Macro AsDisposeObject(Name)
    Procedure __AddDisposeObject#Name()
      Protected index
      index = ArraySize(*__Class\Dispose()) + 1
      ReDim *__Class\Dispose(index)
      *__Class\Dispose(index)\Invoke = @Name()
    EndProcedure : __AddDisposeObject#Name()
  EndMacro
 
  ; Add Procedure as Methode or Overwrite inheritance methode
  Macro AsMethode(Name)
    Procedure __AddMethode#Name()
      *__Class\vTable(OffsetOf(__Interface\Name()) / SizeOf(integer)) = @Name()
    EndProcedure : __AddMethode#Name()
  EndMacro
 
  Macro AsNewMethode(Name)
    AsMethode(Name)
  EndMacro
 
  ; ---------------------------------------------------------------------------
 
  ; Debugger functions
 
  Macro CheckInterface()
    CompilerIf #PB_Compiler_Debugger
      Procedure __CheckInterface()
        Protected *xml, *node, ErrorCount
        *xml = CreateXML(#PB_Any)
        If *xml
          *node = InsertXMLStructure(RootXMLNode(*xml), *__Class\vTable(), __Interface)
          *node = ChildXMLNode(*node)
          Repeat
            If Not *node
              Break
            EndIf
            If GetXMLNodeText(*node) = "0"
              ErrorCount + 1
              Debug "Module " + #PB_Compiler_Module + ": Error Interface - Missing Methode '" + GetXMLNodeName(*node) + "()'"
            EndIf
            *node = NextXMLNode(*node)
          ForEver
          FreeXML(*xml)
          If ErrorCount
            Debug "Module " + #PB_Compiler_Module + ": Error Count " + ErrorCount
            CallDebugger
          EndIf
        EndIf
      EndProcedure : __CheckInterFace()
    CompilerEndIf
  EndMacro

; ---------------------------------------------------------------------------

EndDeclareModule

Module BaseClass
 
  EnableExplicit
 
  Procedure InitBaseClass()
    Global NewMap Class.udtClass()
  EndProcedure : InitBaseClass()
   
  ; ---------------------------------------------------------------------------
 
  Procedure QueryInterface(*This.sBaseClass, *riid, *addr)
    ProcedureReturn $80004002 ; (#E_NOINTERFACE)
  EndProcedure
 
  ; ---------------------------------------------------------------------------
 
  Procedure AddRef(*This.sBaseClass)
    LockMutex(*This\System\Mutex)
    *This\System\RefCount + 1
    UnlockMutex(*This\System\Mutex)
    ProcedureReturn *This\System\RefCount
  EndProcedure
 
  ; ---------------------------------------------------------------------------
 
  Procedure Release(*This.sBaseClass)
    Protected index, cnt
    With *This\System
      LockMutex(*This\System\Mutex)
      If \RefCount = 0
        cnt = ArraySize(\Self\Dispose())
        For index = cnt To 1 Step -1
          \Self\Dispose(index)\Invoke(*This)
        Next
        FreeMutex(*This\System\Mutex)
        FreeStructure(*This)
        ProcedureReturn 0
      Else
        \RefCount - 1
      EndIf
      UnlockMutex(*This\System\Mutex)
      ProcedureReturn \RefCount
    EndWith
  EndProcedure
 
  ; ---------------------------------------------------------------------------
 
  Procedure AddClass(ClassName.s, ClassExtends.s, Size)
    Protected *class.udtClass, *extends.udtClass, sClassName.s, sClassExtends.s
    sClassName = LCase(ClassName)
    sClassExtends = LCase(ClassExtends)
    CompilerIf #PB_Compiler_Debugger
      If FindMapElement(Class(), sClassName)
        Debug "Error: Class '" + ClassName + "' already exists!"
        CallDebugger
        End -1
      EndIf
      If Bool(sClassExtends)
        *extends = FindMapElement(Class(), sClassExtends)
        If Not *extends
          Debug "Error: Extends Class '" + ClassExtends + "' not exists!"
          CallDebugger
          End -1
        EndIf
      EndIf
    CompilerEndIf
    *class = AddMapElement(Class(), sClassName)
    If *class
      If Bool(sClassExtends)
        *extends = FindMapElement(Class(), sClassExtends)
        CopyStructure(*extends, *class, udtClass)
        ReDim *class\vTable(Size)
        ProcedureReturn *class
      Else
        ReDim *class\vTable(Size)
        *class\vTable(0) = @QueryInterface()
        *class\vTable(1) = @AddRef()
        *class\vTable(2) = @Release()
        ProcedureReturn *class
      EndIf
    Else
      Debug "Error: Class '" + ClassName + "' Out Of Memory!"
      CallDebugger
      End -1
    EndIf
  EndProcedure
 
  ; ---------------------------------------------------------------------------
 
EndModule

;- End Module BaseClass

; ***************************************************************************************

Link zum englischen Forum :wink:

Zitat:
Beschreibung vom Modul BaseClassSmall

Update v1.13

Vorwort

Purebasic ist Procedure Orientiert. Unterstützt aber den Aufruf von Objekten.

Mein Ziel ist es nicht eine Objekt orientierte Sprache für Purebasic zu erstellen, sondern das anlegen von eigenen Objekten zu vereinfachen.
Für vollständige Unterstützung von Objekt orientierte Programmierung gibt es andere Programmiersprachen.

Bei machen Aufgaben ist es aber vom Vorteil diese objektorientiert anzulegen.
Hier gilt bei Purebasic der gleiche Aufwand wie zum Beispiel bei „C“.
Alles muss selber definiert und anlegen werden. Es müssen die Regeln für Objekte und der Funktionen und Methoden eingehalten werde.

1. Der erste Eintrag im Objekt ist immer der Zeiger auf die Tabelle mit den Methoden.
2. Der erste Parameter von den Methoden ist immer der Zeiger auf das eigene Objekt.

Klassen

Zum anlegen eines Objektes benötigt man ein Klasse.
Eine Klasse kann man auch den Datentyp eines Objekt nennen.
In diesen wird die Tabelle der Methoden (Funktionen) und der Attribute (Variablen) definiert.

Konstruktoren und Destruktoren

Konstruktoren sind Funktionen die beim anlegen des Objekt in einen definierten Zustand bringen und bei bedarf die erforderliche Ressourcen anlegen.
Destruktoren sind Funktionen die beim freigeben des Objekt die angelegen Ressourcen frei gibt.

Konstruktoren können auch Parameter haben, werden aber nicht von alle Programmiersprachen unterstützen.
Destruktoren haben keine Parameter.

Konstruktoren und Destruktoren haben keinen Rückgabewert.

Methode Super

Um eine Klasse oder auch Basisklasse genannt zu vererben, benötigt man eine Super Funktion welche die Methoden und Attribute an die Subklasse übergibt.
Hierzu gehören auch die Konstruktoren und Destruktoren der Basisklasse.
Bei mehrfache Vererbung kann es somit auch mehrere Konstruktoren und Destruktoren geben, die in der richtigen Reihenfolge aufgerufen werden müssen.

Interface

Interfaces definieren die Schnittstelle welche Methoden vorhanden sind oder vorhanden sein müssen.


Was unterstützt Purebasic

Purebasic unterstützt Interfaces und Attributen, sowie die Vererbung von Interfaces und Attributen

- Interface SubKlasse Extends BasisKlasse
- Structure SubAttribute Extends BasisAttribute

Aufruf der Methoden von dem Interfaces.


Was unterstützt das Modul BaseClassSmall

Anlegen und Verwalten von Klassen : NewClass(InterfaceName, …)
- Anlegen der Tabellen für Methoden, Konstruktoren und Destruktoren.
* Hinweis: Konstruktoren mit Parameter werden nicht unterstützt.
- Die Methode Super automatisiert.

Das Interface mit den Methoden von Typ IUnknown
- QueryInterface(*riid, *addr)
- AddRef()
- Release()

Die BasisAttribute mit der Struktur
- System\vTable : Zeiger auf die Methoden-Tabelle
- System\Self : Zeiger auf die Klasse mit den Tabellen der Methoden, Konstruktoren und Destruktoren.
- System\RefCount : Zähler zum schützen von dem Objekt
- System\Mutex : Mutex für asynchrone Bearbeitung vom dem Objekt

Zuweisung des Kontruktors : Macro AsInitializeObject(Name der Procedure)
Zuweisung des Destruktors : Macro AsDisposeObject(Name der Procedure)

Zuweisung der Methoden : Macro AsMethode(Name der Methode und Procedure)
Überschreiben der Methoden : Macro AsNewMethode(Name der Methode und Procedure)

Anlegen des Objekt : Macro InitObject oder AllocateObject/InitializeObject für die Procedure zum angelegen des Objekt
- Anlegen des Speichers für das Objekt.
- Zuweisung der Virtuellen Tabelle und Basis Attribute.
- Aufruf der Konstruktoren in der richtigen Reihenfolge.

Die Methode QueryInterface : Object\QuerInterface(*riid, *addr)
- Eine leere Methode mit den Rückgabewert #E_NOINTERFACE.
* Diese Methode kann bei bedarf überschrieben werden.

Die Methode AddRef : Object\AddRef()
- Erhöhung des Zählers des Objektes.
* Mit der Methode Release wird der Zähler reduziert und das Objekt wird erst freigegeben, wenn dieser Null erreicht hat.
! Nicht überschreiben !

Die Methode Release : Objekt\Release()
- Aufruf der Destruktoren in der richtigen Reihenfolge.
- Freigeben des Speichers.
! Nicht überschreiben !

Überprüfung der Klasse im Debugger-Modus
- CheckInterface() am Ende vom Modul aufrufen.


_________________
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner v1.x / OOP-BaseClass-Modul / OPC-Helper DLL
PB v3.30 / v5.4x - OS Mac Mini OSX 10.xx / Window 10 Pro. (X64) /Window 7 Pro. (X64) / Window XP Pro. (X86) / Ubuntu 14.04
Downloads auf Webspace


Zuletzt geändert von mk-soft am 11.05.2019 16:02, insgesamt 51-mal geändert.

Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Modul BaseClass (OOP)
BeitragVerfasst: 13.12.2015 22:31 
Offline
Benutzeravatar

Registriert: 24.11.2004 13:12
Wohnort: Germany
Beispiel
Code:
;-TOP

; Example 1

IncludeFile "Modul_BaseClassSmall.pb"

; Erste Klasse

DeclareModule MyMath1
 
  ;UseModule BaseClass
 
  Structure sMyMath1 Extends BaseClass::sBaseClass
    Value.i
  EndStructure
 
  Interface iMyMath1 Extends BaseClass::iBaseClass
    Result.s()
    Add(Value)
    Sub(Value)
  EndInterface
 
  Declare NewMath1()
 
EndDeclareModule

Module MyMath1
 
  UseModule BaseClass
 
  NewClass(iMyMath1)
 
  ; ---------------------------------------------------------------------------
 
  Procedure Init(*this.sMyMath1)
    Debug "Initialize MyMath1"
  EndProcedure : AsInitializeObject(Init)
 
  ; ---------------------------------------------------------------------------
 
  Procedure Destroy(*this.sMyMath1)
    Debug "Dispose MyMath1"   
  EndProcedure : AsDisposeObject(Destroy)
 
  ; ---------------------------------------------------------------------------
 
  Procedure.s Result(*this.sMyMath1)
    ProcedureReturn Str(*this\Value)
  EndProcedure : AsMethode(Result)
 
  ; ---------------------------------------------------------------------------
 
  Procedure Add(*this.sMyMath1, Value = 0)
    *this\Value + Value
  EndProcedure : AsMethode(Add)
 
  ; ---------------------------------------------------------------------------
 
  Procedure Sub(*this.sMyMath1, Value = 0) 
    *this\Value - Value
  EndProcedure : AsMethode(Sub)
 
  ; ---------------------------------------------------------------------------
 
  Procedure NewMath1()
    InitObject(sMyMath1) ; Mehr kommt hier nicht rein!
  EndProcedure
 
  ; ---------------------------------------------------------------------------
 
  CheckInterface()
 
EndModule

; ***************************************************************************************

; Klasse Math 2 mit Vererbung Klasse Math 1

DeclareModule MyMath2
 
  UseModule MyMath1
 
  Structure sMyMath2 Extends sMyMath1
    ; Nothing
  EndStructure
 
  Interface iMyMath2 Extends iMyMath1
    Mul(Value)
    Div(Value)
  EndInterface
 
  Declare NewMath2()
 
EndDeclareModule

Module MyMath2
 
  EnableExplicit
 
  UseModule BaseClass
 
  NewClass(iMyMath2, iMyMath1)
 
  ; ---------------------------------------------------------------------------
 
  Procedure Init(*this.sMyMath2)
    Debug "Initialize MyMath2"
  EndProcedure : AsInitializeObject(Init)
 
  ; ---------------------------------------------------------------------------
 
  Procedure Dispose(*this.sMyMath2)
    Debug "Dispose MyMath2"   
  EndProcedure : AsDisposeObject(Dispose)
 
  ; ---------------------------------------------------------------------------
 
  Procedure Mul(*this.sMyMath2, Value = 0)
    *this\Value * Value
  EndProcedure : AsMethode(Mul)
 
  ; ---------------------------------------------------------------------------
 
  Procedure Div(*this.sMyMath2, Value = 1)
    *this\Value / Value
  EndProcedure : AsMethode(Div)
 
  ; ---------------------------------------------------------------------------
 
  Procedure.s Result(*this.sMyMath2)
    ProcedureReturn "$" + Hex(*this\Value)
  EndProcedure : AsNewMethode(Result) ; Methode Result() von geerbten Klasse ersetzen
   
  ; ---------------------------------------------------------------------------
 
  Procedure NewMath2()
    InitObject(sMyMath2) ; Mehr kommt hier nicht rein!
  EndProcedure
 
  CheckInterface()
 
EndModule

; ***************************************************************************************

Debug "Test Math 1"

UseModule MyMath1
Global *obj.iMyMath1 = NewMath1()
Debug "AddRef: " + *obj\AddRef()
Debug "AddRef: " + *obj\AddRef()
Debug "Release: " + *obj\Release()
Debug "Release: " + *obj\Release()
*obj\Add(200)
*obj\Sub(50)
Debug "Result = " + *obj\Result()
Debug "Release: " + *obj\Release()

Debug "Test Math 2"

UseModule MyMath2
Global *obj2.iMyMath2 = NewMath2()
Debug "AddRef: " + *obj2\AddRef()
Debug "AddRef: " + *obj2\AddRef()
Debug "Release: " + *obj2\Release()
Debug "Release: " + *obj2\Release()
*obj2\Add(200)
*obj2\Sub(50)
*obj2\Mul(100)
*obj2\Div(10)
Debug "Result = " + *obj2\Result()

Debug "Release: " + *obj2\Release()

_________________
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner v1.x / OOP-BaseClass-Modul / OPC-Helper DLL
PB v3.30 / v5.4x - OS Mac Mini OSX 10.xx / Window 10 Pro. (X64) /Window 7 Pro. (X64) / Window XP Pro. (X86) / Ubuntu 14.04
Downloads auf Webspace


Zuletzt geändert von mk-soft am 04.05.2019 14:39, insgesamt 7-mal geändert.

Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Modul BaseClass (OOP)
BeitragVerfasst: 13.12.2015 22:31 
Offline
Benutzeravatar

Registriert: 24.11.2004 13:12
Wohnort: Germany
Beispiel mit Parameter
Code:
;-TOP

; Example 6

IncludeFile "Modul_BaseClassSmall.pb"

; *******************************************************************************

DeclareModule DataSet
 
  UseModule BaseClass
 
  ; Properties
  Structure sDataSet Extends sBaseClass
    *pData
    Count.i
    Array *pStr(0)
  EndStructure
 
  ; Methods
  Interface iDataSet Extends iBaseClass
    Get.s(index)
    Count()
  EndInterface
 
  UnuseModule BaseClass
 
  ; New Object
  Declare New(*pData)
 
EndDeclareModule

Module DataSet
 
  UseModule BaseClass
 
  NewClass(iDataSet)
 
  ; ---------------------------------------------------------------------------
 
  Procedure.s Get(*this.sDataSet, index)
    With *this
      If index < \Count
        ProcedureReturn PeekS(\pStr(index))
      Else
        ProcedureReturn ""
      EndIf
    EndWith
  EndProcedure : AsMethode(Get)
 
  ; ---------------------------------------------------------------------------
 
  Procedure Count(*this.sDataSet)
    ProcedureReturn *this\Count
  EndProcedure : AsMethode(Count)
 
  ; ---------------------------------------------------------------------------
 
  Procedure Init(*this.sDataSet)
    Protected *pos, len, index
    With *this
      *pos = \pData
      Repeat
        len = MemoryStringLength(*pos)
        If len
          \Count + 1
          *pos + len * SizeOf(character) + SizeOf(character)
        Else
          Break
        EndIf
      ForEver
      Dim \pStr(\Count)
      *pos = \pData
      Repeat
        len = MemoryStringLength(*pos)
        If len
          \pStr(index) = *pos
          index + 1
          *pos + len * SizeOf(character) + SizeOf(character)
        Else
          Break
        EndIf
      ForEver
     
    EndWith
   
  EndProcedure : AsInitializeObject(Init)
 
  ; ---------------------------------------------------------------------------
 
  Procedure New(*pData)
   
    Protected *obj.sDataSet
   
    AllocateObject(*obj, sDataSet)
    If *obj
      *obj\pData = *pData
    EndIf
    InitializeObject(*obj)
   
    ProcedureReturn *obj
   
  EndProcedure
 
  ; ---------------------------------------------------------------------------
 
  CheckInterface()
 
EndModule

; *******************************************************************************

;- Test

EnableExplicit

Macro Object(ObjectName, ObjectType)
  ObjectName.ObjectType#::i#ObjectType
EndMacro

;BaseClass::ShowClasses()

Define.DataSet::iDataSet *set1, *set2

Define i

Debug "Data 1"
*set1 = DataSet::New(?DataSet1)
For i = 0 To *set1\Count() - 1
  Debug *set1\Get(i)
Next

Debug "----------------"
Debug "Data 2"
*set2 = DataSet::New(?DataSet2)
For i = 0 To *set2\Count() - 1
  Debug *set2\Get(i)
Next

DataSection
  DataSet1:
  Data.s "Sontag"
  Data.s "Montag"
  Data.s "Dienstag"
  Data.s "Mittwoch"
  Data.s "Donnerstag"
  Data.s "Freitag"
  Data.s "Samstag"
  Data.i 0
 
  DataSet2:
  Data.s "Januar"
  Data.s "Februar"
  Data.s "März"
  Data.s "April"
  Data.s "Mai"
  Data.s "Juni"
  Data.s "Juli"
  Data.s "August"
  Data.s "September"
  Data.s "Oktober"
  Data.s "November"
  Data.s "Dezember"
  Data.i 0
EndDataSection

_________________
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner v1.x / OOP-BaseClass-Modul / OPC-Helper DLL
PB v3.30 / v5.4x - OS Mac Mini OSX 10.xx / Window 10 Pro. (X64) /Window 7 Pro. (X64) / Window XP Pro. (X86) / Ubuntu 14.04
Downloads auf Webspace


Zuletzt geändert von mk-soft am 04.05.2019 14:40, insgesamt 5-mal geändert.

Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Modul BaseClass (Modul als Objekt programmieren)
BeitragVerfasst: 22.12.2015 21:31 
Offline
Benutzeravatar

Registriert: 24.11.2004 13:12
Wohnort: Germany
Beispiel ...
Code:

_________________
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner v1.x / OOP-BaseClass-Modul / OPC-Helper DLL
PB v3.30 / v5.4x - OS Mac Mini OSX 10.xx / Window 10 Pro. (X64) /Window 7 Pro. (X64) / Window XP Pro. (X86) / Ubuntu 14.04
Downloads auf Webspace


Zuletzt geändert von mk-soft am 15.08.2016 14:34, insgesamt 6-mal geändert.

Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Modul BaseClass (Modul als Objekt programmieren)
BeitragVerfasst: 23.12.2015 00:13 
Offline
Benutzeravatar

Registriert: 25.04.2006 17:29
Wohnort: Nähe Hamburg
Hallo mk-soft,

cool! Vielen Dank für deine Modulbasierte OOP Lösung.

OOP ist bisher mehr oder weniger an mir vorbei gegangen und ich habe mich erst vor kurzem dazu entschlossen mir OOP-basierte Entwicklungsumgebungen anzusehen, weil manche komplexe Aufgabe damit vermutlich besser zu lösen sind. Zumindest für mich persönlich, weil ich bei komplexen Programmen schnell den Fokus und den Überblick verliere.

Die Wahl fiel (unter anderem mit Hilfe des Forums) auf C++ und ich hatte mich bereits darauf eingelassen eine komplett neue Sprache zu erlernen, um mich mit dem Thema eingehender zu beschäftigen. Wie das so ist... aus Zeit- und Weihnachtsgründen habe ich diesbezüglich noch keine größeren Schritte unternommen.

Und jetzt sehe ich das hier. Hab mich sehr darüber gefreut - und zwar aus mehrerlei Hinsicht.

1) Deine Lösung kommt ohne einen PreCompiler aus! Ich hatte zur Zeit von PureBasic 5.00 schon mal versuchsweise eine der im Forum verfügbaren Precompiler-Lösungen getestet. Allerdings habe ich den weiteren Einsatz bei Auftreten der ersten Fehler bzw. "Eigenheiten" des Precompilers wieder verworfen. Grund: Ich war auf das Gutdünken des PreCompiler Programmierers angewiesen. Leider war das Projekt zu diesem Zeitpunkt beim Programmierer schon auf der "Sterbensliste" und ich sah mich leider nicht in der Lage den Fehler selbst auszumerzen.

2) Deine Lösung ist herrlich kompakt. Momentan verstehe ich zwar nur Bruchteile von den Internas (das mag auch mit an dem Bierchen liegen, dass ich mir heute Abend gegönnt habe :D), aber ich denke, dass ich die grundlegenden Funktionsprinzipien deiner OOP Lösung bei so einer überschaubaren Codelänge auch irgendwann in mein prozedurales Hirn hineingehämmert bekomme.

3) Möglicherweise bedeutet OOP viel mehr als Deine Lösung derzeit anbietet (ich kann das als ausschließlich prozedural arbeitender Programmierer nicht beurteilen), aber das, was deine Lösung bereits anbietet, sollte als Grundstein völlig ausreichen was meine Vorstellungen von erleichternder Programmierung in OOP angeht.

4) Es ist PureBasic. Wenn ich damit wirklich den Vorteil erlangen kann, den ich mir vom Einsatz einer zweiten OOP basierten Sprache erhofft habe (in meinem Fall hatte ich vor ein paar Tagen C++ gewählt), dann muss ich mich nicht etlichen neuen Problemen stellen: C++ lernen, in ein neues Programmierwerkzeug einarbeiten, rausfinden wie man C++ Code in ein PB Programm einbindet (z.B. als LIB), usw. Ich muss mich absolut nicht umgewöhnen und kann in meiner Lieblingssprache in der gewohnten IDE weiterarbeiten. Lediglich deine OOP-Syntax und besser noch die Internas deines OOP Moduls muss ich mir als neues Wissen aneignen. Und das sind derzeit gerade mal 4 Bildschirmseiten - so what!? Ich bin entzückt. :-)

Allerdings dazu noch eine Frage:

Wie schätzt du deinen code ein? Ist das alles schon wasserdicht ohne Memoryleaks oder vergessende Strukturen? Würdest du das Modul z.B. für ernsthafte Anwendungen nutzen oder ist das ganze eher als proof of concept anzusehen, also frühes alpha oder beta stadium? Ich kann das ehrlich gesagt nicht einschätzen.

Auf jeden Fall vielen Dank, dass du das teilst. :allright:

Edit:
Gleich noch eine Frage. Das Macro NewClass() entspricht der Prozedur AddClass(). Diese Prozedur gibt den Pointer von AddElement() zurück. Allerdings wird damit in Deinen Beispielen nichts weiter gemacht. Es wird lediglich NewClass() aufgerufen ohne den Rückgabewert irgendwo zu speichern. Ist dieser Wert nur irgend eine Testoption von dir oder hat er eine andere Bewandtnis?

_________________
"Never run a changing system!"
PB 5.62, OS: Windows 7 Pro x64, Desktopscaling: 125%, CPU: I7 6500, RAM: 16 GB, GPU: Intel Graphics HD 520
Ich bin Baujahr 1968, also aktuell 51.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Modul BaseClass (Modul als Objekt programmieren)
BeitragVerfasst: 23.12.2015 02:01 
Offline
Benutzeravatar

Registriert: 24.11.2004 13:12
Wohnort: Germany
Mein Ziel ist es ja nicht eine OOP-Sprache in Purebasic zu integrieren, sondern die Tipparbeit zu erleichtern.
Somit auch die Funktion der IDE wie Autovervollständigung und Anzeige der Procedure zu erhalten.

Purebasic bringt ja alles für Objektorientierung mit.
- Interfaces mit Vererbung. (Extends)
- Aufrufumgebung für Objekte

In der Hilfe für Interfaces fehlen allerdings funktionierende Beispiele.
Zu Objektorientierte Programmierung muss man wissen das beim Aufruf der Methode der erste Parameter der Zeiger auf das eigene Objekt ist. Der erste Eintrag ist immer der Zeiger auf die Funktionstabelle. Danach kommen die Daten für die Properties.

Bei den Verfahren in meiner BaseClass verwalte ich alle Objekte in einer Map. Diese kann man sich im Debugger auch anschauen.

Zu den fragen:
1. Es sollte zu keinen Speicherlecks führen. Auch bei der Verwendung von Listen und Map in den Properties.
Dazu wird zum anlegen des Objekts AllocateStructure und bei Release FreeStructure verwendet.

2. Das Konzept möchte ich so beibehalten und nur noch erweitern oder optimieren.

3. NewClass() wird ja ohne Parameter oder mit der zu Erbenen Objekt aufgerufen. AddClass(...) benötigt aber zur Verwaltungen der Objekte noch den Modulnamen. Dieser wird mit den Macro NewClass() automatisch mit den richten Modulname gesetzt.

Der Rückgabewert von NewClass() kann dazu verwendet werden ob das Object erfolgreich angelegt wurde.
Wird bei meinen kleine Beispielen etwas vernachlässigt.

So das war erstmal alles :wink:

_________________
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner v1.x / OOP-BaseClass-Modul / OPC-Helper DLL
PB v3.30 / v5.4x - OS Mac Mini OSX 10.xx / Window 10 Pro. (X64) /Window 7 Pro. (X64) / Window XP Pro. (X86) / Ubuntu 14.04
Downloads auf Webspace


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Modul BaseClass (Modul als Objekt programmieren)
BeitragVerfasst: 23.12.2015 11:03 
Offline
Benutzeravatar

Registriert: 25.04.2006 17:29
Wohnort: Nähe Hamburg
Besten Dank für die Beantwortung der Fragen. :allright:

Code:
2. Das Konzept möchte ich so beibehalten und nur noch erweitern oder optimieren.

Ich find's klasse, eben weil es (für mich) nicht zu überladen ist und ich weniger Zeit für die Einarbeitung brauche. Sicher muss ich mir alle Folgeklassen selbst schreiben, aber das soll ja kein Nachteil sein. :-)

_________________
"Never run a changing system!"
PB 5.62, OS: Windows 7 Pro x64, Desktopscaling: 125%, CPU: I7 6500, RAM: 16 GB, GPU: Intel Graphics HD 520
Ich bin Baujahr 1968, also aktuell 51.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Modul BaseClass (Modul als Objekt programmieren)
BeitragVerfasst: 23.12.2015 12:18 
Offline
Benutzeravatar

Registriert: 24.11.2004 13:12
Wohnort: Germany
Was noch irgendwann erweitert wird das die BaseClass auf die Schnittstelle Unknown angepasst wird (fehlt ja nicht mehr viel)
und die Schnittstelle Dispatch bereitstelle.
Somit lassen sich dann auch DLL´s erstellen die man z.B unter "VB-Script" verwenden kann.

Diese haben aber keine Auswirkung auf die bisherige Verwendung.

Bin aber zur Zeit meistens nur mit MacOS unterwegs.

_________________
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner v1.x / OOP-BaseClass-Modul / OPC-Helper DLL
PB v3.30 / v5.4x - OS Mac Mini OSX 10.xx / Window 10 Pro. (X64) /Window 7 Pro. (X64) / Window XP Pro. (X86) / Ubuntu 14.04
Downloads auf Webspace


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Modul BaseClass (Modul als Objekt programmieren)
BeitragVerfasst: 25.12.2015 14:56 
Offline
Benutzeravatar

Registriert: 24.11.2004 13:12
Wohnort: Germany
Update v1.11
- Debugger Fehler AsNewMethode. Ruft bei fehlende geerbten Methode CallDebugger auf
- Debugger Info ClassList. Hinterlegt bei eingeschalteten Debugger die verwendeten Klassen in BaseClass mit ab.

:wink:

_________________
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner v1.x / OOP-BaseClass-Modul / OPC-Helper DLL
PB v3.30 / v5.4x - OS Mac Mini OSX 10.xx / Window 10 Pro. (X64) /Window 7 Pro. (X64) / Window XP Pro. (X86) / Ubuntu 14.04
Downloads auf Webspace


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Modul BaseClass (Modul als Objekt programmieren)
BeitragVerfasst: 25.12.2015 23:59 
Offline
Benutzeravatar

Registriert: 25.04.2006 17:29
Wohnort: Nähe Hamburg
Vielen Dank. :allright: Soeben geupdatet. :)

_________________
"Never run a changing system!"
PB 5.62, OS: Windows 7 Pro x64, Desktopscaling: 125%, CPU: I7 6500, RAM: 16 GB, GPU: Intel Graphics HD 520
Ich bin Baujahr 1968, also aktuell 51.


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 54 Beiträge ]  Gehe zu Seite 1, 2, 3, 4, 5, 6  Nächste

Alle Zeiten sind UTC + 1 Stunde [ Sommerzeit ]


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 1 Gast


Sie dürfen keine neuen Themen in diesem Forum erstellen.
Sie dürfen keine Antworten zu Themen in diesem Forum erstellen.
Sie dürfen Ihre Beiträge in diesem Forum nicht ändern.
Sie dürfen Ihre Beiträge in diesem Forum nicht löschen.

Suche nach:
Gehe zu:  
cron

 


Powered by phpBB © 2008 phpBB Group | Deutsche Übersetzung durch phpBB.de
subSilver+ theme by Canver Software, sponsor Sanal Modifiye