Programmteil wieder aus Speicher entfernen

Übersicht BlitzMax, BlitzMax NG Allgemein

Neue Antwort erstellen

 

Xar

Betreff: Programmteil wieder aus Speicher entfernen

BeitragDi, Dez 28, 2010 12:35
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo zusammen

Ich suche nun schon länger nach einer Möglichkeit, einen dem Hauptprogramm angehängten Programmteil wieder zu entfernen und (in einer abgeänderten Variante) erneut zu laden. Ich habe mich intensiv durch die INCLUDE-Beiträge gelesen und komme zum Schluss, dass das damit nicht geht, da wie es scheint Include Zusatzprogramme sowieso vor dem Compilieren anhängt und ich somit nach dem Löschen des Teils keinen neuen mitten während des Programmablaufs anhängen kann.

Vermutlich gehe ich es ja grundsätzlich falsch an:

Ich kreiere ein Spiel. Die ganze Steuerung usw. ist in der Hauptschleife im Hauptprogramm. Je nachdem in welchem "Bild" man sich befindet, ändern sich lediglich die Grafik und was passiert wenn man mit etwas interagiert.

Das heisst, dass nur ein relativ kleiner Teil des Programms von Bild zu Bild variabel ist, es aber sehr viele solche "Bilder" gibt. Und diesen variabeln Teil wollte ich in ein eigenes BMX für jedes Bild auslagern, damit ich nicht dutzende Functions dafür haben muss und mich in all den Variabeln verstricke.

Das Programm würde sonst sehr gross und unübersichtlich. Am liebsten wäre es mir, ich hätte eine Function in einem eigenen BMX, und sobald man das Bild verlässt und in ein neues Bild gelangt, schliesse ich diese Function und öffne (anhand eines eigenen BMX) die entsprechende neue Function mit gleichem Namen.

dadurch, dass der Function-Name immer gleich bleibt und lediglich unterschiedliche Varianten dieser Function geladen werden, sind sämtliche Aufrufe aus dem Hauptprogramm immer korrekt.

Gibt es eine Möglichkeit, so ein externes Modul zu laden, zu schliessen und erneut zu laden?

Lord Stweccys

BeitragDi, Dez 28, 2010 12:45
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich weiß nicht, ob ich dich richtig verstanden habe, ich ich glaube,
du möchtest levelabhängige Programmteile von der Festplatte laden und sobald man das Level
wieder verlässt, wird die Funktion aus dem Speicher gehauen und
eine neue Funktion von der Festplatte geladen.

Wenn das das ist, was du möchtest, kann ich dir sagen, dass das etwas kompliziert ist und
du kleine Assemblerkentnisse haben musst. Ich habe mir selbst schon so etwas modulares überlegt,
doch das ist natürlich mit einigen Hürden verbunden (ist ja klar Very Happy )
Die Funktion wird ja in Assembler konvertiert. Diese Funktion kannst du auch alleine konvertieren
(unter bestimmten Gegebenheiten) und dann durch ein MemAlloc in den Speicher hauen.

Ich hab das vielleicht etwas kompliziert erklärt (Erklären ist nicht grade meine Stärke) aber das,
was ich dir geschrieben habe funktioniert auch so, denn ich habe es bereits selbst ausprobiert.
Wenn du willst, kann ich dir den Code schicken.

Xeres

Moderator

BeitragDi, Dez 28, 2010 12:47
Antworten mit Zitat
Benutzer-Profile anzeigen
Kurze Antwort: Nein.
Code wird Compiliert und zu einer Exe zusammen gefasst.

Ich hab noch nicht ganz verstanden, was genau du erreichen willst, aber ggf. lässt sich das über eine (simple) Skriptsprache o.ä. lösen.
Win10 Prof.(x64)/Ubuntu 16.04|CPU 4x3Ghz (Intel i5-4590S)|RAM 8 GB|GeForce GTX 960
Wie man Fragen richtig stellt || "Es geht nicht" || Video-Tutorial: Sinus & Cosinus
T
HERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld)
 

Xar

BeitragDi, Dez 28, 2010 12:59
Antworten mit Zitat
Benutzer-Profile anzeigen
Danke. Da stoss ich dann vermutlich an meine noch etwas bescheidenen Kenntnisgrenzen. Was ich versuche zu erreichen, ist in etwa das, was Lord beschreibt.

Es geht um ein Spiel in der Art der Lucas-Adventures (Gehe zu, Nimm, Benutze usw.) . Das ganze GUI und die Befehlsfunktionen sind programmiert und funktionieren. Nun gibt es natürlich in jedem Bild völlig eigenständige Interaktionsmöglichkeiten. Also für jedes Bild brauche ich eigene Checks, was die Mausposition innerhalb des Grafik anbelangt. Und auch alle möglichen Kombinationen von Interaktionen mit Gegenständen aus diesem Bild.

Alle Interaktionen, welche in jedem Bild möglich sind (z.B. Interaktionen mit den Inventar-Objekten und alles, was mit den Befehlen zu tun hat) ist im Hauptprog abgedeckt.

Nur gibt es dermassen viele Möglichkeiten pro Bild (einige hundert Zeilen mit Checks und entsprechenden daraus resultierenden Textausgaben oder Aktionen), dass ich den Überblick verliere, wenn ich alles an "eine Wurst" packe. Und da ich nicht nur unterschiedliche Werte brauche, sondern auch Programmcode, kann ich es nicht einfach in Datenbanken oder Files auslagern.

*grübelgrübel*

Nachtrag: Falls ihr noch Ideen habt, bin ich dankbar für alles. Ich werde es vorläufig wohl mal so weiterverfolgen, dass ich zwar einzelne BMX mache, diese aber mit unterschiedlichen Function-Namen bestücke und alle zusammen beim Programmstart mit INCLUDE lade. Nicht sehr elegant, aber anyway...
 

undefined

BeitragDi, Dez 28, 2010 14:42
Antworten mit Zitat
Benutzer-Profile anzeigen
Wenn Du es ohne den Aufwand externer Skripte lösen möchtest, dann wäre die eleganteste Methode, dass Du eine Basis-Objektklasse definierst, von der Du alle Räume aus vererbst. So wäre es geordnet, Du kannst die Räume individuell durchstrukturieren und Du kannst sie in der Hauptschleife und anderen Programmteilen dennoch gleich behandeln. Wenn Du die Inhalte dann noch vernünftig und dynamisch programmierst (arbeite mit Methoden, Listen/Arrays und Objekten, um die Räume zu beschreiben! - keine 500 Zeilen IF-THEN und keine einzelnen "mein_gegenstand_x" und "position_von_stuhl" Variablen!), dann kann man das damit sehr gut und angenehm umsetzen.

Xeres

Moderator

BeitragDi, Dez 28, 2010 18:03
Antworten mit Zitat
Benutzer-Profile anzeigen
Xar hat Folgendes geschrieben:
Also für jedes Bild brauche ich eigene Checks, was die Mausposition innerhalb des Grafik anbelangt. Und auch alle möglichen Kombinationen von Interaktionen mit Gegenständen aus diesem Bild.
Dann hast du noch nicht viel Erfahrung mit Programmstrukturierung? Hört sich jedenfalls sehr nach Hardcodeing an. Wie undefined schon schrieb: Benutze Funktionen & Objekte um den Code zu verallgemeinern. Was anderes ist immer unpraktikabel.
Win10 Prof.(x64)/Ubuntu 16.04|CPU 4x3Ghz (Intel i5-4590S)|RAM 8 GB|GeForce GTX 960
Wie man Fragen richtig stellt || "Es geht nicht" || Video-Tutorial: Sinus & Cosinus
T
HERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld)

Thunder

BeitragDi, Dez 28, 2010 20:18
Antworten mit Zitat
Benutzer-Profile anzeigen
Was ist mit der Lua VM aus dem Lua Modul (pub.lua)?
Da brauchst du nicht eine eigene Skriptsprache entwerfen.
Meine Sachen: https://bitbucket.org/chtisgit https://github.com/chtisgit

das wurgel

BeitragDo, Dez 30, 2010 4:55
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich schließe mich undefined und Xeres an. Ich versuche dir Mal zu veranschaulichen, wie ich es machen würde:

In deinem Hauptprogramm definierst du eine Globale, die den auf den aktuellen Screen zeigt:

BlitzMax: [AUSKLAPPEN]
Global screen:TScreen


Diese Variable hat den Typ TScreen, welcher ebenfalls noch im Hauptprogramm ist:

BlitzMax: [AUSKLAPPEN]
Type TScreen
' In dem Typen sind schonmal ein paar Grundlegende Funktionalitäten, wie zum Beispiel das Hintergrundbild und das Zeichnen des Screens allgemein (da kommt je nach Screen noch etwas dazu)
Field hintergrund:TImage

Method draw()
DrawImage hintergrund, 0,0
End Method

Method check() Abstract ' Jeder Screen soll Benutzereingaben prüfen, aber es ist noch nicht definiert was er genau machen soll, deswegen das "Abstract"

' Hier können noch weitere grundlegende Methoden hin, die vom Hauptprogramm aufgerufen werden, aber bei jedem Screen anders sind
End Type

Um jetzt einen bestimmten Screen zu programmieren, erstellst du jeweils eine neue Klasse, die voll funktionsfähig ist und von TScreen abgeleitet wird. Diese kannst du in einzelne Dateien auslagern, welche du mit Include in das Hauptprogramm einbindest.

Datei: meinscreen.bmx

BlitzMax: [AUSKLAPPEN]
Type TMeinScreen Extends TScreen

Method draw()
Super.draw() 'Um die alte Funktionalität zu erhalten können die Mehoden der Superklasse (TScreen) ausgeführt werden
' Hier können zusätzlich noch Dinge gezeichnet werden
End Method

Method check()
' Hier werden die Screenspezifischen Checks durchgeführt
' Bsp.: If *Spieler drückt auf Tür* Then screen=*anderer Screen*
End Method
End Type

'In der Datei wird global ein Objekt des Typen angelegt, da es von jedem Screen eh nur ein Exemplar geben wird:
Global beispielscreen:TBeispielScreen = New TBeispielscreen
beispielscreen.hintergrund=LoadImage(dies und das)
'Diese Globale wird dann überall benutzt, wo der Spieler den Screen betritt (screen=beispielscreen)


Im Hauptprogramm würde dann so aus sehen:

BlitzMax: [AUSKLAPPEN]
Include "beispielscreen.bmx"
Include "anfangsscreen.bmx"
Include "screendies.bmx"
Include "screendas.bmx"

Global screen:TScreen

screen=anfangsscreen

Repeat
...
screen.check() ' Der springende Punkt der ganzen Sache: Je nachdem in welchem Screen sich der Spieler befindet, ist die check() und die draw() Methode eine andere.
...
screen.draw()
...
Until ende


Hoffe ich habe dir etwas näher gebracht, wie man mit Objekt orientierter Programmierung sein Programm dynamischer und übersichtlicher machen kann.
1 ist ungefähr 3
 

PhillipK

BeitragDo, Jan 06, 2011 19:24
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo Ihrse Smile

Nun, ich möchte auch meinen Senf dazu geben Smile

Ich würde es im prinzip so machen, wie das wurgel es erklärt hat.. Allerdings würde ich nicht für jeden raum hardcoded eine eigene BMX auslagern.. wenn ichs mir richtig überlege, kann man jede aktion in einem solchen Point&Click adventure irwi zusammenfassen ^^"

Mein Ansatz wäre, das ich mir einen "editor" schreibe, welcher sehr wohl hardcoded eine map enthält, aber mit einer Save Methode in eine datei auslagert.
Beim Mapwechsel wird die gegensätzliche Load methode im TScreen obj ausgeführt und in ein aktives objekt geladen.
Alternativ könnte man die TScreens mit namen versehen ("Badezimmer1") und alle zusammen in eine TMap auslagern..
Aber ich will nicht zuviel rumbrabbeln, ich bin selbst kein wirkliches Ass im programmieren, sondern stelle nur mehr schlecht wie recht was zusammen.

Aber um noch einmal auf die Load/Save funktion einzugehen:

BlitzMax: [AUSKLAPPEN]
Type TScreen

Field background:TImage ' hier das bild..
Field backgroundFile:String "" ' hier ein Pfad zum hintergrund bild o.ä!
Field mapL:String = "" ' hier der name der map, welcher zur linken kommt (zb)
Field mapR:String = "" ' hier der name der map, welcher zur rechten kommt (brauche ein paar Fields :P)

Method Save(toFile:String, pfad:String = "") ' optionaler pfad
Local fileStream:TStream
If (FileSize(toFile)>0) Then ' prüft, ob die datei schon vorhanden ist.. *quick 'n dirty*
fileStream = OpenFile(pfad+toFile) ' Öffnet eine datei und setzt den Schreibecursor hinten an *denk*
Else
fileStream = WriteFile(pfad+toFile) ' Erstellt eine datei und öffnet sie zum Schreibzugriff *denk*
EndIf

fileStream.WriteInt( Len ( Self.backgroundFile ) )
fileStream.WriteString( Self.backgroundFile )

fileStream.WriteInt( Len ( Self.mapL ) )
fileStream.WriteString( Self.mapL )

fileStream.WriteInt( Len ( Self.mapR ) )
fileStream.WriteString( Self.mapR )
End Method

Function Load:TScreen(fromFile:String, path:String = "") 'auch hier ein optionaler pfad zb ^^
'das selbe wie in der save funktion, stream öffnen und mit stream.ReadString() wieder auslesen.
' beachte hierbei, das stream.ReadString() die länge eines Strings erwartet. Ich verschachtel das, aus faulheit, immer direkt ^^

Local tmpTScreen = New TScreen

tmpTScreen.backgroundFile = fileStream.ReadString( fileStream.ReadInt() ) 'beachte: Readint wird zuerst ausgeführt. Deshalb habe ich in den "paketen" oben immer erst die länge eines strings gespeichert.

[... blablabla .... ]
Return tmpTScreen
End Function
End Type




------

Jetzt so nach dem betrachten, weiß ich nicht ob es so klug war, diesen Kauderwelsch zu schreiben.
Aber naja, ich lass es mal nicht umsonst geschrieben sein, vllt hilfts ja trotzdem ein wenig Sad

Bei dem obigen beispiel könnte man zb mit TScreen.Load("Hinterzimmer.map", "map\") eine map laden.
Du könntest auch alle Dateien in einem ordner durchgehen, jede datei als "TScreen" laden (bzw evtl noch eine unterklasse, je nachdem wo du die Save funktion ansetzt! Wichtig ist, das diese ALLE Felder einer klasse speichert, dh bei einer vererbung auch die übergeordneten Felder von TScreen etc).

Da ich mich in TMaps verliebt habe, würde ich eine TMap mit CreateMap() anlegen und dort alle maps anhand ihres namens einsortieren. (eine TMap kann immer einen "key" für eingetragene werte entgegen nehmen. Da eignet sich dann hervorrangend der Dateiname der map für. Bei einem mapwechsel wird ein globals "aktives" obj einfach durch ein TScreen( TMap.valueForKey("Hinterzimmer") ) ersetzt, worauf dann alles eingeht.

Ach herrje, ich schreibe zuviel und zu wirr.. Vielleicht war es ein Denkanstoß, aber vllt wars auch ein genick brauch. Erklären ist nicht meine stärke und weiß gott, das ist sicher nicht die schlauste idee wie ich sowas lösen würde^^

Gruß, Phillipk

Ps: Der code ist quick & dirty, rechtschreibfehler sind nicht beabsichtigt aber auch nicht überprüft *g* nicht zu viel erwarten, sollte eine veranschaulichung werden und kein funktionierender code.

Neue Antwort erstellen


Übersicht BlitzMax, BlitzMax NG Allgemein

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group