supertux is now searching for a default.nut file in the same dir as the level and...
authorMatthias Braun <matze@braunis.de>
Sat, 11 Jun 2005 21:10:19 +0000 (21:10 +0000)
committerMatthias Braun <matze@braunis.de>
Sat, 11 Jun 2005 21:10:19 +0000 (21:10 +0000)
SVN-Revision: 2589

12 files changed:
data/levels/test/default.nut [new file with mode: 0644]
src/scripting/Jamfile
src/scripting/script_interpreter.cpp
src/scripting/script_interpreter.h
src/scripting/sound.h
src/scripting/wrapper.interface.h
src/sector.cpp
tools/miniswig/create_docu.cpp [new file with mode: 0644]
tools/miniswig/create_docu.h [new file with mode: 0644]
tools/miniswig/lexer.ll
tools/miniswig/main.cpp
tools/miniswig/parser.yy

diff --git a/data/levels/test/default.nut b/data/levels/test/default.nut
new file mode 100644 (file)
index 0000000..874b024
--- /dev/null
@@ -0,0 +1,7 @@
+/* Default functions for the whole levelset */
+
+function wait(time) {
+    set_wakeup_time(time);
+    suspend();
+}
+
index 27116aa..d4ab29d 100644 (file)
@@ -29,7 +29,7 @@ if $(MINISWIG)
 
     actions MiniSwig bind headerfile
     {
-        $(CPP) -x c $(CPPFLAGS) $(>) -o $(LOCATE_OBJECTS)/miniswig.tmp
+        $(CPP) -x c -CC $(CPPFLAGS) $(>) -o $(LOCATE_OBJECTS)/miniswig.tmp
         ./miniswig --output-cpp $(<) --input $(LOCATE_OBJECTS)/miniswig.tmp --output-hpp $(headerfile) --module $(modulename) $(FLAGS)
 #       rm -f $(LOCATE_OBJECTS)/miniswig.tmp
     }
index 25c89d1..b027fbf 100644 (file)
@@ -119,8 +119,11 @@ static SQInteger squirrel_read_char(SQUserPointer file)
 }
 
 void
-ScriptInterpreter::run_script(std::istream& in, const std::string& sourcename)
+ScriptInterpreter::run_script(std::istream& in, const std::string& sourcename,
+        bool remove_when_terminated)
 {
+  printf("Stackbefore:\n");
+  print_squirrel_stack(v);
   if(sq_compile(v, squirrel_read_char, &in, sourcename.c_str(), true) < 0)
     throw SquirrelError(v, "Couldn't parse script");
  
@@ -130,9 +133,15 @@ ScriptInterpreter::run_script(std::istream& in, const std::string& sourcename)
     throw SquirrelError(v, "Couldn't start script");
   _current = 0;
   if(sq_getvmstate(v) != SQ_VMSTATE_SUSPENDED) {
-    printf("script ended...\n");
-    remove_me();
-  }  
+    if(remove_when_terminated) {
+      remove_me();
+    }
+    printf("ended.\n");
+    // remove closure from stack
+    sq_pop(v, 1);
+  }
+  printf("After:\n");
+  print_squirrel_stack(v);
 }
 
 void
@@ -209,7 +218,7 @@ ScriptInterpreter::add_script_object(Sector* sector, const std::string& name,
     try {
       std::string filename = workdir + "/default.nut";
       IFileStream in(filename);
-      interpreter->run_script(in, filename);
+      interpreter->run_script(in, filename, false);
     } catch(std::exception& e) {
       // nothing
     }
index d8db300..ae318be 100644 (file)
@@ -21,7 +21,8 @@ public:
   void draw(DrawingContext& );
   void update(float );
 
-  void run_script(std::istream& in, const std::string& sourcename = "");
+  void run_script(std::istream& in, const std::string& sourcename = "",
+          bool remove_when_terminated = true);
   
   void expose_object(void* object, const std::string& name,
                      const std::string& type);
index 3486719..10d56da 100644 (file)
@@ -4,6 +4,9 @@
 namespace Scripting
 {
 
+/**
+ * This class allows manipulating the sound output of the game
+ */
 class Sound
 {
 public:
index e9645ec..203612f 100644 (file)
@@ -1,4 +1,4 @@
-/** This file is processes by miniswig to produce the scripting API */
+/* This file is processes by miniswig to produce the scripting API */
 #include "display_effect.h"
 #include "camera.h"
 #include "level.h"
index cb7a2d9..81f3591 100644 (file)
@@ -76,7 +76,11 @@ Sector::Sector()
   player = new Player(&player_status);
   add_object(player);
 
+#ifdef USE_GRID
   grid = new CollisionGrid(32000, 32000);
+#else
+  grid = 0;
+#endif
 }
 
 Sector::~Sector()
@@ -497,10 +501,12 @@ Sector::update_game_objects()
           std::remove(bullets.begin(), bullets.end(), bullet),
           bullets.end());
     }
+#ifdef USE_GRID
     MovingObject* movingobject = dynamic_cast<MovingObject*> (object);
     if(movingobject) {
       grid->remove_object(movingobject);
     }
+#endif
     delete *i;
     i = gameobjects.erase(i);
   }
@@ -515,9 +521,11 @@ Sector::update_game_objects()
     if(bullet)
       bullets.push_back(bullet);
 
+#ifdef USE_GRID
     MovingObject* movingobject = dynamic_cast<MovingObject*> (object);
     if(movingobject)
       grid->add_object(movingobject);
+#endif
     
     TileMap* tilemap = dynamic_cast<TileMap*> (object);
     if(tilemap && tilemap->is_solid()) {
@@ -570,7 +578,7 @@ Sector::draw(DrawingContext& context)
   context.pop_transform();
 }
 
-static const float DELTA = .001;
+static const float DELTA = .0001;
 
 void
 Sector::collision_tilemap(MovingObject* object, int depth)
diff --git a/tools/miniswig/create_docu.cpp b/tools/miniswig/create_docu.cpp
new file mode 100644 (file)
index 0000000..b1e1722
--- /dev/null
@@ -0,0 +1,111 @@
+#include "tree.h"
+#include <iostream>
+#include <sstream>
+#include <stdexcept>
+#include "create_docu.h"
+#include "globals.h"
+
+void
+DocuCreator::create_docu(Namespace* ns)
+{
+    std::string fromfile = original_file != "" ? original_file : inputfile;
+    
+    writer.openTag("documentation");
+    writer.openTag("namespace");
+    writer.writeAttribute("name", ns->name);
+
+    for(std::vector<AtomicType*>::iterator i = ns->types.begin();
+            i != ns->types.end(); ++i) {
+        AtomicType* type = *i;
+        Class* _class = dynamic_cast<Class*> (type);
+        if(_class != 0)
+            create_class_docu(_class);
+    }
+    for(std::vector<Function*>::iterator i = ns->functions.begin();
+            i != ns->functions.end(); ++i) {
+        create_function_docu(0, *i);
+    }
+
+    writer.closeTag("namespace");
+    writer.closeTag("documentation");
+}
+
+void
+DocuCreator::create_class_docu(Class* _class)
+{
+    writer.openTag("class");
+    writer.writeAttribute("name", _class->name);
+
+    if(_class->docu_comment != "") {
+        writer.writeTag("documentation");
+        writer.write(_class->docu_comment);
+    }
+    
+    for(std::vector<ClassMember*>::iterator i = _class->members.begin();
+            i != _class->members.end(); ++i) {
+        ClassMember* member = *i;
+        if(member->visibility != ClassMember::PUBLIC)
+            continue;
+        Function* function = dynamic_cast<Function*> (member);
+        if(!function)
+            continue;
+        if(function->type != Function::FUNCTION)
+            continue;
+        create_function_docu(_class, function);
+    }
+
+    writer.closeTag("class");
+}
+
+void
+DocuCreator::create_function_docu(Class* _class, Function* function)
+{
+    writer.openTag("function");
+    
+    writer.writeAttribute("return_type",
+            get_type(function->return_type));
+    writer.writeAttribute("name", function->name);
+
+    if(function->docu_comment != "") {
+        writer.writeTag("documentation");
+        writer.write(function->docu_comment);
+    }
+  
+    for(std::vector<Parameter>::iterator p = function->parameters.begin();
+            p != function->parameters.end(); ++p) {
+        if(p == function->parameters.begin() 
+                && p->type.atomic_type == HSQUIRRELVMType::instance())
+            continue;
+
+        writer.writeTag("param");
+        writer.writeAttribute("type", get_type(p->type));
+        writer.writeAttribute("name", p->name);
+    }
+
+    writer.closeTag("function");
+}
+
+std::string
+DocuCreator::get_type(const Type& type)
+{
+    if(type.ref > 0 && type.atomic_type != StringType::instance())
+        throw std::runtime_error("References not handled yet");
+    if(type.pointer > 0)
+        throw std::runtime_error("Pointers not handled yet");
+    if(type.atomic_type == &BasicType::VOID) {
+        return "void";
+    } else if(type.atomic_type == &BasicType::INT) {
+        return "int";
+    } else if(type.atomic_type == &BasicType::FLOAT) {
+        return "float";
+    } else if(type.atomic_type == &BasicType::BOOL) {
+        return "bool";
+    } else if(type.atomic_type == StringType::instance()) {
+        return "string";
+    } 
+    
+    std::ostringstream msg;
+    msg << "Type '" << type.atomic_type->name << "' not supported yet.";
+    throw std::runtime_error(msg.str());
+}
+
diff --git a/tools/miniswig/create_docu.h b/tools/miniswig/create_docu.h
new file mode 100644 (file)
index 0000000..1f679b5
--- /dev/null
@@ -0,0 +1,26 @@
+#ifndef __CREATE_DOCU_H__
+#define __CREATE_DOCU_H__
+
+#include "tree.h"
+#include "xmlwriter.h"
+
+class DocuCreator
+{
+public:
+    const char* ind;
+    std::ostream& out;
+    XmlWriter writer;
+
+    DocuCreator(std::ostream& _out = std::cout)
+        : out(_out), writer(out)
+    {
+        ind = "  ";
+    }
+
+    void create_docu(Namespace* ns);
+    void create_class_docu(Class* _class);
+    void create_function_docu(Class* _class, Function* function);
+    std::string get_type(const Type& type);
+};
+
+#endif
index 8a2e9a6..21b13f4 100644 (file)
@@ -18,6 +18,7 @@
 std::string last_docucomment;
 std::string original_file;
 std::string current_file;
+std::string comm;
 int offset_lnum;
 
 int getCurrentLine()
@@ -31,6 +32,7 @@ int getCurrentLine()
 %option yylineno
 /* %option never-interactive */
 
+%x comment
 %%
 
 #[ \t]+[0-9]+[ \t]+.*                         {
@@ -47,9 +49,24 @@ int getCurrentLine()
 }
 #.*                                     /* ignore preprocessor directives */
 [[:space:]]+                            /* eat spaces */
-\/\*.*\*\/                              {
-    if(yytext[2] == '*' && yytext[3] != '/') { // It's a docu comment...
-        last_docucomment = std::string(yytext+3, strlen(yytext)-5);
+"/*"                                    { BEGIN(comment); comm = ""; }
+<comment>[^*\n]*                        { comm += yytext; }
+<comment>"*"+[^*/]*                     { comm += yytext; }
+<comment>"*/"                    {
+    BEGIN(INITIAL);
+    if(comm[0] == '*') { // It's a docu comment...
+        last_docucomment = "";
+        bool linestart = true;
+        for(size_t i = 1; i < comm.size(); ++i) {
+            if(linestart && (comm[i] == '*' || isspace(comm[i]))) {
+                continue;
+            } else if(comm[i] == '\n') {
+                linestart = true;
+            } else {
+                linestart = false;
+            }
+            last_docucomment += comm[i];
+        }
     }
 }
 \/\/[^\n]*\n                            {
index 2a5b1ed..0140a85 100644 (file)
@@ -5,6 +5,7 @@
 #include "tree.h"
 #include "globals.h"
 #include "create_wrapper.h"
+#include "create_docu.h"
 
 extern int yyparse();
 extern int yylex();
@@ -25,6 +26,7 @@ int main(int argc, char** argv)
 {
     std::string outputcpp;
     std::string outputhpp;
+    std::string output_doc;
     for(int i = 0; i < argc; ++i) {
         if(strcmp(argv[i], "--module") == 0) {
             if(i+1 >= argc) {
@@ -61,6 +63,13 @@ int main(int argc, char** argv)
                 return 1;
             }
             selected_namespace = argv[++i];
+        } else if(strcmp(argv[i], "--output-doc") == 0) {
+          if(i+1 >= argc) {
+            std::cerr << "Need to specify document xml file.\n";
+            usage();
+            return 1;
+          }
+          output_doc = argv[++i];
         } else if(argv[i][0] == '-') {
             std::cerr << "Unknown option '" << argv[i] << "'.\n";
             usage();
@@ -68,7 +77,8 @@ int main(int argc, char** argv)
         } else {
         }
     }
-    if(inputfile == "" || outputcpp == "" || outputhpp == "") {
+    if( inputfile == "" || (
+            (outputcpp == "" || outputhpp == "") && output_doc == "")) {
         std::cerr << "Not all options specified.\n";
         usage();
         return 1;
@@ -90,24 +100,39 @@ int main(int argc, char** argv)
         
         yyparse();
 
-        std::ofstream cppout(outputcpp.c_str());
-        if(!cppout.good()) {
-            std::cerr << "Couldn't open file '" << outputcpp << "' for writing.\n";
-            return 1;
-        }
-        std::ofstream hppout(outputhpp.c_str());
-        if(!hppout.good()) {
-            std::cerr << "Couldn't open file '" << outputhpp << "' for writing.\n";
-            return 1;
-        }
-
         Namespace* ns = unit;
         if(selected_namespace != "") {
             ns = ns->findNamespace(selected_namespace);
+        }                                                      
+
+        if(outputcpp != "") {
+            std::ofstream cppout(outputcpp.c_str());
+            if(!cppout.good()) {
+                std::cerr << "Couldn't open file '" 
+                          << outputcpp << "' for writing.\n";
+                return 1;
+            }
+            std::ofstream hppout(outputhpp.c_str());
+            if(!hppout.good()) {
+                std::cerr << "Couldn't open file '" << outputhpp 
+                          << "' for writing.\n";
+                return 1;
+            }
+
+            WrapperCreator creator(cppout, hppout);
+            creator.create_wrapper(ns);
         }
 
-        WrapperCreator creator(cppout, hppout);
-        creator.create_wrapper(ns);
+        if(output_doc != "") {
+            std::ofstream dout(output_doc.c_str());
+            if(!dout.good()) {
+                std::cerr << "Couldn't open file '" 
+                    << dout << "' for writing.\n";
+                return 1;
+            }
+            DocuCreator creator(dout);
+            creator.create_docu(ns);
+        }
     } catch(std::exception& e) {
         std::cerr << e.what() << "\n";
         return 1;
index 3e8a4b1..4875401 100644 (file)
@@ -271,7 +271,7 @@ parameter:
             Parameter parameter;
             parameter.type = *($1);
             delete $1;
-            parameter.name = *($2);
+            parameter.name = $2;
             free($2);
             currentFunction->parameters.push_back(parameter);
         }