FreeWRL
view release on metacpan or search on metacpan
ARCHITECTURE view on Meta::CPAN
Scene Manager .... Event model, node actions
| |
V V
Renderer Script interfaces
---
Q. How do you parse the file, ie when and how do you create "objects" (in
terms of VRML)
A. The file Parser.pm contains the top-level parse loop,
the function VRML::Parser::parse is the key. The way parsing works
is that the parser reads the file and calls the VRML::Scene object
which was passed to it to create nodes and such while parsing.
E.g. if you give the parser a file like
Transform {
translation 1 0 0
children [
Shape { geometry Box { } }
]
}
Then the parser calls the functions in the scene object like
(in exact perl syntax, i.e. [1,0,0] is an anonymous array etc.)
All types are translated into native Perl types for easy access.
$a = $scene->new_node("Box", {});
$b = $scene->new_node("Shape", {geometry => $a});
$c = $scene->new_node("Transform", {translation => [1,0,0],
children => [$b]}); # Notice children is an array reference (MFNode)
$scene->topnodes([$c]); # Set which nodes were top-level in the scene.
---
Q. How do you handle PROTOs ?
A. This is currently a bit complicated and messy, I hope to rewrite it
a little later. The important file is Scene.pm
Once the scene has been created (this needs to be changed later
due to bindable nodes.. this is the way it is currently implemented),
I call the $scene->make_executable method. This method iterates through
all the nodes of the scene and expands prototypes by placing the prototype
in the {ProtoExp} member of the node structure. VRML::Node::make_executable
is where this happens.
Prototypes (and their instances) are actually represented internally
by the same structure that scenes are represented by (VRML::Scene).
This structure takes care of the name space of the instance.
---
Q. What is the internal handling of events ?
A. This happens in Events.pm (duh ;) as well as Scene.pm.
Basically, the function VRML::EventMachine::propagate_events (Events.pm)
is called at each event timestamp. This function first gets the
initial events from nodes and from mouse events, propagates the
event cascade, calls eventsProcessed and continues this until
no events remain.
Take note of the {RFields} member of a node -- this is a *tied*
hash (which looks like a normal perl hash (associative array) on top
but assignments to members and getting values of members translate
to function calls) tied with the class VRML::FieldHash (Scene.pm).
This takes care of IS and USE/DEF when getting/setting field values
as well as generating events when setting field values. The line
$node->{EventModel}->put_event($node, $k, $value);
in the function VRML::FieldHash::STORE causes the new event to be queued
to be executed at the next step of the current event cascade.
Nodes receive events by the function VRML::Node::receive_event (Scene.pm)
which calls the function for that particular node (defined in VRMLNodes.pm)
to receive that event.
---
Q. Where and how is JavaScript/VrmlScript/Java connected ?
A. Continuing from the previous question, VRMLNodes.pm is the place where
the different node types receive events. In there, the Script node
definition is the place to check. For Perl scripts, evaluation is
done directly, compiling the subs into the {ScriptScript} member of
the node, and for both JavaScript and Java, an object (the {J} member)
is used to deliver events.
The JavaScript interface is in the JS/ subdirectory and uses code
from Mozilla(R/TM/whatever). The file JS.xs in that file is generated
by genJS.pl (see later about code generation)
FreeWRL currently interprets 'vrmlscript:' to be exactly equivalent
to 'javascript:'.
The Java interface resides in VRMLJava.pm (Perl side)
and the java/ subdirectory (Java side). The interface is currently
through named pipes, with an ascii protocol for communication to make
it as easy as possible to use java. The file VRMLJava.pm spawns the
java interpreter and manages the protocol to use for communication.
---
Q. What is VRMLC.pm, genJS.pl etc?
A. FreeWRL uses extensive code generation to make programming convenient.
Instead of having to declare and use functions in many places and remember
everywhere what is happening at every other place, I only need to
declare/define the way a node is rendered / renders its children in one
place. Also, the actual C types used to represent fields may change later
if I interface with other C modules so it is good to be able to change
them later.
The way it works is simply that VRMLC.pm is a perl script (most
of the action happens at the end of the file) that prints the files
VRMLFunc.xs and VRMLFunc.pm as a result of running it. Some of the C code
is also in VRMLRend.pm. If the structure of these files is unclear, please
ask me.
---
Q. How do you handle Nodes for JavaScript and other languages?
A. There is a package VRML::Handles in Browser.pm which provides
simple string handles for nodes and ways to release them so that
the garbage collection mechanisms of the different languages can be
unified without requiring scripting languages to be in the same process
and handle pointers.
Because that package stores a reference to the object in question,
that object will not be freed before the handle is released.
( run in 2.496 seconds using v1.01-cache-2.11-cpan-2398b32b56e )