Lieber Besucher, herzlich willkommen bei: RPG Studio - Make your World real. Falls dies Ihr erster Besuch auf dieser Seite ist, lesen Sie sich bitte die Hilfe durch. Dort wird Ihnen die Bedienung dieser Seite näher erläutert. Darüber hinaus sollten Sie sich registrieren, um alle Funktionen dieser Seite nutzen zu können. Benutzen Sie das Registrierungsformular, um sich zu registrieren oder informieren Sie sich ausführlich über den Registrierungsvorgang. Falls Sie sich bereits zu einem früheren Zeitpunkt registriert haben, können Sie sich hier anmelden.

  • Playm

    RPG Studio Webmaster

    Sie müssen sich registrieren, um eine Verbindung mit diesem Benutzer herzustellen.

315

Ein super einfaches Pluginsystem für Ruby-Apps entwickeln

Bewertung:

Von Playm, Samstag, 30. September 2017, 22:31

Hier mal wieder ein kleiner Blogpost zum Wochenende. Viel Spaß, Freunde! :hi:

Es galt folgende Aufgabenstellung zu lösen. Gegeben war eine in Ruby geschriebene Anwendung qt_app.rb. Diese sollte jetzt vom Benutzer mit eigenen Bausteinen erweitert werden können, ohne das er aktiv die qt_app.rb-Datei umschreiben müsste. Ich entschied mich dafür ein einfaches Pluginsystem zu entwickeln. Das System war minimalistisch. Die App sollte einfach alle pluged-in Scripts laden und ausführen. Die Plugins sollten schon wissen, was sie tun.
Prinzipiell war das mit dem Scriptsystem im RPG Maker XP bis VX Ace zu vergleichen. Der Maker führte einfach hintereinander alle Scripts aus und hoffentlich kam dann ein feines Spiel bei raus.

Ich wollte aber keine Scripts.rxdata und einen Scripteditor zwischenschalten, sondern der Benutzer würde einfach Rubyscriptdateien in einen bestimmten Ordner legen oder wieder daraus entfernen. Im Grunde genommen nur Dateien verschieben. Das klang einfach und dem Benutzer zumutbar.

Werden wir mal konkret. Das hier ist der Verzeichnisbaum der App.
  • :folder-open: micky/
    • :folder-open: plugins/
      • :document: event_generator.rb
      • :document: gasthaus.rb
      • ...
    • :document: qt_app.rb
    • ...

Also schauen wir mal, wie wir alle Plugins in unsere App laden können. Wir benutzen dafür Rubys require Methode. Diese bekommt als Parameter einen Dateipfad und führt dann das im Dateipfad bezeichnete Script aus. Alle im ausgeführten Script definierten Klassen, Module und Konstanten sind anschließend im require-aufrufenden Script verfügbar.

Haben wir also das folgende Setup
  • :folder-open: /
    • :document: datei_A.rb
    • :document: datei_B.rb


  • Zitat von »datei_A.rb«

    Ruby Quellcode

    1
    2
    
    require( './datei_B.rb' )
    print( M )

    Zitat von »datei_B.rb«

    Ruby Quellcode

    1
    
    M = "Hallo\n"


Und führen jetzt datei_A aus, bekommen wir "Hallo" ausgegeben. Unser Hauptscript hat sich alles, was das andere Script definiert hat geschnappt und kann jetzt damit arbeiten. Genau das, was wir brauchen.

Das Plugin laden funktioniert dann ganz einfach:

Ruby Quellcode

1
2
3
4
5
6
# Get array of filenames
all_plugin_scripts = Dir.glob('./plugins/*.rb')
# Iterate over all filenames
all_plugin_scripts.each do |file|
  require file
end


Ich mag es ja, wenn Code übersichtlich und leicht verständlich ist und das jetzige minimalistische Pluginsystem ist echt nicht schwer zu verstehen.
Zum Abschluss wollen wir noch kurz reinspicken, wie Gasthaus.rb eigentlich im Moment aussieht. Ich schreibe extra "im Moment", weil gerade alles noch in der Entwicklung ist und sich noch einiges Ändern kann. Methoden können noch umbenannt werden oder es kommen neue hinzu. Mal schauen.

Spoiler: Code

Ruby Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
require_relative "./event_generator.rb"
#============================================================================
# ** Creates RPG::Event Instances
#----------------------------------------------------------------------------
#  Generates Inn-Events from boilerplates
#============================================================================
module Gasthaus
  #--------------------------------------------------------------------------
  # * Generator Infos
  #--------------------------------------------------------------------------
  GENERATOR_VERSION = "0.2.0"
  #--------------------------------------------------------------------------
  # * This Generator requires user input
  #--------------------------------------------------------------------------
  def self.use_dialog
    return true
  end
  #--------------------------------------------------------------------------
  # * Label for the Generator trigger
  #--------------------------------------------------------------------------
  def self.label
    "Gasthausbesitzerin"
  end
  #--------------------------------------------------------------------------
  # * Define Dialog widgets
  #--------------------------------------------------------------------------
  def self.dialog_options
    cost     = Event_Generator::Dialog_Option.new( :cost, "Preis", 10, {:range=>(0..999)} )
    currency = Event_Generator::Dialog_Option.new( :currency, "Wärung", "G" )
    return [cost, currency]
  end
  #--------------------------------------------------------------------------
  # * Create a new Inn owner Event
  #--------------------------------------------------------------------------
  def self.create_from_options( options )
    cost = options[:cost]
    currency_name = options[:currency]
 
    ev = RPG::Event.new(0,0)
    ev.name = "Besitzerin"
    ev.pages[0].graphic.character_name = "123-Civilian23"
    ev.pages[0].list = [
      RPG::EventCommand.new( 101, 0, ["Eine Nacht kostet euch #{cost}#{currency_name}. Möchtet ihr bleiben? \\G"] ),
      RPG::EventCommand.new( 102, 0, [["Ja", "Nein"], 2] ),
      RPG::EventCommand.new( 402, 0, [0, "Ja"] ),
      RPG::EventCommand.new( 111, 1, [7, cost, 0] ),
      RPG::EventCommand.new( 125, 2, [1, 0, cost] ),
      RPG::EventCommand.new( 223, 2, [Tone.new(-255,-255,-255), 10] ),
      RPG::EventCommand.new( 249, 2, [RPG::AudioFile.new("014-Inn01", 80, 100)] ),
      RPG::EventCommand.new( 106, 2, [80] ),
      RPG::EventCommand.new( 314, 2, [0] ),
      RPG::EventCommand.new( 223, 2, [Tone.new(0,0,0), 10] ),
      RPG::EventCommand.new( 0, 2, [] ),
      RPG::EventCommand.new( 411, 1, [] ),
      RPG::EventCommand.new( 101, 2, ["Ihr habt nicht genug Geld."] ),
      RPG::EventCommand.new( 0, 2, [] ),
      RPG::EventCommand.new( 412, 1, [] ),
      RPG::EventCommand.new( 0, 1, [] ),
      RPG::EventCommand.new( 402, 0, [1, "Nein"] ),
      RPG::EventCommand.new( 0, 1, [] ),
      RPG::EventCommand.new( 404, 0, [] ),
      RPG::EventCommand.new( 0, 0, [] )
    ]
    return ev
  end
end
#============================================================================
# << Add generator in the list of available generators
#============================================================================
Event_Generator::CHILDS << Gasthaus
zum Lesen den Text mit der Maus markieren


Wir sehen: Plugins sind Rubymodule, die ganz bestimmte Methode implementieren. Die App schaut dann einfach im Event_Generator::CHILDS-Array nach, welche Module es so gibt und zeigt dann für jedes Plugin einen Knopf an. Wenn der App-User den Knopf drückt, kommt bei Bedarf erst noch ein Dialog und ansonsten generiert die App mit dem Plugin ein neues Event und kopiert dieses dann in die Zwischenablage.

Soweit der Blick hinter die Kulissen. Noch ein schönes Wochenende!

Dieser Artikel wurde bereits 38 mal gelesen.


Kommentare (2)

  • 2

    Von Playm (Sonntag, 1. Oktober 2017, 23:38)

    Upps. D:
    Habe schnell das R ergänzt.

  • 1

    Von Josey (Sonntag, 1. Oktober 2017, 01:05)

    Wirklich interessant und diesmal hab ich sofort verstanden, worum es geht! XD
    Der Code sieht wie etwas aus, dass ich nach dem Vobild auch hinkriegen könnte! Ich bin sehr interessiert, wies weitergeht! : D

    "Wäung"-> Da fehlt ein R : P

Blog Navigation

Nächster Artikel

Eine App schreiben, die RPG Maker Projekte öffnen kann

Von Playm (Sonntag, 8. Oktober 2017, 17:10)

Vorheriger Artikel

Mit Ruby eine GUI bauen

Von Playm (Sonntag, 24. September 2017, 08:00)