Multiple components in one library

edited February 2014 in Ruby Scripting

Hi,

I notice the Circle generator PCell example basically looks like this:

module MyLib

  include RBA

  # Remove any definition of our classes (this helps when 
  # reexecuting this code after a change has been applied)
  MyLib.constants.member?(:Circle) && remove_const(:Circle)
  MyLib.constants.member?(:MyLib) && remove_const(:MyLib)

  # The PCell declaration for the circle
  class Circle < PCellDeclarationHelper

    include RBA

    def initialize
      # CODE
    end

    def display_text_impl
      # CODE
    end

    def coerce_parameters_impl
      # CODE
    end

    def can_create_from_shape_impl
      # CODE
    end

    def parameters_from_shape_impl
      # CODE
    end

    def transformation_from_shape_impl
      # CODE
    end

    def produce_impl
      # CODE
    end

  end

  # The library where we will put the PCell into 
  class MyLib < Library

    def initialize  

      # Set the description
      self.description = "My First Library"

      # Create the PCell declarations
      layout.register_pcell("Circle", Circle::new)
      # That would be the place to put in more PCells ...

      # Register us with the name "MyLib".
      # If a library with that name already existed, it will be replaced then.
      register("MyLib")

    end

  end

  # Instantiate and register the library
  MyLib::new

end

Notice the comment near the end where "# That would be the place to put in more PCells ..."

I can indeed pack this file with more PCells. However is there a way to have multiple PCells in different .lym files, and have them all registered under "MyLib"?

Currently if I have two Ruby PCell script files, say, "CircleGenerator.lym" and "DonutGenerator.lym", and they both want to exist in MyLib, then whenever you run CircleGenerator.lym it clears the other one. This is of course explained in the comment above: "# Register us with the name 'MyLib'. # If a library with that name already existed, it will be replaced then."

So, I tried a few things including splitting out that final class above into its own file and having the various PCells refer to it, but no luck.

Thanks!

Comments

  • edited February 2014

    Hallo,

    not .lym files but regular -rb files.

    Let me explain that: .lym files are "annotated" scripts. They are script code plus some metadata that allow KLayout to determine the script language, the title and whether the script shall be exposed in a menu. Inside the .lym file resides the Ruby code. Since .lym files are in fact XML, the cannot be included by the Ruby interpreter. But normal Ruby files can.

    You can include such files the usual way with "require" or "load", provided you have pointed the interpreter to your installation site.

    Here is an simplified example:

    File "circle.rb":

    module MyLib
      class Circle < RBA::PCellDeclarationHelper
        ...
      end
    end
    

    File "square.rb":

    module MyLib
      class Square < RBA::PCellDeclarationHelper
        ...
      end
    end
    

    File "mylib.lym":

    $:.push(File.dirname($0))
    load "circle.rb"
    load "square.rb"
    
    module MyLib
      class MyLib < RBA::Library
        ...
        layout.register_pcell("Circle", Circle::new)
        layout.register_pcell("Square", Square::new)
        ...
      end
      MyLib::new
    end
    

    The $: trick makes the ruby interpreter look for circle.rb and square.rb at the same location where it finds "mylib.lym", so you can install the three files in the macros folder without having to hardcode the path in the scripts. "load" can only load normal Ruby files, but there is no metadata required so that is fine.

    Matthias

  • edited November -1

    Thanks Matthias,

    However it tells me

    Caught the following exception:
    uninitialized constant MyLib::MyLib::Circle (Class NameError)
    

    I've tried various things but am not understanding why it sees Circle::new as a constant of MyLib rather than as a class. I did include it using load "circle.rb" as you said...

  • edited March 2014

    Ah, never mind, I just had to change

    Circle::new
    

    to

    Circle::Circle::new
    

    (note I called the circle module "Circle")

    Thanks!!

Sign In or Register to comment.