naev 0.12.6
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>
12
13#include "nlua_news.h"
14
15#include "array.h"
16#include "land.h"
17#include "news.h"
18#include "nlua_time.h"
19#include "nluadef.h"
20#include "ntime.h"
21
22extern news_t *news_list;
23extern int land_loaded;
24
25static news_t *luaL_validnews( lua_State *L, int ind );
26static int lua_isnews( lua_State *L, int ind );
27static LuaNews_t *lua_pushnews( lua_State *L, LuaNews_t news );
28
29static int newsL_add( lua_State *L );
30static int newsL_rm( lua_State *L );
31static int newsL_get( lua_State *L );
32static int newsL_eq( lua_State *L );
33static int newsL_title( lua_State *L );
34static int newsL_desc( lua_State *L );
35static int newsL_faction( lua_State *L );
36static int newsL_date( lua_State *L );
37static int newsL_bind( lua_State *L );
38
39static const luaL_Reg news_methods[] = {
40 { "add", newsL_add }, { "rm", newsL_rm },
41 { "get", newsL_get }, { "title", newsL_title },
42 { "desc", newsL_desc }, { "faction", newsL_faction },
43 { "date", newsL_date }, { "bind", newsL_bind },
44 { "__eq", newsL_eq }, { 0, 0 } };
45
52int nlua_loadNews( nlua_env env )
53{
54 nlua_register( env, NEWS_METATABLE, news_methods, 1 );
55 return 0; /* No error */
56}
57
65LuaNews_t *lua_tonews( lua_State *L, int ind )
66{
67 return (LuaNews_t *)lua_touserdata( L, ind );
68}
69
76LuaNews_t *luaL_checknews( lua_State *L, int ind )
77{
78 if ( lua_isnews( L, ind ) )
79 return lua_tonews( L, ind );
80 luaL_typerror( L, ind, NEWS_METATABLE );
81 return NULL;
82}
83
90static LuaNews_t *lua_pushnews( lua_State *L, LuaNews_t news )
91{
92 LuaNews_t *la = (LuaNews_t *)lua_newuserdata( L, sizeof( LuaNews_t ) );
93 *la = news;
94 luaL_getmetatable( L, NEWS_METATABLE );
95 lua_setmetatable( L, -2 );
96 return la;
97}
98
105int lua_isnews( lua_State *L, int ind )
106{
107 int ret;
108
109 if ( lua_getmetatable( L, ind ) == 0 )
110 return 0;
111 lua_getfield( L, LUA_REGISTRYINDEX, NEWS_METATABLE );
112
113 ret = 0;
114 if ( lua_rawequal( L, -1, -2 ) ) /* does it have the correct mt? */
115 ret = 1;
116
117 lua_pop( L, 2 ); /* remove both metatables */
118 return ret;
119}
120
128static news_t *luaL_validnews( lua_State *L, int ind )
129{
130 const LuaNews_t *ln = luaL_checknews( L, ind );
131 news_t *n = news_get( *ln );
132 if ( n == NULL )
133 NLUA_ERROR( L, _( "Article is invalid." ) );
134 return n;
135}
136
165int newsL_add( lua_State *L )
166{
167 const char *title, *body, *faction;
168 ntime_t date, date_to_rm;
169 int priority;
170
171 title = NULL;
172 body = NULL;
173 faction = NULL;
174
175 date = ntime_get();
176 date_to_rm = NEWS_FOREVER;
177
178 /* If a table is passed in. ugly hack */
179 if ( lua_istable( L, 1 ) ) {
180 lua_pushnil( L );
181
182 /* traverse table */
183 while ( lua_next( L, -2 ) ) {
184 /* traverse sub table */
185 if ( lua_istable( L, -1 ) ) {
186 faction = title = body = NULL;
187 priority = 5;
188 date = ntime_get();
189 date_to_rm = NEWS_FOREVER;
190
191 lua_getfield( L, -1, "faction" );
192 if ( !lua_isnil( L, -1 ) )
193 faction = luaL_checkstring( L, -1 );
194 lua_pop( L, 1 );
195
196 lua_getfield( L, -1, "head" );
197 if ( !lua_isnil( L, -1 ) )
198 title = luaL_checkstring( L, -1 );
199 lua_pop( L, 1 );
200
201 lua_getfield( L, -1, "body" );
202 if ( !lua_isnil( L, -1 ) )
203 body = luaL_checkstring( L, -1 );
204 lua_pop( L, 1 );
205
206 lua_getfield( L, -1, "date" );
207 if ( !lua_isnil( L, -1 ) ) {
208 if ( lua_isnumber( L, -1 ) )
209 date = lua_tonumber( L, -1 );
210 else
211 date = luaL_validtime( L, -1 );
212 }
213 lua_pop( L, 1 );
214
215 lua_getfield( L, -1, "date_to_rm" );
216 if ( !lua_isnil( L, -1 ) ) {
217 if ( lua_isnumber( L, -1 ) )
218 date_to_rm = lua_tonumber( L, -1 );
219 else
220 date_to_rm = luaL_validtime( L, -1 );
221 }
222 lua_pop( L, 1 );
223
224 lua_getfield( L, -1, "priority" );
225 if ( !lua_isnil( L, -1 ) )
226 priority = luaL_checkinteger( L, -1 );
227 lua_pop( L, 1 );
228
229 if ( title && body && faction )
230 news_add( title, body, faction, NULL, date, date_to_rm,
231 priority );
232 else
233 NLUA_WARN( L, _( "Bad arguments" ) );
234 }
235 lua_pop( L, 1 );
236 }
237 lua_pop( L, 1 );
238
239 /* If we're landed, we should regenerate the news buffer. */
240 if ( landed ) {
241 generate_news( land_spob->presence.faction );
242 if ( land_loaded )
243 bar_regen();
244 }
245
246 return 0;
247 }
248
249 if ( !( lua_isstring( L, 1 ) && lua_isstring( L, 2 ) &&
250 lua_isstring( L, 3 ) ) ) {
251 NLUA_WARN(
252 L, _( "\nBad arguments, use "
253 "addArticle(\"Faction\",\"Title\",\"Content\",[date,[date_to_rm]"
254 "])" ) );
255 return 0;
256 }
257
258 faction = luaL_checkstring( L, 1 );
259 title = luaL_checkstring( L, 2 );
260 body = luaL_checkstring( L, 3 );
261 priority = luaL_optinteger( L, 6, 5 );
262
263 /* Get date and date to remove, or leave at defaults. */
264 if ( !lua_isnoneornil( L, 4 ) ) {
265 if ( lua_istime( L, 4 ) )
266 date_to_rm = luaL_validtime( L, 4 );
267 else
268 date_to_rm = luaL_checklong( L, 4 );
269 }
270 if ( !lua_isnoneornil( L, 5 ) ) {
271 if ( lua_istime( L, 5 ) )
272 date = luaL_validtime( L, 5 );
273 else
274 date = luaL_checklong( L, 5 );
275 }
276
277 if ( title && body && faction ) {
278 LuaNews_t n_article =
279 news_add( title, body, faction, NULL, date, date_to_rm, priority );
280 lua_pushnews( L, n_article );
281 } else
282 return NLUA_ERROR( L, _( "Bad arguments" ) );
283
284 /* If we're landed, we should regenerate the news buffer. */
285 if ( landed ) {
286 generate_news( land_spob->presence.faction );
287 if ( land_loaded )
288 bar_regen();
289 }
290
291 return 1;
292}
293
299int newsL_rm( lua_State *L )
300{
301 if ( lua_istable( L, 1 ) ) {
302 lua_pushnil( L );
303 while ( lua_next( L, -2 ) ) {
304 const LuaNews_t *Larticle = luaL_checknews( L, -1 );
305 news_rm( *Larticle );
306 lua_pop( L, 1 );
307 }
308 } else {
309 const LuaNews_t *Larticle = luaL_checknews( L, 1 );
310 news_rm( *Larticle );
311 }
312
313 /* If we're landed, we should regenerate the news buffer. */
314 if ( landed ) {
315 generate_news( land_spob->presence.faction );
316 if ( land_loaded )
317 bar_regen();
318 }
319
320 return 1;
321}
322
343int newsL_get( lua_State *L )
344{
345 ntime_t date = -1;
346 const char *characteristic = NULL;
347 int print_all = 0;
348 int narticle = 1;
349
350 if ( lua_isnoneornil( L, 1 ) ) /* Case no argument */
351 print_all = 1;
352 else if ( lua_isnumber( L, 1 ) )
353 date = (ntime_t)lua_tonumber( L, 1 );
354 else if ( lua_isstring( L, 1 ) )
355 characteristic = lua_tostring( L, 1 );
356 else
357 NLUA_INVALID_PARAMETER( L, 1 ); /* Bad Parameter */
358
359 /* Now put all the matching articles in a table. */
360 lua_newtable( L );
361 for ( int i = 0; i < array_size( news_list ); i++ ) {
362 const news_t *n = &news_list[i];
363
364 if ( ( n->title == NULL ) || ( n->desc == NULL ) ||
365 ( n->faction == NULL ) )
366 continue;
367
368 if ( print_all || date == n->date ||
369 ( characteristic &&
370 ( ( strcmp( n->title, characteristic ) == 0 ) ||
371 ( strcmp( n->desc, characteristic ) == 0 ) ||
372 ( strcmp( n->faction, characteristic ) == 0 ) ||
373 ( n->tag != NULL &&
374 strcmp( n->tag, characteristic ) == 0 ) ) ) ) {
375 lua_pushnews( L, n->id ); /* value */
376 lua_rawseti( L, -2, narticle++ );
377 }
378 }
379
380 return 1;
381}
382
393int newsL_eq( lua_State *L )
394{
395 const LuaNews_t *a1, *a2;
396 a1 = luaL_checknews( L, 1 );
397 a2 = luaL_checknews( L, 2 );
398 lua_pushboolean( L, *a1 == *a2 );
399 return 1;
400}
401
408int newsL_title( lua_State *L )
409{
410 news_t *article_ptr = luaL_validnews( L, 1 );
411 lua_pushstring( L, article_ptr->title );
412 return 1;
413}
414
421int newsL_desc( lua_State *L )
422{
423 news_t *article_ptr = luaL_validnews( L, 1 );
424 lua_pushstring( L, article_ptr->desc );
425 return 1;
426}
427
434int newsL_faction( lua_State *L )
435{
436 news_t *article_ptr = luaL_validnews( L, 1 );
437 lua_pushstring( L, article_ptr->faction );
438 return 1;
439}
440
447int newsL_date( lua_State *L )
448{
449 news_t *article_ptr = luaL_validnews( L, 1 );
450 lua_pushinteger( L, (lua_Integer)article_ptr->date );
451 return 1;
452}
453
460int newsL_bind( lua_State *L )
461{
462 news_t *article_ptr;
463 LuaNews_t *a = NULL;
464
465 if ( lua_istable( L, 1 ) ) {
466 const char *tag = luaL_checkstring( L, 2 );
467 lua_pop( L, 1 );
468 lua_pushnil( L );
469
470 /* traverse table */
471 while ( lua_next( L, -2 ) ) {
472 if ( !( a = luaL_checknews( L, -1 ) ) ) {
473 NLUA_WARN(
474 L, _( "Bad argument to news.date(), must be article or a table "
475 "of articles" ) );
476 return 0;
477 }
478 article_ptr = news_get( *a );
479 if ( article_ptr == NULL ) {
480 NLUA_WARN( L, _( "Article not valid" ) );
481 return 0;
482 }
483 article_ptr->tag = strdup( tag );
484 lua_pop( L, 1 );
485 }
486 } else {
487 const char *tag;
488 if ( !( a = luaL_checknews( L, 1 ) ) ) {
489 NLUA_WARN(
490 L, _( "Bad argument to news.date(), must be article or a table of "
491 "articles" ) );
492 return 0;
493 }
494 article_ptr = news_get( *a );
495 if ( article_ptr == NULL ) {
496 NLUA_WARN( L, _( "Article not valid" ) );
497 return 0;
498 }
499
500 tag = luaL_checkstring( L, 2 );
501 article_ptr->tag = strdup( tag );
502 }
503 return 1;
504}
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:179
void bar_regen(void)
Regenerates the bar list.
Definition land.c:432
int land_loaded
Definition land.c:79
int landed
Definition land.c:78
Spob * land_spob
Definition land.c:87
news_t * news_list
Definition news.c:31
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:94
news_t * news_get(int id)
gets the article with id ID, else NULL
Definition news.c:169
int * generate_news(int faction)
Generates news from newslist from specific faction AND Generic news.
Definition news.c:202
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:460
static news_t * luaL_validnews(lua_State *L, int ind)
Makes sure the news is valid or raises a Lua error.
Definition nlua_news.c:128
static int newsL_eq(lua_State *L)
Check news articles for equality.
Definition nlua_news.c:393
static LuaNews_t * lua_pushnews(lua_State *L, LuaNews_t news)
Pushes a news on the stack.
Definition nlua_news.c:90
static int lua_isnews(lua_State *L, int ind)
Checks to see if ind is a news.
Definition nlua_news.c:105
static const luaL_Reg news_methods[]
Definition nlua_news.c:39
int nlua_loadNews(nlua_env env)
Loads the news library.
Definition nlua_news.c:52
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:299
static int newsL_get(lua_State *L)
Gets all matching news articles in a table.
Definition nlua_news.c:343
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:421
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:76
static int newsL_add(lua_State *L)
Lua bindings to interact with the news.
Definition nlua_news.c:165
LuaNews_t * lua_tonews(lua_State *L, int ind)
Gets news at index.
Definition nlua_news.c:65
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:408
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:447
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:434
int lua_istime(lua_State *L, int ind)
Checks to see if ind is a time.
Definition nlua_time.c:138
ntime_t luaL_validtime(lua_State *L, int ind)
Gets a time directly.
Definition nlua_time.c:112
ntime_t ntime_get(void)
Gets the current time.
Definition ntime.c:113
Represents a news article.
Definition news.h:15
char * faction
Definition news.h:22
char * title
Definition news.h:20
int id
Definition news.h:16
ntime_t date
Definition news.h:25
char * tag
Definition news.h:23
char * desc
Definition news.h:21