1 // -*- Mode: C++; tab-width:2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 // vi:tw=80:et:ts=2:sts=2
3 //
4 // -----------------------------------------------------------------------
5 //
6 // This file is part of RLVM, a RealLive virtual machine clone.
7 //
8 // -----------------------------------------------------------------------
9 //
10 // Copyright (C) 2014 Elliot Glaysher
11 //
12 // This program is free software; you can redistribute it and/or modify
13 // it under the terms of the GNU General Public License as published by
14 // the Free Software Foundation; either version 3 of the License, or
15 // (at your option) any later version.
16 //
17 // This program is distributed in the hope that it will be useful,
18 // but WITHOUT ANY WARRANTY; without even the implied warranty of
19 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20 // GNU General Public License for more details.
21 //
22 // You should have received a copy of the GNU General Public License
23 // along with this program; if not, write to the Free Software
24 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
25 //
26 // -----------------------------------------------------------------------
27 
28 #ifndef SRC_MODULES_OBJECT_MODULE_H_
29 #define SRC_MODULES_OBJECT_MODULE_H_
30 
31 #include <string>
32 
33 #include "machine/rlmodule.h"
34 #include "systems/base/graphics_object.h"
35 
36 class RLModule;
37 class RLOperation;
38 
39 class ObjectModule {
40  public:
41   typedef int (GraphicsObject::*NormalGetter)() const;
42   typedef void (GraphicsObject::*NormalSetter)(const int);
43 
44   typedef int (GraphicsObject::*RepnoGetter)(const int) const;
45   typedef void (GraphicsObject::*RepnoSetter)(const int, const int);
46 
47   ObjectModule(const std::string& prefix, RLModule* module);
48   virtual ~ObjectModule();
49 
50   void AddSingleObjectCommands(int base_id, const std::string& name,
51                                NormalGetter getter, NormalSetter setter);
52   void AddDoubleObjectCommands(int base_id,
53                                const std::string& name,
54                                NormalGetter getter_one,
55                                NormalSetter setter_one,
56                                NormalGetter getter_two,
57                                NormalSetter setter_two);
58   void AddRepnoObjectCommands(int base_id,
59                               const std::string& name,
60                               RepnoGetter getter,
61                               RepnoSetter setter);
62 
63   template <typename first, typename second>
64   void AddCustomRepno(int base_id,
65                       const std::string& name);
66 
67  private:
68   void AddCheck(const std::string& eve_name,
69                 const std::string& base_eve_name,
70                 int base_id);
71 
72   void AddNormalFinale(const std::string& eve_name,
73                        const std::string& base_eve_name,
74                        int base_id);
75 
76   // The Repno commands need to have their own versions of Wait and End because
77   // they the repno is part of the object identity and is passed in, changing
78   // the arity.
79   void AddRepnoFinale(const std::string& eve_name,
80                       const std::string& base_eve_name,
81                       int base_id);
82 
83   std::string prefix_;
84   RLModule* module_;
85 };
86 
87 template <typename first, typename second>
AddCustomRepno(int base_id,const std::string & name)88 void ObjectModule::AddCustomRepno(int base_id,
89                                   const std::string& name) {
90   std::string base_name = prefix_ + name;
91   module_->AddOpcode(1000 + base_id, 0, base_name, new first);
92 
93   std::string eve_name = prefix_ + "Eve" + name;
94   std::string base_eve_name = "objEve" + name;
95   module_->AddOpcode(2000 + base_id, 0, eve_name, new first);
96   module_->AddOpcode(2000 + base_id, 1, eve_name, new second);
97 
98   AddCheck(eve_name, base_eve_name, base_id);
99   AddRepnoFinale(eve_name, base_eve_name, base_id);
100 }
101 
102 
103 #endif  // SRC_MODULES_OBJECT_MODULE_H_
104