1 /*
2  Copyright (c) 2013 yvt
3 
4  This file is part of OpenSpades.
5 
6  OpenSpades is free software: you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  OpenSpades is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with OpenSpades.  If not, see <http://www.gnu.org/licenses/>.
18 
19  */
20 #include <memory>
21 #include <Core/VoxelModel.h>
22 #include "ScriptManager.h"
23 #include <Core/FileManager.h>
24 
25 namespace spades {
26 
27 
28 	class VoxelModelRegistrar: public ScriptObjectRegistrar {
Factory(int w,int h,int d)29 		static VoxelModel *Factory(int w, int h, int d){
30 			try{
31 				return new VoxelModel(w, h, d);
32 			}catch(const std::exception& ex){
33 				ScriptContextUtils().SetNativeException(ex);
34 				return nullptr;
35 			}
36 		}
LoadFactory(const std::string & fn)37 		static VoxelModel *LoadFactory(const std::string& fn){
38 			try{
39 				std::unique_ptr<spades::IStream> stream{FileManager::OpenForReading(fn.c_str())};
40 				VoxelModel *ret = VoxelModel::LoadKV6(stream.get());
41 				return ret;
42 			}catch(const std::exception& ex) {
43 				ScriptContextUtils().SetNativeException(ex);
44 				return nullptr;
45 			}
46 		}
GetSolidBits(int x,int y,VoxelModel * m)47 		static uint64_t GetSolidBits(int x, int y,
48 									 VoxelModel *m) {
49 			if(x < 0 || y < 0 || x >= m->GetWidth() || y >= m->GetHeight()) {
50 				asGetActiveContext()->SetException("Attempted to access a voxel outside the valid range.");
51 				return 0;
52 			}
53 			return m->GetSolidBitsAt(x, y);
54 		}
55 
GetColor(int x,int y,int z,VoxelModel * m)56 		static uint32_t GetColor(int x, int y, int z,
57 								 VoxelModel *m) {
58 			if(x < 0 || y < 0 || x >= m->GetWidth() || y >= m->GetHeight() ||
59 			   z < 0 || z >= m->GetDepth()) {
60 				asGetActiveContext()->SetException("Attempted to access a voxel outside the valid range.");
61 				return 0;
62 			}
63 			return m->GetColor(x, y, z);
64 		}
65 
IsSolid(int x,int y,int z,VoxelModel * m)66 		static bool IsSolid(int x, int y, int z,
67 							VoxelModel *m) {
68 			if(x < 0 || y < 0 || x >= m->GetWidth() || y >= m->GetHeight() ||
69 			   z < 0 || z >= m->GetDepth()) {
70 				asGetActiveContext()->SetException("Attempted to access a voxel outside the valid range.");
71 				return 0;
72 			}
73 			return m->IsSolid(x, y, z);
74 		}
SetAir(int x,int y,int z,VoxelModel * m)75 		static void SetAir(int x, int y, int z,
76 						   VoxelModel *m) {
77 			if(x < 0 || y < 0 || x >= m->GetWidth() || y >= m->GetHeight() ||
78 			   z < 0 || z >= m->GetDepth()) {
79 				asGetActiveContext()->SetException("Attempted to access a voxel outside the valid range.");
80 				return;
81 			}
82 			m->SetAir(x, y, z);
83 		}
SetSolid(int x,int y,int z,uint32_t col,VoxelModel * m)84 		static void SetSolid(int x, int y, int z, uint32_t col,
85 							 VoxelModel *m) {
86 			if(x < 0 || y < 0 || x >= m->GetWidth() || y >= m->GetHeight() ||
87 			   z < 0 || z >= m->GetDepth()) {
88 				asGetActiveContext()->SetException("Attempted to access a voxel outside the valid range.");
89 				return;
90 			}
91 			m->SetSolid(x, y, z, col);
92 		}
93 
94 
95 	public:
VoxelModelRegistrar()96 		VoxelModelRegistrar():
97 		ScriptObjectRegistrar("VoxelModel") {}
98 
Register(ScriptManager * manager,Phase phase)99 		virtual void Register(ScriptManager *manager, Phase phase) {
100 			asIScriptEngine *eng = manager->GetEngine();
101 			int r;
102 			eng->SetDefaultNamespace("spades");
103 			switch(phase){
104 				case PhaseObjectType:
105 					r = eng->RegisterObjectType("VoxelModel",
106 												0, asOBJ_REF);
107 					manager->CheckError(r);
108 					break;
109 				case PhaseObjectMember:
110 					r = eng->RegisterObjectBehaviour("VoxelModel",
111 													 asBEHAVE_ADDREF,
112 													 "void f()",
113 													 asMETHOD(VoxelModel, AddRef),
114 													 asCALL_THISCALL);
115 					manager->CheckError(r);
116 					r = eng->RegisterObjectBehaviour("VoxelModel",
117 													 asBEHAVE_RELEASE,
118 													 "void f()",
119 													 asMETHOD(VoxelModel, Release),
120 													 asCALL_THISCALL);
121 					manager->CheckError(r);
122 					r = eng->RegisterObjectBehaviour("VoxelModel",
123 													 asBEHAVE_FACTORY,
124 													 "VoxelModel @f(int, int, int)",
125 													 asFUNCTION(Factory),
126 													 asCALL_CDECL);
127 					manager->CheckError(r);
128 					r = eng->RegisterObjectBehaviour("VoxelModel",
129 													 asBEHAVE_FACTORY,
130 													 "VoxelModel @f(const string& in)",
131 													 asFUNCTION(LoadFactory),
132 													 asCALL_CDECL);
133 					manager->CheckError(r);
134 					r = eng->RegisterObjectMethod("VoxelModel",
135 												  "uint GetSolidBits(int, int)",
136 												  asFUNCTION(GetSolidBits),
137 												  asCALL_CDECL_OBJLAST);
138 					manager->CheckError(r);
139 					r = eng->RegisterObjectMethod("VoxelModel",
140 												  "uint GetColor(int, int, int)",
141 												  asFUNCTION(GetColor),
142 												  asCALL_CDECL_OBJLAST);
143 					manager->CheckError(r);
144 					r = eng->RegisterObjectMethod("VoxelModel",
145 												  "bool IsSolid(int, int, int)",
146 												  asFUNCTION(IsSolid),
147 												  asCALL_CDECL_OBJLAST);
148 					manager->CheckError(r);
149 					r = eng->RegisterObjectMethod("VoxelModel",
150 												  "void SetAir(int, int, int)",
151 												  asFUNCTION(SetAir),
152 												  asCALL_CDECL_OBJLAST);
153 					manager->CheckError(r);
154 					r = eng->RegisterObjectMethod("VoxelModel",
155 												  "void SetSolid(int, int, int, uint)",
156 												  asFUNCTION(SetSolid),
157 												  asCALL_CDECL_OBJLAST);
158 					manager->CheckError(r);
159 					r = eng->RegisterObjectMethod("VoxelModel",
160 												  "int get_Width()",
161 												  asMETHOD(VoxelModel, GetWidth),
162 												  asCALL_THISCALL);
163 					manager->CheckError(r);
164 					r = eng->RegisterObjectMethod("VoxelModel",
165 												  "int get_Height()",
166 												  asMETHOD(VoxelModel, GetHeight),
167 												  asCALL_THISCALL);
168 					manager->CheckError(r);
169 					r = eng->RegisterObjectMethod("VoxelModel",
170 												  "int get_Depth()",
171 												  asMETHOD(VoxelModel, GetDepth),
172 												  asCALL_THISCALL);
173 					manager->CheckError(r);
174 					break;
175 				default:
176 					break;
177 			}
178 		}
179 	};
180 
181 	static VoxelModelRegistrar registrar;
182 
183 }
184