Plasmacore v3.5

From Plasmaworks

Jump to: navigation, search

Contents

3.5 Overview

  • Compiler-side delegate method support.
  • Limited compiler-side introspection support.
  • Linux Platform is now defunct for the time being (the new version of Ubuntu breaks it).


Download

  • To start a new project, unzip the file above, open in a command prompt in the new_project folder, and type:
  • Windows:
 gogo build
  • Mac, Linux:
 chmod +x gogo
 ./gogo build
  • To upgrade an existing project, run "gogo upgrade" once to upgrade the core module, run "gogo" to finish the install, and then run "gogo upgrade" once more time to upgrade the auxiliary modules.


Change Log for 3.5.0 (June 18, 2011)

Delegate Methods

Slag now supports delegate methods aka function pointers. By example:

 class Test
   METHODS
     method init
       perform_test( delegate(add), Global.delegate(println(Int64)) )
         # Note: Global has more than one println() so we must add a signature
         #       when obtaining the delegate.
 
     method add( Int32 a, Int32 b ).Int32
       return a + b
 
     method perform_test( Delegate(Int32,Int32).Int32 fn, Delegate(Int64) printfn )
       printfn.call( fn.call(3,5) )  # Prints: 8
 endClass
  • Delegates are objects that store an object context and call a specific method on that object with specific parameters.
  • The type of a delegate is Delegate(ParamType1,ParamType2,...).ReturnType
  • To create a delegate from an existing method, call obj.delegate(method_name).
  • If the method is overloaded you will need to be more specific and supply a signature. For example, "Math.delegate(abs)" would fail because there are multiple overloaded variations (Real64, Int64, etc.). Instead write "Math.delegate(abs(Real64,Real64))" or "Math.delegate(abs(Int64,Int64))".
  • On any given delegate function you can access ".context" to retrieve the object that the delegate operates on.
  • The signal handlers now support delegates. Example:
 ...
 method init
   SignalHandler( "update", delegate(tick) )
 
 method tick
   println( "The game is being updated." )


Introspection

  • Added some compiler-side (instead of runtime) support for introspection (aka reflection) back to Slag.
  • Added a new class qualifier runtime. A "runtime" class causes the compiler to generate extra runtime type information. Details are as follows:
  • Any class that extends a runtime class is also a runtime class.
  • For every runtime class e.g. "Wall" there exists a class RuntimeTypeWall that extends RuntimeType. Calling runtime_type() on a Wall() object will return a reference to RuntimeTypeWall, as will calling Runtime[Wall] or Runtime["Wall"].
  • On any given RuntimeType you can call name() (which returns the same thing as Object::type_name()) and create_instance().Object, which creates an instance of that type.
  • You can also call Runtime.create("ClassName") to create an object of class "ClassName".
  • Runtime classes are very useful for creating objects from data files.
  • Example:
 runtime class Fruit();
 class Strawberry( Real64 tastiness ) : Fruit;
 ...
 local var berry = Runtime.create("Strawberry") as Strawberry
 if (berry?)
   berry.init( 0.8 )   # Call the "regular" initializer
 else
   println( //No such class "Strawberry".// )
 endIf
Note that a default init() method will be created for any runtime class that doesn't have one already, so in the example above two different initializers are called - the default init() and the regular init(Real64).
  • Every RuntimeType has a list of base_type_names:String[] and a list of base_types[]:RuntimeType. Both include direct and indirect types. base_type_names includes both runtime types and other types, while base_types only includes runtime types.
  • If class Actor extends Entity, then Runtime[Actor].instance_of(Runtime[Entity]) == true and Runtime[Actor].instance_of("Object") == true.

Timer

The Plasmacore Timer class has been revamped to use delegate methods. By example:

 class TimeTest
   PROPERTIES
     seconds : Int32
 
   METHODS
     method init
       Timer.schedule( delegate(on_interval), 60 )
         # Call on_interval() once every second
     
     method on_interval
       println( "tick" )
       ++seconds
       if (seconds == 5)
         # Cancel after 5 seconds
         Timer.cancel( this )
       endIf
 endClass


Linux Platform Defunct

  • The latest version of Ubuntu Linux ("Natty") has removed the Audiere library that Linux Plasmacore depends on, effectively breaking Linux Plasmacore. Linux Plasmacore is sadly defunct for the time being - until we can spare the time to fix it (or we find proof that anyone is actually using Linux Plasmacore).

Miscellaneous

  • Key events are fixed - they were inadvertently broken in v3.4.
  • Changed HashTable get() to return "null", "0" or "false" for a non-existent element instead of throwing a NoSuchElement error. This makes an initial call to contains() optional in many cases and is more efficient in general.
  • Modified parser so that the expression Int64(literal_int32) produces positive Int64 values for literal values that would be negative as an Int32. For example, Int64(0xffffffff) now results in 2147483647 instead of -1.
  • Added the keyword ThisType that resolves to the current class type. For example, if you're in class Apple and you write "return ThisType()" you'll be returning a new Apple object.
  • Renamed the Task property active to be task_active instead to avoid common naming conflicts with extended Tasks.
  • Fixed scope bug with class methods - if Orange extends Fruit and both classes define a class method create(), then directly calling "Orange.create()" could mistakenly call "Fruit.create()" depending on the order that classes were defined in.

Previous Versions