naev 0.11.5
nlua_news.c
Go to the documentation of this file.
1/*
2 * See Licensing and Copyright notice in naev.h
3 */
10#include <lauxlib.h>
11
12#include "naev.h"
15#include "nlua_news.h"
16
17#include "array.h"
18#include "land.h"
19#include "nlua_time.h"
20#include "nluadef.h"
21#include "nstring.h"
22#include "ntime.h"
23
24extern news_t *news_list;
25extern int land_loaded;
26
27news_t* luaL_validnews( lua_State *L, int ind );
28int lua_isnews( lua_State *L, int ind );
29LuaNews_t* lua_pushnews( lua_State *L, LuaNews_t news );
30
31static int newsL_add( lua_State *L );
32static int newsL_rm( lua_State *L );
33static int newsL_get( lua_State *L );
34static int newsL_eq( lua_State *L );
35static int newsL_title( lua_State *L );
36static int newsL_desc( lua_State *L );
37static int newsL_faction( lua_State *L );
38static int newsL_date( lua_State *L );
39static int newsL_bind( lua_State *L );
40static const luaL_Reg news_methods[] = {
41 {"add", newsL_add},
42 {"rm", newsL_rm},
43 {"get", newsL_get},
44 {"title", newsL_title},
45 {"desc", newsL_desc},
46 {"faction", newsL_faction},
47 {"date", newsL_date},
48 {"bind", newsL_bind},
49 {"__eq", newsL_eq},
50 {0, 0}
51};
59int nlua_loadNews( nlua_env env )
60{
61 nlua_register(env, NEWS_METATABLE, news_methods, 1);
62 return 0; /* No error */
63}
64
72LuaNews_t* lua_tonews( lua_State *L, int ind )
73{
74 return (LuaNews_t*) lua_touserdata(L,ind);
75}
83LuaNews_t* luaL_checknews( lua_State *L, int ind )
84{
85 if (lua_isnews(L,ind))
86 return lua_tonews(L,ind);
87 luaL_typerror(L, ind, NEWS_METATABLE);
88 return NULL;
89}
97LuaNews_t* lua_pushnews( lua_State *L, LuaNews_t news )
98{
99 LuaNews_t *la = (LuaNews_t*) lua_newuserdata(L, sizeof(LuaNews_t));
100 *la = news;
101 luaL_getmetatable(L, NEWS_METATABLE);
102 lua_setmetatable(L, -2);
103 return la;
104}
112int lua_isnews( lua_State *L, int ind )
113{
114 int ret;
115
116 if (lua_getmetatable(L,ind)==0)
117 return 0;
118 lua_getfield(L, LUA_REGISTRYINDEX, NEWS_METATABLE);
119
120 ret = 0;
121 if (lua_rawequal(L, -1, -2)) /* does it have the correct mt? */
122 ret = 1;
123
124 lua_pop(L, 2); /* remove both metatables */
125 return ret;
126}
127
135news_t* luaL_validnews( lua_State *L, int ind )
136{
137 const LuaNews_t *ln = luaL_checknews( L, ind );
138 news_t *n = news_get( *ln );
139 if (n==NULL)
140 NLUA_ERROR(L, _("Article is invalid."));
141 return n;
142}
143
167int newsL_add( lua_State *L )
168{
169 const char *title, *body, *faction;
170 ntime_t date, date_to_rm;
171 int priority;
172
173 title = NULL;
174 body = NULL;
175 faction = NULL;
176
177 date = ntime_get();
178 date_to_rm = NEWS_FOREVER;
179
180 /* If a table is passed in. ugly hack */
181 if (lua_istable(L, 1)) {
182 lua_pushnil(L);
183
184 /* traverse table */
185 while (lua_next(L, -2)) {
186 /* traverse sub table */
187 if (lua_istable(L, -1)) {
188 faction = title = body = NULL;
189 priority = 5;
190 date = ntime_get();
191 date_to_rm = NEWS_FOREVER;
192
193 lua_getfield( L, -1, "faction" );
194 if (!lua_isnil(L,-1))
195 faction = luaL_checkstring(L,-1);
196 lua_pop(L,1);
197
198 lua_getfield( L, -1, "head" );
199 if (!lua_isnil(L,-1))
200 title = luaL_checkstring(L,-1);
201 lua_pop(L,1);
202
203 lua_getfield( L, -1, "body" );
204 if (!lua_isnil(L,-1))
205 body = luaL_checkstring(L,-1);
206 lua_pop(L,1);
207
208 lua_getfield( L, -1, "date" );
209 if (!lua_isnil(L,-1)) {
210 if (lua_isnumber(L,-1))
211 date = lua_tonumber(L,-1);
212 else
213 date = luaL_validtime(L,-1);
214 }
215 lua_pop(L,1);
216
217 lua_getfield( L, -1, "date_to_rm" );
218 if (!lua_isnil(L,-1)) {
219 if (lua_isnumber(L,-1))
220 date_to_rm = lua_tonumber(L,-1);
221 else
222 date_to_rm = luaL_validtime(L,-1);
223 }
224 lua_pop(L,1);
225
226 lua_getfield( L, -1, "priority" );
227 if (!lua_isnil(L,-1))
228 priority = luaL_checkinteger(L,-1);
229 lua_pop(L,1);
230
231 if (title && body && faction)
232 news_add( title, body, faction, NULL, date, date_to_rm, priority );
233 else
234 WARN(_("Bad arguments"));
235 }
236 lua_pop(L, 1);
237 }
238 lua_pop(L, 1);
239
240 /* If we're landed, we should regenerate the news buffer. */
241 if (landed) {
243 if (land_loaded)
244 bar_regen();
245 }
246
247 return 0;
248 }
249
250 if (!(lua_isstring(L, 1) && lua_isstring(L, 2) && lua_isstring(L, 3))) {
251 WARN(_("\nBad arguments, use "
252 "addArticle(\"Faction\",\"Title\",\"Content\",[date,[date_to_rm]])"));
253 return 0;
254 }
255
256 faction = luaL_checkstring(L, 1);
257 title = luaL_checkstring(L, 2);
258 body = luaL_checkstring(L, 3);
259 priority = luaL_optinteger(L, 6, 5);
260
261 /* Get date and date to remove, or leave at defaults. */
262 if (!lua_isnoneornil(L,4)) {
263 if (lua_istime(L, 4))
264 date_to_rm = luaL_validtime(L, 4);
265 else
266 date_to_rm = luaL_checklong(L, 4);
267 }
268 if (!lua_isnoneornil(L,5)) {
269 if (lua_istime(L, 5))
270 date = luaL_validtime(L, 5);
271 else
272 date = luaL_checklong(L, 5);
273 }
274
275 if (title && body && faction) {
276 LuaNews_t n_article = news_add( title, body, faction, NULL, date, date_to_rm, priority );
277 lua_pushnews( L, n_article );
278 }
279 else
280 return NLUA_ERROR(L,_("Bad arguments"));
281
282 /* If we're landed, we should regenerate the news buffer. */
283 if (landed) {
285 if (land_loaded)
286 bar_regen();
287 }
288
289 return 1;
290}
291
297int newsL_rm( lua_State *L )
298{
299 if (lua_istable(L, 1)) {
300 lua_pushnil(L);
301 while (lua_next(L, -2)) {
302 const LuaNews_t *Larticle = luaL_checknews(L, -1);
303 news_rm( *Larticle );
304 lua_pop(L, 1);
305 }
306 }
307 else {
308 const LuaNews_t *Larticle = luaL_checknews(L, 1);
309 news_rm( *Larticle );
310 }
311
312 /* If we're landed, we should regenerate the news buffer. */
313 if (landed) {
315 if (land_loaded)
316 bar_regen();
317 }
318
319 return 1;
320}
321
341int newsL_get( lua_State *L )
342{
343 ntime_t date = -1;
344 const char *characteristic = NULL;
345 int print_all = 0;
346 int narticle = 1;
347
348 if (lua_isnoneornil(L, 1)) /* Case no argument */
349 print_all = 1;
350 else if (lua_isnumber(L, 1))
351 date = (ntime_t)lua_tonumber(L, 1);
352 else if (lua_isstring(L, 1))
353 characteristic = lua_tostring(L, 1);
354 else
355 NLUA_INVALID_PARAMETER(L,1); /* Bad Parameter */
356
357 /* Now put all the matching articles in a table. */
358 lua_newtable(L);
359 for (int i=0; i<array_size(news_list); i++) {
360 const news_t *n = &news_list[i];
361
362 if ((n->title == NULL) || (n->desc == NULL) || (n->faction == NULL))
363 continue;
364
365 if (print_all || date == n->date
366 || (characteristic
367 && ((strcmp( n->title, characteristic ) == 0)
368 || (strcmp( n->desc, characteristic ) == 0)
369 || (strcmp( n->faction, characteristic ) == 0)
370 || (n->tag != NULL && strcmp( n->tag, characteristic ) == 0 )))) {
371 lua_pushnews(L, n->id); /* value */
372 lua_rawseti(L, -2, narticle++);
373 }
374 }
375
376 return 1;
377}
378
389int newsL_eq( lua_State *L )
390{
391 const LuaNews_t *a1, *a2;
392 a1 = luaL_checknews(L, 1);
393 a2 = luaL_checknews(L, 2);
394 lua_pushboolean(L, *a1 == *a2);
395 return 1;
396}
397
404int newsL_title( lua_State *L )
405{
406 news_t *article_ptr = luaL_validnews(L, 1);
407 lua_pushstring(L, article_ptr->title);
408 return 1;
409}
410
417int newsL_desc( lua_State *L )
418{
419 news_t *article_ptr = luaL_validnews(L, 1);
420 lua_pushstring(L, article_ptr->desc);
421 return 1;
422}
423
430int newsL_faction( lua_State *L )
431{
432 news_t *article_ptr = luaL_validnews(L, 1);
433 lua_pushstring(L, article_ptr->faction);
434 return 1;
435}
436
443int newsL_date( lua_State *L )
444{
445 news_t *article_ptr = luaL_validnews(L, 1);
446 lua_pushinteger(L, (lua_Integer)article_ptr->date);
447 return 1;
448}
449
456int newsL_bind( lua_State *L )
457{
458 news_t *article_ptr;
459 LuaNews_t *a = NULL;
460
461 if (lua_istable(L, 1)) {
462 const char *tag = luaL_checkstring(L, 2);
463 lua_pop(L, 1);
464 lua_pushnil(L);
465
466 /* traverse table */
467 while (lua_next(L, -2)) {
468 if (!(a = luaL_checknews(L, -1))) {
469 WARN(_("Bad argument to news.date(), must be article or a table of articles"));
470 return 0;
471 }
472 article_ptr = news_get( *a );
473 if (article_ptr == NULL) {
474 WARN(_("Article not valid"));
475 return 0;
476 }
477 article_ptr->tag = strdup(tag);
478 lua_pop(L, 1);
479 }
480 }
481 else {
482 const char *tag;
483 if (!(a = luaL_checknews(L, 1))) {
484 WARN(_("Bad argument to news.date(), must be article or a table of articles"));
485 return 0;
486 }
487 article_ptr = news_get(*a);
488 if (article_ptr == NULL) {
489 WARN(_("Article not valid"));
490 return 0;
491 }
492
493 tag = luaL_checkstring(L, 2);
494 article_ptr->tag = strdup( tag );
495 }
496 return 1;
497}
Provides macros to work with dynamic arrays.
static ALWAYS_INLINE int array_size(const void *array)
Returns number of elements in the array.
Definition array.h:168
void bar_regen(void)
Regenerates the bar list.
Definition land.c:382
int landed
Definition land.c:75
Spob * land_spob
Definition land.c:83
Header file with generic functions and naev-specifics.
int news_add(const char *title, const char *content, const char *faction, const char *tag, ntime_t date, ntime_t date_to_rm, int priority)
makes a new article and puts it into the list
Definition news.c:100
news_t * news_get(int id)
gets the article with id ID, else NULL
Definition news.c:176
int * generate_news(int faction)
Generates news from newslist from specific faction AND Generic news.
Definition news.c:209
news_t * news_list
Definition news.c:39
static int newsL_bind(lua_State *L)
Tags a news article or a table of articles with a string. Lua function parameter: Article a Article t...
Definition nlua_news.c:456
static int newsL_eq(lua_State *L)
Check news articles for equality.
Definition nlua_news.c:389
int lua_isnews(lua_State *L, int ind)
Checks to see if ind is a news.
Definition nlua_news.c:112
int land_loaded
Definition land.c:76
static const luaL_Reg news_methods[]
Definition nlua_news.c:40
int nlua_loadNews(nlua_env env)
Loads the news library.
Definition nlua_news.c:59
static int newsL_rm(lua_State *L)
Frees a news article or a table of articles. Lua function parameter: News n News article to free.
Definition nlua_news.c:297
static int newsL_get(lua_State *L)
Gets all matching news articles in a table.
Definition nlua_news.c:341
static int newsL_desc(lua_State *L)
Gets the news article description. Lua function parameter: Article a article to get the desc of Lua r...
Definition nlua_news.c:417
LuaNews_t * luaL_checknews(lua_State *L, int ind)
Gets news at index or raises error if there is no news at index.
Definition nlua_news.c:83
static int newsL_add(lua_State *L)
Lua bindings to interact with the news.
Definition nlua_news.c:167
news_t * luaL_validnews(lua_State *L, int ind)
Makes sure the news is valid or raises a Lua error.
Definition nlua_news.c:135
LuaNews_t * lua_pushnews(lua_State *L, LuaNews_t news)
Pushes a news on the stack.
Definition nlua_news.c:97
LuaNews_t * lua_tonews(lua_State *L, int ind)
Gets news at index.
Definition nlua_news.c:72
static int newsL_title(lua_State *L)
Gets the news article title. Lua function parameter: Article a article to get the title of Lua return...
Definition nlua_news.c:404
static int newsL_date(lua_State *L)
Gets the news article date. Lua function parameter: Article a article to get the date of Lua return p...
Definition nlua_news.c:443
static int newsL_faction(lua_State *L)
Gets the news article faction. Lua function parameter: Article a article to get the faction of Lua re...
Definition nlua_news.c:430
int lua_istime(lua_State *L, int ind)
Checks to see if ind is a time.
Definition nlua_time.c:141
ntime_t luaL_validtime(lua_State *L, int ind)
Gets a time directly.
Definition nlua_time.c:115
ntime_t ntime_get(void)
Gets the current time.
Definition ntime.c:108
int faction
Definition space.h:67
SpobPresence presence
Definition space.h:104
Represents a news article.
Definition news.h:16
char * faction
Definition news.h:22
char * title
Definition news.h:20
ntime_t date
Definition news.h:25
char * tag
Definition news.h:23
char * desc
Definition news.h:21